[mutter] x11/nested: Always draw to an offscreen framebuffer



commit 93c6a869ece2c4be31b2e938e71d7f52defac1e4
Author: Jonas Ådahl <jadahl gmail com>
Date:   Mon Mar 20 17:04:45 2017 +0800

    x11/nested: Always draw to an offscreen framebuffer
    
    Always draw the stage to an offscreen framebuffer when using the nested
    backend, so that we more emulate things more similarly to how it works
    real-world, i.e. it'll work the way whether stage views are enabled or
    not.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=777732

 src/backends/x11/meta-stage-x11-nested.c           |   33 ++++--
 src/backends/x11/nested/meta-renderer-x11-nested.c |  129 +++++++++++++++++---
 src/backends/x11/nested/meta-renderer-x11-nested.h |    4 +
 3 files changed, 138 insertions(+), 28 deletions(-)
---
diff --git a/src/backends/x11/meta-stage-x11-nested.c b/src/backends/x11/meta-stage-x11-nested.c
index ff9d63b..b2732c3 100644
--- a/src/backends/x11/meta-stage-x11-nested.c
+++ b/src/backends/x11/meta-stage-x11-nested.c
@@ -28,6 +28,7 @@
 
 #include "backends/meta-backend-private.h"
 #include "backends/meta-renderer.h"
+#include "backends/x11/nested/meta-renderer-x11-nested.h"
 #include "clutter/clutter-mutter.h"
 
 static ClutterStageWindowIface *clutter_stage_window_parent_iface = NULL;
@@ -53,6 +54,25 @@ typedef struct _ClutterStageX11View
   ClutterStageViewCogl *view;
 } MetaStageX11NestedView;
 
+static void
+meta_stage_x11_nested_resize (ClutterStageWindow *stage_window,
+                              gint                width,
+                              gint                height)
+{
+  if (!meta_is_stage_views_enabled ())
+    {
+      MetaBackend *backend = meta_get_backend ();
+      MetaRenderer *renderer = meta_backend_get_renderer (backend);
+      MetaRendererX11Nested *renderer_x11_nested =
+        META_RENDERER_X11_NESTED (renderer);
+
+      meta_renderer_x11_nested_ensure_legacy_view (renderer_x11_nested,
+                                                   width, height);
+    }
+
+  clutter_stage_window_parent_iface->resize (stage_window, width, height);
+}
+
 static gboolean
 meta_stage_x11_nested_can_clip_redraws (ClutterStageWindow *stage_window)
 {
@@ -65,10 +85,7 @@ meta_stage_x11_nested_get_views (ClutterStageWindow *stage_window)
   MetaBackend *backend = meta_get_backend ();
   MetaRenderer *renderer = meta_backend_get_renderer (backend);
 
-  if (meta_is_stage_views_enabled ())
-    return meta_renderer_get_views (renderer);
-  else
-    return clutter_stage_window_parent_iface->get_views (stage_window);
+  return meta_renderer_get_views (renderer);
 }
 
 static void
@@ -82,12 +99,6 @@ meta_stage_x11_nested_finish_frame (ClutterStageWindow *stage_window)
   CoglFramebuffer *onscreen = COGL_FRAMEBUFFER (stage_x11->onscreen);
   GList *l;
 
-  /*
-   * If we are in legacy mode, the stage is already on the onscreen.
-   */
-  if (!meta_is_stage_views_enabled ())
-    return;
-
   if (!stage_nested->pipeline)
     stage_nested->pipeline = cogl_pipeline_new (clutter_backend->cogl_context);
 
@@ -177,9 +188,9 @@ clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
 {
   clutter_stage_window_parent_iface = g_type_interface_peek_parent (iface);
 
+  iface->resize = meta_stage_x11_nested_resize;
   iface->can_clip_redraws = meta_stage_x11_nested_can_clip_redraws;
   iface->unrealize = meta_stage_x11_nested_unrealize;
   iface->get_views = meta_stage_x11_nested_get_views;
   iface->finish_frame = meta_stage_x11_nested_finish_frame;
 }
-
diff --git a/src/backends/x11/nested/meta-renderer-x11-nested.c 
b/src/backends/x11/nested/meta-renderer-x11-nested.c
index 124ceef..8162062 100644
--- a/src/backends/x11/nested/meta-renderer-x11-nested.c
+++ b/src/backends/x11/nested/meta-renderer-x11-nested.c
@@ -66,6 +66,104 @@ calculate_view_transform (MetaMonitorManager *monitor_manager,
 }
 
 static MetaRendererView *
