This looks good to me and sets things up nicely for the patch I'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"><<a href="mailto:neil@linux.intel.com">neil@linux.intel.com</a>></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->context;<br>
<br>
if (!(flags & COGL_DRAW_SKIP_JOURNAL_FLUSH))<br>
- _cogl_journal_flush (framebuffer->journal, framebuffer);<br>
+ _cogl_journal_flush (framebuffer->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 (&framebuffer->clip_state);<br>
<br>
- framebuffer->journal = _cogl_journal_new ();<br>
+ framebuffer->journal = _cogl_journal_new (framebuffer);<br>
<br>
/* Ensure we know the framebuffer->clear_color* members can'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->journal, framebuffer);<br>
+ _cogl_journal_flush (framebuffer->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'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->framebuffer = framebuffer;<br>
+<br>
journal->entries = g_array_new (FALSE, FALSE, sizeof (CoglJournalEntry));<br>
journal->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->journal->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->driver == COGL_DRIVER_GL)<br>
{<br>
/* XXX: it's rather evil that we sneak in the GL_QUADS enum here... */<br>
- _cogl_framebuffer_draw_attributes (state->framebuffer,<br>
+ _cogl_framebuffer_draw_attributes (framebuffer,<br>
state->pipeline,<br>
GL_QUADS,<br>
state->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->current_vertex * 6 / 4;<br>
- _cogl_framebuffer_draw_indexed_attributes (state->framebuffer,<br>
+ _cogl_framebuffer_draw_indexed_attributes (framebuffer,<br>
state->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->framebuffer,<br>
+ _cogl_framebuffer_draw_attributes (framebuffer,<br>
state->pipeline,<br>
COGL_VERTICES_MODE_TRIANGLE_FAN,<br>
state->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 < batch_len; i++)<br>
- _cogl_framebuffer_draw_attributes (state->framebuffer,<br>
+ _cogl_framebuffer_draw_attributes (framebuffer,<br>
outline,<br>
COGL_VERTICES_MODE_LINE_LOOP,<br>
4 * i + state->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->framebuffer->context;<br>
+ CoglContext *ctx = state->journal->framebuffer->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 ("BATCHING: clip stack batch len = %d\n", batch_len);<br>
<br>
- _cogl_clip_stack_flush (batch_start->clip_stack, state->framebuffer);<br>
+ _cogl_clip_stack_flush (batch_start->clip_stack, state->journal->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->entries->len <= 0)<br>
+ return;<br>
+<br>
for (i = 0; i < journal->entries->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->framebuffer)<br>
- {<br>
- cogl_object_unref (journal->framebuffer);<br>
- journal->framebuffer = NULL;<br>
- }<br>
+ cogl_object_unref (journal->framebuffer);<br>
}<br>
<br>
/* Note: A return value of FALSE doesn't mean 'no' 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->entries->len == 0)<br>
return;<br>
<br>
- /* Something has gone wrong if we'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->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->framebuffer);<br>
<br>
/* Note: we start the timer after flushing dependency journals so<br>
* that the timer isn'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->framebuffer);<br>
<br>
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_BATCHING)))<br>
g_print ("BATCHING: journal len = %d\n", journal->entries->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->framebuffer,<br>
+ journal->framebuffer,<br>
COGL_FRAMEBUFFER_STATE_ALL &<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->journal_flush_attributes_array;<br>
<br>
- modelview_stack = _cogl_framebuffer_get_modelview_stack (framebuffer);<br>
+ modelview_stack =<br>
+ _cogl_framebuffer_get_modelview_stack (journal->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->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'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't have to rely on the global framebuffer stack */<br>
+ removed when the journal is flushed */<br>
if (journal->vertices->len == 0)<br>
- journal->framebuffer = cogl_object_ref (cogl_get_draw_framebuffer ());<br>
+ cogl_object_ref (journal->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's given to GL so we<br>
@@ -1611,13 +1610,8 @@ _cogl_journal_log_quad (CoglJournal *journal,<br>
add_framebuffer_deps_cb,<br>
journal->framebuffer);<br>
<br>
- /* XXX: It doesn'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->framebuffer reference would seem nicer here but<br>
- * the reason we don'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->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>