This looks good to me and sets things up nicely for the patch I&#39;m looking at to add cogl_framebuffer_draw_rectangle/textured_rectangle... functions to replace<div>cogl_rectangle() etc for the 2.0 api.</div><div><br></div>
<div>thanks,</div><div>- Robert</div><br><div class="gmail_quote">On Fri, Mar 16, 2012 at 5:43 PM, Neil Roberts <span dir="ltr">&lt;<a href="mailto:neil@linux.intel.com">neil@linux.intel.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Previously when adding a quad to the journal it would assume the<br>
journal belongs to the framebuffer at the top of the framebuffer stack<br>
and store a reference to that. We eventually want to get rid of the<br>
framebuffer stack so we should avoid using it here. The journal now<br>
takes a pointer back to the framebuffer in its constructor and it<br>
always retains the pointer. As was done previously, the journal still<br>
does not take a reference on the framebuffer unless it is non-empty so<br>
it does not create a permanent circular reference.<br>
---<br>
 cogl/cogl-attribute.c       |    2 +-<br>
 cogl/cogl-framebuffer.c     |    4 +-<br>
 cogl/cogl-journal-private.h |    5 +--<br>
 cogl/cogl-journal.c         |   70 +++++++++++++++++++-----------------------<br>
 4 files changed, 37 insertions(+), 44 deletions(-)<br>
