diff --git a/src/backends/native/meta-cursor-renderer-native.c b/src/backends/native/meta-cursor-renderer-native.c index ccf0434ee..c9de9436e 100644 --- a/src/backends/native/meta-cursor-renderer-native.c +++ b/src/backends/native/meta-cursor-renderer-native.c @@ -383,7 +383,6 @@ typedef struct MetaLogicalMonitor *in_logical_monitor; graphene_rect_t in_local_cursor_rect; MetaCursorSprite *in_cursor_sprite; - MetaKmsUpdate *in_kms_update; gboolean out_painted; } UpdateCrtcCursorData; @@ -401,6 +400,10 @@ update_monitor_crtc_cursor (MetaMonitor *monitor, MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (cursor_renderer_native); MetaCrtc *crtc; + MetaGpuKms *gpu_kms; + MetaKmsDevice *kms_device; + MetaKms *kms; + MetaKmsUpdate *kms_update; MetaMonitorTransform transform; const MetaCrtcModeInfo *crtc_mode_info; graphene_rect_t scaled_crtc_rect; @@ -446,6 +449,10 @@ update_monitor_crtc_cursor (MetaMonitor *monitor, }; crtc = meta_output_get_assigned_crtc (monitor_crtc_mode->output); + gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc)); + kms_device = meta_gpu_kms_get_kms_device (gpu_kms); + kms = meta_kms_device_get_kms (kms_device); + kms_update = meta_kms_ensure_pending_update (kms, kms_device); if (priv->has_hw_cursor && graphene_rect_intersection (&scaled_crtc_rect, @@ -487,7 +494,7 @@ update_monitor_crtc_cursor (MetaMonitor *monitor, &cursor_rect); set_crtc_cursor (data->in_cursor_renderer_native, - data->in_kms_update, + kms_update, META_CRTC_KMS (crtc), cursor_rect.x, cursor_rect.y, @@ -498,7 +505,7 @@ update_monitor_crtc_cursor (MetaMonitor *monitor, else { unset_crtc_cursor (data->in_cursor_renderer_native, - data->in_kms_update, + kms_update, META_CRTC_KMS (crtc)); } @@ -533,15 +540,12 @@ update_hw_cursor (MetaCursorRendererNative *native, MetaKms *kms = meta_backend_native_get_kms (backend_native); MetaMonitorManager *monitor_manager = meta_backend_get_monitor_manager (backend); - MetaKmsUpdate *kms_update; GList *logical_monitors; GList *l; graphene_rect_t rect; gboolean painted = FALSE; g_autoptr (MetaKmsFeedback) feedback = NULL; - kms_update = meta_kms_ensure_pending_update (kms); - if (cursor_sprite) rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite); else @@ -567,7 +571,6 @@ update_hw_cursor (MetaCursorRendererNative *native, .size = rect.size }, .in_cursor_sprite = cursor_sprite, - .in_kms_update = kms_update, }; monitors = meta_logical_monitor_get_monitors (logical_monitor); @@ -586,7 +589,7 @@ update_hw_cursor (MetaCursorRendererNative *native, painted = painted || data.out_painted; } - feedback = meta_kms_post_pending_update_sync (kms); + feedback = meta_kms_post_pending_updates_sync (kms); if (meta_kms_feedback_get_result (feedback) != META_KMS_FEEDBACK_PASSED) { for (l = meta_kms_feedback_get_failed_planes (feedback); l; l = l->next) diff --git a/src/backends/native/meta-kms-device.c b/src/backends/native/meta-kms-device.c index a8abd8842..4179c623c 100644 --- a/src/backends/native/meta-kms-device.c +++ b/src/backends/native/meta-kms-device.c @@ -55,6 +55,12 @@ struct _MetaKmsDevice G_DEFINE_TYPE (MetaKmsDevice, meta_kms_device, G_TYPE_OBJECT); +MetaKms * +meta_kms_device_get_kms (MetaKmsDevice *device) +{ + return device->kms; +} + MetaKmsImplDevice * meta_kms_device_get_impl_device (MetaKmsDevice *device) { diff --git a/src/backends/native/meta-kms-device.h b/src/backends/native/meta-kms-device.h index bd2e85667..0b7c10273 100644 --- a/src/backends/native/meta-kms-device.h +++ b/src/backends/native/meta-kms-device.h @@ -29,6 +29,8 @@ G_DECLARE_FINAL_TYPE (MetaKmsDevice, meta_kms_device, META, KMS_DEVICE, GObject) +MetaKms * meta_kms_device_get_kms (MetaKmsDevice *device); + int meta_kms_device_leak_fd (MetaKmsDevice *device); const char * meta_kms_device_get_path (MetaKmsDevice *device); diff --git a/src/backends/native/meta-kms-update-private.h b/src/backends/native/meta-kms-update-private.h index 8d67b3110..30290c3be 100644 --- a/src/backends/native/meta-kms-update-private.h +++ b/src/backends/native/meta-kms-update-private.h @@ -111,6 +111,8 @@ void meta_kms_update_seal (MetaKmsUpdate *update); gboolean meta_kms_update_is_sealed (MetaKmsUpdate *update); +MetaKmsDevice * meta_kms_update_get_device (MetaKmsUpdate *update); + void meta_kms_plane_assignment_set_rotation (MetaKmsPlaneAssignment *plane_assignment, uint64_t rotation); diff --git a/src/backends/native/meta-kms-update.c b/src/backends/native/meta-kms-update.c index 8d9b4002e..226ede016 100644 --- a/src/backends/native/meta-kms-update.c +++ b/src/backends/native/meta-kms-update.c @@ -23,11 +23,15 @@ #include "backends/native/meta-kms-update-private.h" #include "backends/meta-display-config-shared.h" +#include "backends/native/meta-kms-crtc.h" +#include "backends/native/meta-kms-connector.h" #include "backends/native/meta-kms-mode-private.h" #include "backends/native/meta-kms-plane.h" struct _MetaKmsUpdate { + MetaKmsDevice *device; + gboolean is_sealed; MetaPowerSave power_save; @@ -143,6 +147,8 @@ meta_kms_update_assign_plane (MetaKmsUpdate *update, MetaKmsPlaneAssignment *plane_assignment; g_assert (!meta_kms_update_is_sealed (update)); + g_assert (meta_kms_crtc_get_device (crtc) == update->device); + g_assert (meta_kms_plane_get_device (plane) == update->device); plane_assignment = g_new0 (MetaKmsPlaneAssignment, 1); *plane_assignment = (MetaKmsPlaneAssignment) { @@ -169,6 +175,8 @@ meta_kms_update_unassign_plane (MetaKmsUpdate *update, MetaKmsPlaneAssignment *plane_assignment; g_assert (!meta_kms_update_is_sealed (update)); + g_assert (meta_kms_crtc_get_device (crtc) == update->device); + g_assert (meta_kms_plane_get_device (plane) == update->device); plane_assignment = g_new0 (MetaKmsPlaneAssignment, 1); *plane_assignment = (MetaKmsPlaneAssignment) { @@ -193,6 +201,7 @@ meta_kms_update_mode_set (MetaKmsUpdate *update, MetaKmsModeSet *mode_set; g_assert (!meta_kms_update_is_sealed (update)); + g_assert (meta_kms_crtc_get_device (crtc) == update->device); mode_set = g_new0 (MetaKmsModeSet, 1); *mode_set = (MetaKmsModeSet) { @@ -237,6 +246,7 @@ meta_kms_update_set_underscanning (MetaKmsUpdate *update, MetaKmsConnectorUpdate *connector_update; g_assert (!meta_kms_update_is_sealed (update)); + g_assert (meta_kms_connector_get_device (connector) == update->device); connector_update = ensure_connector_update (update, connector); connector_update->underscanning.has_update = TRUE; @@ -252,6 +262,7 @@ meta_kms_update_unset_underscanning (MetaKmsUpdate *update, MetaKmsConnectorUpdate *connector_update; g_assert (!meta_kms_update_is_sealed (update)); + g_assert (meta_kms_connector_get_device (connector) == update->device); connector_update = ensure_connector_update (update, connector); connector_update->underscanning.has_update = TRUE; @@ -266,6 +277,7 @@ meta_kms_update_set_dpms_state (MetaKmsUpdate *update, MetaKmsConnectorUpdate *connector_update; g_assert (!meta_kms_update_is_sealed (update)); + g_assert (meta_kms_connector_get_device (connector) == update->device); connector_update = ensure_connector_update (update, connector); connector_update->dpms.has_update = TRUE; @@ -292,6 +304,7 @@ meta_kms_update_set_crtc_gamma (MetaKmsUpdate *update, MetaKmsCrtcGamma *gamma; g_assert (!meta_kms_update_is_sealed (update)); + g_assert (meta_kms_crtc_get_device (crtc) == update->device); gamma = g_new0 (MetaKmsCrtcGamma, 1); *gamma = (MetaKmsCrtcGamma) { @@ -315,6 +328,7 @@ meta_kms_update_page_flip (MetaKmsUpdate *update, MetaKmsPageFlip *page_flip; g_assert (!meta_kms_update_is_sealed (update)); + g_assert (meta_kms_crtc_get_device (crtc) == update->device); page_flip = g_new0 (MetaKmsPageFlip, 1); *page_flip = (MetaKmsPageFlip) { @@ -338,6 +352,7 @@ meta_kms_update_custom_page_flip (MetaKmsUpdate *update, MetaKmsPageFlip *page_flip; g_assert (!meta_kms_update_is_sealed (update)); + g_assert (meta_kms_crtc_get_device (crtc) == update->device); page_flip = g_new0 (MetaKmsPageFlip, 1); *page_flip = (MetaKmsPageFlip) { @@ -430,10 +445,21 @@ meta_kms_update_is_sealed (MetaKmsUpdate *update) return update->is_sealed; } -MetaKmsUpdate * -meta_kms_update_new (void) +MetaKmsDevice * +meta_kms_update_get_device (MetaKmsUpdate *update) { - return g_new0 (MetaKmsUpdate, 1); + return update->device; +} + +MetaKmsUpdate * +meta_kms_update_new (MetaKmsDevice *device) +{ + MetaKmsUpdate *update; + + update = g_new0 (MetaKmsUpdate, 1); + update->device = device; + + return update; } void diff --git a/src/backends/native/meta-kms-update.h b/src/backends/native/meta-kms-update.h index 71fc01271..65b510f97 100644 --- a/src/backends/native/meta-kms-update.h +++ b/src/backends/native/meta-kms-update.h @@ -81,7 +81,7 @@ GList * meta_kms_feedback_get_failed_planes (MetaKmsFeedback *feedback); const GError * meta_kms_feedback_get_error (MetaKmsFeedback *feedback); -MetaKmsUpdate * meta_kms_update_new (void); +MetaKmsUpdate * meta_kms_update_new (MetaKmsDevice *device); void meta_kms_update_free (MetaKmsUpdate *update); diff --git a/src/backends/native/meta-kms.c b/src/backends/native/meta-kms.c index 957cc274e..1a7afe2ad 100644 --- a/src/backends/native/meta-kms.c +++ b/src/backends/native/meta-kms.c @@ -95,7 +95,8 @@ * posted. An update consists of plane assignments, mode sets and KMS object * property entries. The user adds updates to the object, and then posts it via * MetaKms. It will then be processed by the MetaKms backend (See - * #MetaKmsImpl), potentially atomically. + * #MetaKmsImpl), potentially atomically. Each #MetaKmsUpdate deals with + * updating a single device. * * * There are also these private objects, without public facing API: @@ -174,7 +175,7 @@ struct _MetaKms GList *devices; - MetaKmsUpdate *pending_update; + GList *pending_updates; GList *pending_callbacks; guint callback_source_id; @@ -183,18 +184,36 @@ struct _MetaKms G_DEFINE_TYPE (MetaKms, meta_kms, G_TYPE_OBJECT) MetaKmsUpdate * -meta_kms_ensure_pending_update (MetaKms *kms) +meta_kms_ensure_pending_update (MetaKms *kms, + MetaKmsDevice *device) { - if (!kms->pending_update) - kms->pending_update = meta_kms_update_new (); + MetaKmsUpdate *update; - return meta_kms_get_pending_update (kms); + update = meta_kms_get_pending_update (kms, device); + if (update) + return update; + + update = meta_kms_update_new (device); + kms->pending_updates = g_list_prepend (kms->pending_updates, update); + + return update; } MetaKmsUpdate * -meta_kms_get_pending_update (MetaKms *kms) +meta_kms_get_pending_update (MetaKms *kms, + MetaKmsDevice *device) { - return kms->pending_update; + GList *l; + + for (l = kms->pending_updates; l; l = l->next) + { + MetaKmsUpdate *update = l->data; + + if (meta_kms_update_get_device (update) == device) + return update; + } + + return NULL; } static void @@ -208,40 +227,84 @@ meta_kms_predict_states_in_impl (MetaKms *kms, update); } -static gpointer -meta_kms_process_update_in_impl (MetaKmsImpl *impl, - gpointer user_data, - GError **error) +static MetaKmsFeedback * +combine_feedbacks (MetaKmsFeedback *feedback, + MetaKmsFeedback *other_feedback) { - g_autoptr (MetaKmsUpdate) update = user_data; - MetaKmsFeedback *feedback; + GList *failed_planes; + MetaKmsFeedback *new_feedback; + const GError *error; - feedback = meta_kms_impl_process_update (impl, update); - meta_kms_predict_states_in_impl (meta_kms_impl_get_kms (impl), update); + if (!feedback) + return other_feedback; + + failed_planes = + g_list_concat (meta_kms_feedback_get_failed_planes (feedback), + meta_kms_feedback_get_failed_planes (other_feedback)); + error = meta_kms_feedback_get_error (feedback); + if (!error) + error = meta_kms_feedback_get_error (other_feedback); + + if (error) + { + new_feedback = meta_kms_feedback_new_failed (failed_planes, + g_error_copy (error)); + } + else + { + new_feedback = meta_kms_feedback_new_passed (); + } + + meta_kms_feedback_free (feedback); + meta_kms_feedback_free (other_feedback); + + return new_feedback; +} + +static gpointer +meta_kms_process_updates_in_impl (MetaKmsImpl *impl, + gpointer user_data, + GError **error) +{ + GList *updates = user_data; + MetaKmsFeedback *feedback = NULL; + GList *l; + + for (l = updates; l; l = l->next) + { + MetaKmsUpdate *update = l->data; + MetaKmsFeedback *device_feedback; + + device_feedback = meta_kms_impl_process_update (impl, update); + feedback = combine_feedbacks (feedback, device_feedback); + meta_kms_predict_states_in_impl (meta_kms_impl_get_kms (impl), update); + } + + g_list_free_full (updates, (GDestroyNotify) meta_kms_update_free); return feedback; } static MetaKmsFeedback * -meta_kms_post_update_sync (MetaKms *kms, - MetaKmsUpdate *update) +meta_kms_post_updates_sync (MetaKms *kms, + GList *updates) { - meta_kms_update_seal (update); + g_list_foreach (updates, (GFunc) meta_kms_update_seal, NULL); COGL_TRACE_BEGIN_SCOPED (MetaKmsPostUpdateSync, "KMS (post update)"); return meta_kms_run_impl_task_sync (kms, - meta_kms_process_update_in_impl, - update, + meta_kms_process_updates_in_impl, + updates, NULL); } MetaKmsFeedback * -meta_kms_post_pending_update_sync (MetaKms *kms) +meta_kms_post_pending_updates_sync (MetaKms *kms) { - return meta_kms_post_update_sync (kms, - g_steal_pointer (&kms->pending_update)); + return meta_kms_post_updates_sync (kms, + g_steal_pointer (&kms->pending_updates)); } static gpointer diff --git a/src/backends/native/meta-kms.h b/src/backends/native/meta-kms.h index ab25b70bd..237ecbce9 100644 --- a/src/backends/native/meta-kms.h +++ b/src/backends/native/meta-kms.h @@ -28,11 +28,13 @@ #define META_TYPE_KMS (meta_kms_get_type ()) G_DECLARE_FINAL_TYPE (MetaKms, meta_kms, META, KMS, GObject) -MetaKmsUpdate * meta_kms_ensure_pending_update (MetaKms *kms); +MetaKmsUpdate * meta_kms_ensure_pending_update (MetaKms *kms, + MetaKmsDevice *device); -MetaKmsUpdate * meta_kms_get_pending_update (MetaKms *kms); +MetaKmsUpdate * meta_kms_get_pending_update (MetaKms *kms, + MetaKmsDevice *device); -MetaKmsFeedback * meta_kms_post_pending_update_sync (MetaKms *kms); +MetaKmsFeedback * meta_kms_post_pending_updates_sync (MetaKms *kms); void meta_kms_discard_pending_page_flips (MetaKms *kms); diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c index aa3c927cb..d6a40688a 100644 --- a/src/backends/native/meta-monitor-manager-kms.c +++ b/src/backends/native/meta-monitor-manager-kms.c @@ -120,7 +120,6 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager, 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; uint64_t state; GList *l; g_autoptr (MetaKmsFeedback) kms_feedback = NULL; @@ -142,15 +141,17 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager, return; } - kms_update = meta_kms_ensure_pending_update (kms); for (l = meta_backend_get_gpus (backend); l; l = l->next) { MetaGpuKms *gpu_kms = l->data; + MetaKmsDevice *kms_device = meta_gpu_kms_get_kms_device (gpu_kms); + MetaKmsUpdate *kms_update; + kms_update = meta_kms_ensure_pending_update (kms, kms_device); meta_gpu_kms_set_power_save_mode (gpu_kms, state, kms_update); } - kms_feedback = meta_kms_post_pending_update_sync (kms); + kms_feedback = meta_kms_post_pending_updates_sync (kms); if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED) { g_warning ("Failed to set DPMS: %s", @@ -418,20 +419,21 @@ meta_monitor_manager_kms_set_crtc_gamma (MetaMonitorManager *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; + MetaKmsDevice *kms_device; MetaKmsUpdate *kms_update; + g_autofree char *gamma_ramp_string = NULL; g_autoptr (MetaKmsFeedback) kms_feedback = NULL; + kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc)); + kms_device = meta_kms_crtc_get_device (kms_crtc); + kms_update = meta_kms_ensure_pending_update (kms, kms_device); + meta_kms_update_set_crtc_gamma (kms_update, kms_crtc, size, red, green, blue); + gamma_ramp_string = generate_gamma_ramp_string (size, red, green, blue); g_debug ("Setting CRTC (%" G_GUINT64_FORMAT ") gamma to %s", meta_crtc_get_id (crtc), gamma_ramp_string); - kms_update = meta_kms_ensure_pending_update (kms); - - kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc)); - meta_kms_update_set_crtc_gamma (kms_update, kms_crtc, size, red, green, blue); - - kms_feedback = meta_kms_post_pending_update_sync (kms); + kms_feedback = meta_kms_post_pending_updates_sync (kms); if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED) { g_warning ("Failed to set CRTC gamma: %s", diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c index 06e698fb0..3cb68c8b0 100644 --- a/src/backends/native/meta-renderer-native.c +++ b/src/backends/native/meta-renderer-native.c @@ -1285,8 +1285,7 @@ static void meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen, MetaRendererView *view, MetaCrtc *crtc, - MetaKmsPageFlipFlag flags, - MetaKmsUpdate *kms_update) + MetaKmsPageFlipFlag flags) { CoglOnscreenEGL *onscreen_egl = onscreen->winsys; MetaOnscreenNative *onscreen_native = onscreen_egl->platform; @@ -1295,10 +1294,16 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen, MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc); MetaRendererNativeGpuData *renderer_gpu_data; MetaGpuKms *gpu_kms; + MetaKmsDevice *kms_device; + MetaKms *kms; + MetaKmsUpdate *kms_update; MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state = NULL; uint32_t fb_id; gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc)); + kms_device = meta_gpu_kms_get_kms_device (gpu_kms); + kms = meta_kms_device_get_kms (kms_device); + kms_update = meta_kms_ensure_pending_update (kms, kms_device); g_assert (meta_gpu_kms_is_crtc_active (gpu_kms, crtc)); @@ -1340,16 +1345,21 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen, static void meta_onscreen_native_set_crtc_mode (CoglOnscreen *onscreen, - MetaRendererNativeGpuData *renderer_gpu_data, - MetaKmsUpdate *kms_update) + MetaRendererNativeGpuData *renderer_gpu_data) { CoglOnscreenEGL *onscreen_egl = onscreen->winsys; MetaOnscreenNative *onscreen_native = onscreen_egl->platform; MetaCrtcKms *crtc_kms = META_CRTC_KMS (onscreen_native->crtc); + MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms); + MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc); + MetaKms *kms = meta_kms_device_get_kms (kms_device); + MetaKmsUpdate *kms_update; COGL_TRACE_BEGIN_SCOPED (MetaOnscreenNativeSetCrtcModes, "Onscreen (set CRTC modes)"); + kms_update = meta_kms_ensure_pending_update (kms, kms_device); + switch (renderer_gpu_data->mode) { case META_RENDERER_NATIVE_MODE_GBM: @@ -1374,32 +1384,17 @@ meta_onscreen_native_set_crtc_mode (CoglOnscreen *onscreen, static void meta_onscreen_native_flip_crtcs (CoglOnscreen *onscreen, - MetaKmsPageFlipFlag flags, - MetaKmsUpdate *kms_update) + MetaKmsPageFlipFlag flags) { CoglOnscreenEGL *onscreen_egl = onscreen->winsys; MetaOnscreenNative *onscreen_native = onscreen_egl->platform; MetaRendererView *view = onscreen_native->view; - MetaRendererNative *renderer_native = onscreen_native->renderer_native; - MetaRenderer *renderer = META_RENDERER (renderer_native); - MetaMonitorManager *monitor_manager = - meta_backend_get_monitor_manager (meta_renderer_get_backend (renderer)); - MetaPowerSave power_save_mode; COGL_TRACE_BEGIN_SCOPED (MetaOnscreenNativeFlipCrtcs, "Onscreen (flip CRTCs)"); - power_save_mode = meta_monitor_manager_get_power_save_mode (monitor_manager); - if (power_save_mode == META_POWER_SAVE_ON) - { - meta_onscreen_native_flip_crtc (onscreen, view, onscreen_native->crtc, - flags, - kms_update); - } - else - { - queue_dummy_power_save_page_flip (onscreen); - } + meta_onscreen_native_flip_crtc (onscreen, view, onscreen_native->crtc, + flags); } static gboolean @@ -1864,8 +1859,7 @@ retry: } static void -ensure_crtc_modes (CoglOnscreen *onscreen, - MetaKmsUpdate *kms_update) +ensure_crtc_modes (CoglOnscreen *onscreen) { CoglOnscreenEGL *onscreen_egl = onscreen->winsys; MetaOnscreenNative *onscreen_native = onscreen_egl->platform; @@ -1874,29 +1868,19 @@ ensure_crtc_modes (CoglOnscreen *onscreen, CoglRenderer *cogl_renderer = cogl_context->display->renderer; CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys; MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform; - MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native; - MetaRenderer *renderer = META_RENDERER (renderer_native); - MetaBackend *backend = meta_renderer_get_backend (renderer); - MetaMonitorManager *monitor_manager = - meta_backend_get_monitor_manager (backend); - MetaPowerSave power_save_mode; - power_save_mode = meta_monitor_manager_get_power_save_mode (monitor_manager); - if (onscreen_native->pending_set_crtc && - power_save_mode == META_POWER_SAVE_ON) + if (onscreen_native->pending_set_crtc) { - meta_onscreen_native_set_crtc_mode (onscreen, - renderer_gpu_data, - kms_update); + meta_onscreen_native_set_crtc_mode (onscreen, renderer_gpu_data); onscreen_native->pending_set_crtc = FALSE; } } -static MetaKmsUpdate * +static gboolean unset_disabled_crtcs (MetaBackend *backend, MetaKms *kms) { - MetaKmsUpdate *kms_update = NULL; + gboolean did_mode_set = FALSE; GList *l; for (l = meta_backend_get_gpus (backend); l; l = l->next) @@ -1907,24 +1891,30 @@ unset_disabled_crtcs (MetaBackend *backend, for (k = meta_gpu_get_crtcs (gpu); k; k = k->next) { MetaCrtc *crtc = k->data; + MetaKmsCrtc *kms_crtc = + meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc)); + MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc); + MetaKmsUpdate *kms_update; if (meta_crtc_get_config (crtc)) continue; - kms_update = meta_kms_ensure_pending_update (kms); + kms_update = meta_kms_ensure_pending_update (kms, kms_device); meta_crtc_kms_set_mode (META_CRTC_KMS (crtc), kms_update); + + did_mode_set = TRUE; } } - return kms_update; + return did_mode_set; } static void -post_pending_update (MetaKms *kms) +post_pending_updates (MetaKms *kms) { g_autoptr (MetaKmsFeedback) kms_feedback = NULL; - kms_feedback = meta_kms_post_pending_update_sync (kms); + kms_feedback = meta_kms_post_pending_updates_sync (kms); if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED) { const GError *error = meta_kms_feedback_get_error (kms_feedback); @@ -1950,12 +1940,14 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, MetaRenderer *renderer = META_RENDERER (renderer_native); MetaBackend *backend = meta_renderer_get_backend (renderer); MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); MetaKms *kms = meta_backend_native_get_kms (backend_native); CoglOnscreenEGL *onscreen_egl = onscreen->winsys; MetaOnscreenNative *onscreen_native = onscreen_egl->platform; MetaGpuKms *render_gpu = onscreen_native->render_gpu; gboolean egl_context_changed = FALSE; - MetaKmsUpdate *kms_update; + MetaPowerSave power_save_mode; g_autoptr (GError) error = NULL; MetaDrmBufferGbm *buffer_gbm; g_autoptr (MetaKmsFeedback) kms_feedback = NULL; @@ -1963,8 +1955,6 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, COGL_TRACE_BEGIN_SCOPED (MetaRendererNativeSwapBuffers, "Onscreen (swap-buffers)"); - kms_update = meta_kms_ensure_pending_update (kms); - update_secondary_gpu_state_pre_swap_buffers (onscreen); parent_vtable->onscreen_swap_buffers_with_damage (onscreen, @@ -2003,10 +1993,17 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, update_secondary_gpu_state_post_swap_buffers (onscreen, &egl_context_changed); - ensure_crtc_modes (onscreen, kms_update); - meta_onscreen_native_flip_crtcs (onscreen, - META_KMS_PAGE_FLIP_FLAG_NONE, - kms_update); + power_save_mode = meta_monitor_manager_get_power_save_mode (monitor_manager); + if (power_save_mode == META_POWER_SAVE_ON) + { + ensure_crtc_modes (onscreen); + meta_onscreen_native_flip_crtcs (onscreen, META_KMS_PAGE_FLIP_FLAG_NONE); + } + else + { + queue_dummy_power_save_page_flip (onscreen); + return; + } /* * If we changed EGL context, cogl will have the wrong idea about what is @@ -2019,7 +2016,7 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, COGL_TRACE_BEGIN (MetaRendererNativePostKmsUpdate, "Onscreen (post pending update)"); - post_pending_update (kms); + post_pending_updates (kms); COGL_TRACE_END (MetaRendererNativePostKmsUpdate); } @@ -2165,10 +2162,18 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen, MetaBackend *backend = meta_renderer_get_backend (renderer); MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); MetaKms *kms = meta_backend_native_get_kms (backend_native); - MetaKmsUpdate *kms_update; + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaPowerSave power_save_mode; g_autoptr (MetaKmsFeedback) kms_feedback = NULL; - kms_update = meta_kms_ensure_pending_update (kms); + power_save_mode = meta_monitor_manager_get_power_save_mode (monitor_manager); + if (power_save_mode != META_POWER_SAVE_ON) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Can't scanout directly while power saving"); + return FALSE; + } renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native, render_gpu); @@ -2178,12 +2183,11 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen, g_set_object (&onscreen_native->gbm.next_fb, META_DRM_BUFFER (scanout)); - ensure_crtc_modes (onscreen, kms_update); + ensure_crtc_modes (onscreen); meta_onscreen_native_flip_crtcs (onscreen, - META_KMS_PAGE_FLIP_FLAG_NO_DISCARD_FEEDBACK, - kms_update); + META_KMS_PAGE_FLIP_FLAG_NO_DISCARD_FEEDBACK); - kms_feedback = meta_kms_post_pending_update_sync (kms); + kms_feedback = meta_kms_post_pending_updates_sync (kms); if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED) { const GError *feedback_error = meta_kms_feedback_get_error (kms_feedback); @@ -3159,16 +3163,16 @@ meta_renderer_native_finish_frame (MetaRendererNative *renderer_native) MetaBackend *backend = meta_renderer_get_backend (renderer); MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); MetaKms *kms = meta_backend_native_get_kms (backend_native); - MetaKmsUpdate *kms_update = NULL; + gboolean did_mode_set = FALSE; if (renderer_native->pending_unset_disabled_crtcs) { - kms_update = unset_disabled_crtcs (backend, kms); + did_mode_set = unset_disabled_crtcs (backend, kms); renderer_native->pending_unset_disabled_crtcs = FALSE; } - if (kms_update) - post_pending_update (kms); + if (did_mode_set) + post_pending_updates (kms); } static gboolean @@ -3751,12 +3755,9 @@ meta_renderer_native_reset_modes (MetaRendererNative *renderer_native) MetaBackend *backend = meta_renderer_get_backend (renderer); MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); MetaKms *kms = meta_backend_native_get_kms (backend_native); - MetaKmsUpdate *kms_update; - kms_update = unset_disabled_crtcs (backend, kms); - - if (kms_update) - post_pending_update (kms); + if (unset_disabled_crtcs (backend, kms)) + post_pending_updates (kms); } static MetaGpuKms *