summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeandro Ribeiro <leandro.ribeiro@collabora.com>2023-03-09 18:16:55 -0300
committerPekka Paalanen <pq@iki.fi>2023-04-12 10:03:32 +0000
commit84eb3158b4889b2c05de714c2b3a35a1364c86a1 (patch)
treef707cdb57fce4a1d938e2a9d54b0cdfa0fc919ff
parenta28e0c26e1e1995e0a05607715696bf4e13c813d (diff)
downloadweston-84eb3158b4889b2c05de714c2b3a35a1364c86a1.tar.gz
color-lcms: add debug scope for pipeline optimizer
Whenever a color transformation is being created, this debug scope prints its pipeline before and after being optimized. It should be used with the color-lcms-transformations scope. Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
-rw-r--r--libweston/color-lcms/color-lcms.c9
-rw-r--r--libweston/color-lcms/color-lcms.h1
-rw-r--r--libweston/color-lcms/color-transform.c131
3 files changed, 139 insertions, 2 deletions
diff --git a/libweston/color-lcms/color-lcms.c b/libweston/color-lcms/color-lcms.c
index aa97f7f7..656acd4a 100644
--- a/libweston/color-lcms/color-lcms.c
+++ b/libweston/color-lcms/color-lcms.c
@@ -389,6 +389,7 @@ cmlcms_destroy(struct weston_color_manager *cm_base)
cmsDeleteContext(cm->lcms_ctx);
weston_log_scope_destroy(cm->transforms_scope);
+ weston_log_scope_destroy(cm->optimizer_scope);
weston_log_scope_destroy(cm->profiles_scope);
free(cm);
@@ -465,18 +466,24 @@ weston_color_manager_create(struct weston_compositor *compositor)
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)
+ 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;
diff --git a/libweston/color-lcms/color-lcms.h b/libweston/color-lcms/color-lcms.h
index bcaa6d26..1f0e90e3 100644
--- a/libweston/color-lcms/color-lcms.h
+++ b/libweston/color-lcms/color-lcms.h
@@ -38,6 +38,7 @@ struct weston_color_manager_lcms {
struct weston_color_manager base;
struct weston_log_scope *profiles_scope;
struct weston_log_scope *transforms_scope;
+ struct weston_log_scope *optimizer_scope;
cmsContext lcms_ctx;
struct wl_list color_transform_list; /* cmlcms_color_transform::link */
diff --git a/libweston/color-lcms/color-transform.c b/libweston/color-lcms/color-transform.c
index 0ccf34f7..4d6ab787 100644
--- a/libweston/color-lcms/color-transform.c
+++ b/libweston/color-lcms/color-transform.c
@@ -598,6 +598,118 @@ optimize_float_pipeline(cmsPipeline **lut, cmsContext context_id,
return FALSE;
}
+static const char *
+cmlcms_stage_type_to_str(cmsStage *stage)
+{
+ /* This table is based on cmsStageSignature enum type from the
+ * LittleCMS API. */
+ switch (cmsStageType(stage))
+ {
+ case cmsSigCurveSetElemType:
+ return "CurveSet";
+ case cmsSigMatrixElemType:
+ return "Matrix";
+ case cmsSigCLutElemType:
+ return "CLut";
+ case cmsSigBAcsElemType:
+ return "BAcs";
+ case cmsSigEAcsElemType:
+ return "EAcs";
+ case cmsSigXYZ2LabElemType:
+ return "XYZ2Lab";
+ case cmsSigLab2XYZElemType:
+ return "Lab2XYz";
+ case cmsSigNamedColorElemType:
+ return "NamedColor";
+ case cmsSigLabV2toV4:
+ return "LabV2toV4";
+ case cmsSigLabV4toV2:
+ return "LabV4toV2";
+ case cmsSigIdentityElemType:
+ return "Identity";
+ case cmsSigLab2FloatPCS:
+ return "Lab2FloatPCS";
+ case cmsSigFloatPCS2Lab:
+ return "FloatPCS2Lab";
+ case cmsSigXYZ2FloatPCS:
+ return "XYZ2FloatPCS";
+ case cmsSigFloatPCS2XYZ:
+ return "FloatPCS2XYZ";
+ case cmsSigClipNegativesElemType:
+ return "ClipNegatives";
+ }
+
+ return NULL;
+}
+
+static void
+matrix_print(cmsStage *stage, struct weston_log_scope *scope)
+{
+ const _cmsStageMatrixData *data;
+ const unsigned int SIZE = 3;
+ unsigned int row, col;
+ double elem;
+ const char *sep;
+
+ if (!weston_log_scope_is_enabled(scope))
+ return;
+
+ assert(cmsStageType(stage) == cmsSigMatrixElemType);
+ data = cmsStageData(stage);
+
+ for (row = 0; row < SIZE; row++) {
+ weston_log_scope_printf(scope, " ");
+
+ for (col = 0, sep = ""; col < SIZE; col++) {
+ elem = data->Double[row * SIZE + col];
+ weston_log_scope_printf(scope, "%s% .4f", sep, elem);
+ sep = " ";
+ }
+
+ /* We print offset after the last column of the matrix. */
+ if (data->Offset)
+ weston_log_scope_printf(scope, "% .4f", data->Offset[row]);
+
+ weston_log_scope_printf(scope, "\n");
+ }
+}
+
+static void
+pipeline_print(cmsPipeline **lut, cmsContext context_id,
+ struct weston_log_scope *scope)
+{
+ cmsStage *stage = cmsPipelineGetPtrToFirstStage(*lut);
+ const char *type_str;
+
+ if (!weston_log_scope_is_enabled(scope))
+ return;
+
+ if (!stage) {
+ weston_log_scope_printf(scope, "no elements\n");
+ return;
+ }
+
+ while (stage != NULL) {
+ type_str = cmlcms_stage_type_to_str(stage);
+ /* Unknown type, just print the hex */
+ if (!type_str)
+ weston_log_scope_printf(scope, " unknown type 0x%x\n",
+ cmsStageType(stage));
+ else
+ weston_log_scope_printf(scope, " %s\n", type_str);
+
+ switch(cmsStageType(stage)) {
+ case cmsSigMatrixElemType:
+ matrix_print(stage, scope);
+ break;
+ default:
+ break;
+ }
+
+ stage = cmsStageNext(stage);
+ }
+}
+
/** LittleCMS transform plugin entry point
*
* This function is called by LittleCMS when it is creating a new
@@ -647,8 +759,10 @@ transform_factory(_cmsTransform2Fn *xform_fn,
cmsUInt32Number *output_format,
cmsUInt32Number *flags)
{
+ struct weston_color_manager_lcms *cm;
struct cmlcms_color_transform *xform;
cmsContext context_id;
+ bool ret;
if (T_CHANNELS(*input_format) != 3) {
weston_log("color-lcms debug: input format is not 3-channel.");
@@ -671,7 +785,22 @@ transform_factory(_cmsTransform2Fn *xform_fn,
xform = cmsGetContextUserData(context_id);
assert(xform);
- return optimize_float_pipeline(lut, context_id, xform);
+ cm = get_cmlcms(xform->base.cm);
+
+ /* Print pipeline before optimization */
+ weston_log_scope_printf(cm->optimizer_scope,
+ " transform pipeline before optimization:\n");
+ pipeline_print(lut, context_id, cm->optimizer_scope);
+
+ /* Optimize pipeline */
+ ret = optimize_float_pipeline(lut, context_id, xform);
+
+ /* Print pipeline after optimization */
+ weston_log_scope_printf(cm->optimizer_scope,
+ " transform pipeline after optimization:\n");
+ pipeline_print(lut, context_id, cm->optimizer_scope);
+
+ return ret;
}
static cmsPluginTransform transform_plugin = {