Revert "Remove xrender-sync and xrender-sync-fence"
This reverts commit 50e2259404
.
Temporarily revert the removal until we have more information about this whole
thing.
Turns out a couple of drivers don't work properly without the sync fence,
including intel, llvmpipe and NVIDIA.
Although sync fence is needed, from the information I have gathered (looking
at old bug reports, protocol specifications, look at other compositors' code),
compton's usage of it is not proper. So we need to rewrite it in the future,
after we get more information from driver developers.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
75
src/common.h
75
src/common.h
@ -49,6 +49,10 @@
|
||||
// #define CONFIG_OPENGL 1
|
||||
// Whether to enable DBus support with libdbus.
|
||||
// #define CONFIG_DBUS 1
|
||||
// Whether to enable X Sync support.
|
||||
// #define CONFIG_XSYNC 1
|
||||
// Whether to enable GLX Sync support.
|
||||
// #define CONFIG_GLX_XSYNC 1
|
||||
|
||||
#ifndef COMPTON_VERSION
|
||||
#define COMPTON_VERSION "unknown"
|
||||
@ -73,6 +77,7 @@
|
||||
|
||||
#include <X11/Xlib-xcb.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/sync.h>
|
||||
|
||||
#include <xcb/composite.h>
|
||||
#include <xcb/render.h>
|
||||
@ -310,7 +315,7 @@ typedef int (*f_SwapIntervalMESA) (unsigned int interval);
|
||||
typedef void (*f_BindTexImageEXT) (Display *display, GLXDrawable drawable, int buffer, const int *attrib_list);
|
||||
typedef void (*f_ReleaseTexImageEXT) (Display *display, GLXDrawable drawable, int buffer);
|
||||
|
||||
#ifdef CONFIG_GLX_SYNC
|
||||
#ifdef CONFIG_OPENGL
|
||||
// Looks like duplicate typedef of the same type is safe?
|
||||
typedef int64_t GLint64;
|
||||
typedef uint64_t GLuint64;
|
||||
@ -449,6 +454,11 @@ typedef struct options_t {
|
||||
char *display_repr;
|
||||
/// The backend in use.
|
||||
enum backend backend;
|
||||
/// Whether to sync X drawing to avoid certain delay issues with
|
||||
/// GLX backend.
|
||||
bool xrender_sync;
|
||||
/// Whether to sync X drawing with X Sync fence.
|
||||
bool xrender_sync_fence;
|
||||
/// Whether to avoid using stencil buffer under GLX backend. Might be
|
||||
/// unsafe.
|
||||
bool glx_no_stencil;
|
||||
@ -646,7 +656,6 @@ typedef struct {
|
||||
f_BindTexImageEXT glXBindTexImageProc;
|
||||
/// Pointer to glXReleaseTexImageEXT function.
|
||||
f_ReleaseTexImageEXT glXReleaseTexImageProc;
|
||||
#ifdef CONFIG_GLX_SYNC
|
||||
/// Pointer to the glFenceSync() function.
|
||||
f_FenceSync glFenceSyncProc;
|
||||
/// Pointer to the glIsSync() function.
|
||||
@ -659,7 +668,6 @@ typedef struct {
|
||||
f_WaitSync glWaitSyncProc;
|
||||
/// Pointer to the glImportSyncEXT() function.
|
||||
f_ImportSyncEXT glImportSyncEXT;
|
||||
#endif
|
||||
#ifdef DEBUG_GLX_MARK
|
||||
/// Pointer to StringMarkerGREMEDY function.
|
||||
f_StringMarkerGREMEDY glStringMarkerGREMEDY;
|
||||
@ -721,6 +729,7 @@ typedef struct session {
|
||||
xcb_render_picture_t tgt_picture;
|
||||
/// Temporary buffer to paint to before sending to display.
|
||||
paint_t tgt_buffer;
|
||||
XSyncFence tgt_buffer_fence;
|
||||
/// Window ID of the window we register as a symbol.
|
||||
Window reg_win;
|
||||
#ifdef CONFIG_OPENGL
|
||||
@ -885,6 +894,12 @@ typedef struct session {
|
||||
/// Number of Xinerama screens.
|
||||
int xinerama_nscrs;
|
||||
#endif
|
||||
/// Whether X Sync extension exists.
|
||||
bool xsync_exists;
|
||||
/// Event base number for X Sync extension.
|
||||
int xsync_event;
|
||||
/// Error base number for X Sync extension.
|
||||
int xsync_error;
|
||||
/// Whether X Render convolution filter exists.
|
||||
bool xrfilter_convolution_exists;
|
||||
|
||||
@ -1463,6 +1478,16 @@ free_all_damage_last(session_t *ps) {
|
||||
pixman_region32_clear(&ps->all_damage_last[i]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Free a XSync fence.
|
||||
*/
|
||||
static inline void
|
||||
free_fence(session_t *ps, XSyncFence *pfence) {
|
||||
if (*pfence)
|
||||
XSyncDestroyFence(ps->dpy, *pfence);
|
||||
*pfence = None;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a rectangle includes the whole screen.
|
||||
*/
|
||||
@ -1613,10 +1638,8 @@ vsync_deinit(session_t *ps);
|
||||
*/
|
||||
///@{
|
||||
|
||||
#ifdef CONFIG_GLX_SYNC
|
||||
void
|
||||
xr_glx_sync(session_t *ps, Drawable d, XSyncFence *pfence);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Free a GLX texture.
|
||||
@ -1701,6 +1724,48 @@ glx_mark_frame(session_t *ps) {
|
||||
|
||||
///@}
|
||||
|
||||
/**
|
||||
* Synchronizes a X Render drawable to ensure all pending painting requests
|
||||
* are completed.
|
||||
*/
|
||||
static inline void
|
||||
xr_sync(session_t *ps, Drawable d, XSyncFence *pfence) {
|
||||
if (!ps->o.xrender_sync)
|
||||
return;
|
||||
|
||||
x_sync(ps->c);
|
||||
if (ps->o.xrender_sync_fence && ps->xsync_exists) {
|
||||
// TODO: If everybody just follows the rules stated in X Sync prototype,
|
||||
// we need only one fence per screen, but let's stay a bit cautious right
|
||||
// now
|
||||
XSyncFence tmp_fence = None;
|
||||
if (!pfence)
|
||||
pfence = &tmp_fence;
|
||||
assert(pfence);
|
||||
if (!*pfence)
|
||||
*pfence = XSyncCreateFence(ps->dpy, d, False);
|
||||
if (*pfence) {
|
||||
Bool __attribute__((unused)) triggered = False;
|
||||
/* if (XSyncQueryFence(ps->dpy, *pfence, &triggered) && triggered)
|
||||
XSyncResetFence(ps->dpy, *pfence); */
|
||||
// The fence may fail to be created (e.g. because of died drawable)
|
||||
assert(!XSyncQueryFence(ps->dpy, *pfence, &triggered) || !triggered);
|
||||
XSyncTriggerFence(ps->dpy, *pfence);
|
||||
XSyncAwaitFence(ps->dpy, pfence, 1);
|
||||
assert(!XSyncQueryFence(ps->dpy, *pfence, &triggered) || triggered);
|
||||
}
|
||||
else {
|
||||
printf_errf("(%#010lx): Failed to create X Sync fence.", d);
|
||||
}
|
||||
free_fence(ps, &tmp_fence);
|
||||
if (*pfence)
|
||||
XSyncResetFence(ps->dpy, *pfence);
|
||||
}
|
||||
#ifdef OPENGL
|
||||
xr_glx_sync(ps, d, pfence);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** @name DBus handling
|
||||
*/
|
||||
///@{
|
||||
|
Reference in New Issue
Block a user