From f13157f4bbde5a505ca885fbcc342c809b572f01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Tue, 24 Feb 2015 18:10:07 +0800 Subject: [PATCH] wayland: Don't allocate a full size SHM buffer when drawing using OpenGL Before this patch, we'd always allocate a full size SHM buffer via the wl_shm_pool, even though it would never be used. Instead allocate a logical 1x1 cairo image surface. https://bugzilla.gnome.org/show_bug.cgi?id=745076 --- gdk/wayland/gdkdisplay-wayland.c | 6 ++++++ gdk/wayland/gdkprivate-wayland.h | 1 + gdk/wayland/gdkwindow-wayland.c | 25 +++++++++++++++++++++++-- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index 0be9ab6965..46c3cc35c8 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -834,6 +834,12 @@ _gdk_wayland_shm_surface_get_busy (cairo_surface_t *surface) return data->busy; } +gboolean +_gdk_wayland_is_shm_surface (cairo_surface_t *surface) +{ + return cairo_surface_get_user_data (surface, &gdk_wayland_cairo_key) != NULL; +} + GdkWaylandSelection * gdk_wayland_display_get_selection (GdkDisplay *display) { diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h index adfff19fab..8a97df0828 100644 --- a/gdk/wayland/gdkprivate-wayland.h +++ b/gdk/wayland/gdkprivate-wayland.h @@ -219,6 +219,7 @@ cairo_surface_t * _gdk_wayland_display_create_shm_surface (GdkWaylandDisplay *di struct wl_buffer *_gdk_wayland_shm_surface_get_wl_buffer (cairo_surface_t *surface); void _gdk_wayland_shm_surface_set_busy (cairo_surface_t *surface); gboolean _gdk_wayland_shm_surface_get_busy (cairo_surface_t *surface); +gboolean _gdk_wayland_is_shm_surface (cairo_surface_t *surface); GdkWaylandSelection * gdk_wayland_display_get_selection (GdkDisplay *display); GdkWaylandSelection * gdk_wayland_selection_new (void); diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index b5f048afcd..23d6d08ffd 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -393,6 +393,8 @@ on_frame_clock_after_paint (GdkFrameClock *clock, if (!impl->pending_commit) return; + g_assert (_gdk_wayland_is_shm_surface (impl->cairo_surface)); + impl->pending_commit = FALSE; impl->pending_frame_counter = gdk_frame_clock_get_frame_counter (clock); @@ -522,6 +524,8 @@ gdk_wayland_window_attach_image (GdkWindow *window) if (GDK_WINDOW_DESTROYED (window)) return; + g_assert (_gdk_wayland_is_shm_surface (impl->cairo_surface)); + /* Attach this new buffer to the surface */ wl_surface_attach (impl->surface, _gdk_wayland_shm_surface_get_wl_buffer (impl->cairo_surface), @@ -539,7 +543,21 @@ static void gdk_wayland_window_ensure_cairo_surface (GdkWindow *window) { GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); - if (!impl->cairo_surface) + + /* If we are drawing using OpenGL then we only need a logical 1x1 surface. */ + if (impl->egl_window) + { + if (impl->cairo_surface && + _gdk_wayland_is_shm_surface (impl->cairo_surface)) + cairo_surface_destroy (impl->cairo_surface); + + impl->cairo_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, + impl->scale, + impl->scale); + cairo_surface_set_device_scale (impl->cairo_surface, + impl->scale, impl->scale); + } + else if (!impl->cairo_surface) { GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (impl->wrapper)); @@ -582,7 +600,10 @@ gdk_window_impl_wayland_begin_paint (GdkWindow *window) { GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); gdk_wayland_window_ensure_cairo_surface (window); - return _gdk_wayland_shm_surface_get_busy (impl->cairo_surface); + if (_gdk_wayland_is_shm_surface (impl->cairo_surface)) + return _gdk_wayland_shm_surface_get_busy (impl->cairo_surface); + else + return FALSE; } static void