cogl: remove _cogl_material_flush_gl_state flush options
Since cogl_material_copy should now be cheap to use we can simplify how we handle fallbacks and wrap mode overrides etc by simply copying the original material and making our override changes on the new material. This avoids the need for a sideband state structure that has been growing in size and makes flushing material state more complex. Note the plan is to eventually use weak materials for these override materials and attach these as private data to the original materials so we aren't making so many one-shot materials.
This commit is contained in:
parent
1cc3ae6944
commit
3979de6982
9 changed files with 153 additions and 95 deletions
|
@ -176,7 +176,7 @@ cogl_create_context (void)
|
|||
default_texture_data);
|
||||
|
||||
cogl_set_source (_context->simple_material);
|
||||
_cogl_material_flush_gl_state (_context->source_material, NULL);
|
||||
_cogl_material_flush_gl_state (_context->source_material, FALSE);
|
||||
_cogl_enable (enable_flags);
|
||||
_cogl_flush_face_winding ();
|
||||
|
||||
|
|
|
@ -33,7 +33,6 @@ typedef struct _CoglJournalEntry
|
|||
{
|
||||
CoglHandle material;
|
||||
int n_layers;
|
||||
CoglMaterialFlushOptions flush_options;
|
||||
CoglMatrix model_view;
|
||||
/* XXX: These entries are pretty big now considering the padding in
|
||||
* CoglMaterialFlushOptions and CoglMatrix, so we might need to optimize this
|
||||
|
|
|
@ -262,7 +262,7 @@ _cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start,
|
|||
(ctxt->journal_rectangles_color & 4) ?
|
||||
color_intensity : 0,
|
||||
0xff);
|
||||
_cogl_material_flush_gl_state (outline, NULL);
|
||||
_cogl_material_flush_gl_state (outline, FALSE);
|
||||
_cogl_enable (COGL_ENABLE_VERTEX_ARRAY);
|
||||
for (i = 0; i < batch_len; i++)
|
||||
GE( glDrawArrays (GL_LINE_LOOP, 4 * i + state->vertex_offset, 4) );
|
||||
|
@ -315,8 +315,7 @@ _cogl_journal_flush_material_and_entries (CoglJournalEntry *batch_start,
|
|||
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_BATCHING))
|
||||
g_print ("BATCHING: material batch len = %d\n", batch_len);
|
||||
|
||||
_cogl_material_flush_gl_state (batch_start->material,
|
||||
&batch_start->flush_options);
|
||||
_cogl_material_flush_gl_state (batch_start->material, TRUE);
|
||||
|
||||
if (ctx->enable_backface_culling)
|
||||
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
|
||||
|
@ -350,9 +349,9 @@ compare_entry_materials (CoglJournalEntry *entry0, CoglJournalEntry *entry1)
|
|||
* that we that we are able to batch the 90% common cases, but may not
|
||||
* look at less common differences. */
|
||||
if (_cogl_material_equal (entry0->material,
|
||||
&entry0->flush_options,
|
||||
NULL,
|
||||
entry1->material,
|
||||
&entry1->flush_options,
|
||||
NULL,
|
||||
TRUE))
|
||||
return TRUE;
|
||||
else
|
||||
|
@ -670,6 +669,8 @@ _cogl_journal_log_quad (const float *position,
|
|||
int next_entry;
|
||||
guint32 disable_layers;
|
||||
CoglJournalEntry *entry;
|
||||
CoglHandle source;
|
||||
CoglMaterialFlushOptions flush_options;
|
||||
COGL_STATIC_TIMER (log_timer,
|
||||
"Mainloop", /* parent */
|
||||
"Journal Log",
|
||||
|
@ -786,36 +787,53 @@ _cogl_journal_log_quad (const float *position,
|
|||
g_array_set_size (ctx->journal, next_entry + 1);
|
||||
entry = &g_array_index (ctx->journal, CoglJournalEntry, next_entry);
|
||||
|
||||
disable_layers = (1 << n_layers) - 1;
|
||||
disable_layers = ~disable_layers;
|
||||
entry->n_layers = n_layers;
|
||||
|
||||
source = material;
|
||||
|
||||
if (G_UNLIKELY (ctx->legacy_state_set))
|
||||
{
|
||||
material = cogl_material_copy (material);
|
||||
_cogl_material_apply_legacy_state (material);
|
||||
entry->material = _cogl_material_journal_ref (material);
|
||||
cogl_handle_unref (material);
|
||||
source = cogl_material_copy (material);
|
||||
_cogl_material_apply_legacy_state (source);
|
||||
}
|
||||
else
|
||||
entry->material = _cogl_material_journal_ref (material);
|
||||
|
||||
entry->n_layers = n_layers;
|
||||
entry->flush_options.flags =
|
||||
COGL_MATERIAL_FLUSH_FALLBACK_MASK |
|
||||
COGL_MATERIAL_FLUSH_DISABLE_MASK |
|
||||
COGL_MATERIAL_FLUSH_SKIP_GL_COLOR;
|
||||
entry->flush_options.fallback_layers = fallback_layers;
|
||||
entry->flush_options.disable_layers = disable_layers;
|
||||
flush_options.flags = COGL_MATERIAL_FLUSH_SKIP_GL_COLOR;
|
||||
if (G_UNLIKELY (cogl_material_get_n_layers (material) != n_layers))
|
||||
{
|
||||
disable_layers = (1 << n_layers) - 1;
|
||||
disable_layers = ~disable_layers;
|
||||
flush_options.disable_layers = disable_layers;
|
||||
flush_options.flags |= COGL_MATERIAL_FLUSH_DISABLE_MASK;
|
||||
}
|
||||
if (G_UNLIKELY (fallback_layers))
|
||||
{
|
||||
flush_options.fallback_layers = fallback_layers;
|
||||
flush_options.flags |= COGL_MATERIAL_FLUSH_FALLBACK_MASK;
|
||||
}
|
||||
if (G_UNLIKELY (layer0_override_texture))
|
||||
{
|
||||
flush_options.flags |= COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE;
|
||||
flush_options.layer0_override_texture = layer0_override_texture;
|
||||
}
|
||||
if (wrap_mode_overrides)
|
||||
{
|
||||
entry->flush_options.flags |= COGL_MATERIAL_FLUSH_WRAP_MODE_OVERRIDES;
|
||||
entry->flush_options.wrap_mode_overrides = *wrap_mode_overrides;
|
||||
flush_options.flags |= COGL_MATERIAL_FLUSH_WRAP_MODE_OVERRIDES;
|
||||
flush_options.wrap_mode_overrides = *wrap_mode_overrides;
|
||||
}
|
||||
if (layer0_override_texture)
|
||||
|
||||
if (G_UNLIKELY (flush_options.flags))
|
||||
{
|
||||
entry->flush_options.flags |= COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE;
|
||||
entry->flush_options.layer0_override_texture = layer0_override_texture;
|
||||
/* If we haven't already created a derived material... */
|
||||
if (source == material)
|
||||
source = cogl_material_copy (material);
|
||||
_cogl_material_apply_overrides (source, &flush_options);
|
||||
}
|
||||
|
||||
entry->material = _cogl_material_journal_ref (source);
|
||||
|
||||
if (G_UNLIKELY (source != material))
|
||||
cogl_handle_unref (source);
|
||||
|
||||
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM))
|
||||
cogl_get_modelview_matrix (&entry->model_view);
|
||||
|
||||
|
|
|
@ -684,7 +684,7 @@ _cogl_material_get_colorubv (CoglHandle handle,
|
|||
|
||||
void
|
||||
_cogl_material_flush_gl_state (CoglHandle material,
|
||||
CoglMaterialFlushOptions *options);
|
||||
gboolean skip_gl_state);
|
||||
|
||||
gboolean
|
||||
_cogl_material_equal (CoglHandle material0_handle,
|
||||
|
@ -725,6 +725,10 @@ _cogl_material_apply_legacy_state (CoglHandle handle);
|
|||
void
|
||||
_cogl_gl_use_program_wrapper (GLuint program);
|
||||
|
||||
void
|
||||
_cogl_material_apply_overrides (CoglMaterial *material,
|
||||
CoglMaterialFlushOptions *options);
|
||||
|
||||
CoglMaterialBlendEnable
|
||||
_cogl_material_get_blend_enabled (CoglHandle handle);
|
||||
|
||||
|
|
|
@ -2475,7 +2475,7 @@ override_layer_texture_cb (CoglMaterialLayer *layer, void *user_data)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
_cogl_material_apply_overrides (CoglMaterial *material,
|
||||
CoglMaterialFlushOptions *options)
|
||||
{
|
||||
|
@ -6401,11 +6401,9 @@ backend_add_layer_cb (CoglMaterialLayer *layer,
|
|||
*/
|
||||
void
|
||||
_cogl_material_flush_gl_state (CoglHandle handle,
|
||||
CoglMaterialFlushOptions *options)
|
||||
gboolean skip_gl_color)
|
||||
{
|
||||
CoglMaterial *material;
|
||||
gboolean material_overriden;
|
||||
gboolean skip_gl_color = FALSE;
|
||||
CoglMaterial *material = COGL_MATERIAL (handle);
|
||||
unsigned long materials_difference;
|
||||
int n_layers;
|
||||
unsigned long *layer_differences;
|
||||
|
@ -6422,33 +6420,6 @@ _cogl_material_flush_gl_state (CoglHandle handle,
|
|||
|
||||
COGL_TIMER_START (_cogl_uprof_context, material_flush_timer);
|
||||
|
||||
if (G_UNLIKELY (options &&
|
||||
(options->flags & ~COGL_MATERIAL_FLUSH_SKIP_GL_COLOR)))
|
||||
{
|
||||
/* Create a oneshot material to handle the overrides.
|
||||
*
|
||||
* XXX: Note this is a stop-gap-solution: We are aiming to
|
||||
* remove the overrides mechanism and move code like this out
|
||||
* into the primitives code.
|
||||
*
|
||||
* Overrides were originally necessitated by the previously
|
||||
* large cost of creating derived material, but they made things
|
||||
* more complex and also introduced a limit of 32 layers.
|
||||
*
|
||||
* Although creating derived materials is now much cheaper it
|
||||
* would be much better for primitives APIs to cache these
|
||||
* derived materials as private data on the original material.
|
||||
*/
|
||||
material = cogl_material_copy (handle);
|
||||
_cogl_material_apply_overrides (material, options);
|
||||
material_overriden = TRUE;
|
||||
}
|
||||
else
|
||||
material = COGL_MATERIAL (handle);
|
||||
|
||||
if (options && options->flags & COGL_MATERIAL_FLUSH_SKIP_GL_COLOR)
|
||||
skip_gl_color = TRUE;
|
||||
|
||||
if (ctx->current_material == material)
|
||||
materials_difference = ctx->current_material_changes_since_flush;
|
||||
else if (ctx->current_material)
|
||||
|
@ -6590,9 +6561,6 @@ _cogl_material_flush_gl_state (CoglHandle handle,
|
|||
unit1->dirty_gl_texture = FALSE;
|
||||
}
|
||||
|
||||
if (material_overriden)
|
||||
cogl_handle_unref (material);
|
||||
|
||||
COGL_TIMER_STOP (_cogl_uprof_context, material_flush_timer);
|
||||
}
|
||||
|
||||
|
|
|
@ -131,7 +131,6 @@ _cogl_path_stroke_nodes (void)
|
|||
unsigned int path_start = 0;
|
||||
unsigned long enable_flags = COGL_ENABLE_VERTEX_ARRAY;
|
||||
CoglPathData *data;
|
||||
CoglMaterialFlushOptions options;
|
||||
CoglHandle source;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
@ -147,10 +146,6 @@ _cogl_path_stroke_nodes (void)
|
|||
|
||||
_cogl_enable (enable_flags);
|
||||
|
||||
options.flags = COGL_MATERIAL_FLUSH_DISABLE_MASK;
|
||||
/* disable all texture layers */
|
||||
options.disable_layers = (guint32)~0;
|
||||
|
||||
if (G_UNLIKELY (ctx->legacy_state_set))
|
||||
{
|
||||
source = cogl_material_copy (ctx->source_material);
|
||||
|
@ -159,7 +154,20 @@ _cogl_path_stroke_nodes (void)
|
|||
else
|
||||
source = ctx->source_material;
|
||||
|
||||
_cogl_material_flush_gl_state (source, &options);
|
||||
if (cogl_material_get_n_layers (source) != 0)
|
||||
{
|
||||
CoglMaterialFlushOptions options;
|
||||
options.flags = COGL_MATERIAL_FLUSH_DISABLE_MASK;
|
||||
/* disable all texture layers */
|
||||
options.disable_layers = (guint32)~0;
|
||||
|
||||
/* If we haven't already created a derived material... */
|
||||
if (source == ctx->source_material)
|
||||
source = cogl_material_copy (ctx->source_material);
|
||||
_cogl_material_apply_overrides (source, &options);
|
||||
}
|
||||
|
||||
_cogl_material_flush_gl_state (source, FALSE);
|
||||
|
||||
while (path_start < data->path_nodes->len)
|
||||
{
|
||||
|
@ -231,7 +239,7 @@ _cogl_add_path_to_stencil_buffer (CoglPath *path,
|
|||
prev_source = cogl_object_ref (ctx->source_material);
|
||||
cogl_set_source (ctx->stencil_material);
|
||||
|
||||
_cogl_material_flush_gl_state (ctx->source_material, NULL);
|
||||
_cogl_material_flush_gl_state (ctx->source_material, FALSE);
|
||||
|
||||
_cogl_enable (enable_flags);
|
||||
|
||||
|
@ -389,7 +397,7 @@ _cogl_path_fill_nodes_scanlines (CoglPathNode *path,
|
|||
else
|
||||
source = ctx->source_material;
|
||||
|
||||
_cogl_material_flush_gl_state (ctx->source_material, NULL);
|
||||
_cogl_material_flush_gl_state (source, FALSE);
|
||||
|
||||
_cogl_enable (COGL_ENABLE_VERTEX_ARRAY);
|
||||
|
||||
|
|
|
@ -865,12 +865,18 @@ draw_polygon_sub_texture_cb (CoglHandle tex_handle,
|
|||
v += state->stride;
|
||||
}
|
||||
|
||||
if (G_UNLIKELY (ctx->legacy_state_set))
|
||||
{
|
||||
source = cogl_material_copy (ctx->source_material);
|
||||
_cogl_material_apply_legacy_state (source);
|
||||
}
|
||||
else
|
||||
source = ctx->source_material;
|
||||
|
||||
options.flags =
|
||||
COGL_MATERIAL_FLUSH_DISABLE_MASK |
|
||||
COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE |
|
||||
COGL_MATERIAL_FLUSH_WRAP_MODE_OVERRIDES;
|
||||
/* disable all except the first layer */
|
||||
options.disable_layers = (guint32)~1;
|
||||
|
||||
options.layer0_override_texture = gl_handle;
|
||||
|
||||
/* Override the wrapping mode on all of the slices to use a
|
||||
|
@ -887,15 +893,19 @@ draw_polygon_sub_texture_cb (CoglHandle tex_handle,
|
|||
options.wrap_mode_overrides.values[0].t =
|
||||
COGL_MATERIAL_WRAP_MODE_OVERRIDE_CLAMP_TO_BORDER;
|
||||
|
||||
if (G_UNLIKELY (ctx->legacy_state_set))
|
||||
if (cogl_material_get_n_layers (source) != 1)
|
||||
{
|
||||
source = cogl_material_copy (ctx->source_material);
|
||||
_cogl_material_apply_legacy_state (source);
|
||||
/* disable all except the first layer */
|
||||
options.disable_layers = (guint32)~1;
|
||||
options.flags |= COGL_MATERIAL_FLUSH_DISABLE_MASK;
|
||||
}
|
||||
else
|
||||
source = ctx->source_material;
|
||||
|
||||
_cogl_material_flush_gl_state (source, &options);
|
||||
/* If we haven't already created a derived material... */
|
||||
if (source == ctx->source_material)
|
||||
source = cogl_material_copy (ctx->source_material);
|
||||
_cogl_material_apply_overrides (source, &options);
|
||||
|
||||
_cogl_material_flush_gl_state (source, FALSE);
|
||||
|
||||
GE (glDrawArrays (GL_TRIANGLE_FAN, 0, state->n_vertices));
|
||||
|
||||
|
@ -1030,16 +1040,6 @@ _cogl_multitexture_polygon_single_primitive (const CoglTextureVertex *vertices,
|
|||
}
|
||||
}
|
||||
|
||||
options.flags = COGL_MATERIAL_FLUSH_FALLBACK_MASK;
|
||||
if (use_color)
|
||||
options.flags |= COGL_MATERIAL_FLUSH_SKIP_GL_COLOR;
|
||||
options.fallback_layers = fallback_layers;
|
||||
if (wrap_mode_overrides)
|
||||
{
|
||||
options.flags |= COGL_MATERIAL_FLUSH_WRAP_MODE_OVERRIDES;
|
||||
options.wrap_mode_overrides = *wrap_mode_overrides;
|
||||
}
|
||||
|
||||
if (G_UNLIKELY (ctx->legacy_state_set))
|
||||
{
|
||||
source = cogl_material_copy (ctx->source_material);
|
||||
|
@ -1048,7 +1048,27 @@ _cogl_multitexture_polygon_single_primitive (const CoglTextureVertex *vertices,
|
|||
else
|
||||
source = ctx->source_material;
|
||||
|
||||
_cogl_material_flush_gl_state (source, &options);
|
||||
options.flags = 0;
|
||||
|
||||
if (G_UNLIKELY (fallback_layers))
|
||||
{
|
||||
options.flags |= COGL_MATERIAL_FLUSH_FALLBACK_MASK;
|
||||
options.fallback_layers = fallback_layers;
|
||||
}
|
||||
if (wrap_mode_overrides)
|
||||
{
|
||||
options.flags |= COGL_MATERIAL_FLUSH_WRAP_MODE_OVERRIDES;
|
||||
options.wrap_mode_overrides = *wrap_mode_overrides;
|
||||
}
|
||||
if (options.flags)
|
||||
{
|
||||
/* If we haven't already created a derived material... */
|
||||
if (source == ctx->source_material)
|
||||
source = cogl_material_copy (ctx->source_material);
|
||||
_cogl_material_apply_overrides (source, &options);
|
||||
}
|
||||
|
||||
_cogl_material_flush_gl_state (source, use_color);
|
||||
|
||||
GE (glDrawArrays (GL_TRIANGLE_FAN, 0, n_vertices));
|
||||
|
||||
|
|
|
@ -1520,6 +1520,7 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
|
|||
const GList *layers;
|
||||
guint32 fallback_layers = 0;
|
||||
int i;
|
||||
gboolean skip_gl_color = FALSE;
|
||||
CoglMaterialFlushOptions options;
|
||||
CoglHandle source;
|
||||
|
||||
|
@ -1588,6 +1589,7 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
|
|||
COGL_MATERIAL_BLEND_ENABLE_ENABLED;
|
||||
source = cogl_material_copy (ctx->source_material);
|
||||
_cogl_material_set_blend_enabled (source, blend_enable);
|
||||
skip_gl_color = TRUE;
|
||||
}
|
||||
break;
|
||||
case COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMAL_ARRAY:
|
||||
|
@ -1727,6 +1729,47 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
|
|||
|
||||
options.fallback_layers = fallback_layers;
|
||||
|
||||
if (G_UNLIKELY (options.flags))
|
||||
{
|
||||
/* If we haven't already created a derived material... */
|
||||
if (source == ctx->source_material)
|
||||
source = cogl_material_copy (ctx->source_material);
|
||||
_cogl_material_apply_overrides (source, &options);
|
||||
|
||||
/* TODO:
|
||||
* overrides = cogl_material_get_data (material,
|
||||
* last_overrides_key);
|
||||
* if (overrides)
|
||||
* {
|
||||
* age = cogl_material_get_age (material);
|
||||
* XXX: actually we also need to check for legacy_state
|
||||
* and blending overrides for use of glColorPointer...
|
||||
* if (overrides->ags != age ||
|
||||
* memcmp (&overrides->options, &options,
|
||||
* sizeof (options) != 0)
|
||||
* {
|
||||
* cogl_handle_unref (overrides->weak_material);
|
||||
* g_slice_free (Overrides, overrides);
|
||||
* overrides = NULL;
|
||||
* }
|
||||
* }
|
||||
* if (!overrides)
|
||||
* {
|
||||
* overrides = g_slice_new (Overrides);
|
||||
* overrides->weak_material =
|
||||
* cogl_material_weak_copy (ctx->source_material);
|
||||
* _cogl_material_apply_overrides (overrides->weak_material,
|
||||
* &options);
|
||||
*
|
||||
* cogl_material_set_data (material, last_overrides_key,
|
||||
* weak_overrides,
|
||||
* free_overrides_cb,
|
||||
* NULL);
|
||||
* }
|
||||
* source = overrides->weak_material;
|
||||
*/
|
||||
}
|
||||
|
||||
if (G_UNLIKELY (ctx->legacy_state_set))
|
||||
{
|
||||
/* If we haven't already created a derived material... */
|
||||
|
@ -1735,7 +1778,7 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
|
|||
_cogl_material_apply_legacy_state (source);
|
||||
}
|
||||
|
||||
_cogl_material_flush_gl_state (source, &options);
|
||||
_cogl_material_flush_gl_state (source, skip_gl_color);
|
||||
|
||||
if (ctx->enable_backface_culling)
|
||||
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
|
||||
|
|
|
@ -816,7 +816,6 @@ _cogl_disable_other_texcoord_arrays (const CoglBitmask *mask)
|
|||
void
|
||||
cogl_begin_gl (void)
|
||||
{
|
||||
CoglMaterialFlushOptions options;
|
||||
unsigned long enable_flags = 0;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
@ -851,8 +850,7 @@ cogl_begin_gl (void)
|
|||
* A user should instead call cogl_set_source_color4ub() before
|
||||
* cogl_begin_gl() to simplify the state flushed.
|
||||
*/
|
||||
options.flags = 0;
|
||||
_cogl_material_flush_gl_state (ctx->source_material, &options);
|
||||
_cogl_material_flush_gl_state (ctx->source_material, FALSE);
|
||||
|
||||
if (ctx->enable_backface_culling)
|
||||
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
|
||||
|
|
Loading…
Reference in a new issue