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 */