[mutter] monitor-manager/kms: Use KMS abstraction to get and set CRTC gamma
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] monitor-manager/kms: Use KMS abstraction to get and set CRTC gamma
- Date: Mon, 24 Jun 2019 13:42:41 +0000 (UTC)
commit 68f18f1fe9dc62667a42afa2c12905780e7db098
Author: Jonas Ã…dahl <jadahl gmail com>
Date: Fri May 3 19:20:21 2019 +0200
monitor-manager/kms: Use KMS abstraction to get and set CRTC gamma
Still doesn't synchronize with frame drawing, but no point in doing that
until gamma is managed by mutter itself and not gnome-settings-daemon.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/634
src/backends/native/meta-kms-crtc.c | 58 ++++++++++++++++++++++++++
src/backends/native/meta-kms-crtc.h | 15 +++++++
src/backends/native/meta-kms-impl-simple.c | 37 ++++++++++++++++
src/backends/native/meta-kms-update-private.h | 18 ++++++++
src/backends/native/meta-kms-update.c | 41 ++++++++++++++++++
src/backends/native/meta-monitor-manager-kms.c | 43 +++++++++----------
6 files changed, 191 insertions(+), 21 deletions(-)
---
diff --git a/src/backends/native/meta-kms-crtc.c b/src/backends/native/meta-kms-crtc.c
index 5006a1816..2dd2b8da4 100644
--- a/src/backends/native/meta-kms-crtc.c
+++ b/src/backends/native/meta-kms-crtc.c
@@ -40,6 +40,17 @@ struct _MetaKmsCrtc
G_DEFINE_TYPE (MetaKmsCrtc, meta_kms_crtc, G_TYPE_OBJECT)
+void
+meta_kms_crtc_set_gamma (MetaKmsCrtc *crtc,
+ MetaKmsUpdate *update,
+ int size,
+ const uint16_t *red,
+ const uint16_t *green,
+ const uint16_t *blue)
+{
+ meta_kms_update_set_crtc_gamma (update, crtc, size, red, green, blue);
+}
+
MetaKmsDevice *
meta_kms_crtc_get_device (MetaKmsCrtc *crtc)
{
@@ -64,6 +75,36 @@ meta_kms_crtc_get_idx (MetaKmsCrtc *crtc)
return crtc->idx;
}
+static void
+read_gamma_state (MetaKmsCrtc *crtc,
+ MetaKmsImplDevice *impl_device,
+ drmModeCrtc *drm_crtc)
+{
+ MetaKmsCrtcState *current_state = &crtc->current_state;
+
+ if (current_state->gamma.size != drm_crtc->gamma_size)
+ {
+ current_state->gamma.size = drm_crtc->gamma_size;
+
+ current_state->gamma.red = g_realloc_n (current_state->gamma.red,
+ drm_crtc->gamma_size,
+ sizeof (uint16_t));
+ current_state->gamma.green = g_realloc_n (current_state->gamma.green,
+ drm_crtc->gamma_size,
+ sizeof (uint16_t));
+ current_state->gamma.blue = g_realloc_n (current_state->gamma.blue,
+ drm_crtc->gamma_size,
+ sizeof (uint16_t));
+ }
+
+ drmModeCrtcGetGamma (meta_kms_impl_device_get_fd (impl_device),
+ crtc->id,
+ current_state->gamma.size,
+ current_state->gamma.red,
+ current_state->gamma.green,
+ current_state->gamma.blue);
+}
+
static void
meta_kms_crtc_read_state (MetaKmsCrtc *crtc,
MetaKmsImplDevice *impl_device,
@@ -79,6 +120,8 @@ meta_kms_crtc_read_state (MetaKmsCrtc *crtc,
.is_drm_mode_valid = drm_crtc->mode_valid,
.drm_mode = drm_crtc->mode,
};
+
+ read_gamma_state (crtc, impl_device, drm_crtc);
}
void
@@ -109,6 +152,18 @@ meta_kms_crtc_new (MetaKmsImplDevice *impl_device,
return crtc;
}
+static void
+meta_kms_crtc_finalize (GObject *object)
+{
+ MetaKmsCrtc *crtc = META_KMS_CRTC (object);
+
+ g_clear_pointer (&crtc->current_state.gamma.red, g_free);
+ g_clear_pointer (&crtc->current_state.gamma.green, g_free);
+ g_clear_pointer (&crtc->current_state.gamma.blue, g_free);
+
+ G_OBJECT_CLASS (meta_kms_crtc_parent_class)->finalize (object);
+}
+
static void
meta_kms_crtc_init (MetaKmsCrtc *crtc)
{
@@ -117,4 +172,7 @@ meta_kms_crtc_init (MetaKmsCrtc *crtc)
static void
meta_kms_crtc_class_init (MetaKmsCrtcClass *klass)
{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = meta_kms_crtc_finalize;
}
diff --git a/src/backends/native/meta-kms-crtc.h b/src/backends/native/meta-kms-crtc.h
index 9d0ceadd9..39a89a751 100644
--- a/src/backends/native/meta-kms-crtc.h
+++ b/src/backends/native/meta-kms-crtc.h
@@ -36,6 +36,14 @@ typedef struct _MetaKmsCrtcState
uint32_t common_possible_crtcs;
uint32_t common_possible_clones;
uint32_t encoder_device_idxs;
+
+ struct {
+ uint16_t *red;
+ uint16_t *green;
+ uint16_t *blue;
+
+ int size;
+ } gamma;
} MetaKmsCrtcState;
#define META_TYPE_KMS_CRTC (meta_kms_crtc_get_type ())
@@ -43,6 +51,13 @@ G_DECLARE_FINAL_TYPE (MetaKmsCrtc, meta_kms_crtc,
META, KMS_CRTC,
GObject)
+void meta_kms_crtc_set_gamma (MetaKmsCrtc *crtc,
+ MetaKmsUpdate *update,
+ int size,
+ const uint16_t *red,
+ const uint16_t *green,
+ const uint16_t *blue);
+
MetaKmsDevice * meta_kms_crtc_get_device (MetaKmsCrtc *crtc);
const MetaKmsCrtcState * meta_kms_crtc_get_current_state (MetaKmsCrtc *crtc);
diff --git a/src/backends/native/meta-kms-impl-simple.c b/src/backends/native/meta-kms-impl-simple.c
index b62599354..929dd950a 100644
--- a/src/backends/native/meta-kms-impl-simple.c
+++ b/src/backends/native/meta-kms-impl-simple.c
@@ -284,6 +284,35 @@ process_mode_set (MetaKmsImpl *impl,
return TRUE;
}
+static gboolean
+process_crtc_gamma (MetaKmsImpl *impl,
+ MetaKmsCrtcGamma *gamma,
+ GError **error)
+{
+ MetaKmsCrtc *crtc = gamma->crtc;
+ MetaKmsDevice *device = meta_kms_crtc_get_device (crtc);
+ MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device);
+ int fd;
+ int ret;
+
+ 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;
+}
+
static gboolean
is_timestamp_earlier_than (uint64_t ts1,
uint64_t ts2)
@@ -708,6 +737,14 @@ meta_kms_impl_simple_process_update (MetaKmsImpl *impl,
goto discard_page_flips;
}
+ for (l = meta_kms_update_get_crtc_gammas (update); l; l = l->next)
+ {
+ MetaKmsCrtcGamma *gamma = l->data;
+
+ if (!process_crtc_gamma (impl, gamma, error))
+ goto discard_page_flips;
+ }
+
for (l = meta_kms_update_get_page_flips (update); l; l = l->next)
{
MetaKmsPageFlip *page_flip = l->data;
diff --git a/src/backends/native/meta-kms-update-private.h b/src/backends/native/meta-kms-update-private.h
index 32bb68bb8..fe320e9b3 100644
--- a/src/backends/native/meta-kms-update-private.h
+++ b/src/backends/native/meta-kms-update-private.h
@@ -59,6 +59,15 @@ typedef struct _MetaKmsConnectorProperty
uint64_t value;
} MetaKmsConnectorProperty;
+typedef struct _MetaKmsCrtcGamma
+{
+ MetaKmsCrtc *crtc;
+ int size;
+ uint16_t *red;
+ uint16_t *green;
+ uint16_t *blue;
+} MetaKmsCrtcGamma;
+
typedef struct _MetaKmsPageFlip
{
MetaKmsCrtc *crtc;
@@ -77,6 +86,13 @@ void meta_kms_update_set_connector_property (MetaKmsUpdate *update,
uint32_t prop_id,
uint64_t value);
+void meta_kms_update_set_crtc_gamma (MetaKmsUpdate *update,
+ MetaKmsCrtc *crtc,
+ int size,
+ const uint16_t *red,
+ const uint16_t *green,
+ const uint16_t *blue);
+
void meta_kms_plane_assignment_set_plane_property (MetaKmsPlaneAssignment *plane_assignment,
uint32_t prop_id,
uint64_t value);
@@ -89,6 +105,8 @@ GList * meta_kms_update_get_page_flips (MetaKmsUpdate *update);
GList * meta_kms_update_get_connector_properties (MetaKmsUpdate *update);
+GList * meta_kms_update_get_crtc_gammas (MetaKmsUpdate *update);
+
gboolean meta_kms_update_has_mode_set (MetaKmsUpdate *update);
#endif /* META_KMS_UPDATE_PRIVATE_H */
diff --git a/src/backends/native/meta-kms-update.c b/src/backends/native/meta-kms-update.c
index 95b2464b6..b6658e7c8 100644
--- a/src/backends/native/meta-kms-update.c
+++ b/src/backends/native/meta-kms-update.c
@@ -34,6 +34,7 @@ struct _MetaKmsUpdate
GList *plane_assignments;
GList *page_flips;
GList *connector_properties;
+ GList *crtc_gammas;
};
static MetaKmsProperty *
@@ -142,6 +143,39 @@ meta_kms_update_set_connector_property (MetaKmsUpdate *update,
prop);
}
+static void
+meta_kms_crtc_gamma_free (MetaKmsCrtcGamma *gamma)
+{
+ g_free (gamma->red);
+ g_free (gamma->green);
+ g_free (gamma->blue);
+ g_free (gamma);
+}
+
+void
+meta_kms_update_set_crtc_gamma (MetaKmsUpdate *update,
+ MetaKmsCrtc *crtc,
+ int size,
+ const uint16_t *red,
+ const uint16_t *green,
+ const uint16_t *blue)
+{
+ MetaKmsCrtcGamma *gamma;
+
+ g_assert (!meta_kms_update_is_sealed (update));
+
+ gamma = g_new0 (MetaKmsCrtcGamma, 1);
+ *gamma = (MetaKmsCrtcGamma) {
+ .crtc = crtc,
+ .size = size,
+ .red = g_memdup (red, size * sizeof *red),
+ .green = g_memdup (green, size * sizeof *green),
+ .blue = g_memdup (blue, size * sizeof *blue),
+ };
+
+ update->crtc_gammas = g_list_prepend (update->crtc_gammas, gamma);
+}
+
void
meta_kms_update_page_flip (MetaKmsUpdate *update,
MetaKmsCrtc *crtc,
@@ -225,6 +259,12 @@ meta_kms_update_get_connector_properties (MetaKmsUpdate *update)
return update->connector_properties;
}
+GList *
+meta_kms_update_get_crtc_gammas (MetaKmsUpdate *update)
+{
+ return update->crtc_gammas;
+}
+
gboolean
meta_kms_update_has_mode_set (MetaKmsUpdate *update)
{
@@ -258,6 +298,7 @@ meta_kms_update_free (MetaKmsUpdate *update)
(GDestroyNotify) meta_kms_mode_set_free);
g_list_free_full (update->page_flips, g_free);
g_list_free_full (update->connector_properties, g_free);
+ g_list_free_full (update->crtc_gammas, (GDestroyNotify) meta_kms_crtc_gamma_free);
g_free (update);
}
diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c
index 7f094ab42..9bac13576 100644
--- a/src/backends/native/meta-monitor-manager-kms.c
+++ b/src/backends/native/meta-monitor-manager-kms.c
@@ -367,20 +367,16 @@ meta_monitor_manager_kms_get_crtc_gamma (MetaMonitorManager *manager,
unsigned short **green,
unsigned short **blue)
{
- MetaGpu *gpu = meta_crtc_get_gpu (crtc);
- int kms_fd = meta_gpu_kms_get_fd (META_GPU_KMS (gpu));
- drmModeCrtc *kms_crtc;
+ MetaKmsCrtc *kms_crtc;
+ const MetaKmsCrtcState *crtc_state;
- kms_crtc = drmModeGetCrtc (kms_fd, crtc->crtc_id);
+ kms_crtc = meta_crtc_kms_get_kms_crtc (crtc);
+ crtc_state = meta_kms_crtc_get_current_state (kms_crtc);
- *size = kms_crtc->gamma_size;
- *red = g_new (unsigned short, *size);
- *green = g_new (unsigned short, *size);
- *blue = g_new (unsigned short, *size);
-
- drmModeCrtcGetGamma (kms_fd, crtc->crtc_id, *size, *red, *green, *blue);
-
- drmModeFreeCrtc (kms_crtc);
+ *size = crtc_state->gamma.size;
+ *red = g_memdup (crtc_state->gamma.red, *size * sizeof **red);
+ *green = g_memdup (crtc_state->gamma.green, *size * sizeof **green);
+ *blue = g_memdup (crtc_state->gamma.blue, *size * sizeof **blue);
}
static char *
@@ -453,20 +449,25 @@ meta_monitor_manager_kms_set_crtc_gamma (MetaMonitorManager *manager,
unsigned short *green,
unsigned short *blue)
{
- MetaGpu *gpu = meta_crtc_get_gpu (crtc);
- int kms_fd = meta_gpu_kms_get_fd (META_GPU_KMS (gpu));
+ MetaBackend *backend = meta_monitor_manager_get_backend (manager);
+ MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
+ MetaKms *kms = meta_backend_native_get_kms (backend_native);
+ MetaKmsCrtc *kms_crtc;
g_autofree char *gamma_ramp_string = NULL;
- int ret;
+ MetaKmsUpdate *kms_update;
+ g_autoptr (GError) error = NULL;
gamma_ramp_string = generate_gamma_ramp_string (size, red, green, blue);
g_debug ("Setting CRTC (%ld) gamma to %s", crtc->crtc_id, gamma_ramp_string);
- ret = drmModeCrtcSetGamma (kms_fd, crtc->crtc_id, size, red, green, blue);
- if (ret != 0)
- {
- g_warning ("Failed to set CRTC (%ld) Gamma: %s",
- crtc->crtc_id, g_strerror (-ret));
- }
+ kms_update = meta_kms_ensure_pending_update (kms);
+
+ kms_crtc = meta_crtc_kms_get_kms_crtc (crtc);
+ meta_kms_crtc_set_gamma (kms_crtc, kms_update,
+ size, red, green, blue);
+
+ if (!meta_kms_post_pending_update_sync (kms, &error))
+ g_warning ("Failed to CRTC gamma: %s", error->message);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]