|
|
@ -95,6 +95,8 @@ struct drm_output { |
|
|
|
drmModeCrtcPtr original_crtc; |
|
|
|
drmModeCrtcPtr original_crtc; |
|
|
|
|
|
|
|
|
|
|
|
struct gbm_surface *surface; |
|
|
|
struct gbm_surface *surface; |
|
|
|
|
|
|
|
struct gbm_bo *cursor_bo[2]; |
|
|
|
|
|
|
|
int current_cursor; |
|
|
|
EGLSurface egl_surface; |
|
|
|
EGLSurface egl_surface; |
|
|
|
struct drm_fb *current, *next; |
|
|
|
struct drm_fb *current, *next; |
|
|
|
struct backlight *backlight; |
|
|
|
struct backlight *backlight; |
|
|
@ -657,8 +659,7 @@ weston_output_set_cursor(struct weston_output *output, |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
if (!prior_was_hardware) |
|
|
|
if (!prior_was_hardware) |
|
|
|
weston_surface_damage_below(device->sprite); |
|
|
|
weston_surface_damage_below(device->sprite); |
|
|
|
pixman_region32_fini(&device->sprite->damage); |
|
|
|
wl_list_remove(&device->sprite->link); |
|
|
|
pixman_region32_init(&device->sprite->damage); |
|
|
|
|
|
|
|
device->hw_cursor = 1; |
|
|
|
device->hw_cursor = 1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -670,7 +671,7 @@ static void |
|
|
|
drm_assign_planes(struct weston_output *output) |
|
|
|
drm_assign_planes(struct weston_output *output) |
|
|
|
{ |
|
|
|
{ |
|
|
|
struct weston_compositor *ec = output->compositor; |
|
|
|
struct weston_compositor *ec = output->compositor; |
|
|
|
struct weston_surface *es; |
|
|
|
struct weston_surface *es, *next; |
|
|
|
pixman_region32_t overlap, surface_overlap; |
|
|
|
pixman_region32_t overlap, surface_overlap; |
|
|
|
struct weston_input_device *device; |
|
|
|
struct weston_input_device *device; |
|
|
|
|
|
|
|
|
|
|
@ -688,7 +689,7 @@ drm_assign_planes(struct weston_output *output) |
|
|
|
* as we do for flipping full screen surfaces. |
|
|
|
* as we do for flipping full screen surfaces. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
pixman_region32_init(&overlap); |
|
|
|
pixman_region32_init(&overlap); |
|
|
|
wl_list_for_each(es, &ec->surface_list, link) { |
|
|
|
wl_list_for_each_safe(es, next, &ec->surface_list, link) { |
|
|
|
/*
|
|
|
|
/*
|
|
|
|
* FIXME: try to assign hw cursors here too, they're just |
|
|
|
* FIXME: try to assign hw cursors here too, they're just |
|
|
|
* special overlays |
|
|
|
* special overlays |
|
|
@ -730,36 +731,42 @@ drm_output_set_cursor(struct weston_output *output_base, |
|
|
|
EGLint handle, stride; |
|
|
|
EGLint handle, stride; |
|
|
|
int ret = -1; |
|
|
|
int ret = -1; |
|
|
|
struct gbm_bo *bo; |
|
|
|
struct gbm_bo *bo; |
|
|
|
|
|
|
|
uint32_t buf[64 * 64]; |
|
|
|
|
|
|
|
unsigned char *d, *s, *end; |
|
|
|
|
|
|
|
|
|
|
|
if (eid == NULL) { |
|
|
|
if (eid == NULL) { |
|
|
|
drmModeSetCursor(c->drm.fd, output->crtc_id, 0, 0, 0); |
|
|
|
drmModeSetCursor(c->drm.fd, output->crtc_id, 0, 0, 0); |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (eid->sprite->image == EGL_NO_IMAGE_KHR) |
|
|
|
if (eid->sprite->buffer == NULL || |
|
|
|
|
|
|
|
!wl_buffer_is_shm(eid->sprite->buffer)) |
|
|
|
goto out; |
|
|
|
goto out; |
|
|
|
|
|
|
|
|
|
|
|
if (eid->sprite->geometry.width > 64 || |
|
|
|
if (eid->sprite->geometry.width > 64 || |
|
|
|
eid->sprite->geometry.height > 64) |
|
|
|
eid->sprite->geometry.height > 64) |
|
|
|
goto out; |
|
|
|
goto out; |
|
|
|
|
|
|
|
|
|
|
|
bo = gbm_bo_create_from_egl_image(c->gbm, |
|
|
|
output->current_cursor ^= 1; |
|
|
|
c->base.display, |
|
|
|
bo = output->cursor_bo[output->current_cursor]; |
|
|
|
eid->sprite->image, 64, 64, |
|
|
|
|
|
|
|
GBM_BO_USE_CURSOR_64X64); |
|
|
|
|
|
|
|
/* Not suitable for hw cursor, fall back */ |
|
|
|
|
|
|
|
if (bo == NULL) |
|
|
|
if (bo == NULL) |
|
|
|
goto out; |
|
|
|
goto out; |
|
|
|
|
|
|
|
|
|
|
|
handle = gbm_bo_get_handle(bo).s32; |
|
|
|
memset(buf, 0, sizeof buf); |
|
|
|
stride = gbm_bo_get_pitch(bo); |
|
|
|
d = (unsigned char *) buf; |
|
|
|
gbm_bo_destroy(bo); |
|
|
|
stride = wl_shm_buffer_get_stride(eid->sprite->buffer); |
|
|
|
|
|
|
|
s = wl_shm_buffer_get_data(eid->sprite->buffer); |
|
|
|
|
|
|
|
end = s + stride * eid->sprite->geometry.height; |
|
|
|
|
|
|
|
while (s < end) { |
|
|
|
|
|
|
|
memcpy(d, s, eid->sprite->geometry.width * 4); |
|
|
|
|
|
|
|
s += stride; |
|
|
|
|
|
|
|
d += 64 * 4; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* gbm_bo_create_from_egl_image() didn't always validate the usage
|
|
|
|
if (gbm_bo_write(bo, buf, sizeof buf) < 0) |
|
|
|
* flags, and in that case we might end up with a bad stride. */ |
|
|
|
|
|
|
|
if (stride != 64 * 4) |
|
|
|
|
|
|
|
goto out; |
|
|
|
goto out; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handle = gbm_bo_get_handle(bo).s32; |
|
|
|
ret = drmModeSetCursor(c->drm.fd, output->crtc_id, handle, 64, 64); |
|
|
|
ret = drmModeSetCursor(c->drm.fd, output->crtc_id, handle, 64, 64); |
|
|
|
if (ret) { |
|
|
|
if (ret) { |
|
|
|
fprintf(stderr, "failed to set cursor: %s\n", strerror(-ret)); |
|
|
|
fprintf(stderr, "failed to set cursor: %s\n", strerror(-ret)); |
|
|
@ -1304,6 +1311,13 @@ create_output_for_connector(struct drm_compositor *ec, |
|
|
|
goto err_surface; |
|
|
|
goto err_surface; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
output->cursor_bo[0] = |
|
|
|
|
|
|
|
gbm_bo_create(ec->gbm, 64, 64, GBM_FORMAT_ARGB8888, |
|
|
|
|
|
|
|
GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE); |
|
|
|
|
|
|
|
output->cursor_bo[1] = |
|
|
|
|
|
|
|
gbm_bo_create(ec->gbm, 64, 64, GBM_FORMAT_ARGB8888, |
|
|
|
|
|
|
|
GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE); |
|
|
|
|
|
|
|
|
|
|
|
output->backlight = backlight_init(drm_device, |
|
|
|
output->backlight = backlight_init(drm_device, |
|
|
|
connector->connector_type); |
|
|
|
connector->connector_type); |
|
|
|
if (output->backlight) { |
|
|
|
if (output->backlight) { |
|
|
|