kathenas / rpms / mutter

Forked from rpms/mutter 5 years ago
Clone

Blame SOURCES/0001-renderer-native-Use-shadow-fb-on-software-GL-if-pref.patch

776610
From d05751b1a28d7e99a089203401b0ec940373cbd0 Mon Sep 17 00:00:00 2001
776610
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
776610
Date: Tue, 9 Oct 2018 15:55:23 +0200
776610
Subject: [PATCH] renderer/native: Use shadow fb on software GL if preferred
776610
776610
If a KMS device has the DRM_CAP_DUMB_PREFER_SHADOW and a software based
776610
GL driver is used, always use a shadow fb. This will speed up read backs
776610
in the llvmpipe OpenGL implementation, making blend operations faster.
776610
776610
Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/106
776610
---
776610
 src/backends/native/meta-renderer-native.c | 61 ++++++++++++++++++++--
776610
 1 file changed, 57 insertions(+), 4 deletions(-)
776610
776610
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
776610
index 470da8845..b15a6da96 100644
776610
--- a/src/backends/native/meta-renderer-native.c
776610
+++ b/src/backends/native/meta-renderer-native.c
776610
@@ -2746,108 +2746,161 @@ meta_onscreen_native_set_view (CoglOnscreen     *onscreen,
776610
 
776610
 static MetaMonitorTransform
776610
 calculate_view_transform (MetaMonitorManager *monitor_manager,
776610
                           MetaLogicalMonitor *logical_monitor)
776610
 {
776610
   MetaMonitor *main_monitor;
776610
   MetaOutput *main_output;
776610
   MetaCrtc *crtc;
776610
   MetaMonitorTransform crtc_transform;
776610
 
776610
   main_monitor = meta_logical_monitor_get_monitors (logical_monitor)->data;
776610
   main_output = meta_monitor_get_main_output (main_monitor);
776610
   crtc = meta_output_get_assigned_crtc (main_output);
776610
   crtc_transform =
776610
     meta_monitor_logical_to_crtc_transform (main_monitor,
776610
                                             logical_monitor->transform);
776610
 
776610
   /*
776610
    * Pick any monitor and output and check; all CRTCs of a logical monitor will
776610
    * always have the same transform assigned to them.
776610
    */
776610
 
776610
   if (meta_monitor_manager_is_transform_handled (monitor_manager,
776610
                                                  crtc,
776610
                                                  crtc_transform))
776610
     return META_MONITOR_TRANSFORM_NORMAL;
776610
   else
776610
     return crtc_transform;
776610
 }
776610
 
776610
+static CoglContext *
776610
+cogl_context_from_renderer_native (MetaRendererNative *renderer_native)
776610
+{
776610
+  MetaMonitorManager *monitor_manager =
776610
+    META_MONITOR_MANAGER (renderer_native->monitor_manager_kms);
776610
+  MetaBackend *backend = meta_monitor_manager_get_backend (monitor_manager);
776610
+  ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
776610
+
776610
+  return clutter_backend_get_cogl_context (clutter_backend);
776610
+}
776610
+
776610
+static gboolean
776610
+should_force_shadow_fb (MetaRendererNative *renderer_native,
776610
+                        MetaGpuKms         *primary_gpu)
776610
+{
776610
+  CoglContext *cogl_context =
776610
+    cogl_context_from_renderer_native (renderer_native);
776610
+  CoglGpuInfo *info = &cogl_context->gpu;
776610
+  int kms_fd;
776610
+  uint64_t prefer_shadow = 0;
776610
+
776610
+  switch (info->architecture)
776610
+    {
776610
+    case COGL_GPU_INFO_ARCHITECTURE_UNKNOWN:
776610
+    case COGL_GPU_INFO_ARCHITECTURE_SANDYBRIDGE:
776610
+    case COGL_GPU_INFO_ARCHITECTURE_SGX:
776610
+    case COGL_GPU_INFO_ARCHITECTURE_MALI:
776610
+      return FALSE;
776610
+    case COGL_GPU_INFO_ARCHITECTURE_LLVMPIPE:
776610
+    case COGL_GPU_INFO_ARCHITECTURE_SOFTPIPE:
776610
+    case COGL_GPU_INFO_ARCHITECTURE_SWRAST:
776610
+      break;
776610
+    }
776610
+
776610
+  kms_fd = meta_gpu_kms_get_fd (primary_gpu);
776610
+  if (drmGetCap (kms_fd, DRM_CAP_DUMB_PREFER_SHADOW, &prefer_shadow) == 0)
776610
+    {
776610
+      if (prefer_shadow)
776610
+        {
776610
+          static gboolean logged_once = FALSE;
776610
+
776610
+          if (!logged_once)
776610
+            {
776610
+              g_message ("Forcing shadow framebuffer");
776610
+              logged_once = TRUE;
776610
+            }
776610
+
776610
+          return TRUE;
776610
+        }
776610
+    }
776610
+
776610
+  return FALSE;
776610
+}
776610
+
776610
 static MetaRendererView *
776610
 meta_renderer_native_create_view (MetaRenderer       *renderer,
776610
                                   MetaLogicalMonitor *logical_monitor)
776610
 {
776610
   MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
776610
   MetaMonitorManagerKms *monitor_manager_kms =
776610
     renderer_native->monitor_manager_kms;
776610
   MetaMonitorManager *monitor_manager =
776610
     META_MONITOR_MANAGER (monitor_manager_kms);
776610
-  MetaBackend *backend = meta_monitor_manager_get_backend (monitor_manager);
776610
-  ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
776610
   CoglContext *cogl_context =
776610
-    clutter_backend_get_cogl_context (clutter_backend);
776610
+    cogl_context_from_renderer_native (renderer_native);
776610
   CoglDisplay *cogl_display = cogl_context_get_display (cogl_context);
776610
   MetaGpuKms *primary_gpu;
776610
   CoglDisplayEGL *cogl_display_egl;
776610
   CoglOnscreenEGL *onscreen_egl;
776610
   MetaMonitorTransform view_transform;
776610
   CoglOnscreen *onscreen = NULL;
776610
   CoglOffscreen *offscreen = NULL;
776610
   float scale;
776610
   int width, height;
776610
   MetaRendererView *view;
776610
   GError *error = NULL;
776610
 
776610
   view_transform = calculate_view_transform (monitor_manager, logical_monitor);
776610
 
776610
   if (meta_is_stage_views_scaled ())
776610
     scale = meta_logical_monitor_get_scale (logical_monitor);
776610
   else
776610
     scale = 1.0;
776610
 
776610
   width = roundf (logical_monitor->rect.width * scale);
776610
   height = roundf (logical_monitor->rect.height * scale);
776610
 
776610
   primary_gpu = meta_monitor_manager_kms_get_primary_gpu (monitor_manager_kms);
776610
   onscreen = meta_renderer_native_create_onscreen (renderer_native,
776610
                                                    primary_gpu,
776610
                                                    logical_monitor,
776610
                                                    cogl_context,
776610
                                                    view_transform,
776610
                                                    width,
776610
                                                    height,
776610
                                                    &error);
776610
   if (!onscreen)
776610
     g_error ("Failed to allocate onscreen framebuffer: %s", error->message);
776610
 
776610
-  if (view_transform != META_MONITOR_TRANSFORM_NORMAL)
776610
+  if (view_transform != META_MONITOR_TRANSFORM_NORMAL ||
776610
+      should_force_shadow_fb (renderer_native, primary_gpu))
776610
     {
776610
       offscreen = meta_renderer_native_create_offscreen (renderer_native,
776610
                                                          cogl_context,
776610
                                                          view_transform,
776610
                                                          width,
776610
                                                          height,
776610
                                                          &error);
776610
       if (!offscreen)
776610
         g_error ("Failed to allocate back buffer texture: %s", error->message);
776610
     }
776610
 
776610
   view = g_object_new (META_TYPE_RENDERER_VIEW,
776610
                        "layout", &logical_monitor->rect,
776610
                        "scale", scale,
776610
                        "framebuffer", onscreen,
776610
                        "offscreen", offscreen,
776610
                        "logical-monitor", logical_monitor,
776610
                        "transform", view_transform,
776610
                        NULL);
776610
   g_clear_pointer (&offscreen, cogl_object_unref);
776610
 
776610
   meta_onscreen_native_set_view (onscreen, view);
776610
 
776610
   if (!meta_onscreen_native_allocate (onscreen, &error))
776610
     {
776610
       g_warning ("Could not create onscreen: %s", error->message);
776610
       cogl_object_unref (onscreen);
776610
       g_object_unref (view);
776610
       g_error_free (error);
776610
       return NULL;
776610
-- 
776610
2.17.1
776610