Signed-off-by: Mingi Sung <sungmg@saltyming.net>
This commit is contained in:
parent
5f9a7581c6
commit
d32c1dd8cb
6 changed files with 1201 additions and 1129 deletions
15
.SRCINFO
15
.SRCINFO
|
@ -1,7 +1,7 @@
|
|||
pkgbase = mutter-performance
|
||||
pkgdesc = A window manager for GNOME | Attempts to improve performances with non-upstreamed merge-requests and frequent stable branch resync
|
||||
pkgver = 46.4+r18+g081b918ba
|
||||
pkgrel = 2
|
||||
pkgrel = 3
|
||||
epoch = 1
|
||||
url = https://gitlab.gnome.org/GNOME/mutter
|
||||
arch = x86_64
|
||||
|
@ -77,20 +77,17 @@ pkgbase = mutter-performance
|
|||
source = mr1441.patch
|
||||
source = mr3567.patch
|
||||
source = mr3751.patch
|
||||
source = mr3934.patch
|
||||
source = mr4015.patch
|
||||
source = mr3960.patch
|
||||
sha256sums = 81978164d9f2715438fbc623c77ea7529332cac5c4c519e4781daa5bf1a315eb
|
||||
sha256sums = 60638078a3f3c46da61f868c04b2a3424488510702648452c3e8214a3790e37b
|
||||
sha256sums = 043d6f4abce085b5ecc3debf0d334cc9fe826d256a421a4cbbe6aee8cffce255
|
||||
sha256sums = 2e474a574edad8dc047a53a920fc7cbe005cac0102907eef80a252fc556d0517
|
||||
sha256sums = 4c15b0e6d0001c8c3feedf05a9140f7f17d52eb36ff7b8039e0281c1373ccdfe
|
||||
sha256sums = c0ae2855247cddde806a320d031021fd0f7c867c61ac95af99ea3765f290bbf5
|
||||
sha256sums = 261d08c54142cd462b651e236565e2289074f53743f30afa9c62a1e20bff37e7
|
||||
sha256sums = 361af6ed4ff6039c3b24dca8cd737468b7a441ea9855f8033c8348ce1aab0f0c
|
||||
b2sums = aaed24cb5bac5f62096d44bfdf0e6acfff3944137a06f5cbd7fd1f18d03ebb816d02ab170c9128eafb023a339de3e7ea79480654687ec449d29f9e45d66218e3
|
||||
b2sums = 802cf82c0d4fa4514dc376bac57a65453df0ce789e6efac334d2f76a24349ad0a2b6e9ce02345839e8de719d7696dfcae911b1e66922103b2ec315e9fbaa8f01
|
||||
b2sums = 3231bdae36ae05892d2106199dc75a0dd8dc59b45bc77a51090ad35bec9e21420aeb86578e97fb64565b265beb7406a406362a06a091ef066965c7c9ea2fe50e
|
||||
b2sums = 65302b1fa24a7aba26915269fb694c7a64b134ee2062ec7e649036a3a41efb2f2f4110cff6194808af34985855ade641c5fb01f0b97536cd3c912892ea3a0d4c
|
||||
b2sums = f9f2284d7236d6072a818de3784a339c2d934490da8870876f49d4effd59ce807593ce8b8a3c5e06586fd5fd7e81fb31fedca84115acf1e71cfe23d4a5e727b3
|
||||
b2sums = 18e8d521336422f4c441979fe77ff22c60406e94cd2159c08bbfd127bf6b010dece55c7226b99a953c560b05194fe72e5c2140765577069d970c93479b573bcb
|
||||
b2sums = a7ce3e4288ad4b14a6b7cb4d9e3f77fc27445f46e5439bc4fe85b696c63298487909a48d4bc4238333c9f9724ba1b5779c29ef8df6a61ac9eb78dd2e83de6502
|
||||
b2sums = 9517c7c84b20ff28ccb3cfd1168eb3ca294934df6088c7938b1ff659933043d2687031b2da1eac7eaf0a8cec21284147cb925aa08584563488fce1bcef361184
|
||||
|
||||
pkgname = mutter-performance
|
||||
groups = gnome
|
||||
|
|
45
PKGBUILD
45
PKGBUILD
|
@ -11,8 +11,8 @@
|
|||
|
||||
### PACKAGE OPTIONS
|
||||
## MERGE REQUESTS SELECTION
|
||||
# Merge Requests List: ('579' '1441' '3567' '3751' '3934' '4015')
|
||||
_merge_requests_to_use=('1441' '3751' '4015')
|
||||
# Merge Requests List: ('579' '1441' '3567' '3751' '3960')
|
||||
_merge_requests_to_use=('1441' '3751' '3960')
|
||||
|
||||
|
||||
### IMPORTANT: Do no edit below this line unless you know what you're doing!
|
||||
|
@ -21,7 +21,7 @@ _pkgname=mutter
|
|||
pkgname=mutter-performance
|
||||
epoch=1
|
||||
pkgver=46.4+r18+g081b918ba
|
||||
pkgrel=2
|
||||
pkgrel=3
|
||||
pkgdesc="A window manager for GNOME | Attempts to improve performances with non-upstreamed merge-requests and frequent stable branch resync"
|
||||
url="https://gitlab.gnome.org/GNOME/mutter"
|
||||
arch=(x86_64 aarch64)
|
||||
|
@ -105,20 +105,17 @@ source=("git+$url.git#commit=$_commit"
|
|||
'mr1441.patch'
|
||||
'mr3567.patch'
|
||||
'mr3751.patch'
|
||||
'mr3934.patch'
|
||||
'mr4015.patch')
|
||||
'mr3960.patch')
|
||||
sha256sums=('81978164d9f2715438fbc623c77ea7529332cac5c4c519e4781daa5bf1a315eb'
|
||||
'60638078a3f3c46da61f868c04b2a3424488510702648452c3e8214a3790e37b'
|
||||
'043d6f4abce085b5ecc3debf0d334cc9fe826d256a421a4cbbe6aee8cffce255'
|
||||
'2e474a574edad8dc047a53a920fc7cbe005cac0102907eef80a252fc556d0517'
|
||||
'4c15b0e6d0001c8c3feedf05a9140f7f17d52eb36ff7b8039e0281c1373ccdfe'
|
||||
'c0ae2855247cddde806a320d031021fd0f7c867c61ac95af99ea3765f290bbf5'
|
||||
'261d08c54142cd462b651e236565e2289074f53743f30afa9c62a1e20bff37e7')
|
||||
'361af6ed4ff6039c3b24dca8cd737468b7a441ea9855f8033c8348ce1aab0f0c')
|
||||
b2sums=('aaed24cb5bac5f62096d44bfdf0e6acfff3944137a06f5cbd7fd1f18d03ebb816d02ab170c9128eafb023a339de3e7ea79480654687ec449d29f9e45d66218e3'
|
||||
'802cf82c0d4fa4514dc376bac57a65453df0ce789e6efac334d2f76a24349ad0a2b6e9ce02345839e8de719d7696dfcae911b1e66922103b2ec315e9fbaa8f01'
|
||||
'3231bdae36ae05892d2106199dc75a0dd8dc59b45bc77a51090ad35bec9e21420aeb86578e97fb64565b265beb7406a406362a06a091ef066965c7c9ea2fe50e'
|
||||
'65302b1fa24a7aba26915269fb694c7a64b134ee2062ec7e649036a3a41efb2f2f4110cff6194808af34985855ade641c5fb01f0b97536cd3c912892ea3a0d4c'
|
||||
'f9f2284d7236d6072a818de3784a339c2d934490da8870876f49d4effd59ce807593ce8b8a3c5e06586fd5fd7e81fb31fedca84115acf1e71cfe23d4a5e727b3'
|
||||
'18e8d521336422f4c441979fe77ff22c60406e94cd2159c08bbfd127bf6b010dece55c7226b99a953c560b05194fe72e5c2140765577069d970c93479b573bcb'
|
||||
'a7ce3e4288ad4b14a6b7cb4d9e3f77fc27445f46e5439bc4fe85b696c63298487909a48d4bc4238333c9f9724ba1b5779c29ef8df6a61ac9eb78dd2e83de6502')
|
||||
'9517c7c84b20ff28ccb3cfd1168eb3ca294934df6088c7938b1ff659933043d2687031b2da1eac7eaf0a8cec21284147cb925aa08584563488fce1bcef361184')
|
||||
|
||||
for mr in "${_merge_requests_to_use[@]}"; do
|
||||
if [ '3567' = "$mr" ]; then
|
||||
|
@ -225,24 +222,12 @@ prepare() {
|
|||
# (mostly Chromium/Electron based apps with Ozone Wayland.)
|
||||
pick_mr '3751' 'mr3751.patch' 'patch'
|
||||
|
||||
# Title: kms/impl-device: Track dispatch duration in crtc_frame_deadline_dispatch
|
||||
# Author: Michel Dänzer <mdaenzer@redhat.com>
|
||||
# URL: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3934
|
||||
# Type: 1
|
||||
# Status: 2
|
||||
# Comment: This fixes cursor stutter.
|
||||
# Do not enable this if !1441 is enabled since it already includes !3934.
|
||||
pick_mr '3934' 'mr3934.patch' 'patch'
|
||||
|
||||
# Title: onscreen/native: Use EGLSyncs instead of cogl_framebuffer_finish
|
||||
# Author: Gert <Gert-dev@users.noreply.github.com>
|
||||
# URL: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4015
|
||||
# Type: 1
|
||||
# Status: 2
|
||||
# Comment: This can unblock the CPU in situations where the primary GPU wasn't done
|
||||
# processing the queue by the time cogl_framebuffer_finish was called.
|
||||
# It is not intended to be merged in its current state and more of a proof-of-concept.
|
||||
pick_mr '4015' 'mr4015.patch' 'patch'
|
||||
# Title: kms: Inhibit real time scheduling until initial mode set
|
||||
# Author: Jonas Ådahl <jadahl@gmail.com>
|
||||
# URL: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3960
|
||||
# Type: 3
|
||||
# Status: 4
|
||||
pick_mr '3960' 'mr3960.patch' 'patch'
|
||||
|
||||
# Title: Draft: Dynamic triple/double buffering (v4)
|
||||
# Author: Daniel van Vugt <daniel.van.vugt@canonical.com>
|
||||
|
@ -250,7 +235,7 @@ prepare() {
|
|||
# Type: 1
|
||||
# Status: 2 & 3
|
||||
# Comment: Helps GPU frequencies to scale up.
|
||||
# Backported: !3934.
|
||||
# Backported: !3184 !3265 !3799 !3817 !3829 !3830 !3891 !3934 !3958 !4015
|
||||
pick_mr '1441' 'mr1441.patch' 'patch'
|
||||
|
||||
}
|
||||
|
|
926
mr1441.patch
926
mr1441.patch
File diff suppressed because it is too large
Load diff
617
mr3934.patch
617
mr3934.patch
|
@ -1,617 +0,0 @@
|
|||
From adb26372d0dc18c90293733f1c5f3b0479badf6c Mon Sep 17 00:00:00 2001
|
||||
From: Mingi Sung <sungmg@saltyming.net>
|
||||
Date: Wed, 28 Aug 2024 20:21:07 +0900
|
||||
Subject: [PATCH] Merge branch 'crtc_frame_deadline_dispatch-track-duration'
|
||||
into gnome-46
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Track dispatch duration in crtc_frame_deadline_dispatch
|
||||
and take it into account in meta_kms_crtc_get_deadline_evasion.
|
||||
|
||||
This uses the same fundamental approach as clutter frame clock scheduling:
|
||||
|
||||
Measure the deadline timer dispatch duration, keep track of the longest
|
||||
duration, and set the timer to fire such that the longest measured
|
||||
dispatch duration would result in it completing shortly before start of
|
||||
vblank.
|
||||
|
||||
Closes: #3612
|
||||
|
||||
Author: Michel Dänzer <mdaenzer@redhat.com>
|
||||
Source: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3934
|
||||
Commit: 88e7f353c482b2574927dbd06b483ebb3197379b
|
||||
|
||||
Backported: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3184
|
||||
Backported: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3265
|
||||
|
||||
Signed-off-by: Mingi Sung <sungmg@saltyming.net>
|
||||
---
|
||||
clutter/clutter/clutter-frame-clock.c | 12 ++++-
|
||||
clutter/clutter/clutter-frame-clock.h | 4 ++
|
||||
clutter/clutter/clutter-stage-view.c | 4 ++
|
||||
clutter/clutter/clutter-stage-view.h | 2 +
|
||||
src/backends/native/meta-crtc-kms.c | 10 ++++
|
||||
src/backends/native/meta-crtc-native.c | 8 ++++
|
||||
src/backends/native/meta-crtc-native.h | 3 ++
|
||||
src/backends/native/meta-crtc-virtual.c | 8 ++++
|
||||
src/backends/native/meta-kms-crtc.c | 63 ++++++++++++++++++++++---
|
||||
src/backends/native/meta-kms-crtc.h | 5 ++
|
||||
src/backends/native/meta-kms-impl-device.c | 51 ++++++++++++++++++--
|
||||
src/backends/native/meta-onscreen-native.c | 12 +++--
|
||||
src/backends/native/meta-renderer-view-native.c | 41 ++++++++++++++++
|
||||
src/core/util.c | 3 ++
|
||||
src/meta/meta-debug.h | 2 +
|
||||
src/meta/util.h | 3 ++
|
||||
src/tests/meta-monitor-manager-test.c | 6 +++
|
||||
17 files changed, 222 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/clutter/clutter/clutter-frame-clock.c b/clutter/clutter/clutter-frame-clock.c
|
||||
index 30a319f604..4bba34887a 100644
|
||||
--- a/clutter/clutter/clutter-frame-clock.c
|
||||
+++ b/clutter/clutter/clutter-frame-clock.c
|
||||
@@ -137,6 +137,8 @@ struct _ClutterFrameClock
|
||||
|
||||
int64_t last_dispatch_interval_us;
|
||||
|
||||
+ int64_t deadline_evasion_us;
|
||||
+
|
||||
char *output_name;
|
||||
};
|
||||
|
||||
@@ -389,7 +391,8 @@ clutter_frame_clock_notify_presented (ClutterFrameClock *frame_clock,
|
||||
|
||||
frame_clock->shortterm_max_update_duration_us =
|
||||
CLAMP (frame_clock->last_dispatch_lateness_us + dispatch_to_swap_us +
|
||||
- MAX (swap_to_rendering_done_us, swap_to_flip_us),
|
||||
+ MAX (swap_to_rendering_done_us,
|
||||
+ swap_to_flip_us + frame_clock->deadline_evasion_us),
|
||||
frame_clock->shortterm_max_update_duration_us,
|
||||
frame_clock->refresh_interval_us);
|
||||
|
||||
@@ -1253,3 +1256,10 @@ clutter_frame_clock_class_init (ClutterFrameClockClass *klass)
|
||||
G_TYPE_NONE,
|
||||
0);
|
||||
}
|
||||
+
|
||||
+void
|
||||
+clutter_frame_clock_set_deadline_evasion (ClutterFrameClock *frame_clock,
|
||||
+ int64_t deadline_evasion_us)
|
||||
+{
|
||||
+ frame_clock->deadline_evasion_us = deadline_evasion_us;
|
||||
+}
|
||||
diff --git a/clutter/clutter/clutter-frame-clock.h b/clutter/clutter/clutter-frame-clock.h
|
||||
index a7be5ef316..6a940f48be 100644
|
||||
--- a/clutter/clutter/clutter-frame-clock.h
|
||||
+++ b/clutter/clutter/clutter-frame-clock.h
|
||||
@@ -106,3 +106,7 @@ void clutter_frame_clock_record_flip_time (ClutterFrameClock *frame_clock,
|
||||
int64_t flip_time_us);
|
||||
|
||||
GString * clutter_frame_clock_get_max_render_time_debug_info (ClutterFrameClock *frame_clock);
|
||||
+
|
||||
+CLUTTER_EXPORT
|
||||
+void clutter_frame_clock_set_deadline_evasion (ClutterFrameClock *frame_clock,
|
||||
+ int64_t deadline_evasion_us);
|
||||
diff --git a/clutter/clutter/clutter-stage-view.c b/clutter/clutter/clutter-stage-view.c
|
||||
index f5188e2acf..2aabe9aa4c 100644
|
||||
--- a/clutter/clutter/clutter-stage-view.c
|
||||
+++ b/clutter/clutter/clutter-stage-view.c
|
||||
@@ -740,6 +740,10 @@ clutter_stage_view_schedule_update (ClutterStageView *view)
|
||||
{
|
||||
ClutterStageViewPrivate *priv =
|
||||
clutter_stage_view_get_instance_private (view);
|
||||
+ ClutterStageViewClass *view_class = CLUTTER_STAGE_VIEW_GET_CLASS (view);
|
||||
+
|
||||
+ if (view_class->schedule_update)
|
||||
+ view_class->schedule_update (view);
|
||||
|
||||
clutter_frame_clock_schedule_update (priv->frame_clock);
|
||||
}
|
||||
diff --git a/clutter/clutter/clutter-stage-view.h b/clutter/clutter/clutter-stage-view.h
|
||||
index c0888f7f94..bdaa065c00 100644
|
||||
--- a/clutter/clutter/clutter-stage-view.h
|
||||
+++ b/clutter/clutter/clutter-stage-view.h
|
||||
@@ -54,6 +54,8 @@ struct _ClutterStageViewClass
|
||||
ClutterFrame * (* new_frame) (ClutterStageView *view);
|
||||
|
||||
ClutterPaintFlag (* get_default_paint_flags) (ClutterStageView *view);
|
||||
+
|
||||
+ void (* schedule_update) (ClutterStageView *view);
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
diff --git a/src/backends/native/meta-crtc-kms.c b/src/backends/native/meta-crtc-kms.c
|
||||
index 3498f922a3..8cb0e935a7 100644
|
||||
--- a/src/backends/native/meta-crtc-kms.c
|
||||
+++ b/src/backends/native/meta-crtc-kms.c
|
||||
@@ -348,6 +348,15 @@ meta_crtc_kms_is_hw_cursor_supported (MetaCrtcNative *crtc_native)
|
||||
return meta_kms_device_has_cursor_plane_for (kms_device, kms_crtc);
|
||||
}
|
||||
|
||||
+static int64_t
|
||||
+meta_crtc_kms_get_deadline_evasion (MetaCrtcNative *crtc_native)
|
||||
+{
|
||||
+ MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc_native);
|
||||
+ MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
|
||||
+
|
||||
+ return meta_kms_crtc_get_deadline_evasion (kms_crtc);
|
||||
+}
|
||||
+
|
||||
MetaKmsPlane *
|
||||
meta_crtc_kms_get_assigned_cursor_plane (MetaCrtcKms *crtc_kms)
|
||||
{
|
||||
@@ -479,6 +488,7 @@ meta_crtc_kms_class_init (MetaCrtcKmsClass *klass)
|
||||
|
||||
crtc_native_class->is_transform_handled = meta_crtc_kms_is_transform_handled;
|
||||
crtc_native_class->is_hw_cursor_supported = meta_crtc_kms_is_hw_cursor_supported;
|
||||
+ crtc_native_class->get_deadline_evasion = meta_crtc_kms_get_deadline_evasion;
|
||||
|
||||
signals[GAMMA_LUT_CHANGED] =
|
||||
g_signal_new ("gamma-lut-changed",
|
||||
diff --git a/src/backends/native/meta-crtc-native.c b/src/backends/native/meta-crtc-native.c
|
||||
index fc280f696e..80406a5033 100644
|
||||
--- a/src/backends/native/meta-crtc-native.c
|
||||
+++ b/src/backends/native/meta-crtc-native.c
|
||||
@@ -39,6 +39,14 @@ meta_crtc_native_is_hw_cursor_supported (MetaCrtcNative *crtc_native)
|
||||
return klass->is_hw_cursor_supported (crtc_native);
|
||||
}
|
||||
|
||||
+int64_t
|
||||
+meta_crtc_native_get_deadline_evasion (MetaCrtcNative *crtc_native)
|
||||
+{
|
||||
+ MetaCrtcNativeClass *klass = META_CRTC_NATIVE_GET_CLASS (crtc_native);
|
||||
+
|
||||
+ return klass->get_deadline_evasion (crtc_native);
|
||||
+}
|
||||
+
|
||||
static void
|
||||
meta_crtc_native_init (MetaCrtcNative *crtc_native)
|
||||
{
|
||||
diff --git a/src/backends/native/meta-crtc-native.h b/src/backends/native/meta-crtc-native.h
|
||||
index 3fb4bc7586..1f9a2ed46c 100644
|
||||
--- a/src/backends/native/meta-crtc-native.h
|
||||
+++ b/src/backends/native/meta-crtc-native.h
|
||||
@@ -31,9 +31,12 @@ struct _MetaCrtcNativeClass
|
||||
gboolean (* is_transform_handled) (MetaCrtcNative *crtc_native,
|
||||
MetaMonitorTransform monitor_transform);
|
||||
gboolean (* is_hw_cursor_supported) (MetaCrtcNative *crtc_native);
|
||||
+ int64_t (* get_deadline_evasion) (MetaCrtcNative *crtc_native);
|
||||
};
|
||||
|
||||
gboolean meta_crtc_native_is_transform_handled (MetaCrtcNative *crtc_native,
|
||||
MetaMonitorTransform transform);
|
||||
|
||||
gboolean meta_crtc_native_is_hw_cursor_supported (MetaCrtcNative *crtc_native);
|
||||
+
|
||||
+int64_t meta_crtc_native_get_deadline_evasion (MetaCrtcNative *crtc_native);
|
||||
diff --git a/src/backends/native/meta-crtc-virtual.c b/src/backends/native/meta-crtc-virtual.c
|
||||
index 76165eb1bd..00b599c612 100644
|
||||
--- a/src/backends/native/meta-crtc-virtual.c
|
||||
+++ b/src/backends/native/meta-crtc-virtual.c
|
||||
@@ -70,6 +70,12 @@ meta_crtc_virtual_is_hw_cursor_supported (MetaCrtcNative *crtc_native)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+static int64_t
|
||||
+meta_crtc_virtual_get_deadline_evasion (MetaCrtcNative *crtc_native)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
meta_crtc_virtual_init (MetaCrtcVirtual *crtc_virtual)
|
||||
{
|
||||
@@ -89,4 +95,6 @@ meta_crtc_virtual_class_init (MetaCrtcVirtualClass *klass)
|
||||
meta_crtc_virtual_is_transform_handled;
|
||||
crtc_native_class->is_hw_cursor_supported =
|
||||
meta_crtc_virtual_is_hw_cursor_supported;
|
||||
+ crtc_native_class->get_deadline_evasion =
|
||||
+ meta_crtc_virtual_get_deadline_evasion;
|
||||
}
|
||||
diff --git a/src/backends/native/meta-kms-crtc.c b/src/backends/native/meta-kms-crtc.c
|
||||
index a0872089a0..cad9f88ce5 100644
|
||||
--- a/src/backends/native/meta-kms-crtc.c
|
||||
+++ b/src/backends/native/meta-kms-crtc.c
|
||||
@@ -28,8 +28,7 @@
|
||||
#include "backends/native/meta-kms-update-private.h"
|
||||
#include "backends/native/meta-kms-utils.h"
|
||||
|
||||
-#define DEADLINE_EVASION_US 800
|
||||
-#define DEADLINE_EVASION_WITH_KMS_TOPIC_US 1000
|
||||
+#define DEADLINE_EVASION_CONSTANT_US 200
|
||||
|
||||
#define MINIMUM_REFRESH_RATE 30.f
|
||||
|
||||
@@ -50,6 +49,10 @@ struct _MetaKmsCrtc
|
||||
MetaKmsCrtcState current_state;
|
||||
|
||||
MetaKmsCrtcPropTable prop_table;
|
||||
+
|
||||
+ int64_t shortterm_max_dispatch_duration_us;
|
||||
+ int64_t deadline_evasion_us;
|
||||
+ int64_t deadline_evasion_update_time_us;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaKmsCrtc, meta_kms_crtc, G_TYPE_OBJECT)
|
||||
@@ -543,6 +546,33 @@ get_crtc_type_bitmask (MetaKmsCrtc *crtc)
|
||||
}
|
||||
}
|
||||
|
||||
+static void
|
||||
+maybe_update_deadline_evasion (MetaKmsCrtc *crtc,
|
||||
+ int64_t next_presentation_time_us)
|
||||
+{
|
||||
+ /* Do not update long-term max if there has been no measurement */
|
||||
+ if (!crtc->shortterm_max_dispatch_duration_us)
|
||||
+ return;
|
||||
+
|
||||
+ if (next_presentation_time_us - crtc->deadline_evasion_update_time_us <
|
||||
+ G_USEC_PER_SEC)
|
||||
+ return;
|
||||
+
|
||||
+ if (crtc->deadline_evasion_us > crtc->shortterm_max_dispatch_duration_us)
|
||||
+ {
|
||||
+ /* Exponential drop-off toward the clamped short-term max */
|
||||
+ crtc->deadline_evasion_us -=
|
||||
+ (crtc->deadline_evasion_us - crtc->shortterm_max_dispatch_duration_us) / 2;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ crtc->deadline_evasion_us = crtc->shortterm_max_dispatch_duration_us;
|
||||
+ }
|
||||
+
|
||||
+ crtc->shortterm_max_dispatch_duration_us = 0;
|
||||
+ crtc->deadline_evasion_update_time_us = next_presentation_time_us;
|
||||
+}
|
||||
+
|
||||
gboolean
|
||||
meta_kms_crtc_determine_deadline (MetaKmsCrtc *crtc,
|
||||
int64_t *out_next_deadline_us,
|
||||
@@ -610,10 +640,8 @@ meta_kms_crtc_determine_deadline (MetaKmsCrtc *crtc,
|
||||
*
|
||||
*/
|
||||
|
||||
- if (meta_is_topic_enabled (META_DEBUG_KMS))
|
||||
- deadline_evasion_us = DEADLINE_EVASION_WITH_KMS_TOPIC_US;
|
||||
- else
|
||||
- deadline_evasion_us = DEADLINE_EVASION_US;
|
||||
+ deadline_evasion_us = meta_kms_crtc_get_deadline_evasion (crtc);
|
||||
+ maybe_update_deadline_evasion (crtc, next_presentation_us);
|
||||
|
||||
vblank_duration_us = meta_calculate_drm_mode_vblank_duration_us (drm_mode);
|
||||
next_deadline_us = next_presentation_us - (vblank_duration_us +
|
||||
@@ -625,3 +653,26 @@ meta_kms_crtc_determine_deadline (MetaKmsCrtc *crtc,
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
+
|
||||
+void
|
||||
+meta_kms_crtc_update_shortterm_max_dispatch_duration (MetaKmsCrtc *crtc,
|
||||
+ int64_t duration_us)
|
||||
+{
|
||||
+ int64_t refresh_interval_us;
|
||||
+
|
||||
+ if (duration_us <= crtc->shortterm_max_dispatch_duration_us)
|
||||
+ return;
|
||||
+
|
||||
+ refresh_interval_us =
|
||||
+ (int64_t) (0.5 + G_USEC_PER_SEC /
|
||||
+ meta_calculate_drm_mode_refresh_rate (&crtc->current_state.drm_mode));
|
||||
+
|
||||
+ crtc->shortterm_max_dispatch_duration_us = MIN (duration_us, refresh_interval_us);
|
||||
+}
|
||||
+
|
||||
+int64_t
|
||||
+meta_kms_crtc_get_deadline_evasion (MetaKmsCrtc *crtc)
|
||||
+{
|
||||
+ return MAX (crtc->shortterm_max_dispatch_duration_us,
|
||||
+ crtc->deadline_evasion_us) + DEADLINE_EVASION_CONSTANT_US;
|
||||
+}
|
||||
diff --git a/src/backends/native/meta-kms-crtc.h b/src/backends/native/meta-kms-crtc.h
|
||||
index 580ee9a89c..b293f8e7cc 100644
|
||||
--- a/src/backends/native/meta-kms-crtc.h
|
||||
+++ b/src/backends/native/meta-kms-crtc.h
|
||||
@@ -65,3 +65,8 @@ int meta_kms_crtc_get_idx (MetaKmsCrtc *crtc);
|
||||
|
||||
META_EXPORT_TEST
|
||||
gboolean meta_kms_crtc_is_active (MetaKmsCrtc *crtc);
|
||||
+
|
||||
+void meta_kms_crtc_update_shortterm_max_dispatch_duration (MetaKmsCrtc *crtc,
|
||||
+ int64_t duration_us);
|
||||
+
|
||||
+int64_t meta_kms_crtc_get_deadline_evasion (MetaKmsCrtc *crtc);
|
||||
diff --git a/src/backends/native/meta-kms-impl-device.c b/src/backends/native/meta-kms-impl-device.c
|
||||
index 6758982a6a..6ce62cd697 100644
|
||||
--- a/src/backends/native/meta-kms-impl-device.c
|
||||
+++ b/src/backends/native/meta-kms-impl-device.c
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "backends/native/meta-kms-plane-private.h"
|
||||
#include "backends/native/meta-kms-plane.h"
|
||||
#include "backends/native/meta-kms-private.h"
|
||||
+#include "backends/native/meta-kms-utils.h"
|
||||
#include "backends/native/meta-thread-private.h"
|
||||
|
||||
#include "meta-default-modes.h"
|
||||
@@ -71,6 +72,7 @@ typedef struct _CrtcDeadline
|
||||
GSource *source;
|
||||
gboolean armed;
|
||||
gboolean is_deadline_page_flip;
|
||||
+ int64_t expected_deadline_time_us;
|
||||
int64_t expected_presentation_time_us;
|
||||
gboolean has_expected_presentation_time;
|
||||
} deadline;
|
||||
@@ -1165,6 +1167,7 @@ arm_crtc_frame_deadline_timer (CrtcFrame *crtc_frame,
|
||||
timerfd_settime (crtc_frame->deadline.timer_fd,
|
||||
TFD_TIMER_ABSTIME, &its, NULL);
|
||||
|
||||
+ crtc_frame->deadline.expected_deadline_time_us = next_deadline_us;
|
||||
crtc_frame->deadline.expected_presentation_time_us = next_presentation_us;
|
||||
crtc_frame->deadline.has_expected_presentation_time = next_presentation_us != 0;
|
||||
crtc_frame->deadline.armed = TRUE;
|
||||
@@ -1197,7 +1200,7 @@ crtc_page_flip_feedback_flipped (MetaKmsCrtc *crtc,
|
||||
CrtcFrame *crtc_frame = user_data;
|
||||
|
||||
if (crtc_frame->deadline.is_deadline_page_flip &&
|
||||
- meta_is_topic_enabled (META_DEBUG_KMS))
|
||||
+ meta_is_topic_enabled (META_DEBUG_KMS_DEADLINE))
|
||||
{
|
||||
struct timeval page_flip_timeval;
|
||||
int64_t presentation_time_us;
|
||||
@@ -1210,7 +1213,7 @@ crtc_page_flip_feedback_flipped (MetaKmsCrtc *crtc,
|
||||
|
||||
if (crtc_frame->deadline.has_expected_presentation_time)
|
||||
{
|
||||
- meta_topic (META_DEBUG_KMS,
|
||||
+ meta_topic (META_DEBUG_KMS_DEADLINE,
|
||||
"Deadline page flip presentation time: %" G_GINT64_FORMAT " us, "
|
||||
"expected %" G_GINT64_FORMAT " us "
|
||||
"(diff: %" G_GINT64_FORMAT ")",
|
||||
@@ -1221,7 +1224,7 @@ crtc_page_flip_feedback_flipped (MetaKmsCrtc *crtc,
|
||||
}
|
||||
else
|
||||
{
|
||||
- meta_topic (META_DEBUG_KMS,
|
||||
+ meta_topic (META_DEBUG_KMS_DEADLINE,
|
||||
"Deadline page flip presentation time: %" G_GINT64_FORMAT " us",
|
||||
presentation_time_us);
|
||||
}
|
||||
@@ -1390,11 +1393,16 @@ crtc_frame_deadline_dispatch (MetaThreadImpl *thread_impl,
|
||||
GError **error)
|
||||
{
|
||||
CrtcFrame *crtc_frame = user_data;
|
||||
- MetaKmsDevice *device = meta_kms_crtc_get_device (crtc_frame->crtc);
|
||||
+ MetaKmsCrtc *crtc = crtc_frame->crtc;
|
||||
+ MetaKmsDevice *device = meta_kms_crtc_get_device (crtc);
|
||||
MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device);
|
||||
g_autoptr (MetaKmsFeedback) feedback = NULL;
|
||||
uint64_t timer_value;
|
||||
ssize_t ret;
|
||||
+ int64_t dispatch_time_us = 0, update_done_time_us, interval_us;
|
||||
+
|
||||
+ if (meta_is_topic_enabled (META_DEBUG_KMS_DEADLINE))
|
||||
+ dispatch_time_us = g_get_monotonic_time ();
|
||||
|
||||
ret = read (crtc_frame->deadline.timer_fd,
|
||||
&timer_value,
|
||||
@@ -1416,6 +1424,36 @@ crtc_frame_deadline_dispatch (MetaThreadImpl *thread_impl,
|
||||
crtc_frame->crtc,
|
||||
g_steal_pointer (&crtc_frame->pending_update),
|
||||
META_KMS_UPDATE_FLAG_NONE);
|
||||
+
|
||||
+ update_done_time_us = g_get_monotonic_time ();
|
||||
+ /* Calculate how long after the planned start of deadline dispatch it finished */
|
||||
+ interval_us = update_done_time_us - crtc_frame->deadline.expected_deadline_time_us;
|
||||
+
|
||||
+ if (meta_is_topic_enabled (META_DEBUG_KMS_DEADLINE))
|
||||
+ {
|
||||
+ int64_t deadline_evasion_us, lateness_us, duration_us, vblank_delta_us;
|
||||
+
|
||||
+ deadline_evasion_us = meta_kms_crtc_get_deadline_evasion (crtc);
|
||||
+ lateness_us = dispatch_time_us -
|
||||
+ crtc_frame->deadline.expected_deadline_time_us;
|
||||
+ duration_us = update_done_time_us - dispatch_time_us;
|
||||
+ vblank_delta_us = deadline_evasion_us - lateness_us - duration_us;
|
||||
+
|
||||
+ meta_topic (META_DEBUG_KMS_DEADLINE,
|
||||
+ "Deadline evasion %3"G_GINT64_FORMAT "µs, "
|
||||
+ "dispatch started %3"G_GINT64_FORMAT "µs %s and "
|
||||
+ "completed %3"G_GINT64_FORMAT "µs after that, "
|
||||
+ "%3"G_GINT64_FORMAT "µs %s start of vblank.",
|
||||
+ deadline_evasion_us,
|
||||
+ ABS (lateness_us),
|
||||
+ lateness_us >= 0 ? "late" : "early",
|
||||
+ duration_us,
|
||||
+ ABS (vblank_delta_us),
|
||||
+ vblank_delta_us >= 0 ? "before" : "after");
|
||||
+ }
|
||||
+
|
||||
+ meta_kms_crtc_update_shortterm_max_dispatch_duration (crtc, interval_us);
|
||||
+
|
||||
if (meta_kms_feedback_did_pass (feedback))
|
||||
crtc_frame->deadline.is_deadline_page_flip = TRUE;
|
||||
disarm_crtc_frame_deadline_timer (crtc_frame);
|
||||
@@ -1592,6 +1630,11 @@ meta_kms_impl_device_handle_update (MetaKmsImplDevice *impl_device,
|
||||
meta_kms_device_handle_flush (priv->device, latch_crtc);
|
||||
|
||||
feedback = do_process (impl_device, latch_crtc, update, flags);
|
||||
+
|
||||
+ if (meta_kms_feedback_did_pass (feedback) &&
|
||||
+ crtc_frame->deadline.armed)
|
||||
+ disarm_crtc_frame_deadline_timer (crtc_frame);
|
||||
+
|
||||
meta_kms_feedback_unref (feedback);
|
||||
return;
|
||||
|
||||
diff --git a/src/backends/native/meta-onscreen-native.c b/src/backends/native/meta-onscreen-native.c
|
||||
index 9b739faf39..b790c1e5c8 100644
|
||||
--- a/src/backends/native/meta-onscreen-native.c
|
||||
+++ b/src/backends/native/meta-onscreen-native.c
|
||||
@@ -1786,11 +1786,15 @@ meta_onscreen_native_before_redraw (CoglOnscreen *onscreen,
|
||||
ClutterFrame *frame)
|
||||
{
|
||||
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);
|
||||
|
||||
- meta_kms_device_await_flush (meta_kms_crtc_get_device (kms_crtc),
|
||||
- kms_crtc);
|
||||
+ if (meta_get_debug_paint_flags () & META_DEBUG_PAINT_SYNC_CURSOR_PRIMARY)
|
||||
+ {
|
||||
+ MetaCrtcKms *crtc_kms = META_CRTC_KMS (onscreen_native->crtc);
|
||||
+ MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
|
||||
+
|
||||
+ meta_kms_device_await_flush (meta_kms_crtc_get_device (kms_crtc), kms_crtc);
|
||||
+ }
|
||||
+
|
||||
maybe_update_frame_sync (onscreen_native, frame);
|
||||
}
|
||||
|
||||
diff --git a/src/backends/native/meta-renderer-view-native.c b/src/backends/native/meta-renderer-view-native.c
|
||||
index a04e2e3533..5699f9a558 100644
|
||||
--- a/src/backends/native/meta-renderer-view-native.c
|
||||
+++ b/src/backends/native/meta-renderer-view-native.c
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "backends/native/meta-renderer-view-native.h"
|
||||
|
||||
+#include "backends/native/meta-crtc-native.h"
|
||||
#include "backends/native/meta-frame-native.h"
|
||||
|
||||
struct _MetaRendererViewNative
|
||||
@@ -34,18 +35,58 @@ struct _MetaRendererViewNative
|
||||
G_DEFINE_TYPE (MetaRendererViewNative, meta_renderer_view_native,
|
||||
META_TYPE_RENDERER_VIEW)
|
||||
|
||||
+static void
|
||||
+update_frame_clock_deadline_evasion (MetaRendererView *renderer_view)
|
||||
+{
|
||||
+ ClutterStageView *stage_view = CLUTTER_STAGE_VIEW (renderer_view);
|
||||
+ ClutterFrameClock *frame_clock;
|
||||
+ MetaCrtc *crtc;
|
||||
+ MetaCrtcNative *crtc_native;
|
||||
+ int64_t deadline_evasion_us;
|
||||
+
|
||||
+ frame_clock = clutter_stage_view_get_frame_clock (stage_view);
|
||||
+ crtc = meta_renderer_view_get_crtc (renderer_view);
|
||||
+ crtc_native = META_CRTC_NATIVE (crtc);
|
||||
+
|
||||
+ deadline_evasion_us = meta_crtc_native_get_deadline_evasion (crtc_native);
|
||||
+ clutter_frame_clock_set_deadline_evasion (frame_clock,
|
||||
+ deadline_evasion_us);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+meta_renderer_view_native_constructed (GObject *object)
|
||||
+{
|
||||
+ MetaRendererView *renderer_view = META_RENDERER_VIEW (object);
|
||||
+
|
||||
+ G_OBJECT_CLASS (meta_renderer_view_native_parent_class)->constructed (object);
|
||||
+
|
||||
+ update_frame_clock_deadline_evasion (renderer_view);
|
||||
+}
|
||||
+
|
||||
static ClutterFrame *
|
||||
meta_renderer_view_native_new_frame (ClutterStageView *stage_view)
|
||||
{
|
||||
return (ClutterFrame *) meta_frame_native_new ();
|
||||
}
|
||||
|
||||
+static void
|
||||
+meta_renderer_view_native_schedule_update (ClutterStageView *stage_view)
|
||||
+{
|
||||
+ MetaRendererView *renderer_view = META_RENDERER_VIEW (stage_view);
|
||||
+
|
||||
+ update_frame_clock_deadline_evasion (renderer_view);
|
||||
+}
|
||||
+
|
||||
static void
|
||||
meta_renderer_view_native_class_init (MetaRendererViewNativeClass *klass)
|
||||
{
|
||||
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
ClutterStageViewClass *stage_view_class = CLUTTER_STAGE_VIEW_CLASS (klass);
|
||||
|
||||
+ object_class->constructed = meta_renderer_view_native_constructed;
|
||||
+
|
||||
stage_view_class->new_frame = meta_renderer_view_native_new_frame;
|
||||
+ stage_view_class->schedule_update = meta_renderer_view_native_schedule_update;
|
||||
}
|
||||
|
||||
static void
|
||||
diff --git a/src/core/util.c b/src/core/util.c
|
||||
index 05a0dea398..f8a08c747f 100644
|
||||
--- a/src/core/util.c
|
||||
+++ b/src/core/util.c
|
||||
@@ -69,6 +69,7 @@ static const GDebugKey meta_debug_keys[] = {
|
||||
{ "color", META_DEBUG_COLOR },
|
||||
{ "input-events", META_DEBUG_INPUT_EVENTS },
|
||||
{ "eis", META_DEBUG_EIS },
|
||||
+ { "kms-deadline", META_DEBUG_KMS_DEADLINE },
|
||||
};
|
||||
|
||||
static gint verbose_topics = 0;
|
||||
@@ -326,6 +327,8 @@ meta_topic_to_string (MetaDebugTopic topic)
|
||||
return "INPUT_EVENTS";
|
||||
case META_DEBUG_EIS:
|
||||
return "EIS";
|
||||
+ case META_DEBUG_KMS_DEADLINE:
|
||||
+ return "KMS_DEADLINE";
|
||||
}
|
||||
|
||||
return "WM";
|
||||
diff --git a/src/meta/meta-debug.h b/src/meta/meta-debug.h
|
||||
index b4c70144b7..2de9a89d75 100644
|
||||
--- a/src/meta/meta-debug.h
|
||||
+++ b/src/meta/meta-debug.h
|
||||
@@ -50,6 +50,7 @@
|
||||
* @META_DEBUG_COLOR: color management
|
||||
* @META_DEBUG_INPUT_EVENTS: input events
|
||||
* @META_DEBUG_EIS: eis state
|
||||
+ * @META_DEBUG_KMS_DEADLINE: KMS deadline timers
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
@@ -83,6 +84,7 @@ typedef enum
|
||||
META_DEBUG_COLOR = 1 << 26,
|
||||
META_DEBUG_INPUT_EVENTS = 1 << 27,
|
||||
META_DEBUG_EIS = 1 << 28,
|
||||
+ META_DEBUG_KMS_DEADLINE = 1 << 29,
|
||||
} MetaDebugTopic;
|
||||
|
||||
META_EXPORT
|
||||
diff --git a/src/meta/util.h b/src/meta/util.h
|
||||
index ca8ca2adeb..91ca6a8366 100644
|
||||
--- a/src/meta/util.h
|
||||
+++ b/src/meta/util.h
|
||||
@@ -51,11 +51,14 @@ void meta_fatal (const char *format,
|
||||
* MetaDebugPaintFlag:
|
||||
* @META_DEBUG_PAINT_NONE: default
|
||||
* @META_DEBUG_PAINT_OPAQUE_REGION: paint opaque regions
|
||||
+ * @META_DEBUG_PAINT_SYNC_CURSOR_PRIMARY: make cursor updates await compositing
|
||||
+ * frames
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
META_DEBUG_PAINT_NONE = 0,
|
||||
META_DEBUG_PAINT_OPAQUE_REGION = 1 << 0,
|
||||
+ META_DEBUG_PAINT_SYNC_CURSOR_PRIMARY = 1 << 1,
|
||||
} MetaDebugPaintFlag;
|
||||
|
||||
META_EXPORT
|
||||
diff --git a/src/tests/meta-monitor-manager-test.c b/src/tests/meta-monitor-manager-test.c
|
||||
index f9275160c3..fd37eab380 100644
|
||||
--- a/src/tests/meta-monitor-manager-test.c
|
||||
+++ b/src/tests/meta-monitor-manager-test.c
|
||||
@@ -517,6 +517,12 @@ meta_crtc_test_set_gamma_lut (MetaCrtc *crtc,
|
||||
sizeof (uint16_t) * lut->size);
|
||||
}
|
||||
|
||||
+static int64_t
|
||||
+meta_crtc_test_get_deadline_evasion (MetaCrtcNative *crtc_native)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
meta_crtc_test_finalize (GObject *object)
|
||||
{
|
322
mr3960.patch
Normal file
322
mr3960.patch
Normal file
|
@ -0,0 +1,322 @@
|
|||
From 36a1a74f7a6ea674e3911e89935256f1c6c5a149 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
||||
Date: Tue, 20 Aug 2024 11:07:29 +0200
|
||||
Subject: [PATCH] kms: Inhibit real time scheduling until initial mode set
|
||||
|
||||
We're already inhibiting real time scheduling when reading new KMS state
|
||||
after hot plugs, as well as when during mode sets, due to the kernel not
|
||||
being able to reliably handle these within the 250 ms limit. However, we
|
||||
didn't do this during initial probing, which meant that occasionally
|
||||
we'd run into these kind of issues during startup.
|
||||
|
||||
Handle this by always inhibiting real time scheduling up front, and
|
||||
don't uninhibit until all initially discovered device have finished
|
||||
processing their initial mode set.
|
||||
|
||||
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/3628
|
||||
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3960>
|
||||
|
||||
Signed-off-by: Mingi Sung <sungmg@saltyming.net>
|
||||
---
|
||||
src/backends/native/meta-backend-native.c | 3 ++
|
||||
src/backends/native/meta-kms-impl-device.c | 32 ++++++++++++++++++++++
|
||||
src/backends/native/meta-kms-impl.c | 20 ++++++++++++++
|
||||
src/backends/native/meta-kms-impl.h | 2 ++
|
||||
src/backends/native/meta-kms.c | 17 ++++++++++++
|
||||
src/backends/native/meta-kms.h | 2 ++
|
||||
src/backends/native/meta-thread-impl.c | 9 ++++++
|
||||
src/backends/native/meta-thread-impl.h | 4 +++
|
||||
src/backends/native/meta-thread.c | 26 ++++++++++++------
|
||||
9 files changed, 106 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c
|
||||
index 131a687e21..e3ed02894a 100644
|
||||
--- a/src/backends/native/meta-backend-native.c
|
||||
+++ b/src/backends/native/meta-backend-native.c
|
||||
@@ -609,6 +609,7 @@ init_gpus (MetaBackendNative *native,
|
||||
{
|
||||
MetaBackend *backend = META_BACKEND (native);
|
||||
MetaUdev *udev = meta_backend_native_get_udev (native);
|
||||
+ MetaKms *kms = meta_backend_native_get_kms (native);
|
||||
g_autoptr (GError) local_error = NULL;
|
||||
MetaUdevDeviceType device_type = 0;
|
||||
GList *devices;
|
||||
@@ -669,6 +670,8 @@ init_gpus (MetaBackendNative *native,
|
||||
|
||||
g_list_free_full (devices, g_object_unref);
|
||||
|
||||
+ meta_kms_notify_probed (kms);
|
||||
+
|
||||
if (!meta_backend_is_headless (backend) &&
|
||||
g_list_length (meta_backend_get_gpus (backend)) == 0)
|
||||
{
|
||||
diff --git a/src/backends/native/meta-kms-impl-device.c b/src/backends/native/meta-kms-impl-device.c
|
||||
index 6758982a6a..f73aecac7a 100644
|
||||
--- a/src/backends/native/meta-kms-impl-device.c
|
||||
+++ b/src/backends/native/meta-kms-impl-device.c
|
||||
@@ -108,6 +108,8 @@ typedef struct _MetaKmsImplDevicePrivate
|
||||
|
||||
GHashTable *crtc_frames;
|
||||
|
||||
+ gboolean realtime_inhibited_pending_mode_set;
|
||||
+
|
||||
MetaDeadlineTimerState deadline_timer_state;
|
||||
|
||||
gboolean sync_file_retrieved;
|
||||
@@ -1734,6 +1736,12 @@ process_mode_set_update (MetaKmsImplDevice *impl_device,
|
||||
feedback = do_process (impl_device, NULL, update, flags);
|
||||
meta_thread_uninhibit_realtime_in_impl (thread);
|
||||
|
||||
+ if (priv->realtime_inhibited_pending_mode_set)
|
||||
+ {
|
||||
+ priv->realtime_inhibited_pending_mode_set = FALSE;
|
||||
+ meta_thread_uninhibit_realtime_in_impl (thread);
|
||||
+ }
|
||||
+
|
||||
return feedback;
|
||||
}
|
||||
|
||||
@@ -1924,6 +1932,15 @@ meta_kms_impl_device_finalize (GObject *object)
|
||||
MetaKmsImplDevicePrivate *priv =
|
||||
meta_kms_impl_device_get_instance_private (impl_device);
|
||||
|
||||
+ if (priv->realtime_inhibited_pending_mode_set)
|
||||
+ {
|
||||
+ MetaThreadImpl *thread_impl = META_THREAD_IMPL (priv->impl);
|
||||
+ MetaThread *thread = meta_thread_impl_get_thread (thread_impl);
|
||||
+
|
||||
+ priv->realtime_inhibited_pending_mode_set = FALSE;
|
||||
+ meta_thread_uninhibit_realtime_in_impl (thread);
|
||||
+ }
|
||||
+
|
||||
meta_kms_impl_remove_impl_device (priv->impl, impl_device);
|
||||
|
||||
g_list_free_full (priv->planes, g_object_unref);
|
||||
@@ -1973,6 +1990,16 @@ meta_kms_impl_device_init_mode_setting (MetaKmsImplDevice *impl_device,
|
||||
|
||||
update_connectors (impl_device, drm_resources, 0);
|
||||
|
||||
+ if (!priv->crtcs)
|
||||
+ {
|
||||
+ MetaThreadImpl *thread_impl = META_THREAD_IMPL (priv->impl);
|
||||
+ MetaThread *thread = meta_thread_impl_get_thread (thread_impl);
|
||||
+
|
||||
+ g_warn_if_fail (priv->realtime_inhibited_pending_mode_set);
|
||||
+ meta_thread_uninhibit_realtime_in_impl (thread);
|
||||
+ priv->realtime_inhibited_pending_mode_set = FALSE;
|
||||
+ }
|
||||
+
|
||||
drmModeFreeResources (drm_resources);
|
||||
|
||||
return TRUE;
|
||||
@@ -2050,6 +2077,8 @@ meta_kms_impl_device_initable_init (GInitable *initable,
|
||||
MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (initable);
|
||||
MetaKmsImplDevicePrivate *priv =
|
||||
meta_kms_impl_device_get_instance_private (impl_device);
|
||||
+ MetaThreadImpl *thread_impl = META_THREAD_IMPL (priv->impl);
|
||||
+ MetaThread *thread = meta_thread_impl_get_thread (thread_impl);
|
||||
int fd;
|
||||
|
||||
if (!ensure_device_file (impl_device, error))
|
||||
@@ -2075,6 +2104,9 @@ meta_kms_impl_device_initable_init (GInitable *initable,
|
||||
|
||||
priv->sync_file = -1;
|
||||
|
||||
+ meta_thread_inhibit_realtime_in_impl (thread);
|
||||
+ priv->realtime_inhibited_pending_mode_set = TRUE;
|
||||
+
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
diff --git a/src/backends/native/meta-kms-impl.c b/src/backends/native/meta-kms-impl.c
|
||||
index 99019ca85f..e34af98202 100644
|
||||
--- a/src/backends/native/meta-kms-impl.c
|
||||
+++ b/src/backends/native/meta-kms-impl.c
|
||||
@@ -172,12 +172,32 @@ meta_kms_impl_finalize (GObject *object)
|
||||
G_OBJECT_CLASS (meta_kms_impl_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
+static void
|
||||
+meta_kms_impl_setup (MetaThreadImpl *thread_impl)
|
||||
+{
|
||||
+ MetaThread *thread = meta_thread_impl_get_thread (thread_impl);
|
||||
+
|
||||
+ meta_thread_inhibit_realtime_in_impl (thread);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+meta_kms_impl_notify_probed (MetaKmsImpl *impl)
|
||||
+{
|
||||
+ MetaThreadImpl *thread_impl = META_THREAD_IMPL (impl);
|
||||
+ MetaThread *thread = meta_thread_impl_get_thread (thread_impl);
|
||||
+
|
||||
+ meta_thread_uninhibit_realtime_in_impl (thread);
|
||||
+}
|
||||
+
|
||||
static void
|
||||
meta_kms_impl_class_init (MetaKmsImplClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
+ MetaThreadImplClass *thread_impl_class = META_THREAD_IMPL_CLASS (klass);
|
||||
|
||||
object_class->finalize = meta_kms_impl_finalize;
|
||||
+
|
||||
+ thread_impl_class->setup = meta_kms_impl_setup;
|
||||
}
|
||||
|
||||
MetaKmsUpdateFilter *
|
||||
diff --git a/src/backends/native/meta-kms-impl.h b/src/backends/native/meta-kms-impl.h
|
||||
index f8379fab28..582bebf5e6 100644
|
||||
--- a/src/backends/native/meta-kms-impl.h
|
||||
+++ b/src/backends/native/meta-kms-impl.h
|
||||
@@ -53,6 +53,8 @@ void meta_kms_impl_notify_modes_set (MetaKmsImpl *impl);
|
||||
|
||||
MetaKmsImpl * meta_kms_impl_new (MetaKms *kms);
|
||||
|
||||
+void meta_kms_impl_notify_probed (MetaKmsImpl *impl);
|
||||
+
|
||||
MetaKmsUpdateFilter * meta_kms_impl_add_update_filter (MetaKmsImpl *impl,
|
||||
MetaKmsUpdateFilterFunc func,
|
||||
gpointer user_data);
|
||||
diff --git a/src/backends/native/meta-kms.c b/src/backends/native/meta-kms.c
|
||||
index d41fcefb5a..d989337a10 100644
|
||||
--- a/src/backends/native/meta-kms.c
|
||||
+++ b/src/backends/native/meta-kms.c
|
||||
@@ -413,6 +413,23 @@ meta_kms_new (MetaBackend *backend,
|
||||
return kms;
|
||||
}
|
||||
|
||||
+static gpointer
|
||||
+notify_probed_in_impl (MetaThreadImpl *thread_impl,
|
||||
+ gpointer user_data,
|
||||
+ GError **error)
|
||||
+{
|
||||
+ meta_kms_impl_notify_probed (META_KMS_IMPL (thread_impl));
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+meta_kms_notify_probed (MetaKms *kms)
|
||||
+{
|
||||
+ meta_thread_post_impl_task (META_THREAD (kms),
|
||||
+ notify_probed_in_impl,
|
||||
+ NULL, NULL, NULL, NULL);
|
||||
+}
|
||||
+
|
||||
static void
|
||||
meta_kms_finalize (GObject *object)
|
||||
{
|
||||
diff --git a/src/backends/native/meta-kms.h b/src/backends/native/meta-kms.h
|
||||
index 7434014063..057c7a2348 100644
|
||||
--- a/src/backends/native/meta-kms.h
|
||||
+++ b/src/backends/native/meta-kms.h
|
||||
@@ -64,6 +64,8 @@ MetaKms * meta_kms_new (MetaBackend *backend,
|
||||
MetaKmsFlags flags,
|
||||
GError **error);
|
||||
|
||||
+void meta_kms_notify_probed (MetaKms *kms);
|
||||
+
|
||||
META_EXPORT_TEST
|
||||
void meta_kms_inhibit_kernel_thread (MetaKms *kms);
|
||||
|
||||
diff --git a/src/backends/native/meta-thread-impl.c b/src/backends/native/meta-thread-impl.c
|
||||
index 28ef349f7c..d02d49203f 100644
|
||||
--- a/src/backends/native/meta-thread-impl.c
|
||||
+++ b/src/backends/native/meta-thread-impl.c
|
||||
@@ -568,6 +568,15 @@ meta_thread_impl_dispatch (MetaThreadImpl *thread_impl)
|
||||
return 1;
|
||||
}
|
||||
|
||||
+void
|
||||
+meta_thread_impl_setup (MetaThreadImpl *thread_impl)
|
||||
+{
|
||||
+ MetaThreadImplClass *klass = META_THREAD_IMPL_GET_CLASS (thread_impl);
|
||||
+
|
||||
+ if (klass->setup)
|
||||
+ klass->setup (thread_impl);
|
||||
+}
|
||||
+
|
||||
void
|
||||
meta_thread_impl_run (MetaThreadImpl *thread_impl,
|
||||
MetaThreadImplRunFlags flags)
|
||||
diff --git a/src/backends/native/meta-thread-impl.h b/src/backends/native/meta-thread-impl.h
|
||||
index 2083b3bf16..1837c465cb 100644
|
||||
--- a/src/backends/native/meta-thread-impl.h
|
||||
+++ b/src/backends/native/meta-thread-impl.h
|
||||
@@ -38,6 +38,8 @@ G_DECLARE_DERIVABLE_TYPE (MetaThreadImpl, meta_thread_impl,
|
||||
struct _MetaThreadImplClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
+
|
||||
+ void (* setup) (MetaThreadImpl *thread_impl);
|
||||
};
|
||||
|
||||
typedef enum _MetaThreadTaskFeedbackType
|
||||
@@ -70,6 +72,8 @@ void meta_thread_impl_queue_task (MetaThreadImpl *thread_impl,
|
||||
|
||||
void meta_thread_impl_terminate (MetaThreadImpl *thread_impl);
|
||||
|
||||
+void meta_thread_impl_setup (MetaThreadImpl *thread_impl);
|
||||
+
|
||||
void meta_thread_impl_run (MetaThreadImpl *thread_impl,
|
||||
MetaThreadImplRunFlags flags);
|
||||
|
||||
diff --git a/src/backends/native/meta-thread.c b/src/backends/native/meta-thread.c
|
||||
index 08bd9b8fe2..5dcdb05eba 100644
|
||||
--- a/src/backends/native/meta-thread.c
|
||||
+++ b/src/backends/native/meta-thread.c
|
||||
@@ -333,22 +333,28 @@ request_normal_scheduling (MetaThread *thread,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
-should_use_realtime_scheduling_in_impl (MetaThread *thread)
|
||||
+can_use_realtime_scheduling_in_impl (MetaThread *thread)
|
||||
{
|
||||
MetaThreadPrivate *priv = meta_thread_get_instance_private (thread);
|
||||
- gboolean should_use_realtime_scheduling = FALSE;
|
||||
|
||||
switch (priv->thread_type)
|
||||
{
|
||||
case META_THREAD_TYPE_USER:
|
||||
- break;
|
||||
+ return FALSE;
|
||||
case META_THREAD_TYPE_KERNEL:
|
||||
- if (priv->wants_realtime && priv->kernel.realtime_inhibit_count == 0)
|
||||
- should_use_realtime_scheduling = TRUE;
|
||||
- break;
|
||||
+ return priv->wants_realtime;
|
||||
}
|
||||
|
||||
- return should_use_realtime_scheduling;
|
||||
+ g_assert_not_reached ();
|
||||
+}
|
||||
+
|
||||
+static gboolean
|
||||
+should_use_realtime_scheduling_in_impl (MetaThread *thread)
|
||||
+{
|
||||
+ MetaThreadPrivate *priv = meta_thread_get_instance_private (thread);
|
||||
+
|
||||
+ return (can_use_realtime_scheduling_in_impl (thread) &&
|
||||
+ priv->kernel.realtime_inhibit_count == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -417,11 +423,13 @@ thread_impl_func (gpointer user_data)
|
||||
priv->kernel.realtime_inhibit_count = 0;
|
||||
priv->kernel.is_realtime = FALSE;
|
||||
|
||||
+ meta_thread_impl_setup (impl);
|
||||
+
|
||||
sync_realtime_scheduling_in_impl (thread);
|
||||
|
||||
- if (priv->kernel.is_realtime)
|
||||
+ if (can_use_realtime_scheduling_in_impl (thread))
|
||||
{
|
||||
- g_message ("Made thread '%s' realtime scheduled", priv->name);
|
||||
+ g_message ("Thread '%s' will be using real time scheduling", priv->name);
|
||||
run_flags |= META_THREAD_IMPL_RUN_FLAG_REALTIME;
|
||||
}
|
||||
|
||||
--
|
||||
2.46.0
|
||||
|
345
mr4015.patch
345
mr4015.patch
|
@ -1,345 +0,0 @@
|
|||
From cf97df46f751470b6df99376840842afc211636d Mon Sep 17 00:00:00 2001
|
||||
From: Gert <Gert-dev@users.noreply.github.com>
|
||||
Date: Thu, 12 Sep 2024 20:13:33 +0200
|
||||
Subject: [PATCH] onscreen/native: Use EGLSyncs instead of
|
||||
cogl_framebuffer_finish
|
||||
|
||||
cogl_framebuffer_finish can result in a CPU-side stall because it waits for
|
||||
the primary GPU to flush and execute all commands that were queued before
|
||||
that. By using a GPU-side EGLSync we can let the primary GPU inform us when
|
||||
it is done with the queued commands instead. We then create another EGLSync
|
||||
on the secondary GPU using the same fd so the primary GPU effectively
|
||||
signals the secondary GPU when it is done rendering, causing the latter
|
||||
to wait for the former before copying part of the frames it needs for
|
||||
monitors attached to it directly.
|
||||
|
||||
This solves the corruption that cogl_framebuffer_finish also solved, but
|
||||
without needing a CPU-side stall.
|
||||
---
|
||||
src/backends/meta-egl.c | 94 +++++++++++++++++++
|
||||
src/backends/meta-egl.h | 23 +++++
|
||||
src/backends/native/meta-onscreen-native.c | 100 ++++++++++++++++++---
|
||||
3 files changed, 206 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/src/backends/meta-egl.c b/src/backends/meta-egl.c
|
||||
index cc023f705c4..9e9fada375a 100644
|
||||
--- a/src/backends/meta-egl.c
|
||||
+++ b/src/backends/meta-egl.c
|
||||
@@ -44,6 +44,11 @@ struct _MetaEgl
|
||||
PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR;
|
||||
PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR;
|
||||
|
||||
+ PFNEGLCREATESYNCPROC eglCreateSync;
|
||||
+ PFNEGLDESTROYSYNCPROC eglDestroySync;
|
||||
+ PFNEGLWAITSYNCPROC eglWaitSync;
|
||||
+ PFNEGLDUPNATIVEFENCEFDANDROIDPROC eglDupNativeFenceFDANDROID;
|
||||
+
|
||||
PFNEGLBINDWAYLANDDISPLAYWL eglBindWaylandDisplayWL;
|
||||
PFNEGLQUERYWAYLANDBUFFERWL eglQueryWaylandBufferWL;
|
||||
|
||||
@@ -1162,6 +1167,90 @@ meta_egl_query_display_attrib (MetaEgl *egl,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+gboolean
|
||||
+meta_egl_create_sync (MetaEgl *egl,
|
||||
+ EGLDisplay display,
|
||||
+ EGLenum type,
|
||||
+ const EGLAttrib *attrib_list,
|
||||
+ EGLSync *egl_sync,
|
||||
+ GError **error)
|
||||
+{
|
||||
+ if (!is_egl_proc_valid (egl->eglCreateSync, error))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ EGLSync sync;
|
||||
+
|
||||
+ sync = egl->eglCreateSync(display, type, attrib_list);
|
||||
+
|
||||
+ if (sync == EGL_NO_SYNC)
|
||||
+ {
|
||||
+ set_egl_error (error);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ *egl_sync = sync;
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+gboolean
|
||||
+meta_egl_destroy_sync (MetaEgl *egl,
|
||||
+ EGLDisplay display,
|
||||
+ EGLSync sync,
|
||||
+ GError **error)
|
||||
+{
|
||||
+ if (!is_egl_proc_valid (egl->eglDestroySync, error))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (!egl->eglDestroySync (display, sync))
|
||||
+ {
|
||||
+ set_egl_error (error);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+gboolean
|
||||
+meta_egl_wait_sync (MetaEgl *egl,
|
||||
+ EGLDisplay display,
|
||||
+ EGLSync sync,
|
||||
+ EGLint flags,
|
||||
+ GError **error)
|
||||
+{
|
||||
+ if (!is_egl_proc_valid (egl->eglWaitSync, error))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (!egl->eglWaitSync (display, sync, flags))
|
||||
+ {
|
||||
+ set_egl_error (error);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+EGLint
|
||||
+meta_egl_duplicate_native_fence_fd (MetaEgl *egl,
|
||||
+ EGLDisplay display,
|
||||
+ EGLSync sync,
|
||||
+ GError **error)
|
||||
+{
|
||||
+ if (!is_egl_proc_valid (egl->eglDupNativeFenceFDANDROID, error))
|
||||
+ return EGL_NO_NATIVE_FENCE_FD_ANDROID;
|
||||
+
|
||||
+ EGLint fd = EGL_NO_NATIVE_FENCE_FD_ANDROID;
|
||||
+
|
||||
+ fd = egl->eglDupNativeFenceFDANDROID (display, sync);
|
||||
+
|
||||
+ if (fd == EGL_NO_NATIVE_FENCE_FD_ANDROID)
|
||||
+ {
|
||||
+ set_egl_error (error);
|
||||
+ }
|
||||
+
|
||||
+ return fd;
|
||||
+}
|
||||
+
|
||||
#define GET_EGL_PROC_ADDR(proc) \
|
||||
egl->proc = (void *) eglGetProcAddress (#proc);
|
||||
|
||||
@@ -1175,6 +1264,11 @@ meta_egl_constructed (GObject *object)
|
||||
GET_EGL_PROC_ADDR (eglCreateImageKHR);
|
||||
GET_EGL_PROC_ADDR (eglDestroyImageKHR);
|
||||
|
||||
+ GET_EGL_PROC_ADDR (eglCreateSync);
|
||||
+ GET_EGL_PROC_ADDR (eglDestroySync);
|
||||
+ GET_EGL_PROC_ADDR (eglWaitSync);
|
||||
+ GET_EGL_PROC_ADDR (eglDupNativeFenceFDANDROID);
|
||||
+
|
||||
GET_EGL_PROC_ADDR (eglBindWaylandDisplayWL);
|
||||
GET_EGL_PROC_ADDR (eglQueryWaylandBufferWL);
|
||||
|
||||
diff --git a/src/backends/meta-egl.h b/src/backends/meta-egl.h
|
||||
index 8b955c90c38..55775c7a421 100644
|
||||
--- a/src/backends/meta-egl.h
|
||||
+++ b/src/backends/meta-egl.h
|
||||
@@ -276,3 +276,26 @@ gboolean meta_egl_query_display_attrib (MetaEgl *egl,
|
||||
EGLint attribute,
|
||||
EGLAttrib *value,
|
||||
GError **error);
|
||||
+
|
||||
+gboolean meta_egl_create_sync (MetaEgl *egl,
|
||||
+ EGLDisplay display,
|
||||
+ EGLenum type,
|
||||
+ const EGLAttrib *attrib_list,
|
||||
+ EGLSync *egl_sync,
|
||||
+ GError **error);
|
||||
+
|
||||
+gboolean meta_egl_destroy_sync (MetaEgl *egl,
|
||||
+ EGLDisplay display,
|
||||
+ EGLSync sync,
|
||||
+ GError **error);
|
||||
+
|
||||
+gboolean meta_egl_wait_sync (MetaEgl *egl,
|
||||
+ EGLDisplay display,
|
||||
+ EGLSync sync,
|
||||
+ EGLint flags,
|
||||
+ GError **error);
|
||||
+
|
||||
+EGLint meta_egl_duplicate_native_fence_fd (MetaEgl *egl,
|
||||
+ EGLDisplay display,
|
||||
+ EGLSync sync,
|
||||
+ GError **error);
|
||||
\ No newline at end of file
|
||||
diff --git a/src/backends/native/meta-onscreen-native.c b/src/backends/native/meta-onscreen-native.c
|
||||
index 1a31f04a164..4f80b394f65 100644
|
||||
--- a/src/backends/native/meta-onscreen-native.c
|
||||
+++ b/src/backends/native/meta-onscreen-native.c
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
#include "backends/native/meta-onscreen-native.h"
|
||||
|
||||
+#include <glib/gstdio.h>
|
||||
#include <drm_fourcc.h>
|
||||
|
||||
#include "backends/meta-egl-ext.h"
|
||||
@@ -828,20 +829,53 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
|
||||
MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native;
|
||||
MetaEgl *egl = meta_renderer_native_get_egl (renderer_native);
|
||||
MetaGles3 *gles3 = meta_renderer_native_get_gles3 (renderer_native);
|
||||
+ CoglContext *cogl_context = cogl_framebuffer_get_context (COGL_FRAMEBUFFER (onscreen));
|
||||
+ CoglRendererEGL *cogl_renderer_egl = cogl_context->display->renderer->winsys;
|
||||
MetaRenderDevice *render_device;
|
||||
EGLDisplay egl_display;
|
||||
- GError *error = NULL;
|
||||
+ g_autoptr (GError) error = NULL;
|
||||
gboolean use_modifiers;
|
||||
MetaDeviceFile *device_file;
|
||||
MetaDrmBufferFlags flags;
|
||||
MetaDrmBufferGbm *buffer_gbm;
|
||||
struct gbm_bo *bo;
|
||||
+ EGLSync primary_gpu_egl_sync = EGL_NO_SYNC;
|
||||
+ EGLSync secondary_gpu_egl_sync = EGL_NO_SYNC;
|
||||
+ g_autofd int primary_gpu_sync_fence = EGL_NO_NATIVE_FENCE_FD_ANDROID;
|
||||
|
||||
COGL_TRACE_BEGIN_SCOPED (CopySharedFramebufferSecondaryGpu,
|
||||
"copy_shared_framebuffer_gpu()");
|
||||
-
|
||||
+
|
||||
if (renderer_gpu_data->secondary.needs_explicit_sync)
|
||||
- cogl_framebuffer_finish (COGL_FRAMEBUFFER (onscreen));
|
||||
+ {
|
||||
+ if (!meta_egl_create_sync (egl,
|
||||
+ cogl_renderer_egl->edpy,
|
||||
+ EGL_SYNC_NATIVE_FENCE_ANDROID,
|
||||
+ NULL,
|
||||
+ &primary_gpu_egl_sync,
|
||||
+ &error))
|
||||
+ {
|
||||
+ g_warning ("Failed to create EGLSync on primary GPU: %s", error->message);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ // According to the EGL_KHR_fence_sync specification we must ensure
|
||||
+ // the fence command is flushed in this context to be able to await it
|
||||
+ // in another (secondary GPU context) or we risk waiting indefinitely.
|
||||
+ cogl_framebuffer_flush (COGL_FRAMEBUFFER (onscreen));
|
||||
+
|
||||
+ primary_gpu_sync_fence =
|
||||
+ meta_egl_duplicate_native_fence_fd (egl,
|
||||
+ cogl_renderer_egl->edpy,
|
||||
+ primary_gpu_egl_sync,
|
||||
+ &error);
|
||||
+
|
||||
+ if (primary_gpu_sync_fence == EGL_NO_NATIVE_FENCE_FD_ANDROID)
|
||||
+ {
|
||||
+ g_warning ("Failed to duplicate EGLSync FD on primary GPU: %s", error->message);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
render_device = renderer_gpu_data->render_device;
|
||||
egl_display = meta_render_device_get_egl_display (render_device);
|
||||
@@ -854,13 +888,45 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
|
||||
&error))
|
||||
{
|
||||
g_warning ("Failed to make current: %s", error->message);
|
||||
- g_error_free (error);
|
||||
- return NULL;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
*egl_context_changed = TRUE;
|
||||
|
||||
+ if (primary_gpu_sync_fence != EGL_NO_NATIVE_FENCE_FD_ANDROID)
|
||||
+ {
|
||||
+ EGLAttrib attribs[3];
|
||||
+
|
||||
+ attribs[0] = EGL_SYNC_NATIVE_FENCE_FD_ANDROID;
|
||||
+ attribs[1] = primary_gpu_sync_fence;
|
||||
+ attribs[2] = EGL_NONE;
|
||||
+
|
||||
+ if (!meta_egl_create_sync (egl,
|
||||
+ egl_display,
|
||||
+ EGL_SYNC_NATIVE_FENCE_ANDROID,
|
||||
+ attribs,
|
||||
+ &secondary_gpu_egl_sync,
|
||||
+ &error))
|
||||
+ {
|
||||
+ g_warning ("Failed to create EGLSync on secondary GPU: %s", error->message);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ // eglCreateSync takes ownership of an existing fd that is passed, so
|
||||
+ // don't try to clean it up twice.
|
||||
+ primary_gpu_sync_fence = EGL_NO_NATIVE_FENCE_FD_ANDROID;
|
||||
|
||||
+ if (!meta_egl_wait_sync (egl,
|
||||
+ egl_display,
|
||||
+ secondary_gpu_egl_sync,
|
||||
+ 0,
|
||||
+ &error))
|
||||
+ {
|
||||
+ g_warning ("Failed to wait for EGLSync on secondary GPU: %s", error->message);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
buffer_gbm = META_DRM_BUFFER_GBM (primary_gpu_fb);
|
||||
bo = meta_drm_buffer_gbm_get_bo (buffer_gbm);
|
||||
if (!meta_renderer_native_gles3_blit_shared_bo (egl,
|
||||
@@ -872,8 +938,7 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
|
||||
&error))
|
||||
{
|
||||
g_warning ("Failed to blit shared framebuffer: %s", error->message);
|
||||
- g_error_free (error);
|
||||
- return NULL;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
if (!meta_egl_swap_buffers (egl,
|
||||
@@ -882,8 +947,7 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
|
||||
&error))
|
||||
{
|
||||
g_warning ("Failed to swap buffers: %s", error->message);
|
||||
- g_error_free (error);
|
||||
- return NULL;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
use_modifiers = meta_renderer_native_use_modifiers (renderer_native);
|
||||
@@ -902,8 +966,7 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
|
||||
{
|
||||
g_warning ("meta_drm_buffer_gbm_new_lock_front failed: %s",
|
||||
error->message);
|
||||
- g_error_free (error);
|
||||
- return NULL;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
g_object_set_qdata_full (G_OBJECT (buffer_gbm),
|
||||
@@ -911,6 +974,21 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
|
||||
g_object_ref (primary_gpu_fb),
|
||||
g_object_unref);
|
||||
|
||||
+out:
|
||||
+ if (primary_gpu_egl_sync != EGL_NO_SYNC &&
|
||||
+ !meta_egl_destroy_sync (egl,
|
||||
+ cogl_renderer_egl->edpy,
|
||||
+ primary_gpu_egl_sync,
|
||||
+ &error))
|
||||
+ g_warning ("Failed to destroy primary GPU EGLSync: %s", error->message);
|
||||
+
|
||||
+ if (secondary_gpu_egl_sync != EGL_NO_SYNC &&
|
||||
+ !meta_egl_destroy_sync (egl,
|
||||
+ egl_display,
|
||||
+ secondary_gpu_egl_sync,
|
||||
+ &error))
|
||||
+ g_warning ("Failed to destroy secondary GPU EGLSync: %s", error->message);
|
||||
+
|
||||
return META_DRM_BUFFER (buffer_gbm);
|
||||
}
|
||||
|
||||
--
|
||||
GitLab
|
Loading…
Reference in a new issue