cursor: Split out the structure for the actual textures / buffers out
This will allow us to have a MetaCursorReference 'subclass' that's lazily loaded. We currently always load all the images. The long-term plan is to have a subclass for each "backend" and only have CoglTexture as a common denominator. For the nested X11 backend, we use XDefineCursor on our stage window. For the Wayland backend, we would use set_cursor on our stage surface. For the native backend, we would use the GBM code that's there right now. The CoglTexture is there to be a "shared fallback" between all devices, and also for the get_sprite API. The odd man out is the X11 compositor case. For that, we need to move the responsibility of setting the final cursor image out of MetaCursorTracker, and simply have it be about tracking the used sprite image and pointer position.
This commit is contained in:
parent
f4e299ca46
commit
78dbf8cb56
@ -27,12 +27,16 @@
|
||||
#include <cogl/cogl.h>
|
||||
#include <gbm.h>
|
||||
|
||||
struct _MetaCursorReference {
|
||||
int ref_count;
|
||||
|
||||
typedef struct {
|
||||
CoglTexture2D *texture;
|
||||
struct gbm_bo *bo;
|
||||
int hot_x, hot_y;
|
||||
} MetaCursorImage;
|
||||
|
||||
struct _MetaCursorReference {
|
||||
int ref_count;
|
||||
|
||||
MetaCursorImage image;
|
||||
};
|
||||
|
||||
CoglTexture *meta_cursor_reference_get_cogl_texture (MetaCursorReference *cursor,
|
||||
|
@ -253,9 +253,9 @@ meta_cursor_reference_take_texture (CoglTexture2D *texture,
|
||||
|
||||
self = g_slice_new0 (MetaCursorReference);
|
||||
self->ref_count = 1;
|
||||
self->texture = texture;
|
||||
self->hot_x = hot_x;
|
||||
self->hot_y = hot_y;
|
||||
self->image.texture = texture;
|
||||
self->image.hot_x = hot_x;
|
||||
self->image.hot_y = hot_y;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
@ -46,13 +46,18 @@ meta_cursor_reference_ref (MetaCursorReference *self)
|
||||
return self;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_image_free (MetaCursorImage *image)
|
||||
{
|
||||
cogl_object_unref (image->texture);
|
||||
if (image->bo)
|
||||
gbm_bo_destroy (image->bo);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_reference_free (MetaCursorReference *self)
|
||||
{
|
||||
cogl_object_unref (self->texture);
|
||||
if (self->bo)
|
||||
gbm_bo_destroy (self->bo);
|
||||
|
||||
meta_cursor_image_free (&self->image);
|
||||
g_slice_free (MetaCursorReference, self);
|
||||
}
|
||||
|
||||
@ -209,17 +214,17 @@ meta_cursor_reference_from_xcursor_image (MetaCursorTracker *tracker,
|
||||
|
||||
self = g_slice_new0 (MetaCursorReference);
|
||||
self->ref_count = 1;
|
||||
self->hot_x = image->xhot;
|
||||
self->hot_y = image->yhot;
|
||||
self->image.hot_x = image->xhot;
|
||||
self->image.hot_y = image->yhot;
|
||||
|
||||
clutter_backend = clutter_get_default_backend ();
|
||||
cogl_context = clutter_backend_get_cogl_context (clutter_backend);
|
||||
self->texture = cogl_texture_2d_new_from_data (cogl_context,
|
||||
width, height,
|
||||
cogl_format,
|
||||
rowstride,
|
||||
(uint8_t*)image->pixels,
|
||||
NULL);
|
||||
self->image.texture = cogl_texture_2d_new_from_data (cogl_context,
|
||||
width, height,
|
||||
cogl_format,
|
||||
rowstride,
|
||||
(uint8_t*)image->pixels,
|
||||
NULL);
|
||||
|
||||
if (tracker->gbm)
|
||||
{
|
||||
@ -235,14 +240,14 @@ meta_cursor_reference_from_xcursor_image (MetaCursorTracker *tracker,
|
||||
uint32_t buf[64 * 64];
|
||||
int i;
|
||||
|
||||
self->bo = gbm_bo_create (tracker->gbm, 64, 64,
|
||||
gbm_format, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE);
|
||||
self->image.bo = gbm_bo_create (tracker->gbm, 64, 64,
|
||||
gbm_format, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE);
|
||||
|
||||
memset (buf, 0, sizeof(buf));
|
||||
for (i = 0; i < height; i++)
|
||||
memcpy (buf + i * 64, image->pixels + i * width, width * 4);
|
||||
|
||||
gbm_bo_write (self->bo, buf, 64 * 64 * 4);
|
||||
gbm_bo_write (self->image.bo, buf, 64 * 64 * 4);
|
||||
}
|
||||
else
|
||||
meta_warning ("HW cursor for format %d not supported\n", gbm_format);
|
||||
@ -287,8 +292,8 @@ meta_cursor_reference_from_buffer (MetaCursorTracker *tracker,
|
||||
|
||||
self = g_slice_new0 (MetaCursorReference);
|
||||
self->ref_count = 1;
|
||||
self->hot_x = hot_x;
|
||||
self->hot_y = hot_y;
|
||||
self->image.hot_x = hot_x;
|
||||
self->image.hot_y = hot_y;
|
||||
|
||||
backend = clutter_get_default_backend ();
|
||||
cogl_context = clutter_backend_get_cogl_context (backend);
|
||||
@ -327,12 +332,12 @@ meta_cursor_reference_from_buffer (MetaCursorTracker *tracker,
|
||||
gbm_format = GBM_FORMAT_ARGB8888;
|
||||
}
|
||||
|
||||
self->texture = cogl_texture_2d_new_from_data (cogl_context,
|
||||
width, height,
|
||||
cogl_format,
|
||||
rowstride,
|
||||
wl_shm_buffer_get_data (shm_buffer),
|
||||
NULL);
|
||||
self->image.texture = cogl_texture_2d_new_from_data (cogl_context,
|
||||
width, height,
|
||||
cogl_format,
|
||||
rowstride,
|
||||
wl_shm_buffer_get_data (shm_buffer),
|
||||
NULL);
|
||||
|
||||
if (width > 64 || height > 64)
|
||||
{
|
||||
@ -349,15 +354,15 @@ meta_cursor_reference_from_buffer (MetaCursorTracker *tracker,
|
||||
uint8_t buf[4 * 64 * 64];
|
||||
int i;
|
||||
|
||||
self->bo = gbm_bo_create (tracker->gbm, 64, 64,
|
||||
gbm_format, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE);
|
||||
self->image.bo = gbm_bo_create (tracker->gbm, 64, 64,
|
||||
gbm_format, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE);
|
||||
|
||||
data = wl_shm_buffer_get_data (shm_buffer);
|
||||
memset (buf, 0, sizeof(buf));
|
||||
for (i = 0; i < height; i++)
|
||||
memcpy (buf + i * 4 * 64, data + i * rowstride, 4 * width);
|
||||
|
||||
gbm_bo_write (self->bo, buf, 64 * 64 * 4);
|
||||
gbm_bo_write (self->image.bo, buf, 64 * 64 * 4);
|
||||
}
|
||||
else
|
||||
meta_warning ("HW cursor for format %d not supported\n", gbm_format);
|
||||
@ -367,9 +372,9 @@ meta_cursor_reference_from_buffer (MetaCursorTracker *tracker,
|
||||
{
|
||||
int width, height;
|
||||
|
||||
self->texture = cogl_wayland_texture_2d_new_from_buffer (cogl_context, buffer, NULL);
|
||||
width = cogl_texture_get_width (COGL_TEXTURE (self->texture));
|
||||
height = cogl_texture_get_height (COGL_TEXTURE (self->texture));
|
||||
self->image.texture = cogl_wayland_texture_2d_new_from_buffer (cogl_context, buffer, NULL);
|
||||
width = cogl_texture_get_width (COGL_TEXTURE (self->image.texture));
|
||||
height = cogl_texture_get_height (COGL_TEXTURE (self->image.texture));
|
||||
|
||||
/* HW cursors must be 64x64, but 64x64 is huge, and no cursor theme actually uses
|
||||
that, so themed cursors must be padded with transparent pixels to fill the
|
||||
@ -385,9 +390,9 @@ meta_cursor_reference_from_buffer (MetaCursorTracker *tracker,
|
||||
|
||||
if (tracker->gbm)
|
||||
{
|
||||
self->bo = gbm_bo_import (tracker->gbm, GBM_BO_IMPORT_WL_BUFFER,
|
||||
buffer, GBM_BO_USE_CURSOR_64X64);
|
||||
if (!self->bo)
|
||||
self->image.bo = gbm_bo_import (tracker->gbm, GBM_BO_IMPORT_WL_BUFFER,
|
||||
buffer, GBM_BO_USE_CURSOR_64X64);
|
||||
if (!self->image.bo)
|
||||
meta_warning ("Importing HW cursor from wl_buffer failed\n");
|
||||
}
|
||||
}
|
||||
@ -401,10 +406,10 @@ meta_cursor_reference_get_cogl_texture (MetaCursorReference *cursor,
|
||||
int *hot_y)
|
||||
{
|
||||
if (hot_x)
|
||||
*hot_x = cursor->hot_x;
|
||||
*hot_x = cursor->image.hot_x;
|
||||
if (hot_y)
|
||||
*hot_y = cursor->hot_y;
|
||||
return COGL_TEXTURE (cursor->texture);
|
||||
*hot_y = cursor->image.hot_y;
|
||||
return COGL_TEXTURE (cursor->image.texture);
|
||||
}
|
||||
|
||||
struct gbm_bo *
|
||||
@ -413,8 +418,8 @@ meta_cursor_reference_get_gbm_bo (MetaCursorReference *cursor,
|
||||
int *hot_y)
|
||||
{
|
||||
if (hot_x)
|
||||
*hot_x = cursor->hot_x;
|
||||
*hot_x = cursor->image.hot_x;
|
||||
if (hot_y)
|
||||
*hot_y = cursor->hot_y;
|
||||
return cursor->bo;
|
||||
*hot_y = cursor->image.hot_y;
|
||||
return cursor->image.bo;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user