cogl-vertex-attribute: Add flags to _cogl_draw_vertex_attributes_array

There is an internal version of cogl_draw_vertex_attributes_array
which previously just bypassed the framebuffer flushing, journal
flushing and pipeline validation so that it could be used to draw the
journal. This patch generalises the function so that it takes a set of
flags to specify which parts to flush. The public version of the
function now just calls the internal version with the flags set to
0. The '_real' version of the function has now been merged into the
internal version of the function because it was only called in one
place. This simplifies the code somewhat. The common code which
flushed the various state has been moved to a separate function. The
indexed versions of the functions have had a similar treatment.

http://bugzilla.clutter-project.org/show_bug.cgi?id=2481
This commit is contained in:
Neil Roberts 2010-12-14 14:24:17 +00:00
parent 4a7dbc0e4e
commit a847289850
5 changed files with 102 additions and 119 deletions

View File

@ -233,6 +233,10 @@ _cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start,
{ {
CoglJournalFlushState *state = data; CoglJournalFlushState *state = data;
CoglVertexAttribute **attributes; CoglVertexAttribute **attributes;
static const CoglDrawFlags draw_flags = (COGL_DRAW_SKIP_JOURNAL_FLUSH |
COGL_DRAW_SKIP_PIPELINE_VALIDATION |
COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH);
COGL_STATIC_TIMER (time_flush_modelview_and_entries, COGL_STATIC_TIMER (time_flush_modelview_and_entries,
"flush: pipeline+entries", /* parent */ "flush: pipeline+entries", /* parent */
"flush: modelview+entries", "flush: modelview+entries",
@ -262,7 +266,8 @@ _cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start,
/* XXX: it's rather evil that we sneak in the GL_QUADS enum here... */ /* XXX: it's rather evil that we sneak in the GL_QUADS enum here... */
_cogl_draw_vertex_attributes_array (GL_QUADS, _cogl_draw_vertex_attributes_array (GL_QUADS,
state->current_vertex, batch_len * 4, state->current_vertex, batch_len * 4,
attributes); attributes,
draw_flags);
#else /* HAVE_COGL_GL */ #else /* HAVE_COGL_GL */
if (batch_len > 1) if (batch_len > 1)
@ -271,13 +276,16 @@ _cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start,
state->current_vertex * 6 / 4, state->current_vertex * 6 / 4,
batch_len * 6, batch_len * 6,
state->indices, state->indices,
attributes); attributes,
draw_flags);
} }
else else
{ {
_cogl_draw_vertex_attributes_array (COGL_VERTICES_MODE_TRIANGLE_FAN, _cogl_draw_vertex_attributes_array (COGL_VERTICES_MODE_TRIANGLE_FAN,
state->current_vertex, 4, state->current_vertex, 4,
attributes); attributes,
draw_flags);
} }
#endif #endif
@ -322,7 +330,8 @@ _cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start,
for (i = 0; i < batch_len; i++) for (i = 0; i < batch_len; i++)
_cogl_draw_vertex_attributes_array (COGL_VERTICES_MODE_LINE_LOOP, _cogl_draw_vertex_attributes_array (COGL_VERTICES_MODE_LINE_LOOP,
4 * i + state->current_vertex, 4, 4 * i + state->current_vertex, 4,
loop_attributes); loop_attributes,
draw_flags);
/* Go to the next color */ /* Go to the next color */
do do

View File

@ -943,7 +943,11 @@ _cogl_rectangle_immediate (float x_1,
_cogl_draw_vertex_attributes_array (COGL_VERTICES_MODE_TRIANGLE_STRIP, _cogl_draw_vertex_attributes_array (COGL_VERTICES_MODE_TRIANGLE_STRIP,
0, /* first_index */ 0, /* first_index */
4, /* n_vertices */ 4, /* n_vertices */
attributes); attributes,
COGL_DRAW_SKIP_JOURNAL_FLUSH |
COGL_DRAW_SKIP_PIPELINE_VALIDATION |
COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH);
cogl_object_unref (attributes[0]); cogl_object_unref (attributes[0]);
cogl_object_unref (vertex_array); cogl_object_unref (vertex_array);

View File

@ -57,6 +57,13 @@ struct _CoglVertexAttribute
int immutable_ref; int immutable_ref;
}; };
typedef enum
{
COGL_DRAW_SKIP_JOURNAL_FLUSH = 1 << 0,
COGL_DRAW_SKIP_PIPELINE_VALIDATION = 1 << 1,
COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH = 1 << 2
} CoglDrawFlags;
CoglVertexAttribute * CoglVertexAttribute *
_cogl_vertex_attribute_immutable_ref (CoglVertexAttribute *vertex_attribute); _cogl_vertex_attribute_immutable_ref (CoglVertexAttribute *vertex_attribute);
@ -67,14 +74,16 @@ void
_cogl_draw_vertex_attributes_array (CoglVerticesMode mode, _cogl_draw_vertex_attributes_array (CoglVerticesMode mode,
int first_vertex, int first_vertex,
int n_vertices, int n_vertices,
CoglVertexAttribute **attributes); CoglVertexAttribute **attributes,
CoglDrawFlags flags);
void void
_cogl_draw_indexed_vertex_attributes_array (CoglVerticesMode mode, _cogl_draw_indexed_vertex_attributes_array (CoglVerticesMode mode,
int first_vertex, int first_vertex,
int n_vertices, int n_vertices,
CoglIndices *indices, CoglIndices *indices,
CoglVertexAttribute **attributes); CoglVertexAttribute **attributes,
CoglDrawFlags flags);
void void
_cogl_vertex_attribute_disable_cached_arrays (void); _cogl_vertex_attribute_disable_cached_arrays (void);

