xfree86/modes: Move gamma initialization to xf86RandR12Init12 v2
RRCrtcGammaSetSize cannot be used yet in xf86InitialConfiguration, because randr_crtc isn't allocated yet at that point, but a following change will require RRCrtcGammaSetSize to be called from xf86RandR12CrtcInitGamma. v2: * Bail from xf86RandR12CrtcInitGamma if !crtc->funcs->gamma_set (Keith Packard) Reviewed-by: Keith Packard <keithp@keithp.com>
This commit is contained in:
		
							parent
							
								
									0b2f30834b
								
							
						
					
					
						commit
						62f4405257
					
				| 
						 | 
				
			
			@ -2451,108 +2451,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
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -2672,15 +2570,8 @@ 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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (xf86_crtc_supports_gamma(scrn))
 | 
			
		||||
        xf86DrvMsg(scrn->scrnIndex, X_INFO,
 | 
			
		||||
                   "Using default gamma of (1.0, 1.0, 1.0) unless otherwise stated.\n");
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Set initial configuration
 | 
			
		||||
     */
 | 
			
		||||
| 
						 | 
				
			
			@ -2703,10 +2594,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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1313,6 +1313,116 @@ xf86RandR12CrtcGetGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc)
 | 
			
		|||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
    if (!crtc->funcs->gamma_set &&
 | 
			
		||||
        (gamma_red != 1.0f || gamma_green != 1.0f || gamma_blue != 1.0f))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
 | 
			
		||||
    red = xallocarray(size, 3 * sizeof(CARD16));
 | 
			
		||||
    if (!red)
 | 
			
		||||
        return FALSE;
 | 
			
		||||
 | 
			
		||||
    green = red + size;
 | 
			
		||||
    blue = green + 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);
 | 
			
		||||
    free(red);
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Bool
 | 
			
		||||
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];
 | 
			
		||||
 | 
			
		||||
        if (!RRCrtcGammaSetSize(crtc->randr_crtc, gammaSize) ||
 | 
			
		||||
            !xf86RandR12CrtcInitGamma(crtc, 1.0f, 1.0f, 1.0f))
 | 
			
		||||
            return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Bool
 | 
			
		||||
xf86RandR12OutputSetProperty(ScreenPtr pScreen,
 | 
			
		||||
                             RROutputPtr randr_output,
 | 
			
		||||
| 
						 | 
				
			
			@ -1533,7 +1643,6 @@ xf86RandR12CreateObjects12(ScreenPtr pScreen)
 | 
			
		|||
        xf86CrtcPtr crtc = config->crtc[c];
 | 
			
		||||
 | 
			
		||||
        crtc->randr_crtc = RRCrtcCreate(pScreen, crtc);
 | 
			
		||||
        RRCrtcGammaSetSize(crtc->randr_crtc, 256);
 | 
			
		||||
    }
 | 
			
		||||
    /*
 | 
			
		||||
     * Configure outputs
 | 
			
		||||
| 
						 | 
				
			
			@ -2011,6 +2120,10 @@ xf86RandR12Init12(ScreenPtr pScreen)
 | 
			
		|||
     */
 | 
			
		||||
    if (!xf86RandR12SetInfo12(pScreen))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
 | 
			
		||||
    if (!xf86RandR12InitGamma(pScrn, 256))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < rp->numCrtcs; i++) {
 | 
			
		||||
        xf86RandR12CrtcGetGamma(pScreen, rp->crtcs[i]);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue