aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/wlr/types/wlr_output.h8
-rw-r--r--types/output/cursor.c56
2 files changed, 64 insertions, 0 deletions
diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h
index 767418bd..dbf7524a 100644
--- a/include/wlr/types/wlr_output.h
+++ b/include/wlr/types/wlr_output.h
@@ -112,6 +112,7 @@ struct wlr_output_state {
};
struct wlr_output_impl;
+struct wlr_render_pass;
/**
* A compositor output region. This typically corresponds to a monitor that
@@ -516,6 +517,13 @@ void wlr_output_lock_software_cursors(struct wlr_output *output, bool lock);
void wlr_output_render_software_cursors(struct wlr_output *output,
const pixman_region32_t *damage);
/**
+ * Render software cursors.
+ *
+ * This is a utility function that can be called when compositors render.
+ */
+void wlr_output_add_software_cursors_to_render_pass(struct wlr_output *output,
+ struct wlr_render_pass *render_pass, const pixman_region32_t *damage);
+/**
* Get the set of DRM formats suitable for the primary buffer, assuming a
* buffer with the specified capabilities.
*
diff --git a/types/output/cursor.c b/types/output/cursor.c
index 6ab557b5..d83e3244 100644
--- a/types/output/cursor.c
+++ b/types/output/cursor.c
@@ -7,6 +7,7 @@
#include <wlr/types/wlr_compositor.h>
#include <wlr/types/wlr_matrix.h>
#include <wlr/util/log.h>
+#include <wlr/util/region.h>
#include "render/allocator/allocator.h"
#include "types/wlr_buffer.h"
#include "types/wlr_output.h"
@@ -156,6 +157,61 @@ void wlr_output_render_software_cursors(struct wlr_output *output,
pixman_region32_fini(&render_damage);
}
+void wlr_output_add_software_cursors_to_render_pass(struct wlr_output *output,
+ struct wlr_render_pass *render_pass, const pixman_region32_t *damage) {
+ int width, height;
+ wlr_output_transformed_resolution(output, &width, &height);
+
+ pixman_region32_t render_damage;
+ pixman_region32_init_rect(&render_damage, 0, 0, width, height);
+ if (damage != NULL) {
+ pixman_region32_intersect(&render_damage, &render_damage, damage);
+ }
+
+ struct wlr_output_cursor *cursor;
+ wl_list_for_each(cursor, &output->cursors, link) {
+ if (!cursor->enabled || !cursor->visible ||
+ output->hardware_cursor == cursor) {
+ continue;
+ }
+
+ struct wlr_texture *texture = cursor->texture;
+ if (cursor->surface != NULL) {
+ texture = wlr_surface_get_texture(cursor->surface);
+ }
+ if (texture == NULL) {
+ continue;
+ }
+
+ struct wlr_box box;
+ output_cursor_get_box(cursor, &box);
+
+ pixman_region32_t cursor_damage;
+ pixman_region32_init_rect(&cursor_damage, box.x, box.y, box.width, box.height);
+ pixman_region32_intersect(&cursor_damage, &cursor_damage, &render_damage);
+ if (!pixman_region32_not_empty(&cursor_damage)) {
+ pixman_region32_fini(&cursor_damage);
+ continue;
+ }
+
+ enum wl_output_transform transform =
+ wlr_output_transform_invert(output->transform);
+ wlr_box_transform(&box, &box, transform, width, height);
+ wlr_region_transform(&cursor_damage, &cursor_damage, transform, width, height);
+
+ wlr_render_pass_add_texture(render_pass, &(struct wlr_render_texture_options) {
+ .texture = texture,
+ .dst_box = box,
+ .clip = &cursor_damage,
+ .transform = output->transform,
+ });
+
+ pixman_region32_fini(&cursor_damage);
+ }
+
+ pixman_region32_fini(&render_damage);
+}
+
static void output_cursor_damage_whole(struct wlr_output_cursor *cursor) {
struct wlr_box box;
output_cursor_get_box(cursor, &box);