From be3743ec3f569263fa5f83edb933b19681652866 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Sun, 5 Jul 2020 13:41:19 -0300 Subject: [PATCH] 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 --- clutter/clutter/clutter-offscreen-effect.c | 39 ++++++++++++++-------- clutter/clutter/clutter-offscreen-effect.h | 2 ++ 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/clutter/clutter/clutter-offscreen-effect.c b/clutter/clutter/clutter-offscreen-effect.c index 0c3e123ea..f209e9ca6 100644 --- a/clutter/clutter/clutter-offscreen-effect.c +++ b/clutter/clutter/clutter-offscreen-effect.c @@ -158,6 +158,25 @@ ensure_pipeline_filter_for_scale (ClutterOffscreenEffect *self, 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 update_fbo (ClutterEffect *effect, int target_width, @@ -166,6 +185,8 @@ update_fbo (ClutterEffect *effect, { ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (effect); ClutterOffscreenEffectPrivate *priv = self->priv; + ClutterOffscreenEffectClass *offscreen_class = + CLUTTER_OFFSCREEN_EFFECT_GET_CLASS (effect); priv->stage = clutter_actor_get_stage (priv->actor); if (priv->stage == NULL) @@ -185,15 +206,6 @@ update_fbo (ClutterEffect *effect, 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->offscreen, cogl_object_unref); @@ -202,8 +214,6 @@ update_fbo (ClutterEffect *effect, if (priv->texture == NULL) return FALSE; - cogl_pipeline_set_layer_texture (priv->pipeline, 0, priv->texture); - priv->target_width = target_width; priv->target_height = target_height; @@ -212,8 +222,7 @@ update_fbo (ClutterEffect *effect, { g_warning ("%s: Unable to create an Offscreen buffer", G_STRLOC); - cogl_object_unref (priv->pipeline); - priv->pipeline = NULL; + cogl_clear_object (&priv->pipeline); priv->target_width = 0; priv->target_height = 0; @@ -221,6 +230,9 @@ update_fbo (ClutterEffect *effect, return FALSE; } + cogl_clear_object (&priv->pipeline); + priv->pipeline = offscreen_class->create_pipeline (self, priv->texture); + return TRUE; } @@ -527,6 +539,7 @@ clutter_offscreen_effect_class_init (ClutterOffscreenEffectClass *klass) GObjectClass *gobject_class = G_OBJECT_CLASS (klass); 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; meta_class->set_actor = clutter_offscreen_effect_set_actor; diff --git a/clutter/clutter/clutter-offscreen-effect.h b/clutter/clutter/clutter-offscreen-effect.h index 6884ea77e..6a91f3f12 100644 --- a/clutter/clutter/clutter-offscreen-effect.h +++ b/clutter/clutter/clutter-offscreen-effect.h @@ -79,6 +79,8 @@ struct _ClutterOffscreenEffectClass CoglHandle (* create_texture) (ClutterOffscreenEffect *effect, gfloat width, gfloat height); + CoglPipeline* (* create_pipeline) (ClutterOffscreenEffect *effect, + CoglTexture *texture); void (* paint_target) (ClutterOffscreenEffect *effect, ClutterPaintContext *paint_context);