[cogl/wip/virtual-framebuffer: 36/37] fix: optimize framebuffer flush state



commit b9a746332e290e65dca2c6071f7b5fba3572fef6
Author: Robert Bragg <robert linux intel com>
Date:   Tue Nov 22 23:07:30 2011 +0000

    fix: optimize framebuffer flush state

 cogl/cogl-framebuffer-private.h |   16 ----------------
 cogl/cogl-framebuffer.c         |   32 ++++++++++++++++++--------------
 cogl/cogl-onscreen.c            |    8 ++++++++
 3 files changed, 26 insertions(+), 30 deletions(-)
---
diff --git a/cogl/cogl-framebuffer-private.h b/cogl/cogl-framebuffer-private.h
index 31864f3..cfdf29f 100644
--- a/cogl/cogl-framebuffer-private.h
+++ b/cogl/cogl-framebuffer-private.h
@@ -252,22 +252,6 @@ _cogl_framebuffer_try_fast_read_pixel (CoglFramebuffer *framebuffer,
                                        CoglPixelFormat format,
                                        guint8 *pixel);
 
-typedef enum _CoglFramebufferFlushFlags
-{
-  /* XXX: When using this, that imples you are going to manually load the
-   * modelview matrix (via glLoadMatrix). _cogl_matrix_stack_flush_to_gl wont
-   * be called for framebuffer->modelview_stack, and the modelview_stack will
-   * also be marked as dirty. */
-  COGL_FRAMEBUFFER_FLUSH_SKIP_MODELVIEW =     1L<<0,
-  /* Similarly this flag implies you are going to flush the clip state
-     yourself */
-  COGL_FRAMEBUFFER_FLUSH_SKIP_CLIP_STATE =    1L<<1,
-  /* When using this all that will be updated is the glBindFramebuffer
-   * state and corresponding winsys state to make the framebuffer
-   * current if it is a CoglOnscreen framebuffer. */
-  COGL_FRAMEBUFFER_FLUSH_BIND_ONLY =          1L<<2
-} CoglFramebufferFlushFlags;
-
 void
 _cogl_framebuffer_flush_state (CoglFramebuffer *draw_buffer,
                                CoglFramebuffer *read_buffer,
diff --git a/cogl/cogl-framebuffer.c b/cogl/cogl-framebuffer.c
index 62cb132..103014c 100644
--- a/cogl/cogl-framebuffer.c
+++ b/cogl/cogl-framebuffer.c
@@ -230,6 +230,11 @@ _cogl_framebuffer_free (CoglFramebuffer *framebuffer)
 
   ctx->framebuffers = g_list_remove (ctx->framebuffers, framebuffer);
   cogl_object_unref (ctx);
+
+  if (ctx->current_draw_buffer == framebuffer)
+    ctx->current_draw_buffer = NULL;
+  if (ctx->current_read_buffer == framebuffer)
+    ctx->current_read_buffer = NULL;
 }
 
 const CoglWinsysVtable *
@@ -1422,16 +1427,18 @@ _cogl_framebuffer_compare_front_face_winding_state (CoglFramebuffer *a,
 static unsigned long
 _cogl_framebuffer_compare (CoglFramebuffer *a,
                            CoglFramebuffer *b,
-                           CoglFramebufferState state)
+                           unsigned long state)
 {
   unsigned long differences = 0;
   int bit;
 
   if (state & COGL_FRAMEBUFFER_STATE_BIND)
-    differences |= COGL_FRAMEBUFFER_STATE_BIND;
+    {
+      differences |= COGL_FRAMEBUFFER_STATE_BIND;
+      state &= ~COGL_FRAMEBUFFER_STATE_BIND;
+    }
 
-  COGL_FLAGS_FOREACH_START (&differences,
-                            COGL_FRAMEBUFFER_STATE_INDEX_MAX, bit)
+  COGL_FLAGS_FOREACH_START (&state, 1, bit)
     {
       /* XXX: We considered having an array of callbacks for each state index
        * that we'd call here but decided that this way the compiler is more
@@ -1622,9 +1629,9 @@ _cogl_framebuffer_flush_state (CoglFramebuffer *draw_buffer,
       differences |= _cogl_framebuffer_compare (ctx->current_draw_buffer,
                                                 draw_buffer,
                                                 state & ~differences);
-      if (ctx->current_draw_buffer)
-        cogl_object_unref (ctx->current_draw_buffer);
-      ctx->current_draw_buffer = cogl_object_ref (draw_buffer);
+      /* NB: we don't take a reference here, to avoid a circular
+       * reference. */
+      ctx->current_draw_buffer = draw_buffer;
       ctx->current_draw_buffer_state_flushed = 0;
     }
 
@@ -1632,8 +1639,9 @@ _cogl_framebuffer_flush_state (CoglFramebuffer *draw_buffer,
       state & COGL_FRAMEBUFFER_STATE_BIND)
     {
       differences |= COGL_FRAMEBUFFER_STATE_BIND;
-      cogl_object_unref (ctx->current_read_buffer);
-      ctx->current_read_buffer = cogl_object_ref (read_buffer);
+      /* NB: we don't take a reference here, to avoid a circular
+       * reference. */
+      ctx->current_read_buffer = read_buffer;
     }
 
   if (!differences)
@@ -1667,13 +1675,9 @@ _cogl_framebuffer_flush_state (CoglFramebuffer *draw_buffer,
         }
 
       differences &= ~COGL_FRAMEBUFFER_STATE_BIND;
-
-      if (state == COGL_FRAMEBUFFER_STATE_BIND)
-        return;
     }
 
-  COGL_FLAGS_FOREACH_START (&differences,
-                            COGL_FRAMEBUFFER_STATE_INDEX_MAX, bit)
+  COGL_FLAGS_FOREACH_START (&differences, 1, bit)
     {
       /* XXX: We considered having an array of callbacks for each state index
        * that we'd call here but decided that this way the compiler is more
diff --git a/cogl/cogl-onscreen.c b/cogl/cogl-onscreen.c
index 8f1634b..4eff256 100644
--- a/cogl/cogl-onscreen.c
+++ b/cogl/cogl-onscreen.c
@@ -339,4 +339,12 @@ _cogl_framebuffer_winsys_update_size (CoglFramebuffer *framebuffer,
 
   framebuffer->width = width;
   framebuffer->height = height;
+
+  /* The framebuffer geometry can affect the GL viewport so if the
+   * framebuffer being updated is the current framebuffer we mark the
+   * viewport state as changed so it will be updated the next time
+   * _cogl_framebuffer_flush_state() is called. */
+  if (framebuffer->context->current_draw_buffer == framebuffer)
+    framebuffer->context->current_draw_buffer_changes |=
+      COGL_FRAMEBUFFER_STATE_VIEWPORT;
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]