color-lcms: add debug scope for color tranformations

It prints the existent color transformations for new subscribers. Also
prints any creation/destruction of color transformations.

Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
This commit is contained in:
Leandro Ribeiro 2023-03-06 17:25:33 -03:00 committed by Pekka Paalanen
parent cb542dd56a
commit d827bdd5d4
5 changed files with 184 additions and 3 deletions

View file

@ -33,6 +33,7 @@
#include "color.h"
#include "color-lcms.h"
#include "shared/helpers.h"
#include "shared/xalloc.h"
const char *
cmlcms_category_name(enum cmlcms_category cat)
@ -386,9 +387,36 @@ cmlcms_destroy(struct weston_color_manager *cm_base)
assert(wl_list_empty(&cm->color_profile_list));
cmsDeleteContext(cm->lcms_ctx);
weston_log_scope_destroy(cm->transforms_scope);
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);
}
}
WL_EXPORT struct weston_color_manager *
weston_color_manager_create(struct weston_compositor *compositor)
{
@ -412,5 +440,16 @@ 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);
if (!cm->transforms_scope)
goto err;
return &cm->base;
err:
free(cm);
return NULL;
}

View file

@ -29,12 +29,14 @@
#include <lcms2.h>
#include <libweston/libweston.h>
#include <libweston/weston-log.h>
#include "color.h"
#include "shared/helpers.h"
struct weston_color_manager_lcms {
struct weston_color_manager base;
struct weston_log_scope *transforms_scope;
cmsContext lcms_ctx;
struct wl_list color_transform_list; /* cmlcms_color_transform::link */
@ -205,6 +207,9 @@ cmlcms_color_transform_get(struct weston_color_manager_lcms *cm,
void
cmlcms_color_transform_destroy(struct cmlcms_color_transform *xform);
char *
cmlcms_color_transform_search_param_string(const struct cmlcms_color_transform_search_param *search_key);
struct cmlcms_color_profile *
ref_cprof(struct cmlcms_color_profile *cprof);

View file

@ -33,6 +33,7 @@
#include "color.h"
#include "color-lcms.h"
#include "shared/helpers.h"
#include "shared/string-helpers.h"
#include "shared/xalloc.h"
/**
@ -163,6 +164,8 @@ 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);
wl_list_remove(&xform->link);
cmsFreeToneCurveTriple(xform->pre_curve);
@ -177,6 +180,10 @@ cmlcms_color_transform_destroy(struct cmlcms_color_transform *xform)
unref_cprof(xform->search_key.input_profile);
unref_cprof(xform->search_key.output_profile);
weston_log_scope_printf(cm->transforms_scope,
"Destroyed color transformation %p.\n", xform);
free(xform);
}
@ -791,11 +798,39 @@ failed:
return false;
}
char *
cmlcms_color_transform_search_param_string(const struct cmlcms_color_transform_search_param *search_key)
{
const char *input_prof_desc = "none", *output_prof_desc = "none";
char *str;
if (search_key->input_profile)
input_prof_desc = search_key->input_profile->base.description;
if (search_key->output_profile)
output_prof_desc = search_key->output_profile->base.description;
str_printf(&str, " catergory: %s\n" \
" input profile: %s\n" \
" output profile: %s\n" \
" selected intent from output profile: %u\n",
cmlcms_category_name(search_key->category),
input_prof_desc,
output_prof_desc,
search_key->intent_output);
abort_oom_if_null(str);
return str;
}
static struct cmlcms_color_transform *
cmlcms_color_transform_create(struct weston_color_manager_lcms *cm,
const struct cmlcms_color_transform_search_param *search_param)
{
struct cmlcms_color_transform *xform;
const char *err_msg;
char *str;
xform = xzalloc(sizeof *xform);
weston_color_transform_init(&xform->base, &cm->base);
@ -804,6 +839,12 @@ cmlcms_color_transform_create(struct weston_color_manager_lcms *cm,
xform->search_key.input_profile = ref_cprof(search_param->input_profile);
xform->search_key.output_profile = ref_cprof(search_param->output_profile);
weston_log_scope_printf(cm->transforms_scope,
"New color transformation: %p\n", xform);
str = cmlcms_color_transform_search_param_string(&xform->search_key);
weston_log_scope_printf(cm->transforms_scope, "%s", str);
free(str);
/* Ensure the linearization etc. have been extracted. */
if (!search_param->output_profile->eotf[0]) {
if (!retrieve_eotf_and_output_inv_eotf(cm->lcms_ctx,
@ -811,8 +852,10 @@ cmlcms_color_transform_create(struct weston_color_manager_lcms *cm,
search_param->output_profile->eotf,
search_param->output_profile->output_inv_eotf_vcgt,
search_param->output_profile->vcgt,
cmlcms_reasonable_1D_points()))
cmlcms_reasonable_1D_points())) {
err_msg = "retrieve_eotf_and_output_inv_eotf failed";
goto error;
}
}
/*
@ -823,8 +866,10 @@ cmlcms_color_transform_create(struct weston_color_manager_lcms *cm,
switch (search_param->category) {
case CMLCMS_CATEGORY_INPUT_TO_BLEND:
case CMLCMS_CATEGORY_INPUT_TO_OUTPUT:
if (!xform_realize_chain(xform))
if (!xform_realize_chain(xform)) {
err_msg = "xform_realize_chain failed";
goto error;
}
break;
case CMLCMS_CATEGORY_BLEND_TO_OUTPUT:
xform->base.pre_curve.type = WESTON_COLOR_CURVE_TYPE_LUT_3x1D;
@ -837,11 +882,17 @@ cmlcms_color_transform_create(struct weston_color_manager_lcms *cm,
wl_list_insert(&cm->color_transform_list, &xform->link);
assert(xform->status != CMLCMS_TRANSFORM_FAILED);
str = weston_color_transform_string(&xform->base);
weston_log_scope_printf(cm->transforms_scope, " %s", str);
free(str);
return xform;
error:
weston_log_scope_printf(cm->transforms_scope,
" %s\n", err_msg);
cmlcms_color_transform_destroy(xform);
weston_log("CM cmlcms_color_transform_create failed\n");
return NULL;
}

View file

@ -38,6 +38,8 @@
#include "color.h"
#include "libweston-internal.h"
#include <libweston/weston-log.h>
#include "shared/xalloc.h"
/**
* Increase reference count of the color profile object
@ -165,6 +167,87 @@ weston_color_transform_init(struct weston_color_transform *xform,
wl_signal_init(&xform->destroy_signal);
}
static const char *
curve_type_to_str(enum weston_color_curve_type curve_type)
{
switch (curve_type) {
case WESTON_COLOR_CURVE_TYPE_IDENTITY:
return "identity";
case WESTON_COLOR_CURVE_TYPE_LUT_3x1D:
return "3x1D LUT";
}
return "???";
}
static const char *
mapping_type_to_str(enum weston_color_mapping_type mapping_type)
{
switch (mapping_type) {
case WESTON_COLOR_MAPPING_TYPE_IDENTITY:
return "identity";
case WESTON_COLOR_MAPPING_TYPE_3D_LUT:
return "3D LUT";
case WESTON_COLOR_MAPPING_TYPE_MATRIX:
return "matrix";
}
return "???";
}
/**
* Print the color transform pipeline to a string
*
* \param xform The color transform.
* \return The string in which the pipeline is printed.
*/
WL_EXPORT char *
weston_color_transform_string(const struct weston_color_transform *xform)
{
enum weston_color_mapping_type mapping_type = xform->mapping.type;
enum weston_color_curve_type pre_type = xform->pre_curve.type;
enum weston_color_curve_type post_type = xform->post_curve.type;
const char *empty = "";
const char *sep = empty;
FILE *fp;
char *str = NULL;
size_t size = 0;
fp = open_memstream(&str, &size);
abort_oom_if_null(fp);
fprintf(fp, "pipeline: ");
if (pre_type != WESTON_COLOR_CURVE_TYPE_IDENTITY) {
fprintf(fp, "%spre %s", sep, curve_type_to_str(pre_type));
if (pre_type == WESTON_COLOR_CURVE_TYPE_LUT_3x1D)
fprintf(fp, " [%u]", xform->pre_curve.u.lut_3x1d.optimal_len);
sep = ", ";
}
if (mapping_type != WESTON_COLOR_MAPPING_TYPE_IDENTITY) {
fprintf(fp, "%smapping %s", sep, mapping_type_to_str(mapping_type));
if (mapping_type == WESTON_COLOR_MAPPING_TYPE_3D_LUT)
fprintf(fp, " [%u]", xform->mapping.u.lut3d.optimal_len);
sep = ", ";
}
if (post_type != WESTON_COLOR_CURVE_TYPE_IDENTITY) {
fprintf(fp, "%spost %s", sep, curve_type_to_str(post_type));
if (post_type == WESTON_COLOR_CURVE_TYPE_LUT_3x1D)
fprintf(fp, " [%u]", xform->post_curve.u.lut_3x1d.optimal_len);
sep = ", ";
}
if (sep == empty)
fprintf(fp, "identity\n");
else
fprintf(fp, "\n");
fclose(fp);
abort_oom_if_null(str);
return str;
}
/** Deep copy */
void
weston_surface_color_transform_copy(struct weston_surface_color_transform *dst,

View file

@ -337,6 +337,9 @@ void
weston_color_transform_init(struct weston_color_transform *xform,
struct weston_color_manager *cm);
char *
weston_color_transform_string(const struct weston_color_transform *xform);
void
weston_surface_color_transform_copy(struct weston_surface_color_transform *dst,
const struct weston_surface_color_transform *src);