Commit 78dbf8cb authored by Jasper St. Pierre's avatar Jasper St. Pierre

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.
parent f4e299ca
......@@ -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;
}
......
......@@ -47,12 +47,17 @@ meta_cursor_reference_ref (MetaCursorReference *self)
}
static void
meta_cursor_reference_free (MetaCursorReference *self)
meta_cursor_image_free (MetaCursorImage *image)
{
cogl_object_unref (self->texture);
if (self->bo)
gbm_bo_destroy (self->bo);
cogl_object_unref (image->texture);
if (image->bo)
gbm_bo_destroy (image->bo);
}
static void
meta_cursor_reference_free (MetaCursorReference *self)
{
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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment