drm: introduce pipe color correction properties
Patch based on a previous series by Shashank Sharma.
This introduces optional properties to enable color correction at the
pipe level. It relies on 3 transformations applied to every pixels
displayed. First a lookup into a degamma table, then a multiplication
of the rgb components by a 3x3 matrix and finally another lookup into
a gamma table.
The following properties can be added to a pipe :
- DEGAMMA_LUT : blob containing degamma LUT
- DEGAMMA_LUT_SIZE : number of elements in DEGAMMA_LUT
- CTM : transformation matrix applied after the degamma LUT
- GAMMA_LUT : blob containing gamma LUT
- GAMMA_LUT_SIZE : number of elements in GAMMA_LUT
DEGAMMA_LUT_SIZE and GAMMA_LUT_SIZE are read only properties, set by
the driver to tell userspace applications what sizes should be the
lookup tables in DEGAMMA_LUT and GAMMA_LUT.
A helper is also provided so legacy gamma correction is redirected
through these new properties.
v2: Register LUT size properties as range
v3: Fix round in drm_color_lut_get_value() helper
More docs on how degamma/gamma properties are used
v4: Update contributors
v5: Rename CTM_MATRIX property to CTM (Doh!)
Add legacy gamma_set atomic helper
Describe CTM/LUT acronyms in the kernel doc
v6: Fix missing blob unref in drm_atomic_helper_crtc_reset
Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
Signed-off-by: Kumar, Kiran S <kiran.s.kumar@intel.com>
Signed-off-by: Kausal Malladi <kausalmalladi@gmail.com>
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Acked-by: Rob Bradford <robert.bradford@intel.com>
[danvet: CrOS maintainers are also happy with the userspacde side:
https://codereview.chromium.org/1182063002/ ]
Reviewed-by: Daniel Stone <daniels@collabora.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/1456506302-640-4-git-send-email-lionel.g.landwerlin@intel.com
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 75b28de..b10eba23a 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -305,6 +305,8 @@
* @mode_changed: crtc_state->mode or crtc_state->enable has been changed
* @active_changed: crtc_state->active has been toggled.
* @connectors_changed: connectors to this crtc have been updated
+ * @color_mgmt_changed: color management properties have changed (degamma or
+ * gamma LUT or CSC matrix)
* @plane_mask: bitmask of (1 << drm_plane_index(plane)) of attached planes
* @connector_mask: bitmask of (1 << drm_connector_index(connector)) of attached connectors
* @encoder_mask: bitmask of (1 << drm_encoder_index(encoder)) of attached encoders
@@ -312,6 +314,11 @@
* update to ensure framebuffer cleanup isn't done too early
* @adjusted_mode: for use by helpers and drivers to compute adjusted mode timings
* @mode: current mode timings
+ * @degamma_lut: Lookup table for converting framebuffer pixel data
+ * before apply the conversion matrix
+ * @ctm: Transformation matrix
+ * @gamma_lut: Lookup table for converting pixel data after the
+ * conversion matrix
* @event: optional pointer to a DRM event to signal upon completion of the
* state update
* @state: backpointer to global drm_atomic_state
@@ -333,6 +340,7 @@
bool mode_changed : 1;
bool active_changed : 1;
bool connectors_changed : 1;
+ bool color_mgmt_changed : 1;
/* attached planes bitmask:
* WARNING: transitional helpers do not maintain plane_mask so
@@ -355,6 +363,11 @@
/* blob property to expose current mode to atomic userspace */
struct drm_property_blob *mode_blob;
+ /* blob property to expose color management to userspace */
+ struct drm_property_blob *degamma_lut;
+ struct drm_property_blob *ctm;
+ struct drm_property_blob *gamma_lut;
+
struct drm_pending_vblank_event *event;
struct drm_atomic_state *state;
@@ -757,7 +770,7 @@
int x, y;
const struct drm_crtc_funcs *funcs;
- /* CRTC gamma size for reporting to userspace */
+ /* Legacy FB CRTC gamma size for reporting to userspace */
uint32_t gamma_size;
uint16_t *gamma_store;
@@ -2027,6 +2040,15 @@
* @property_blob_list: list of all the blob property objects
* @blob_lock: mutex for blob property allocation and management
* @*_property: core property tracking
+ * @degamma_lut_property: LUT used to convert the framebuffer's colors to linear
+ * gamma
+ * @degamma_lut_size_property: size of the degamma LUT as supported by the
+ * driver (read-only)
+ * @ctm_property: Matrix used to convert colors after the lookup in the
+ * degamma LUT
+ * @gamma_lut_property: LUT used to convert the colors, after the CSC matrix, to
+ * the gamma space of the connected screen (read-only)
+ * @gamma_lut_size_property: size of the gamma LUT as supported by the driver
* @preferred_depth: preferred RBG pixel depth, used by fb helpers
* @prefer_shadow: hint to userspace to prefer shadow-fb rendering
* @async_page_flip: does this device support async flips on the primary plane?
@@ -2128,6 +2150,13 @@
struct drm_property *aspect_ratio_property;
struct drm_property *dirty_info_property;
+ /* Optional color correction properties */
+ struct drm_property *degamma_lut_property;
+ struct drm_property *degamma_lut_size_property;
+ struct drm_property *ctm_property;
+ struct drm_property *gamma_lut_property;
+ struct drm_property *gamma_lut_size_property;
+
/* properties for virtual machine layout */
struct drm_property *suggested_x_property;
struct drm_property *suggested_y_property;
@@ -2550,6 +2579,21 @@
return mo ? obj_to_property(mo) : NULL;
}
+/*
+ * Extract a degamma/gamma LUT value provided by user and round it to the
+ * precision supported by the hardware.
+ */
+static inline uint32_t drm_color_lut_extract(uint32_t user_input,
+ uint32_t bit_precision)
+{
+ uint32_t val = user_input + (1 << (16 - bit_precision - 1));
+ uint32_t max = 0xffff >> (16 - bit_precision);
+
+ val >>= 16 - bit_precision;
+
+ return clamp_val(val, 0, max);
+}
+
/* Plane list iterator for legacy (overlay only) planes. */
#define drm_for_each_legacy_plane(plane, dev) \
list_for_each_entry(plane, &(dev)->mode_config.plane_list, head) \