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;