<br>
diff --git a/cogl/cogl-attribute.c b/cogl/cogl-attribute.c<br>
index e9f6cef..3f1ae71 100644<br>
--- a/cogl/cogl-attribute.c<br>
+++ b/cogl/cogl-attribute.c<br>
@@ -562,7 +562,7 @@ _cogl_flush_attributes_state (CoglFramebuffer *framebuffer,<br>
   CoglContext *ctx = framebuffer-&gt;context;<br>
<br>
   if (!(flags &amp; COGL_DRAW_SKIP_JOURNAL_FLUSH))<br>
-    _cogl_journal_flush (framebuffer-&gt;journal, framebuffer);<br>
+    _cogl_journal_flush (framebuffer-&gt;journal);<br>
<br>
   layers_state.unit = 0;<br>
   layers_state.options.flags = 0;<br>
diff --git a/cogl/cogl-framebuffer.c b/cogl/cogl-framebuffer.c<br>
index 799f406..ab7f0aa 100644<br>
--- a/cogl/cogl-framebuffer.c<br>
+++ b/cogl/cogl-framebuffer.c<br>
@@ -189,7 +189,7 @@ _cogl_framebuffer_init (CoglFramebuffer *framebuffer,<br>
   /* Initialise the clip stack */<br>
   _cogl_clip_state_init (&amp;framebuffer-&gt;clip_state);<br>
<br>
-  framebuffer-&gt;journal = _cogl_journal_new ();<br>
+  framebuffer-&gt;journal = _cogl_journal_new (framebuffer);<br>
<br>
   /* Ensure we know the framebuffer-&gt;clear_color* members can&#39;t be<br>
    * referenced for our fast-path read-pixel optimization (see<br>
@@ -633,7 +633,7 @@ _cogl_framebuffer_remove_all_dependencies (CoglFramebuffer *framebuffer)<br>
 void<br>
 _cogl_framebuffer_flush_journal (CoglFramebuffer *framebuffer)<br>
 {<br>
-  _cogl_journal_flush (framebuffer-&gt;journal, framebuffer);<br>
+  _cogl_journal_flush (framebuffer-&gt;journal);<br>
 }<br>
<br>
 void<br>
diff --git a/cogl/cogl-journal-private.h b/cogl/cogl-journal-private.h<br>
index 6e9764a..90363cd 100644<br>
--- a/cogl/cogl-journal-private.h<br>
+++ b/cogl/cogl-journal-private.h<br>
@@ -77,7 +77,7 @@ typedef struct _CoglJournalEntry<br>
 } CoglJournalEntry;<br>
<br>
 CoglJournal *<br>
-_cogl_journal_new (void);<br>
+_cogl_journal_new (CoglFramebuffer *framebuffer);<br>
<br>
 void<br>
 _cogl_journal_log_quad (CoglJournal  *journal,<br>
@@ -89,8 +89,7 @@ _cogl_journal_log_quad (CoglJournal  *journal,<br>
                         unsigned int  tex_coords_len);<br>
<br>
 void<br>
-_cogl_journal_flush (CoglJournal *journal,<br>
-                     CoglFramebuffer *framebuffer);<br>
+_cogl_journal_flush (CoglJournal *journal);<br>
<br>
 void<br>
 _cogl_journal_discard (CoglJournal *journal);<br>
diff --git a/cogl/cogl-journal.c b/cogl/cogl-journal.c<br>
index b8191c0..59a9fd8 100644<br>
--- a/cogl/cogl-journal.c<br>
+++ b/cogl/cogl-journal.c<br>
@@ -96,8 +96,6 @@ typedef struct _CoglJournalFlushState<br>
 {<br>
   CoglJournal         *journal;<br>
<br>
-  CoglFramebuffer     *framebuffer;<br>
-<br>
   CoglAttributeBuffer *attribute_buffer;<br>
   GArray              *attributes;<br>
   int                  current_attribute;<br>
@@ -143,10 +141,18 @@ _cogl_journal_free (CoglJournal *journal)<br>
 }<br>
<br>
 CoglJournal *<br>
-_cogl_journal_new (void)<br>
+_cogl_journal_new (CoglFramebuffer *framebuffer)<br>
 {<br>
   CoglJournal *journal = g_slice_new0 (CoglJournal);<br>
<br>
+  /* The journal keeps a pointer back to the framebuffer because there<br>
+     is effectively a 1:1 mapping between journals and framebuffers.<br>
+     However, to avoid a circular reference the journal doesn&#39;t take a<br>
+     reference unless it is non-empty. The framebuffer has a special<br>
+     unref implementation to ensure that the journal is flushed when<br>
+     the journal is the only thing keeping it alive */<br>
+  journal-&gt;framebuffer = framebuffer;<br>
+<br>
   journal-&gt;entries = g_array_new (FALSE, FALSE, sizeof (CoglJournalEntry));<br>
   journal-&gt;vertices = g_array_new (FALSE, FALSE, sizeof (float));<br>
<br>
@@ -270,6 +276,7 @@ _cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start,<br>
                                            void             *data)<br>
 {<br>
   CoglJournalFlushState *state = data;<br>
+  CoglFramebuffer *framebuffer = state-&gt;journal-&gt;framebuffer;<br>
   CoglAttribute **attributes;<br>
   CoglDrawFlags draw_flags = (COGL_DRAW_SKIP_JOURNAL_FLUSH |<br>
                               COGL_DRAW_SKIP_PIPELINE_VALIDATION |<br>
@@ -305,7 +312,7 @@ _cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start,<br>
   if (ctx-&gt;driver == COGL_DRIVER_GL)<br>
     {<br>
       /* XXX: it&#39;s rather evil that we sneak in the GL_QUADS enum here... */<br>
-      _cogl_framebuffer_draw_attributes (state-&gt;framebuffer,<br>
+      _cogl_framebuffer_draw_attributes (framebuffer,<br>
                                          state-&gt;pipeline,<br>
                                          GL_QUADS,<br>
                                          state-&gt;current_vertex, batch_len * 4,<br>
@@ -320,7 +327,7 @@ _cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start,<br>
         {<br>
           CoglVerticesMode mode = COGL_VERTICES_MODE_TRIANGLES;<br>
           int first_vertex = state-&gt;current_vertex * 6 / 4;<br>
-          _cogl_framebuffer_draw_indexed_attributes (state-&gt;framebuffer,<br>
+          _cogl_framebuffer_draw_indexed_attributes (framebuffer,<br>
                                                      state-&gt;pipeline,<br>
                                                      mode,<br>
                                                      first_vertex,<br>
@@ -332,7 +339,7 @@ _cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start,<br>
         }<br>
       else<br>
         {<br>
-          _cogl_framebuffer_draw_attributes (state-&gt;framebuffer,<br>
+          _cogl_framebuffer_draw_attributes (framebuffer,<br>
                                              state-&gt;pipeline,<br>
                                              COGL_VERTICES_MODE_TRIANGLE_FAN,<br>
                                              state-&gt;current_vertex, 4,<br>
@@ -379,7 +386,7 @@ _cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start,<br>
<br>
       loop_attributes[0] = attributes[0]; /* we just want the position */<br>
       for (i = 0; i &lt; batch_len; i++)<br>
-        _cogl_framebuffer_draw_attributes (state-&gt;framebuffer,<br>
+        _cogl_framebuffer_draw_attributes (framebuffer,<br>
                                            outline,<br>
                                            COGL_VERTICES_MODE_LINE_LOOP,<br>
                                            4 * i + state-&gt;current_vertex, 4,<br>
@@ -576,7 +583,7 @@ _cogl_journal_flush_vbo_offsets_and_entries (CoglJournalEntry *batch_start,<br>
                                              void             *data)<br>
 {<br>
   CoglJournalFlushState   *state = data;<br>
-  CoglContext             *ctx = state-&gt;framebuffer-&gt;context;<br>
+  CoglContext             *ctx = state-&gt;journal-&gt;framebuffer-&gt;context;<br>
   gsize                    stride;<br>
   int                      i;<br>
   CoglAttribute          **attribute_entry;<br>
@@ -711,7 +718,7 @@ _cogl_journal_flush_clip_stacks_and_entries (CoglJournalEntry *batch_start,<br>
   if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_BATCHING)))<br>
     g_print (&quot;BATCHING:  clip stack batch len = %d\n&quot;, batch_len);<br>
<br>
-  _cogl_clip_stack_flush (batch_start-&gt;clip_stack, state-&gt;framebuffer);<br>
+  _cogl_clip_stack_flush (batch_start-&gt;clip_stack, state-&gt;journal-&gt;framebuffer);<br>
<br>
   /* XXX: Because we are manually flushing clip state here we need to<br>
    * make sure that the clip state gets updated the next time we flush<br>
@@ -1254,6 +1261,9 @@ _cogl_journal_discard (CoglJournal *journal)<br>
 {<br>
   int i;<br>
<br>
+  if (journal-&gt;entries-&gt;len &lt;= 0)<br>
+    return;<br>
+<br>
   for (i = 0; i &lt; journal-&gt;entries-&gt;len; i++)<br>
     {<br>
       CoglJournalEntry *entry =<br>
@@ -1269,11 +1279,7 @@ _cogl_journal_discard (CoglJournal *journal)<br>
<br>
   /* The journal only holds a reference to the framebuffer while the<br>
      journal is not empty */<br>
-  if (journal-&gt;framebuffer)<br>
-    {<br>
-      cogl_object_unref (journal-&gt;framebuffer);<br>
-      journal-&gt;framebuffer = NULL;<br>
-    }<br>
+  cogl_object_unref (journal-&gt;framebuffer);<br>
 }<br>
<br>
 /* Note: A return value of FALSE doesn&#39;t mean &#39;no&#39; it means<br>
@@ -1349,8 +1355,7 @@ _cogl_journal_all_entries_within_bounds (CoglJournal *journal,<br>
  * is undefined.<br>
  */<br>
 void<br>
-_cogl_journal_flush (CoglJournal *journal,<br>
-                     CoglFramebuffer *framebuffer)<br>
+_cogl_journal_flush (CoglJournal *journal)<br>
 {<br>
   CoglJournalFlushState state;<br>
   int                   i;<br>
@@ -1366,31 +1371,25 @@ _cogl_journal_flush (CoglJournal *journal,<br>
   if (journal-&gt;entries-&gt;len == 0)<br>
     return;<br>
<br>
-  /* Something has gone wrong if we&#39;re using a different framebuffer<br>
-     to flush than the one that was current when the entries were<br>
-     added */<br>
-  _COGL_RETURN_IF_FAIL (framebuffer == journal-&gt;framebuffer);<br>
-<br>
   /* The entries in this journal may depend on images in other<br>
    * framebuffers which may require that we flush the journals<br>
    * associated with those framebuffers before we can flush<br>
    * this journal... */<br>
-  _cogl_framebuffer_flush_dependency_journals (framebuffer);<br>
+  _cogl_framebuffer_flush_dependency_journals (journal-&gt;framebuffer);<br>
<br>
   /* Note: we start the timer after flushing dependency journals so<br>
    * that the timer isn&#39;t started recursively. */<br>
   COGL_TIMER_START (_cogl_uprof_context, flush_timer);<br>
<br>
-  state.framebuffer = framebuffer;<br>
-  cogl_push_framebuffer (framebuffer);<br>
+  cogl_push_framebuffer (journal-&gt;framebuffer);<br>
<br>
   if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_BATCHING)))<br>
     g_print (&quot;BATCHING: journal len = %d\n&quot;, journal-&gt;entries-&gt;len);<br>
<br>
   /* NB: the journal deals with flushing the modelview stack and clip<br>
      state manually */<br>
-  _cogl_framebuffer_flush_state (framebuffer,<br>
-                                 framebuffer,<br>
+  _cogl_framebuffer_flush_state (journal-&gt;framebuffer,<br>
+                                 journal-&gt;framebuffer,<br>
                                  COGL_FRAMEBUFFER_STATE_ALL &amp;<br>
                                  ~(COGL_FRAMEBUFFER_STATE_MODELVIEW |<br>
                                    COGL_FRAMEBUFFER_STATE_CLIP));<br>
@@ -1399,9 +1398,11 @@ _cogl_journal_flush (CoglJournal *journal,<br>
<br>
   state.attributes = ctx-&gt;journal_flush_attributes_array;<br>
<br>
-  modelview_stack = _cogl_framebuffer_get_modelview_stack (framebuffer);<br>
+  modelview_stack =<br>
+    _cogl_framebuffer_get_modelview_stack (journal-&gt;framebuffer);<br>
   state.modelview_stack = modelview_stack;<br>
-  state.projection_stack = _cogl_framebuffer_get_projection_stack (framebuffer);<br>
+  state.projection_stack =<br>
+    _cogl_framebuffer_get_projection_stack (journal-&gt;framebuffer);<br>
<br>
   if (G_UNLIKELY ((COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_SOFTWARE_CLIP)) == 0))<br>
     {<br>
@@ -1516,11 +1517,9 @@ _cogl_journal_log_quad (CoglJournal  *journal,<br>
<br>
   /* If the framebuffer was previously empty then we&#39;ll take a<br>
      reference to the current framebuffer. This reference will be<br>
-     removed when the journal is flushed. FIXME: This should probably<br>
-     be being passed a pointer to the framebuffer from further up so<br>
-     that we don&#39;t have to rely on the global framebuffer stack */<br>
+     removed when the journal is flushed */<br>
   if (journal-&gt;vertices-&gt;len == 0)<br>
-    journal-&gt;framebuffer = cogl_object_ref (cogl_get_draw_framebuffer ());<br>
+    cogl_object_ref (journal-&gt;framebuffer);<br>
<br>
   /* The vertex data is logged into a separate array. The data needs<br>
      to be copied into a vertex array before it&#39;s given to GL so we<br>
@@ -1611,13 +1610,8 @@ _cogl_journal_log_quad (CoglJournal  *journal,<br>
                                          add_framebuffer_deps_cb,<br>
                                          journal-&gt;framebuffer);<br>
<br>
-  /* XXX: It doesn&#39;t feel very nice that in this case we just assume<br>
-   * that the journal is associated with the current framebuffer. I<br>
-   * think a journal-&gt;framebuffer reference would seem nicer here but<br>
-   * the reason we don&#39;t have that currently is that it would<br>
-   * introduce a circular reference. */<br>
   if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_BATCHING)))<br>
-    _cogl_framebuffer_flush_journal (journal-&gt;framebuffer);<br>
+    _cogl_journal_flush (journal);<br>
<br>
   COGL_TIMER_STOP (_cogl_uprof_context, log_timer);<br>
 }<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.7.3.16.g9464b<br>
<br>
_______________________________________________<br>
Cogl mailing list<br>
<a href="mailto:Cogl@lists.freedesktop.org">Cogl@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/cogl" target="_blank">http://lists.freedesktop.org/mailman/listinfo/cogl</a><br>
</font></span></blockquote></div><br>