diff options
Diffstat (limited to 'src/backends')
-rw-r--r-- | src/backends/native/meta-kms-crtc.c | 40 | ||||
-rw-r--r-- | src/backends/native/meta-kms-crtc.h | 13 | ||||
-rw-r--r-- | src/backends/native/meta-kms-impl-simple.c | 110 | ||||
-rw-r--r-- | src/backends/native/meta-kms-update-private.h | 11 | ||||
-rw-r--r-- | src/backends/native/meta-kms-update.c | 55 | ||||
-rw-r--r-- | src/backends/native/meta-kms-update.h | 7 | ||||
-rw-r--r-- | src/backends/native/meta-monitor-manager-kms.c | 101 |
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 |