[RFC PATCH 3/6] Attach output profiles and build corresponding LUTs

Niels Ole Salscheider niels_ole at salscheider-online.de
Sun Mar 30 04:36:34 PDT 2014


This patch allows to attach an ICC profile to each output. It then
builds an LUT that can be used to translate colors from the
blending space to the output space.

Signed-off-by: Niels Ole Salscheider <niels_ole at salscheider-online.de>
---
 src/cms-colord.c |  4 +++-
 src/cms-helper.c |  7 ++++++-
 src/cms-helper.h |  3 ++-
 src/cms-static.c |  1 +
 src/compositor.c | 38 ++++++++++++++++++++++++++++++++++++++
 src/compositor.h |  7 +++++++
 6 files changed, 57 insertions(+), 3 deletions(-)

diff --git a/src/cms-colord.c b/src/cms-colord.c
index 4ff3aac..5696ea3 100644
--- a/src/cms-colord.c
+++ b/src/cms-colord.c
@@ -155,8 +155,9 @@ colord_update_output_from_device (struct cms_output *ocms)
 	gint percentage;
 
 	/* old profile is no longer valid */
-	weston_cms_destroy_profile(ocms->p);
+	weston_cms_destroy_profile(ocms->o, ocms->p);
 	ocms->p = NULL;
+	wl_signal_emit(&ocms->o->profile_signal, ocms->o);
 
 	ret = cd_device_connect_sync(ocms->device, NULL, &error);
 	if (!ret) {
@@ -384,6 +385,7 @@ colord_dispatch_all_pending(int fd, uint32_t mask, void *data)
 		}
 
 		weston_cms_set_color_profile(ocms->o, ocms->p);
+		wl_signal_emit(&ocms->o->profile_signal, ocms->o);
 	}
 	g_list_free (cms->pending);
 	cms->pending = NULL;
diff --git a/src/cms-helper.c b/src/cms-helper.c
index c063c77..7437b68 100644
--- a/src/cms-helper.c
+++ b/src/cms-helper.c
@@ -64,6 +64,9 @@ weston_cms_set_color_profile(struct weston_output *o,
 	uint16_t *green = NULL;
 	uint16_t *blue = NULL;
 
+	if (p)
+		o->color_profile = p->lcms_handle;
+
 	if (!o->set_gamma)
 		return;
 	if (!p) {
@@ -96,11 +99,13 @@ weston_cms_set_color_profile(struct weston_output *o,
 }
 
 void
-weston_cms_destroy_profile(struct weston_color_profile *p)
+weston_cms_destroy_profile(struct weston_output *o,
+			   struct weston_color_profile *p)
 {
 	if (!p)
 		return;
 #ifdef HAVE_LCMS
+	o->color_profile = NULL;
 	cmsCloseProfile(p->lcms_handle);
 #endif
 	free(p->filename);
diff --git a/src/cms-helper.h b/src/cms-helper.h
index 6e5594d..3fd17b3 100644
--- a/src/cms-helper.h
+++ b/src/cms-helper.h
@@ -67,6 +67,7 @@ weston_cms_create_profile(const char *filename,
 struct weston_color_profile *
 weston_cms_load_profile(const char *filename);
 void
-weston_cms_destroy_profile(struct weston_color_profile *p);
+weston_cms_destroy_profile(struct weston_output *o,
+			   struct weston_color_profile *p);
 
 #endif
diff --git a/src/cms-static.c b/src/cms-static.c
index ad54fd1..c7dce58 100644
--- a/src/cms-static.c
+++ b/src/cms-static.c
@@ -58,6 +58,7 @@ cms_output_created(struct cms_static *cms, struct weston_output *o)
 		weston_log("cms-static: loading %s for %s\n",
 			   profile, o->name);
 		weston_cms_set_color_profile(o, p);
+		wl_signal_emit(&o->profile_signal, o);
 	}
 }
 
diff --git a/src/compositor.c b/src/compositor.c
index 6adc2a0..e92a699 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -3140,6 +3140,37 @@ weston_compositor_remove_output(struct weston_compositor *compositor,
 	}
 }
 
+static void
+weston_output_notifier_profile(struct wl_listener *listener, void *data)
+{
+#ifdef HAVE_LCMS
+	struct weston_output *output = (struct weston_output *) data;
+	struct weston_compositor *ec = output->compositor;
+	struct weston_view *view;
+	struct wl_array profile_data;
+	char *ptr;
+	uint32_t size;
+
+	weston_build_clut(&output->clut, ec->blending_profile,
+			  output->color_profile);
+
+	cmsSaveProfileToMem(output->color_profile, NULL, &size);
+	if (size) {
+		wl_array_init(&profile_data);
+		ptr = wl_array_add(&profile_data, size);
+		cmsSaveProfileToMem(output->color_profile, ptr, &size);
+
+		wl_list_for_each(view, &ec->view_list, link) {
+			wl_colorcorrection_send_output_space(
+				view->surface->resource, output->id,
+				&profile_data);
+		}
+
+		wl_array_release(&profile_data);
+	}
+#endif
+}
+
 WL_EXPORT void
 weston_output_destroy(struct weston_output *output)
 {
@@ -3151,6 +3182,10 @@ weston_output_destroy(struct weston_output *output)
 	wl_signal_emit(&output->compositor->output_destroyed_signal, output);
 	wl_signal_emit(&output->destroy_signal, output);
 
+#ifdef HAVE_LCMS
+	weston_free_clut(&output->clut);
+#endif
+
 	free(output->name);
 	pixman_region32_fini(&output->region);
 	pixman_region32_fini(&output->previous_damage);
@@ -3348,8 +3383,11 @@ weston_output_init(struct weston_output *output, struct weston_compositor *c,
 
 	wl_signal_init(&output->frame_signal);
 	wl_signal_init(&output->destroy_signal);
+	wl_signal_init(&output->profile_signal);
 	wl_list_init(&output->animation_list);
 	wl_list_init(&output->resource_list);
+	output->profile_listener.notify = weston_output_notifier_profile;
+	wl_signal_add(&output->profile_signal, &output->profile_listener);
 
 	output->id = ffs(~output->compositor->output_id_pool) - 1;
 	output->compositor->output_id_pool |= 1 << output->id;
diff --git a/src/compositor.h b/src/compositor.h
index 10d461f..0ecae8c 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -204,6 +204,8 @@ struct weston_output {
 	struct wl_signal frame_signal;
 	struct wl_signal destroy_signal;
 	struct wl_signal move_signal;
+	struct wl_signal profile_signal;
+	struct wl_listener profile_listener;
 	int move_x, move_y;
 	uint32_t frame_time;
 	int disable_planes;
@@ -221,6 +223,11 @@ struct weston_output {
 	struct weston_mode *original_mode;
 	struct wl_list mode_list;
 
+	struct weston_clut clut;
+#ifdef HAVE_LCMS
+	cmsHPROFILE color_profile;
+#endif
+
 	void (*start_repaint_loop)(struct weston_output *output);
 	int (*repaint)(struct weston_output *output,
 			pixman_region32_t *damage);
-- 
1.9.1



More information about the wayland-devel mailing list