summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian <brian.paul@tungstengraphics.com>2007-11-01 18:37:00 -0600
committerBrian <brian.paul@tungstengraphics.com>2007-11-01 18:37:00 -0600
commitd8e66aca8443c6802ecd8f1a353024ed1d0f32c3 (patch)
treec0038761beedea1e4854981c2fbfb7a6942ce722
parent28bed6d355e7ea3acbc4dbef0490e269d560f89e (diff)
Start re-working SwapBuffers.
intelCopyBuffer() is now intelDisplayBuffer(): it displays the given surface in the on-screen window. Added a pipe_surface parameter to winsys->flush_frontbuffer(). Front buffer rendering/flushing actually works now. But, we should only allocate the front surface on demand...
-rw-r--r--src/mesa/drivers/dri/intel_winsys/intel_swapbuffers.c79
-rw-r--r--src/mesa/drivers/dri/intel_winsys/intel_swapbuffers.h5
-rw-r--r--src/mesa/drivers/dri/intel_winsys/intel_winsys_pipe.c7
-rw-r--r--src/mesa/pipe/p_winsys.h4
-rw-r--r--src/mesa/pipe/xlib/xm_winsys.c14
-rw-r--r--src/mesa/state_tracker/st_cb_flush.c7
6 files changed, 64 insertions, 52 deletions
diff --git a/src/mesa/drivers/dri/intel_winsys/intel_swapbuffers.c b/src/mesa/drivers/dri/intel_winsys/intel_swapbuffers.c
index 2ffc757469..350c3f38a2 100644
--- a/src/mesa/drivers/dri/intel_winsys/intel_swapbuffers.c
+++ b/src/mesa/drivers/dri/intel_winsys/intel_swapbuffers.c
@@ -58,15 +58,33 @@ typedef struct drm_i915_flip {
#endif
+/**
+ * Return the pipe_surface for the given renderbuffer.
+ */
+static struct pipe_surface *
+get_color_surface(struct intel_framebuffer *intel_fb,
+ GLuint bufferIndex)
+{
+ struct st_renderbuffer *strb
+ = st_renderbuffer(intel_fb->Base.Attachment[bufferIndex].Renderbuffer);
+ if (strb)
+ return strb->surface;
+ return NULL;
+}
/**
- * Copy the back color buffer to the front color buffer.
- * Used for SwapBuffers().
+ * Display a colorbuffer surface in an X window.
+ * Used for SwapBuffers and flushing front buffer rendering.
+ *
+ * \param dPriv the window/drawable to display into
+ * \param surf the surface to display
+ * \param rect optional subrect of surface to display (may be NULL).
*/
void
-intelCopyBuffer(__DRIdrawablePrivate * dPriv,
- const drm_clip_rect_t * rect)
+intelDisplayBuffer(__DRIdrawablePrivate * dPriv,
+ struct pipe_surface *surf,
+ const drm_clip_rect_t * rect)
{
struct intel_context *intel;
@@ -103,49 +121,24 @@ intelCopyBuffer(__DRIdrawablePrivate * dPriv,
if (dPriv && dPriv->numClipRects) {
struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
-#if 0
- const struct pipe_region *backRegion
- = intel_fb->Base._ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT ?
- intel_get_rb_region(&intel_fb->Base, BUFFER_FRONT_LEFT) :
- intel_get_rb_region(&intel_fb->Base, BUFFER_BACK_LEFT);
-#endif
const int backWidth = intel_fb->Base.Width;
const int backHeight = intel_fb->Base.Height;
const int nbox = dPriv->numClipRects;
const drm_clip_rect_t *pbox = dPriv->pClipRects;
const int pitch = intelScreen->front.pitch / intelScreen->front.cpp;
-#if 0
- const int srcpitch = backRegion->pitch;
-#endif
const int cpp = intelScreen->front.cpp;
int BR13, CMD;
int i;
-
- const struct pipe_surface *backSurf;
- const struct pipe_region *backRegion;
- int srcpitch;
- struct st_renderbuffer *strb;
-
- /* blit from back color buffer if it exists, else front buffer */
- strb = st_renderbuffer(intel_fb->Base.Attachment[BUFFER_BACK_LEFT].Renderbuffer);
- if (strb) {
- backSurf = strb->surface;
- }
- else {
- strb = st_renderbuffer(intel_fb->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
- backSurf = strb->surface;
- }
-
- backRegion = backSurf->region;
- srcpitch = backRegion->pitch;
+ const struct pipe_region *srcRegion = surf->region;
+ const int srcpitch= srcRegion->pitch;
ASSERT(intel_fb);
ASSERT(intel_fb->Base.Name == 0); /* Not a user-created FBO */
- ASSERT(backRegion);
- ASSERT(backRegion->cpp == cpp);
+ ASSERT(srcRegion);
+ ASSERT(srcRegion->cpp == cpp);
DBG(SWAP, "front pitch %d back pitch %d\n",
- pitch, backRegion->pitch);
+ pitch, srcRegion->pitch);
if (cpp == 2) {
BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24);
@@ -164,12 +157,15 @@ intelCopyBuffer(__DRIdrawablePrivate * dPriv,
if (pbox->x1 > pbox->x2 ||
pbox->y1 > pbox->y2 ||
pbox->x2 > intelScreen->front.width ||
- pbox->y2 > intelScreen->front.height)
+ pbox->y2 > intelScreen->front.height) {
+ /* invalid cliprect, skip it */
continue;
+ }
box = *pbox;
if (rect) {
+ /* intersect cliprect with user-provided src rect */
drm_clip_rect_t rrect;
rrect.x1 = dPriv->x + rect->x1;
@@ -212,7 +208,7 @@ intelCopyBuffer(__DRIdrawablePrivate * dPriv,
DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0);
OUT_BATCH((sbox.y1 << 16) | sbox.x1);
OUT_BATCH((srcpitch * cpp) & 0xffff);
- OUT_RELOC(dri_bo(backRegion->buffer),
+ OUT_RELOC(dri_bo(srcRegion->buffer),
DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0);
@@ -590,10 +586,13 @@ intelSwapBuffers(__DRIdrawablePrivate * dPriv)
_mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */
if (!intelScheduleSwap(dPriv, &missed_target)) {
+ struct pipe_surface *back_surf
+ = get_color_surface(intel_fb, BUFFER_BACK_LEFT);
+
driWaitForVBlank(dPriv, &intel_fb->vbl_seq, intel_fb->vblank_flags,
&missed_target);
- intelCopyBuffer(dPriv, NULL);
+ intelDisplayBuffer(dPriv, back_surf, NULL);
}
intel_fb->swap_count++;
@@ -621,6 +620,10 @@ intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h)
GLcontext *ctx = intel->st->ctx;
if (ctx->Visual.doubleBufferMode) {
+ struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
+ struct pipe_surface *back_surf
+ = get_color_surface(intel_fb, BUFFER_BACK_LEFT);
+
drm_clip_rect_t rect;
/* fixup cliprect (driDrawable may have changed?) later */
rect.x1 = x;
@@ -628,7 +631,7 @@ intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h)
rect.x2 = w;
rect.y2 = h;
_mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */
- intelCopyBuffer(dPriv, &rect);
+ intelDisplayBuffer(dPriv, back_surf, &rect);
}
}
else {
diff --git a/src/mesa/drivers/dri/intel_winsys/intel_swapbuffers.h b/src/mesa/drivers/dri/intel_winsys/intel_swapbuffers.h
index 0065eac9b2..15ed6704d2 100644
--- a/src/mesa/drivers/dri/intel_winsys/intel_swapbuffers.h
+++ b/src/mesa/drivers/dri/intel_winsys/intel_swapbuffers.h
@@ -62,8 +62,9 @@ struct intel_framebuffer
};
-void intelCopyBuffer(__DRIdrawablePrivate * dPriv,
- const drm_clip_rect_t * rect);
+extern void intelDisplayBuffer(__DRIdrawablePrivate * dPriv,
+ struct pipe_surface *surf,
+ const drm_clip_rect_t * rect);
extern void intel_wait_flips(struct intel_context *intel, GLuint batch_flags);
diff --git a/src/mesa/drivers/dri/intel_winsys/intel_winsys_pipe.c b/src/mesa/drivers/dri/intel_winsys/intel_winsys_pipe.c
index 4569b1e3bf..7f788b8537 100644
--- a/src/mesa/drivers/dri/intel_winsys/intel_winsys_pipe.c
+++ b/src/mesa/drivers/dri/intel_winsys/intel_winsys_pipe.c
@@ -185,12 +185,13 @@ static void intel_wait_idle( struct pipe_winsys *sws )
* we copied its contents to the real frontbuffer. Our task is easy:
*/
static void
-intel_flush_frontbuffer( struct pipe_winsys *sws )
+intel_flush_frontbuffer( struct pipe_winsys *sws,
+ struct pipe_surface *surf )
{
struct intel_context *intel = intel_pipe_winsys(sws)->intel;
__DRIdrawablePrivate *dPriv = intel->driDrawable;
-
- intelCopyBuffer(dPriv, NULL);
+
+ intelDisplayBuffer(dPriv, surf, NULL);
}
diff --git a/src/mesa/pipe/p_winsys.h b/src/mesa/pipe/p_winsys.h
index 10a2caf1a2..2d4432dbca 100644
--- a/src/mesa/pipe/p_winsys.h
+++ b/src/mesa/pipe/p_winsys.h
@@ -53,6 +53,7 @@ struct pipe_buffer_handle;
struct pipe_region;
+struct pipe_surface;
/** Opaque type */
struct pipe_buffer_handle;
@@ -63,7 +64,8 @@ struct pipe_winsys
* Do any special operations to ensure frontbuffer contents are
* displayed, eg copy fake frontbuffer.
*/
- void (*flush_frontbuffer)( struct pipe_winsys *sws );
+ void (*flush_frontbuffer)( struct pipe_winsys *sws,
+ struct pipe_surface *surf );
/** Debug output */
void (*printf)( struct pipe_winsys *sws,
diff --git a/src/mesa/pipe/xlib/xm_winsys.c b/src/mesa/pipe/xlib/xm_winsys.c
index e6e98ed396..5de811a66f 100644
--- a/src/mesa/pipe/xlib/xm_winsys.c
+++ b/src/mesa/pipe/xlib/xm_winsys.c
@@ -157,14 +157,14 @@ xm_buffer_get_subdata(struct pipe_winsys *pws, struct pipe_buffer_handle *buf,
}
static void
-xm_flush_frontbuffer(struct pipe_winsys *pws)
+xm_flush_frontbuffer(struct pipe_winsys *pws,
+ struct pipe_surface *surf )
{
- /*
- struct intel_context *intel = intel_pipe_winsys(sws)->intel;
- __DRIdrawablePrivate *dPriv = intel->driDrawable;
-
- intelCopyBuffer(dPriv, NULL);
- */
+ /* The Xlib driver's front color surfaces are actually X Windows so
+ * this flush is a no-op.
+ * If we instead did front buffer rendering to a temporary XImage,
+ * this would be the place to copy the Ximage to the on-screen Window.
+ */
}
static void
diff --git a/src/mesa/state_tracker/st_cb_flush.c b/src/mesa/state_tracker/st_cb_flush.c
index 41f21c361c..c2c3c80b87 100644
--- a/src/mesa/state_tracker/st_cb_flush.c
+++ b/src/mesa/state_tracker/st_cb_flush.c
@@ -35,6 +35,7 @@
#include "main/macros.h"
#include "st_context.h"
#include "st_cb_flush.h"
+#include "st_cb_fbo.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_winsys.h"
@@ -59,9 +60,13 @@ static void st_flush(GLcontext *ctx)
if (st->flags.frontbuffer_dirty) {
+ struct st_renderbuffer *strb
+ = st_renderbuffer(ctx->DrawBuffer->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
+ struct pipe_surface *front_surf = strb->surface;
+
/* Hook for copying "fake" frontbuffer if necessary:
*/
- st->pipe->winsys->flush_frontbuffer( st->pipe->winsys );
+ st->pipe->winsys->flush_frontbuffer( st->pipe->winsys, front_surf );
st->flags.frontbuffer_dirty = 0;
}
}