clutter/offscreen-effect: Add new create_pipeline() vfunc

The most annoying aspect of ClutterOffscreenEffect right now, and
the reason for all its subclasses to override pre-paint, is that
the pipeline creating isn't under subclasses' control. That means
all subclasses must ask ClutterOffscreenEffect to run pre-paint
and create the pipeline, then they all create their own pipelines
to paint.

To reduce this complexity, add a new create_pipeline() vfunc to
ClutterOffscreenEffect. Next commits will port effects to use this
vfunc when necessary.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1355
This commit is contained in:
Georges Basile Stavracas Neto 2020-07-05 13:41:19 -03:00
parent 59a3075f60
commit be3743ec3f
2 changed files with 28 additions and 13 deletions

View File

@ -158,6 +158,25 @@ ensure_pipeline_filter_for_scale (ClutterOffscreenEffect *self,
filter, filter); filter, filter);
} }
static CoglPipeline *
clutter_offscreen_effect_real_create_pipeline (ClutterOffscreenEffect *effect,
CoglTexture *texture)
{
ClutterOffscreenEffectPrivate *priv = effect->priv;
CoglContext *ctx =
clutter_backend_get_cogl_context (clutter_get_default_backend ());
CoglPipeline *pipeline;
float resource_scale;
resource_scale = clutter_actor_get_real_resource_scale (priv->actor);
pipeline = cogl_pipeline_new (ctx);
ensure_pipeline_filter_for_scale (effect, resource_scale);
cogl_pipeline_set_layer_texture (pipeline, 0, texture);
return pipeline;
}
static gboolean static gboolean
update_fbo (ClutterEffect *effect, update_fbo (ClutterEffect *effect,
int target_width, int target_width,
@ -166,6 +185,8 @@ update_fbo (ClutterEffect *effect,
{ {
ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (effect); ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (effect);
ClutterOffscreenEffectPrivate *priv = self->priv; ClutterOffscreenEffectPrivate *priv = self->priv;
ClutterOffscreenEffectClass *offscreen_class =
CLUTTER_OFFSCREEN_EFFECT_GET_CLASS (effect);
priv->stage = clutter_actor_get_stage (priv->actor); priv->stage = clutter_actor_get_stage (priv->actor);
if (priv->stage == NULL) if (priv->stage == NULL)
@ -185,15 +206,6 @@ update_fbo (ClutterEffect *effect,
return TRUE; return TRUE;
} }
if (priv->pipeline == NULL)
{
CoglContext *ctx =
clutter_backend_get_cogl_context (clutter_get_default_backend ());
priv->pipeline = cogl_pipeline_new (ctx);
ensure_pipeline_filter_for_scale (self, resource_scale);
}
g_clear_pointer (&priv->texture, cogl_object_unref); g_clear_pointer (&priv->texture, cogl_object_unref);
g_clear_pointer (&priv->offscreen, cogl_object_unref); g_clear_pointer (&priv->offscreen, cogl_object_unref);
@ -202,8 +214,6 @@ update_fbo (ClutterEffect *effect,
if (priv->texture == NULL) if (priv->texture == NULL)
return FALSE; return FALSE;
cogl_pipeline_set_layer_texture (priv->pipeline, 0, priv->texture);
priv->target_width = target_width; priv->target_width = target_width;
priv->target_height = target_height; priv->target_height = target_height;
@ -212,8 +222,7 @@ update_fbo (ClutterEffect *effect,
{ {
g_warning ("%s: Unable to create an Offscreen buffer", G_STRLOC); g_warning ("%s: Unable to create an Offscreen buffer", G_STRLOC);
cogl_object_unref (priv->pipeline); cogl_clear_object (&priv->pipeline);
priv->pipeline = NULL;
priv->target_width = 0; priv->target_width = 0;
priv->target_height = 0; priv->target_height = 0;
@ -221,6 +230,9 @@ update_fbo (ClutterEffect *effect,
return FALSE; return FALSE;
} }
cogl_clear_object (&priv->pipeline);
priv->pipeline = offscreen_class->create_pipeline (self, priv->texture);
return TRUE; return TRUE;
} }
@ -527,6 +539,7 @@ clutter_offscreen_effect_class_init (ClutterOffscreenEffectClass *klass)
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
klass->create_texture = clutter_offscreen_effect_real_create_texture; klass->create_texture = clutter_offscreen_effect_real_create_texture;
klass->create_pipeline = clutter_offscreen_effect_real_create_pipeline;
klass->paint_target = clutter_offscreen_effect_real_paint_target; klass->paint_target = clutter_offscreen_effect_real_paint_target;
meta_class->set_actor = clutter_offscreen_effect_set_actor; meta_class->set_actor = clutter_offscreen_effect_set_actor;

View File

@ -79,6 +79,8 @@ struct _ClutterOffscreenEffectClass
CoglHandle (* create_texture) (ClutterOffscreenEffect *effect, CoglHandle (* create_texture) (ClutterOffscreenEffect *effect,
gfloat width, gfloat width,
gfloat height); gfloat height);
CoglPipeline* (* create_pipeline) (ClutterOffscreenEffect *effect,
CoglTexture *texture);
void (* paint_target) (ClutterOffscreenEffect *effect, void (* paint_target) (ClutterOffscreenEffect *effect,
ClutterPaintContext *paint_context); ClutterPaintContext *paint_context);