backend: glx: tentatively enable glFinish for NVIDIA

We use the __GL_YIELD=usleep workaround when we detect the NVIDIA
driver, so we could use glFinish without the NVIDIA driver taking all
the CPU.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2020-04-22 18:05:04 +01:00
parent 7043b2da5e
commit 0efdb6c2d9
No known key found for this signature in database
GPG Key ID: 37C999F617EA1A47
4 changed files with 13 additions and 4 deletions

View File

@ -12,6 +12,13 @@
#include "compiler.h" #include "compiler.h"
#include "log.h" #include "log.h"
/// Apply driver specified global workarounds. It's safe to call this multiple times.
void apply_driver_workarounds(enum driver driver) {
if (driver & DRIVER_NVIDIA) {
setenv("__GL_YIELD", "usleep", true);
}
}
enum driver detect_driver(xcb_connection_t *c, backend_t *backend_data, xcb_window_t window) { enum driver detect_driver(xcb_connection_t *c, backend_t *backend_data, xcb_window_t window) {
enum driver ret = 0; enum driver ret = 0;
// First we try doing backend agnostic detection using RANDR // First we try doing backend agnostic detection using RANDR

View File

@ -32,6 +32,9 @@ enum driver {
/// Note, this is a best-effort test, so no guarantee all drivers will be detected. /// Note, this is a best-effort test, so no guarantee all drivers will be detected.
enum driver detect_driver(xcb_connection_t *, struct backend_base *, xcb_window_t); enum driver detect_driver(xcb_connection_t *, struct backend_base *, xcb_window_t);
/// Apply driver specified global workarounds. It's safe to call this multiple times.
void apply_driver_workarounds(enum driver);
// Print driver names to stdout, for diagnostics // Print driver names to stdout, for diagnostics
static inline void print_drivers(enum driver drivers) { static inline void print_drivers(enum driver drivers) {
if (drivers & DRIVER_AMDGPU) { if (drivers & DRIVER_AMDGPU) {

View File

@ -466,11 +466,8 @@ static void glx_present(backend_t *base, const region_t *region attr_unused) {
struct _glx_data *gd = (void *)base; struct _glx_data *gd = (void *)base;
gl_present(base, region); gl_present(base, region);
glXSwapBuffers(gd->display, gd->target_win); glXSwapBuffers(gd->display, gd->target_win);
// XXX there should be no need to block, the core should wait for render to finish
if (!gd->gl.is_nvidia) {
glFinish(); glFinish();
} }
}
static int glx_buffer_age(backend_t *base) { static int glx_buffer_age(backend_t *base) {
if (!glxext.has_GLX_EXT_buffer_age) { if (!glxext.has_GLX_EXT_buffer_age) {

View File

@ -1224,6 +1224,7 @@ static bool redirect_start(session_t *ps) {
// Re-detect driver since we now have a backend // Re-detect driver since we now have a backend
ps->drivers = detect_driver(ps->c, ps->backend_data, ps->root); ps->drivers = detect_driver(ps->c, ps->backend_data, ps->root);
apply_driver_workarounds(ps->drivers);
root_damaged(ps); root_damaged(ps);
@ -1965,6 +1966,7 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
// window; non experimental backends always need a target window // window; non experimental backends always need a target window
ps->drivers = detect_driver(ps->c, ps->backend_data, ps->root); ps->drivers = detect_driver(ps->c, ps->backend_data, ps->root);
apply_driver_workarounds(ps->drivers);
// Initialize filters, must be preceded by OpenGL context creation // Initialize filters, must be preceded by OpenGL context creation
if (!ps->o.experimental_backends && !init_render(ps)) { if (!ps->o.experimental_backends && !init_render(ps)) {