summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Ã…dahl <jadahl@gmail.com>2022-10-20 21:57:25 +0200
committerRobert Mader <robert.mader@collabora.com>2023-03-02 01:40:16 +0100
commitf27ca241f9a2c519eb6b43e17c791ba33efad095 (patch)
tree6fc7afdad0fc1abc1fed89b3ad8e5df4f2378b45
parent90ae14e792a32c45f18c0ce2a556a1a97e0cf9da (diff)
downloadmutter-f27ca241f9a2c519eb6b43e17c791ba33efad095.tar.gz
renderer/native: Move per frame KMS update to MetaFrameNative
In order to make things more and more asynchronus and to each time we paint be an isolated event, that can be potentially be applied individually or together with other updates, make it so that each time we draw, we use the transient MetaFrameNative (ClutterFrame) instance to carry a KMS update for us. For this to work, we also need to restructure how we apply mode sets. Previously we'd amend the same KMS update each frame during mode set, then after the last CRTC was composited, we'd apply the update that contained updates for all CRTC. Now each CRTC has its own KMS update, and instead we put them in a per device table, and whenever we finished painting, we'll merge the new update into any existing one, and then finally once all CRTCs have been composited, we'll apply an update that contains all the mode sets for all relevant CRTCs on a device. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2855>
-rw-r--r--src/backends/native/meta-cursor-renderer-native.c23
-rw-r--r--src/backends/native/meta-cursor-renderer-native.h3
-rw-r--r--src/backends/native/meta-frame-native.c49
-rw-r--r--src/backends/native/meta-frame-native.h19
-rw-r--r--src/backends/native/meta-kms-update-private.h7
-rw-r--r--src/backends/native/meta-kms-update.h7
-rw-r--r--src/backends/native/meta-kms.c87
-rw-r--r--src/backends/native/meta-kms.h13
-rw-r--r--src/backends/native/meta-onscreen-native.c83
-rw-r--r--src/backends/native/meta-renderer-native-private.h4
-rw-r--r--src/backends/native/meta-renderer-native.c121
-rw-r--r--src/backends/native/meta-renderer-native.h1
-rw-r--r--src/backends/native/meta-stage-native.c3
-rw-r--r--src/core/util-private.h3
-rw-r--r--src/tests/native-kms-render.c14
15 files changed, 246 insertions, 191 deletions
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);
}
-void
-meta_renderer_native_post_mode_set_updates (MetaRendererNative *renderer_native)
+static void
+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;
+ GHashTableIter iter;
+ gpointer key, value;
- for (l = meta_kms_get_devices (kms); l; l = l->next)
+ g_hash_table_iter_init (&iter, renderer_native->mode_set_updates);
+ while (g_hash_table_iter_next (&iter, &key, &value))
{
- MetaKmsDevice *kms_device = l->data;
- MetaKmsUpdate *kms_update;
-
- configure_disabled_crtcs (kms_device);
+ MetaKmsDevice *kms_device = META_KMS_DEVICE (key);
+ MetaKmsUpdate *kms_update = value;
+ g_autoptr (MetaKmsFeedback) feedback = NULL;
- kms_update = meta_kms_get_pending_update (kms, kms_device);
- if (!kms_update)
- continue;
+ g_hash_table_iter_steal (&iter);
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);
+ 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));
+
+ renderer_native->pending_mode_set = FALSE;
+
+ g_list_foreach (meta_kms_get_devices (kms),
+ (GFunc) configure_disabled_crtcs,
+ renderer_native);
+
+ 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);
}
+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 (MetaBackend *backend,
- MetaKms *kms)
+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);