pipeline: improve real_blend_enable checks
Since _cogl_pipeline_update_blend_enable() can sometimes show up quite high in profiles; instead of calling _cogl_pipeline_update_blend_enable() whenever we change pipeline state that may affect blending we now just set a dirty flag and when we flush a pipeline we check this dirty flag and lazily calculate whether blender really needs to be enabled if it's set. Since it turns out we were too optimistic in assuming most GL drivers would recognize blending with ADD(src,0) is equivalent to disabling GL_BLEND we now check this case ourselves so we can always explicitly disable GL_BLEND if we know we don't need blending. This introduces the idea of an 'unknown_color_alpha' boolean to the pipeline flush code which is set whenever we can't guarantee that the color attribute is opaque. For example this is set whenever a user specifies a color attribute with 4 components when drawing a primitive. This boolean needs to be cached along with every pipeline because pipeline::real_blend_enabled depends on this and so we need to also call _cogl_pipeline_update_blend_enable() if the status of this changes. Incidentally with this patch we now no longer ever use _cogl_pipeline_set_blend_enable() internally. For now the internal api hasn't been removed though since we might want to consider re-purposing it as a public api since it will now not conflict with our own internal state tracking and could provide a more convenient way to disable blending than setting a blend string. Reviewed-by: Neil Roberts <neil@linux.intel.com> (cherry picked from commit ab2ae18f3207514c91fa6fd9f2d3f2ed93a86497)
This commit is contained in:
parent
2ed926120d
commit
8f9151303d
@ -126,5 +126,8 @@ _cogl_flush_attributes_state (CoglFramebuffer *framebuffer,
|
|||||||
CoglAttribute **attributes,
|
CoglAttribute **attributes,
|
||||||
int n_attributes);
|
int n_attributes);
|
||||||
|
|
||||||
|
int
|
||||||
|
_cogl_attribute_get_n_components (CoglAttribute *attribute);
|
||||||
|
|
||||||
#endif /* __COGL_ATTRIBUTE_PRIVATE_H */
|
#endif /* __COGL_ATTRIBUTE_PRIVATE_H */
|
||||||
|
|
||||||
|
@ -657,3 +657,12 @@ _cogl_flush_attributes_state (CoglFramebuffer *framebuffer,
|
|||||||
if (copy)
|
if (copy)
|
||||||
cogl_object_unref (copy);
|
cogl_object_unref (copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_cogl_attribute_get_n_components (CoglAttribute *attribute)
|
||||||
|
{
|
||||||
|
if (attribute->is_buffered)
|
||||||
|
return attribute->d.buffered.n_components;
|
||||||
|
else
|
||||||
|
return attribute->d.constant.boxed.size;
|
||||||
|
}
|
||||||
|
@ -167,7 +167,8 @@ struct _CoglContext
|
|||||||
/* Some simple caching, to minimize state changes... */
|
/* Some simple caching, to minimize state changes... */
|
||||||
CoglPipeline *current_pipeline;
|
CoglPipeline *current_pipeline;
|
||||||
unsigned long current_pipeline_changes_since_flush;
|
unsigned long current_pipeline_changes_since_flush;
|
||||||
CoglBool current_pipeline_skip_gl_color;
|
CoglBool current_pipeline_with_color_attrib;
|
||||||
|
CoglBool current_pipeline_unknown_color_alpha;
|
||||||
unsigned long current_pipeline_age;
|
unsigned long current_pipeline_age;
|
||||||
|
|
||||||
CoglBool gl_blend_enable_cache;
|
CoglBool gl_blend_enable_cache;
|
||||||
|
@ -325,7 +325,7 @@ cogl_context_new (CoglDisplay *display,
|
|||||||
|
|
||||||
context->current_pipeline = NULL;
|
context->current_pipeline = NULL;
|
||||||
context->current_pipeline_changes_since_flush = 0;
|
context->current_pipeline_changes_since_flush = 0;
|
||||||
context->current_pipeline_skip_gl_color = FALSE;
|
context->current_pipeline_with_color_attrib = FALSE;
|
||||||
|
|
||||||
_cogl_bitmask_init (&context->enabled_builtin_attributes);
|
_cogl_bitmask_init (&context->enabled_builtin_attributes);
|
||||||
_cogl_bitmask_init (&context->enable_builtin_attributes_tmp);
|
_cogl_bitmask_init (&context->enable_builtin_attributes_tmp);
|
||||||
|
@ -210,7 +210,7 @@ _cogl_pipeline_set_layer_texture_type (CoglPipeline *pipeline,
|
|||||||
|
|
||||||
changed:
|
changed:
|
||||||
|
|
||||||
_cogl_pipeline_update_blend_enable (pipeline, COGL_PIPELINE_STATE_LAYERS);
|
pipeline->dirty_real_blend_enable = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -289,7 +289,7 @@ _cogl_pipeline_set_layer_texture_data (CoglPipeline *pipeline,
|
|||||||
|
|
||||||
changed:
|
changed:
|
||||||
|
|
||||||
_cogl_pipeline_update_blend_enable (pipeline, COGL_PIPELINE_STATE_LAYERS);
|
pipeline->dirty_real_blend_enable = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1267,7 +1267,7 @@ cogl_pipeline_set_layer_combine (CoglPipeline *pipeline,
|
|||||||
|
|
||||||
changed:
|
changed:
|
||||||
|
|
||||||
_cogl_pipeline_update_blend_enable (pipeline, COGL_PIPELINE_STATE_LAYERS);
|
pipeline->dirty_real_blend_enable = TRUE;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1352,7 +1352,7 @@ cogl_pipeline_set_layer_combine_constant (CoglPipeline *pipeline,
|
|||||||
|
|
||||||
changed:
|
changed:
|
||||||
|
|
||||||
_cogl_pipeline_update_blend_enable (pipeline, COGL_PIPELINE_STATE_LAYERS);
|
pipeline->dirty_real_blend_enable = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -470,6 +470,19 @@ struct _CoglPipeline
|
|||||||
* blending, this holds our final decision */
|
* blending, this holds our final decision */
|
||||||
unsigned int real_blend_enable:1;
|
unsigned int real_blend_enable:1;
|
||||||
|
|
||||||
|
/* Since the code for deciding if blending really needs to be
|
||||||
|
* enabled for a particular pipeline is quite expensive we update
|
||||||
|
* the real_blend_enable flag lazily when flushing a pipeline if
|
||||||
|
* this dirty flag has been set. */
|
||||||
|
unsigned int dirty_real_blend_enable:1;
|
||||||
|
|
||||||
|
/* Whenever a pipeline is flushed we keep track of whether the
|
||||||
|
* pipeline was used with a color attribute where we don't know
|
||||||
|
* whether the colors are opaque. The real_blend_enable state
|
||||||
|
* depends on this, and must be updated whenever this changes (even
|
||||||
|
* if dirty_real_blend_enable isn't set) */
|
||||||
|
unsigned int unknown_color_alpha:1;
|
||||||
|
|
||||||
unsigned int layers_cache_dirty:1;
|
unsigned int layers_cache_dirty:1;
|
||||||
unsigned int deprecated_get_layers_list_dirty:1;
|
unsigned int deprecated_get_layers_list_dirty:1;
|
||||||
|
|
||||||
@ -597,8 +610,9 @@ _cogl_pipeline_pre_change_notify (CoglPipeline *pipeline,
|
|||||||
void
|
void
|
||||||
_cogl_pipeline_prune_redundant_ancestry (CoglPipeline *pipeline);
|
_cogl_pipeline_prune_redundant_ancestry (CoglPipeline *pipeline);
|
||||||
|
|
||||||
void _cogl_pipeline_update_blend_enable (CoglPipeline *pipeline,
|
void
|
||||||
CoglPipelineState changes);
|
_cogl_pipeline_update_real_blend_enable (CoglPipeline *pipeline,
|
||||||
|
CoglBool unknown_color_alpha);
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
@ -835,13 +849,13 @@ _cogl_pipeline_compare_differences (CoglPipeline *pipeline0,
|
|||||||
CoglBool
|
CoglBool
|
||||||
_cogl_pipeline_equal (CoglPipeline *pipeline0,
|
_cogl_pipeline_equal (CoglPipeline *pipeline0,
|
||||||
CoglPipeline *pipeline1,
|
CoglPipeline *pipeline1,
|
||||||
unsigned long differences,
|
unsigned int differences,
|
||||||
unsigned long layer_differences,
|
unsigned long layer_differences,
|
||||||
CoglPipelineEvalFlags flags);
|
CoglPipelineEvalFlags flags);
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
_cogl_pipeline_hash (CoglPipeline *pipeline,
|
_cogl_pipeline_hash (CoglPipeline *pipeline,
|
||||||
unsigned long differences,
|
unsigned int differences,
|
||||||
unsigned long layer_differences,
|
unsigned long layer_differences,
|
||||||
CoglPipelineEvalFlags flags);
|
CoglPipelineEvalFlags flags);
|
||||||
|
|
||||||
|
@ -408,7 +408,7 @@ cogl_pipeline_set_color (CoglPipeline *pipeline,
|
|||||||
_cogl_pipeline_update_authority (pipeline, authority, state,
|
_cogl_pipeline_update_authority (pipeline, authority, state,
|
||||||
_cogl_pipeline_color_equal);
|
_cogl_pipeline_color_equal);
|
||||||
|
|
||||||
_cogl_pipeline_update_blend_enable (pipeline, state);
|
pipeline->dirty_real_blend_enable = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -482,7 +482,7 @@ _cogl_pipeline_set_blend_enabled (CoglPipeline *pipeline,
|
|||||||
_cogl_pipeline_update_authority (pipeline, authority, state,
|
_cogl_pipeline_update_authority (pipeline, authority, state,
|
||||||
_cogl_pipeline_blend_enable_equal);
|
_cogl_pipeline_blend_enable_equal);
|
||||||
|
|
||||||
_cogl_pipeline_update_blend_enable (pipeline, state);
|
pipeline->dirty_real_blend_enable = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -532,7 +532,7 @@ cogl_pipeline_set_ambient (CoglPipeline *pipeline,
|
|||||||
_cogl_pipeline_update_authority (pipeline, authority, state,
|
_cogl_pipeline_update_authority (pipeline, authority, state,
|
||||||
_cogl_pipeline_lighting_state_equal);
|
_cogl_pipeline_lighting_state_equal);
|
||||||
|
|
||||||
_cogl_pipeline_update_blend_enable (pipeline, state);
|
pipeline->dirty_real_blend_enable = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -583,7 +583,7 @@ cogl_pipeline_set_diffuse (CoglPipeline *pipeline,
|
|||||||
_cogl_pipeline_update_authority (pipeline, authority, state,
|
_cogl_pipeline_update_authority (pipeline, authority, state,
|
||||||
_cogl_pipeline_lighting_state_equal);
|
_cogl_pipeline_lighting_state_equal);
|
||||||
|
|
||||||
_cogl_pipeline_update_blend_enable (pipeline, state);
|
pipeline->dirty_real_blend_enable = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -640,7 +640,7 @@ cogl_pipeline_set_specular (CoglPipeline *pipeline, const CoglColor *specular)
|
|||||||
_cogl_pipeline_update_authority (pipeline, authority, state,
|
_cogl_pipeline_update_authority (pipeline, authority, state,
|
||||||
_cogl_pipeline_lighting_state_equal);
|
_cogl_pipeline_lighting_state_equal);
|
||||||
|
|
||||||
_cogl_pipeline_update_blend_enable (pipeline, state);
|
pipeline->dirty_real_blend_enable = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
float
|
float
|
||||||
@ -740,7 +740,7 @@ cogl_pipeline_set_emission (CoglPipeline *pipeline, const CoglColor *emission)
|
|||||||
_cogl_pipeline_update_authority (pipeline, authority, state,
|
_cogl_pipeline_update_authority (pipeline, authority, state,
|
||||||
_cogl_pipeline_lighting_state_equal);
|
_cogl_pipeline_lighting_state_equal);
|
||||||
|
|
||||||
_cogl_pipeline_update_blend_enable (pipeline, state);
|
pipeline->dirty_real_blend_enable = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1008,7 +1008,7 @@ cogl_pipeline_set_blend (CoglPipeline *pipeline,
|
|||||||
_cogl_pipeline_prune_redundant_ancestry (pipeline);
|
_cogl_pipeline_prune_redundant_ancestry (pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
_cogl_pipeline_update_blend_enable (pipeline, state);
|
pipeline->dirty_real_blend_enable = TRUE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -1049,7 +1049,7 @@ cogl_pipeline_set_blend_constant (CoglPipeline *pipeline,
|
|||||||
_cogl_pipeline_update_authority (pipeline, authority, state,
|
_cogl_pipeline_update_authority (pipeline, authority, state,
|
||||||
_cogl_pipeline_blend_state_equal);
|
_cogl_pipeline_blend_state_equal);
|
||||||
|
|
||||||
_cogl_pipeline_update_blend_enable (pipeline, state);
|
pipeline->dirty_real_blend_enable = TRUE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -1126,7 +1126,7 @@ cogl_pipeline_set_user_program (CoglPipeline *pipeline,
|
|||||||
cogl_handle_unref (pipeline->big_state->user_program);
|
cogl_handle_unref (pipeline->big_state->user_program);
|
||||||
pipeline->big_state->user_program = program;
|
pipeline->big_state->user_program = program;
|
||||||
|
|
||||||
_cogl_pipeline_update_blend_enable (pipeline, state);
|
pipeline->dirty_real_blend_enable = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
CoglBool
|
CoglBool
|
||||||
|
@ -740,71 +740,29 @@ layer_has_alpha_cb (CoglPipelineLayer *layer, void *data)
|
|||||||
return !(*has_alpha);
|
return !(*has_alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* NB: If this pipeline returns FALSE that doesn't mean that the
|
||||||
|
* pipeline is definitely opaque, it just means that that the
|
||||||
|
* given changes dont imply transparency.
|
||||||
|
*
|
||||||
|
* If you want to find out of the pipeline is opaque then assuming
|
||||||
|
* this returns FALSE for a set of changes then you can follow
|
||||||
|
* up
|
||||||
|
*/
|
||||||
static CoglBool
|
static CoglBool
|
||||||
_cogl_pipeline_needs_blending_enabled (CoglPipeline *pipeline,
|
_cogl_pipeline_change_implies_transparency (CoglPipeline *pipeline,
|
||||||
unsigned long changes,
|
unsigned int changes,
|
||||||
const CoglColor *override_color)
|
const CoglColor *override_color,
|
||||||
|
CoglBool unknown_color_alpha)
|
||||||
{
|
{
|
||||||
CoglPipeline *enable_authority;
|
|
||||||
CoglPipeline *blend_authority;
|
|
||||||
CoglPipelineBlendState *blend_state;
|
|
||||||
CoglPipelineBlendEnable enabled;
|
|
||||||
unsigned long other_state;
|
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, FALSE);
|
|
||||||
|
|
||||||
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_BLENDING)))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
enable_authority =
|
|
||||||
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_BLEND_ENABLE);
|
|
||||||
|
|
||||||
enabled = enable_authority->blend_enable;
|
|
||||||
if (enabled != COGL_PIPELINE_BLEND_ENABLE_AUTOMATIC)
|
|
||||||
return enabled == COGL_PIPELINE_BLEND_ENABLE_ENABLED ? TRUE : FALSE;
|
|
||||||
|
|
||||||
blend_authority =
|
|
||||||
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_BLEND);
|
|
||||||
|
|
||||||
blend_state = &blend_authority->big_state->blend_state;
|
|
||||||
|
|
||||||
/* We are trying to identify awkward cases that are equivalent to
|
|
||||||
* blending being disable, where the output is simply GL_SRC_COLOR.
|
|
||||||
*
|
|
||||||
* Note: we assume that all OpenGL drivers will identify the simple
|
|
||||||
* case of ADD (ONE, ZERO) as equivalent to blending being disabled.
|
|
||||||
*
|
|
||||||
* We should update this when we add support for more blend
|
|
||||||
* functions...
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined (HAVE_COGL_GLES2) || defined (HAVE_COGL_GL)
|
|
||||||
if (ctx->driver != COGL_DRIVER_GLES1)
|
|
||||||
{
|
|
||||||
/* GLES 1 can't change the function or have separate alpha factors */
|
|
||||||
if (blend_state->blend_equation_rgb != GL_FUNC_ADD ||
|
|
||||||
blend_state->blend_equation_alpha != GL_FUNC_ADD)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
if (blend_state->blend_src_factor_alpha != GL_ONE ||
|
|
||||||
blend_state->blend_dst_factor_alpha != GL_ONE_MINUS_SRC_ALPHA)
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (blend_state->blend_src_factor_rgb != GL_ONE ||
|
|
||||||
blend_state->blend_dst_factor_rgb != GL_ONE_MINUS_SRC_ALPHA)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
/* Given the above constraints, it's now a case of finding any
|
|
||||||
* SRC_ALPHA that != 1 */
|
|
||||||
|
|
||||||
/* In the case of a layer state change we need to check everything
|
/* In the case of a layer state change we need to check everything
|
||||||
* else first since they contribute to the has_alpha status of the
|
* else first since they contribute to the has_alpha status of the
|
||||||
* GL_PREVIOUS layer. */
|
* "PREVIOUS" layer. */
|
||||||
if (changes & COGL_PIPELINE_STATE_LAYERS)
|
if (changes & COGL_PIPELINE_STATE_LAYERS)
|
||||||
changes = COGL_PIPELINE_STATE_AFFECTS_BLENDING;
|
changes = COGL_PIPELINE_STATE_AFFECTS_BLENDING;
|
||||||
|
|
||||||
|
if (unknown_color_alpha)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
if ((override_color && cogl_color_get_alpha_byte (override_color) != 0xff))
|
if ((override_color && cogl_color_get_alpha_byte (override_color) != 0xff))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
@ -878,24 +836,104 @@ _cogl_pipeline_needs_blending_enabled (CoglPipeline *pipeline,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CoglBool
|
||||||
|
_cogl_pipeline_needs_blending_enabled (CoglPipeline *pipeline,
|
||||||
|
unsigned int changes,
|
||||||
|
const CoglColor *override_color,
|
||||||
|
CoglBool unknown_color_alpha)
|
||||||
|
{
|
||||||
|
CoglPipeline *enable_authority;
|
||||||
|
CoglPipeline *blend_authority;
|
||||||
|
CoglPipelineBlendState *blend_state;
|
||||||
|
CoglPipelineBlendEnable enabled;
|
||||||
|
|
||||||
|
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_BLENDING)))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* We unconditionally check the _BLEND_ENABLE state first because
|
||||||
|
* all the other changes are irrelevent if blend_enable != _AUTOMATIC
|
||||||
|
*/
|
||||||
|
enable_authority =
|
||||||
|
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_BLEND_ENABLE);
|
||||||
|
|
||||||
|
enabled = enable_authority->blend_enable;
|
||||||
|
if (enabled != COGL_PIPELINE_BLEND_ENABLE_AUTOMATIC)
|
||||||
|
return enabled == COGL_PIPELINE_BLEND_ENABLE_ENABLED ? TRUE : FALSE;
|
||||||
|
|
||||||
|
blend_authority =
|
||||||
|
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_BLEND);
|
||||||
|
|
||||||
|
blend_state = &blend_authority->big_state->blend_state;
|
||||||
|
|
||||||
|
/* We are trying to identify some cases that are equivalent to
|
||||||
|
* blending being disable, where the output is simply GL_SRC_COLOR.
|
||||||
|
*
|
||||||
|
* Note: we currently only consider a few cases that can be
|
||||||
|
* optimized but there could be opportunities to special case more
|
||||||
|
* blend functions later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* As the most common way that we currently use to effectively
|
||||||
|
* disable blending is to use an equation of
|
||||||
|
* "RGBA=ADD(SRC_COLOR, 0)" that's the first thing we check
|
||||||
|
* for... */
|
||||||
|
if (blend_state->blend_equation_rgb == GL_FUNC_ADD &&
|
||||||
|
blend_state->blend_equation_alpha == GL_FUNC_ADD &&
|
||||||
|
blend_state->blend_src_factor_alpha == GL_ONE &&
|
||||||
|
blend_state->blend_dst_factor_alpha == GL_ZERO)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NB: The default blending equation for Cogl is
|
||||||
|
* "RGBA=ADD(SRC_COLOR, DST_COLOR * (1-SRC_COLOR[A]))"
|
||||||
|
*
|
||||||
|
* Next we check if the default blending equation is being used. If
|
||||||
|
* so then we follow that by looking for cases where SRC_COLOR[A] ==
|
||||||
|
* 1 since that simplifies "DST_COLOR * (1-SRC_COLOR[A])" to 0 which
|
||||||
|
* also effectively requires no blending.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (blend_state->blend_equation_rgb != GL_FUNC_ADD ||
|
||||||
|
blend_state->blend_equation_alpha != GL_FUNC_ADD)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (blend_state->blend_src_factor_alpha != GL_ONE ||
|
||||||
|
blend_state->blend_dst_factor_alpha != GL_ONE_MINUS_SRC_ALPHA)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (blend_state->blend_src_factor_rgb != GL_ONE ||
|
||||||
|
blend_state->blend_dst_factor_rgb != GL_ONE_MINUS_SRC_ALPHA)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* Given the above constraints, it's now a case of finding any
|
||||||
|
* SRC_ALPHA that != 1 */
|
||||||
|
|
||||||
|
if (_cogl_pipeline_change_implies_transparency (pipeline, changes,
|
||||||
|
override_color,
|
||||||
|
unknown_color_alpha))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
/* At this point, considering just the state that has changed it
|
/* At this point, considering just the state that has changed it
|
||||||
* looks like blending isn't needed. If blending was previously
|
* looks like blending isn't needed. If blending was previously
|
||||||
* enabled though it could be that some other state still requires
|
* enabled though it could be that some other state still requires
|
||||||
* that we have blending enabled. In this case we still need to
|
* that we have blending enabled because it implies transparency.
|
||||||
* go and check the other state...
|
* In this case we still need to go and check the other state...
|
||||||
*
|
*
|
||||||
* FIXME: We should explicitly keep track of the mask of state
|
* XXX: We could explicitly keep track of the mask of state groups
|
||||||
* groups that are currently causing blending to be enabled so that
|
* that are currently causing blending to be enabled so that we
|
||||||
* we never have to resort to checking *all* the state and can
|
* never have to resort to checking *all* the state and can instead
|
||||||
* instead always limit the check to those in the mask.
|
* always limit the check to those in the mask.
|
||||||
*/
|
*/
|
||||||
if (pipeline->real_blend_enable)
|
if (pipeline->real_blend_enable)
|
||||||
{
|
{
|
||||||
other_state = COGL_PIPELINE_STATE_AFFECTS_BLENDING & ~changes;
|
unsigned int other_state =
|
||||||
|
COGL_PIPELINE_STATE_AFFECTS_BLENDING & ~changes;
|
||||||
if (other_state &&
|
if (other_state &&
|
||||||
_cogl_pipeline_needs_blending_enabled (pipeline,
|
_cogl_pipeline_change_implies_transparency (pipeline, other_state, NULL, FALSE))
|
||||||
other_state,
|
|
||||||
NULL))
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1066,7 +1104,7 @@ _cogl_pipeline_copy_differences (CoglPipeline *dest,
|
|||||||
*/
|
*/
|
||||||
check_for_blending_change:
|
check_for_blending_change:
|
||||||
if (differences & COGL_PIPELINE_STATE_AFFECTS_BLENDING)
|
if (differences & COGL_PIPELINE_STATE_AFFECTS_BLENDING)
|
||||||
_cogl_pipeline_update_blend_enable (dest, differences);
|
dest->dirty_real_blend_enable = TRUE;
|
||||||
|
|
||||||
dest->differences |= differences;
|
dest->differences |= differences;
|
||||||
}
|
}
|
||||||
@ -1235,7 +1273,8 @@ _cogl_pipeline_pre_change_notify (CoglPipeline *pipeline,
|
|||||||
CoglBool will_need_blending =
|
CoglBool will_need_blending =
|
||||||
_cogl_pipeline_needs_blending_enabled (pipeline,
|
_cogl_pipeline_needs_blending_enabled (pipeline,
|
||||||
change,
|
change,
|
||||||
new_color);
|
new_color,
|
||||||
|
FALSE);
|
||||||
CoglBool blend_enable = pipeline->real_blend_enable ? TRUE : FALSE;
|
CoglBool blend_enable = pipeline->real_blend_enable ? TRUE : FALSE;
|
||||||
|
|
||||||
if (will_need_blending == blend_enable)
|
if (will_need_blending == blend_enable)
|
||||||
@ -1507,29 +1546,51 @@ _cogl_pipeline_try_reverting_layers_authority (CoglPipeline *authority,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_cogl_pipeline_update_blend_enable (CoglPipeline *pipeline,
|
_cogl_pipeline_update_real_blend_enable (CoglPipeline *pipeline,
|
||||||
CoglPipelineState change)
|
CoglBool unknown_color_alpha)
|
||||||
{
|
{
|
||||||
CoglBool blend_enable =
|
CoglPipeline *parent;
|
||||||
_cogl_pipeline_needs_blending_enabled (pipeline, change, NULL);
|
unsigned int differences;
|
||||||
|
|
||||||
if (blend_enable != pipeline->real_blend_enable)
|
if (pipeline->dirty_real_blend_enable == FALSE &&
|
||||||
|
pipeline->unknown_color_alpha == unknown_color_alpha)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (pipeline->dirty_real_blend_enable)
|
||||||
{
|
{
|
||||||
/* - Flush journal primitives referencing the current state.
|
differences = pipeline->differences;
|
||||||
* - Make sure the pipeline has no dependants so it may be
|
|
||||||
* modified.
|
parent = _cogl_pipeline_get_parent (pipeline);
|
||||||
* - If the pipeline isn't currently an authority for the state
|
while (parent->dirty_real_blend_enable)
|
||||||
* being changed, then initialize that state from the current
|
{
|
||||||
* authority.
|
differences |= parent->differences;
|
||||||
|
parent = _cogl_pipeline_get_parent (parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We initialize the pipeline's real_blend_enable with a known
|
||||||
|
* reference value from its nearest ancestor with clean state so
|
||||||
|
* we can then potentially reduce the work involved in checking
|
||||||
|
* if the pipeline really needs blending itself because we can
|
||||||
|
* just look at the things that differ between the ancestor and
|
||||||
|
* this pipeline.
|
||||||
*/
|
*/
|
||||||
_cogl_pipeline_pre_change_notify (pipeline,
|
pipeline->real_blend_enable = parent->real_blend_enable;
|
||||||
COGL_PIPELINE_STATE_REAL_BLEND_ENABLE,
|
|
||||||
NULL,
|
|
||||||
FALSE);
|
|
||||||
pipeline->real_blend_enable = blend_enable;
|
|
||||||
}
|
}
|
||||||
|
else /* pipeline->unknown_color_alpha != unknown_color_alpha */
|
||||||
|
differences = 0;
|
||||||
|
|
||||||
|
/* Note we don't call _cogl_pipeline_pre_change_notify() for this
|
||||||
|
* state change because ->real_blend_enable is lazily derived from
|
||||||
|
* other state while flushing the pipeline and we'd need to avoid
|
||||||
|
* recursion problems in cases where _pre_change_notify() flushes
|
||||||
|
* the journal if the pipeline is referenced by a journal.
|
||||||
|
*/
|
||||||
|
pipeline->real_blend_enable =
|
||||||
|
_cogl_pipeline_needs_blending_enabled (pipeline, differences,
|
||||||
|
NULL, unknown_color_alpha);
|
||||||
|
pipeline->dirty_real_blend_enable = FALSE;
|
||||||
|
pipeline->unknown_color_alpha = unknown_color_alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@ -2145,7 +2206,7 @@ _cogl_pipeline_resolve_authorities (CoglPipeline *pipeline,
|
|||||||
CoglBool
|
CoglBool
|
||||||
_cogl_pipeline_equal (CoglPipeline *pipeline0,
|
_cogl_pipeline_equal (CoglPipeline *pipeline0,
|
||||||
CoglPipeline *pipeline1,
|
CoglPipeline *pipeline1,
|
||||||
unsigned long differences,
|
unsigned int differences,
|
||||||
unsigned long layer_differences,
|
unsigned long layer_differences,
|
||||||
CoglPipelineEvalFlags flags)
|
CoglPipelineEvalFlags flags)
|
||||||
{
|
{
|
||||||
@ -2171,6 +2232,9 @@ _cogl_pipeline_equal (CoglPipeline *pipeline0,
|
|||||||
|
|
||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
|
|
||||||
|
_cogl_pipeline_update_real_blend_enable (pipeline0, FALSE);
|
||||||
|
_cogl_pipeline_update_real_blend_enable (pipeline1, FALSE);
|
||||||
|
|
||||||
/* First check non-sparse properties */
|
/* First check non-sparse properties */
|
||||||
|
|
||||||
if (differences & COGL_PIPELINE_STATE_REAL_BLEND_ENABLE &&
|
if (differences & COGL_PIPELINE_STATE_REAL_BLEND_ENABLE &&
|
||||||
@ -2438,7 +2502,7 @@ cogl_pipeline_remove_layer (CoglPipeline *pipeline, int layer_index)
|
|||||||
_cogl_pipeline_remove_layer_difference (pipeline, layer_info.layer, TRUE);
|
_cogl_pipeline_remove_layer_difference (pipeline, layer_info.layer, TRUE);
|
||||||
_cogl_pipeline_try_reverting_layers_authority (pipeline, NULL);
|
_cogl_pipeline_try_reverting_layers_authority (pipeline, NULL);
|
||||||
|
|
||||||
_cogl_pipeline_update_blend_enable (pipeline, COGL_PIPELINE_STATE_LAYERS);
|
pipeline->dirty_real_blend_enable = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CoglBool
|
static CoglBool
|
||||||
@ -2718,12 +2782,12 @@ _cogl_pipeline_init_state_hash_functions (void)
|
|||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
_cogl_pipeline_hash (CoglPipeline *pipeline,
|
_cogl_pipeline_hash (CoglPipeline *pipeline,
|
||||||
unsigned long differences,
|
unsigned int differences,
|
||||||
unsigned long layer_differences,
|
unsigned long layer_differences,
|
||||||
CoglPipelineEvalFlags flags)
|
CoglPipelineEvalFlags flags)
|
||||||
{
|
{
|
||||||
CoglPipeline *authorities[COGL_PIPELINE_STATE_SPARSE_COUNT];
|
CoglPipeline *authorities[COGL_PIPELINE_STATE_SPARSE_COUNT];
|
||||||
unsigned long mask;
|
unsigned int mask;
|
||||||
int i;
|
int i;
|
||||||
CoglPipelineHashState state;
|
CoglPipelineHashState state;
|
||||||
unsigned int final_hash = 0;
|
unsigned int final_hash = 0;
|
||||||
@ -2732,6 +2796,8 @@ _cogl_pipeline_hash (CoglPipeline *pipeline,
|
|||||||
state.layer_differences = layer_differences;
|
state.layer_differences = layer_differences;
|
||||||
state.flags = flags;
|
state.flags = flags;
|
||||||
|
|
||||||
|
_cogl_pipeline_update_real_blend_enable (pipeline, FALSE);
|
||||||
|
|
||||||
/* hash non-sparse state */
|
/* hash non-sparse state */
|
||||||
|
|
||||||
if (differences & COGL_PIPELINE_STATE_REAL_BLEND_ENABLE)
|
if (differences & COGL_PIPELINE_STATE_REAL_BLEND_ENABLE)
|
||||||
@ -2748,7 +2814,7 @@ _cogl_pipeline_hash (CoglPipeline *pipeline,
|
|||||||
|
|
||||||
for (i = 0; i < COGL_PIPELINE_STATE_SPARSE_COUNT; i++)
|
for (i = 0; i < COGL_PIPELINE_STATE_SPARSE_COUNT; i++)
|
||||||
{
|
{
|
||||||
unsigned long current_state = (1L<<i);
|
unsigned int current_state = (1<<i);
|
||||||
|
|
||||||
/* XXX: we are hashing the un-mixed hash values of all the
|
/* XXX: we are hashing the un-mixed hash values of all the
|
||||||
* individual state groups; we should provide a means to test
|
* individual state groups; we should provide a means to test
|
||||||
|
@ -390,8 +390,10 @@ cogl_begin_gl (void)
|
|||||||
* values.
|
* values.
|
||||||
*/
|
*/
|
||||||
pipeline = cogl_get_source ();
|
pipeline = cogl_get_source ();
|
||||||
_cogl_pipeline_flush_gl_state (pipeline,
|
_cogl_pipeline_flush_gl_state (ctx,
|
||||||
|
pipeline,
|
||||||
cogl_get_draw_framebuffer (),
|
cogl_get_draw_framebuffer (),
|
||||||
|
FALSE,
|
||||||
FALSE);
|
FALSE);
|
||||||
|
|
||||||
/* Disable any cached vertex arrays */
|
/* Disable any cached vertex arrays */
|
||||||
|
@ -375,26 +375,22 @@ _cogl_gl_flush_attributes_state (CoglFramebuffer *framebuffer,
|
|||||||
{
|
{
|
||||||
CoglContext *ctx = framebuffer->context;
|
CoglContext *ctx = framebuffer->context;
|
||||||
int i;
|
int i;
|
||||||
CoglBool skip_gl_color = FALSE;
|
CoglBool with_color_attrib = FALSE;
|
||||||
|
CoglBool unknown_color_alpha = FALSE;
|
||||||
CoglPipeline *copy = NULL;
|
CoglPipeline *copy = NULL;
|
||||||
|
|
||||||
/* Iterate the attributes to work out whether blending needs to be
|
/* Iterate the attributes to see if we have a color attribute which
|
||||||
enabled and how many texture coords there are. We need to do this
|
* may affect our decision to enable blending or not.
|
||||||
before flushing the pipeline. */
|
*
|
||||||
|
* We need to do this before flushing the pipeline. */
|
||||||
for (i = 0; i < n_attributes; i++)
|
for (i = 0; i < n_attributes; i++)
|
||||||
switch (attributes[i]->name_state->name_id)
|
switch (attributes[i]->name_state->name_id)
|
||||||
{
|
{
|
||||||
case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY:
|
case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY:
|
||||||
if ((flags & COGL_DRAW_COLOR_ATTRIBUTE_IS_OPAQUE) == 0 &&
|
if ((flags & COGL_DRAW_COLOR_ATTRIBUTE_IS_OPAQUE) == 0 &&
|
||||||
!_cogl_pipeline_get_real_blend_enabled (pipeline))
|
_cogl_attribute_get_n_components (attributes[i]) == 4)
|
||||||
{
|
unknown_color_alpha = TRUE;
|
||||||
CoglPipelineBlendEnable blend_enable =
|
with_color_attrib = TRUE;
|
||||||
COGL_PIPELINE_BLEND_ENABLE_ENABLED;
|
|
||||||
copy = cogl_pipeline_copy (pipeline);
|
|
||||||
_cogl_pipeline_set_blend_enabled (copy, blend_enable);
|
|
||||||
pipeline = copy;
|
|
||||||
}
|
|
||||||
skip_gl_color = TRUE;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -445,9 +441,11 @@ _cogl_gl_flush_attributes_state (CoglFramebuffer *framebuffer,
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
_cogl_pipeline_flush_gl_state (pipeline,
|
_cogl_pipeline_flush_gl_state (ctx,
|
||||||
|
pipeline,
|
||||||
framebuffer,
|
framebuffer,
|
||||||
skip_gl_color);
|
with_color_attrib,
|
||||||
|
unknown_color_alpha);
|
||||||
|
|
||||||
_cogl_bitmask_clear_all (&ctx->enable_builtin_attributes_tmp);
|
_cogl_bitmask_clear_all (&ctx->enable_builtin_attributes_tmp);
|
||||||
_cogl_bitmask_clear_all (&ctx->enable_texcoord_attributes_tmp);
|
_cogl_bitmask_clear_all (&ctx->enable_texcoord_attributes_tmp);
|
||||||
|
@ -287,7 +287,8 @@ add_stencil_clip_silhouette (CoglFramebuffer *framebuffer,
|
|||||||
projection_stack->last_entry);
|
projection_stack->last_entry);
|
||||||
_cogl_context_set_current_modelview_entry (ctx, modelview_entry);
|
_cogl_context_set_current_modelview_entry (ctx, modelview_entry);
|
||||||
|
|
||||||
_cogl_pipeline_flush_gl_state (ctx->stencil_pipeline, framebuffer, FALSE);
|
_cogl_pipeline_flush_gl_state (ctx, ctx->stencil_pipeline,
|
||||||
|
framebuffer, FALSE, FALSE);
|
||||||
|
|
||||||
GE( ctx, glEnable (GL_STENCIL_TEST) );
|
GE( ctx, glEnable (GL_STENCIL_TEST) );
|
||||||
|
|
||||||
|
@ -142,9 +142,11 @@ void
|
|||||||
_cogl_delete_gl_texture (GLuint gl_texture);
|
_cogl_delete_gl_texture (GLuint gl_texture);
|
||||||
|
|
||||||
void
|
void
|
||||||
_cogl_pipeline_flush_gl_state (CoglPipeline *pipeline,
|
_cogl_pipeline_flush_gl_state (CoglContext *context,
|
||||||
|
CoglPipeline *pipeline,
|
||||||
CoglFramebuffer *framebuffer,
|
CoglFramebuffer *framebuffer,
|
||||||
CoglBool skip_gl_state);
|
CoglBool skip_gl_state,
|
||||||
|
CoglBool unknown_color_alpha);
|
||||||
|
|
||||||
#endif /* __COGL_PIPELINE_OPENGL_PRIVATE_H */
|
#endif /* __COGL_PIPELINE_OPENGL_PRIVATE_H */
|
||||||
|
|
||||||
|
@ -448,18 +448,18 @@ static void
|
|||||||
_cogl_pipeline_flush_color_blend_alpha_depth_state (
|
_cogl_pipeline_flush_color_blend_alpha_depth_state (
|
||||||
CoglPipeline *pipeline,
|
CoglPipeline *pipeline,
|
||||||
unsigned long pipelines_difference,
|
unsigned long pipelines_difference,
|
||||||
CoglBool skip_gl_color)
|
CoglBool with_color_attrib)
|
||||||
{
|
{
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
/* On GLES2 we'll flush the color later */
|
/* On GLES2 we'll flush the color later */
|
||||||
if ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_FIXED_FUNCTION) &&
|
if ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_FIXED_FUNCTION) &&
|
||||||
!skip_gl_color)
|
!with_color_attrib)
|
||||||
{
|
{
|
||||||
if ((pipelines_difference & COGL_PIPELINE_STATE_COLOR) ||
|
if ((pipelines_difference & COGL_PIPELINE_STATE_COLOR) ||
|
||||||
/* Assume if we were previously told to skip the color, then
|
/* Assume if we were previously told to skip the color, then
|
||||||
* the current color needs updating... */
|
* the current color needs updating... */
|
||||||
ctx->current_pipeline_skip_gl_color)
|
ctx->current_pipeline_with_color_attrib)
|
||||||
{
|
{
|
||||||
CoglPipeline *authority =
|
CoglPipeline *authority =
|
||||||
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_COLOR);
|
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_COLOR);
|
||||||
@ -889,7 +889,7 @@ static void
|
|||||||
_cogl_pipeline_flush_common_gl_state (CoglPipeline *pipeline,
|
_cogl_pipeline_flush_common_gl_state (CoglPipeline *pipeline,
|
||||||
unsigned long pipelines_difference,
|
unsigned long pipelines_difference,
|
||||||
unsigned long *layer_differences,
|
unsigned long *layer_differences,
|
||||||
CoglBool skip_gl_color)
|
CoglBool with_color_attrib)
|
||||||
{
|
{
|
||||||
CoglPipelineFlushLayerState state;
|
CoglPipelineFlushLayerState state;
|
||||||
|
|
||||||
@ -897,7 +897,7 @@ _cogl_pipeline_flush_common_gl_state (CoglPipeline *pipeline,
|
|||||||
|
|
||||||
_cogl_pipeline_flush_color_blend_alpha_depth_state (pipeline,
|
_cogl_pipeline_flush_color_blend_alpha_depth_state (pipeline,
|
||||||
pipelines_difference,
|
pipelines_difference,
|
||||||
skip_gl_color);
|
with_color_attrib);
|
||||||
|
|
||||||
state.i = 0;
|
state.i = 0;
|
||||||
state.layer_differences = layer_differences;
|
state.layer_differences = layer_differences;
|
||||||
@ -1149,10 +1149,13 @@ fragend_add_layer_cb (CoglPipelineLayer *layer,
|
|||||||
* isn't ideal, and can't be used with CoglVertexBuffers.
|
* isn't ideal, and can't be used with CoglVertexBuffers.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
_cogl_pipeline_flush_gl_state (CoglPipeline *pipeline,
|
_cogl_pipeline_flush_gl_state (CoglContext *ctx,
|
||||||
|
CoglPipeline *pipeline,
|
||||||
CoglFramebuffer *framebuffer,
|
CoglFramebuffer *framebuffer,
|
||||||
CoglBool skip_gl_color)
|
CoglBool with_color_attrib,
|
||||||
|
CoglBool unknown_color_alpha)
|
||||||
{
|
{
|
||||||
|
CoglPipeline *current_pipeline = ctx->current_pipeline;
|
||||||
unsigned long pipelines_difference;
|
unsigned long pipelines_difference;
|
||||||
int n_layers;
|
int n_layers;
|
||||||
unsigned long *layer_differences;
|
unsigned long *layer_differences;
|
||||||
@ -1166,29 +1169,61 @@ _cogl_pipeline_flush_gl_state (CoglPipeline *pipeline,
|
|||||||
"The time spent flushing material state",
|
"The time spent flushing material state",
|
||||||
0 /* no application private data */);
|
0 /* no application private data */);
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
|
||||||
|
|
||||||
COGL_TIMER_START (_cogl_uprof_context, pipeline_flush_timer);
|
COGL_TIMER_START (_cogl_uprof_context, pipeline_flush_timer);
|
||||||
|
|
||||||
if (ctx->current_pipeline == pipeline)
|
/* Bail out asap if we've been asked to re-flush the already current
|
||||||
{
|
* pipeline and we can see the pipeline hasn't changed */
|
||||||
/* Bail out asap if we've been asked to re-flush the already current
|
if (current_pipeline == pipeline &&
|
||||||
* pipeline and we can see the pipeline hasn't changed */
|
ctx->current_pipeline_age == pipeline->age &&
|
||||||
if (ctx->current_pipeline_age == pipeline->age &&
|
ctx->current_pipeline_with_color_attrib == with_color_attrib &&
|
||||||
ctx->current_pipeline_skip_gl_color == skip_gl_color)
|
ctx->current_pipeline_unknown_color_alpha == unknown_color_alpha)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
pipelines_difference = ctx->current_pipeline_changes_since_flush;
|
|
||||||
}
|
|
||||||
else if (ctx->current_pipeline)
|
|
||||||
{
|
|
||||||
pipelines_difference = ctx->current_pipeline_changes_since_flush;
|
|
||||||
pipelines_difference |=
|
|
||||||
_cogl_pipeline_compare_differences (ctx->current_pipeline,
|
|
||||||
pipeline);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
pipelines_difference = COGL_PIPELINE_STATE_ALL_SPARSE;
|
{
|
||||||
|
/* Update derived state (currently just the 'real_blend_enable'
|
||||||
|
* state) and determine a mask of state that differs between the
|
||||||
|
* current pipeline and the one we are flushing.
|
||||||
|
*
|
||||||
|
* Note updating the derived state is done before doing any
|
||||||
|
* pipeline comparisons so that we can correctly compare the
|
||||||
|
* 'real_blend_enable' state itself.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (current_pipeline == pipeline)
|
||||||
|
{
|
||||||
|
pipelines_difference = ctx->current_pipeline_changes_since_flush;
|
||||||
|
|
||||||
|
if (pipelines_difference & COGL_PIPELINE_STATE_AFFECTS_BLENDING ||
|
||||||
|
pipeline->unknown_color_alpha != unknown_color_alpha)
|
||||||
|
{
|
||||||
|
CoglBool save_real_blend_enable = pipeline->real_blend_enable;
|
||||||
|
|
||||||
|
_cogl_pipeline_update_real_blend_enable (pipeline,
|
||||||
|
unknown_color_alpha);
|
||||||
|
|
||||||
|
if (save_real_blend_enable != pipeline->real_blend_enable)
|
||||||
|
pipelines_difference |= COGL_PIPELINE_STATE_REAL_BLEND_ENABLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (current_pipeline)
|
||||||
|
{
|
||||||
|
pipelines_difference = ctx->current_pipeline_changes_since_flush;
|
||||||
|
|
||||||
|
_cogl_pipeline_update_real_blend_enable (pipeline,
|
||||||
|
unknown_color_alpha);
|
||||||
|
|
||||||
|
pipelines_difference |=
|
||||||
|
_cogl_pipeline_compare_differences (ctx->current_pipeline,
|
||||||
|
pipeline);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_cogl_pipeline_update_real_blend_enable (pipeline,
|
||||||
|
unknown_color_alpha);
|
||||||
|
|
||||||
|
pipelines_difference = COGL_PIPELINE_STATE_ALL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Get a layer_differences mask for each layer to be flushed */
|
/* Get a layer_differences mask for each layer to be flushed */
|
||||||
n_layers = cogl_pipeline_get_n_layers (pipeline);
|
n_layers = cogl_pipeline_get_n_layers (pipeline);
|
||||||
@ -1225,7 +1260,7 @@ _cogl_pipeline_flush_gl_state (CoglPipeline *pipeline,
|
|||||||
_cogl_pipeline_flush_common_gl_state (pipeline,
|
_cogl_pipeline_flush_common_gl_state (pipeline,
|
||||||
pipelines_difference,
|
pipelines_difference,
|
||||||
layer_differences,
|
layer_differences,
|
||||||
skip_gl_color);
|
with_color_attrib);
|
||||||
|
|
||||||
/* Now flush the fragment, vertex and program state according to the
|
/* Now flush the fragment, vertex and program state according to the
|
||||||
* current progend backend.
|
* current progend backend.
|
||||||
@ -1327,7 +1362,8 @@ _cogl_pipeline_flush_gl_state (CoglPipeline *pipeline,
|
|||||||
cogl_object_unref (ctx->current_pipeline);
|
cogl_object_unref (ctx->current_pipeline);
|
||||||
ctx->current_pipeline = pipeline;
|
ctx->current_pipeline = pipeline;
|
||||||
ctx->current_pipeline_changes_since_flush = 0;
|
ctx->current_pipeline_changes_since_flush = 0;
|
||||||
ctx->current_pipeline_skip_gl_color = skip_gl_color;
|
ctx->current_pipeline_with_color_attrib = with_color_attrib;
|
||||||
|
ctx->current_pipeline_unknown_color_alpha = unknown_color_alpha;
|
||||||
ctx->current_pipeline_age = pipeline->age;
|
ctx->current_pipeline_age = pipeline->age;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
@ -1338,7 +1374,7 @@ done:
|
|||||||
* using the glsl progend because the generic attribute values are
|
* using the glsl progend because the generic attribute values are
|
||||||
* not stored as part of the program object so they could be
|
* not stored as part of the program object so they could be
|
||||||
* overridden by any attribute changes in another program */
|
* overridden by any attribute changes in another program */
|
||||||
if (pipeline->progend == COGL_PIPELINE_PROGEND_GLSL && !skip_gl_color)
|
if (pipeline->progend == COGL_PIPELINE_PROGEND_GLSL && !with_color_attrib)
|
||||||
{
|
{
|
||||||
int attribute;
|
int attribute;
|
||||||
CoglPipeline *authority =
|
CoglPipeline *authority =
|
||||||
|
Loading…
x
Reference in New Issue
Block a user