From 6c4739a2f1652b4d0830dccdab020af387e37e44 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 12 Feb 2024 14:16:09 -0500 Subject: [PATCH] gsk: Don't use gpu renderers with llvmpipe Unless the renderer has been explicitly selected via the GSK_RENDERER environment variable, don't use it with llvmpipe. It is important that we allow explicit setting to override this, so we can continue to use ngl in ci, where we don't have hw and want to test with llvmpipe. This should address many of the "performance is terrible in GNOME OS" complaints that are coming from people running in VMs, etc. --- gsk/gskrenderer.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/gsk/gskrenderer.c b/gsk/gskrenderer.c index 31477b84c71..08344cf7e7e 100644 --- a/gsk/gskrenderer.c +++ b/gsk/gskrenderer.c @@ -46,6 +46,8 @@ #include "gl/gskglrenderer.h" #include "gpu/gskvulkanrenderer.h" +#include "gdk/gdkvulkancontextprivate.h" +#include "gdk/gdkdisplayprivate.h" #include #include @@ -630,16 +632,56 @@ get_renderer_for_backend (GdkSurface *surface) return G_TYPE_INVALID; } +static gboolean +gl_software_rendering (GdkSurface *surface) +{ + GdkDisplay *display = gdk_surface_get_display (surface); + GdkGLContext *context; + + if (!gdk_display_prepare_gl (display, NULL)) + return G_TYPE_INVALID; + + context = gdk_display_get_gl_context (display); + gdk_gl_context_make_current (context); + + return strstr ((const char *) glGetString (GL_RENDERER), "llvmpipe") != NULL; +} + static GType get_renderer_for_gl (GdkSurface *surface) { + if (gl_software_rendering (surface)) + return G_TYPE_INVALID; + return gsk_ngl_renderer_get_type (); } +#ifdef GDK_RENDERING_VULKAN +static gboolean +vulkan_software_rendering (GdkSurface *surface) +{ + GdkDisplay *display = gdk_surface_get_display (surface); + GdkVulkanContext *context = gdk_display_create_vulkan_context (display, surface, NULL); + VkPhysicalDevice device; + VkPhysicalDeviceProperties props; + + if (!context) + return G_TYPE_INVALID; + + device = gdk_vulkan_context_get_physical_device (context); + vkGetPhysicalDeviceProperties (device, &props); + + return props.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU; +} +#endif + static GType get_renderer_for_vulkan (GdkSurface *surface) { #ifdef GDK_RENDERING_VULKAN + if (vulkan_software_rendering (surface)) + return G_TYPE_INVALID; + return GSK_TYPE_VULKAN_RENDERER; #else return G_TYPE_INVALID; @@ -649,6 +691,9 @@ get_renderer_for_vulkan (GdkSurface *surface) static GType get_renderer_for_gles2 (GdkSurface *surface) { + if (gl_software_rendering (surface)) + return G_TYPE_INVALID; + return GSK_TYPE_GL_RENDERER; }