From 60800d231395cfdeaa7c1fb8d24f7c7830c56bb5 Mon Sep 17 00:00:00 2001 From: Olivier Fourdan Date: Tue, 22 Oct 2019 17:05:46 +0200 Subject: [PATCH] renderer-native: Separate offscreen and shadowfb Create the intermediate shadow framebuffer for use exclusively when a shadowfb is required. Keep the previous offscreen framebuffer is as an intermediate framebuffer for transformations only. This way, we can apply transformations between in-memory framebuffers prior to blit the result to screen, and achieve acceptable performance even with software rendering on discrete GPU. https://gitlab.gnome.org/GNOME/mutter/merge_requests/877 --- src/backends/native/meta-renderer-native.c | 29 ++++++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c index 5c01375c8..84b6a7323 100644 --- a/src/backends/native/meta-renderer-native.c +++ b/src/backends/native/meta-renderer-native.c @@ -3053,7 +3053,6 @@ meta_renderer_native_create_onscreen (MetaRendererNative *renderer_native, static CoglOffscreen * meta_renderer_native_create_offscreen (MetaRendererNative *renderer, CoglContext *context, - MetaMonitorTransform transform, gint view_width, gint view_height, GError **error) @@ -3256,6 +3255,7 @@ meta_renderer_native_create_view (MetaRenderer *renderer, MetaMonitorTransform view_transform; CoglOnscreen *onscreen = NULL; CoglOffscreen *offscreen = NULL; + CoglOffscreen *shadowfb = NULL; float scale; int width, height; MetaRendererView *view; @@ -3282,18 +3282,35 @@ meta_renderer_native_create_view (MetaRenderer *renderer, if (!onscreen) g_error ("Failed to allocate onscreen framebuffer: %s", error->message); - if (view_transform != META_MONITOR_TRANSFORM_NORMAL || - should_force_shadow_fb (renderer_native, - renderer_native->primary_gpu_kms)) + if (view_transform != META_MONITOR_TRANSFORM_NORMAL) { offscreen = meta_renderer_native_create_offscreen (renderer_native, cogl_context, - view_transform, width, height, &error); if (!offscreen) 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); } view = g_object_new (META_TYPE_RENDERER_VIEW, @@ -3301,10 +3318,12 @@ meta_renderer_native_create_view (MetaRenderer *renderer, "scale", scale, "framebuffer", onscreen, "offscreen", offscreen, + "shadowfb", shadowfb, "logical-monitor", logical_monitor, "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);