mirror of
https://github.com/brl/mutter.git
synced 2024-11-28 02:50:41 -05:00
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>
This commit is contained in:
parent
b1c8ce110c
commit
33529426a9
@ -747,7 +747,9 @@ secondary_gpu_get_next_dumb_buffer (MetaOnscreenNativeSecondaryGpuState *seconda
|
|||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
copy_shared_framebuffer_primary_gpu (CoglOnscreen *onscreen,
|
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);
|
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||||
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
|
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
|
||||||
@ -814,14 +816,37 @@ copy_shared_framebuffer_primary_gpu (CoglOnscreen *onscre
|
|||||||
error->message);
|
error->message);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
/* Limit the number of individual copies to 16 */
|
||||||
|
#define MAX_RECTS 16
|
||||||
|
|
||||||
if (!cogl_blit_framebuffer (framebuffer, COGL_FRAMEBUFFER (dmabuf_fb),
|
if (n_rectangles == 0 || n_rectangles > MAX_RECTS)
|
||||||
0, 0, 0, 0,
|
|
||||||
width, height,
|
|
||||||
&error))
|
|
||||||
{
|
{
|
||||||
g_object_unref (dmabuf_fb);
|
if (!cogl_blit_framebuffer (framebuffer, COGL_FRAMEBUFFER (dmabuf_fb),
|
||||||
return FALSE;
|
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);
|
g_object_unref (dmabuf_fb);
|
||||||
@ -890,7 +915,9 @@ copy_shared_framebuffer_cpu (CoglOnscreen *onscreen,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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);
|
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
|
||||||
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state;
|
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state;
|
||||||
@ -920,7 +947,9 @@ update_secondary_gpu_state_pre_swap_buffers (CoglOnscreen *onscreen)
|
|||||||
G_GNUC_FALLTHROUGH;
|
G_GNUC_FALLTHROUGH;
|
||||||
case META_SHARED_FRAMEBUFFER_COPY_MODE_PRIMARY:
|
case META_SHARED_FRAMEBUFFER_COPY_MODE_PRIMARY:
|
||||||
if (!copy_shared_framebuffer_primary_gpu (onscreen,
|
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)
|
if (!secondary_gpu_state->noted_primary_gpu_copy_failed)
|
||||||
{
|
{
|
||||||
@ -1041,7 +1070,9 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
|||||||
COGL_TRACE_BEGIN_SCOPED (MetaRendererNativeSwapBuffers,
|
COGL_TRACE_BEGIN_SCOPED (MetaRendererNativeSwapBuffers,
|
||||||
"Onscreen (swap-buffers)");
|
"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 = COGL_ONSCREEN_CLASS (meta_onscreen_native_parent_class);
|
||||||
parent_class->swap_buffers_with_damage (onscreen,
|
parent_class->swap_buffers_with_damage (onscreen,
|
||||||
|
Loading…
Reference in New Issue
Block a user