g_free (material);
}
-
-static void
-handle_automatic_blend_enable (CoglMaterial *material)
+static gboolean
+_cogl_material_needs_blending_enabled (CoglMaterial *material,
+ GLubyte *override_color)
{
GList *tmp;
/* XXX: If we expose manual control over ENABLE_BLEND, we'll add
* a flag to know when it's user configured, so we don't trash it */
- material->flags &= ~COGL_MATERIAL_FLAG_ENABLE_BLEND;
-
/* XXX: Uncomment this to disable all blending */
#if 0
return;
#endif
+ if ((override_color && override_color[3] != 0xff) ||
+ material->unlit[3] != 0xff)
+ return TRUE;
+
for (tmp = material->layers; tmp != NULL; tmp = tmp->next)
{
CoglMaterialLayer *layer = tmp->data;
continue;
if (cogl_texture_get_format (layer->texture) & COGL_A_BIT)
- material->flags |= COGL_MATERIAL_FLAG_ENABLE_BLEND;
+ return TRUE;
}
- if (material->unlit[3] != 0xff)
+ return FALSE;
+}
+
+static void
+handle_automatic_blend_enable (CoglMaterial *material)
+{
+ material->flags &= ~COGL_MATERIAL_FLAG_ENABLE_BLEND;
+
+ if (_cogl_material_needs_blending_enabled (material, NULL))
material->flags |= COGL_MATERIAL_FLAG_ENABLE_BLEND;
}
* state of this material we need to flush the journal before we can
* modify it... */
static void
-_cogl_material_pre_change_notify (CoglMaterial *material)
+_cogl_material_pre_change_notify (CoglMaterial *material,
+ gboolean only_color_change,
+ GLubyte *new_color)
{
+ /* XXX: We don't usually need to flush the journal just due to color changes
+ * since material colors are logged in the journals vertex buffer. The
+ * exception is when the change in color enables or disables the need for
+ * blending. */
+ if (only_color_change)
+ {
+ gboolean will_need_blending =
+ _cogl_material_needs_blending_enabled (material, new_color);
+ if (will_need_blending ==
+ (material->flags & COGL_MATERIAL_FLAG_ENABLE_BLEND) ? TRUE : FALSE)
+ return;
+ }
+
if (material->journal_ref_count)
_cogl_journal_flush ();
}
return;
/* possibly flush primitives referencing the current state... */
- _cogl_material_pre_change_notify (material);
+ _cogl_material_pre_change_notify (material, TRUE, unlit);
memcpy (material->unlit, unlit, sizeof (unlit));
material = _cogl_material_pointer_from_handle (handle);
/* possibly flush primitives referencing the current state... */
- _cogl_material_pre_change_notify (material);
+ _cogl_material_pre_change_notify (material, FALSE, NULL);
ambient = material->ambient;
ambient[0] = cogl_color_get_red_float (ambient_color);
material = _cogl_material_pointer_from_handle (handle);
/* possibly flush primitives referencing the current state... */
- _cogl_material_pre_change_notify (material);
+ _cogl_material_pre_change_notify (material, FALSE, NULL);
diffuse = material->diffuse;
diffuse[0] = cogl_color_get_red_float (diffuse_color);
material = _cogl_material_pointer_from_handle (handle);
/* possibly flush primitives referencing the current state... */
- _cogl_material_pre_change_notify (material);
+ _cogl_material_pre_change_notify (material, FALSE, NULL);
specular = material->specular;
specular[0] = cogl_color_get_red_float (specular_color);
material = _cogl_material_pointer_from_handle (handle);
/* possibly flush primitives referencing the current state... */
- _cogl_material_pre_change_notify (material);
+ _cogl_material_pre_change_notify (material, FALSE, NULL);
material->shininess = (GLfloat)shininess * 128.0;
material = _cogl_material_pointer_from_handle (handle);
/* possibly flush primitives referencing the current state... */
- _cogl_material_pre_change_notify (material);
+ _cogl_material_pre_change_notify (material, FALSE, NULL);
emission = material->emission;
emission[0] = cogl_color_get_red_float (emission_color);
material = _cogl_material_pointer_from_handle (handle);
/* possibly flush primitives referencing the current state... */
- _cogl_material_pre_change_notify (material);
+ _cogl_material_pre_change_notify (material, FALSE, NULL);
material->alpha_func = alpha_func;
material->alpha_func_reference = (GLfloat)alpha_reference;
}
/* possibly flush primitives referencing the current state... */
- _cogl_material_pre_change_notify (material);
+ _cogl_material_pre_change_notify (material, FALSE, NULL);
#ifndef HAVE_COGL_GLES
setup_blend_state (rgb,
material = _cogl_material_pointer_from_handle (handle);
/* possibly flush primitives referencing the current state... */
- _cogl_material_pre_change_notify (material);
+ _cogl_material_pre_change_notify (material, FALSE, NULL);
constant = material->blend_constant;
constant[0] = cogl_color_get_red_float (constant_color);
if (!create_if_not_found)
return NULL;
+ /* possibly flush primitives referencing the current state... */
+ _cogl_material_pre_change_notify (material, FALSE, NULL);
+
layer = g_new0 (CoglMaterialLayer, 1);
layer_handle = _cogl_material_layer_handle_new (layer);
material = _cogl_material_pointer_from_handle (material_handle);
- /* possibly flush primitives referencing the current state... */
- _cogl_material_pre_change_notify (material);
-
layer = _cogl_material_get_layer (material_handle, layer_index, TRUE);
if (texture_handle == layer->texture)
return;
/* possibly flush primitives referencing the current state... */
- _cogl_material_pre_change_notify (material);
+ _cogl_material_pre_change_notify (material, FALSE, NULL);
material->n_layers = g_list_length (material->layers);
if (material->n_layers >= CGL_MAX_COMBINED_TEXTURE_IMAGE_UNITS)
}
/* possibly flush primitives referencing the current state... */
- _cogl_material_pre_change_notify (material);
+ _cogl_material_pre_change_notify (material, FALSE, NULL);
setup_texture_combine_state (rgb,
&layer->texture_combine_rgb_func,
layer = _cogl_material_get_layer (material, layer_index, TRUE);
/* possibly flush primitives referencing the current state... */
- _cogl_material_pre_change_notify (material);
+ _cogl_material_pre_change_notify (material, FALSE, NULL);
constant = layer->texture_combine_constant;
constant[0] = cogl_color_get_red_float (constant_color);
layer = _cogl_material_get_layer (material, layer_index, TRUE);
/* possibly flush primitives referencing the current state... */
- _cogl_material_pre_change_notify (material);
+ _cogl_material_pre_change_notify (material, FALSE, NULL);
layer->matrix = *matrix;
material = _cogl_material_pointer_from_handle (material_handle);
/* possibly flush primitives referencing the current state... */
- _cogl_material_pre_change_notify (material);
+ _cogl_material_pre_change_notify (material, FALSE, NULL);
for (tmp = material->layers; tmp != NULL; tmp = tmp->next)
{
g_return_if_fail (cogl_is_material (handle));
material = _cogl_material_pointer_from_handle (handle);
+ layer = _cogl_material_get_layer (material, layer_index, TRUE);
/* possibly flush primitives referencing the current state... */
- _cogl_material_pre_change_notify (material);
-
- layer = _cogl_material_get_layer (material, layer_index, TRUE);
+ _cogl_material_pre_change_notify (material, FALSE, NULL);
layer->min_filter = min_filter;
layer->mag_filter = mag_filter;