From 4eb581ffc1a63f7c843a8143c6a1c97056b94caa Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Mon, 15 Aug 2022 23:37:41 +0200 Subject: [PATCH] backends/native: Read CRTC Gamma state from legacy and property APIs If the device supports the atomic API the property based API is used to write gamma updates and the legacy API is used in the non-atomic case. The current state is read from the legacy API always though which can be different from the property API. This commit always uses the correct API to update the state. Part-of: --- src/backends/meta-crtc.c | 16 ++++ src/backends/meta-crtc.h | 2 + src/backends/native/meta-kms-crtc-private.h | 1 + src/backends/native/meta-kms-crtc.c | 90 +++++++++++++++++++-- 4 files changed, 104 insertions(+), 5 deletions(-) diff --git a/src/backends/meta-crtc.c b/src/backends/meta-crtc.c index 3fb59be01..f3b1549c8 100644 --- a/src/backends/meta-crtc.c +++ b/src/backends/meta-crtc.c @@ -194,6 +194,22 @@ meta_gamma_lut_new (int size, return gamma; } +MetaGammaLut * +meta_gamma_lut_new_sized (int size) +{ + MetaGammaLut *gamma; + + gamma = g_new0 (MetaGammaLut, 1); + *gamma = (MetaGammaLut) { + .size = size, + .red = g_new0 (uint16_t, size), + .green = g_new0 (uint16_t, size), + .blue = g_new0 (uint16_t, size), + }; + + return gamma; +} + MetaGammaLut * meta_gamma_lut_copy (const MetaGammaLut *gamma) { diff --git a/src/backends/meta-crtc.h b/src/backends/meta-crtc.h index ac84fbee9..06494f9a9 100644 --- a/src/backends/meta-crtc.h +++ b/src/backends/meta-crtc.h @@ -99,6 +99,8 @@ MetaGammaLut * meta_gamma_lut_new (int size, const uint16_t *green, const uint16_t *blue); +MetaGammaLut * meta_gamma_lut_new_sized (int size); + META_EXPORT_TEST MetaGammaLut * meta_gamma_lut_copy (const MetaGammaLut *gamma); diff --git a/src/backends/native/meta-kms-crtc-private.h b/src/backends/native/meta-kms-crtc-private.h index 372f2f5a4..e36202be7 100644 --- a/src/backends/native/meta-kms-crtc-private.h +++ b/src/backends/native/meta-kms-crtc-private.h @@ -30,6 +30,7 @@ typedef enum _MetaKmsCrtcProp META_KMS_CRTC_PROP_MODE_ID = 0, META_KMS_CRTC_PROP_ACTIVE, META_KMS_CRTC_PROP_GAMMA_LUT, + META_KMS_CRTC_PROP_GAMMA_LUT_SIZE, META_KMS_CRTC_N_PROPS } MetaKmsCrtcProp; diff --git a/src/backends/native/meta-kms-crtc.c b/src/backends/native/meta-kms-crtc.c index 182afecd6..fb795441d 100644 --- a/src/backends/native/meta-kms-crtc.c +++ b/src/backends/native/meta-kms-crtc.c @@ -24,6 +24,8 @@ #include "backends/native/meta-kms-device-private.h" #include "backends/native/meta-kms-impl-device.h" +#include "backends/native/meta-kms-impl-device-atomic.h" +#include "backends/native/meta-kms-impl-device-simple.h" #include "backends/native/meta-kms-mode.h" #include "backends/native/meta-kms-update-private.h" @@ -102,13 +104,69 @@ meta_kms_crtc_is_active (MetaKmsCrtc *crtc) } static void -read_gamma_state (MetaKmsCrtc *crtc, - MetaKmsCrtcState *crtc_state, - MetaKmsImplDevice *impl_device, - drmModeCrtc *drm_crtc) +read_crtc_gamma (MetaKmsCrtc *crtc, + MetaKmsCrtcState *crtc_state, + MetaKmsImplDevice *impl_device, + drmModeCrtc *drm_crtc) { - g_assert (crtc_state->gamma.value == NULL); + MetaKmsProp *prop_lut; + MetaKmsProp *prop_size; + uint64_t blob_id; + uint64_t lut_size; + int fd; + drmModePropertyBlobPtr blob; + int drm_lut_size; + struct drm_color_lut *drm_lut; + int i; + prop_lut = &crtc->prop_table.props[META_KMS_CRTC_PROP_GAMMA_LUT]; + prop_size = &crtc->prop_table.props[META_KMS_CRTC_PROP_GAMMA_LUT_SIZE]; + + if (!prop_lut->prop_id || !prop_size->prop_id) + return; + + blob_id = prop_lut->value; + if (blob_id == 0) + return; + + lut_size = prop_size->value; + if (lut_size <= 0) + return; + + fd = meta_kms_impl_device_get_fd (impl_device); + blob = drmModeGetPropertyBlob (fd, blob_id); + if (!blob) + return; + + drm_lut_size = blob->length / sizeof (struct drm_color_lut); + if (drm_lut_size == 0) + { + drmModeFreePropertyBlob (blob); + return; + } + + drm_lut = blob->data; + + crtc_state->gamma.size = lut_size; + crtc_state->gamma.supported = TRUE; + crtc_state->gamma.value = meta_gamma_lut_new_sized (drm_lut_size); + + for (i = 0; i < drm_lut_size; i++) + { + crtc_state->gamma.value->red[i] = drm_lut[i].red; + crtc_state->gamma.value->green[i] = drm_lut[i].green; + crtc_state->gamma.value->blue[i] = drm_lut[i].blue; + } + + drmModeFreePropertyBlob (blob); +} + +static void +read_crtc_legacy_gamma (MetaKmsCrtc *crtc, + MetaKmsCrtcState *crtc_state, + MetaKmsImplDevice *impl_device, + drmModeCrtc *drm_crtc) +{ crtc_state->gamma.size = drm_crtc->gamma_size; crtc_state->gamma.supported = drm_crtc->gamma_size != 0; crtc_state->gamma.value = meta_gamma_lut_new (drm_crtc->gamma_size, @@ -126,6 +184,23 @@ read_gamma_state (MetaKmsCrtc *crtc, crtc_state->gamma.value->blue); } +static void +read_gamma_state (MetaKmsCrtc *crtc, + MetaKmsCrtcState *crtc_state, + MetaKmsImplDevice *impl_device, + drmModeCrtc *drm_crtc) +{ + g_assert_null (crtc_state->gamma.value); + + crtc_state->gamma.size = 0; + crtc_state->gamma.supported = FALSE; + + if (META_IS_KMS_IMPL_DEVICE_ATOMIC (impl_device)) + read_crtc_gamma (crtc, crtc_state, impl_device, drm_crtc); + else if (META_IS_KMS_IMPL_DEVICE_SIMPLE (impl_device)) + read_crtc_legacy_gamma (crtc, crtc_state, impl_device, drm_crtc); +} + static gboolean gamma_equal (MetaKmsCrtcState *state, MetaKmsCrtcState *other_state) @@ -349,6 +424,11 @@ init_properties (MetaKmsCrtc *crtc, .name = "GAMMA_LUT", .type = DRM_MODE_PROP_BLOB, }, + [META_KMS_CRTC_PROP_GAMMA_LUT_SIZE] = + { + .name = "GAMMA_LUT_SIZE", + .type = DRM_MODE_PROP_RANGE, + }, } }; }