View File

@ -1028,7 +1028,11 @@ draw_wireframe (CoglVerticesMode mode,
_cogl_draw_vertex_attributes_array (COGL_VERTICES_MODE_LINES, _cogl_draw_vertex_attributes_array (COGL_VERTICES_MODE_LINES,
0, 0,
n_line_vertices, n_line_vertices,
wire_attribute); wire_attribute,
COGL_DRAW_SKIP_JOURNAL_FLUSH |
COGL_DRAW_SKIP_PIPELINE_VALIDATION |
COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH);
cogl_debug_flags |= COGL_DEBUG_WIREFRAME; cogl_debug_flags |= COGL_DEBUG_WIREFRAME;
cogl_pop_source (); cogl_pop_source ();
@ -1038,13 +1042,47 @@ draw_wireframe (CoglVerticesMode mode,
#endif #endif
static void static void
_cogl_draw_vertex_attributes_array_real (CoglVerticesMode mode, flush_state (CoglDrawFlags flags,
ValidateLayerState *state)
{
if (!(flags & COGL_DRAW_SKIP_JOURNAL_FLUSH))
_cogl_journal_flush ();
state->unit = 0;
state->options.flags = 0;
state->fallback_layers = 0;
if (!(flags & COGL_DRAW_SKIP_PIPELINE_VALIDATION))
cogl_pipeline_foreach_layer (cogl_get_source (),
validate_layer_cb,
state);
/* NB: _cogl_framebuffer_flush_state may disrupt various state (such
* as the pipeline state) when flushing the clip stack, so should
* always be done first when preparing to draw. We need to do this
* before setting up the array pointers because setting up the clip
* stack can cause some drawing which would change the array
* pointers. */
if (!(flags & COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH))
_cogl_framebuffer_flush_state (_cogl_get_framebuffer (), 0);
}
/* This can be called directly by the CoglJournal to draw attributes
* skipping the implicit journal flush, the framebuffer flush and
* pipeline validation. */
void
_cogl_draw_vertex_attributes_array (CoglVerticesMode mode,
int first_vertex, int first_vertex,
int n_vertices, int n_vertices,
CoglVertexAttribute **attributes, CoglVertexAttribute **attributes,
ValidateLayerState *state) CoglDrawFlags flags)
{ {
CoglPipeline *source = enable_gl_state (attributes, state); ValidateLayerState state;
CoglPipeline *source;
flush_state (flags, &state);
source = enable_gl_state (attributes, &state);
GE (glDrawArrays ((GLenum)mode, first_vertex, n_vertices)); GE (glDrawArrays ((GLenum)mode, first_vertex, n_vertices));
@ -1058,55 +1096,15 @@ _cogl_draw_vertex_attributes_array_real (CoglVerticesMode mode,
#endif #endif
} }
/* This can be used by the CoglJournal to draw attributes skipping the
* implicit journal flush, the framebuffer flush and pipeline
* validation. */
void
_cogl_draw_vertex_attributes_array (CoglVerticesMode mode,
int first_vertex,
int n_vertices,
CoglVertexAttribute **attributes)
{
ValidateLayerState state;
state.unit = 0;
state.options.flags = 0;
state.fallback_layers = 0;
_cogl_draw_vertex_attributes_array_real (mode, first_vertex, n_vertices,
attributes, &state);
}
void void
cogl_draw_vertex_attributes_array (CoglVerticesMode mode, cogl_draw_vertex_attributes_array (CoglVerticesMode mode,
int first_vertex, int first_vertex,
int n_vertices, int n_vertices,
CoglVertexAttribute **attributes) CoglVertexAttribute **attributes)
{ {
ValidateLayerState state; _cogl_draw_vertex_attributes_array (mode, first_vertex,
n_vertices, attributes,
_COGL_GET_CONTEXT (ctx, NO_RETVAL); 0 /* no flags */);
_cogl_journal_flush ();
state.unit = 0;
state.options.flags = 0;
state.fallback_layers = 0;
cogl_pipeline_foreach_layer (cogl_get_source (),
validate_layer_cb,
&state);
/* NB: _cogl_framebuffer_flush_state may disrupt various state (such
* as the pipeline state) when flushing the clip stack, so should
* always be done first when preparing to draw. We need to do this
* before setting up the array pointers because setting up the clip
* stack can cause some drawing which would change the array
* pointers. */
_cogl_framebuffer_flush_state (_cogl_get_framebuffer (), 0);
_cogl_draw_vertex_attributes_array_real (mode, first_vertex, n_vertices,
attributes, &state);
} }
void void
@ -1153,15 +1151,16 @@ sizeof_index_type (CoglIndicesType type)
g_return_val_if_reached (0); g_return_val_if_reached (0);
} }
static void void
_cogl_draw_indexed_vertex_attributes_array_real (CoglVerticesMode mode, _cogl_draw_indexed_vertex_attributes_array (CoglVerticesMode mode,
int first_vertex, int first_vertex,
int n_vertices, int n_vertices,
CoglIndices *indices, CoglIndices *indices,
CoglVertexAttribute **attributes, CoglVertexAttribute **attributes,
ValidateLayerState *state) CoglDrawFlags flags)
{ {
CoglPipeline *source = enable_gl_state (attributes, state); ValidateLayerState state;
CoglPipeline *source;
CoglBuffer *buffer; CoglBuffer *buffer;
void *base; void *base;
size_t array_offset; size_t array_offset;
@ -1170,6 +1169,10 @@ _cogl_draw_indexed_vertex_attributes_array_real (CoglVerticesMode mode,
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
flush_state (flags, &state);
source = enable_gl_state (attributes, &state);
buffer = COGL_BUFFER (cogl_indices_get_array (indices)); buffer = COGL_BUFFER (cogl_indices_get_array (indices));
base = _cogl_buffer_bind (buffer, COGL_BUFFER_BIND_TARGET_INDEX_ARRAY); base = _cogl_buffer_bind (buffer, COGL_BUFFER_BIND_TARGET_INDEX_ARRAY);
array_offset = cogl_indices_get_offset (indices); array_offset = cogl_indices_get_offset (indices);
@ -1205,27 +1208,6 @@ _cogl_draw_indexed_vertex_attributes_array_real (CoglVerticesMode mode,
#endif #endif
} }
void
_cogl_draw_indexed_vertex_attributes_array (CoglVerticesMode mode,
int first_vertex,
int n_vertices,
CoglIndices *indices,
CoglVertexAttribute **attributes)
{
ValidateLayerState state;
state.unit = 0;
state.options.flags = 0;
state.fallback_layers = 0;
_cogl_draw_indexed_vertex_attributes_array_real (mode,
first_vertex,
n_vertices,
indices,
attributes,
&state);
}
void void
cogl_draw_indexed_vertex_attributes_array (CoglVerticesMode mode, cogl_draw_indexed_vertex_attributes_array (CoglVerticesMode mode,
int first_vertex, int first_vertex,
@ -1233,34 +1215,9 @@ cogl_draw_indexed_vertex_attributes_array (CoglVerticesMode mode,
CoglIndices *indices, CoglIndices *indices,
CoglVertexAttribute **attributes) CoglVertexAttribute **attributes)
{ {
ValidateLayerState state; _cogl_draw_indexed_vertex_attributes_array (mode, first_vertex,
n_vertices, indices, attributes,
_COGL_GET_CONTEXT (ctx, NO_RETVAL); 0 /* no flags */);
_cogl_journal_flush ();
state.unit = 0;
state.options.flags = 0;
state.fallback_layers = 0;
cogl_pipeline_foreach_layer (cogl_get_source (),
validate_layer_cb,
&state);
/* NB: _cogl_framebuffer_flush_state may disrupt various state (such
* as the pipeline state) when flushing the clip stack, so should
* always be done first when preparing to draw. We need to do this
* before setting up the array pointers because setting up the clip
* stack can cause some drawing which would change the array
* pointers. */
_cogl_framebuffer_flush_state (_cogl_get_framebuffer (), 0);
_cogl_draw_indexed_vertex_attributes_array_real (mode,
first_vertex,
n_vertices,
indices,
attributes,
&state);
} }
void void

View File

@ -338,11 +338,15 @@ _cogl_path_fill_nodes (CoglPath *path)
_cogl_path_build_fill_vbo (path); _cogl_path_build_fill_vbo (path);
_cogl_draw_indexed_vertex_attributes_array (COGL_VERTICES_MODE_TRIANGLES, _cogl_draw_indexed_vertex_attributes_array
(COGL_VERTICES_MODE_TRIANGLES,
0, /* first_vertex */ 0, /* first_vertex */
path->data->fill_vbo_n_indices, path->data->fill_vbo_n_indices,
path->data->fill_vbo_indices, path->data->fill_vbo_indices,
path->data->fill_vbo_attributes); path->data->fill_vbo_attributes,
COGL_DRAW_SKIP_JOURNAL_FLUSH |
COGL_DRAW_SKIP_PIPELINE_VALIDATION |
COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH);
} }
void void