[mutter] renderer-native: Move shadow fb construction to the stage view



commit f4d9953b9ce7afce8849e610e8dfaf23c63c974d
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Thu Apr 30 17:53:30 2020 +0200

    renderer-native: Move shadow fb construction to the stage view
    
    The stage view will need a more involved approach to shadow buffers, in
    order to implement things such double buffered shadow buffers and damage
    detection.
    
    https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1237

 clutter/clutter/clutter-stage-view.c       | 115 +++++++++++++++++++++++++----
 src/backends/native/meta-renderer-native.c |  25 +------
 2 files changed, 106 insertions(+), 34 deletions(-)
---
diff --git a/clutter/clutter/clutter-stage-view.c b/clutter/clutter/clutter-stage-view.c
index 1580a8493d..c24fab4f79 100644
--- a/clutter/clutter/clutter-stage-view.c
+++ b/clutter/clutter/clutter-stage-view.c
@@ -35,7 +35,7 @@ enum
   PROP_LAYOUT,
   PROP_FRAMEBUFFER,
   PROP_OFFSCREEN,
-  PROP_SHADOWFB,
+  PROP_USE_SHADOWFB,
   PROP_SCALE,
 
   PROP_LAST
@@ -54,6 +54,7 @@ typedef struct _ClutterStageViewPrivate
   CoglOffscreen *offscreen;
   CoglPipeline *offscreen_pipeline;
 
+  gboolean use_shadowfb;
   CoglOffscreen *shadowfb;
   CoglPipeline *shadowfb_pipeline;
 
@@ -214,6 +215,80 @@ clutter_stage_view_copy_to_framebuffer (ClutterStageView *view,
   cogl_framebuffer_pop_matrix (dst_framebuffer);
 }
 
