Skip to content
Commits on Source (14)
......@@ -32,7 +32,7 @@
#include "color.h"
#include "color-lcms.h"
#include "color-management.h"
#include "color-properties.h"
#include "shared/helpers.h"
#include "shared/xalloc.h"
#include "shared/weston-assert.h"
......@@ -76,11 +76,11 @@ cmlcms_get_render_intent(enum cmlcms_category cat,
}
static struct cmlcms_color_profile *
get_cprof_or_stock_sRGB(struct weston_color_manager_lcms *cm,
struct weston_color_profile *cprof_base)
to_cprof_or_stock_sRGB(struct weston_color_manager_lcms *cm,
struct weston_color_profile *cprof_base)
{
if (cprof_base)
return get_cprof(cprof_base);
return to_cmlcms_cprof(cprof_base);
else
return cm->sRGB_profile;
}
......@@ -88,7 +88,7 @@ get_cprof_or_stock_sRGB(struct weston_color_manager_lcms *cm,
static void
cmlcms_destroy_color_transform(struct weston_color_transform *xform_base)
{
struct cmlcms_color_transform *xform = get_xform(xform_base);
struct cmlcms_color_transform *xform = to_cmlcms_xform(xform_base);
cmlcms_color_transform_destroy(xform);
}
......@@ -99,15 +99,15 @@ cmlcms_get_surface_color_transform(struct weston_color_manager *cm_base,
struct weston_output *output,
struct weston_surface_color_transform *surf_xform)
{
struct weston_color_manager_lcms *cm = get_cmlcms(cm_base);
struct weston_color_manager_lcms *cm = to_cmlcms(cm_base);
struct cmlcms_color_transform *xform;
/* TODO: take weston_output::eotf_mode into account */
struct cmlcms_color_transform_search_param param = {
.category = CMLCMS_CATEGORY_INPUT_TO_BLEND,
.input_profile = get_cprof_or_stock_sRGB(cm, surface->color_profile),
.output_profile = get_cprof_or_stock_sRGB(cm, output->color_profile),
.input_profile = to_cprof_or_stock_sRGB(cm, surface->color_profile),
.output_profile = to_cprof_or_stock_sRGB(cm, output->color_profile),
};
param.render_intent = cmlcms_get_render_intent(param.category,
surface, output);
......@@ -142,7 +142,7 @@ cmlcms_get_blend_to_output_color_transform(struct weston_color_manager_lcms *cm,
struct cmlcms_color_transform_search_param param = {
.category = CMLCMS_CATEGORY_BLEND_TO_OUTPUT,
.input_profile = NULL,
.output_profile = get_cprof_or_stock_sRGB(cm, output->color_profile),
.output_profile = to_cprof_or_stock_sRGB(cm, output->color_profile),
};
param.render_intent = cmlcms_get_render_intent(param.category,
NULL, output);
......@@ -167,7 +167,7 @@ cmlcms_get_sRGB_to_output_color_transform(struct weston_color_manager_lcms *cm,
struct cmlcms_color_transform_search_param param = {
.category = CMLCMS_CATEGORY_INPUT_TO_OUTPUT,
.input_profile = cm->sRGB_profile,
.output_profile = get_cprof_or_stock_sRGB(cm, output->color_profile),
.output_profile = to_cprof_or_stock_sRGB(cm, output->color_profile),
};
param.render_intent = cmlcms_get_render_intent(param.category,
NULL, output);
......@@ -200,7 +200,7 @@ cmlcms_get_sRGB_to_blend_color_transform(struct weston_color_manager_lcms *cm,
struct cmlcms_color_transform_search_param param = {
.category = CMLCMS_CATEGORY_INPUT_TO_BLEND,
.input_profile = cm->sRGB_profile,
.output_profile = get_cprof_or_stock_sRGB(cm, output->color_profile),
.output_profile = to_cprof_or_stock_sRGB(cm, output->color_profile),
};
param.render_intent = cmlcms_get_render_intent(param.category,
NULL, output);
......@@ -305,7 +305,7 @@ static struct weston_output_color_outcome *
cmlcms_create_output_color_outcome(struct weston_color_manager *cm_base,
struct weston_output *output)
{
struct weston_color_manager_lcms *cm = get_cmlcms(cm_base);
struct weston_color_manager_lcms *cm = to_cmlcms(cm_base);
struct weston_output_color_outcome *co;
co = zalloc(sizeof *co);
......@@ -338,6 +338,50 @@ out_fail:
return NULL;
}
static void
transforms_scope_new_sub(struct weston_log_subscription *subs, void *data)
{
struct weston_color_manager_lcms *cm = data;
struct cmlcms_color_transform *xform;
char *str;
if (wl_list_empty(&cm->color_transform_list))
return;
weston_log_subscription_printf(subs, "Existent:\n");
wl_list_for_each(xform, &cm->color_transform_list, link) {
weston_log_subscription_printf(subs, "Color transformation %p:\n", xform);
str = cmlcms_color_transform_search_param_string(&xform->search_key);
weston_log_subscription_printf(subs, "%s", str);
free(str);
str = weston_color_transform_string(&xform->base);
weston_log_subscription_printf(subs, " %s", str);
free(str);
}
}
static void
profiles_scope_new_sub(struct weston_log_subscription *subs, void *data)
{
struct weston_color_manager_lcms *cm = data;
struct cmlcms_color_profile *cprof;
char *str;
if (wl_list_empty(&cm->color_profile_list))
return;
weston_log_subscription_printf(subs, "Existent:\n");
wl_list_for_each(cprof, &cm->color_profile_list, link) {
weston_log_subscription_printf(subs, "Color profile %p:\n", cprof);
str = cmlcms_color_profile_print(cprof);
weston_log_subscription_printf(subs, "%s", str);
free(str);
}
}
static void
lcms_error_logger(cmsContext context_id,
cmsUInt32Number error_code,
......@@ -349,34 +393,68 @@ lcms_error_logger(cmsContext context_id,
static bool
cmlcms_init(struct weston_color_manager *cm_base)
{
struct weston_color_manager_lcms *cm = get_cmlcms(cm_base);
struct weston_color_manager_lcms *cm = to_cmlcms(cm_base);
struct weston_compositor *compositor = cm->base.compositor;
if (!(cm->base.compositor->capabilities & WESTON_CAP_COLOR_OPS)) {
if (!(compositor->capabilities & WESTON_CAP_COLOR_OPS)) {
weston_log("color-lcms: error: color operations capability missing. Is GL-renderer not in use?\n");
return false;
}
cm->transforms_scope =
weston_compositor_add_log_scope(compositor, "color-lcms-transformations",
"Color transformation creation and destruction.\n",
transforms_scope_new_sub, NULL, cm);
weston_assert_ptr(compositor, cm->transforms_scope);
cm->optimizer_scope =
weston_compositor_add_log_scope(compositor, "color-lcms-optimizer",
"Color transformation pipeline optimizer. It's best " \
"used together with the color-lcms-transformations " \
"log scope.\n", NULL, NULL, NULL);
weston_assert_ptr(compositor, cm->optimizer_scope);
cm->profiles_scope =
weston_compositor_add_log_scope(compositor, "color-lcms-profiles",
"Color profile creation and destruction.\n",
profiles_scope_new_sub, NULL, cm);
weston_assert_ptr(compositor, cm->profiles_scope);
cm->lcms_ctx = cmsCreateContext(NULL, cm);
if (!cm->lcms_ctx) {
weston_log("color-lcms error: creating LittCMS context failed.\n");
return false;
goto out_err;
}
cmsSetLogErrorHandlerTHR(cm->lcms_ctx, lcms_error_logger);
if (!cmlcms_create_stock_profile(cm)) {
weston_log("color-lcms: error: cmlcms_create_stock_profile failed\n");
return false;
goto out_err;
}
weston_log("LittleCMS %d initialized.\n", cmsGetEncodedCMMversion());
return true;
out_err:
if (cm->lcms_ctx)
cmsDeleteContext(cm->lcms_ctx);
cm->lcms_ctx = NULL;
weston_log_scope_destroy(cm->transforms_scope);
cm->transforms_scope = NULL;
weston_log_scope_destroy(cm->optimizer_scope);
cm->optimizer_scope = NULL;
weston_log_scope_destroy(cm->profiles_scope);
cm->profiles_scope = NULL;
return false;
}
static void
cmlcms_destroy(struct weston_color_manager *cm_base)
{
struct weston_color_manager_lcms *cm = get_cmlcms(cm_base);
struct weston_color_manager_lcms *cm = to_cmlcms(cm_base);
if (cm->sRGB_profile) {
/* TODO: when we fix the ugly bug described below, we should
......@@ -406,7 +484,8 @@ cmlcms_destroy(struct weston_color_manager *cm_base)
assert(wl_list_empty(&cm->color_transform_list));
assert(wl_list_empty(&cm->color_profile_list));
cmsDeleteContext(cm->lcms_ctx);
if (cm->lcms_ctx)
cmsDeleteContext(cm->lcms_ctx);
weston_log_scope_destroy(cm->transforms_scope);
weston_log_scope_destroy(cm->optimizer_scope);
......@@ -415,50 +494,6 @@ cmlcms_destroy(struct weston_color_manager *cm_base)
free(cm);
}
static void
transforms_scope_new_sub(struct weston_log_subscription *subs, void *data)
{
struct weston_color_manager_lcms *cm = data;
struct cmlcms_color_transform *xform;
char *str;
if (wl_list_empty(&cm->color_transform_list))
return;
weston_log_subscription_printf(subs, "Existent:\n");
wl_list_for_each(xform, &cm->color_transform_list, link) {
weston_log_subscription_printf(subs, "Color transformation %p:\n", xform);
str = cmlcms_color_transform_search_param_string(&xform->search_key);
weston_log_subscription_printf(subs, "%s", str);
free(str);
str = weston_color_transform_string(&xform->base);
weston_log_subscription_printf(subs, " %s", str);
free(str);
}
}
static void
profiles_scope_new_sub(struct weston_log_subscription *subs, void *data)
{
struct weston_color_manager_lcms *cm = data;
struct cmlcms_color_profile *cprof;
char *str;
if (wl_list_empty(&cm->color_profile_list))
return;
weston_log_subscription_printf(subs, "Existent:\n");
wl_list_for_each(cprof, &cm->color_profile_list, link) {
weston_log_subscription_printf(subs, "Color profile %p:\n", cprof);
str = cmlcms_color_profile_print(cprof);
weston_log_subscription_printf(subs, "%s", str);
free(str);
}
}
WL_EXPORT struct weston_color_manager *
weston_color_manager_create(struct weston_compositor *compositor)
{
......@@ -470,20 +505,17 @@ weston_color_manager_create(struct weston_compositor *compositor)
cm->base.name = "work-in-progress";
cm->base.compositor = compositor;
cm->base.supports_client_protocol = true;
cm->base.init = cmlcms_init;
cm->base.destroy = cmlcms_destroy;
cm->base.destroy_color_profile = cmlcms_destroy_color_profile;
cm->base.get_stock_sRGB_color_profile = cmlcms_get_stock_sRGB_color_profile;
cm->base.ref_stock_sRGB_color_profile = cmlcms_ref_stock_sRGB_color_profile;
cm->base.get_color_profile_from_icc = cmlcms_get_color_profile_from_icc;
cm->base.send_image_desc_info = cmlcms_send_image_desc_info;
cm->base.destroy_color_transform = cmlcms_destroy_color_transform;
cm->base.get_surface_color_transform = cmlcms_get_surface_color_transform;
cm->base.create_output_color_outcome = cmlcms_create_output_color_outcome;
/* We support the CM&HDR protocol extension when using LittleCMS. */
if (weston_compositor_enable_color_management_protocol(compositor) < 0)
goto err;
/* We still do not support creating parametric color profiles. */
cm->base.supported_color_features = (1 << WESTON_COLOR_FEATURE_ICC);
......@@ -497,29 +529,5 @@ weston_color_manager_create(struct weston_compositor *compositor)
wl_list_init(&cm->color_transform_list);
wl_list_init(&cm->color_profile_list);
cm->transforms_scope =
weston_compositor_add_log_scope(compositor, "color-lcms-transformations",
"Color transformation creation and destruction.\n",
transforms_scope_new_sub, NULL, cm);
cm->optimizer_scope =
weston_compositor_add_log_scope(compositor, "color-lcms-optimizer",
"Color transformation pipeline optimizer. It's best " \
"used together with the color-lcms-transformations " \
"log scope.\n", NULL, NULL, NULL);
cm->profiles_scope =
weston_compositor_add_log_scope(compositor, "color-lcms-profiles",
"Color profile creation and destruction.\n",
profiles_scope_new_sub, NULL, cm);
if (!cm->profiles_scope || !cm->transforms_scope || !cm->optimizer_scope)
goto err;
return &cm->base;
err:
weston_log_scope_destroy(cm->transforms_scope);
weston_log_scope_destroy(cm->optimizer_scope);
weston_log_scope_destroy(cm->profiles_scope);
free(cm);
return NULL;
}
......@@ -48,7 +48,7 @@ struct weston_color_manager_lcms {
};
static inline struct weston_color_manager_lcms *
get_cmlcms(struct weston_color_manager *cm_base)
to_cmlcms(struct weston_color_manager *cm_base)
{
return container_of(cm_base, struct weston_color_manager_lcms, base);
}
......@@ -126,13 +126,13 @@ const char *
cmlcms_category_name(enum cmlcms_category cat);
static inline struct cmlcms_color_profile *
get_cprof(struct weston_color_profile *cprof_base)
to_cmlcms_cprof(struct weston_color_profile *cprof_base)
{
return container_of(cprof_base, struct cmlcms_color_profile, base);
}
struct weston_color_profile *
cmlcms_get_stock_sRGB_color_profile(struct weston_color_manager *cm_base);
cmlcms_ref_stock_sRGB_color_profile(struct weston_color_manager *cm_base);
bool
cmlcms_get_color_profile_from_icc(struct weston_color_manager *cm,
......@@ -208,7 +208,7 @@ struct cmlcms_color_transform {
};
static inline struct cmlcms_color_transform *
get_xform(struct weston_color_transform *xform_base)
to_cmlcms_xform(struct weston_color_transform *xform_base)
{
return container_of(xform_base, struct cmlcms_color_transform, base);
}
......
......@@ -343,7 +343,7 @@ cmlcms_color_profile_create(struct weston_color_manager_lcms *cm,
void
cmlcms_color_profile_destroy(struct cmlcms_color_profile *cprof)
{
struct weston_color_manager_lcms *cm = get_cmlcms(cprof->base.cm);
struct weston_color_manager_lcms *cm = to_cmlcms(cprof->base.cm);
wl_list_remove(&cprof->link);
cmsFreeToneCurveTriple(cprof->vcgt);
......@@ -448,9 +448,9 @@ err_close:
}
struct weston_color_profile *
cmlcms_get_stock_sRGB_color_profile(struct weston_color_manager *cm_base)
cmlcms_ref_stock_sRGB_color_profile(struct weston_color_manager *cm_base)
{
struct weston_color_manager_lcms *cm = get_cmlcms(cm_base);
struct weston_color_manager_lcms *cm = to_cmlcms(cm_base);
struct cmlcms_color_profile *cprof;
cprof = ref_cprof(cm->sRGB_profile);
......@@ -466,7 +466,7 @@ cmlcms_get_color_profile_from_icc(struct weston_color_manager *cm_base,
struct weston_color_profile **cprof_out,
char **errmsg)
{
struct weston_color_manager_lcms *cm = get_cmlcms(cm_base);
struct weston_color_manager_lcms *cm = to_cmlcms(cm_base);
cmsHPROFILE profile;
struct cmlcms_md5_sum md5sum;
struct cmlcms_color_profile *cprof = NULL;
......@@ -530,9 +530,9 @@ bool
cmlcms_send_image_desc_info(struct cm_image_desc_info *cm_image_desc_info,
struct weston_color_profile *cprof_base)
{
struct weston_color_manager_lcms *cm = get_cmlcms(cprof_base->cm);
struct weston_color_manager_lcms *cm = to_cmlcms(cprof_base->cm);
struct weston_compositor *compositor = cm->base.compositor;
struct cmlcms_color_profile *cprof = get_cprof(cprof_base);
struct cmlcms_color_profile *cprof = to_cmlcms_cprof(cprof_base);
const struct weston_color_primaries_info *primaries_info;
const struct weston_color_tf_info *tf_info;
int32_t fd;
......@@ -593,7 +593,7 @@ cmlcms_send_image_desc_info(struct cm_image_desc_info *cm_image_desc_info,
void
cmlcms_destroy_color_profile(struct weston_color_profile *cprof_base)
{
struct cmlcms_color_profile *cprof = get_cprof(cprof_base);
struct cmlcms_color_profile *cprof = to_cmlcms_cprof(cprof_base);
cmlcms_color_profile_destroy(cprof);
}
......@@ -91,7 +91,7 @@ static void
cmlcms_fill_in_output_inv_eotf_vcgt(struct weston_color_transform *xform_base,
float *values, unsigned len)
{
struct cmlcms_color_transform *xform = get_xform(xform_base);
struct cmlcms_color_transform *xform = to_cmlcms_xform(xform_base);
struct cmlcms_color_profile *p = xform->search_key.output_profile;
assert(p && "output_profile");
......@@ -102,7 +102,7 @@ static void
cmlcms_fill_in_pre_curve(struct weston_color_transform *xform_base,
float *values, unsigned len)
{
struct cmlcms_color_transform *xform = get_xform(xform_base);
struct cmlcms_color_transform *xform = to_cmlcms_xform(xform_base);
fill_in_curves(xform->pre_curve, values, len);
}
......@@ -111,7 +111,7 @@ static void
cmlcms_fill_in_post_curve(struct weston_color_transform *xform_base,
float *values, unsigned len)
{
struct cmlcms_color_transform *xform = get_xform(xform_base);
struct cmlcms_color_transform *xform = to_cmlcms_xform(xform_base);
fill_in_curves(xform->post_curve, values, len);
}
......@@ -135,7 +135,7 @@ static void
cmlcms_fill_in_3dlut(struct weston_color_transform *xform_base,
float *lut, unsigned int len)
{
struct cmlcms_color_transform *xform = get_xform(xform_base);
struct cmlcms_color_transform *xform = to_cmlcms_xform(xform_base);
float rgb_in[3];
float rgb_out[3];
unsigned int index;
......@@ -166,7 +166,7 @@ cmlcms_fill_in_3dlut(struct weston_color_transform *xform_base,
void
cmlcms_color_transform_destroy(struct cmlcms_color_transform *xform)
{
struct weston_color_manager_lcms *cm = get_cmlcms(xform->base.cm);
struct weston_color_manager_lcms *cm = to_cmlcms(xform->base.cm);
wl_list_remove(&xform->link);
......@@ -813,7 +813,7 @@ transform_factory(_cmsTransform2Fn *xform_fn,
xform = cmsGetContextUserData(context_id);
assert(xform);
cm = get_cmlcms(xform->base.cm);
cm = to_cmlcms(xform->base.cm);
/* Print pipeline before optimization */
weston_log_scope_printf(cm->optimizer_scope,
......@@ -880,7 +880,7 @@ profile_from_rgb_curves(cmsContext ctx, cmsToneCurve *const curveset[3])
static bool
xform_realize_chain(struct cmlcms_color_transform *xform)
{
struct weston_color_manager_lcms *cm = get_cmlcms(xform->base.cm);
struct weston_color_manager_lcms *cm = to_cmlcms(xform->base.cm);
struct cmlcms_color_profile *output_profile = xform->search_key.output_profile;
cmsHPROFILE chain[5];
unsigned chain_len = 0;
......
......@@ -1105,11 +1105,15 @@ bind_color_management(struct wl_client *client, void *data, uint32_t version,
* \param compositor The compositor to init for.
* \return Zero on success, -1 on failure.
*/
WL_EXPORT int
int
weston_compositor_enable_color_management_protocol(struct weston_compositor *compositor)
{
uint32_t version = 1;
weston_assert_bit_is_set(compositor,
compositor->color_manager->supported_rendering_intents,
WESTON_RENDER_INTENT_PERCEPTUAL);
if (!wl_global_create(compositor->wl_display,
&xx_color_manager_v2_interface,
version, compositor, bind_color_management))
......
......@@ -28,6 +28,8 @@
#include "color-properties.h"
struct cm_image_desc_info;
int
weston_compositor_enable_color_management_protocol(struct weston_compositor *compositor);
......
......@@ -54,13 +54,13 @@ check_output_eotf_mode(struct weston_output *output)
}
static struct weston_color_manager_noop *
get_cmnoop(struct weston_color_manager *cm_base)
to_cmnoop(struct weston_color_manager *cm_base)
{
return container_of(cm_base, struct weston_color_manager_noop, base);
}
static inline struct cmnoop_color_profile *
get_cprof(struct weston_color_profile *cprof_base)
to_cmnoop_cprof(struct weston_color_profile *cprof_base)
{
return container_of(cprof_base, struct cmnoop_color_profile, base);
}
......@@ -94,7 +94,7 @@ cmnoop_color_profile_destroy(struct cmnoop_color_profile *cprof)
static void
cmnoop_destroy_color_profile(struct weston_color_profile *cprof_base)
{
struct cmnoop_color_profile *cprof = get_cprof(cprof_base);
struct cmnoop_color_profile *cprof = to_cmnoop_cprof(cprof_base);
cmnoop_color_profile_destroy(cprof);
}
......@@ -113,9 +113,9 @@ cmnoop_color_profile_create(struct weston_color_manager_noop *cm, char *desc)
}
static struct weston_color_profile *
cmnoop_get_stock_sRGB_color_profile(struct weston_color_manager *cm_base)
cmnoop_ref_stock_sRGB_color_profile(struct weston_color_manager *cm_base)
{
struct weston_color_manager_noop *cm = get_cmnoop(cm_base);
struct weston_color_manager_noop *cm = to_cmnoop(cm_base);
struct cmnoop_color_profile *cprof;
cprof = ref_cprof(cm->stock_cprof);
......@@ -148,16 +148,16 @@ cmnoop_get_surface_color_transform(struct weston_color_manager *cm_base,
struct weston_surface_color_transform *surf_xform)
{
struct weston_compositor *compositor = output->compositor;
struct weston_color_manager_noop *cmnoop = get_cmnoop(cm_base);
struct weston_color_manager_noop *cmnoop = to_cmnoop(cm_base);
/* If surface has a cprof, it has to be the stock one. */
if (surface->color_profile)
weston_assert_ptr_eq(compositor, get_cprof(surface->color_profile),
weston_assert_ptr_eq(compositor, to_cmnoop_cprof(surface->color_profile),
cmnoop->stock_cprof);
/* The output must have a cprof, and it has to be the stock one. */
weston_assert_ptr(compositor, output->color_profile);
weston_assert_ptr_eq(compositor, get_cprof(output->color_profile),
weston_assert_ptr_eq(compositor, to_cmnoop_cprof(output->color_profile),
cmnoop->stock_cprof);
if (!check_output_eotf_mode(output))
......@@ -175,11 +175,11 @@ cmnoop_create_output_color_outcome(struct weston_color_manager *cm_base,
struct weston_output *output)
{
struct weston_compositor *compositor = cm_base->compositor;
struct weston_color_manager_noop *cmnoop = get_cmnoop(cm_base);
struct weston_color_manager_noop *cmnoop = to_cmnoop(cm_base);
struct weston_output_color_outcome *co;
weston_assert_ptr(compositor, output->color_profile);
weston_assert_ptr_eq(compositor, get_cprof(output->color_profile),
weston_assert_ptr_eq(compositor, to_cmnoop_cprof(output->color_profile),
cmnoop->stock_cprof);
if (!check_output_eotf_mode(output))
......@@ -216,7 +216,7 @@ cmnoop_create_stock_profile(struct weston_color_manager_noop *cm)
static bool
cmnoop_init(struct weston_color_manager *cm_base)
{
struct weston_color_manager_noop *cm = get_cmnoop(cm_base);
struct weston_color_manager_noop *cm = to_cmnoop(cm_base);
if (!cmnoop_create_stock_profile(cm))
return false;
......@@ -228,7 +228,7 @@ cmnoop_init(struct weston_color_manager *cm_base)
static void
cmnoop_destroy(struct weston_color_manager *cm_base)
{
struct weston_color_manager_noop *cmnoop = get_cmnoop(cm_base);
struct weston_color_manager_noop *cmnoop = to_cmnoop(cm_base);
/* TODO: change this assert to make sure that ref_count is equal to 1.
* Currently we have a bug in which we leak surfaces when shutting down
......@@ -250,10 +250,11 @@ weston_color_manager_noop_create(struct weston_compositor *compositor)
cm->base.name = "no-op";
cm->base.compositor = compositor;
cm->base.supports_client_protocol = false;
cm->base.init = cmnoop_init;
cm->base.destroy = cmnoop_destroy;
cm->base.destroy_color_profile = cmnoop_destroy_color_profile;
cm->base.get_stock_sRGB_color_profile = cmnoop_get_stock_sRGB_color_profile;
cm->base.ref_stock_sRGB_color_profile = cmnoop_ref_stock_sRGB_color_profile;
cm->base.get_color_profile_from_icc = cmnoop_get_color_profile_from_icc;
cm->base.send_image_desc_info = NULL;
cm->base.destroy_color_transform = cmnoop_destroy_color_transform;
......
......@@ -252,6 +252,9 @@ struct weston_color_manager {
/** This compositor instance */
struct weston_compositor *compositor;
/** Supports the Wayland CM&HDR protocol extension? */
bool supports_client_protocol;
/**
* Supported color features from Wayland CM&HDR protocol extension.
*
......@@ -280,13 +283,13 @@ struct weston_color_manager {
void
(*destroy_color_profile)(struct weston_color_profile *cprof);
/** Gets a reference to the stock sRGB color profile
/** Gets a new reference to the stock sRGB color profile
*
* \param cm The color manager.
* \return A reference to the stock sRGB profile, never returns NULL.
* \return A new reference to the stock sRGB profile, never returns NULL.
*/
struct weston_color_profile *
(*get_stock_sRGB_color_profile)(struct weston_color_manager *cm);
(*ref_stock_sRGB_color_profile)(struct weston_color_manager *cm);
/** Create a color profile from ICC data
*
......
......@@ -859,7 +859,7 @@ weston_surface_update_preferred_color_profile(struct weston_surface *surface)
} else {
/* Unmapped surface and no outputs available, so let's pick
* stock sRGB color profile. */
new = cm->get_stock_sRGB_color_profile(cm);
new = cm->ref_stock_sRGB_color_profile(cm);
}
/* Nothing to do. */
......@@ -7583,7 +7583,7 @@ weston_output_set_color_profile(struct weston_output *output,
old = output->color_profile;
new = cprof ? weston_color_profile_ref(cprof) :
cm->get_stock_sRGB_color_profile(cm);
cm->ref_stock_sRGB_color_profile(cm);
/* Nothing to do. */
if (new == old) {
......@@ -7824,7 +7824,7 @@ weston_output_init(struct weston_output *output,
/* Set the stock sRGB color profile for the output. Libweston users are
* free to set the color profile to whatever they want later on. */
cm = compositor->color_manager;
output->color_profile = cm->get_stock_sRGB_color_profile(cm);
output->color_profile = cm->ref_stock_sRGB_color_profile(cm);
}
/** Adds weston_output object to pending output list.
......@@ -9455,6 +9455,17 @@ weston_compositor_backends_loaded(struct weston_compositor *compositor)
return -1;
weston_log("Color manager: %s\n", compositor->color_manager->name);
weston_log_continue(STAMP_SPACE " protocol support: %s\n",
yesno(compositor->color_manager->supports_client_protocol));
if (compositor->color_manager->supports_client_protocol &&
weston_compositor_enable_color_management_protocol(compositor) < 0) {
/*
* The only way out is to quit the compositor,
* and that will clean up.
*/
return -1;
}
return 0;
}
......
......@@ -30,6 +30,7 @@
#include <stdarg.h>
#include <string.h>
#include <stdbool.h>
#include <inttypes.h>
struct weston_compositor;
......@@ -110,3 +111,15 @@ do { \
#define weston_assert_str_eq(compositor, a, b) \
weston_assert_fn_(compositor, strcmp, a, b, const char *, "%s", ==)
#define weston_assert_bit_is_set(compositor, value, bit) \
({ \
struct weston_compositor *ec = compositor; \
uint64_t v = (value); \
uint8_t b = (bit); \
bool cond = (v >> b) & 1; \
if (!cond) \
custom_assert_fail_(ec, "%s:%u: Assertion failed! Bit %s (%u) of %s (0x%" PRIx64 ") is not set.\n", \
__FILE__, __LINE__, #bit, b, #value, v); \
cond; \
})
......@@ -126,4 +126,10 @@ TEST(asserts)
abort_if_not(ret);
ret = weston_assert_my_type_lt(compositor, &a, &b);
abort_if_not(ret == false);
uint32_t bitfield = 0xffff;
ret = weston_assert_bit_is_set(compositor, bitfield, 2);
abort_if_not(ret);
ret = weston_assert_bit_is_set(compositor, bitfield, 57);
abort_if_not(ret == false);
}
......@@ -170,7 +170,7 @@ mock_create_output_color_outcome(struct weston_color_manager *cm_base,
}
static struct weston_color_profile *
mock_cm_get_stock_sRGB_color_profile(struct weston_color_manager *mock_cm)
mock_cm_ref_stock_sRGB_color_profile(struct weston_color_manager *mock_cm)
{
struct weston_color_profile *mock_cprof;
......@@ -206,7 +206,7 @@ TEST_P(color_characteristics_config_error, config_cases)
size_t logsize;
struct mock_color_manager mock_cm = {
.base.create_output_color_outcome = mock_create_output_color_outcome,
.base.get_stock_sRGB_color_profile = mock_cm_get_stock_sRGB_color_profile,
.base.ref_stock_sRGB_color_profile = mock_cm_ref_stock_sRGB_color_profile,
.base.destroy_color_profile = mock_cm_destroy_color_profile,
};
struct weston_compositor mock_compositor = {
......@@ -248,7 +248,7 @@ TEST(weston_output_set_color_characteristics_null)
{
struct mock_color_manager mock_cm = {
.base.create_output_color_outcome = mock_create_output_color_outcome,
.base.get_stock_sRGB_color_profile = mock_cm_get_stock_sRGB_color_profile,
.base.ref_stock_sRGB_color_profile = mock_cm_ref_stock_sRGB_color_profile,
.base.destroy_color_profile = mock_cm_destroy_color_profile,
};
struct weston_compositor mock_compositor = {
......@@ -329,7 +329,7 @@ TEST_P(hdr_metadata_type1_errors, value_cases)
};
struct mock_color_manager mock_cm = {
.base.create_output_color_outcome = mock_create_output_color_outcome,
.base.get_stock_sRGB_color_profile = mock_cm_get_stock_sRGB_color_profile,
.base.ref_stock_sRGB_color_profile = mock_cm_ref_stock_sRGB_color_profile,
.base.destroy_color_profile = mock_cm_destroy_color_profile,
.test_hdr_meta = &meta,
};
......@@ -374,7 +374,7 @@ TEST(hdr_metadata_type1_ignore_unflagged)
};
struct mock_color_manager mock_cm = {
.base.create_output_color_outcome = mock_create_output_color_outcome,
.base.get_stock_sRGB_color_profile = mock_cm_get_stock_sRGB_color_profile,
.base.ref_stock_sRGB_color_profile = mock_cm_ref_stock_sRGB_color_profile,
.base.destroy_color_profile = mock_cm_destroy_color_profile,
.test_hdr_meta = &meta,
};
......