diff mbox

[1/1,RFC] drm: Add per-plane color management

Message ID 1519660762-16981-2-git-send-email-alexandru-cosmin.gheorghe@arm.com (mailing list archive)
State New, archived
Headers show

Commit Message

Alexandru-Cosmin Gheorghe Feb. 26, 2018, 3:59 p.m. UTC
From: Mihail Atanassov <mihail.atanassov@arm.com>

Export drm_plane_enable_color_mgmt, which attaches the existing degamma,
ctm, and gamma properties to a plane. Add a color_mgmt_changed flag to
drm_plane_state, mimicking the drm_crtc_state flag of the same name.

Signed-off-by: Mihail Atanassov <mihail.atanassov@arm.com>
Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>
---
 drivers/gpu/drm/drm_atomic.c        | 33 ++++++++++++++++
 drivers/gpu/drm/drm_atomic_helper.c |  9 +++++
 drivers/gpu/drm/drm_color_mgmt.c    | 76 +++++++++++++++++++++++++++----------
 include/drm/drm_color_mgmt.h        |  5 +++
 include/drm/drm_mode_config.h       | 20 +++++-----
 include/drm/drm_plane.h             |  8 ++++
 6 files changed, 122 insertions(+), 29 deletions(-)
diff mbox

Patch

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 46733d5..39af45f 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -717,6 +717,8 @@  static int drm_atomic_plane_set_property(struct drm_plane *plane,
 {
 	struct drm_device *dev = plane->dev;
 	struct drm_mode_config *config = &dev->mode_config;
+	bool replaced = false;
+	int ret;
 
 	if (property == config->prop_fb_id) {
 		struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, NULL, val);
@@ -762,6 +764,31 @@  static int drm_atomic_plane_set_property(struct drm_plane *plane,
 	} else if (plane->funcs->atomic_set_property) {
 		return plane->funcs->atomic_set_property(plane, state,
 				property, val);
+	}
+	if (property == config->degamma_lut_property) {
+		ret = drm_atomic_replace_property_blob_from_id(dev,
+					&state->degamma_lut,
+					val,
+					-1,
+					&replaced);
+		state->color_mgmt_changed |= replaced;
+		return ret;
+	} else if (property == config->ctm_property) {
+		ret = drm_atomic_replace_property_blob_from_id(dev,
+					&state->ctm,
+					val,
+					sizeof(struct drm_color_ctm),
+					&replaced);
+		state->color_mgmt_changed |= replaced;
+		return ret;
+	} else if (property == config->gamma_lut_property) {
+		ret = drm_atomic_replace_property_blob_from_id(dev,
+					&state->gamma_lut,
+					val,
+					-1,
+					&replaced);
+		state->color_mgmt_changed |= replaced;
+		return ret;
 	} else {
 		return -EINVAL;
 	}
@@ -814,6 +841,12 @@  drm_atomic_plane_get_property(struct drm_plane *plane,
 		*val = state->src_w;
 	} else if (property == config->prop_src_h) {
 		*val = state->src_h;
+	} else if (property == config->degamma_lut_property) {
+		*val = (state->degamma_lut) ? state->degamma_lut->base.id : 0;
+	} else if (property == config->ctm_property) {
+		*val = (state->ctm) ? state->ctm->base.id : 0;
+	} else if (property == config->gamma_lut_property) {
+		*val = (state->gamma_lut) ? state->gamma_lut->base.id : 0;
 	} else if (property == plane->rotation_property) {
 		*val = state->rotation;
 	} else if (property == plane->zpos_property) {
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index ae3cbfe..1995b49 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3501,6 +3501,12 @@  void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
 
 	if (state->fb)
 		drm_framebuffer_get(state->fb);
+	if (state->degamma_lut)
+		drm_property_reference_blob(state->degamma_lut);
+	if (state->ctm)
+		drm_property_reference_blob(state->ctm);
+	if (state->gamma_lut)
+		drm_property_reference_blob(state->gamma_lut);
 
 	state->fence = NULL;
 	state->commit = NULL;
@@ -3548,6 +3554,9 @@  void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state)
 
 	if (state->commit)
 		drm_crtc_commit_put(state->commit);
+	drm_property_unreference_blob(state->degamma_lut);
+	drm_property_unreference_blob(state->ctm);
+	drm_property_unreference_blob(state->gamma_lut);
 }
 EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
 
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index 0d002b0..e0871ce 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -90,6 +90,61 @@ 
  * "GAMMA_LUT" property above.
  */
 
+static void drm_object_enable_color_mgmt(struct drm_mode_object *drm_object,
+					 struct drm_mode_config *config,
+					 uint degamma_lut_size,
+					 bool has_ctm,
+					 uint gamma_lut_size)
+{
+	if (degamma_lut_size) {
+		drm_object_attach_property(drm_object,
+					   config->degamma_lut_property, 0);
+		drm_object_attach_property(drm_object,
+					   config->degamma_lut_size_property,
+					   degamma_lut_size);
+	}
+
+	if (has_ctm)
+		drm_object_attach_property(drm_object,
+					   config->ctm_property, 0);
+
+	if (gamma_lut_size) {
+		drm_object_attach_property(drm_object,
+					   config->gamma_lut_property, 0);
+		drm_object_attach_property(drm_object,
+					   config->gamma_lut_size_property,
+					   gamma_lut_size);
+	}
+}
+
+/**
+ * drm_plane_enable_color_mgmt - enable color management properties for a plane
+ * @plane: DRM plane
+ * @degamma_lut_size: the size of the degamma lut (before CSC)
+ * @has_ctm: whether to attach ctm_property for CSC matrix
+ * @gamma_lut_size: the size of the gamma lut (after CSC)
+ *
+ * This function lets the driver enable the color correction
+ * properties on a plane. This includes 3 degamma, csc and gamma
+ * properties that userspace can set and 2 size properties to inform
+ * the userspace of the lut sizes. Each of the properties is
+ * optional. The gamma and degamma properties are only attached if
+ * their size is not 0 and ctm_property is only attached if has_ctm is
+ * true.
+ */
+void drm_plane_enable_color_mgmt(struct drm_plane *plane,
+				 uint degamma_lut_size,
+				 bool has_ctm,
+				 uint gamma_lut_size)
+{
+	struct drm_device *dev = plane->dev;
+	struct drm_mode_config *config = &dev->mode_config;
+
+	drm_object_enable_color_mgmt(&plane->base, config,
+				     degamma_lut_size, has_ctm, gamma_lut_size);
+}
+EXPORT_SYMBOL(drm_plane_enable_color_mgmt);
+
 /**
  * drm_color_lut_extract - clamp and round LUT entries
  * @user_input: input value
@@ -140,25 +195,8 @@  void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc,
 	struct drm_device *dev = crtc->dev;
 	struct drm_mode_config *config = &dev->mode_config;
 
-	if (degamma_lut_size) {
-		drm_object_attach_property(&crtc->base,
-					   config->degamma_lut_property, 0);
-		drm_object_attach_property(&crtc->base,
-					   config->degamma_lut_size_property,
-					   degamma_lut_size);
-	}
-
-	if (has_ctm)
-		drm_object_attach_property(&crtc->base,
-					   config->ctm_property, 0);
-
-	if (gamma_lut_size) {
-		drm_object_attach_property(&crtc->base,
-					   config->gamma_lut_property, 0);
-		drm_object_attach_property(&crtc->base,
-					   config->gamma_lut_size_property,
-					   gamma_lut_size);
-	}
+	drm_object_enable_color_mgmt(&crtc->base, config,
+				     degamma_lut_size, has_ctm, gamma_lut_size);
 }
 EXPORT_SYMBOL(drm_crtc_enable_color_mgmt);
 
diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h
index 03a59cb..831b09f 100644
--- a/include/drm/drm_color_mgmt.h
+++ b/include/drm/drm_color_mgmt.h
@@ -29,6 +29,11 @@  struct drm_crtc;
 
 uint32_t drm_color_lut_extract(uint32_t user_input, uint32_t bit_precision);
 
+void drm_plane_enable_color_mgmt(struct drm_plane *plane,
+				 uint degamma_lut_size,
+				 bool has_ctm,
+				 uint gamma_lut_size);
+
 void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc,
 				uint degamma_lut_size,
 				bool has_ctm,
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 7569f22..a19e59e 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -727,30 +727,30 @@  struct drm_mode_config {
 	 */
 	struct drm_property *aspect_ratio_property;
 	/**
-	 * @degamma_lut_property: Optional CRTC property to set the LUT used to
-	 * convert the framebuffer's colors to linear gamma.
+	 * @degamma_lut_property: Optional CRTC or plane property to set the
+	 * LUT used to convert the framebuffer's colors to linear gamma.
 	 */
 	struct drm_property *degamma_lut_property;
 	/**
-	 * @degamma_lut_size_property: Optional CRTC property for the size of
-	 * the degamma LUT as supported by the driver (read-only).
+	 * @degamma_lut_size_property: Optional CRTC or plane property for the
+	 * size of the degamma LUT as supported by the driver (read-only).
 	 */
 	struct drm_property *degamma_lut_size_property;
 	/**
-	 * @ctm_property: Optional CRTC property to set the
+	 * @ctm_property: Optional CRTC or plane property to set the
 	 * matrix used to convert colors after the lookup in the
 	 * degamma LUT.
 	 */
 	struct drm_property *ctm_property;
 	/**
-	 * @gamma_lut_property: Optional CRTC property to set the LUT used to
-	 * convert the colors, after the CTM matrix, to the gamma space of the
-	 * connected screen.
+	 * @gamma_lut_property: Optional CRTC or plane property to set the LUT
+	 * used to convert the colors, after the CTM matrix, to the gamma space
+	 * of the connected screen.
 	 */
 	struct drm_property *gamma_lut_property;
 	/**
-	 * @gamma_lut_size_property: Optional CRTC property for the size of the
-	 * gamma LUT as supported by the driver (read-only).
+	 * @gamma_lut_size_property: Optional CRTC or plane property for the
+	 * size of the gamma LUT as supported by the driver (read-only).
 	 */
 	struct drm_property *gamma_lut_size_property;
 
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 8185e34..dd52fab 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -105,6 +105,11 @@  struct drm_plane_state {
 	uint32_t src_x, src_y;
 	uint32_t src_h, src_w;
 
+	/* Color transform blob properties exposed to userspace */
+	struct drm_property_blob *degamma_lut;
+	struct drm_property_blob *ctm;
+	struct drm_property_blob *gamma_lut;
+
 	/* Plane rotation */
 	unsigned int rotation;
 
@@ -131,6 +136,9 @@  struct drm_plane_state {
 	 */
 	struct drm_crtc_commit *commit;
 
+	/* computed state bits used by drivers */
+	bool color_mgmt_changed : 1;
+
 	struct drm_atomic_state *state;
 };