backend-drm: reset gamma on legacy KMS
We are assuming that gamma LUT is pass-through, so better ensure it really is pass-through rather than whatever the previous KMS client left there. Unfortunately the legacy ioctl does not offer any way to reset the LUT without actually crafting an identity LUT. If the legacy gamma libdrm function indicates the feature is not supported, do not try to use it again. This avoids hammering the legacy gamma every frame when deprecated drm_output_set_gamma() is not used. drm_output_set_gamma() is not updated to check/set this flag in order to maintain its old behavior. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This commit is contained in:
parent
debfeb3049
commit
1acf69ac2f
@ -576,6 +576,7 @@ struct drm_output {
|
|||||||
unsigned max_bpc;
|
unsigned max_bpc;
|
||||||
|
|
||||||
bool deprecated_gamma_is_set;
|
bool deprecated_gamma_is_set;
|
||||||
|
bool legacy_gamma_not_supported;
|
||||||
|
|
||||||
/* Plane being displayed directly on the CRTC */
|
/* Plane being displayed directly on the CRTC */
|
||||||
struct drm_plane *scanout_plane;
|
struct drm_plane *scanout_plane;
|
||||||
|
@ -636,6 +636,41 @@ err:
|
|||||||
drmModeSetCursor(device->drm.fd, crtc->crtc_id, 0, 0, 0);
|
drmModeSetCursor(device->drm.fd, crtc->crtc_id, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
drm_output_reset_legacy_gamma(struct drm_output *output)
|
||||||
|
{
|
||||||
|
uint32_t len = output->base.gamma_size;
|
||||||
|
uint16_t *lut;
|
||||||
|
uint32_t i;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (len == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (output->legacy_gamma_not_supported)
|
||||||
|
return;
|
||||||
|
|
||||||
|
lut = calloc(len, sizeof(uint16_t));
|
||||||
|
if (!lut)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Identity curve */
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
lut[i] = 0xffff * i / (len - 1);
|
||||||
|
|
||||||
|
ret = drmModeCrtcSetGamma(output->device->drm.fd,
|
||||||
|
output->crtc->crtc_id,
|
||||||
|
len, lut, lut, lut);
|
||||||
|
if (ret == -EOPNOTSUPP || ret == -ENOSYS)
|
||||||
|
output->legacy_gamma_not_supported = true;
|
||||||
|
else if (ret < 0) {
|
||||||
|
weston_log("%s failed for %s: %s\n", __func__,
|
||||||
|
output->base.name, strerror(-ret));
|
||||||
|
}
|
||||||
|
|
||||||
|
free(lut);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
drm_output_apply_state_legacy(struct drm_output_state *state)
|
drm_output_apply_state_legacy(struct drm_output_state *state)
|
||||||
{
|
{
|
||||||
@ -728,6 +763,9 @@ drm_output_apply_state_legacy(struct drm_output_state *state)
|
|||||||
weston_log("set mode failed: %s\n", strerror(errno));
|
weston_log("set mode failed: %s\n", strerror(errno));
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!output->deprecated_gamma_is_set)
|
||||||
|
drm_output_reset_legacy_gamma(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
pinfo = scanout_state->fb->format;
|
pinfo = scanout_state->fb->format;
|
||||||
|
Loading…
Reference in New Issue
Block a user