[mutter/gnome-41] backend: Copy damage rectangles to secondary GPU when available
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/gnome-41] backend: Copy damage rectangles to secondary GPU when available
- Date: Thu, 2 Dec 2021 14:27:31 +0000 (UTC)
commit 8e0acad2d3d576efeea703967f0f50aee10684f0
Author: Piotr Łopatka <piotr lopatka gmail com>
Date: Sat Nov 6 14:14:25 2021 +0000
backend: Copy damage rectangles to secondary GPU when available
Systems with AMD GPUs do not take advantage of Mutter's zero-copy path
when driving DisplayLink screens. This is due to a very slow CPU access
to the zero-copy texture. Instead they fall back on primary GPU doing a
copy of the texture for fast CPU access. This commit accelerates texture
copy by working through damage regions only.
Tests on a 4K screen with windowed applications show significant
reduction of GPU utilisation.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2033>
src/backends/native/meta-onscreen-native.c | 51 ++++++++++++++++++++++++------
1 file changed, 41 insertions(+), 10 deletions(-)
---
diff --git a/src/backends/native/meta-onscreen-native.c b/src/backends/native/meta-onscreen-native.c
index ca3752bcb3..47b0d7eefc 100644
--- a/src/backends/native/meta-onscreen-native.c
+++ b/src/backends/native/meta-onscreen-native.c
@@ -735,7 +735,9 @@ secondary_gpu_get_next_dumb_buffer (MetaOnscreenNativeSecondaryGpuState *seconda
static gboolean
copy_shared_framebuffer_primary_gpu (CoglOnscreen *onscreen,
- MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state)
+ MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state,
+ const int *rectangles,
+ int n_rectangles)
{
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
@@ -802,14 +804,37 @@ copy_shared_framebuffer_primary_gpu (CoglOnscreen *onscre
error->message);
return FALSE;
}
+ /* Limit the number of individual copies to 16 */
+#define MAX_RECTS 16
- if (!cogl_blit_framebuffer (framebuffer, COGL_FRAMEBUFFER (dmabuf_fb),
- 0, 0, 0, 0,
- width, height,
- &error))
+ if (n_rectangles == 0 || n_rectangles > MAX_RECTS)
{
- g_object_unref (dmabuf_fb);
- return FALSE;
+ if (!cogl_blit_framebuffer (framebuffer, COGL_FRAMEBUFFER (dmabuf_fb),
+ 0, 0, 0, 0,
+ width, height,
+ &error))
+ {
+ g_object_unref (dmabuf_fb);
+ return FALSE;
+ }
+ }
+ else
+ {
+ int i;
+
+ for (i = 0; i < n_rectangles; ++i)
+ {
+ if (!cogl_blit_framebuffer (framebuffer, COGL_FRAMEBUFFER (dmabuf_fb),
+ rectangles[i * 4], rectangles[i * 4 + 1],
+ rectangles[i * 4], rectangles[i * 4 + 1],
+ rectangles[i * 4 + 2],
+ rectangles[i * 4 + 3],
+ &error))
+ {
+ g_object_unref (dmabuf_fb);
+ return FALSE;
+ }
+ }
}
g_object_unref (dmabuf_fb);
@@ -877,7 +902,9 @@ copy_shared_framebuffer_cpu (CoglOnscreen *onscreen,
}
static void
-update_secondary_gpu_state_pre_swap_buffers (CoglOnscreen *onscreen)
+update_secondary_gpu_state_pre_swap_buffers (CoglOnscreen *onscreen,
+ const int *rectangles,
+ int n_rectangles)
{
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state;
@@ -907,7 +934,9 @@ update_secondary_gpu_state_pre_swap_buffers (CoglOnscreen *onscreen)
G_GNUC_FALLTHROUGH;
case META_SHARED_FRAMEBUFFER_COPY_MODE_PRIMARY:
if (!copy_shared_framebuffer_primary_gpu (onscreen,
- secondary_gpu_state))
+ secondary_gpu_state,
+ rectangles,
+ n_rectangles))
{
if (!secondary_gpu_state->noted_primary_gpu_copy_failed)
{
@@ -1028,7 +1057,9 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
COGL_TRACE_BEGIN_SCOPED (MetaRendererNativeSwapBuffers,
"Onscreen (swap-buffers)");
- update_secondary_gpu_state_pre_swap_buffers (onscreen);
+ update_secondary_gpu_state_pre_swap_buffers (onscreen,
+ rectangles,
+ n_rectangles);
parent_class = COGL_ONSCREEN_CLASS (meta_onscreen_native_parent_class);
parent_class->swap_buffers_with_damage (onscreen,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]