From 9e641f623fd917f7c795f0c07c64a7627923f566 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Mon, 1 Aug 2016 03:48:30 +0200 Subject: [PATCH] backends/native: Set offscreen on the transformed MetaRendererViews The texture is only created if the view is transformed at the software level, otherwise the texture is NULL, and rendering happens on the onscreen. https://bugzilla.gnome.org/show_bug.cgi?id=745079 --- src/backends/native/meta-renderer-native.c | 57 ++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c index 9867a5b4d..2093e0996 100644 --- a/src/backends/native/meta-renderer-native.c +++ b/src/backends/native/meta-renderer-native.c @@ -885,6 +885,39 @@ meta_renderer_native_create_onscreen (MetaRendererNative *renderer, return onscreen; } +static CoglOffscreen * +meta_renderer_native_create_offscreen (MetaRendererNative *renderer, + CoglContext *context, + MetaMonitorTransform transform, + gint view_width, + gint view_height) +{ + CoglOffscreen *fb; + CoglTexture2D *tex; + GError *error = NULL; + + tex = cogl_texture_2d_new_with_size (context, view_width, view_height); + cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (tex), FALSE); + + if (!cogl_texture_allocate (COGL_TEXTURE (tex), &error)) + { + cogl_object_unref (tex); + return FALSE; + } + + fb = cogl_offscreen_new_with_texture (COGL_TEXTURE (tex)); + cogl_object_unref (tex); + if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (fb), &error)) + { + g_warning ("Could not create offscreen: %s", error->message); + g_error_free (error); + cogl_object_unref (fb); + return FALSE; + } + + return fb; +} + gboolean meta_renderer_native_set_legacy_view_size (MetaRendererNative *renderer_native, MetaRendererView *view, @@ -1083,8 +1116,12 @@ meta_renderer_native_create_view (MetaRenderer *renderer, MetaBackend *backend = meta_get_backend (); ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); + CoglDisplay *cogl_display = cogl_context_get_display (cogl_context); + CoglDisplayEGL *egl_display = cogl_display->winsys; + CoglOnscreenEGL *egl_onscreen; MetaMonitorTransform transform; CoglOnscreen *onscreen = NULL; + CoglOffscreen *offscreen = NULL; MetaRendererView *view; transform = meta_renderer_native_get_monitor_info_transform (renderer, @@ -1098,13 +1135,33 @@ meta_renderer_native_create_view (MetaRenderer *renderer, if (!onscreen) meta_fatal ("Failed to allocate onscreen framebuffer\n"); + /* Ensure we don't point to stale surfaces when creating the offscreen */ + egl_onscreen = onscreen->winsys; + _cogl_winsys_egl_make_current (cogl_display, + egl_onscreen->egl_surface, + egl_onscreen->egl_surface, + egl_display->egl_context); + + if (transform != META_MONITOR_TRANSFORM_NORMAL) + { + offscreen = meta_renderer_native_create_offscreen (META_RENDERER_NATIVE (renderer), + cogl_context, + transform, + monitor_info->rect.width, + monitor_info->rect.height); + if (!offscreen) + meta_fatal ("Failed to allocate back buffer texture\n"); + } + view = g_object_new (META_TYPE_RENDERER_VIEW, "layout", &monitor_info->rect, "framebuffer", onscreen, + "offscreen", offscreen, "monitor-info", monitor_info, "transform", transform, NULL); cogl_object_unref (onscreen); + g_clear_pointer (&offscreen, cogl_object_unref); meta_onscreen_native_set_view (onscreen, view);