output: don't rebuild cursor color transform for each update

This commit is contained in:
Félix Poisot 2025-11-23 11:03:30 +00:00 committed by Simon Ser
parent 7101a69804
commit 811765ffa0
4 changed files with 43 additions and 19 deletions

View file

@ -22,6 +22,8 @@ bool output_cursor_set_texture(struct wlr_output_cursor *cursor,
int dst_width, int dst_height, enum wl_output_transform transform,
int32_t hotspot_x, int32_t hotspot_y, struct wlr_drm_syncobj_timeline *wait_timeline,
uint64_t wait_point);
bool output_cursor_refresh_color_transform(struct wlr_output_cursor *cursor,
const struct wlr_output_image_description *img_desc);
void output_defer_present(struct wlr_output *output, struct wlr_output_event_present event);

View file

@ -53,6 +53,7 @@ struct wlr_output_cursor {
struct {
struct wl_listener renderer_destroy;
struct wlr_color_transform *color_transform;
} WLR_PRIVATE;
};

View file

@ -256,26 +256,10 @@ static struct wlr_buffer *render_cursor_buffer(struct wlr_output_cursor *cursor)
wlr_box_transform(&dst_box, &dst_box, wlr_output_transform_invert(output->transform),
buffer->width, buffer->height);
struct wlr_buffer_pass_options options = {0};
if (output->image_description != NULL) {
struct wlr_color_primaries primaries_srgb;
wlr_color_primaries_from_named(&primaries_srgb, WLR_COLOR_NAMED_PRIMARIES_SRGB);
struct wlr_color_primaries primaries;
wlr_color_primaries_from_named(&primaries, output->image_description->primaries);
float matrix[9];
wlr_color_primaries_transform_absolute_colorimetric(&primaries_srgb, &primaries, matrix);
struct wlr_color_transform *transforms[] = {
wlr_color_transform_init_matrix(matrix),
wlr_color_transform_init_linear_to_inverse_eotf(
output->image_description->transfer_function),
struct wlr_buffer_pass_options options = {
.color_transform = cursor->color_transform,
};
size_t transform_count = sizeof(transforms) / sizeof(transforms[0]);
options.color_transform = wlr_color_transform_init_pipeline(transforms, transform_count);
wlr_color_transform_unref(transforms[0]);
wlr_color_transform_unref(transforms[1]);
}
struct wlr_render_pass *pass = wlr_renderer_begin_buffer_pass(renderer, buffer, &options);
wlr_color_transform_unref(options.color_transform);
if (pass == NULL) {
wlr_buffer_unlock(buffer);
return NULL;
@ -490,6 +474,7 @@ struct wlr_output_cursor *wlr_output_cursor_create(struct wlr_output *output) {
wl_list_insert(&output->cursors, &cursor->link);
cursor->visible = true; // default position is at (0, 0)
wl_list_init(&cursor->renderer_destroy.link);
output_cursor_refresh_color_transform(cursor, output->image_description);
return cursor;
}
@ -509,5 +494,36 @@ void wlr_output_cursor_destroy(struct wlr_output_cursor *cursor) {
}
wlr_drm_syncobj_timeline_unref(cursor->wait_timeline);
wl_list_remove(&cursor->link);
wlr_color_transform_unref(cursor->color_transform);
free(cursor);
}
bool output_cursor_refresh_color_transform(struct wlr_output_cursor *output_cursor,
const struct wlr_output_image_description *img_desc) {
wlr_color_transform_unref(output_cursor->color_transform);
output_cursor->color_transform = NULL;
if (img_desc == NULL) {
return true;
}
struct wlr_color_primaries primaries_srgb;
wlr_color_primaries_from_named(&primaries_srgb, WLR_COLOR_NAMED_PRIMARIES_SRGB);
struct wlr_color_primaries primaries;
wlr_color_primaries_from_named(&primaries, img_desc->primaries);
float matrix[9];
wlr_color_primaries_transform_absolute_colorimetric(&primaries_srgb, &primaries, matrix);
struct wlr_color_transform *transforms[] = {
wlr_color_transform_init_matrix(matrix),
wlr_color_transform_init_linear_to_inverse_eotf(img_desc->transfer_function),
};
if (transforms[0] == NULL || transforms[1] == NULL) {
wlr_color_transform_unref(transforms[0]);
wlr_color_transform_unref(transforms[1]);
return false;
}
output_cursor->color_transform = wlr_color_transform_init_pipeline(transforms,
sizeof(transforms) / sizeof(transforms[0]));
wlr_color_transform_unref(transforms[0]);
wlr_color_transform_unref(transforms[1]);
return output_cursor->color_transform != NULL;
}

View file

@ -240,6 +240,11 @@ static void output_apply_state(struct wlr_output *output,
} else {
output->image_description = NULL;
}
struct wlr_output_cursor *output_cursor;
wl_list_for_each(output_cursor, &output->cursors, link) {
output_cursor_refresh_color_transform(output_cursor, output->image_description);
}
}
if (state->committed & WLR_OUTPUT_STATE_COLOR_TRANSFORM) {