[mutter] MetaCursorSprite: Put renderer specific code in the renderer
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] MetaCursorSprite: Put renderer specific code in the renderer
- Date: Fri, 28 Aug 2015 02:08:54 +0000 (UTC)
commit d3fdaa3232e4ff258f86f3020c2814385ef581e8
Author: Jonas Ådahl <jadahl gmail com>
Date: Wed Mar 11 11:16:58 2015 +0800
MetaCursorSprite: Put renderer specific code in the renderer
There were lots of code handling the native renderer specific cases;
move these parts to the renderer. Note that this causes the X11 case to
always generate the texture which is a waste of memory, but his
regression will be fixed in a following commit.
The lazy loading of the texture was removed because it was eventually
always loaded anyway indirectly by the renderer to calculate the
current rect.
https://bugzilla.gnome.org/show_bug.cgi?id=744932
src/backends/meta-cursor-renderer.c | 25 ++
src/backends/meta-cursor-renderer.h | 22 ++
src/backends/meta-cursor.c | 254 ++++-----------------
src/backends/meta-cursor.h | 12 +-
src/backends/native/meta-cursor-renderer-native.c | 210 ++++++++++++++++-
5 files changed, 294 insertions(+), 229 deletions(-)
---
diff --git a/src/backends/meta-cursor-renderer.c b/src/backends/meta-cursor-renderer.c
index 5509288..689ac26 100644
--- a/src/backends/meta-cursor-renderer.c
+++ b/src/backends/meta-cursor-renderer.c
@@ -181,3 +181,28 @@ meta_cursor_renderer_get_rect (MetaCursorRenderer *renderer)
return &priv->current_rect;
}
+
+#ifdef HAVE_WAYLAND
+void
+meta_cursor_renderer_realize_cursor_from_wl_buffer (MetaCursorRenderer *renderer,
+ MetaCursorSprite *cursor_sprite,
+ struct wl_resource *buffer)
+{
+
+ MetaCursorRendererClass *renderer_class = META_CURSOR_RENDERER_GET_CLASS (renderer);
+
+ if (renderer_class->realize_cursor_from_wl_buffer)
+ renderer_class->realize_cursor_from_wl_buffer (renderer, cursor_sprite, buffer);
+}
+#endif
+
+void
+meta_cursor_renderer_realize_cursor_from_xcursor (MetaCursorRenderer *renderer,
+ MetaCursorSprite *cursor_sprite,
+ XcursorImage *xc_image)
+{
+ MetaCursorRendererClass *renderer_class = META_CURSOR_RENDERER_GET_CLASS (renderer);
+
+ if (renderer_class->realize_cursor_from_xcursor)
+ renderer_class->realize_cursor_from_xcursor (renderer, cursor_sprite, xc_image);
+}
diff --git a/src/backends/meta-cursor-renderer.h b/src/backends/meta-cursor-renderer.h
index 7a554e8..337d5c1 100644
--- a/src/backends/meta-cursor-renderer.h
+++ b/src/backends/meta-cursor-renderer.h
@@ -26,6 +26,10 @@
#define META_CURSOR_RENDERER_H
#include <glib-object.h>
+#include <X11/Xcursor/Xcursor.h>
+#ifdef HAVE_WAYLAND
+#include <wayland-server.h>
+#endif
#include <meta/screen.h>
#include "meta-cursor.h"
@@ -39,6 +43,14 @@ struct _MetaCursorRendererClass
GObjectClass parent_class;
gboolean (* update_cursor) (MetaCursorRenderer *renderer);
+#ifdef HAVE_WAYLAND
+ void (* realize_cursor_from_wl_buffer) (MetaCursorRenderer *renderer,
+ MetaCursorSprite *cursor_sprite,
+ struct wl_resource *buffer);
+#endif
+ void (* realize_cursor_from_xcursor) (MetaCursorRenderer *renderer,
+ MetaCursorSprite *cursor_sprite,
+ XcursorImage *xc_image);
};
GType meta_cursor_renderer_get_type (void) G_GNUC_CONST;
@@ -55,4 +67,14 @@ void meta_cursor_renderer_force_update (MetaCursorRenderer *renderer);
MetaCursorSprite * meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer);
const MetaRectangle * meta_cursor_renderer_get_rect (MetaCursorRenderer *renderer);
+#ifdef HAVE_WAYLAND
+void meta_cursor_renderer_realize_cursor_from_wl_buffer (MetaCursorRenderer *renderer,
+ MetaCursorSprite *cursor_sprite,
+ struct wl_resource *buffer);
+#endif
+
+void meta_cursor_renderer_realize_cursor_from_xcursor (MetaCursorRenderer *renderer,
+ MetaCursorSprite *cursor_sprite,
+ XcursorImage *xc_image);
+
#endif /* META_CURSOR_RENDERER_H */
diff --git a/src/backends/meta-cursor.c b/src/backends/meta-cursor.c
index 706984d..8c09516 100644
--- a/src/backends/meta-cursor.c
+++ b/src/backends/meta-cursor.c
@@ -29,11 +29,6 @@
#include "screen-private.h"
#include "meta-backend-private.h"
-#ifdef HAVE_NATIVE_BACKEND
-#include <gbm.h>
-#include "backends/native/meta-cursor-renderer-native.h"
-#endif
-
#include <string.h>
#include <X11/cursorfont.h>
@@ -48,10 +43,6 @@ typedef struct
{
CoglTexture2D *texture;
int hot_x, hot_y;
-
-#ifdef HAVE_NATIVE_BACKEND
- struct gbm_bo *bo;
-#endif
} MetaCursorImage;
struct _MetaCursorSprite
@@ -74,11 +65,6 @@ meta_cursor_image_free (MetaCursorImage *image)
{
if (image->texture)
cogl_object_unref (image->texture);
-
-#ifdef HAVE_NATIVE_BACKEND
- if (image->bo)
- gbm_bo_destroy (image->bo);
-#endif
}
static const char *
@@ -144,81 +130,13 @@ load_cursor_on_client (MetaCursor cursor)
meta_prefs_get_cursor_size ());
}
-#ifdef HAVE_NATIVE_BACKEND
-static void
-get_hardware_cursor_size (uint64_t *cursor_width, uint64_t *cursor_height)
-{
- MetaBackend *meta_backend = meta_get_backend ();
- MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (meta_backend);
-
- if (META_IS_CURSOR_RENDERER_NATIVE (renderer))
- {
- meta_cursor_renderer_native_get_cursor_size (META_CURSOR_RENDERER_NATIVE (renderer), cursor_width,
cursor_height);
- return;
- }
-
- g_assert_not_reached ();
-}
-#endif
-
-#ifdef HAVE_NATIVE_BACKEND
static void
-meta_cursor_image_load_gbm_buffer (struct gbm_device *gbm,
- MetaCursorImage *image,
- uint8_t *pixels,
- uint width,
- uint height,
- int rowstride,
- uint32_t gbm_format)
-{
- uint64_t cursor_width, cursor_height;
- get_hardware_cursor_size (&cursor_width, &cursor_height);
-
- if (width > cursor_width || height > cursor_height)
- {
- meta_warning ("Invalid theme cursor size (must be at most %ux%u)\n",
- (unsigned int)cursor_width, (unsigned int)cursor_height);
- return;
- }
-
- if (gbm_device_is_format_supported (gbm, gbm_format,
- GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE))
- {
- uint8_t buf[4 * cursor_width * cursor_height];
- uint i;
-
- image->bo = gbm_bo_create (gbm, cursor_width, cursor_height,
- gbm_format, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
-
- memset (buf, 0, sizeof(buf));
- for (i = 0; i < height; i++)
- memcpy (buf + i * 4 * cursor_width, pixels + i * rowstride, width * 4);
-
- gbm_bo_write (image->bo, buf, cursor_width * cursor_height * 4);
- }
- else
- meta_warning ("HW cursor for format %d not supported\n", gbm_format);
-}
-#endif
-
-#ifdef HAVE_NATIVE_BACKEND
-static struct gbm_device *
-get_gbm_device (void)
+meta_cursor_sprite_load_from_xcursor_image (MetaCursorSprite *self,
+ XcursorImage *xc_image)
{
+ MetaCursorImage *image = &self->image;
MetaBackend *meta_backend = meta_get_backend ();
MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (meta_backend);
-
- if (META_IS_CURSOR_RENDERER_NATIVE (renderer))
- return meta_cursor_renderer_native_get_gbm_device (META_CURSOR_RENDERER_NATIVE (renderer));
- else
- return NULL;
-}
-#endif
-
-static void
-meta_cursor_image_load_from_xcursor_image (MetaCursorImage *image,
- XcursorImage *xc_image)
-{
uint width, height, rowstride;
CoglPixelFormat cogl_format;
ClutterBackend *clutter_backend;
@@ -246,15 +164,7 @@ meta_cursor_image_load_from_xcursor_image (MetaCursorImage *image,
(uint8_t *) xc_image->pixels,
NULL);
-#ifdef HAVE_NATIVE_BACKEND
- struct gbm_device *gbm = get_gbm_device ();
- if (gbm)
- meta_cursor_image_load_gbm_buffer (gbm,
- image,
- (uint8_t *) xc_image->pixels,
- width, height, rowstride,
- GBM_FORMAT_ARGB8888);
-#endif
+ meta_cursor_renderer_realize_cursor_from_xcursor (renderer, self, xc_image);
}
static XcursorImage *
@@ -278,7 +188,7 @@ meta_cursor_sprite_tick_frame (MetaCursorSprite *self)
meta_cursor_image_free (&self->image);
image = meta_cursor_sprite_get_current_frame_image (self);
- meta_cursor_image_load_from_xcursor_image (&self->image, image);
+ meta_cursor_sprite_load_from_xcursor_image (self, image);
}
guint
@@ -297,36 +207,22 @@ meta_cursor_sprite_is_animated (MetaCursorSprite *self)
self->xcursor_images->nimage > 1);
}
-static void
-load_cursor_image (MetaCursorSprite *self)
-{
- XcursorImage *image;
-
- /* Either cursors are loaded from X cursors or buffers. Since
- * buffers are converted over immediately, we can make sure to
- * load this directly. */
- g_assert (self->cursor != META_CURSOR_NONE);
-
- if (!self->xcursor_images)
- {
- self->current_frame = 0;
- self->xcursor_images = load_cursor_on_client (self->cursor);
- if (!self->xcursor_images)
- meta_fatal ("Could not find cursor. Perhaps set XCURSOR_PATH?");
- }
-
- image = meta_cursor_sprite_get_current_frame_image (self);
- meta_cursor_image_load_from_xcursor_image (&self->image, image);
-}
-
MetaCursorSprite *
meta_cursor_sprite_from_theme (MetaCursor cursor)
{
MetaCursorSprite *self;
+ XcursorImage *image;
self = g_object_new (META_TYPE_CURSOR_SPRITE, NULL);
self->cursor = cursor;
+ self->current_frame = 0;
+ self->xcursor_images = load_cursor_on_client (self->cursor);
+ if (!self->xcursor_images)
+ meta_fatal ("Could not find cursor. Perhaps set XCURSOR_PATH?");
+
+ image = meta_cursor_sprite_get_current_frame_image (self);
+ meta_cursor_sprite_load_from_xcursor_image (self, image);
return self;
}
@@ -351,11 +247,15 @@ meta_cursor_sprite_from_texture (CoglTexture2D *texture,
#ifdef HAVE_WAYLAND
static void
-meta_cursor_image_load_from_buffer (MetaCursorImage *image,
- struct wl_resource *buffer,
- int hot_x,
- int hot_y)
+meta_cursor_sprite_load_from_buffer (MetaCursorSprite *self,
+ struct wl_resource *buffer,
+ int hot_x,
+ int hot_y)
{
+ MetaCursorImage *image = &self->image;
+ MetaBackend *meta_backend = meta_get_backend ();
+ MetaCursorRenderer *renderer =
+ meta_backend_get_cursor_renderer (meta_backend);
ClutterBackend *backend;
CoglContext *cogl_context;
@@ -367,76 +267,7 @@ meta_cursor_image_load_from_buffer (MetaCursorImage *image,
image->texture = cogl_wayland_texture_2d_new_from_buffer (cogl_context, buffer, NULL);
-#ifdef HAVE_NATIVE_BACKEND
- struct gbm_device *gbm = get_gbm_device ();
- if (gbm)
- {
- uint32_t gbm_format;
- uint64_t cursor_width, cursor_height;
- uint width, height;
-
- width = cogl_texture_get_width (COGL_TEXTURE (image->texture));
- height = cogl_texture_get_height (COGL_TEXTURE (image->texture));
-
- struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (buffer);
- if (shm_buffer)
- {
- int rowstride = wl_shm_buffer_get_stride (shm_buffer);
-
- wl_shm_buffer_begin_access (shm_buffer);
-
- switch (wl_shm_buffer_get_format (shm_buffer))
- {
-#if G_BYTE_ORDER == G_BIG_ENDIAN
- case WL_SHM_FORMAT_ARGB8888:
- gbm_format = GBM_FORMAT_ARGB8888;
- break;
- case WL_SHM_FORMAT_XRGB8888:
- gbm_format = GBM_FORMAT_XRGB8888;
- break;
-#else
- case WL_SHM_FORMAT_ARGB8888:
- gbm_format = GBM_FORMAT_ARGB8888;
- break;
- case WL_SHM_FORMAT_XRGB8888:
- gbm_format = GBM_FORMAT_XRGB8888;
- break;
-#endif
- default:
- g_warn_if_reached ();
- gbm_format = GBM_FORMAT_ARGB8888;
- }
-
- meta_cursor_image_load_gbm_buffer (gbm,
- image,
- (uint8_t *) wl_shm_buffer_get_data (shm_buffer),
- width, height, rowstride,
- gbm_format);
-
- wl_shm_buffer_end_access (shm_buffer);
- }
- else
- {
- /* HW cursors have a predefined size (at least 64x64), which usually is bigger than cursor theme
- size, so themed cursors must be padded with transparent pixels to fill the
- overlay. This is trivial if we have CPU access to the data, but it's not
- possible if the buffer is in GPU memory (and possibly tiled too), so if we
- don't get the right size, we fallback to GL.
- */
- get_hardware_cursor_size (&cursor_width, &cursor_height);
-
- if (width != cursor_width || height != cursor_height)
- {
- meta_warning ("Invalid cursor size (must be 64x64), falling back to software (GL) cursors\n");
- return;
- }
-
- image->bo = gbm_bo_import (gbm, GBM_BO_IMPORT_WL_BUFFER, buffer, GBM_BO_USE_CURSOR);
- if (!image->bo)
- meta_warning ("Importing HW cursor from wl_buffer failed\n");
- }
- }
-#endif
+ meta_cursor_renderer_realize_cursor_from_wl_buffer (renderer, self, buffer);
}
MetaCursorSprite *
@@ -448,7 +279,7 @@ meta_cursor_sprite_from_buffer (struct wl_resource *buffer,
self = g_object_new (META_TYPE_CURSOR_SPRITE, NULL);
- meta_cursor_image_load_from_buffer (&self->image, buffer, hot_x, hot_y);
+ meta_cursor_sprite_load_from_buffer (self, buffer, hot_x, hot_y);
return self;
}
@@ -459,9 +290,6 @@ meta_cursor_sprite_get_cogl_texture (MetaCursorSprite *self,
int *hot_x,
int *hot_y)
{
- if (!self->image.texture)
- load_cursor_image (self);
-
if (hot_x)
*hot_x = self->image.hot_x;
if (hot_y)
@@ -470,27 +298,31 @@ meta_cursor_sprite_get_cogl_texture (MetaCursorSprite *self,
return COGL_TEXTURE (self->image.texture);
}
-#ifdef HAVE_NATIVE_BACKEND
-struct gbm_bo *
-meta_cursor_sprite_get_gbm_bo (MetaCursorSprite *self,
- int *hot_x,
- int *hot_y)
+MetaCursor
+meta_cursor_sprite_get_meta_cursor (MetaCursorSprite *self)
{
- if (!self->image.bo)
- load_cursor_image (self);
+ return self->cursor;
+}
- if (hot_x)
- *hot_x = self->image.hot_x;
- if (hot_y)
- *hot_y = self->image.hot_y;
- return self->image.bo;
+void
+meta_cursor_sprite_get_hotspot (MetaCursorSprite *self,
+ int *hot_x,
+ int *hot_y)
+{
+ *hot_x = self->image.hot_x;
+ *hot_y = self->image.hot_y;
}
-#endif
-MetaCursor
-meta_cursor_sprite_get_meta_cursor (MetaCursorSprite *self)
+guint
+meta_cursor_sprite_get_width (MetaCursorSprite *self)
{
- return self->cursor;
+ return cogl_texture_get_width (COGL_TEXTURE (self->image.texture));
+}
+
+guint
+meta_cursor_sprite_get_height (MetaCursorSprite *self)
+{
+ return cogl_texture_get_height (COGL_TEXTURE (self->image.texture));
}
static void
diff --git a/src/backends/meta-cursor.h b/src/backends/meta-cursor.h
index a9e3a9f..f0b014b 100644
--- a/src/backends/meta-cursor.h
+++ b/src/backends/meta-cursor.h
@@ -54,11 +54,13 @@ CoglTexture *meta_cursor_sprite_get_cogl_texture (MetaCursorSprite *self,
int *hot_x,
int *hot_y);
-#ifdef HAVE_NATIVE_BACKEND
-struct gbm_bo *meta_cursor_sprite_get_gbm_bo (MetaCursorSprite *self,
- int *hot_x,
- int *hot_y);
-#endif
+void meta_cursor_sprite_get_hotspot (MetaCursorSprite *self,
+ int *hot_x,
+ int *hot_y);
+
+guint meta_cursor_sprite_get_width (MetaCursorSprite *self);
+
+guint meta_cursor_sprite_get_height (MetaCursorSprite *self);
gboolean meta_cursor_sprite_is_animated (MetaCursorSprite *self);
void meta_cursor_sprite_tick_frame (MetaCursorSprite *self);
diff --git a/src/backends/native/meta-cursor-renderer-native.c
b/src/backends/native/meta-cursor-renderer-native.c
index 81ab4d0..b9e4b0d 100644
--- a/src/backends/native/meta-cursor-renderer-native.c
+++ b/src/backends/native/meta-cursor-renderer-native.c
@@ -26,9 +26,11 @@
#include "meta-cursor-renderer-native.h"
+#include <string.h>
#include <gbm.h>
#include <xf86drm.h>
+#include <meta/util.h>
#include "meta-monitor-manager-private.h"
#ifndef DRM_CAP_CURSOR_WIDTH
@@ -38,6 +40,8 @@
#define DRM_CAP_CURSOR_HEIGHT 0x9
#endif
+static GQuark quark_cursor_sprite = 0;
+
struct _MetaCursorRendererNativePrivate
{
gboolean has_hw_cursor;
@@ -70,6 +74,28 @@ meta_cursor_renderer_native_finalize (GObject *object)
G_OBJECT_CLASS (meta_cursor_renderer_native_parent_class)->finalize (object);
}
+static struct gbm_bo *
+get_cursor_sprite_gbm_bo (MetaCursorSprite *cursor_sprite)
+{
+ return g_object_get_qdata (G_OBJECT (cursor_sprite), quark_cursor_sprite);
+}
+
+static void
+cursor_gbm_bo_free (gpointer data)
+{
+ if (!data)
+ return;
+
+ gbm_bo_destroy ((struct gbm_bo *)data);
+}
+
+static void
+set_cursor_sprite_gbm_bo (MetaCursorSprite *cursor_sprite, struct gbm_bo *bo)
+{
+ g_object_set_qdata_full (G_OBJECT (cursor_sprite), quark_cursor_sprite,
+ bo, cursor_gbm_bo_free);
+}
+
static void
set_crtc_cursor (MetaCursorRendererNative *native,
MetaCRTC *crtc,
@@ -89,9 +115,10 @@ set_crtc_cursor (MetaCursorRendererNative *native,
union gbm_bo_handle handle;
int hot_x, hot_y;
- bo = meta_cursor_sprite_get_gbm_bo (cursor_sprite, &hot_x, &hot_y);
-
+ bo = get_cursor_sprite_gbm_bo (cursor_sprite);
handle = gbm_bo_get_handle (bo);
+ meta_cursor_sprite_get_hotspot (cursor_sprite, &hot_x, &hot_y);
+
drmModeSetCursor2 (priv->drm_fd, crtc->crtc_id, handle.u32,
priv->cursor_width, priv->cursor_height, hot_x, hot_y);
}
@@ -147,7 +174,7 @@ should_have_hw_cursor (MetaCursorRenderer *renderer)
MetaCursorSprite *cursor_sprite = meta_cursor_renderer_get_cursor (renderer);
if (cursor_sprite)
- return (meta_cursor_sprite_get_gbm_bo (cursor_sprite, NULL, NULL) != NULL);
+ return (get_cursor_sprite_gbm_bo (cursor_sprite) != NULL);
else
return FALSE;
}
@@ -220,6 +247,165 @@ meta_cursor_renderer_native_update_cursor (MetaCursorRenderer *renderer)
}
static void
+get_hardware_cursor_size (MetaCursorRendererNative *native,
+ uint64_t *width, uint64_t *height)
+{
+ MetaCursorRendererNativePrivate *priv =
+ meta_cursor_renderer_native_get_instance_private (native);
+
+ *width = priv->cursor_width;
+ *height = priv->cursor_height;
+}
+
+static void
+load_cursor_sprite_gbm_buffer (MetaCursorRendererNative *native,
+ MetaCursorSprite *cursor_sprite,
+ uint8_t *pixels,
+ uint width,
+ uint height,
+ int rowstride,
+ uint32_t gbm_format)
+{
+ MetaCursorRendererNativePrivate *priv =
+ meta_cursor_renderer_native_get_instance_private (native);
+ uint64_t cursor_width, cursor_height;
+
+ get_hardware_cursor_size (native, &cursor_width, &cursor_height);
+
+ if (width > cursor_width || height > cursor_height)
+ {
+ meta_warning ("Invalid theme cursor size (must be at most %ux%u)\n",
+ (unsigned int)cursor_width, (unsigned int)cursor_height);
+ return;
+ }
+
+ if (gbm_device_is_format_supported (priv->gbm, gbm_format,
+ GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE))
+ {
+ struct gbm_bo *bo;
+ uint8_t buf[4 * cursor_width * cursor_height];
+ uint i;
+
+ bo = gbm_bo_create (priv->gbm, cursor_width, cursor_height,
+ gbm_format, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
+
+ memset (buf, 0, sizeof(buf));
+ for (i = 0; i < height; i++)
+ memcpy (buf + i * 4 * cursor_width, pixels + i * rowstride, width * 4);
+
+ gbm_bo_write (bo, buf, cursor_width * cursor_height * 4);
+
+ set_cursor_sprite_gbm_bo (cursor_sprite, bo);
+ }
+ else
+ meta_warning ("HW cursor for format %d not supported\n", gbm_format);
+}
+
+#ifdef HAVE_WAYLAND
+static void
+meta_cursor_renderer_native_realize_cursor_from_wl_buffer (MetaCursorRenderer *renderer,
+ MetaCursorSprite *cursor_sprite,
+ struct wl_resource *buffer)
+{
+ MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
+ MetaCursorRendererNativePrivate *priv =
+ meta_cursor_renderer_native_get_instance_private (native);
+ uint32_t gbm_format;
+ uint64_t cursor_width, cursor_height;
+ uint width, height;
+
+ width = meta_cursor_sprite_get_width (cursor_sprite);
+ height = meta_cursor_sprite_get_height (cursor_sprite);
+
+ struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (buffer);
+ if (shm_buffer)
+ {
+ int rowstride = wl_shm_buffer_get_stride (shm_buffer);
+ uint8_t *buffer_data;
+
+ wl_shm_buffer_begin_access (shm_buffer);
+
+ switch (wl_shm_buffer_get_format (shm_buffer))
+ {
+#if G_BYTE_ORDER == G_BIG_ENDIAN
+ case WL_SHM_FORMAT_ARGB8888:
+ gbm_format = GBM_FORMAT_ARGB8888;
+ break;
+ case WL_SHM_FORMAT_XRGB8888:
+ gbm_format = GBM_FORMAT_XRGB8888;
+ break;
+#else
+ case WL_SHM_FORMAT_ARGB8888:
+ gbm_format = GBM_FORMAT_ARGB8888;
+ break;
+ case WL_SHM_FORMAT_XRGB8888:
+ gbm_format = GBM_FORMAT_XRGB8888;
+ break;
+#endif
+ default:
+ g_warn_if_reached ();
+ gbm_format = GBM_FORMAT_ARGB8888;
+ }
+
+ buffer_data = wl_shm_buffer_get_data (shm_buffer);
+ load_cursor_sprite_gbm_buffer (native,
+ cursor_sprite,
+ buffer_data,
+ width, height, rowstride,
+ gbm_format);
+
+ wl_shm_buffer_end_access (shm_buffer);
+ }
+ else
+ {
+ struct gbm_bo *bo;
+
+ /* HW cursors have a predefined size (at least 64x64), which usually is
+ * bigger than cursor theme size, so themed cursors must be padded with
+ * transparent pixels to fill the overlay. This is trivial if we have CPU
+ * access to the data, but it's not possible if the buffer is in GPU
+ * memory (and possibly tiled too), so if we don't get the right size, we
+ * fallback to GL. */
+ get_hardware_cursor_size (native, &cursor_width, &cursor_height);
+
+ if (width != cursor_width || height != cursor_height)
+ {
+ meta_warning ("Invalid cursor size (must be 64x64), falling back to software (GL) cursors\n");
+ return;
+ }
+
+ bo = gbm_bo_import (priv->gbm,
+ GBM_BO_IMPORT_WL_BUFFER,
+ buffer,
+ GBM_BO_USE_CURSOR);
+ if (!bo)
+ {
+ meta_warning ("Importing HW cursor from wl_buffer failed\n");
+ return;
+ }
+
+ set_cursor_sprite_gbm_bo (cursor_sprite, bo);
+ }
+}
+#endif
+
+static void
+meta_cursor_renderer_native_realize_cursor_from_xcursor (MetaCursorRenderer *renderer,
+ MetaCursorSprite *cursor_sprite,
+ XcursorImage *xc_image)
+{
+ MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
+
+ load_cursor_sprite_gbm_buffer (native,
+ cursor_sprite,
+ (uint8_t *) xc_image->pixels,
+ xc_image->width,
+ xc_image->height,
+ xc_image->width * 4,
+ GBM_FORMAT_ARGB8888);
+}
+
+static void
meta_cursor_renderer_native_class_init (MetaCursorRendererNativeClass *klass)
{
MetaCursorRendererClass *renderer_class = META_CURSOR_RENDERER_CLASS (klass);
@@ -227,6 +413,14 @@ meta_cursor_renderer_native_class_init (MetaCursorRendererNativeClass *klass)
object_class->finalize = meta_cursor_renderer_native_finalize;
renderer_class->update_cursor = meta_cursor_renderer_native_update_cursor;
+#ifdef HAVE_WAYLAND
+ renderer_class->realize_cursor_from_wl_buffer =
+ meta_cursor_renderer_native_realize_cursor_from_wl_buffer;
+#endif
+ renderer_class->realize_cursor_from_xcursor =
+ meta_cursor_renderer_native_realize_cursor_from_xcursor;
+
+ quark_cursor_sprite = g_quark_from_static_string ("-meta-cursor-native");
}
static void
@@ -280,16 +474,6 @@ meta_cursor_renderer_native_get_gbm_device (MetaCursorRendererNative *native)
}
void
-meta_cursor_renderer_native_get_cursor_size (MetaCursorRendererNative *native,
- uint64_t *width, uint64_t *height)
-{
- MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
-
- *width = priv->cursor_width;
- *height = priv->cursor_height;
-}
-
-void
meta_cursor_renderer_native_force_update (MetaCursorRendererNative *native)
{
update_hw_cursor (native, TRUE);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]