From ddd2ce3a88293633d309d99ed61ebf458ef3f42c Mon Sep 17 00:00:00 2001 From: Robert Mader Date: Sat, 16 Feb 2019 13:35:22 +0100 Subject: [PATCH] wayland/buffer: Fall back to CoglTexture2DSliced XWayland creates buffers of the combined size of all connected displays. This can, especially on older but still in use hardware, exceed the limits of the GPU. If that is the case, use `CoglTexture2DSliced` instead of `CoglTexture2D` https://gitlab.gnome.org/GNOME/mutter/merge_requests/447 --- src/wayland/meta-wayland-buffer.c | 33 +++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/src/wayland/meta-wayland-buffer.c b/src/wayland/meta-wayland-buffer.c index 8fda90016..ac2eb98b7 100644 --- a/src/wayland/meta-wayland-buffer.c +++ b/src/wayland/meta-wayland-buffer.c @@ -209,7 +209,7 @@ shm_buffer_attach (MetaWaylandBuffer *buffer, CoglPixelFormat format; CoglTextureComponents components; CoglBitmap *bitmap; - CoglTexture2D *texture_2d; + CoglTexture *new_texture; shm_buffer = wl_shm_buffer_get (buffer->resource); stride = wl_shm_buffer_get_stride (shm_buffer); @@ -238,20 +238,37 @@ shm_buffer_attach (MetaWaylandBuffer *buffer, stride, wl_shm_buffer_get_data (shm_buffer)); - texture_2d = cogl_texture_2d_new_from_bitmap (bitmap); - cogl_texture_set_components (COGL_TEXTURE (texture_2d), components); + new_texture = COGL_TEXTURE (cogl_texture_2d_new_from_bitmap (bitmap)); + cogl_texture_set_components (new_texture, components); + + if (!cogl_texture_allocate (new_texture, error)) + { + g_clear_pointer (&new_texture, cogl_object_unref); + if (g_error_matches (*error, COGL_TEXTURE_ERROR, COGL_TEXTURE_ERROR_SIZE)) + { + CoglTexture2DSliced *texture_sliced; + + g_clear_error (error); + + texture_sliced = + cogl_texture_2d_sliced_new_from_bitmap (bitmap, + COGL_TEXTURE_MAX_WASTE); + new_texture = COGL_TEXTURE (texture_sliced); + cogl_texture_set_components (new_texture, components); + + if (!cogl_texture_allocate (new_texture, error)) + g_clear_pointer (&new_texture, cogl_object_unref); + } + } cogl_object_unref (bitmap); - if (!cogl_texture_allocate (COGL_TEXTURE (texture_2d), error)) - g_clear_pointer (&texture_2d, cogl_object_unref); - wl_shm_buffer_end_access (shm_buffer); - if (!texture_2d) + if (!new_texture) return FALSE; - *texture = COGL_TEXTURE (texture_2d); + *texture = new_texture; *changed_texture = TRUE; buffer->is_y_inverted = TRUE;