+static CoglOffscreen *
+create_offscreen_framebuffer (CoglContext  *context,
+                              int           width,
+                              int           height,
+                              GError      **error)
+{
+  CoglOffscreen *framebuffer;
+  CoglTexture2D *texture;
+
+  texture = cogl_texture_2d_new_with_size (context, width, height);
+  cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (texture),
+                                          FALSE);
+
+  if (!cogl_texture_allocate (COGL_TEXTURE (texture), error))
+    {
+      cogl_object_unref (texture);
+      return FALSE;
+    }
+
+  framebuffer = cogl_offscreen_new_with_texture (COGL_TEXTURE (texture));
+  cogl_object_unref (texture);
+  if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (framebuffer), error))
+    {
+      cogl_object_unref (framebuffer);
+      return FALSE;
+    }
+
+  return framebuffer;
+}
+
+static gboolean
+init_offscreen_shadowfb (ClutterStageView  *view,
+                         CoglContext       *cogl_context,
+                         int                width,
+                         int                height,
+                         GError           **error)
+{
+  ClutterStageViewPrivate *priv =
+    clutter_stage_view_get_instance_private (view);
+  CoglOffscreen *offscreen;
+
+  offscreen = create_offscreen_framebuffer (cogl_context, width, height, error);
+  if (!offscreen)
+    return FALSE;
+
+  priv->shadowfb = offscreen;
+  return TRUE;
+}
+
+static void
+init_shadowfb (ClutterStageView *view)
+{
+  ClutterStageViewPrivate *priv =
+    clutter_stage_view_get_instance_private (view);
+  g_autoptr (GError) error = NULL;
+  int width;
+  int height;
+  CoglContext *cogl_context;
+
+  width = cogl_framebuffer_get_width (priv->framebuffer);
+  height = cogl_framebuffer_get_height (priv->framebuffer);
+  cogl_context = cogl_framebuffer_get_context (priv->framebuffer);
+
+  if (!init_offscreen_shadowfb (view, cogl_context, width, height, &error))
+    {
+      g_warning ("Failed to initialize single buffered shadow fb for %s: %s",
+                 priv->name, error->message);
+    }
+  else
+    {
+      g_message ("Initialized single buffered shadow fb for %s", priv->name);
+    }
+}
+
 void
 clutter_stage_view_after_paint (ClutterStageView *view)
 {
@@ -457,8 +532,8 @@ clutter_stage_view_get_property (GObject    *object,
     case PROP_OFFSCREEN:
       g_value_set_boxed (value, priv->offscreen);
       break;
-    case PROP_SHADOWFB:
-      g_value_set_boxed (value, priv->shadowfb);
+    case PROP_USE_SHADOWFB:
+      g_value_set_boolean (value, priv->use_shadowfb);
       break;
     case PROP_SCALE:
       g_value_set_float (value, priv->scale);
@@ -508,8 +583,8 @@ clutter_stage_view_set_property (GObject      *object,
     case PROP_OFFSCREEN:
       priv->offscreen = g_value_dup_boxed (value);
       break;
-    case PROP_SHADOWFB:
-      priv->shadowfb = g_value_dup_boxed (value);
+    case PROP_USE_SHADOWFB:
+      priv->use_shadowfb = g_value_get_boolean (value);
       break;
     case PROP_SCALE:
       priv->scale = g_value_get_float (value);
@@ -519,6 +594,19 @@ clutter_stage_view_set_property (GObject      *object,
     }
 }
 
+static void
+clutter_stage_view_constructed (GObject *object)
+{
+  ClutterStageView *view = CLUTTER_STAGE_VIEW (object);
+  ClutterStageViewPrivate *priv =
+    clutter_stage_view_get_instance_private (view);
+
+  if (priv->use_shadowfb)
+    init_shadowfb (view);
+
+  G_OBJECT_CLASS (clutter_stage_view_parent_class)->constructed (object);
+}
+
 static void
 clutter_stage_view_dispose (GObject *object)
 {
@@ -558,6 +646,7 @@ clutter_stage_view_class_init (ClutterStageViewClass *klass)
 
   object_class->get_property = clutter_stage_view_get_property;
   object_class->set_property = clutter_stage_view_set_property;
+  object_class->constructed = clutter_stage_view_constructed;
   object_class->dispose = clutter_stage_view_dispose;
 
   obj_props[PROP_NAME] =
@@ -595,14 +684,14 @@ clutter_stage_view_class_init (ClutterStageViewClass *klass)
                         G_PARAM_CONSTRUCT_ONLY |
                         G_PARAM_STATIC_STRINGS);
 
-  obj_props[PROP_SHADOWFB] =
-    g_param_spec_boxed ("shadowfb",
-                        "Shadow framebuffer",
-                        "Framebuffer used as intermediate shadow buffer",
-                        COGL_TYPE_HANDLE,
-                        G_PARAM_READWRITE |
-                        G_PARAM_CONSTRUCT_ONLY |
-                        G_PARAM_STATIC_STRINGS);
+  obj_props[PROP_USE_SHADOWFB] =
+    g_param_spec_boolean ("use-shadowfb",
+                          "Use shadowfb",
+                          "Whether to use one or more shadow framebuffers",
+                          FALSE,
+                          G_PARAM_READWRITE |
+                          G_PARAM_CONSTRUCT_ONLY |
+                          G_PARAM_STATIC_STRINGS);
 
   obj_props[PROP_SCALE] =
     g_param_spec_float ("scale",
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index 7b47174a00..43611d3e4f 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -3150,7 +3150,7 @@ meta_renderer_native_create_view (MetaRenderer       *renderer,
   MetaMonitorTransform view_transform;
   CoglOnscreen *onscreen = NULL;
   CoglOffscreen *offscreen = NULL;
-  CoglOffscreen *shadowfb = NULL;
+  gboolean use_shadowfb;
   float scale;
   int onscreen_width;
   int onscreen_height;
@@ -3202,24 +3202,8 @@ meta_renderer_native_create_view (MetaRenderer       *renderer,
         g_error ("Failed to allocate back buffer texture: %s", error->message);
     }
 
-  if (should_force_shadow_fb (renderer_native,
-                              renderer_native->primary_gpu_kms))
-    {
-      int shadow_width;
-      int shadow_height;
-
-      /* The shadowfb must be the same size as the on-screen framebuffer */
-      shadow_width = cogl_framebuffer_get_width (COGL_FRAMEBUFFER (onscreen));
-      shadow_height = cogl_framebuffer_get_height (COGL_FRAMEBUFFER (onscreen));
-
-      shadowfb = meta_renderer_native_create_offscreen (renderer_native,
-                                                        cogl_context,
-                                                        shadow_width,
-                                                        shadow_height,
-                                                        &error);
-      if (!shadowfb)
-        g_error ("Failed to allocate shadow buffer texture: %s", error->message);
-    }
+  use_shadowfb = should_force_shadow_fb (renderer_native,
+                                         renderer_native->primary_gpu_kms);
 
   if (meta_is_stage_views_scaled ())
     scale = meta_logical_monitor_get_scale (logical_monitor);
@@ -3235,11 +3219,10 @@ meta_renderer_native_create_view (MetaRenderer       *renderer,
                        "scale", scale,
                        "framebuffer", onscreen,
                        "offscreen", offscreen,
-                       "shadowfb", shadowfb,
+                       "use-shadowfb", use_shadowfb,
                        "transform", view_transform,
                        NULL);
   g_clear_pointer (&offscreen, cogl_object_unref);
-  g_clear_pointer (&shadowfb, cogl_object_unref);
 
   meta_onscreen_native_set_view (onscreen, view);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]