summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Mader <robert.mader@posteo.de>2019-02-16 13:35:22 +0100
committerRobert Mader <robert.mader@posteo.de>2019-02-25 17:51:44 +0100
commitddd2ce3a88293633d309d99ed61ebf458ef3f42c (patch)
treed7f4c0027f41d1edbc6dc37e70e7407a1f9f9cfe
parent979e689278faebe4cb069d9be65f9b3d84ff9e2e (diff)
downloadmutter-ddd2ce3a88293633d309d99ed61ebf458ef3f42c.tar.gz
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
-rw-r--r--src/wayland/meta-wayland-buffer.c33
1 files 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);
- cogl_object_unref (bitmap);
+ 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);
- if (!cogl_texture_allocate (COGL_TEXTURE (texture_2d), error))
- g_clear_pointer (&texture_2d, cogl_object_unref);
+ 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);
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;