summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichel Dänzer <michel.daenzer@amd.com>2016-02-27 18:20:38 +0900
committerMichel Dänzer <michel@daenzer.net>2016-03-01 12:48:34 +0900
commit9869ed6aad3ee6d4e5d70cd9e8631840709693cb (patch)
tree82f371e6299795cf647b7cd0e36c83a08f965502
parentaecc6ffd03d9a949e42790cf574003fdd44a8d3b (diff)
WIP: xfree86/modes: Decouple RandR core and driver gamma ramp sizesrandr12-colormaps
-rw-r--r--hw/xfree86/common/xf86cmap.c5
-rw-r--r--hw/xfree86/modes/xf86Crtc.c109
-rw-r--r--hw/xfree86/modes/xf86RandR12.c148
-rw-r--r--hw/xfree86/modes/xf86RandR12.h2
4 files changed, 106 insertions, 158 deletions
diff --git a/hw/xfree86/common/xf86cmap.c b/hw/xfree86/common/xf86cmap.c
index 4b38c994e..b491d1868 100644
--- a/hw/xfree86/common/xf86cmap.c
+++ b/hw/xfree86/common/xf86cmap.c
@@ -187,9 +187,10 @@ xf86HandleColormaps(ScreenPtr pScreen,
pScreen->InstallColormap = CMapInstallColormap;
pScreen->StoreColors = CMapStoreColors;
- if (xf86_crtc_supports_gamma(pScrn))
+ if (xf86_crtc_supports_gamma(pScrn)) {
pScrn->LoadPalette = xf86RandR12LoadPalette;
- else
+ xf86RandR12InitGamma(pScrn, elements);
+ } else
pScrn->LoadPalette = loadPalette;
pScrn->SetOverscan = setOverscan;
pScreenPriv->maxColors = maxColors;
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index c2f58ff0c..05dce52ac 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -2445,108 +2445,6 @@ xf86TargetUserpref(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
return FALSE;
}
-static Bool
-xf86CrtcSetInitialGamma(xf86CrtcPtr crtc, float gamma_red, float gamma_green,
- float gamma_blue)
-{
- int i, size = 256;
- CARD16 *red, *green, *blue;
-
- red = xallocarray(size, 3 * sizeof(CARD16));
- green = red + size;
- blue = green + size;
-
- /* Only cause warning if user wanted gamma to be set. */
- if (!crtc->funcs->gamma_set &&
- (gamma_red != 1.0 || gamma_green != 1.0 || gamma_blue != 1.0)) {
- free(red);
- return FALSE;
- }
- else if (!crtc->funcs->gamma_set) {
- free(red);
- return TRUE;
- }
-
- /* At this early stage none of the randr-interface stuff is up.
- * So take the default gamma size for lack of something better.
- */
- for (i = 0; i < size; i++) {
- if (gamma_red == 1.0)
- red[i] = i << 8;
- else
- red[i] = (CARD16) (pow((double) i / (double) (size - 1),
- 1. / (double) gamma_red) * (double) (size -
- 1) *
- 256);
-
- if (gamma_green == 1.0)
- green[i] = i << 8;
- else
- green[i] = (CARD16) (pow((double) i / (double) (size - 1),
- 1. / (double) gamma_green) *
- (double) (size - 1) * 256);
-
- if (gamma_blue == 1.0)
- blue[i] = i << 8;
- else
- blue[i] = (CARD16) (pow((double) i / (double) (size - 1),
- 1. / (double) gamma_blue) * (double) (size -
- 1) *
- 256);
- }
-
- /* Default size is 256, so anything else is failure. */
- if (size != crtc->gamma_size) {
- free(red);
- return FALSE;
- }
-
- crtc->gamma_size = size;
- memcpy(crtc->gamma_red, red, crtc->gamma_size * sizeof(CARD16));
- memcpy(crtc->gamma_green, green, crtc->gamma_size * sizeof(CARD16));
- memcpy(crtc->gamma_blue, blue, crtc->gamma_size * sizeof(CARD16));
-
- /* Do not set gamma now, delay until the crtc is activated. */
-
- free(red);
-
- return TRUE;
-}
-
-static Bool
-xf86OutputSetInitialGamma(xf86OutputPtr output)
-{
- XF86ConfMonitorPtr mon = output->conf_monitor;
- float gamma_red = 1.0, gamma_green = 1.0, gamma_blue = 1.0;
-
- if (!mon)
- return TRUE;
-
- if (!output->crtc)
- return FALSE;
-
- /* Get configured values, where they exist. */
- if (mon->mon_gamma_red >= GAMMA_MIN && mon->mon_gamma_red <= GAMMA_MAX)
- gamma_red = mon->mon_gamma_red;
-
- if (mon->mon_gamma_green >= GAMMA_MIN && mon->mon_gamma_green <= GAMMA_MAX)
- gamma_green = mon->mon_gamma_green;
-
- if (mon->mon_gamma_blue >= GAMMA_MIN && mon->mon_gamma_blue <= GAMMA_MAX)
- gamma_blue = mon->mon_gamma_blue;
-
- /* This avoids setting gamma 1.0 in case another cloned output on this crtc has a specific gamma. */
- if (gamma_red != 1.0 || gamma_green != 1.0 || gamma_blue != 1.0) {
- xf86DrvMsg(output->scrn->scrnIndex, X_INFO,
- "Output %s wants gamma correction (%.1f, %.1f, %.1f)\n",
- output->name, gamma_red, gamma_green, gamma_blue);
- return xf86CrtcSetInitialGamma(output->crtc, gamma_red, gamma_green,
- gamma_blue);
- }
- else
- return TRUE;
-}
-
/**
* Construct default screen configuration
*
@@ -2666,9 +2564,6 @@ xf86InitialConfiguration(ScrnInfoPtr scrn, Bool canGrow)
crtc->enabled = FALSE;
memset(&crtc->desiredMode, '\0', sizeof(crtc->desiredMode));
- /* Set default gamma for all crtc's. */
- /* This is done to avoid problems later on with cloned outputs. */
- xf86CrtcSetInitialGamma(crtc, 1.0, 1.0, 1.0);
}
/*
@@ -2693,10 +2588,6 @@ xf86InitialConfiguration(ScrnInfoPtr scrn, Bool canGrow)
memcpy(crtc->panningBorder, output->initialBorder,
4 * sizeof(INT16));
output->crtc = crtc;
- if (!xf86OutputSetInitialGamma(output))
- xf86DrvMsg(scrn->scrnIndex, X_WARNING,
- "Initial gamma correction for output %s: failed.\n",
- output->name);
}
else {
output->crtc = NULL;
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index e26eecd78..1f0088e31 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -1240,15 +1240,13 @@ static void
xf86RandR12CrtcComputeGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc)
{
xf86CrtcPtr crtc = randr_crtc->devPrivate;
- int gamma_slots, gamma_ramp_size = xf86GetGammaRampSize(pScreen);
+ int gamma_slots;
int i, j;
gamma_slots = crtc->gamma_size / randr_crtc->paletteRedSize;
for (i = 0; i < randr_crtc->paletteRedSize; i++) {
j = i * gamma_slots;
- crtc->gamma_red[j] = randr_crtc->gammaRed[randr_crtc->palette[i].red *
- crtc->gamma_size /
- gamma_ramp_size];
+ crtc->gamma_red[j] = randr_crtc->gammaRed[randr_crtc->palette[i].red];
while (++j < (i + 1) * gamma_slots)
crtc->gamma_red[j] = crtc->gamma_red[j - 1];
@@ -1257,9 +1255,7 @@ xf86RandR12CrtcComputeGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc)
gamma_slots = crtc->gamma_size / randr_crtc->paletteGreenSize;
for (i = 0; i < randr_crtc->paletteGreenSize; i++) {
j = i * gamma_slots;
- crtc->gamma_green[j] = randr_crtc->gammaGreen[randr_crtc->palette[i].green *
- crtc->gamma_size /
- gamma_ramp_size];
+ crtc->gamma_green[j] = randr_crtc->gammaGreen[randr_crtc->palette[i].green];
while (++j < (i + 1) * gamma_slots)
crtc->gamma_green[j] = crtc->gamma_green[j - 1];
@@ -1268,9 +1264,7 @@ xf86RandR12CrtcComputeGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc)
gamma_slots = crtc->gamma_size / randr_crtc->paletteBlueSize;
for (i = 0; i < randr_crtc->paletteBlueSize; i++) {
j = i * gamma_slots;
- crtc->gamma_blue[j] = randr_crtc->gammaBlue[randr_crtc->palette[i].blue *
- crtc->gamma_size /
- gamma_ramp_size];
+ crtc->gamma_blue[j] = randr_crtc->gammaBlue[randr_crtc->palette[i].blue];
while (++j < (i + 1) * gamma_slots)
crtc->gamma_blue[j] = crtc->gamma_blue[j - 1];
@@ -1301,60 +1295,121 @@ xf86RandR12CrtcSetGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc)
if (crtc->funcs->gamma_set == NULL)
return FALSE;
- /* Realloc local gamma if needed. */
- if (randr_crtc->gammaSize != crtc->gamma_size) {
- CARD16 *tmp_ptr;
-
- tmp_ptr = reallocarray(crtc->gamma_red,
- randr_crtc->gammaSize, 3 * sizeof(CARD16));
- if (!tmp_ptr)
- return FALSE;
- crtc->gamma_red = tmp_ptr;
- crtc->gamma_green = crtc->gamma_red + randr_crtc->gammaSize;
- crtc->gamma_blue = crtc->gamma_green + randr_crtc->gammaSize;
- crtc->gamma_size = randr_crtc->gammaSize;
+ if (randr_crtc->paletteSize) {
+ xf86RandR12CrtcComputeGamma(pScreen, randr_crtc);
+ xf86RandR12CrtcResetGamma(randr_crtc);
}
- xf86RandR12CrtcComputeGamma(pScreen, randr_crtc);
- xf86RandR12CrtcResetGamma(randr_crtc);
-
return TRUE;
}
static Bool
xf86RandR12CrtcGetGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc)
{
- xf86CrtcPtr crtc = randr_crtc->devPrivate;
+ return TRUE;
+}
- if (!crtc->gamma_size)
- return FALSE;
+static void
+init_one_component(CARD16 *comp, unsigned size, unsigned shift, float gamma)
+{
+ int i;
+
+ if (gamma == 1.0) {
+ for (i = 0; i < size; i++)
+ comp[i] = i << shift;
+ } else {
+ for (i = 0; i < size; i++)
+ comp[i] = (CARD16) (pow((double) i / (double) (size - 1),
+ 1. / (double) gamma) *
+ (double) (size - 1) * (1 << shift));
+ }
+}
- if (!crtc->gamma_red || !crtc->gamma_green || !crtc->gamma_blue)
+static Bool
+xf86RandR12CrtcInitGamma(xf86CrtcPtr crtc, float gamma_red, float gamma_green,
+ float gamma_blue)
+{
+ unsigned size = crtc->randr_crtc->gammaSize, shift;
+ CARD16 *red, *green, *blue;
+
+ red = xallocarray(size, 3 * sizeof(CARD16));
+ if (!red)
return FALSE;
- /* Realloc randr gamma if needed. */
- if (randr_crtc->gammaSize != crtc->gamma_size) {
- CARD16 *tmp_ptr;
+ green = red + size;
+ blue = green + size;
- tmp_ptr = reallocarray(randr_crtc->gammaRed,
- crtc->gamma_size, 3 * sizeof(CARD16));
- if (!tmp_ptr)
- return FALSE;
- randr_crtc->gammaRed = tmp_ptr;
- randr_crtc->gammaGreen = randr_crtc->gammaRed + crtc->gamma_size;
- randr_crtc->gammaBlue = randr_crtc->gammaGreen + crtc->gamma_size;
+ for (shift = 0; (size << shift) < (1 << 16); shift++);
+
+ init_one_component(red, size, shift, gamma_red);
+ init_one_component(green, size, shift, gamma_green);
+ init_one_component(blue, size, shift, gamma_blue);
+
+ RRCrtcGammaSet(crtc->randr_crtc, red, green, blue);
+
+ return TRUE;
+}
+
+static Bool
+xf86RandR12OutputInitGamma(xf86OutputPtr output)
+{
+ XF86ConfMonitorPtr mon = output->conf_monitor;
+ float gamma_red = 1.0, gamma_green = 1.0, gamma_blue = 1.0;
+
+ if (!mon)
+ return TRUE;
+
+ /* Get configured values, where they exist. */
+ if (mon->mon_gamma_red >= GAMMA_MIN && mon->mon_gamma_red <= GAMMA_MAX)
+ gamma_red = mon->mon_gamma_red;
+
+ if (mon->mon_gamma_green >= GAMMA_MIN && mon->mon_gamma_green <= GAMMA_MAX)
+ gamma_green = mon->mon_gamma_green;
+
+ if (mon->mon_gamma_blue >= GAMMA_MIN && mon->mon_gamma_blue <= GAMMA_MAX)
+ gamma_blue = mon->mon_gamma_blue;
+
+ /* Don't set gamma 1.0 if another cloned output on this CRTC already set a
+ * different gamma
+ */
+ if (gamma_red != 1.0 || gamma_green != 1.0 || gamma_blue != 1.0) {
+ xf86DrvMsg(output->scrn->scrnIndex, X_INFO,
+ "Output %s wants gamma correction (%.1f, %.1f, %.1f)\n",
+ output->name, gamma_red, gamma_green, gamma_blue);
+ return xf86RandR12CrtcInitGamma(output->crtc, gamma_red, gamma_green,
+ gamma_blue);
}
- randr_crtc->gammaSize = crtc->gamma_size;
- memcpy(randr_crtc->gammaRed, crtc->gamma_red,
- crtc->gamma_size * sizeof(CARD16));
- memcpy(randr_crtc->gammaGreen, crtc->gamma_green,
- crtc->gamma_size * sizeof(CARD16));
- memcpy(randr_crtc->gammaBlue, crtc->gamma_blue,
- crtc->gamma_size * sizeof(CARD16));
return TRUE;
}
+void
+xf86RandR12InitGamma(ScrnInfoPtr pScrn, unsigned gammaSize) {
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int o, c;
+
+ /* Set default gamma for all CRTCs
+ * This is done to avoid problems later on with cloned outputs
+ */
+ for (c = 0; c < config->num_crtc; c++) {
+ xf86CrtcPtr crtc = config->crtc[c];
+
+ RRCrtcGammaSetSize(crtc->randr_crtc, gammaSize);
+ xf86RandR12CrtcInitGamma(crtc, 1.0, 1.0, 1.0);
+ }
+
+ /* Set initial gamma per monitor configuration
+ */
+ for (o = 0; o < config->num_output; o++) {
+ xf86OutputPtr output = config->output[o];
+
+ if (output->crtc && !xf86RandR12OutputInitGamma(output))
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Initial gamma correction for output %s: failed.\n",
+ output->name);
+ }
+}
+
static Bool
xf86RandR12OutputSetProperty(ScreenPtr pScreen,
RROutputPtr randr_output,
@@ -1575,7 +1630,6 @@ xf86RandR12CreateObjects12(ScreenPtr pScreen)
xf86CrtcPtr crtc = config->crtc[c];
crtc->randr_crtc = RRCrtcCreate(pScreen, crtc);
- RRCrtcGammaSetSize(crtc->randr_crtc, 256);
}
/*
* Configure outputs
diff --git a/hw/xfree86/modes/xf86RandR12.h b/hw/xfree86/modes/xf86RandR12.h
index 8b4219c2d..fbdfe75b4 100644
--- a/hw/xfree86/modes/xf86RandR12.h
+++ b/hw/xfree86/modes/xf86RandR12.h
@@ -42,5 +42,7 @@ extern _X_EXPORT void xf86RandR12TellChanged(ScreenPtr pScreen);
extern _X_EXPORT void xf86RandR12LoadPalette(ScrnInfoPtr pScrn, int numColors,
int *indices, LOCO *colors,
VisualPtr pVisual);
+extern _X_EXPORT void xf86RandR12InitGamma(ScrnInfoPtr pScrn,
+ unsigned gammaSize);
#endif /* _XF86_RANDR_H_ */