diff --git a/include/types/wlr_output.h b/include/types/wlr_output.h index d59b05f0b..fdbffaf9d 100644 --- a/include/types/wlr_output.h +++ b/include/types/wlr_output.h @@ -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); diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h index 3cf8778a5..4485b3694 100644 --- a/include/wlr/types/wlr_output.h +++ b/include/wlr/types/wlr_output.h @@ -53,6 +53,7 @@ struct wlr_output_cursor { struct { struct wl_listener renderer_destroy; + struct wlr_color_transform *color_transform; } WLR_PRIVATE; }; diff --git a/types/output/cursor.c b/types/output/cursor.c index 1b33eb335..8a7f9e92a 100644 --- a/types/output/cursor.c +++ b/types/output/cursor.c @@ -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), - }; - 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_buffer_pass_options options = { + .color_transform = cursor->color_transform, + }; 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; +} \ No newline at end of file diff --git a/types/output/output.c b/types/output/output.c index ca2e55538..3715950ce 100644 --- a/types/output/output.c +++ b/types/output/output.c @@ -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) {