+get_legacy_view (MetaRenderer *renderer)
+{
+  GList *views;
+
+  views = meta_renderer_get_views (renderer);
+  if (views)
+    return META_RENDERER_VIEW (views->data);
+  else
+    return NULL;
+}
+
+static CoglOffscreen *
+create_offscreen (CoglContext *cogl_context,
+                  int          width,
+                  int          height)
+{
+  CoglTexture2D *texture_2d;
+  CoglOffscreen *offscreen;
+  GError *error = NULL;
+
+  texture_2d = cogl_texture_2d_new_with_size (cogl_context, width, height);
+  offscreen = cogl_offscreen_new_with_texture (COGL_TEXTURE (texture_2d));
+
+  if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (offscreen), &error))
+    meta_fatal ("Couldn't allocate framebuffer: %s", error->message);
+
+  return offscreen;
+}
+
+static void
+meta_renderer_x11_nested_resize_legacy_view (MetaRendererX11Nested *renderer_x11_nested,
+                                             int                    width,
+                                             int                    height)
+{
+  MetaRenderer *renderer = META_RENDERER (renderer_x11_nested);
+  MetaBackend *backend = meta_get_backend ();
+  ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
+  CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
+  MetaRendererView *legacy_view;
+  cairo_rectangle_int_t view_layout;
+  CoglOffscreen *fake_onscreen;
+
+  legacy_view = get_legacy_view (renderer);
+
+  clutter_stage_view_get_layout (CLUTTER_STAGE_VIEW (legacy_view),
+                                 &view_layout);
+  if (view_layout.width == width &&
+      view_layout.height == height)
+    return;
+
+  view_layout = (cairo_rectangle_int_t) {
+      .width = width,
+        .height = height
+  };
+
+  fake_onscreen = create_offscreen (cogl_context, width, height);
+
+  g_object_set (G_OBJECT (legacy_view),
+                "layout", &view_layout,
+                "framebuffer", COGL_FRAMEBUFFER (fake_onscreen),
+                NULL);
+}
+
+void
+meta_renderer_x11_nested_ensure_legacy_view (MetaRendererX11Nested *renderer_x11_nested,
+                                             int                    width,
+                                             int                    height)
+{
+  MetaRenderer *renderer = META_RENDERER (renderer_x11_nested);
+  MetaBackend *backend = meta_get_backend ();
+  ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
+  CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
+  cairo_rectangle_int_t view_layout;
+  CoglOffscreen *fake_onscreen;
+  MetaRendererView *legacy_view;
+
+  if (get_legacy_view (renderer))
+    {
+      meta_renderer_x11_nested_resize_legacy_view (renderer_x11_nested,
+                                                   width, height);
+      return;
+    }
+
+  fake_onscreen = create_offscreen (cogl_context, width, height);
+
+  view_layout = (cairo_rectangle_int_t) {
+    .width = width,
+    .height = height
+  };
+  legacy_view = g_object_new (META_TYPE_RENDERER_VIEW,
+                              "layout", &view_layout,
+                              "framebuffer", COGL_FRAMEBUFFER (fake_onscreen),
+                              NULL);
+
+  meta_renderer_set_legacy_view (renderer, legacy_view);
+}
+
+static MetaRendererView *
 meta_renderer_x11_nested_create_view (MetaRenderer       *renderer,
                                       MetaLogicalMonitor *logical_monitor)
 {
@@ -77,10 +175,8 @@ meta_renderer_x11_nested_create_view (MetaRenderer       *renderer,
   MetaMonitorTransform view_transform;
   int view_scale;
   int width, height;
-  CoglTexture2D *texture_2d;
   CoglOffscreen *fake_onscreen;
   CoglOffscreen *offscreen;
-  GError *error = NULL;
 
   view_transform = calculate_view_transform (monitor_manager, logical_monitor);
 
@@ -89,26 +185,25 @@ meta_renderer_x11_nested_create_view (MetaRenderer       *renderer,
   else
     view_scale = 1;
 
-  width = logical_monitor->rect.width * view_scale;
-  height = logical_monitor->rect.height * view_scale;
-
-  texture_2d = cogl_texture_2d_new_with_size (cogl_context, width, height);
-  fake_onscreen = cogl_offscreen_new_with_texture (COGL_TEXTURE (texture_2d));
-
-  if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (fake_onscreen), &error))
-    meta_fatal ("Couldn't allocate framebuffer: %s", error->message);
-
-  if (view_transform != META_MONITOR_TRANSFORM_NORMAL)
+  if (meta_monitor_transform_is_rotated (view_transform))
     {
-      texture_2d = cogl_texture_2d_new_with_size (cogl_context, width, height);
-      offscreen = cogl_offscreen_new_with_texture (COGL_TEXTURE (texture_2d));
-      if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (offscreen), &error))
-        meta_fatal ("Couldn't allocate offscreen framebuffer: %s", error->message);
+      width = logical_monitor->rect.height;
+      height = logical_monitor->rect.width;
     }
   else
     {
-      offscreen = NULL;
+      width = logical_monitor->rect.width;
+      height = logical_monitor->rect.height;
     }
+  width *= view_scale;
+  height *= view_scale;
+
+  fake_onscreen = create_offscreen (cogl_context, width, height);
+
+  if (view_transform != META_MONITOR_TRANSFORM_NORMAL)
+    offscreen = create_offscreen (cogl_context, width, height);
+  else
+    offscreen = NULL;
 
   return g_object_new (META_TYPE_RENDERER_VIEW,
                        "layout", &logical_monitor->rect,
diff --git a/src/backends/x11/nested/meta-renderer-x11-nested.h 
b/src/backends/x11/nested/meta-renderer-x11-nested.h
index c766db8..9fc88e8 100644
--- a/src/backends/x11/nested/meta-renderer-x11-nested.h
+++ b/src/backends/x11/nested/meta-renderer-x11-nested.h
@@ -30,4 +30,8 @@ G_DECLARE_FINAL_TYPE (MetaRendererX11Nested, meta_renderer_x11_nested,
                       META, RENDERER_X11_NESTED,
                       MetaRendererX11)
 
+void meta_renderer_x11_nested_ensure_legacy_view (MetaRendererX11Nested *renderer_x11_nested,
+                                                  int                    width,
+                                                  int                    height);
+
 #endif /* META_RENDERER_X11_NESTED_H */


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