mirror of https://github.com/yshui/picom.git
diagnostic: warn the user if they are using a software GL renderer
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
parent
b66e5fd422
commit
1df3360989
|
@ -240,6 +240,8 @@ struct backend_operations {
|
||||||
// =========== Misc ============
|
// =========== Misc ============
|
||||||
/// Return the driver that is been used by the backend
|
/// Return the driver that is been used by the backend
|
||||||
enum driver (*detect_driver)(backend_t *backend_data);
|
enum driver (*detect_driver)(backend_t *backend_data);
|
||||||
|
|
||||||
|
void (*diagnostics)(backend_t *backend_data);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct backend_operations *backend_list[];
|
extern struct backend_operations *backend_list[];
|
||||||
|
|
|
@ -26,9 +26,9 @@
|
||||||
#include "backend/gl/glx.h"
|
#include "backend/gl/glx.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "compiler.h"
|
#include "compiler.h"
|
||||||
#include "picom.h"
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "picom.h"
|
||||||
#include "region.h"
|
#include "region.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "win.h"
|
#include "win.h"
|
||||||
|
@ -480,6 +480,45 @@ static int glx_buffer_age(backend_t *base) {
|
||||||
return (int)val ?: -1;
|
return (int)val ?: -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void glx_diagnostics(backend_t *base) {
|
||||||
|
struct _glx_data *gd = (void *)base;
|
||||||
|
bool warn_software_rendering = false;
|
||||||
|
const char *software_renderer_names[] = {"llvmpipe", "SWR", "softpipe"};
|
||||||
|
auto glx_vendor = glXGetClientString(gd->display, GLX_VENDOR);
|
||||||
|
printf("* Driver vendors:\n");
|
||||||
|
printf(" * GLX: %s\n", glx_vendor);
|
||||||
|
printf(" * GL: %s\n", glGetString(GL_VENDOR));
|
||||||
|
|
||||||
|
auto gl_renderer = (const char *)glGetString(GL_RENDERER);
|
||||||
|
printf("* GL renderer: %s\n", gl_renderer);
|
||||||
|
if (strcmp(glx_vendor, "Mesa Project and SGI")) {
|
||||||
|
for (size_t i = 0; i < ARR_SIZE(software_renderer_names); i++) {
|
||||||
|
if (strstr(gl_renderer, software_renderer_names[i]) != NULL) {
|
||||||
|
warn_software_rendering = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef GLX_MESA_query_renderer
|
||||||
|
if (glxext.has_GLX_MESA_query_renderer) {
|
||||||
|
unsigned int accelerated = 0;
|
||||||
|
glXQueryCurrentRendererIntegerMESA(GLX_RENDERER_ACCELERATED_MESA, &accelerated);
|
||||||
|
printf("* Accelerated: %d\n", accelerated);
|
||||||
|
|
||||||
|
// Trust GLX_MESA_query_renderer when it's available
|
||||||
|
warn_software_rendering = (accelerated == 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (warn_software_rendering) {
|
||||||
|
printf("\n(You are using a software renderer. Unless you are doing this\n"
|
||||||
|
"intentionally, this means you don't have a graphics driver\n"
|
||||||
|
"properly installed. Performance will suffer. Please fix this\n"
|
||||||
|
"before reporting your issue.)\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct backend_operations glx_ops = {
|
struct backend_operations glx_ops = {
|
||||||
.init = glx_init,
|
.init = glx_init,
|
||||||
.deinit = glx_deinit,
|
.deinit = glx_deinit,
|
||||||
|
@ -497,6 +536,7 @@ struct backend_operations glx_ops = {
|
||||||
.create_blur_context = gl_create_blur_context,
|
.create_blur_context = gl_create_blur_context,
|
||||||
.destroy_blur_context = gl_destroy_blur_context,
|
.destroy_blur_context = gl_destroy_blur_context,
|
||||||
.get_blur_size = gl_get_blur_size,
|
.get_blur_size = gl_get_blur_size,
|
||||||
|
.diagnostics = glx_diagnostics,
|
||||||
.max_buffer_age = 5, // Why?
|
.max_buffer_age = 5, // Why?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -546,6 +586,10 @@ PFNGLXBINDTEXIMAGEEXTPROC glXBindTexImageEXT;
|
||||||
PFNGLXRELEASETEXIMAGEEXTPROC glXReleaseTexImageEXT;
|
PFNGLXRELEASETEXIMAGEEXTPROC glXReleaseTexImageEXT;
|
||||||
PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB;
|
PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB;
|
||||||
|
|
||||||
|
#ifdef GLX_MESA_query_renderer
|
||||||
|
PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC glXQueryCurrentRendererIntegerMESA;
|
||||||
|
#endif
|
||||||
|
|
||||||
void glxext_init(Display *dpy, int screen) {
|
void glxext_init(Display *dpy, int screen) {
|
||||||
if (glxext.initialized) {
|
if (glxext.initialized) {
|
||||||
return;
|
return;
|
||||||
|
@ -560,6 +604,9 @@ void glxext_init(Display *dpy, int screen) {
|
||||||
check_ext(GLX_EXT_texture_from_pixmap);
|
check_ext(GLX_EXT_texture_from_pixmap);
|
||||||
check_ext(GLX_ARB_create_context);
|
check_ext(GLX_ARB_create_context);
|
||||||
check_ext(GLX_EXT_buffer_age);
|
check_ext(GLX_EXT_buffer_age);
|
||||||
|
#ifdef GLX_MESA_query_renderer
|
||||||
|
check_ext(GLX_MESA_query_renderer);
|
||||||
|
#endif
|
||||||
#undef check_ext
|
#undef check_ext
|
||||||
|
|
||||||
#define lookup(name) (name = (__typeof__(name))glXGetProcAddress((GLubyte *)#name))
|
#define lookup(name) (name = (__typeof__(name))glXGetProcAddress((GLubyte *)#name))
|
||||||
|
@ -587,5 +634,10 @@ void glxext_init(Display *dpy, int screen) {
|
||||||
if (!lookup(glXCreateContextAttribsARB)) {
|
if (!lookup(glXCreateContextAttribsARB)) {
|
||||||
glxext.has_GLX_ARB_create_context = false;
|
glxext.has_GLX_ARB_create_context = false;
|
||||||
}
|
}
|
||||||
|
#ifdef GLX_MESA_query_renderer
|
||||||
|
if (!lookup(glXQueryCurrentRendererIntegerMESA)) {
|
||||||
|
glxext.has_GLX_MESA_query_renderer = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#undef lookup
|
#undef lookup
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ struct glxext_info {
|
||||||
bool has_GLX_EXT_texture_from_pixmap;
|
bool has_GLX_EXT_texture_from_pixmap;
|
||||||
bool has_GLX_ARB_create_context;
|
bool has_GLX_ARB_create_context;
|
||||||
bool has_GLX_EXT_buffer_age;
|
bool has_GLX_EXT_buffer_age;
|
||||||
|
bool has_GLX_MESA_query_renderer;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct glxext_info glxext;
|
extern struct glxext_info glxext;
|
||||||
|
@ -69,4 +70,8 @@ extern PFNGLXBINDTEXIMAGEEXTPROC glXBindTexImageEXT;
|
||||||
extern PFNGLXRELEASETEXIMAGEEXTPROC glXReleaseTexImageEXT;
|
extern PFNGLXRELEASETEXIMAGEEXTPROC glXReleaseTexImageEXT;
|
||||||
extern PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB;
|
extern PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB;
|
||||||
|
|
||||||
|
#ifdef GLX_MESA_query_renderer
|
||||||
|
extern PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC glXQueryCurrentRendererIntegerMESA;
|
||||||
|
#endif
|
||||||
|
|
||||||
void glxext_init(Display *, int screen);
|
void glxext_init(Display *, int screen);
|
||||||
|
|
|
@ -22,9 +22,9 @@ void print_diagnostics(session_t *ps, const char *config_file, bool compositor_r
|
||||||
printf("* Use Overlay: %s\n", ps->overlay != XCB_NONE ? "Yes" : "No");
|
printf("* Use Overlay: %s\n", ps->overlay != XCB_NONE ? "Yes" : "No");
|
||||||
if (ps->overlay == XCB_NONE) {
|
if (ps->overlay == XCB_NONE) {
|
||||||
if (compositor_running) {
|
if (compositor_running) {
|
||||||
printf(" (Another compositor is already running)\n");
|
printf(" (Another compositor is already running)\n");
|
||||||
} else if (session_redirection_mode(ps) != XCB_COMPOSITE_REDIRECT_MANUAL) {
|
} else if (session_redirection_mode(ps) != XCB_COMPOSITE_REDIRECT_MANUAL) {
|
||||||
printf(" (Not in manual redirection mode)\n");
|
printf(" (Not in manual redirection mode)\n");
|
||||||
} else {
|
} else {
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,19 @@ void print_diagnostics(session_t *ps, const char *config_file, bool compositor_r
|
||||||
printf("* Config file used: %s\n", config_file ?: "None");
|
printf("* Config file used: %s\n", config_file ?: "None");
|
||||||
printf("\n### Drivers (inaccurate):\n\n");
|
printf("\n### Drivers (inaccurate):\n\n");
|
||||||
print_drivers(ps->drivers);
|
print_drivers(ps->drivers);
|
||||||
|
|
||||||
|
for (int i = 0; i < NUM_BKEND; i++) {
|
||||||
|
if (backend_list[i] && backend_list[i]->diagnostics) {
|
||||||
|
printf("\n### Backend: %s\n\n", BACKEND_STRS[i]);
|
||||||
|
auto data = backend_list[i]->init(ps);
|
||||||
|
if (!data) {
|
||||||
|
printf(" Cannot initialize this backend\n");
|
||||||
|
} else {
|
||||||
|
backend_list[i]->diagnostics(data);
|
||||||
|
backend_list[i]->deinit(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// vim: set noet sw=8 ts=8 :
|
// vim: set noet sw=8 ts=8 :
|
||||||
|
|
Loading…
Reference in New Issue