aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/wlr/types/wlr_output.h6
-rw-r--r--rootston/output.c1
-rw-r--r--types/wlr_output.c207
3 files changed, 121 insertions, 93 deletions
diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h
index 4e569168..557a3895 100644
--- a/include/wlr/types/wlr_output.h
+++ b/include/wlr/types/wlr_output.h
@@ -230,6 +230,12 @@ struct wlr_output *wlr_output_from_resource(struct wl_resource *resource);
* a lock.
*/
void wlr_output_lock_software_cursors(struct wlr_output *output, bool lock);
+/**
+ * Renders software cursors. This is a utility function that can be called when
+ * compositors render.
+ */
+void wlr_output_render_software_cursors(struct wlr_output *output,
+ pixman_region32_t *damage);
struct wlr_output_cursor *wlr_output_cursor_create(struct wlr_output *output);
diff --git a/rootston/output.c b/rootston/output.c
index e5a6b478..9ca55447 100644
--- a/rootston/output.c
+++ b/rootston/output.c
@@ -518,6 +518,7 @@ static void render_output(struct roots_output *output) {
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]);
renderer_end:
+ wlr_output_render_software_cursors(wlr_output, &damage);
wlr_renderer_scissor(renderer, NULL);
wlr_renderer_end(renderer);
diff --git a/types/wlr_output.c b/types/wlr_output.c
index 09654796..c4fc7096 100644
--- a/types/wlr_output.c
+++ b/types/wlr_output.c
@@ -339,85 +339,6 @@ bool wlr_output_make_current(struct wlr_output *output, int *buffer_age) {
return output->impl->make_current(output, buffer_age);
}
-static void output_scissor(struct wlr_output *output, pixman_box32_t *rect) {
- struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend);
- assert(renderer);
-
- struct wlr_box box = {
- .x = rect->x1,
- .y = rect->y1,
- .width = rect->x2 - rect->x1,
- .height = rect->y2 - rect->y1,
- };
-
- int ow, oh;
- wlr_output_transformed_resolution(output, &ow, &oh);
-
- // Scissor is in renderer coordinates, ie. upside down
- enum wl_output_transform transform =
- wlr_output_transform_invert(output->transform);
- wlr_box_transform(&box, transform, ow, oh, &box);
-
- wlr_renderer_scissor(renderer, &box);
-}
-
-/**
- * Returns the cursor box, scaled for its output.
- */
-static void output_cursor_get_box(struct wlr_output_cursor *cursor,
- struct wlr_box *box) {
- box->x = cursor->x - cursor->hotspot_x;
- box->y = cursor->y - cursor->hotspot_y;
- box->width = cursor->width;
- box->height = cursor->height;
-}
-
-static void output_cursor_render(struct wlr_output_cursor *cursor,
- const struct timespec *when, pixman_region32_t *damage) {
- struct wlr_renderer *renderer =
- wlr_backend_get_renderer(cursor->output->backend);
- assert(renderer);
-
- struct wlr_texture *texture = cursor->texture;
- if (cursor->surface != NULL) {
- texture = wlr_surface_get_texture(cursor->surface);
- }
- if (texture == NULL) {
- return;
- }
-
- struct wlr_box box;
- output_cursor_get_box(cursor, &box);
-
- pixman_region32_t surface_damage;
- pixman_region32_init(&surface_damage);
- pixman_region32_union_rect(&surface_damage, &surface_damage, box.x, box.y,
- box.width, box.height);
- pixman_region32_intersect(&surface_damage, &surface_damage, damage);
- if (!pixman_region32_not_empty(&surface_damage)) {
- goto surface_damage_finish;
- }
-
- float matrix[9];
- wlr_matrix_project_box(matrix, &box, WL_OUTPUT_TRANSFORM_NORMAL, 0,
- cursor->output->transform_matrix);
-
- int nrects;
- pixman_box32_t *rects = pixman_region32_rectangles(&surface_damage, &nrects);
- for (int i = 0; i < nrects; ++i) {
- output_scissor(cursor->output, &rects[i]);
- wlr_render_texture_with_matrix(renderer, texture, matrix, 1.0f);
- }
- wlr_renderer_scissor(renderer, NULL);
-
- if (cursor->surface != NULL) {
- wlr_surface_send_frame_done(cursor->surface, when);
- }
-
-surface_damage_finish:
- pixman_region32_fini(&surface_damage);
-}
-
bool wlr_output_swap_buffers(struct wlr_output *output, struct timespec *when,
pixman_region32_t *damage) {
if (output->frame_pending) {
@@ -447,17 +368,6 @@ bool wlr_output_swap_buffers(struct wlr_output *output, struct timespec *when,
when = &now;
}
- if (pixman_region32_not_empty(&render_damage)) {
- struct wlr_output_cursor *cursor;
- wl_list_for_each(cursor, &output->cursors, link) {
- if (!cursor->enabled || !cursor->visible ||
- output->hardware_cursor == cursor) {
- continue;
- }
- output_cursor_render(cursor, when, &render_damage);
- }
- }
-
struct wlr_output_event_swap_buffers event = {
.output = output,
.when = when,
@@ -466,6 +376,7 @@ bool wlr_output_swap_buffers(struct wlr_output *output, struct timespec *when,
wlr_signal_emit_safe(&output->events.swap_buffers, &event);
// Transform damage into renderer coordinates, ie. upside down
+ // TODO: take transformed coords, make the renderer flip the damage
enum wl_output_transform transform = wlr_output_transform_compose(
wlr_output_transform_invert(output->transform),
WL_OUTPUT_TRANSFORM_FLIPPED_180);
@@ -476,6 +387,14 @@ bool wlr_output_swap_buffers(struct wlr_output *output, struct timespec *when,
return false;
}
+ struct wlr_output_cursor *cursor;
+ wl_list_for_each(cursor, &output->cursors, link) {
+ if (!cursor->enabled || !cursor->visible || cursor->surface == NULL) {
+ continue;
+ }
+ wlr_surface_send_frame_done(cursor->surface, when);
+ }
+
output->frame_pending = true;
output->needs_swap = false;
pixman_region32_clear(&output->damage);
@@ -605,6 +524,111 @@ void wlr_output_lock_software_cursors(struct wlr_output *output, bool lock) {
// again.
}
+static void output_scissor(struct wlr_output *output, pixman_box32_t *rect) {
+ struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend);
+ assert(renderer);
+
+ struct wlr_box box = {
+ .x = rect->x1,
+ .y = rect->y1,
+ .width = rect->x2 - rect->x1,
+ .height = rect->y2 - rect->y1,
+ };
+
+ int ow, oh;
+ wlr_output_transformed_resolution(output, &ow, &oh);
+
+ enum wl_output_transform transform =
+ wlr_output_transform_invert(output->transform);
+ wlr_box_transform(&box, transform, ow, oh, &box);
+
+ wlr_renderer_scissor(renderer, &box);
+}
+
+static void output_cursor_get_box(struct wlr_output_cursor *cursor,
+ struct wlr_box *box);
+
+static void output_cursor_render(struct wlr_output_cursor *cursor,
+ pixman_region32_t *damage) {
+ struct wlr_renderer *renderer =
+ wlr_backend_get_renderer(cursor->output->backend);
+ assert(renderer);
+
+ struct wlr_texture *texture = cursor->texture;
+ if (cursor->surface != NULL) {
+ texture = wlr_surface_get_texture(cursor->surface);
+ }
+ if (texture == NULL) {
+ return;
+ }
+
+ struct wlr_box box;
+ output_cursor_get_box(cursor, &box);
+
+ pixman_region32_t surface_damage;
+ pixman_region32_init(&surface_damage);
+ pixman_region32_union_rect(&surface_damage, &surface_damage, box.x, box.y,
+ box.width, box.height);
+ pixman_region32_intersect(&surface_damage, &surface_damage, damage);
+ if (!pixman_region32_not_empty(&surface_damage)) {
+ goto surface_damage_finish;
+ }
+
+ float matrix[9];
+ wlr_matrix_project_box(matrix, &box, WL_OUTPUT_TRANSFORM_NORMAL, 0,
+ cursor->output->transform_matrix);
+
+ int nrects;
+ pixman_box32_t *rects = pixman_region32_rectangles(&surface_damage, &nrects);
+ for (int i = 0; i < nrects; ++i) {
+ output_scissor(cursor->output, &rects[i]);
+ wlr_render_texture_with_matrix(renderer, texture, matrix, 1.0f);
+ }
+ wlr_renderer_scissor(renderer, NULL);
+
+surface_damage_finish:
+ pixman_region32_fini(&surface_damage);
+}
+
+void wlr_output_render_software_cursors(struct wlr_output *output,
+ pixman_region32_t *damage) {
+ int width, height;
+ wlr_output_transformed_resolution(output, &width, &height);
+
+ pixman_region32_t render_damage;
+ pixman_region32_init(&render_damage);
+ pixman_region32_union_rect(&render_damage, &render_damage, 0, 0,
+ width, height);
+ if (damage != NULL) {
+ // Damage tracking supported
+ pixman_region32_intersect(&render_damage, &render_damage, damage);
+ }
+
+ if (pixman_region32_not_empty(&render_damage)) {
+ struct wlr_output_cursor *cursor;
+ wl_list_for_each(cursor, &output->cursors, link) {
+ if (!cursor->enabled || !cursor->visible ||
+ output->hardware_cursor == cursor) {
+ continue;
+ }
+ output_cursor_render(cursor, &render_damage);
+ }
+ }
+
+ pixman_region32_fini(&render_damage);
+}
+
+
+/**
+ * Returns the cursor box, scaled for its output.
+ */
+static void output_cursor_get_box(struct wlr_output_cursor *cursor,
+ struct wlr_box *box) {
+ box->x = cursor->x - cursor->hotspot_x;
+ box->y = cursor->y - cursor->hotspot_y;
+ box->width = cursor->width;
+ box->height = cursor->height;
+}
static void output_cursor_damage_whole(struct wlr_output_cursor *cursor) {
struct wlr_box box;
@@ -738,9 +762,6 @@ static void output_cursor_commit(struct wlr_output_cursor *cursor,
}
if (output_cursor_attempt_hardware(cursor)) {
- struct timespec now;
- clock_gettime(CLOCK_MONOTONIC, &now);
- wlr_surface_send_frame_done(surface, &now);
return;
}