[PATCH 1/1] [RFC] drm: Add per-plane color management
Alexandru Gheorghe
alexandru-cosmin.gheorghe at arm.com
Mon Feb 26 15:59:22 UTC 2018
From: Mihail Atanassov <mihail.atanassov at 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 at arm.com>
Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe at 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 --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;
};
--
2.7.4
More information about the dri-devel
mailing list