diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 07ff6e6ba..4ed8925dd 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -867,8 +867,12 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, if (drmmode_crtc->tear_free) scanout_id = drmmode_crtc->scanout_id; - crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green, - crtc->gamma_blue, crtc->gamma_size); + if (drmmode_crtc->gamma_size) { + crtc->funcs->gamma_set(crtc, drmmode_crtc->gamma_red, + drmmode_crtc->gamma_green, + drmmode_crtc->gamma_blue, + drmmode_crtc->gamma_size); + } drmmode_ConvertToKMode(crtc->scrn, &kmode, mode); @@ -1206,6 +1210,25 @@ drmmode_crtc_gamma_set(xf86CrtcPtr crtc, uint16_t *red, uint16_t *green, drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; drmmode_ptr drmmode = drmmode_crtc->drmmode; + if (drmmode_crtc->gamma_size != size) { + drmmode_crtc->gamma_red = realloc(drmmode_crtc->gamma_red, + 3 * size * sizeof(uint16_t)); + + if (drmmode_crtc->gamma_red) { + drmmode_crtc->gamma_green = drmmode_crtc->gamma_red + size; + drmmode_crtc->gamma_blue = drmmode_crtc->gamma_green + size; + drmmode_crtc->gamma_size = size; + } else { + drmmode_crtc->gamma_size = 0; + } + } + + if (drmmode_crtc->gamma_size) { + memcpy(drmmode_crtc->gamma_red, red, size * sizeof(uint16_t)); + memcpy(drmmode_crtc->gamma_green, green, size * sizeof(uint16_t)); + memcpy(drmmode_crtc->gamma_blue, blue, size * sizeof(uint16_t)); + } + drmModeCrtcSetGamma(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, size, red, green, blue); } @@ -2592,8 +2615,15 @@ void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode) #endif } - for (c = 0; c < config->num_crtc; c++) - drmmode_crtc_scanout_free(config->crtc[c]->driver_private); + for (c = 0; c < config->num_crtc; c++) { + drmmode_crtc_private_ptr drmmode_crtc = config->crtc[c]->driver_private; + + drmmode_crtc_scanout_free(drmmode_crtc); + if (drmmode_crtc->gamma_size) { + free(drmmode_crtc->gamma_red); + drmmode_crtc->gamma_size = 0; + } + } } diff --git a/src/drmmode_display.h b/src/drmmode_display.h index 3783d1415..bde9988af 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -105,6 +104,11 @@ typedef struct { Bool need_modeset; /* A flip is pending for this CRTC */ Bool flip_pending; + + int gamma_size; + uint16_t *gamma_red; + uint16_t *gamma_green; + uint16_t *gamma_blue; } drmmode_crtc_private_rec, *drmmode_crtc_private_ptr; typedef struct {