/* * Copyright 2021 Collabora, Ltd. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial * portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include "config.h" #include #include #include "color.h" #include "libweston-internal.h" /** * Increase reference count of the color transform object * * \param xform The color transform. NULL is accepted too. * \return xform. */ WL_EXPORT struct weston_color_transform * weston_color_transform_ref(struct weston_color_transform *xform) { /* NULL is a valid color transform: identity */ if (!xform) return NULL; assert(xform->ref_count > 0); xform->ref_count++; return xform; } /** * Decrease and potentially destroy the color transform object * * \param xform The color transform. NULL is accepted too. */ WL_EXPORT void weston_color_transform_unref(struct weston_color_transform *xform) { if (!xform) return; assert(xform->ref_count > 0); if (--xform->ref_count > 0) return; wl_signal_emit(&xform->destroy_signal, xform); xform->cm->destroy_color_transform(xform); } /** * Initializes a newly allocated color transform object * * This is used only by color managers. They sub-class weston_color_transform. * * The reference count starts at 1. * * To destroy a weston_color_transform, use weston_color_transfor_unref(). */ WL_EXPORT void weston_color_transform_init(struct weston_color_transform *xform, struct weston_color_manager *cm) { xform->cm = cm; xform->ref_count = 1; wl_signal_init(&xform->destroy_signal); } /** Deep copy */ void weston_surface_color_transform_copy(struct weston_surface_color_transform *dst, const struct weston_surface_color_transform *src) { *dst = *src; dst->transform = weston_color_transform_ref(src->transform); } /** Unref contents */ void weston_surface_color_transform_fini(struct weston_surface_color_transform *surf_xform) { weston_color_transform_unref(surf_xform->transform); } /** * Ensure that the surface's color transformation for the given output is * populated in the paint nodes for all the views. * * Creates the color transformation description if necessary by calling * into the color manager. * * \param pnode Paint node defining the surface and the output. All * paint nodes with the same surface and output will be ensured. */ void weston_paint_node_ensure_color_transform(struct weston_paint_node *pnode) { struct weston_surface *surface = pnode->surface; struct weston_output *output = pnode->output; struct weston_color_manager *cm = surface->compositor->color_manager; struct weston_surface_color_transform surf_xform = {}; struct weston_paint_node *it; bool ok; /* * Invariant: all paint nodes with the same surface+output have the * same surf_xform state. */ if (pnode->surf_xform_valid) return; ok = cm->get_surface_color_transform(cm, surface, output, &surf_xform); wl_list_for_each(it, &surface->paint_node_list, surface_link) { if (it->output == output) { assert(it->surf_xform_valid == false); assert(it->surf_xform.transform == NULL); weston_surface_color_transform_copy(&it->surf_xform, &surf_xform); it->surf_xform_valid = ok; } } weston_surface_color_transform_fini(&surf_xform); if (!ok) { if (surface->resource) wl_resource_post_no_memory(surface->resource); weston_log("Failed to create color transformation for a surface.\n"); } }