xfree86/modes: Make colormap/gamma glue code work with RandR disabled
E.g. because Xinerama is enabled.
Fixes crash on startup and wrong colours in that case.
Bugzilla: https://bugs.freedesktop.org/100293
Bugzilla: https://bugs.freedesktop.org/100294
Fixes: 62f4405257
("xfree86/modes: Move gamma initialization to
xf86RandR12Init12 v2")
Tested-by: Mariusz Bialonczyk <manio@skyboo.net>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
bcee1b76aa
commit
41dafcc2a2
|
@ -1246,33 +1246,50 @@ xf86RandR12CrtcSet(ScreenPtr pScreen,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xf86RandR12CrtcComputeGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc)
|
xf86RandR12CrtcComputeGamma(xf86CrtcPtr crtc, LOCO *palette,
|
||||||
|
int palette_red_size, int palette_green_size,
|
||||||
|
int palette_blue_size, CARD16 *gamma_red,
|
||||||
|
CARD16 *gamma_green, CARD16 *gamma_blue,
|
||||||
|
int gamma_size)
|
||||||
{
|
{
|
||||||
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
|
|
||||||
xf86CrtcPtr crtc = randr_crtc->devPrivate;
|
|
||||||
int gamma_slots;
|
int gamma_slots;
|
||||||
CARD16 value;
|
unsigned shift;
|
||||||
|
CARD32 value;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
gamma_slots = crtc->gamma_size / randrp->palette_red_size;
|
for (shift = 0; (gamma_size << shift) < (1 << 16); shift++);
|
||||||
for (i = 0; i < randrp->palette_red_size; i++) {
|
|
||||||
value = randr_crtc->gammaRed[randrp->palette[i].red];
|
gamma_slots = crtc->gamma_size / palette_red_size;
|
||||||
|
for (i = 0; i < palette_red_size; i++) {
|
||||||
|
value = palette[i].red;
|
||||||
|
if (gamma_red)
|
||||||
|
value = gamma_red[value];
|
||||||
|
else
|
||||||
|
value <<= shift;
|
||||||
|
|
||||||
for (j = 0; j < gamma_slots; j++)
|
for (j = 0; j < gamma_slots; j++)
|
||||||
crtc->gamma_red[i * gamma_slots + j] = value;
|
crtc->gamma_red[i * gamma_slots + j] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
gamma_slots = crtc->gamma_size / randrp->palette_green_size;
|
gamma_slots = crtc->gamma_size / palette_green_size;
|
||||||
for (i = 0; i < randrp->palette_green_size; i++) {
|
for (i = 0; i < palette_green_size; i++) {
|
||||||
value = randr_crtc->gammaGreen[randrp->palette[i].green];
|
value = palette[i].green;
|
||||||
|
if (gamma_green)
|
||||||
|
value = gamma_green[value];
|
||||||
|
else
|
||||||
|
value <<= shift;
|
||||||
|
|
||||||
for (j = 0; j < gamma_slots; j++)
|
for (j = 0; j < gamma_slots; j++)
|
||||||
crtc->gamma_green[i * gamma_slots + j] = value;
|
crtc->gamma_green[i * gamma_slots + j] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
gamma_slots = crtc->gamma_size / randrp->palette_blue_size;
|
gamma_slots = crtc->gamma_size / palette_blue_size;
|
||||||
for (i = 0; i < randrp->palette_blue_size; i++) {
|
for (i = 0; i < palette_blue_size; i++) {
|
||||||
value = randr_crtc->gammaBlue[randrp->palette[i].blue];
|
value = palette[i].blue;
|
||||||
|
if (gamma_blue)
|
||||||
|
value = gamma_blue[value];
|
||||||
|
else
|
||||||
|
value <<= shift;
|
||||||
|
|
||||||
for (j = 0; j < gamma_slots; j++)
|
for (j = 0; j < gamma_slots; j++)
|
||||||
crtc->gamma_blue[i * gamma_slots + j] = value;
|
crtc->gamma_blue[i * gamma_slots + j] = value;
|
||||||
|
@ -1280,10 +1297,8 @@ xf86RandR12CrtcComputeGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xf86RandR12CrtcReloadGamma(RRCrtcPtr randr_crtc)
|
xf86RandR12CrtcReloadGamma(xf86CrtcPtr crtc)
|
||||||
{
|
{
|
||||||
xf86CrtcPtr crtc = randr_crtc->devPrivate;
|
|
||||||
|
|
||||||
if (!crtc->scrn->vtSema || !crtc->funcs->gamma_set)
|
if (!crtc->scrn->vtSema || !crtc->funcs->gamma_set)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1305,7 +1320,14 @@ xf86RandR12CrtcSetGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (randrp->palette_size) {
|
if (randrp->palette_size) {
|
||||||
xf86RandR12CrtcComputeGamma(pScreen, randr_crtc);
|
xf86RandR12CrtcComputeGamma(crtc, randrp->palette,
|
||||||
|
randrp->palette_red_size,
|
||||||
|
randrp->palette_green_size,
|
||||||
|
randrp->palette_blue_size,
|
||||||
|
randr_crtc->gammaRed,
|
||||||
|
randr_crtc->gammaGreen,
|
||||||
|
randr_crtc->gammaBlue,
|
||||||
|
randr_crtc->gammaSize);
|
||||||
} else {
|
} else {
|
||||||
memcpy(crtc->gamma_red, randr_crtc->gammaRed,
|
memcpy(crtc->gamma_red, randr_crtc->gammaRed,
|
||||||
crtc->gamma_size * sizeof(crtc->gamma_red[0]));
|
crtc->gamma_size * sizeof(crtc->gamma_red[0]));
|
||||||
|
@ -1315,7 +1337,7 @@ xf86RandR12CrtcSetGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc)
|
||||||
crtc->gamma_size * sizeof(crtc->gamma_blue[0]));
|
crtc->gamma_size * sizeof(crtc->gamma_blue[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
xf86RandR12CrtcReloadGamma(randr_crtc);
|
xf86RandR12CrtcReloadGamma(crtc);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1390,6 +1412,13 @@ xf86RandR12OutputInitGamma(xf86OutputPtr output)
|
||||||
* different gamma
|
* different gamma
|
||||||
*/
|
*/
|
||||||
if (gamma_red != 1.0 || gamma_green != 1.0 || gamma_blue != 1.0) {
|
if (gamma_red != 1.0 || gamma_green != 1.0 || gamma_blue != 1.0) {
|
||||||
|
if (!output->crtc->randr_crtc) {
|
||||||
|
xf86DrvMsg(output->scrn->scrnIndex, X_WARNING,
|
||||||
|
"Gamma correction for output %s not possible because "
|
||||||
|
"RandR is disabled\n", output->name);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
xf86DrvMsg(output->scrn->scrnIndex, X_INFO,
|
xf86DrvMsg(output->scrn->scrnIndex, X_INFO,
|
||||||
"Output %s wants gamma correction (%.1f, %.1f, %.1f)\n",
|
"Output %s wants gamma correction (%.1f, %.1f, %.1f)\n",
|
||||||
output->name, gamma_red, gamma_green, gamma_blue);
|
output->name, gamma_red, gamma_green, gamma_blue);
|
||||||
|
@ -1411,6 +1440,9 @@ xf86RandR12InitGamma(ScrnInfoPtr pScrn, unsigned gammaSize) {
|
||||||
for (c = 0; c < config->num_crtc; c++) {
|
for (c = 0; c < config->num_crtc; c++) {
|
||||||
xf86CrtcPtr crtc = config->crtc[c];
|
xf86CrtcPtr crtc = config->crtc[c];
|
||||||
|
|
||||||
|
if (!crtc->randr_crtc)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!RRCrtcGammaSetSize(crtc->randr_crtc, gammaSize) ||
|
if (!RRCrtcGammaSetSize(crtc->randr_crtc, gammaSize) ||
|
||||||
!xf86RandR12CrtcInitGamma(crtc, 1.0f, 1.0f, 1.0f))
|
!xf86RandR12CrtcInitGamma(crtc, 1.0f, 1.0f, 1.0f))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -1872,7 +1904,6 @@ xf86RandR12LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
|
||||||
LOCO *colors, VisualPtr pVisual)
|
LOCO *colors, VisualPtr pVisual)
|
||||||
{
|
{
|
||||||
ScreenPtr pScreen = pScrn->pScreen;
|
ScreenPtr pScreen = pScrn->pScreen;
|
||||||
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
|
|
||||||
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
||||||
int reds, greens, blues, index, palette_size;
|
int reds, greens, blues, index, palette_size;
|
||||||
int c, i;
|
int c, i;
|
||||||
|
@ -1887,6 +1918,9 @@ xf86RandR12LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
|
||||||
|
|
||||||
palette_size = max(reds, max(greens, blues));
|
palette_size = max(reds, max(greens, blues));
|
||||||
|
|
||||||
|
if (dixPrivateKeyRegistered(rrPrivKey)) {
|
||||||
|
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
|
||||||
|
|
||||||
if (randrp->palette_size != palette_size) {
|
if (randrp->palette_size != palette_size) {
|
||||||
randrp->palette = reallocarray(randrp->palette, palette_size,
|
randrp->palette = reallocarray(randrp->palette, palette_size,
|
||||||
sizeof(colors[0]));
|
sizeof(colors[0]));
|
||||||
|
@ -1911,12 +1945,24 @@ xf86RandR12LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
|
||||||
if (index < blues)
|
if (index < blues)
|
||||||
randrp->palette[index].blue = colors[index].blue;
|
randrp->palette[index].blue = colors[index].blue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (c = 0; c < config->num_crtc; c++) {
|
for (c = 0; c < config->num_crtc; c++) {
|
||||||
RRCrtcPtr randr_crtc = config->crtc[c]->randr_crtc;
|
xf86CrtcPtr crtc = config->crtc[c];
|
||||||
|
RRCrtcPtr randr_crtc = crtc->randr_crtc;
|
||||||
|
|
||||||
xf86RandR12CrtcComputeGamma(pScreen, randr_crtc);
|
if (randr_crtc) {
|
||||||
xf86RandR12CrtcReloadGamma(randr_crtc);
|
xf86RandR12CrtcComputeGamma(crtc, colors, reds, greens, blues,
|
||||||
|
randr_crtc->gammaRed,
|
||||||
|
randr_crtc->gammaGreen,
|
||||||
|
randr_crtc->gammaBlue,
|
||||||
|
randr_crtc->gammaSize);
|
||||||
|
} else {
|
||||||
|
xf86RandR12CrtcComputeGamma(crtc, colors, reds, greens, blues,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
xf86GetGammaRampSize(pScreen));
|
||||||
|
}
|
||||||
|
xf86RandR12CrtcReloadGamma(crtc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1969,7 +2015,7 @@ xf86RandR12EnterVT(ScrnInfoPtr pScrn)
|
||||||
|
|
||||||
/* reload gamma */
|
/* reload gamma */
|
||||||
for (i = 0; i < rp->numCrtcs; i++)
|
for (i = 0; i < rp->numCrtcs; i++)
|
||||||
xf86RandR12CrtcReloadGamma(rp->crtcs[i]);
|
xf86RandR12CrtcReloadGamma(rp->crtcs[i]->devPrivate);
|
||||||
|
|
||||||
return RRGetInfo(pScreen, TRUE); /* force a re-probe of outputs and notify clients about changes */
|
return RRGetInfo(pScreen, TRUE); /* force a re-probe of outputs and notify clients about changes */
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue