backends/native: Use MetaKmsCrtcGamma for the KMS gamma color update

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2861>
This commit is contained in:
Sebastian Wick 2023-02-18 02:14:27 +01:00 committed by Marge Bot
parent 0180ffdaa1
commit 8ccbc21d23
5 changed files with 99 additions and 90 deletions

View File

@ -130,9 +130,16 @@ meta_crtc_kms_get_gamma_lut (MetaCrtc *crtc)
crtc_gamma =
meta_monitor_manager_native_get_cached_crtc_gamma (monitor_manager_native,
crtc_kms);
if (!crtc_gamma)
{
crtc_state = meta_kms_crtc_get_current_state (kms_crtc);
crtc_gamma = crtc_state->gamma.value;
}
lut = g_new0 (MetaGammaLut, 1);
if (crtc_gamma)
{
lut = g_new0 (MetaGammaLut, 1);
lut->size = crtc_gamma->size;
lut->red = g_memdup2 (crtc_gamma->red,
lut->size * sizeof (uint16_t));
@ -140,19 +147,14 @@ meta_crtc_kms_get_gamma_lut (MetaCrtc *crtc)
lut->size * sizeof (uint16_t));
lut->blue = g_memdup2 (crtc_gamma->blue,
lut->size * sizeof (uint16_t));
return lut;
}
crtc_state = meta_kms_crtc_get_current_state (kms_crtc);
lut = g_new0 (MetaGammaLut, 1);
lut->size = crtc_state->gamma.size;
lut->red = g_memdup2 (crtc_state->gamma.red,
lut->size * sizeof (uint16_t));
lut->green = g_memdup2 (crtc_state->gamma.green,
lut->size * sizeof (uint16_t));
lut->blue = g_memdup2 (crtc_state->gamma.blue,
lut->size * sizeof (uint16_t));
else
{
lut->size = 0;
lut->red = NULL;
lut->green = NULL;
lut->blue = NULL;
}
return lut;
}

View File

