intel / DRI2: Track and flush front-buffer rendering
authorIan Romanick <idr@freedesktop.org>
Mon, 6 Apr 2009 20:15:54 +0000 (13:15 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Thu, 9 Apr 2009 21:18:14 +0000 (14:18 -0700)
Track two flags:  whether or not front-buffer rendering is currently
enabled and whether or not front-buffer rendering has been enabled
since the last glFlush.  If the second flag is set, the front-buffer
is flushed via a loader call back.  If the first flag is cleared, the
second flag is cleared at this time.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Kristian Høgsberg <krh@redhat.com>
src/mesa/drivers/dri/intel/intel_buffers.c
src/mesa/drivers/dri/intel/intel_context.c
src/mesa/drivers/dri/intel/intel_context.h

index 0929a2c223cc49bbb0f49619a010739b5117772c..f1249f7635a3ad57cf4631fe1061e6c947cb07b3 100644 (file)
@@ -202,6 +202,8 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)
               intel_batchbuffer_flush(intel->batch);
            intel->front_cliprects = GL_TRUE;
            colorRegions[0] = intel_get_rb_region(fb, BUFFER_FRONT_LEFT);
+
+           intel->front_buffer_dirty = GL_TRUE;
         }
         else {
            if (!intel->constant_cliprect && intel->front_cliprects)
@@ -319,6 +321,12 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)
 static void
 intelDrawBuffer(GLcontext * ctx, GLenum mode)
 {
+   if (ctx->DrawBuffer->Name == 0) {
+      struct intel_context *const intel = intel_context(ctx);
+
+      intel->is_front_buffer_rendering = (mode == GL_FRONT_LEFT);
+   }
+
    intel_draw_buffer(ctx, ctx->DrawBuffer);
 }
 
index a664e7493609606bb9f4a684b45d1cf9bb2606cc..797bfa8c4b1d4858d9d10daccdb5963abf76cd9c 100644 (file)
@@ -391,6 +391,26 @@ intel_flush(GLcontext *ctx, GLboolean needs_mi_flush)
 
    if (intel->batch->map != intel->batch->ptr)
       intel_batchbuffer_flush(intel->batch);
+
+   if ((ctx->DrawBuffer->Name == 0) && intel->front_buffer_dirty) {
+      __DRIscreen *const screen = intel->intelScreen->driScrnPriv;
+
+      if ((screen->dri2.loader->base.version >= 2)
+         && (screen->dri2.loader->flushFrontBuffer != NULL)) {
+        (*screen->dri2.loader->flushFrontBuffer)(intel->driDrawable,
+                                                 intel->driDrawable->loaderPrivate);
+
+        /* Only clear the dirty bit if front-buffer rendering is no longer
+         * enabled.  This is done so that the dirty bit can only be set in
+         * glDrawBuffer.  Otherwise the dirty bit would have to be set at
+         * each of N places that do rendering.  This has worse performances,
+         * but it is much easier to get correct.
+         */
+        if (intel->is_front_buffer_rendering) {
+           intel->front_buffer_dirty = GL_FALSE;
+        }
+      }
+   }
 }
 
 void
index d635f3f50dc43e4f86011d9431170ed7687d9464..bd3810549aa57875a60eb12c1c026a11a40fb0c9 100644 (file)
@@ -262,11 +262,29 @@ struct intel_context
     * flush time while the lock is held.
     */
    GLboolean constant_cliprect;
+
    /**
     * In !constant_cliprect mode, set to true if the front cliprects should be
     * used instead of back.
     */
    GLboolean front_cliprects;
+
+   /**
+    * Set if rendering has occured to the drawable's front buffer.
+    *
+    * This is used in the DRI2 case to detect that glFlush should also copy
+    * the contents of the fake front buffer to the real front buffer.
+    */
+   GLboolean front_buffer_dirty;
+
+   /**
+    * Track whether front-buffer rendering is currently enabled
+    *
+    * A separate flag is used to track this in order to support MRT more
+    * easily.
+    */
+   GLboolean is_front_buffer_rendering;
+
    drm_clip_rect_t fboRect;     /**< cliprect for FBO rendering */
 
    int perf_boxes;