renderer/native: Use shadow fb on software GL if preferred

If a KMS device has the DRM_CAP_DUMB_PREFER_SHADOW and a software based
GL driver is used, always use a shadow fb. This will speed up read backs
in the llvmpipe OpenGL implementation, making blend operations faster.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/106
This commit is contained in:
Jonas Ådahl 2018-10-09 15:55:23 +02:00 committed by Ray Strode
parent bcacaf4562
commit eea0a2b11d

View File

@ -2773,6 +2773,60 @@ calculate_view_transform (MetaMonitorManager *monitor_manager,
return crtc_transform; return crtc_transform;
} }
static CoglContext *
cogl_context_from_renderer_native (MetaRendererNative *renderer_native)
{
MetaMonitorManager *monitor_manager =
META_MONITOR_MANAGER (renderer_native->monitor_manager_kms);
MetaBackend *backend = meta_monitor_manager_get_backend (monitor_manager);
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
return clutter_backend_get_cogl_context (clutter_backend);
}
static gboolean
should_force_shadow_fb (MetaRendererNative *renderer_native,
MetaGpuKms *primary_gpu)
{
CoglContext *cogl_context =
cogl_context_from_renderer_native (renderer_native);
CoglGpuInfo *info = &cogl_context->gpu;
int kms_fd;
uint64_t prefer_shadow = 0;
switch (info->architecture)
{
case COGL_GPU_INFO_ARCHITECTURE_UNKNOWN:
case COGL_GPU_INFO_ARCHITECTURE_SANDYBRIDGE:
case COGL_GPU_INFO_ARCHITECTURE_SGX:
case COGL_GPU_INFO_ARCHITECTURE_MALI:
return FALSE;
case COGL_GPU_INFO_ARCHITECTURE_LLVMPIPE:
case COGL_GPU_INFO_ARCHITECTURE_SOFTPIPE:
case COGL_GPU_INFO_ARCHITECTURE_SWRAST:
break;
}
kms_fd = meta_gpu_kms_get_fd (primary_gpu);
if (drmGetCap (kms_fd, DRM_CAP_DUMB_PREFER_SHADOW, &prefer_shadow) == 0)
{
if (prefer_shadow)
{
static gboolean logged_once = FALSE;
if (!logged_once)
{
g_message ("Forcing shadow framebuffer");
logged_once = TRUE;
}
return TRUE;
}
}
return FALSE;
}
static MetaRendererView * static MetaRendererView *
meta_renderer_native_create_view (MetaRenderer *renderer, meta_renderer_native_create_view (MetaRenderer *renderer,
MetaLogicalMonitor *logical_monitor) MetaLogicalMonitor *logical_monitor)
@ -2782,10 +2836,8 @@ meta_renderer_native_create_view (MetaRenderer *renderer,
renderer_native->monitor_manager_kms; renderer_native->monitor_manager_kms;
MetaMonitorManager *monitor_manager = MetaMonitorManager *monitor_manager =
META_MONITOR_MANAGER (monitor_manager_kms); META_MONITOR_MANAGER (monitor_manager_kms);
MetaBackend *backend = meta_monitor_manager_get_backend (monitor_manager);
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
CoglContext *cogl_context = CoglContext *cogl_context =
clutter_backend_get_cogl_context (clutter_backend); cogl_context_from_renderer_native (renderer_native);
CoglDisplay *cogl_display = cogl_context_get_display (cogl_context); CoglDisplay *cogl_display = cogl_context_get_display (cogl_context);
MetaGpuKms *primary_gpu; MetaGpuKms *primary_gpu;
CoglDisplayEGL *cogl_display_egl; CoglDisplayEGL *cogl_display_egl;
@ -2820,7 +2872,8 @@ meta_renderer_native_create_view (MetaRenderer *renderer,
if (!onscreen) if (!onscreen)
g_error ("Failed to allocate onscreen framebuffer: %s", error->message); g_error ("Failed to allocate onscreen framebuffer: %s", error->message);
if (view_transform != META_MONITOR_TRANSFORM_NORMAL) if (view_transform != META_MONITOR_TRANSFORM_NORMAL ||
should_force_shadow_fb (renderer_native, primary_gpu))
{ {
offscreen = meta_renderer_native_create_offscreen (renderer_native, offscreen = meta_renderer_native_create_offscreen (renderer_native,
cogl_context, cogl_context,