summaryrefslogtreecommitdiff
path: root/src/backends
diff options
context:
space:
mode:
Diffstat (limited to 'src/backends')
-rw-r--r--src/backends/native/meta-kms-crtc.c40
-rw-r--r--src/backends/native/meta-kms-crtc.h13
-rw-r--r--src/backends/native/meta-kms-impl-simple.c110
-rw-r--r--src/backends/native/meta-kms-update-private.h11
-rw-r--r--src/backends/native/meta-kms-update.c55
-rw-r--r--src/backends/native/meta-kms-update.h7
-rw-r--r--src/backends/native/meta-monitor-manager-kms.c101
7 files changed, 249 insertions, 88 deletions
diff --git a/src/backends/native/meta-kms-crtc.c b/src/backends/native/meta-kms-crtc.c
index 5006a1816..2ea0d51dd 100644
--- a/src/backends/native/meta-kms-crtc.c
+++ b/src/backends/native/meta-kms-crtc.c
@@ -69,6 +69,10 @@ meta_kms_crtc_read_state (MetaKmsCrtc *crtc,
MetaKmsImplDevice *impl_device,
drmModeCrtc *drm_crtc)
{
+ 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);
+
crtc->current_state = (MetaKmsCrtcState) {
.rect = {
.x = drm_crtc->x,
@@ -78,7 +82,20 @@ meta_kms_crtc_read_state (MetaKmsCrtc *crtc,
},
.is_drm_mode_valid = drm_crtc->mode_valid,
.drm_mode = drm_crtc->mode,
+ .gamma = {
+ .size = drm_crtc->gamma_size,
+ .red = g_new0 (unsigned short, drm_crtc->gamma_size),
+ .green = g_new0 (unsigned short, drm_crtc->gamma_size),
+ .blue = g_new0 (unsigned short, drm_crtc->gamma_size),
+ },
};
+
+ drmModeCrtcGetGamma (meta_kms_impl_device_get_fd (impl_device),
+ crtc->id,
+ drm_crtc->gamma_size,
+ crtc->current_state.gamma.red,
+ crtc->current_state.gamma.green,
+ crtc->current_state.gamma.blue);
}
void
@@ -118,3 +135,26 @@ static void
meta_kms_crtc_class_init (MetaKmsCrtcClass *klass)
{
}
+
+void
+meta_kms_crtc_get_gamma (MetaKmsCrtc *crtc,
+ gsize *size,
+ unsigned short **red,
+ unsigned short **green,
+ unsigned short **blue)
+{
+ unsigned int n_gamma_values = crtc->current_state.gamma.size;
+ unsigned int i;
+
+ *size = n_gamma_values;
+ *red = g_new0 (unsigned short, n_gamma_values);
+ *green = g_new0 (unsigned short, n_gamma_values);
+ *blue = g_new0 (unsigned short, n_gamma_values);
+
+ for (i = 0; i < n_gamma_values; i++)
+ {
+ *red[i] = crtc->current_state.gamma.red[i];
+ *green[i] = crtc->current_state.gamma.green[i];
+ *blue[i] = crtc->current_state.gamma.blue[i];
+ }
+}
diff --git a/src/backends/native/meta-kms-crtc.h b/src/backends/native/meta-kms-crtc.h
index 9d0ceadd9..645f4f956 100644
--- a/src/backends/native/meta-kms-crtc.h
+++ b/src/backends/native/meta-kms-crtc.h
@@ -36,6 +36,13 @@ typedef struct _MetaKmsCrtcState
uint32_t common_possible_crtcs;
uint32_t common_possible_clones;
uint32_t encoder_device_idxs;
+
+ struct {
+ unsigned int size;
+ unsigned short *red;
+ unsigned short *green;
+ unsigned short *blue;
+ } gamma;
} MetaKmsCrtcState;
#define META_TYPE_KMS_CRTC (meta_kms_crtc_get_type ())
@@ -51,4 +58,10 @@ uint32_t meta_kms_crtc_get_id (MetaKmsCrtc *crtc);
int meta_kms_crtc_get_idx (MetaKmsCrtc *crtc);
+void meta_kms_crtc_get_gamma (MetaKmsCrtc *crtc,
+ gsize *size,
+ unsigned short **red,
+ unsigned short **green,
+ unsigned short **blue);
+
#endif /* META_KMS_CRTC_H */
diff --git a/src/backends/native/meta-kms-impl-simple.c b/src/backends/native/meta-kms-impl-simple.c
index ddbee6b81..25643801c 100644
--- a/src/backends/native/meta-kms-impl-simple.c
+++ b/src/backends/native/meta-kms-impl-simple.c
@@ -62,6 +62,68 @@ G_DEFINE_TYPE (MetaKmsImplSimple, meta_kms_impl_simple,
static void
flush_postponed_page_flip_datas (MetaKmsImplSimple *impl_simple);
+static char *
+generate_gamma_ramp_string (size_t size,
+ unsigned short *red,
+ unsigned short *green,
+ unsigned short *blue)
+{
+ GString *string;
+ int color;
+
+ string = g_string_new ("[");
+ for (color = 0; color < 3; color++)
+ {
+ unsigned short **color_ptr;
+ char color_char;
+ size_t i;
+
+ switch (color)
+ {
+ case 0:
+ color_ptr = &red;
+ color_char = 'r';
+ break;
+ case 1:
+ color_ptr = &green;
+ color_char = 'g';
+ break;
+ case 2:
+ color_ptr = &blue;
+ color_char = 'b';
+ break;
+ }
+
+ g_string_append_printf (string, " %c: ", color_char);
+ for (i = 0; i < MIN (4, size); i++)
+ {
+ int j;
+
+ if (size > 4)
+ {
+ if (i == 2)
+ g_string_append (string, ",...");
+
+ if (i >= 2)
+ j = i + (size - 4);
+ else
+ j = i;
+ }
+ else
+ {
+ j = i;
+ }
+ g_string_append_printf (string, "%s%hu",
+ j == 0 ? "" : ",",
+ (*color_ptr)[i]);
+ }
+ }
+
+ g_string_append (string, " ]");
+
+ return g_string_free (string, FALSE);
+}
+
MetaKmsImplSimple *
meta_kms_impl_simple_new (MetaKms *kms,
GError **error)
@@ -104,6 +166,46 @@ process_connector_property (MetaKmsImpl *impl,
}
static gboolean
+process_crtc_gamma (MetaKmsImpl *impl,
+ MetaKmsUpdate *update,
+ MetaKmsCrtcGamma *crtc_gamma,
+ GError **error)
+{
+ MetaKmsCrtc *crtc = crtc_gamma->crtc;
+ MetaKmsDevice *device = meta_kms_crtc_get_device (crtc);
+ MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device);
+ g_autofree char *gamma_ramp_string = NULL;
+ uint32_t crtc_id;
+ int fd;
+ int ret;
+
+ fd = meta_kms_impl_device_get_fd (impl_device);
+ crtc_id = meta_kms_crtc_get_id (crtc);
+
+ gamma_ramp_string = generate_gamma_ramp_string (crtc_gamma->size,
+ crtc_gamma->red,
+ crtc_gamma->green,
+ crtc_gamma->blue);
+ g_debug ("Setting CRTC (%u) gamma to %s", crtc_id, gamma_ramp_string);
+
+ ret = drmModeCrtcSetGamma (fd,
+ crtc_id,
+ crtc_gamma->size,
+ crtc_gamma->red,
+ crtc_gamma->green,
+ crtc_gamma->blue);
+ if (ret != 0)
+ {
+ g_warning ("Failed to set CRTC (%u) Gamma: %s",
+ meta_kms_crtc_get_id (crtc),
+ g_strerror (-ret));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
process_plane_property (MetaKmsImpl *impl,
MetaKmsPlane *plane,
MetaKmsProperty *prop,
@@ -700,6 +802,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 *crtc_gamma = l->data;
+
+ if (!process_crtc_gamma (impl, update, crtc_gamma, error))
+ goto discard_page_flips;
+ }
+
for (l = meta_kms_update_get_mode_sets (update); l; l = l->next)
{
MetaKmsModeSet *mode_set = l->data;
diff --git a/src/backends/native/meta-kms-update-private.h b/src/backends/native/meta-kms-update-private.h
index bf3326ac4..54c1699d7 100644
--- a/src/backends/native/meta-kms-update-private.h
+++ b/src/backends/native/meta-kms-update-private.h
@@ -67,6 +67,15 @@ typedef struct _MetaKmsPageFlip
gpointer custom_page_flip_user_data;
} MetaKmsPageFlip;
+typedef struct _MetaKmsCrtcGamma
+{
+ MetaKmsCrtc *crtc;
+ gsize size;
+ unsigned short *red;
+ unsigned short *green;
+ unsigned short *blue;
+} MetaKmsCrtcGamma;
+
void meta_kms_update_set_connector_property (MetaKmsUpdate *update,
MetaKmsConnector *connector,
uint32_t prop_id,
@@ -84,6 +93,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 439e917ba..4e12189f5 100644
--- a/src/backends/native/meta-kms-update.c
+++ b/src/backends/native/meta-kms-update.c
@@ -32,6 +32,7 @@ struct _MetaKmsUpdate
GList *plane_assignments;
GList *page_flips;
GList *connector_properties;
+ GList *crtc_gammas;
};
static MetaKmsProperty *
@@ -71,6 +72,30 @@ meta_kms_mode_set_free (MetaKmsModeSet *mode_set)
g_free (mode_set);
}
+static void
+meta_kms_crtc_gamma_free (MetaKmsCrtcGamma *crtc_gamma)
+{
+ g_free (crtc_gamma->red);
+ g_free (crtc_gamma->green);
+ g_free (crtc_gamma->blue);
+ g_free (crtc_gamma);
+}
+
+static unsigned short *
+copy_unsigned_short_array (unsigned short *values,
+ gsize n_values)
+{
+ unsigned short *copy;
+
+ if (!values)
+ return NULL;
+
+ copy = g_new (unsigned short, n_values);
+ memcpy (copy, values, sizeof (unsigned short) * n_values);
+
+ return copy;
+}
+
MetaKmsPlaneAssignment *
meta_kms_update_assign_plane (MetaKmsUpdate *update,
MetaKmsCrtc *crtc,
@@ -97,6 +122,28 @@ meta_kms_update_assign_plane (MetaKmsUpdate *update,
}
void
+meta_kms_update_set_crtc_gamma (MetaKmsUpdate *update,
+ MetaKmsCrtc *crtc,
+ gsize size,
+ unsigned short *red,
+ unsigned short *green,
+ unsigned short *blue)
+{
+ MetaKmsCrtcGamma *crtc_gamma;
+
+ crtc_gamma = g_new0 (MetaKmsCrtcGamma, 1);
+ *crtc_gamma = (MetaKmsCrtcGamma) {
+ .crtc = crtc,
+ .size = size,
+ .red = copy_unsigned_short_array (red, size),
+ .green = copy_unsigned_short_array (green, size),
+ .blue = copy_unsigned_short_array (blue, size),
+ };
+
+ update->crtc_gammas = g_list_prepend (update->crtc_gammas, crtc_gamma);
+}
+
+void
meta_kms_update_mode_set (MetaKmsUpdate *update,
MetaKmsCrtc *crtc,
GList *connectors,
@@ -210,6 +257,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)
{
@@ -231,6 +284,8 @@ 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-kms-update.h b/src/backends/native/meta-kms-update.h
index fc7d83f33..e237ef26f 100644
--- a/src/backends/native/meta-kms-update.h
+++ b/src/backends/native/meta-kms-update.h
@@ -65,6 +65,13 @@ MetaKmsPlaneAssignment * meta_kms_update_assign_plane (MetaKmsUpdate *upd
MetaFixed16Rectangle src_rect,
MetaFixed16Rectangle dst_rect);
+void meta_kms_update_set_crtc_gamma (MetaKmsUpdate *update,
+ MetaKmsCrtc *crtc,
+ gsize size,
+ unsigned short *red,
+ unsigned short *green,
+ unsigned short *blue);
+
void meta_kms_update_page_flip (MetaKmsUpdate *update,
MetaKmsCrtc *crtc,
const MetaKmsPageFlipFeedback *feedback,
diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c
index 7f094ab42..4b24938cf 100644
--- a/src/backends/native/meta-monitor-manager-kms.c
+++ b/src/backends/native/meta-monitor-manager-kms.c
@@ -367,82 +367,8 @@ 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;
-
- kms_crtc = drmModeGetCrtc (kms_fd, crtc->crtc_id);
-
- *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);
-}
-
-static char *
-generate_gamma_ramp_string (size_t size,
- unsigned short *red,
- unsigned short *green,
- unsigned short *blue)
-{
- GString *string;
- int color;
-
- string = g_string_new ("[");
- for (color = 0; color < 3; color++)
- {
- unsigned short **color_ptr;
- char color_char;
- size_t i;
-
- switch (color)
- {
- case 0:
- color_ptr = &red;
- color_char = 'r';
- break;
- case 1:
- color_ptr = &green;
- color_char = 'g';
- break;
- case 2:
- color_ptr = &blue;
- color_char = 'b';
- break;
- }
-
- g_string_append_printf (string, " %c: ", color_char);
- for (i = 0; i < MIN (4, size); i++)
- {
- int j;
-
- if (size > 4)
- {
- if (i == 2)
- g_string_append (string, ",...");
-
- if (i >= 2)
- j = i + (size - 4);
- else
- j = i;
- }
- else
- {
- j = i;
- }
- g_string_append_printf (string, "%s%hu",
- j == 0 ? "" : ",",
- (*color_ptr)[i]);
- }
- }
-
- g_string_append (string, " ]");
-
- return g_string_free (string, FALSE);
+ meta_kms_crtc_get_gamma (meta_crtc_kms_get_kms_crtc (crtc),
+ size, red, green, blue);
}
static void
@@ -453,20 +379,19 @@ 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));
- g_autofree char *gamma_ramp_string = NULL;
- int ret;
+ MetaBackend *backend = meta_monitor_manager_get_backend (manager);
+ MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
+ MetaKms *kms = meta_backend_native_get_kms (backend_native);
+ 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);
+ kms_update = meta_kms_ensure_pending_update (kms);
+ meta_kms_update_set_crtc_gamma (kms_update,
+ meta_crtc_kms_get_kms_crtc (crtc),
+ size, red, green, blue);
- 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));
- }
+ if (!meta_kms_post_pending_update_sync (kms, &error))
+ g_warning ("Failed to set CRTC gamma: %s", error->message);
}
static void