gallium: specialize glFlush vs other flush semantics
authorKeith Whitwell <keith@tungstengraphics.com>
Mon, 21 Jan 2008 20:22:49 +0000 (20:22 +0000)
committerJosé Fonseca <jrfonseca@tungstengraphics.com>
Sat, 26 Jan 2008 01:30:31 +0000 (10:30 +0900)
src/mesa/state_tracker/st_cb_flush.c
src/mesa/state_tracker/st_framebuffer.c

index 9808b1f8f65b45a7df6489c913ecdf88c3201261..dbec993f1ba8780638ce193994def3b93d2efc9b 100644 (file)
 
 void st_flush( struct st_context *st, uint pipeFlushFlags )
 {
-   GLframebuffer *fb = st->ctx->DrawBuffer;
-
    FLUSH_VERTICES(st->ctx, 0);
 
-   /* If there has been no rendering to the frontbuffer, consider
-    * short-circuiting this, or perhaps pass an "optional" flag down
-    * to the driver so that it can make the decision.
-    */
    st->pipe->flush( st->pipe, pipeFlushFlags );
+}
+
+
+static void st_gl_flush( struct st_context *st, uint pipeFlushFlags )
+{
+   GLframebuffer *fb = st->ctx->DrawBuffer;
+
+   FLUSH_VERTICES(st->ctx, 0);
 
    if (!fb)
       return;
 
    /* XXX: temporary hack.  This flag should only be set if we do any
     * rendering to the front buffer.
+    *
+    * Further more, the scissor rectangle could be tracked to
+    * construct a dirty region of the front buffer, to avoid
+    * situations where it must be copied repeatedly.
+    *
+    * In the extreme case, some kind of timer could be set up to allow
+    * coalescing of multiple flushes to the frontbuffer, which can be
+    * quite a performance drain if there are a sufficient number of
+    * them.
     */
    st->flags.frontbuffer_dirty
       = (fb->_ColorDrawBufferMask[0] & BUFFER_BIT_FRONT_LEFT);
@@ -69,6 +80,15 @@ void st_flush( struct st_context *st, uint pipeFlushFlags )
          = st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
       struct pipe_surface *front_surf = strb->surface;
 
+      /* If we aren't rendering to the frontbuffer, this is a noop.
+       * This should be uncontroversial for glFlush, though people may
+       * feel more strongly about glFinish.
+       *
+       * Additionally, need to make sure that the frontbuffer_dirty
+       * flag really gets set on frontbuffer rendering.
+       */
+      st->pipe->flush( st->pipe, pipeFlushFlags );
+
       /* Hook for copying "fake" frontbuffer if necessary:
        */
       st->pipe->winsys->flush_frontbuffer( st->pipe->winsys, front_surf,
@@ -81,23 +101,23 @@ void st_flush( struct st_context *st, uint pipeFlushFlags )
 /**
  * Called via ctx->Driver.Flush()
  */
-static void st_Flush(GLcontext *ctx)
+static void st_glFlush(GLcontext *ctx)
 {
-   st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE);
+   st_gl_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE);
 }
 
 
 /**
  * Called via ctx->Driver.Finish()
  */
-static void st_Finish(GLcontext *ctx)
+static void st_glFinish(GLcontext *ctx)
 {
-   st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_WAIT);
+   st_gl_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_WAIT);
 }
 
 
 void st_init_flush_functions(struct dd_function_table *functions)
 {
-   functions->Flush = st_Flush;
-   functions->Finish = st_Finish;
+   functions->Flush = st_glFlush;
+   functions->Finish = st_glFinish;
 }
index 7ddc74e355c6fd4a1ef200665f6b47df3aa92079..42e8e24896c72cde0182fa2a97f0b018fe5b8a8f 100644 (file)
@@ -34,6 +34,7 @@
 #include "st_context.h"
 #include "st_cb_fbo.h"
 #include "pipe/p_defines.h"
+#include "pipe/p_context.h"
 
 
 struct st_framebuffer *
@@ -171,7 +172,11 @@ st_notify_swapbuffers(struct st_framebuffer *stfb)
    GET_CURRENT_CONTEXT(ctx);
 
    if (ctx && ctx->DrawBuffer == &stfb->Base) {
-      st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE);
+      st_flush( ctx->st, 
+               PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_SWAPBUFFERS);
+   }
+}
+
    }
 }