[transitions] Do not recreate FBOs on opacity changes
Creating an FBO may be expensive, so we should avoid the operation if possible. When transitioning between theme nodes, the widget's opacity is used to paint to the offscreen textures which are blended together - this means that the textures have to be recreated each time the widget's opacity changes. It is much more effective to paint the textures at full opacity and respect the widget's paint opacity when blending the textures together. https://bugzilla.gnome.org/show_bug.cgi?id=627085
This commit is contained in:
parent
c3cb0be011
commit
5bd977dd3c
@ -49,7 +49,6 @@ struct _StThemeNodeTransitionPrivate {
|
|||||||
|
|
||||||
ClutterActorBox last_allocation;
|
ClutterActorBox last_allocation;
|
||||||
ClutterActorBox offscreen_box;
|
ClutterActorBox offscreen_box;
|
||||||
guint8 last_opacity;
|
|
||||||
|
|
||||||
gboolean needs_setup;
|
gboolean needs_setup;
|
||||||
};
|
};
|
||||||
@ -200,8 +199,7 @@ calculate_offscreen_box (StThemeNodeTransition *transition,
|
|||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
setup_framebuffers (StThemeNodeTransition *transition,
|
setup_framebuffers (StThemeNodeTransition *transition,
|
||||||
const ClutterActorBox *allocation,
|
const ClutterActorBox *allocation)
|
||||||
guint8 paint_opacity)
|
|
||||||
{
|
{
|
||||||
StThemeNodeTransitionPrivate *priv = transition->priv;
|
StThemeNodeTransitionPrivate *priv = transition->priv;
|
||||||
CoglColor clear_color = { 0, 0, 0, 0 };
|
CoglColor clear_color = { 0, 0, 0, 0 };
|
||||||
@ -243,11 +241,17 @@ setup_framebuffers (StThemeNodeTransition *transition,
|
|||||||
cogl_handle_unref (priv->material);
|
cogl_handle_unref (priv->material);
|
||||||
priv->material = cogl_material_new ();
|
priv->material = cogl_material_new ();
|
||||||
|
|
||||||
|
cogl_material_set_layer_combine (priv->material, 0,
|
||||||
|
"RGBA = REPLACE (TEXTURE)",
|
||||||
|
NULL);
|
||||||
cogl_material_set_layer_combine (priv->material, 1,
|
cogl_material_set_layer_combine (priv->material, 1,
|
||||||
"RGBA = INTERPOLATE (PREVIOUS, "
|
"RGBA = INTERPOLATE (PREVIOUS, "
|
||||||
"TEXTURE, "
|
"TEXTURE, "
|
||||||
"CONSTANT[A])",
|
"CONSTANT[A])",
|
||||||
NULL);
|
NULL);
|
||||||
|
cogl_material_set_layer_combine (priv->material, 2,
|
||||||
|
"RGBA = MODULATE (PREVIOUS, PRIMARY)",
|
||||||
|
NULL);
|
||||||
|
|
||||||
cogl_material_set_layer (priv->material, 0, priv->new_texture);
|
cogl_material_set_layer (priv->material, 0, priv->new_texture);
|
||||||
cogl_material_set_layer (priv->material, 1, priv->old_texture);
|
cogl_material_set_layer (priv->material, 1, priv->old_texture);
|
||||||
@ -257,9 +261,7 @@ setup_framebuffers (StThemeNodeTransition *transition,
|
|||||||
cogl_ortho (priv->offscreen_box.x1, priv->offscreen_box.x2,
|
cogl_ortho (priv->offscreen_box.x1, priv->offscreen_box.x2,
|
||||||
priv->offscreen_box.y2, priv->offscreen_box.y1,
|
priv->offscreen_box.y2, priv->offscreen_box.y1,
|
||||||
0.0, 1.0);
|
0.0, 1.0);
|
||||||
st_theme_node_paint (priv->old_theme_node,
|
st_theme_node_paint (priv->old_theme_node, allocation, 255);
|
||||||
allocation,
|
|
||||||
paint_opacity);
|
|
||||||
cogl_pop_framebuffer ();
|
cogl_pop_framebuffer ();
|
||||||
|
|
||||||
cogl_push_framebuffer (priv->new_offscreen);
|
cogl_push_framebuffer (priv->new_offscreen);
|
||||||
@ -267,9 +269,7 @@ setup_framebuffers (StThemeNodeTransition *transition,
|
|||||||
cogl_ortho (priv->offscreen_box.x1, priv->offscreen_box.x2,
|
cogl_ortho (priv->offscreen_box.x1, priv->offscreen_box.x2,
|
||||||
priv->offscreen_box.y2, priv->offscreen_box.y1,
|
priv->offscreen_box.y2, priv->offscreen_box.y1,
|
||||||
0.0, 1.0);
|
0.0, 1.0);
|
||||||
st_theme_node_paint (priv->new_theme_node,
|
st_theme_node_paint (priv->new_theme_node, allocation, 255);
|
||||||
allocation,
|
|
||||||
paint_opacity);
|
|
||||||
cogl_pop_framebuffer ();
|
cogl_pop_framebuffer ();
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -291,26 +291,25 @@ st_theme_node_transition_paint (StThemeNodeTransition *transition,
|
|||||||
g_return_if_fail (ST_IS_THEME_NODE (priv->old_theme_node));
|
g_return_if_fail (ST_IS_THEME_NODE (priv->old_theme_node));
|
||||||
g_return_if_fail (ST_IS_THEME_NODE (priv->new_theme_node));
|
g_return_if_fail (ST_IS_THEME_NODE (priv->new_theme_node));
|
||||||
|
|
||||||
if (!clutter_actor_box_equal (allocation, &priv->last_allocation) ||
|
if (!clutter_actor_box_equal (allocation, &priv->last_allocation))
|
||||||
paint_opacity != priv->last_opacity)
|
|
||||||
priv->needs_setup = TRUE;
|
priv->needs_setup = TRUE;
|
||||||
|
|
||||||
if (priv->needs_setup)
|
if (priv->needs_setup)
|
||||||
{
|
{
|
||||||
priv->last_allocation = *allocation;
|
priv->last_allocation = *allocation;
|
||||||
priv->last_opacity = paint_opacity;
|
|
||||||
|
|
||||||
calculate_offscreen_box (transition, allocation);
|
calculate_offscreen_box (transition, allocation);
|
||||||
priv->needs_setup = !setup_framebuffers (transition,
|
priv->needs_setup = !setup_framebuffers (transition, allocation);
|
||||||
allocation,
|
|
||||||
paint_opacity);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cogl_color_set_from_4ub (&constant, 0, 0, 0,
|
cogl_color_set_from_4f (&constant, 0., 0., 0.,
|
||||||
clutter_alpha_get_alpha (priv->alpha) * paint_opacity);
|
clutter_alpha_get_alpha (priv->alpha));
|
||||||
|
|
||||||
cogl_material_set_layer_combine_constant (priv->material, 1, &constant);
|
cogl_material_set_layer_combine_constant (priv->material, 1, &constant);
|
||||||
|
|
||||||
|
cogl_material_set_color4ub (priv->material,
|
||||||
|
paint_opacity, paint_opacity,
|
||||||
|
paint_opacity, paint_opacity);
|
||||||
|
|
||||||
cogl_set_source (priv->material);
|
cogl_set_source (priv->material);
|
||||||
cogl_rectangle_with_multitexture_coords (priv->offscreen_box.x1,
|
cogl_rectangle_with_multitexture_coords (priv->offscreen_box.x1,
|
||||||
priv->offscreen_box.y1,
|
priv->offscreen_box.y1,
|
||||||
|
Loading…
Reference in New Issue
Block a user