aboutsummaryrefslogtreecommitdiff
path: root/backend
diff options
context:
space:
mode:
authoremersion <contact@emersion.fr>2018-05-09 19:58:18 +0100
committeremersion <contact@emersion.fr>2018-05-09 19:58:18 +0100
commit13098a18eaa8e6edd56f7f8c508b030f91dae67e (patch)
treeaf0181660de5e76f8620ee0e786c12e50901c1ca /backend
parent8e831cd416e2eb0c47bbd097422822a0c8888459 (diff)
Fix hardware cursors scale & transform
Diffstat (limited to 'backend')
-rw-r--r--backend/drm/drm.c19
-rw-r--r--backend/wayland/output.c33
2 files changed, 37 insertions, 15 deletions
diff --git a/backend/drm/drm.c b/backend/drm/drm.c
index e8ed7316..30be40ea 100644
--- a/backend/drm/drm.c
+++ b/backend/drm/drm.c
@@ -538,7 +538,8 @@ static void drm_connector_transform(struct wlr_output *output,
}
static bool drm_connector_set_cursor(struct wlr_output *output,
- struct wlr_texture *texture, int32_t hotspot_x, int32_t hotspot_y,
+ struct wlr_texture *texture, int32_t scale,
+ enum wl_output_transform transform, int32_t hotspot_x, int32_t hotspot_y,
bool update_texture) {
struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output;
struct wlr_drm_backend *drm = (struct wlr_drm_backend *)output->backend;
@@ -581,15 +582,12 @@ static bool drm_connector_set_cursor(struct wlr_output *output,
return false;
}
- enum wl_output_transform transform = output->transform;
wlr_matrix_projection(plane->matrix, plane->surf.width,
- plane->surf.height, transform);
+ plane->surf.height, output->transform);
}
struct wlr_box hotspot = { .x = hotspot_x, .y = hotspot_y };
- enum wl_output_transform transform =
- wlr_output_transform_invert(output->transform);
- wlr_box_transform(&hotspot, transform,
+ wlr_box_transform(&hotspot, wlr_output_transform_invert(output->transform),
plane->surf.width, plane->surf.height, &hotspot);
if (plane->cursor_hotspot_x != hotspot.x ||
@@ -617,6 +615,8 @@ static bool drm_connector_set_cursor(struct wlr_output *output,
if (texture != NULL) {
int width, height;
wlr_texture_get_size(texture, &width, &height);
+ width = width * output->scale / scale;
+ height = height * output->scale / scale;
if (width > (int)plane->surf.width || height > (int)plane->surf.height) {
wlr_log(L_ERROR, "Cursor too large (max %dx%d)",
@@ -639,9 +639,14 @@ static bool drm_connector_set_cursor(struct wlr_output *output,
struct wlr_renderer *rend = plane->surf.renderer->wlr_rend;
+ struct wlr_box cursor_box = { .width = width, .height = height };
+
+ float matrix[9];
+ wlr_matrix_project_box(matrix, &cursor_box, transform, 0, plane->matrix);
+
wlr_renderer_begin(rend, plane->surf.width, plane->surf.height);
wlr_renderer_clear(rend, (float[]){ 0.0, 0.0, 0.0, 0.0 });
- wlr_render_texture(rend, texture, plane->matrix, 0, 0, 1.0f);
+ wlr_render_texture_with_matrix(rend, texture, matrix, 1.0);
wlr_renderer_end(rend);
wlr_renderer_read_pixels(rend, WL_SHM_FORMAT_ARGB8888, bo_stride,
diff --git a/backend/wayland/output.c b/backend/wayland/output.c
index c498fc4e..109834c9 100644
--- a/backend/wayland/output.c
+++ b/backend/wayland/output.c
@@ -72,16 +72,20 @@ static void output_transform(struct wlr_output *_output,
output->wlr_output.transform = transform;
}
-static bool output_set_cursor(struct wlr_output *_output,
- struct wlr_texture *texture, int32_t hotspot_x, int32_t hotspot_y,
+static bool output_set_cursor(struct wlr_output *wlr_output,
+ struct wlr_texture *texture, int32_t scale,
+ enum wl_output_transform transform, int32_t hotspot_x, int32_t hotspot_y,
bool update_texture) {
- struct wlr_wl_output *output =
- (struct wlr_wl_output *)_output;
+ struct wlr_wl_output *output = (struct wlr_wl_output *)wlr_output;
struct wlr_wl_backend *backend = output->backend;
+ struct wlr_box hotspot = { .x = hotspot_x, .y = hotspot_y };
+ wlr_box_transform(&hotspot, wlr_output_transform_invert(wlr_output->transform),
+ output->cursor.width, output->cursor.height, &hotspot);
+
// TODO: use output->wlr_output.transform to transform pixels and hotpot
- output->cursor.hotspot_x = hotspot_x;
- output->cursor.hotspot_y = hotspot_y;
+ output->cursor.hotspot_x = hotspot.x;
+ output->cursor.hotspot_y = hotspot.y;
if (!update_texture) {
// Update hotspot without changing cursor image
@@ -98,6 +102,11 @@ static bool output_set_cursor(struct wlr_output *_output,
if (texture != NULL) {
int width, height;
wlr_texture_get_size(texture, &width, &height);
+ width = width * wlr_output->scale / scale;
+ height = height * wlr_output->scale / scale;
+
+ output->cursor.width = width;
+ output->cursor.height = height;
if (output->cursor.egl_window == NULL) {
output->cursor.egl_window =
@@ -110,12 +119,20 @@ static bool output_set_cursor(struct wlr_output *_output,
wlr_egl_make_current(&backend->egl, egl_surface, NULL);
+ struct wlr_box cursor_box = {
+ .width = width,
+ .height = height,
+ };
+
+ float projection[9];
+ wlr_matrix_projection(projection, width, height, wlr_output->transform);
+
float matrix[9];
- wlr_matrix_projection(matrix, width, height, WL_OUTPUT_TRANSFORM_NORMAL);
+ wlr_matrix_project_box(matrix, &cursor_box, transform, 0, projection);
wlr_renderer_begin(backend->renderer, width, height);
wlr_renderer_clear(backend->renderer, (float[]){ 0.0, 0.0, 0.0, 0.0 });
- wlr_render_texture(backend->renderer, texture, matrix, 0, 0, 1.0);
+ wlr_render_texture_with_matrix(backend->renderer, texture, matrix, 1.0);
wlr_renderer_end(backend->renderer);
wlr_egl_swap_buffers(&backend->egl, egl_surface, NULL);