[PATCH 07/22] drm/amd/display: Refactor to move gamma correction to module

Harry Wentland harry.wentland at amd.com
Wed Dec 21 16:30:01 UTC 2016


From: Anthony Koo <Anthony.Koo at amd.com>

Refactor part 4 - Moving input gamma correction programming into color module

DM will translate to dc_gamma structure, but programming will be moved into
the color module. Later, this will allow gamma correction to be added on top of
in/out transfer function curves.

Change-Id: I857b24f8284948a62d3a1476dd18691185ffbfd2
Signed-off-by: Anthony Koo <anthony.koo at amd.com>
Reviewed-by: Anthony Koo <Anthony.Koo at amd.com>
Acked-by: Harry Wentland <Harry.Wentland at amd.com>
---
 drivers/gpu/drm/amd/display/modules/color/color.c  | 77 ++++++++++++++++++++++
 .../gpu/drm/amd/display/modules/inc/mod_color.h    |  4 ++
 2 files changed, 81 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/modules/color/color.c b/drivers/gpu/drm/amd/display/modules/color/color.c
index 0610b82b6d84..6613ff9f4d28 100644
--- a/drivers/gpu/drm/amd/display/modules/color/color.c
+++ b/drivers/gpu/drm/amd/display/modules/color/color.c
@@ -69,6 +69,7 @@ struct color_state {
 	struct color_range saturation;
 	struct color_range brightness;
 	struct color_range hue;
+	struct dc_gamma *gamma;
 	enum dc_quantization_range preferred_quantization_range;
 };
 
@@ -1265,6 +1266,26 @@ static void calculate_csc_matrix(struct core_color *core_color,
 	}
 }
 
+static struct dc_surface *dc_stream_to_surface_from_pipe_ctx(
+		struct core_color *core_color,
+		const struct dc_stream *stream)
+{
+	int i;
+	struct core_dc *core_dc = DC_TO_CORE(core_color->dc);
+	struct core_stream *core_stream = DC_STREAM_TO_CORE(stream);
+	struct dc_surface *out_surface = NULL;
+
+	for (i = 0; i < MAX_PIPES; i++) {
+		if (core_dc->current_context->res_ctx.pipe_ctx[i].stream
+						== core_stream) {
+			out_surface = &core_dc->current_context->res_ctx.
+					pipe_ctx[i].surface->public;
+			break;
+		}
+	}
+	return out_surface;
+}
+
 struct mod_color *mod_color_create(struct dc *dc)
 {
 	int i = 0;
@@ -1369,6 +1390,10 @@ void mod_color_destroy(struct mod_color *mod_color)
 		struct core_color *core_color =
 				MOD_COLOR_TO_CORE(mod_color);
 
+		for (i = 0; i < core_color->num_sinks; i++)
+			if (core_color->state[i].gamma)
+				dc_gamma_release(core_color->state[i].gamma);
+
 		dm_free(core_color->state);
 
 		for (i = 0; i < core_color->num_sinks; i++)
@@ -1552,6 +1577,9 @@ bool mod_color_remove_sink(struct mod_color *mod_color,
 
 	for (i = 0; i < core_color->num_sinks; i++) {
 		if (core_color->caps[i].sink == sink) {
+			if (core_color->state[i].gamma)
+				dc_gamma_release(core_color->state[i].gamma);
+
 			/* To remove this sink, shift everything after down */
 			for (j = i; j < core_color->num_sinks - 1; j++) {
 				core_color->caps[j].sink =
@@ -2184,6 +2212,55 @@ bool mod_color_set_saturation(struct mod_color *mod_color,
 	return true;
 }
 
+bool mod_color_set_input_gamma_correction(struct mod_color *mod_color,
+		const struct dc_stream **streams, int num_streams,
+		struct dc_gamma *gamma)
+{
+	struct core_color *core_color = MOD_COLOR_TO_CORE(mod_color);
+	unsigned int stream_index, sink_index;
+
+	for (stream_index = 0; stream_index < num_streams; stream_index++) {
+		sink_index = sink_index_from_sink(core_color,
+				streams[stream_index]->sink);
+
+		struct dc_surface *surface =
+				dc_stream_to_surface_from_pipe_ctx(core_color,
+						streams[stream_index]);
+
+		if (surface != NULL) {
+			struct dc_transfer_func *input_tf =
+					dc_create_transfer_func(core_color->dc);
+			struct dc_surface_update updates = {0};
+
+			if (input_tf != NULL) {
+				input_tf->type = TF_TYPE_PREDEFINED;
+				input_tf->tf = TRANSFER_FUNCTION_SRGB;
+			}
+
+			if (core_color->state[sink_index].gamma != gamma) {
+				if (core_color->state[sink_index].gamma)
+					dc_gamma_release(
+						core_color->state[sink_index].
+						gamma);
+
+				dc_gamma_retain(gamma);
+				core_color->state[sink_index].gamma = gamma;
+			}
+
+			updates.surface = surface;
+			updates.gamma = gamma;
+			updates.in_transfer_func = input_tf;
+			dc_update_surfaces_for_target(core_color->dc, &updates,
+					1, NULL);
+
+			if (input_tf != NULL)
+				dc_transfer_func_release(input_tf);
+		}
+	}
+
+	return true;
+}
+
 bool mod_color_persist_user_preferred_quantization_range(
 		struct mod_color *mod_color,
 		const struct dc_sink *sink,
diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_color.h b/drivers/gpu/drm/amd/display/modules/inc/mod_color.h
index 787c2c0a0e14..fbf908141ba7 100644
--- a/drivers/gpu/drm/amd/display/modules/inc/mod_color.h
+++ b/drivers/gpu/drm/amd/display/modules/inc/mod_color.h
@@ -168,6 +168,10 @@ bool mod_color_set_saturation(struct mod_color *mod_color,
 		const struct dc_stream **streams, int num_streams,
 		int saturation_value);
 
+bool mod_color_set_input_gamma_correction(struct mod_color *mod_color,
+		const struct dc_stream **streams, int num_streams,
+		struct dc_gamma *gamma);
+
 bool mod_color_persist_user_preferred_quantization_range(
 		struct mod_color *mod_color,
 		const struct dc_sink *sink,
-- 
2.9.3



More information about the amd-gfx mailing list