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
This commit is contained in:
Olivier Fourdan 2019-10-22 17:05:46 +02:00
parent db90c0d509
commit 60800d2313

View File

@ -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);