diff --git a/src/backends/native/meta-cursor-renderer-native.c b/src/backends/native/meta-cursor-renderer-native.c index 57774345c..f1b7459fe 100644 --- a/src/backends/native/meta-cursor-renderer-native.c +++ b/src/backends/native/meta-cursor-renderer-native.c @@ -43,6 +43,7 @@ #include "backends/native/meta-device-pool.h" #include "backends/native/meta-drm-buffer-dumb.h" #include "backends/native/meta-drm-buffer-gbm.h" +#include "backends/native/meta-frame-native.h" #include "backends/native/meta-kms-device.h" #include "backends/native/meta-kms-plane.h" #include "backends/native/meta-kms-update.h" @@ -282,6 +283,7 @@ ensure_crtc_cursor_data (MetaCrtcKms *crtc_kms) static void assign_cursor_plane (MetaCursorRendererNative *native, + ClutterFrame *frame, MetaCrtcKms *crtc_kms, int x, int y, @@ -294,6 +296,7 @@ assign_cursor_plane (MetaCursorRendererNative *native, meta_cursor_renderer_native_gpu_data_from_gpu (gpu_kms); MetaCursorNativeGpuState *cursor_gpu_state = get_cursor_gpu_state (cursor_priv, gpu_kms); + MetaFrameNative *frame_native = meta_frame_native_from_frame (frame); MetaKmsCrtc *kms_crtc; MetaKmsDevice *kms_device; MetaKmsPlane *cursor_plane; @@ -340,9 +343,8 @@ assign_cursor_plane (MetaCursorRendererNative *native, if (!crtc_cursor_data->hw_state_invalidated && buffer == crtc_buffer) flags |= META_KMS_ASSIGN_PLANE_FLAG_FB_UNCHANGED; - kms_update = - meta_kms_ensure_pending_update (meta_kms_device_get_kms (kms_device), - meta_kms_crtc_get_device (kms_crtc)); + kms_update = meta_frame_native_ensure_kms_update (frame_native, + kms_device); plane_assignment = meta_kms_update_assign_plane (kms_update, kms_crtc, cursor_plane, @@ -390,6 +392,7 @@ calculate_cursor_crtc_sprite_scale (MetaBackend *backend, static void set_crtc_cursor (MetaCursorRendererNative *cursor_renderer_native, + ClutterFrame *frame, MetaRendererView *view, MetaCrtc *crtc, MetaCursorSprite *cursor_sprite) @@ -467,6 +470,7 @@ set_crtc_cursor (MetaCursorRendererNative *cursor_renderer_native, &cursor_rect); assign_cursor_plane (cursor_renderer_native, + frame, META_CRTC_KMS (crtc), cursor_rect.x, cursor_rect.y, @@ -475,9 +479,11 @@ set_crtc_cursor (MetaCursorRendererNative *cursor_renderer_native, static void unset_crtc_cursor (MetaCursorRendererNative *native, + ClutterFrame *frame, MetaCrtc *crtc) { MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc); + MetaFrameNative *frame_native = meta_frame_native_from_frame (frame); CrtcCursorData *crtc_cursor_data; MetaKmsCrtc *kms_crtc; MetaKmsDevice *kms_device; @@ -495,10 +501,10 @@ unset_crtc_cursor (MetaCursorRendererNative *native, if (cursor_plane) { - MetaKms *kms = meta_kms_device_get_kms (kms_device); MetaKmsUpdate *kms_update; - kms_update = meta_kms_ensure_pending_update (kms, kms_device); + kms_update = meta_frame_native_ensure_kms_update (frame_native, + kms_device); meta_kms_update_unassign_plane (kms_update, kms_crtc, cursor_plane); } @@ -531,7 +537,8 @@ disable_hw_cursor_for_crtc (MetaKmsCrtc *kms_crtc, void meta_cursor_renderer_native_prepare_frame (MetaCursorRendererNative *cursor_renderer_native, - MetaRendererView *view) + MetaRendererView *view, + ClutterFrame *frame) { MetaCursorRenderer *cursor_renderer = META_CURSOR_RENDERER (cursor_renderer_native); @@ -574,7 +581,7 @@ meta_cursor_renderer_native_prepare_frame (MetaCursorRendererNative *cursor_rend if (!graphene_rect_intersection (&cursor_rect, &view_rect, NULL)) goto unset_cursor; - set_crtc_cursor (cursor_renderer_native, view, crtc, cursor_sprite); + set_crtc_cursor (cursor_renderer_native, frame, view, crtc, cursor_sprite); meta_cursor_renderer_emit_painted (cursor_renderer, cursor_sprite, @@ -585,7 +592,7 @@ meta_cursor_renderer_native_prepare_frame (MetaCursorRendererNative *cursor_rend return; unset_cursor: - unset_crtc_cursor (cursor_renderer_native, crtc); + unset_crtc_cursor (cursor_renderer_native, frame, crtc); crtc_cursor_data = ensure_crtc_cursor_data (META_CRTC_KMS (crtc)); crtc_cursor_data->hw_state_invalidated = FALSE; diff --git a/src/backends/native/meta-cursor-renderer-native.h b/src/backends/native/meta-cursor-renderer-native.h index 72b7b3c35..d3858e5e5 100644 --- a/src/backends/native/meta-cursor-renderer-native.h +++ b/src/backends/native/meta-cursor-renderer-native.h @@ -35,7 +35,8 @@ G_DECLARE_FINAL_TYPE (MetaCursorRendererNative, meta_cursor_renderer_native, MetaCursorRenderer) void meta_cursor_renderer_native_prepare_frame (MetaCursorRendererNative *cursor_renderer_native, - MetaRendererView *view); + MetaRendererView *view, + ClutterFrame *frame); MetaCursorRendererNative * meta_cursor_renderer_native_new (MetaBackend *backend, ClutterInputDevice *device); diff --git a/src/backends/native/meta-frame-native.c b/src/backends/native/meta-frame-native.c index 45351b70b..c39af96ae 100644 --- a/src/backends/native/meta-frame-native.c +++ b/src/backends/native/meta-frame-native.c @@ -21,16 +21,23 @@ #include "backends/native/meta-frame-native.h" +#include "backends/native/meta-kms-update.h" #include "clutter/clutter-mutter.h" +#include "core/util-private.h" struct _MetaFrameNative { ClutterFrame base; + + MetaKmsUpdate *kms_update; }; static void meta_frame_native_release (ClutterFrame *frame) { + MetaFrameNative *frame_native = meta_frame_native_from_frame (frame); + + g_return_if_fail (!frame_native->kms_update); } MetaFrameNative * @@ -38,3 +45,45 @@ meta_frame_native_new (void) { return clutter_frame_new (MetaFrameNative, meta_frame_native_release); } + +MetaFrameNative * +meta_frame_native_from_frame (ClutterFrame *frame) +{ + return META_CONTAINER_OF (frame, MetaFrameNative, base); +} + +void +meta_frame_native_set_kms_update (MetaFrameNative *frame_native, + MetaKmsUpdate *kms_update) +{ + g_return_if_fail (!frame_native->kms_update); + + frame_native->kms_update = kms_update; +} + +MetaKmsUpdate * +meta_frame_native_ensure_kms_update (MetaFrameNative *frame_native, + MetaKmsDevice *kms_device) +{ + if (frame_native->kms_update) + { + g_warn_if_fail (meta_kms_update_get_device (frame_native->kms_update) == + kms_device); + return frame_native->kms_update; + } + + frame_native->kms_update = meta_kms_update_new (kms_device); + return frame_native->kms_update; +} + +MetaKmsUpdate * +meta_frame_native_steal_kms_update (MetaFrameNative *frame_native) +{ + return g_steal_pointer (&frame_native->kms_update); +} + +gboolean +meta_frame_native_has_kms_update (MetaFrameNative *frame_native) +{ + return !!frame_native->kms_update; +} diff --git a/src/backends/native/meta-frame-native.h b/src/backends/native/meta-frame-native.h index f52921ce6..e7140929b 100644 --- a/src/backends/native/meta-frame-native.h +++ b/src/backends/native/meta-frame-native.h @@ -20,8 +20,27 @@ #ifndef META_FRAME_NATIVE_H #define META_FRAME_NATIVE_H +#include "backends/native/meta-kms-types.h" +#include "clutter/clutter.h" +#include "core/util-private.h" + typedef struct _MetaFrameNative MetaFrameNative; MetaFrameNative * meta_frame_native_new (void); +META_EXPORT_TEST +MetaFrameNative * meta_frame_native_from_frame (ClutterFrame *frame); + +void meta_frame_native_set_kms_update (MetaFrameNative *frame_native, + MetaKmsUpdate *kms_update); + +META_EXPORT_TEST +MetaKmsUpdate * meta_frame_native_ensure_kms_update (MetaFrameNative *frame_native, + MetaKmsDevice *kms_device); + +MetaKmsUpdate * meta_frame_native_steal_kms_update (MetaFrameNative *frame_native); + +META_EXPORT_TEST +gboolean meta_frame_native_has_kms_update (MetaFrameNative *frame_native); + #endif /* META_FRAME_NATIVE_H */ diff --git a/src/backends/native/meta-kms-update-private.h b/src/backends/native/meta-kms-update-private.h index f39b47b9f..0e91778e7 100644 --- a/src/backends/native/meta-kms-update-private.h +++ b/src/backends/native/meta-kms-update-private.h @@ -148,9 +148,6 @@ void meta_kms_update_seal (MetaKmsUpdate *update); META_EXPORT_TEST gboolean meta_kms_update_is_sealed (MetaKmsUpdate *update); -META_EXPORT_TEST -MetaKmsDevice * meta_kms_update_get_device (MetaKmsUpdate *update); - void meta_kms_plane_assignment_set_rotation (MetaKmsPlaneAssignment *plane_assignment, MetaKmsPlaneRotation rotation); @@ -184,10 +181,6 @@ void meta_kms_update_drop_plane_assignment (MetaKmsUpdate *update, GList * meta_kms_update_take_result_listeners (MetaKmsUpdate *update); -META_EXPORT_TEST -void meta_kms_update_merge_from (MetaKmsUpdate *update, - MetaKmsUpdate *other_update); - void meta_kms_result_listener_set_feedback (MetaKmsResultListener *listener, MetaKmsFeedback *feedback); diff --git a/src/backends/native/meta-kms-update.h b/src/backends/native/meta-kms-update.h index 6ce5a8159..885655c42 100644 --- a/src/backends/native/meta-kms-update.h +++ b/src/backends/native/meta-kms-update.h @@ -101,6 +101,9 @@ MetaKmsUpdate * meta_kms_update_new (MetaKmsDevice *device); META_EXPORT_TEST void meta_kms_update_free (MetaKmsUpdate *update); +META_EXPORT_TEST +MetaKmsDevice * meta_kms_update_get_device (MetaKmsUpdate *update); + void meta_kms_update_set_underscanning (MetaKmsUpdate *update, MetaKmsConnector *connector, uint64_t hborder, @@ -170,6 +173,10 @@ void meta_kms_update_add_result_listener (MetaKmsUpdate *update, MetaKmsResultListenerFunc func, gpointer user_data); +META_EXPORT_TEST +void meta_kms_update_merge_from (MetaKmsUpdate *update, + MetaKmsUpdate *other_update); + static inline MetaFixed16 meta_fixed_16_from_int (int16_t d) { diff --git a/src/backends/native/meta-kms.c b/src/backends/native/meta-kms.c index 0c5ca0726..d3a840b31 100644 --- a/src/backends/native/meta-kms.c +++ b/src/backends/native/meta-kms.c @@ -181,72 +181,6 @@ struct _MetaKms G_DEFINE_TYPE (MetaKms, meta_kms, G_TYPE_OBJECT) -void -meta_kms_discard_pending_updates (MetaKms *kms) -{ - g_clear_list (&kms->pending_updates, (GDestroyNotify) meta_kms_update_free); -} - -static void -meta_kms_add_pending_update (MetaKms *kms, - MetaKmsUpdate *update) -{ - kms->pending_updates = g_list_prepend (kms->pending_updates, update); -} - -MetaKmsUpdate * -meta_kms_ensure_pending_update (MetaKms *kms, - MetaKmsDevice *device) -{ - MetaKmsUpdate *update; - - update = meta_kms_get_pending_update (kms, device); - if (update) - return update; - - update = meta_kms_update_new (device); - meta_kms_add_pending_update (kms, update); - - return update; -} - -MetaKmsUpdate * -meta_kms_get_pending_update (MetaKms *kms, - MetaKmsDevice *device) -{ - 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 MetaKmsUpdate * -meta_kms_take_pending_update (MetaKms *kms, - MetaKmsDevice *device) -{ - GList *l; - - for (l = kms->pending_updates; l; l = l->next) - { - MetaKmsUpdate *update = l->data; - - if (meta_kms_update_get_device (update) == device) - { - kms->pending_updates = g_list_delete_link (kms->pending_updates, l); - return update; - } - } - - return NULL; -} - static void invoke_result_listener (MetaKms *kms, gpointer user_data) @@ -266,27 +200,6 @@ meta_kms_queue_result_callback (MetaKms *kms, (GDestroyNotify) meta_kms_result_listener_free); } -void -meta_kms_post_pending_update_sync (MetaKms *kms, - MetaKmsDevice *device, - MetaKmsUpdateFlag flags) -{ - MetaKmsUpdate *update; - g_autoptr (MetaKmsFeedback) feedback = NULL; - GList *result_listeners; - - COGL_TRACE_BEGIN_SCOPED (MetaKmsPostUpdateSync, - "KMS (post update)"); - - update = meta_kms_take_pending_update (kms, device); - if (!update) - return; - - result_listeners = meta_kms_update_take_result_listeners (update); - feedback = meta_kms_device_process_update_sync (device, update, flags); - meta_kms_feedback_dispatch_result (feedback, kms, result_listeners); -} - static gpointer meta_kms_discard_pending_page_flips_in_impl (MetaKmsImpl *impl, gpointer user_data, diff --git a/src/backends/native/meta-kms.h b/src/backends/native/meta-kms.h index 3d9aaed1c..fe4fef1a0 100644 --- a/src/backends/native/meta-kms.h +++ b/src/backends/native/meta-kms.h @@ -34,19 +34,6 @@ typedef enum _MetaKmsFlags #define META_TYPE_KMS (meta_kms_get_type ()) G_DECLARE_FINAL_TYPE (MetaKms, meta_kms, META, KMS, GObject) -void meta_kms_discard_pending_updates (MetaKms *kms); - -META_EXPORT_TEST -MetaKmsUpdate * meta_kms_ensure_pending_update (MetaKms *kms, - MetaKmsDevice *device); - -MetaKmsUpdate * meta_kms_get_pending_update (MetaKms *kms, - MetaKmsDevice *device); - -void meta_kms_post_pending_update_sync (MetaKms *kms, - MetaKmsDevice *device, - MetaKmsUpdateFlag flags); - void meta_kms_discard_pending_page_flips (MetaKms *kms); void meta_kms_notify_modes_set (MetaKms *kms); diff --git a/src/backends/native/meta-onscreen-native.c b/src/backends/native/meta-onscreen-native.c index 49385c901..5b9396aeb 100644 --- a/src/backends/native/meta-onscreen-native.c +++ b/src/backends/native/meta-onscreen-native.c @@ -39,6 +39,7 @@ #include "backends/native/meta-drm-buffer-gbm.h" #include "backends/native/meta-drm-buffer-import.h" #include "backends/native/meta-drm-buffer.h" +#include "backends/native/meta-frame-native.h" #include "backends/native/meta-kms-device.h" #include "backends/native/meta-kms-utils.h" #include "backends/native/meta-kms.h" @@ -412,6 +413,7 @@ static void meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen, MetaRendererView *view, MetaCrtc *crtc, + MetaKmsUpdate *kms_update, MetaKmsPageFlipListenerFlag flags, const int *rectangles, int n_rectangles) @@ -423,9 +425,6 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen, MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms); MetaRendererNativeGpuData *renderer_gpu_data; MetaGpuKms *gpu_kms; - MetaKmsDevice *kms_device; - MetaKms *kms; - MetaKmsUpdate *kms_update; MetaDrmBuffer *buffer; MetaKmsPlaneAssignment *plane_assignment; @@ -433,9 +432,6 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen, "Onscreen (flip CRTCs)"); 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)); @@ -478,20 +474,15 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen, static void meta_onscreen_native_set_crtc_mode (CoglOnscreen *onscreen, + MetaKmsUpdate *kms_update, MetaRendererNativeGpuData *renderer_gpu_data) { MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen); 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: @@ -1002,7 +993,8 @@ update_secondary_gpu_state_post_swap_buffers (CoglOnscreen *onscreen, } static void -ensure_crtc_modes (CoglOnscreen *onscreen) +ensure_crtc_modes (CoglOnscreen *onscreen, + MetaKmsUpdate *kms_update) { MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen); CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); @@ -1014,7 +1006,7 @@ ensure_crtc_modes (CoglOnscreen *onscreen) if (meta_renderer_native_pop_pending_mode_set (renderer_native, onscreen_native->view)) - meta_onscreen_native_set_crtc_mode (onscreen, renderer_gpu_data); + meta_onscreen_native_set_crtc_mode (onscreen, kms_update, renderer_gpu_data); } static void @@ -1062,14 +1054,14 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native; 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); MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen); MetaGpuKms *render_gpu = onscreen_native->render_gpu; MetaDeviceFile *render_device_file; ClutterFrame *frame = user_data; + MetaFrameNative *frame_native = meta_frame_native_from_frame (frame); + MetaKmsUpdate *kms_update; CoglOnscreenClass *parent_class; gboolean egl_context_changed = FALSE; MetaPowerSave power_save_mode; @@ -1080,6 +1072,7 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, g_autoptr (MetaDrmBuffer) secondary_gpu_fb = NULL; MetaKmsCrtc *kms_crtc; MetaKmsDevice *kms_device; + g_autoptr (MetaKmsFeedback) kms_feedback = NULL; COGL_TRACE_BEGIN_SCOPED (MetaRendererNativeSwapBuffers, "Onscreen (swap-buffers)"); @@ -1168,17 +1161,17 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, power_save_mode = meta_monitor_manager_get_power_save_mode (monitor_manager); if (power_save_mode == META_POWER_SAVE_ON) { - MetaKmsUpdate *kms_update; - - kms_update = meta_kms_ensure_pending_update (kms, kms_device); + kms_update = meta_frame_native_ensure_kms_update (frame_native, + kms_device); meta_kms_update_add_result_listener (kms_update, on_swap_buffer_update_result, onscreen_native); - ensure_crtc_modes (onscreen); + ensure_crtc_modes (onscreen, kms_update); meta_onscreen_native_flip_crtc (onscreen, onscreen_native->view, onscreen_native->crtc, + kms_update, META_KMS_PAGE_FLIP_LISTENER_FLAG_NONE, rectangles, n_rectangles); @@ -1205,6 +1198,9 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, meta_kms_crtc_get_id (kms_crtc), meta_kms_device_get_path (kms_device)); + kms_update = meta_frame_native_steal_kms_update (frame_native); + meta_renderer_native_queue_mode_set_update (renderer_native, + kms_update); clutter_frame_set_result (frame, CLUTTER_FRAME_RESULT_PENDING_PRESENTED); return; @@ -1214,7 +1210,11 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, meta_topic (META_DEBUG_KMS, "Posting global mode set updates on %s", meta_kms_device_get_path (kms_device)); - meta_renderer_native_notify_mode_sets_reset (renderer_native); + kms_update = meta_frame_native_steal_kms_update (frame_native); + meta_renderer_native_queue_mode_set_update (renderer_native, + kms_update); + + meta_frame_native_steal_kms_update (frame_native); meta_renderer_native_post_mode_set_updates (renderer_native); clutter_frame_set_result (frame, CLUTTER_FRAME_RESULT_PENDING_PRESENTED); @@ -1228,7 +1228,10 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, case META_RENDERER_NATIVE_MODE_EGL_DEVICE: if (meta_renderer_native_has_pending_mode_set (renderer_native)) { - meta_renderer_native_notify_mode_sets_reset (renderer_native); + kms_update = meta_frame_native_steal_kms_update (frame_native); + meta_renderer_native_queue_mode_set_update (renderer_native, + kms_update); + meta_renderer_native_post_mode_set_updates (renderer_native); clutter_frame_set_result (frame, CLUTTER_FRAME_RESULT_PENDING_PRESENTED); @@ -1243,7 +1246,10 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, meta_kms_crtc_get_id (kms_crtc), meta_kms_device_get_path (kms_device)); - meta_kms_post_pending_update_sync (kms, kms_device, META_KMS_UPDATE_FLAG_NONE); + kms_update = meta_frame_native_steal_kms_update (frame_native); + kms_feedback = + meta_kms_device_process_update_sync (kms_device, kms_update, + META_KMS_UPDATE_FLAG_NONE); clutter_frame_set_result (frame, CLUTTER_FRAME_RESULT_PENDING_PRESENTED); } @@ -1332,17 +1338,17 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen, MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native; MetaRenderer *renderer = META_RENDERER (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); MetaMonitorManager *monitor_manager = meta_backend_get_monitor_manager (backend); MetaPowerSave power_save_mode; ClutterFrame *frame = user_data; + MetaFrameNative *frame_native = meta_frame_native_from_frame (frame); MetaDrmBuffer *scanout_buffer; GError *fill_timings_error = NULL; MetaKmsCrtc *kms_crtc; MetaKmsDevice *kms_device; MetaKmsUpdate *kms_update; + g_autoptr (MetaKmsFeedback) kms_feedback = NULL; power_save_mode = meta_monitor_manager_get_power_save_mode (monitor_manager); if (power_save_mode != META_POWER_SAVE_ON) @@ -1400,7 +1406,7 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen, kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (onscreen_native->crtc)); kms_device = meta_kms_crtc_get_device (kms_crtc); - kms_update = meta_kms_ensure_pending_update (kms, kms_device); + kms_update = meta_frame_native_ensure_kms_update (frame_native, kms_device); meta_kms_update_add_result_listener (kms_update, on_scanout_update_result, @@ -1409,6 +1415,7 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen, meta_onscreen_native_flip_crtc (onscreen, onscreen_native->view, onscreen_native->crtc, + kms_update, META_KMS_PAGE_FLIP_LISTENER_FLAG_NONE, NULL, 0); @@ -1418,8 +1425,11 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen, meta_kms_crtc_get_id (kms_crtc), meta_kms_device_get_path (kms_device)); + kms_update = meta_frame_native_steal_kms_update (frame_native); + kms_feedback = + meta_kms_device_process_update_sync (kms_device, kms_update, + META_KMS_UPDATE_FLAG_NONE); clutter_frame_set_result (frame, CLUTTER_FRAME_RESULT_PENDING_PRESENTED); - meta_kms_post_pending_update_sync (kms, kms_device, META_KMS_UPDATE_FLAG_NONE); return TRUE; } @@ -1446,8 +1456,8 @@ meta_onscreen_native_prepare_frame (CoglOnscreen *onscreen, MetaCrtcKms *crtc_kms = META_CRTC_KMS (onscreen_native->crtc); MetaOutputKms *output_kms = META_OUTPUT_KMS (onscreen_native->output); 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); + MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc);; + MetaFrameNative *frame_native = meta_frame_native_from_frame (frame); if (onscreen_native->is_gamma_lut_invalid) { @@ -1458,7 +1468,8 @@ meta_onscreen_native_prepare_frame (CoglOnscreen *onscreen, { MetaKmsUpdate *kms_update; - kms_update = meta_kms_ensure_pending_update (kms, kms_device); + kms_update = meta_frame_native_ensure_kms_update (frame_native, + kms_device); meta_kms_update_set_crtc_gamma (kms_update, kms_crtc, gamma); @@ -1472,7 +1483,8 @@ meta_onscreen_native_prepare_frame (CoglOnscreen *onscreen, MetaKmsUpdate *kms_update; gboolean enabled; - kms_update = meta_kms_ensure_pending_update (kms, kms_device); + kms_update = meta_frame_native_ensure_kms_update (frame_native, + kms_device); enabled = meta_output_is_privacy_screen_enabled (onscreen_native->output); meta_kms_update_set_privacy_screen (kms_update, kms_connector, enabled); @@ -1487,10 +1499,11 @@ meta_onscreen_native_finish_frame (CoglOnscreen *onscreen, MetaCrtc *crtc = onscreen_native->crtc; MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc)); MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc); - MetaKms *kms = meta_kms_device_get_kms (kms_device); + MetaFrameNative *frame_native = meta_frame_native_from_frame (frame); MetaKmsUpdate *kms_update; + g_autoptr (MetaKmsFeedback) kms_feedback = NULL; - kms_update = meta_kms_get_pending_update (kms, kms_device); + kms_update = meta_frame_native_steal_kms_update (frame_native); if (!kms_update) { clutter_frame_set_result (frame, CLUTTER_FRAME_RESULT_IDLE); @@ -1510,7 +1523,9 @@ meta_onscreen_native_finish_frame (CoglOnscreen *onscreen, meta_kms_crtc_get_id (kms_crtc), meta_kms_device_get_path (kms_device)); - meta_kms_post_pending_update_sync (kms, kms_device, META_KMS_UPDATE_FLAG_NONE); + kms_feedback = + meta_kms_device_process_update_sync (kms_device, kms_update, + META_KMS_UPDATE_FLAG_NONE); clutter_frame_set_result (frame, CLUTTER_FRAME_RESULT_PENDING_PRESENTED); } diff --git a/src/backends/native/meta-renderer-native-private.h b/src/backends/native/meta-renderer-native-private.h index e2e133bd9..5e741bff7 100644 --- a/src/backends/native/meta-renderer-native-private.h +++ b/src/backends/native/meta-renderer-native-private.h @@ -75,6 +75,7 @@ MetaGles3 * meta_renderer_native_get_gles3 (MetaRendererNative *renderer_native) MetaRendererNativeGpuData * meta_renderer_native_get_gpu_data (MetaRendererNative *renderer_native, MetaGpuKms *gpu_kms); +META_EXPORT_TEST gboolean meta_renderer_native_has_pending_mode_sets (MetaRendererNative *renderer_native); gboolean meta_renderer_native_has_pending_mode_set (MetaRendererNative *renderer_native); @@ -83,6 +84,9 @@ void meta_renderer_native_notify_mode_sets_reset (MetaRendererNative *renderer_n void meta_renderer_native_post_mode_set_updates (MetaRendererNative *renderer_native); +void meta_renderer_native_queue_mode_set_update (MetaRendererNative *renderer_native, + MetaKmsUpdate *new_kms_update); + void meta_renderer_native_queue_power_save_page_flip (MetaRendererNative *renderer_native, CoglOnscreen *onscreen); diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c index 1a3195166..4da361e2b 100644 --- a/src/backends/native/meta-renderer-native.c +++ b/src/backends/native/meta-renderer-native.c @@ -101,6 +101,8 @@ struct _MetaRendererNative GList *power_save_page_flip_onscreens; guint power_save_page_flip_source_id; + + GHashTable *mode_set_updates; }; static void @@ -298,6 +300,22 @@ meta_renderer_native_disconnect (CoglRenderer *cogl_renderer) g_free (cogl_renderer_egl); } +static MetaKmsUpdate * +ensure_mode_set_update (MetaRendererNative *renderer_native, + MetaKmsDevice *kms_device) +{ + MetaKmsUpdate *kms_update; + + kms_update = g_hash_table_lookup (renderer_native->mode_set_updates, + kms_device); + if (kms_update) + return kms_update; + + kms_update = meta_kms_update_new (kms_device); + + return kms_update; +} + static gboolean meta_renderer_native_connect (CoglRenderer *cogl_renderer, GError **error) @@ -664,9 +682,9 @@ meta_renderer_native_create_dma_buf_framebuffer (MetaRendererNative *renderer_n } static void -configure_disabled_crtcs (MetaKmsDevice *kms_device) +configure_disabled_crtcs (MetaKmsDevice *kms_device, + MetaRendererNative *renderer_native) { - MetaKms *kms = meta_kms_device_get_kms (kms_device); GList *l; for (l = meta_kms_device_get_crtcs (kms_device); l; l = l->next) @@ -681,7 +699,7 @@ configure_disabled_crtcs (MetaKmsDevice *kms_device) if (!meta_kms_crtc_is_active (kms_crtc)) continue; - kms_update = meta_kms_ensure_pending_update (kms, kms_device); + kms_update = ensure_mode_set_update (renderer_native, kms_device); meta_kms_update_mode_set (kms_update, kms_crtc, NULL, NULL); } } @@ -831,32 +849,44 @@ on_mode_sets_update_result (const MetaKmsFeedback *kms_feedback, g_warning ("Failed to post KMS update: %s", feedback_error->message); } +static void +post_mode_set_updates (MetaRendererNative *renderer_native) +{ + GHashTableIter iter; + gpointer key, value; + + g_hash_table_iter_init (&iter, renderer_native->mode_set_updates); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + MetaKmsDevice *kms_device = META_KMS_DEVICE (key); + MetaKmsUpdate *kms_update = value; + g_autoptr (MetaKmsFeedback) feedback = NULL; + + g_hash_table_iter_steal (&iter); + + meta_kms_update_add_result_listener (kms_update, + on_mode_sets_update_result, + NULL); + + feedback = meta_kms_device_process_update_sync (kms_device, kms_update, + META_KMS_UPDATE_FLAG_NONE); + } +} + void meta_renderer_native_post_mode_set_updates (MetaRendererNative *renderer_native) { MetaRenderer *renderer = META_RENDERER (renderer_native); MetaBackend *backend = meta_renderer_get_backend (renderer); MetaKms *kms = meta_backend_native_get_kms (META_BACKEND_NATIVE (backend)); - GList *l; - for (l = meta_kms_get_devices (kms); l; l = l->next) - { - MetaKmsDevice *kms_device = l->data; - MetaKmsUpdate *kms_update; + renderer_native->pending_mode_set = FALSE; - configure_disabled_crtcs (kms_device); + g_list_foreach (meta_kms_get_devices (kms), + (GFunc) configure_disabled_crtcs, + renderer_native); - kms_update = meta_kms_get_pending_update (kms, kms_device); - if (!kms_update) - continue; - - meta_kms_update_add_result_listener (kms_update, - on_mode_sets_update_result, - NULL); - - meta_kms_post_pending_update_sync (kms, kms_device, - META_KMS_UPDATE_FLAG_NONE); - } + post_mode_set_updates (renderer_native); clear_detached_onscreens (renderer_native); @@ -865,10 +895,31 @@ meta_renderer_native_post_mode_set_updates (MetaRendererNative *renderer_native) free_unused_gpu_datas (renderer_native); } -static void -unset_disabled_crtcs (MetaBackend *backend, - MetaKms *kms) +void +meta_renderer_native_queue_mode_set_update (MetaRendererNative *renderer_native, + MetaKmsUpdate *new_kms_update) { + MetaKmsDevice *kms_device = meta_kms_update_get_device (new_kms_update); + MetaKmsUpdate *kms_update; + + kms_update = g_hash_table_lookup (renderer_native->mode_set_updates, + kms_device); + if (!kms_update) + { + g_hash_table_insert (renderer_native->mode_set_updates, + kms_device, new_kms_update); + return; + } + + meta_kms_update_merge_from (kms_update, new_kms_update); + meta_kms_update_free (new_kms_update); +} + +static void +unset_disabled_crtcs (MetaRendererNative *renderer_native) +{ + MetaRenderer *renderer = META_RENDERER (renderer_native); + MetaBackend *backend = meta_renderer_get_backend (renderer); GList *l; meta_topic (META_DEBUG_KMS, "Disabling all disabled CRTCs"); @@ -889,19 +940,12 @@ unset_disabled_crtcs (MetaBackend *backend, if (meta_crtc_get_config (crtc)) continue; - kms_update = meta_kms_ensure_pending_update (kms, kms_device); + kms_update = ensure_mode_set_update (renderer_native, kms_device); meta_crtc_kms_set_mode (META_CRTC_KMS (crtc), kms_update); } - - if (!kms_update) - continue; - - meta_kms_update_add_result_listener (kms_update, - on_mode_sets_update_result, - NULL); - meta_kms_post_pending_update_sync (kms, kms_device, - META_KMS_UPDATE_FLAG_NONE); } + + post_mode_set_updates (renderer_native); } static CoglDmaBufHandle * @@ -1432,6 +1476,7 @@ detach_onscreens (MetaRenderer *renderer) static void meta_renderer_native_rebuild_views (MetaRenderer *renderer) { + MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer); MetaBackend *backend = meta_renderer_get_backend (renderer); MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); MetaKms *kms = meta_backend_native_get_kms (backend_native); @@ -1439,7 +1484,7 @@ meta_renderer_native_rebuild_views (MetaRenderer *renderer) META_RENDERER_CLASS (meta_renderer_native_parent_class); meta_kms_discard_pending_page_flips (kms); - meta_kms_discard_pending_updates (kms); + g_hash_table_remove_all (renderer_native->mode_set_updates); detach_onscreens (renderer); @@ -1930,12 +1975,7 @@ on_power_save_mode_changed (MetaMonitorManager *monitor_manager, void meta_renderer_native_reset_modes (MetaRendererNative *renderer_native) { - MetaRenderer *renderer = META_RENDERER (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); - - unset_disabled_crtcs (backend, kms); + unset_disabled_crtcs (renderer_native); } static MetaGpuKms * @@ -2133,6 +2173,7 @@ meta_renderer_native_finalize (GObject *object) g_source_remove); g_list_free (renderer_native->pending_mode_set_views); + g_hash_table_unref (renderer_native->mode_set_updates); g_clear_handle_id (&renderer_native->release_unused_gpus_idle_id, g_source_remove); @@ -2173,6 +2214,10 @@ meta_renderer_native_init (MetaRendererNative *renderer_native) g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) meta_renderer_native_gpu_data_free); + renderer_native->mode_set_updates = + g_hash_table_new_full (NULL, NULL, + NULL, + (GDestroyNotify) meta_kms_update_free); } static void diff --git a/src/backends/native/meta-renderer-native.h b/src/backends/native/meta-renderer-native.h index b39e35f80..f34881889 100644 --- a/src/backends/native/meta-renderer-native.h +++ b/src/backends/native/meta-renderer-native.h @@ -34,6 +34,7 @@ #include "backends/native/meta-monitor-manager-native.h" #define META_TYPE_RENDERER_NATIVE (meta_renderer_native_get_type ()) +META_EXPORT_TEST G_DECLARE_FINAL_TYPE (MetaRendererNative, meta_renderer_native, META, RENDERER_NATIVE, MetaRenderer) diff --git a/src/backends/native/meta-stage-native.c b/src/backends/native/meta-stage-native.c index 7aad9b643..8cdf6cb02 100644 --- a/src/backends/native/meta-stage-native.c +++ b/src/backends/native/meta-stage-native.c @@ -130,7 +130,8 @@ meta_stage_native_prepare_frame (ClutterStageWindow *stage_window, META_RENDERER_VIEW (stage_view), frame); meta_cursor_renderer_native_prepare_frame (cursor_renderer_native, - META_RENDERER_VIEW (stage_view)); + META_RENDERER_VIEW (stage_view), + frame); } static void diff --git a/src/core/util-private.h b/src/core/util-private.h index 806cdc652..d6af275b3 100644 --- a/src/core/util-private.h +++ b/src/core/util-private.h @@ -50,4 +50,7 @@ void meta_init_debug_utils (void); (ycoord) >= (rect).y && \ (ycoord) < ((rect).y + (rect).height)) +#define META_CONTAINER_OF(ptr, type, member) \ + (type *) ((uint8_t *) (ptr) - G_STRUCT_OFFSET (type, member)) + #endif diff --git a/src/tests/native-kms-render.c b/src/tests/native-kms-render.c index 841d1064c..1557b764e 100644 --- a/src/tests/native-kms-render.c +++ b/src/tests/native-kms-render.c @@ -26,7 +26,9 @@ #include "backends/native/meta-crtc-kms.h" #include "backends/native/meta-device-pool.h" #include "backends/native/meta-drm-buffer.h" +#include "backends/native/meta-frame-native.h" #include "backends/native/meta-onscreen-native.h" +#include "backends/native/meta-renderer-native-private.h" #include "backends/native/meta-kms.h" #include "backends/native/meta-kms-device.h" #include "backends/native/meta-kms-device-private.h" @@ -77,6 +79,14 @@ on_after_update (ClutterStage *stage, ClutterFrame *frame, KmsRenderingTest *test) { + MetaBackend *backend = meta_context_get_backend (test_context); + MetaRenderer *renderer = meta_backend_get_renderer (backend); + MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer); + MetaFrameNative *frame_native = meta_frame_native_from_frame (frame); + + g_assert (meta_renderer_native_has_pending_mode_sets (renderer_native) || + !meta_frame_native_has_kms_update (frame_native)); + test->number_of_frames_left--; if (test->number_of_frames_left == 0) g_main_loop_quit (test->loop); @@ -342,7 +352,7 @@ on_scanout_fallback_before_paint (ClutterStage *stage, MetaCrtc *crtc = meta_renderer_view_get_crtc (view); MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc)); MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc); - MetaKms *kms = meta_kms_device_get_kms (kms_device); + MetaFrameNative *frame_native = meta_frame_native_from_frame (frame); CoglScanout *scanout; MetaKmsUpdate *kms_update; @@ -364,7 +374,7 @@ on_scanout_fallback_before_paint (ClutterStage *stage, test->scanout_fallback.scanout_sabotaged = TRUE; - kms_update = meta_kms_ensure_pending_update (kms, kms_device); + kms_update = meta_frame_native_ensure_kms_update (frame_native, kms_device); meta_kms_update_add_result_listener (kms_update, on_scanout_fallback_result, test);