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 <pekka.paalanen@collabora.com>
This commit is contained in:
Pekka Paalanen 2021-02-25 12:03:28 +02:00 committed by Pekka Paalanen
parent 90a5ffa097
commit 1d2eee208c
6 changed files with 65 additions and 0 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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 *

View File

@ -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;
}

View File

@ -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;

View File

@ -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;