From 93c6a869ece2c4be31b2e938e71d7f52defac1e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Mon, 20 Mar 2017 17:04:45 +0800 Subject: [PATCH] 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 +++-- .../x11/nested/meta-renderer-x11-nested.c | 129 +++++++++++++++--- .../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 ff9d63b00..b2732c345 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 124ceef90..8162062d6 100644 --- a/src/backends/x11/nested/meta-renderer-x11-nested.c +++ b/src/backends/x11/nested/meta-renderer-x11-nested.c @@ -65,6 +65,104 @@ calculate_view_transform (MetaMonitorManager *monitor_manager, return logical_monitor->transform; } +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 c766db84c..9fc88e85b 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 */