mirror of https://github.com/yshui/picom.git
backend: add new optional API: device_status
This is meant to be used to detect GPU resets. Implemented in the glx backend using the GL_ARB_robustness extension. Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
parent
126750f099
commit
a383dc1cdd
|
@ -32,6 +32,15 @@ typedef struct backend_base {
|
|||
|
||||
typedef void (*backend_ready_callback_t)(void *);
|
||||
|
||||
// This mimics OpenGL's ARB_robustness extension, which enables detection of GPU context
|
||||
// resets.
|
||||
// See: https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_robustness.txt, section
|
||||
// 2.6 "Graphics Reset Recovery".
|
||||
enum device_status {
|
||||
DEVICE_STATUS_NORMAL,
|
||||
DEVICE_STATUS_RESETTING,
|
||||
};
|
||||
|
||||
// When image properties are actually applied to the image, they are applied in a
|
||||
// particular order:
|
||||
//
|
||||
|
@ -273,6 +282,8 @@ struct backend_operations {
|
|||
enum driver (*detect_driver)(backend_t *backend_data);
|
||||
|
||||
void (*diagnostics)(backend_t *backend_data);
|
||||
|
||||
enum device_status (*device_status)(backend_t *backend_data);
|
||||
};
|
||||
|
||||
extern struct backend_operations *backend_list[];
|
||||
|
|
|
@ -1694,6 +1694,7 @@ bool gl_init(struct gl_data *gd, session_t *ps) {
|
|||
} else {
|
||||
gd->is_nvidia = false;
|
||||
}
|
||||
gd->has_robustness = gl_has_extension("GL_ARB_robustness");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1908,3 +1909,15 @@ bool gl_image_op(backend_t *base, enum image_operations op, void *image_data,
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
enum device_status gl_device_status(backend_t *base) {
|
||||
auto gd = (struct gl_data *)base;
|
||||
if (!gd->has_robustness) {
|
||||
return DEVICE_STATUS_NORMAL;
|
||||
}
|
||||
if (glGetGraphicsResetStatusARB() == GL_NO_ERROR) {
|
||||
return DEVICE_STATUS_NORMAL;
|
||||
} else {
|
||||
return DEVICE_STATUS_RESETTING;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,6 +75,8 @@ struct gl_data {
|
|||
backend_t base;
|
||||
// If we are using proprietary NVIDIA driver
|
||||
bool is_nvidia;
|
||||
// If ARB_robustness extension is present
|
||||
bool has_robustness;
|
||||
// Height and width of the root window
|
||||
int height, width;
|
||||
gl_win_shader_t win_shader;
|
||||
|
@ -132,6 +134,7 @@ void gl_fill(backend_t *base, struct color, const region_t *clip);
|
|||
|
||||
void gl_present(backend_t *base, const region_t *);
|
||||
bool gl_read_pixel(backend_t *base, void *image_data, int x, int y, struct color *output);
|
||||
enum device_status gl_device_status(backend_t *base);
|
||||
|
||||
static inline void gl_delete_texture(GLuint texture) {
|
||||
glDeleteTextures(1, &texture);
|
||||
|
|
|
@ -302,16 +302,21 @@ static backend_t *glx_init(session_t *ps) {
|
|||
continue;
|
||||
}
|
||||
|
||||
gd->ctx = glXCreateContextAttribsARB(ps->dpy, cfg[i], 0, true,
|
||||
(int[]){
|
||||
GLX_CONTEXT_MAJOR_VERSION_ARB,
|
||||
3,
|
||||
GLX_CONTEXT_MINOR_VERSION_ARB,
|
||||
3,
|
||||
GLX_CONTEXT_PROFILE_MASK_ARB,
|
||||
GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
|
||||
0,
|
||||
});
|
||||
int *attributes = (int[]){GLX_CONTEXT_MAJOR_VERSION_ARB,
|
||||
3,
|
||||
GLX_CONTEXT_MINOR_VERSION_ARB,
|
||||
3,
|
||||
GLX_CONTEXT_PROFILE_MASK_ARB,
|
||||
GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
|
||||
0,
|
||||
0,
|
||||
0};
|
||||
if (glxext.has_GLX_ARB_create_context_robustness) {
|
||||
attributes[6] = GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB;
|
||||
attributes[7] = GLX_LOSE_CONTEXT_ON_RESET_ARB;
|
||||
}
|
||||
|
||||
gd->ctx = glXCreateContextAttribsARB(ps->dpy, cfg[i], 0, true, attributes);
|
||||
free(cfg);
|
||||
|
||||
if (!gd->ctx) {
|
||||
|
@ -541,6 +546,7 @@ struct backend_operations glx_ops = {
|
|||
.destroy_blur_context = gl_destroy_blur_context,
|
||||
.get_blur_size = gl_get_blur_size,
|
||||
.diagnostics = glx_diagnostics,
|
||||
.device_status = gl_device_status,
|
||||
.max_buffer_age = 5, // Why?
|
||||
};
|
||||
|
||||
|
@ -608,6 +614,7 @@ void glxext_init(Display *dpy, int screen) {
|
|||
check_ext(GLX_EXT_texture_from_pixmap);
|
||||
check_ext(GLX_ARB_create_context);
|
||||
check_ext(GLX_EXT_buffer_age);
|
||||
check_ext(GLX_ARB_create_context_robustness);
|
||||
#ifdef GLX_MESA_query_renderer
|
||||
check_ext(GLX_MESA_query_renderer);
|
||||
#endif
|
||||
|
|
|
@ -55,6 +55,7 @@ struct glxext_info {
|
|||
bool has_GLX_ARB_create_context;
|
||||
bool has_GLX_EXT_buffer_age;
|
||||
bool has_GLX_MESA_query_renderer;
|
||||
bool has_GLX_ARB_create_context_robustness;
|
||||
};
|
||||
|
||||
extern struct glxext_info glxext;
|
||||
|
|
Loading…
Reference in New Issue