From 1d2eee208c241241b39423e1bf94554177a016f5 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Thu, 25 Feb 2021 12:03:28 +0200 Subject: [PATCH] color: add output color transform API This is the blending space to monitor space color transform. It needs to be implemented in the renderers, unless a backend sets from_blend_to_output_by_backend = true, in which case the backend does it and the renderer does not. The intention is that from_blend_to_output_by_backend can be toggled frame by frame to allow backends to react to dynamic change of output color profile. For now, renderers just assert that they don't need to do anything for output color transform. Signed-off-by: Pekka Paalanen --- include/libweston/libweston.h | 3 +++ libweston/color-noop.c | 14 ++++++++++++++ libweston/color.h | 16 ++++++++++++++++ libweston/compositor.c | 24 ++++++++++++++++++++++++ libweston/pixman-renderer.c | 3 +++ libweston/renderer-gl/gl-renderer.c | 5 +++++ 6 files changed, 65 insertions(+) diff --git a/include/libweston/libweston.h b/include/libweston/libweston.h index f0db7315..c69a6655 100644 --- a/include/libweston/libweston.h +++ b/include/libweston/libweston.h @@ -79,6 +79,7 @@ struct linux_dmabuf_buffer; struct weston_recorder; struct weston_pointer_constraint; struct ro_anonymous_file; +struct weston_color_transform; enum weston_keyboard_modifier { MODIFIER_CTRL = (1 << 0), @@ -373,6 +374,8 @@ struct weston_output { int scale; bool use_renderer_shadow_buffer; + struct weston_color_transform *from_blend_to_output; + bool from_blend_to_output_by_backend; int (*enable)(struct weston_output *output); int (*disable)(struct weston_output *output); diff --git a/libweston/color-noop.c b/libweston/color-noop.c index 8a3c853b..89015222 100644 --- a/libweston/color-noop.c +++ b/libweston/color-noop.c @@ -62,6 +62,19 @@ cmnoop_get_surface_color_transform(struct weston_color_manager *cm_base, return true; } +static bool +cmnoop_get_output_color_transform(struct weston_color_manager *cm_base, + struct weston_output *output, + struct weston_color_transform **xform_out) +{ + /* TODO: Assert output has no colorspace set */ + + /* Identity transform */ + *xform_out = NULL; + + return true; +} + static bool cmnoop_init(struct weston_color_manager *cm_base) { @@ -95,6 +108,7 @@ weston_color_manager_noop_create(struct weston_compositor *compositor) cm->base.destroy_color_transform = cmnoop_destroy_color_transform; cm->base.get_surface_color_transform = cmnoop_get_surface_color_transform; + cm->base.get_output_color_transform = cmnoop_get_output_color_transform; return &cm->base; } diff --git a/libweston/color.h b/libweston/color.h index 663261ed..1c330e5f 100644 --- a/libweston/color.h +++ b/libweston/color.h @@ -160,6 +160,22 @@ struct weston_color_manager { struct weston_surface *surface, struct weston_output *output, struct weston_surface_color_transform *surf_xform); + + /** Get output's blending space to output transformation + * + * \param cm The color manager. + * \param output The output for the destination color space. + * \param xform_out Pointer for storing the weston_color_transform. + * \return True on success, false on failure. + * + * The callee is responsible for increasing the reference count on the + * weston_color_transform it stores via xform_out. On failure, xform_out + * is untouched. + */ + bool + (*get_output_color_transform)(struct weston_color_manager *cm, + struct weston_output *output, + struct weston_color_transform **xform_out); }; struct weston_color_transform * diff --git a/libweston/compositor.c b/libweston/compositor.c index 117c6aa3..e94849bd 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -6269,6 +6269,13 @@ weston_output_transform_coordinate(struct weston_output *output, *y = p.f[1] / p.f[3]; } +static void +weston_output_reset_color_transforms(struct weston_output *output) +{ + weston_color_transform_unref(output->from_blend_to_output); + output->from_blend_to_output = NULL; +} + /** Removes output from compositor's list of enabled outputs * * \param output The weston_output object that is being removed. @@ -6280,6 +6287,8 @@ weston_output_transform_coordinate(struct weston_output *output, * - The output assignments of all views in the current scenegraph are * recomputed. * + * - Destroys output's color transforms. + * * - Presentation feedback is discarded. * * - Compositor is notified that outputs were changed and @@ -6324,6 +6333,8 @@ weston_compositor_remove_output(struct weston_output *output) weston_view_assign_output(view); } + weston_output_reset_color_transforms(output); + weston_presentation_feedback_discard_list(&output->feedback_list); weston_compositor_reflow_outputs(compositor, output, -output->width); @@ -6613,10 +6624,12 @@ WL_EXPORT int weston_output_enable(struct weston_output *output) { struct weston_compositor *c = output->compositor; + struct weston_color_manager *cm = c->color_manager; struct weston_output *iterator; struct weston_head *head; char *head_names; int x = 0, y = 0; + bool ok; if (output->enabled) { weston_log("Error: attempt to enable an enabled output '%s'\n", @@ -6672,12 +6685,23 @@ weston_output_enable(struct weston_output *output) wl_list_init(&output->paint_node_list); wl_list_init(&output->paint_node_z_order_list); + ok = cm->get_output_color_transform(cm, output, + &output->from_blend_to_output); + if (!ok) { + weston_log("Creating color transformation for output \"%s\" failed.\n", + output->name); + weston_output_reset_color_transforms(output); + return -1; + } + output->from_blend_to_output_by_backend = false; + /* Enable the output (set up the crtc or create a * window representing the output, set up the * renderer, etc) */ if (output->enable(output) < 0) { weston_log("Enabling output \"%s\" failed.\n", output->name); + weston_output_reset_color_transforms(output); return -1; } diff --git a/libweston/pixman-renderer.c b/libweston/pixman-renderer.c index 151eb8a5..78a0bcb8 100644 --- a/libweston/pixman-renderer.c +++ b/libweston/pixman-renderer.c @@ -566,6 +566,9 @@ pixman_renderer_repaint_output(struct weston_output *output, struct pixman_output_state *po = get_output_state(output); pixman_region32_t hw_damage; + assert(output->from_blend_to_output_by_backend || + output->from_blend_to_output == NULL); + if (!po->hw_buffer) { po->hw_extra_damage = NULL; return; diff --git a/libweston/renderer-gl/gl-renderer.c b/libweston/renderer-gl/gl-renderer.c index 5c91c36a..f20dee1f 100644 --- a/libweston/renderer-gl/gl-renderer.c +++ b/libweston/renderer-gl/gl-renderer.c @@ -1507,6 +1507,8 @@ blit_shadow_to_output(struct weston_output *output, pixman_region32_t translated_damage; GLfloat verts[4 * 2]; + assert(output->from_blend_to_output == NULL); + pixman_region32_init(&translated_damage); gl_renderer_use_program(gr, &sconf); @@ -1569,6 +1571,9 @@ gl_renderer_repaint_output(struct weston_output *output, enum gl_border_status border_status = BORDER_STATUS_CLEAN; struct weston_paint_node *pnode; + assert(output->from_blend_to_output_by_backend || + output->from_blend_to_output == NULL); + if (use_output(output) < 0) return;