diff --git a/src/backends/native/meta-crtc-kms.c b/src/backends/native/meta-crtc-kms.c index 1d3cf3de8..561407f48 100644 --- a/src/backends/native/meta-crtc-kms.c +++ b/src/backends/native/meta-crtc-kms.c @@ -248,8 +248,7 @@ meta_crtc_kms_set_gamma_lut (MetaCrtc *crtc, "Setting CRTC (%" G_GUINT64_FORMAT ") gamma to %s", meta_crtc_get_id (crtc), gamma_ramp_string); - crtc_gamma = meta_kms_crtc_gamma_new (kms_crtc, - lut->size, + crtc_gamma = meta_kms_crtc_gamma_new (lut->size, lut->red, lut->green, lut->blue); diff --git a/src/backends/native/meta-kms-crtc.c b/src/backends/native/meta-kms-crtc.c index 5512f6b42..1562a50aa 100644 --- a/src/backends/native/meta-kms-crtc.c +++ b/src/backends/native/meta-kms-crtc.c @@ -316,9 +316,10 @@ meta_kms_crtc_predict_state_in_impl (MetaKmsCrtc *crtc, crtc_color_updates = meta_kms_update_get_crtc_color_updates (update); for (l = crtc_color_updates; l; l = l->next) { - MetaKmsCrtcGamma *gamma = l->data; + MetaKmsCrtcColorUpdate *color_update = l->data; + MetaKmsCrtcGamma *gamma = color_update->gamma.state; - if (gamma->crtc != crtc) + if (color_update->crtc != crtc) continue; clear_gamma_state (&crtc->current_state); diff --git a/src/backends/native/meta-kms-crtc.h b/src/backends/native/meta-kms-crtc.h index 218bec9a1..83f1899eb 100644 --- a/src/backends/native/meta-kms-crtc.h +++ b/src/backends/native/meta-kms-crtc.h @@ -47,7 +47,6 @@ typedef struct _MetaKmsCrtcState typedef struct _MetaKmsCrtcGamma { - MetaKmsCrtc *crtc; int size; uint16_t *red; uint16_t *green; @@ -76,8 +75,7 @@ gboolean meta_kms_crtc_is_active (MetaKmsCrtc *crtc); void meta_kms_crtc_gamma_free (MetaKmsCrtcGamma *gamma); -MetaKmsCrtcGamma * meta_kms_crtc_gamma_new (MetaKmsCrtc *crtc, - int size, +MetaKmsCrtcGamma * meta_kms_crtc_gamma_new (int size, const uint16_t *red, const uint16_t *green, const uint16_t *blue); diff --git a/src/backends/native/meta-kms-impl-device-atomic.c b/src/backends/native/meta-kms-impl-device-atomic.c index 5ef5e550a..c884ac2e2 100644 --- a/src/backends/native/meta-kms-impl-device-atomic.c +++ b/src/backends/native/meta-kms-impl-device-atomic.c @@ -621,40 +621,45 @@ process_crtc_color_updates (MetaKmsImplDevice *impl_device, gpointer user_data, GError **error) { - MetaKmsCrtcGamma *gamma = update_entry; - MetaKmsCrtc *crtc = gamma->crtc; - struct drm_color_lut drm_color_lut[gamma->size]; - int i; - uint32_t color_lut_blob_id; + MetaKmsCrtcColorUpdate *color_update = update_entry; + MetaKmsCrtc *crtc = color_update->crtc; - for (i = 0; i < gamma->size; i++) + if (color_update->gamma.has_update) { - drm_color_lut[i].red = gamma->red[i]; - drm_color_lut[i].green = gamma->green[i]; - drm_color_lut[i].blue = gamma->blue[i]; + MetaKmsCrtcGamma *gamma = color_update->gamma.state; + struct drm_color_lut drm_color_lut[gamma->size]; + int i; + uint32_t color_lut_blob_id; + + for (i = 0; i < gamma->size; i++) + { + drm_color_lut[i].red = gamma->red[i]; + drm_color_lut[i].green = gamma->green[i]; + drm_color_lut[i].blue = gamma->blue[i]; + } + + color_lut_blob_id = store_new_blob (impl_device, + blob_ids, + drm_color_lut, + sizeof drm_color_lut, + error); + if (!color_lut_blob_id) + return FALSE; + + meta_topic (META_DEBUG_KMS, + "[atomic] Setting CRTC (%u, %s) gamma, size: %d", + meta_kms_crtc_get_id (crtc), + meta_kms_impl_device_get_path (impl_device), + gamma->size); + + if (!add_crtc_property (impl_device, + crtc, req, + META_KMS_CRTC_PROP_GAMMA_LUT, + color_lut_blob_id, + error)) + return FALSE; } - color_lut_blob_id = store_new_blob (impl_device, - blob_ids, - drm_color_lut, - sizeof drm_color_lut, - error); - if (!color_lut_blob_id) - return FALSE; - - meta_topic (META_DEBUG_KMS, - "[atomic] Setting CRTC (%u, %s) gamma, size: %d", - meta_kms_crtc_get_id (crtc), - meta_kms_impl_device_get_path (impl_device), - gamma->size); - - if (!add_crtc_property (impl_device, - crtc, req, - META_KMS_CRTC_PROP_GAMMA_LUT, - color_lut_blob_id, - error)) - return FALSE; - return TRUE; } diff --git a/src/backends/native/meta-kms-impl-device-simple.c b/src/backends/native/meta-kms-impl-device-simple.c index 3a378481c..8ccc2bfa3 100644 --- a/src/backends/native/meta-kms-impl-device-simple.c +++ b/src/backends/native/meta-kms-impl-device-simple.c @@ -508,30 +508,35 @@ process_crtc_color_updates (MetaKmsImplDevice *impl_device, gpointer update_entry, GError **error) { - MetaKmsCrtcGamma *gamma = update_entry; - MetaKmsCrtc *crtc = gamma->crtc; - int fd; - int ret; + MetaKmsCrtcColorUpdate *color_update = update_entry; + MetaKmsCrtc *crtc = color_update->crtc; - meta_topic (META_DEBUG_KMS, - "[simple] Setting CRTC %u (%s) gamma, size: %d", - meta_kms_crtc_get_id (crtc), - meta_kms_impl_device_get_path (impl_device), - gamma->size); - - fd = meta_kms_impl_device_get_fd (impl_device); - ret = drmModeCrtcSetGamma (fd, meta_kms_crtc_get_id (crtc), - gamma->size, - gamma->red, - gamma->green, - gamma->blue); - if (ret != 0) + if (color_update->gamma.has_update) { - g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-ret), - "drmModeCrtcSetGamma on CRTC %u failed: %s", - meta_kms_crtc_get_id (crtc), - g_strerror (-ret)); - return FALSE; + MetaKmsCrtcGamma *gamma = color_update->gamma.state; + int fd; + int ret; + + meta_topic (META_DEBUG_KMS, + "[simple] Setting CRTC %u (%s) gamma, size: %d", + meta_kms_crtc_get_id (crtc), + meta_kms_impl_device_get_path (impl_device), + gamma->size); + + fd = meta_kms_impl_device_get_fd (impl_device); + ret = drmModeCrtcSetGamma (fd, meta_kms_crtc_get_id (crtc), + gamma->size, + gamma->red, + gamma->green, + gamma->blue); + if (ret != 0) + { + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-ret), + "drmModeCrtcSetGamma on CRTC %u failed: %s", + meta_kms_crtc_get_id (crtc), + g_strerror (-ret)); + return FALSE; + } } return TRUE; diff --git a/src/backends/native/meta-kms-update-private.h b/src/backends/native/meta-kms-update-private.h index 29285ed5d..3a640cae9 100644 --- a/src/backends/native/meta-kms-update-private.h +++ b/src/backends/native/meta-kms-update-private.h @@ -23,10 +23,21 @@ #include #include +#include "backends/native/meta-kms-crtc.h" #include "backends/native/meta-kms-plane-private.h" #include "backends/native/meta-kms-types.h" #include "backends/native/meta-kms-update.h" +typedef struct _MetaKmsCrtcColorUpdate +{ + MetaKmsCrtc *crtc; + + struct { + gboolean has_update; + MetaKmsCrtcGamma *state; + } gamma; +} MetaKmsCrtcColorUpdate; + typedef struct _MetaKmsFeedback { MetaKmsFeedbackResult result; diff --git a/src/backends/native/meta-kms-update.c b/src/backends/native/meta-kms-update.c index 00c129bbe..8c7647059 100644 --- a/src/backends/native/meta-kms-update.c +++ b/src/backends/native/meta-kms-update.c @@ -370,6 +370,30 @@ meta_kms_update_set_max_bpc (MetaKmsUpdate *update, connector_update->max_bpc.has_update = TRUE; } +static MetaKmsCrtcColorUpdate * +ensure_color_update (MetaKmsUpdate *update, + MetaKmsCrtc *crtc) +{ + GList *l; + MetaKmsCrtcColorUpdate *color_update; + + for (l = update->crtc_color_updates; l; l = l->next) + { + color_update = l->data; + + if (color_update->crtc == crtc) + return color_update; + } + + color_update = g_new0 (MetaKmsCrtcColorUpdate, 1); + color_update->crtc = crtc; + + update->crtc_color_updates = g_list_prepend (update->crtc_color_updates, + color_update); + + return color_update; +} + void meta_kms_crtc_gamma_free (MetaKmsCrtcGamma *gamma) { @@ -380,8 +404,7 @@ meta_kms_crtc_gamma_free (MetaKmsCrtcGamma *gamma) } MetaKmsCrtcGamma * -meta_kms_crtc_gamma_new (MetaKmsCrtc *crtc, - int size, +meta_kms_crtc_gamma_new (int size, const uint16_t *red, const uint16_t *green, const uint16_t *blue) @@ -390,7 +413,6 @@ meta_kms_crtc_gamma_new (MetaKmsCrtc *crtc, gamma = g_new0 (MetaKmsCrtcGamma, 1); *gamma = (MetaKmsCrtcGamma) { - .crtc = crtc, .size = size, .red = g_memdup2 (red, size * sizeof (*red)), .green = g_memdup2 (green, size * sizeof (*green)), @@ -408,14 +430,21 @@ meta_kms_update_set_crtc_gamma (MetaKmsUpdate *update, const uint16_t *green, const uint16_t *blue) { - MetaKmsCrtcGamma *gamma; + MetaKmsCrtcColorUpdate *color_update; g_assert (!meta_kms_update_is_locked (update)); g_assert (meta_kms_crtc_get_device (crtc) == update->device); - gamma = meta_kms_crtc_gamma_new (crtc, size, red, green, blue); + color_update = ensure_color_update (update, crtc); + color_update->gamma.state = meta_kms_crtc_gamma_new (size, red, green, blue); + color_update->gamma.has_update = TRUE; +} - update->crtc_color_updates = g_list_prepend (update->crtc_color_updates, gamma); +static void +meta_kms_crtc_color_updates_free (MetaKmsCrtcColorUpdate *color_update) +{ + if (color_update->gamma.has_update) + g_clear_pointer (&color_update->gamma.state, meta_kms_crtc_gamma_free); } void @@ -700,7 +729,8 @@ meta_kms_update_free (MetaKmsUpdate *update) g_list_free_full (update->page_flip_listeners, (GDestroyNotify) meta_kms_page_flip_listener_free); g_list_free_full (update->connector_updates, g_free); - g_list_free_full (update->crtc_color_updates, (GDestroyNotify) meta_kms_crtc_gamma_free); + g_list_free_full (update->crtc_color_updates, + (GDestroyNotify) meta_kms_crtc_color_updates_free); g_clear_pointer (&update->custom_page_flip, meta_kms_custom_page_flip_free); g_free (update);