summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2012-07-14 01:24:58 -0400
committerKristian Høgsberg <krh@bitplanet.net>2012-07-14 15:28:58 -0400
commit49a3b17e423dd30dcdf4105aef8f8f16904dea8b (patch)
tree7074a3baee5dde37471daf60fde46fe5dc5e7a72
parentab725103125bf40852aef72fa84983878a8201bb (diff)
compositor-drm: Allocate hw cursor like other planesassign-planes
We no longer reserve the hw cursor for just the pointer sprite. Any surface that satisfies the requirements for the hw cursor can be used. Of course that's more or less always the pointer sprite, but at least now we don't hard-code the references to compositor->seat anymore.
-rw-r--r--src/compositor-drm.c45
1 files changed, 19 insertions, 26 deletions
diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index d0100d06..b450a006 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -108,7 +108,7 @@ struct drm_output {
struct gbm_surface *surface;
struct gbm_bo *cursor_bo[2];
- int current_cursor;
+ int current_cursor, cursor_free;
EGLSurface egl_surface;
struct drm_fb *current, *next;
struct backlight *backlight;
@@ -663,7 +663,7 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
static void
drm_output_set_cursor(struct weston_output *output_base,
- struct weston_seat *seat)
+ struct weston_surface *es)
{
struct drm_output *output = (struct drm_output *) output_base;
struct drm_compositor *c =
@@ -674,23 +674,21 @@ drm_output_set_cursor(struct weston_output *output_base,
unsigned char *s;
int i;
- if (seat->sprite->output_mask != (1u << output_base->id))
+ if (!output->cursor_free)
return;
-
- if (seat->sprite->buffer == NULL ||
- !wl_buffer_is_shm(seat->sprite->buffer) ||
- seat->sprite->geometry.width > 64 ||
- seat->sprite->geometry.height > 64)
+ if (es->output_mask != (1u << output_base->id))
+ return;
+ if (es->buffer == NULL || !wl_buffer_is_shm(es->buffer) ||
+ es->geometry.width > 64 || es->geometry.height > 64)
return;
output->current_cursor ^= 1;
bo = output->cursor_bo[output->current_cursor];
memset(buf, 0, sizeof buf);
- stride = wl_shm_buffer_get_stride(seat->sprite->buffer);
- s = wl_shm_buffer_get_data(seat->sprite->buffer);
- for (i = 0; i < seat->sprite->geometry.height; i++)
- memcpy(buf + i * 64, s + i * stride,
- seat->sprite->geometry.width * 4);
+ stride = wl_shm_buffer_get_stride(es->buffer);
+ s = wl_shm_buffer_get_data(es->buffer);
+ for (i = 0; i < es->geometry.height; i++)
+ memcpy(buf + i * 64, s + i * stride, es->geometry.width * 4);
if (gbm_bo_write(bo, buf, sizeof buf) < 0)
return;
@@ -702,13 +700,14 @@ drm_output_set_cursor(struct weston_output *output_base,
}
if (drmModeMoveCursor(c->drm.fd, output->crtc_id,
- seat->sprite->geometry.x - output->base.x,
- seat->sprite->geometry.y - output->base.y)) {
+ es->geometry.x - output->base.x,
+ es->geometry.y - output->base.y)) {
weston_log("failed to move cursor: %m\n");
return;
}
- seat->sprite->plane = WESTON_PLANE_DRM_CURSOR;
+ es->plane = WESTON_PLANE_DRM_CURSOR;
+ output->cursor_free = 0;
}
static void
@@ -719,7 +718,6 @@ drm_assign_planes(struct weston_output *output)
struct drm_output *drm_output = (struct drm_output *) output;
struct weston_surface *es, *next;
pixman_region32_t overlap, surface_overlap;
- struct weston_seat *seat;
int prev_plane;
/*
@@ -735,13 +733,9 @@ drm_assign_planes(struct weston_output *output)
* the client buffer can be used directly for the sprite surface
* as we do for flipping full screen surfaces.
*/
- seat = (struct weston_seat *) c->base.seat;
pixman_region32_init(&overlap);
+ drm_output->cursor_free = 1;
wl_list_for_each_safe(es, next, &c->base.surface_list, link) {
- /*
- * FIXME: try to assign hw cursors here too, they're just
- * special overlays
- */
pixman_region32_init(&surface_overlap);
pixman_region32_intersect(&surface_overlap, &overlap,
&es->transform.boundingbox);
@@ -751,9 +745,8 @@ drm_assign_planes(struct weston_output *output)
if (pixman_region32_not_empty(&surface_overlap))
goto bail;
- if (es == seat->sprite)
- drm_output_set_cursor(output, seat);
-
+ if (es->plane == WESTON_PLANE_PRIMARY)
+ drm_output_set_cursor(output, es);
if (es->plane == WESTON_PLANE_PRIMARY)
drm_output_prepare_scanout_surface(output, es);
if (es->plane == WESTON_PLANE_PRIMARY)
@@ -775,7 +768,7 @@ drm_assign_planes(struct weston_output *output)
}
pixman_region32_fini(&overlap);
- if (!seat->sprite || seat->sprite->plane == WESTON_PLANE_PRIMARY)
+ if (drm_output->cursor_free)
drmModeSetCursor(c->drm.fd, drm_output->crtc_id, 0, 0, 0);
drm_disable_unused_sprites(output);