summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Li (Sunpeng) <sunpeng.li@amd.com>2018-06-15 17:04:58 -0400
committerMichel Dänzer <michel@daenzer.net>2018-06-26 17:27:09 +0200
commit639acf54b4de6f62000d12cc6dbf4f5e49cae888 (patch)
tree32faea9361a038bdbd1acd6872b685fb945dc05f
parent3cf5a281d8481c997029dae164d6fdeca66b9447 (diff)
Configure color properties when creating output resources
List color management properties on outputs if there is kernel support. Otherwise, don't list them at all. v2: - Use switch statement in configure_and_change - Also configure LUT sizes for outputs that don't have an attached CRTC. We can do this since LUT sizes are now cached on the drmmode object. Signed-off-by: Leo (Sunpeng) Li <sunpeng.li@amd.com> [ Michel Dänzer: Drop const from data pointer declaration in rr_configure_and_change_cm_property, to avoid warning when building against xserver 1.13 ] Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
-rw-r--r--src/drmmode_display.c131
1 files changed, 131 insertions, 0 deletions
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index e0ddc10..b30bf76 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -777,6 +777,127 @@ static Bool drmmode_cm_enabled(drmmode_ptr drmmode)
}
/**
+ * Configure and change a color property on a CRTC, through RandR. Only the
+ * specified output will be affected, even if the CRTC is attached to multiple
+ * outputs. Note that changes will be non-pending: the changes won't be pushed
+ * to kernel driver.
+ *
+ * @output: RandR output to set the property on.
+ * @crtc: The driver-private CRTC object containing the color properties.
+ * If this is NULL, "disabled" values of 0 will be used.
+ * @cm_prop_index: Color management property to configure and change.
+ *
+ * Return 0 on success, X-defined error code otherwise.
+ */
+static int rr_configure_and_change_cm_property(xf86OutputPtr output,
+ drmmode_crtc_private_ptr crtc,
+ enum drmmode_cm_prop cm_prop_index)
+{
+ drmmode_output_private_ptr drmmode_output = output->driver_private;
+ drmmode_ptr drmmode = drmmode_output->drmmode;
+ Bool need_configure = TRUE;
+ unsigned long length = 0;
+ void *data = NULL;
+ int format = 0;
+ uint32_t zero = 0;
+ INT32 range[2];
+ Atom atom;
+ int err;
+
+ if (cm_prop_index == CM_INVALID_PROP)
+ return BadName;
+
+ switch(cm_prop_index) {
+ case CM_GAMMA_LUT_SIZE:
+ format = 32;
+ length = 1;
+ data = &drmmode->gamma_lut_size;
+ range[0] = 0;
+ range[1] = -1;
+ break;
+ case CM_DEGAMMA_LUT_SIZE:
+ format = 32;
+ length = 1;
+ data = &drmmode->degamma_lut_size;
+ range[0] = 0;
+ range[1] = -1;
+ break;
+ case CM_GAMMA_LUT:
+ format = 16;
+ range[0] = 0;
+ range[1] = (1 << 16) - 1; // Max 16 bit unsigned int.
+ if (crtc && crtc->gamma_lut) {
+ /* Convert from 8bit size to 16bit size */
+ length = sizeof(*crtc->gamma_lut) >> 1;
+ length *= drmmode->gamma_lut_size;
+ data = crtc->gamma_lut;
+ } else {
+ length = 1;
+ data = &zero;
+ }
+ break;
+ case CM_DEGAMMA_LUT:
+ format = 16;
+ range[0] = 0;
+ range[1] = (1 << 16) - 1;
+ if (crtc && crtc->degamma_lut) {
+ length = sizeof(*crtc->degamma_lut) >> 1;
+ length *= drmmode->degamma_lut_size;
+ data = crtc->degamma_lut;
+ } else {
+ length = 1;
+ data = &zero;
+ }
+ break;
+ case CM_CTM:
+ /* CTM is fixed-point S31.32 format. */
+ format = 32;
+ need_configure = FALSE;
+ if (crtc && crtc->ctm) {
+ /* Convert from 8bit size to 32bit size */
+ length = sizeof(*crtc->ctm) >> 2;
+ data = crtc->ctm;
+ } else {
+ length = 1;
+ data = &zero;
+ }
+ break;
+ default:
+ return BadName;
+ }
+
+ atom = MakeAtom(cm_prop_names[cm_prop_index],
+ strlen(cm_prop_names[cm_prop_index]),
+ TRUE);
+ if (!atom)
+ return BadAlloc;
+
+ if (need_configure) {
+ err = RRConfigureOutputProperty(output->randr_output, atom,
+ FALSE, TRUE, FALSE, 2, range);
+ if (err) {
+ xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
+ "Configuring color management property %s failed with %d\n",
+ cm_prop_names[cm_prop_index], err);
+ return err;
+ }
+ }
+
+ /* Always issue a non-pending change. We'll push cm properties
+ * ourselves.
+ */
+ err = RRChangeOutputProperty(output->randr_output, atom,
+ XA_INTEGER, format,
+ PropModeReplace,
+ length, data, FALSE, FALSE);
+ if (err)
+ xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
+ "Changing color management property %s failed with %d\n",
+ cm_prop_names[cm_prop_index], err);
+ return err;
+}
+
+/**
* Push staged color management properties on the CRTC to DRM.
*
* @crtc: The CRTC containing staged properties
@@ -1780,6 +1901,7 @@ static void drmmode_output_create_resources(xf86OutputPtr output)
{
AMDGPUInfoPtr info = AMDGPUPTR(output->scrn);
drmmode_output_private_ptr drmmode_output = output->driver_private;
+ drmmode_crtc_private_ptr drmmode_crtc;
drmModeConnectorPtr mode_output = drmmode_output->mode_output;
AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(output->scrn);
drmModePropertyPtr drmmode_prop, tearfree_prop;
@@ -1903,6 +2025,15 @@ static void drmmode_output_create_resources(xf86OutputPtr output)
}
}
}
+
+ /* Do not configure cm properties on output if there's no support. */
+ if (!drmmode_cm_enabled(drmmode_output->drmmode))
+ return;
+
+ drmmode_crtc = output->crtc ? output->crtc->driver_private : NULL;
+
+ for (i = 0; i < CM_NUM_PROPS; i++)
+ rr_configure_and_change_cm_property(output, drmmode_crtc, i);
}
static void