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>
This commit is contained in:
Jonas Ådahl 2022-10-20 21:57:25 +02:00 committed by Robert Mader
parent 90ae14e792
commit f27ca241f9
15 changed files with 248 additions and 193 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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 */

View File

@ -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);

View File

@ -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)
{

View File

@ -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,

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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);