@ -107,21 +107,32 @@ read_gamma_state (MetaKmsCrtc *crtc,
MetaKmsImplDevice *impl_device,
drmModeCrtc *drm_crtc)
{
g_assert (!crtc_state->gamma.red &&
!crtc_state->gamma.green &&
!crtc_state->gamma.blue);
g_assert (crtc_state->gamma.value == NULL);
crtc_state->gamma.size = drm_crtc->gamma_size;
crtc_state->gamma.red = g_new0 (uint16_t, drm_crtc->gamma_size);
crtc_state->gamma.green = g_new0 (uint16_t, drm_crtc->gamma_size);
crtc_state->gamma.blue = g_new0 (uint16_t, drm_crtc->gamma_size);
crtc_state->gamma.supported = drm_crtc->gamma_size != 0;
crtc_state->gamma.value = meta_kms_crtc_gamma_new (drm_crtc->gamma_size,
NULL, NULL, NULL);
crtc_state->gamma.value->red = g_new0 (uint16_t, drm_crtc->gamma_size);
crtc_state->gamma.value->green = g_new0 (uint16_t, drm_crtc->gamma_size);
crtc_state->gamma.value->blue = g_new0 (uint16_t, drm_crtc->gamma_size);
drmModeCrtcGetGamma (meta_kms_impl_device_get_fd (impl_device),
crtc->id,
crtc_state->gamma.size,
crtc_state->gamma.red,
crtc_state->gamma.green,
crtc_state->gamma.blue);
crtc_state->gamma.value->size,
crtc_state->gamma.value->red,
crtc_state->gamma.value->green,
crtc_state->gamma.value->blue);
}
static gboolean
gamma_equal (MetaKmsCrtcState *state,
MetaKmsCrtcState *other_state)
{
return state->gamma.size == other_state->gamma.size &&
state->gamma.supported == other_state->gamma.supported &&
meta_kms_crtc_gamma_equal (state->gamma.value, other_state->gamma.value);
}
static MetaKmsResourceChanges
@ -140,33 +151,12 @@ meta_kms_crtc_state_changes (MetaKmsCrtcState *state,
if (!meta_drm_mode_equal (&state->drm_mode, &other_state->drm_mode))
return META_KMS_RESOURCE_CHANGE_FULL;
if (state->gamma.size != other_state->gamma.size)
return META_KMS_RESOURCE_CHANGE_GAMMA;
if (memcmp (state->gamma.blue, other_state->gamma.blue,
state->gamma.size * sizeof (uint16_t)) != 0)
return META_KMS_RESOURCE_CHANGE_GAMMA;
if (memcmp (state->gamma.green, other_state->gamma.green,
state->gamma.size * sizeof (uint16_t)) != 0)
return META_KMS_RESOURCE_CHANGE_GAMMA;
if (memcmp (state->gamma.red, other_state->gamma.red,
state->gamma.size * sizeof (uint16_t)) != 0)
if (!gamma_equal (state, other_state))
return META_KMS_RESOURCE_CHANGE_GAMMA;
return META_KMS_RESOURCE_CHANGE_NONE;
}
static void
clear_gamma_state (MetaKmsCrtcState *crtc_state)
{
crtc_state->gamma.size = 0;
g_clear_pointer (&crtc_state->gamma.red, g_free);
g_clear_pointer (&crtc_state->gamma.green, g_free);
g_clear_pointer (&crtc_state->gamma.blue, g_free);
}
static MetaKmsResourceChanges
meta_kms_crtc_read_state (MetaKmsCrtc *crtc,
MetaKmsImplDevice *impl_device,
@ -213,7 +203,8 @@ meta_kms_crtc_read_state (MetaKmsCrtc *crtc,
changes = meta_kms_crtc_state_changes (&crtc->current_state, &crtc_state);
}
clear_gamma_state (&crtc->current_state);
g_clear_pointer (&crtc->current_state.gamma.value,
meta_kms_crtc_gamma_free);
crtc->current_state = crtc_state;
meta_topic (META_DEBUG_KMS,
@ -322,15 +313,11 @@ meta_kms_crtc_predict_state_in_impl (MetaKmsCrtc *crtc,
if (color_update->crtc != crtc)
continue;
clear_gamma_state (&crtc->current_state);
crtc->current_state.gamma.size = gamma->size;
crtc->current_state.gamma.red =
g_memdup2 (gamma->red, gamma->size * sizeof (uint16_t));
crtc->current_state.gamma.green =
g_memdup2 (gamma->green, gamma->size * sizeof (uint16_t));
crtc->current_state.gamma.blue =
g_memdup2 (gamma->blue, gamma->size * sizeof (uint16_t));
g_clear_pointer (&crtc->current_state.gamma.value, meta_kms_crtc_gamma_free);
crtc->current_state.gamma.value = meta_kms_crtc_gamma_new (gamma->size,
gamma->red,
gamma->green,
gamma->blue);
break;
}
}
@ -402,7 +389,7 @@ meta_kms_crtc_finalize (GObject *object)
{
MetaKmsCrtc *crtc = META_KMS_CRTC (object);
clear_gamma_state (&crtc->current_state);
g_clear_pointer (&crtc->current_state.gamma.value, meta_kms_crtc_gamma_free);
G_OBJECT_CLASS (meta_kms_crtc_parent_class)->finalize (object);
}
@ -411,6 +398,7 @@ static void
meta_kms_crtc_init (MetaKmsCrtc *crtc)
{
crtc->current_state.gamma.size = 0;
crtc->current_state.gamma.value = NULL;
}
static void

View File

@ -28,6 +28,14 @@
#include "core/util-private.h"
#include "meta/boxes.h"
typedef struct _MetaKmsCrtcGamma
{
int size;
uint16_t *red;
uint16_t *green;
uint16_t *blue;
} MetaKmsCrtcGamma;
typedef struct _MetaKmsCrtcState
{
gboolean is_active;
@ -37,22 +45,12 @@ typedef struct _MetaKmsCrtcState
drmModeModeInfo drm_mode;
struct {
uint16_t *red;
uint16_t *green;
uint16_t *blue;
MetaKmsCrtcGamma *value;
int size;
gboolean supported;
} gamma;
} MetaKmsCrtcState;
typedef struct _MetaKmsCrtcGamma
{
int size;
uint16_t *red;
uint16_t *green;
uint16_t *blue;
} MetaKmsCrtcGamma;
#define META_TYPE_KMS_CRTC (meta_kms_crtc_get_type ())
META_EXPORT_TEST
G_DECLARE_FINAL_TYPE (MetaKmsCrtc, meta_kms_crtc,
@ -80,4 +78,7 @@ MetaKmsCrtcGamma * meta_kms_crtc_gamma_new (int size,
const uint16_t *green,
const uint16_t *blue);
gboolean meta_kms_crtc_gamma_equal (MetaKmsCrtcGamma *gamma,
MetaKmsCrtcGamma *other_gamma);
#endif /* META_KMS_CRTC_H */

View File

@ -397,6 +397,8 @@ ensure_color_update (MetaKmsUpdate *update,
void
meta_kms_crtc_gamma_free (MetaKmsCrtcGamma *gamma)
{
g_return_if_fail (gamma != NULL);
g_free (gamma->red);
g_free (gamma->green);
g_free (gamma->blue);
@ -422,6 +424,19 @@ meta_kms_crtc_gamma_new (int size,
return gamma;
}
gboolean
meta_kms_crtc_gamma_equal (MetaKmsCrtcGamma *gamma,
MetaKmsCrtcGamma *other_gamma)
{
return gamma->size == other_gamma->size &&
memcmp (gamma->red, other_gamma->red,
gamma->size * sizeof (uint16_t)) == 0 &&
memcmp (gamma->green, other_gamma->green,
gamma->size * sizeof (uint16_t)) == 0 &&
memcmp (gamma->blue, other_gamma->blue,
gamma->size * sizeof (uint16_t)) == 0;
}
void
meta_kms_update_set_crtc_gamma (MetaKmsUpdate *update,
MetaKmsCrtc *crtc,

View File

@ -105,19 +105,19 @@ assert_crtc_state_equals (const MetaKmsCrtcState *crtc_state1,
crtc_state2->drm_mode.name);
}
g_assert_cmpint (crtc_state1->gamma.size, ==, crtc_state1->gamma.size);
g_assert_cmpmem (crtc_state1->gamma.red,
crtc_state1->gamma.size * sizeof (uint16_t),
crtc_state2->gamma.red,
crtc_state2->gamma.size * sizeof (uint16_t));
g_assert_cmpmem (crtc_state1->gamma.green,
crtc_state1->gamma.size * sizeof (uint16_t),
crtc_state2->gamma.green,
crtc_state2->gamma.size * sizeof (uint16_t));
g_assert_cmpmem (crtc_state1->gamma.blue,
crtc_state1->gamma.size * sizeof (uint16_t),
crtc_state2->gamma.blue,
crtc_state2->gamma.size * sizeof (uint16_t));
g_assert_cmpint (crtc_state1->gamma.value->size, ==, crtc_state1->gamma.value->size);
g_assert_cmpmem (crtc_state1->gamma.value->red,
crtc_state1->gamma.value->size * sizeof (uint16_t),
crtc_state2->gamma.value->red,
crtc_state2->gamma.value->size * sizeof (uint16_t));
g_assert_cmpmem (crtc_state1->gamma.value->green,
crtc_state1->gamma.value->size * sizeof (uint16_t),
crtc_state2->gamma.value->green,
crtc_state2->gamma.value->size * sizeof (uint16_t));
g_assert_cmpmem (crtc_state1->gamma.value->blue,
crtc_state1->gamma.value->size * sizeof (uint16_t),
crtc_state2->gamma.value->blue,
crtc_state2->gamma.value->size * sizeof (uint16_t));
}
static int
@ -213,12 +213,15 @@ copy_crtc_state (const MetaKmsCrtcState *crtc_state)
g_assert_nonnull (crtc_state);
new_state = *crtc_state;
new_state.gamma.red = g_memdup2 (new_state.gamma.red,
new_state.gamma.size * sizeof (uint16_t));
new_state.gamma.green = g_memdup2 (new_state.gamma.green,
new_state.gamma.size * sizeof (uint16_t));
new_state.gamma.blue = g_memdup2 (new_state.gamma.blue,
new_state.gamma.size * sizeof (uint16_t));
new_state.gamma.value->red =
g_memdup2 (new_state.gamma.value->red,
new_state.gamma.value->size * sizeof (uint16_t));
new_state.gamma.value->green =
g_memdup2 (new_state.gamma.value->green,
new_state.gamma.value->size * sizeof (uint16_t));
new_state.gamma.value->blue =
g_memdup2 (new_state.gamma.value->blue,
new_state.gamma.value->size * sizeof (uint16_t));
return new_state;
}
@ -248,9 +251,9 @@ copy_connector_state (const MetaKmsConnectorState *connector_state)
static void
release_crtc_state (const MetaKmsCrtcState *crtc_state)
{
g_free (crtc_state->gamma.red);
g_free (crtc_state->gamma.green);
g_free (crtc_state->gamma.blue);
g_free (crtc_state->gamma.value->red);
g_free (crtc_state->gamma.value->green);
g_free (crtc_state->gamma.value->blue);
}
static void