Skip to content

Commit

Permalink
Merge branch 'next'
Browse files Browse the repository at this point in the history
  • Loading branch information
yshui committed Nov 10, 2018
2 parents 403d170 + d0e824e commit a34dfd3
Show file tree
Hide file tree
Showing 15 changed files with 223 additions and 77 deletions.
2 changes: 2 additions & 0 deletions .github/issue_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

### GPU, drivers, and screen setup
// Example: NVidia GTX 670, nvidia-drivers 381.09, two monitors configured side-by-side with xrandr
// Please include the version of the video drivers (xf86-video-*) and mesa.
// Please also paste the output of `glxinfo -B` here.

### Environment
// Tell us something about the desktop environment you are using, for example: i3-gaps, Gnome Shell, etc.
Expand Down
2 changes: 2 additions & 0 deletions compton.sample.conf
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ invert-color-include = [ ];
# glx-no-rebind-pixmap = true;
glx-swap-method = "undefined";
# glx-use-gpushader4 = true;
# xrender-sync = true;
# xrender-sync-fence = true;

# Window type settings
wintypes:
Expand Down
8 changes: 7 additions & 1 deletion man/compton.1.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ May also be one of the predefined kernels: `3x3box` (default), `5x5box`, `7x7box
+
--
* `xrender` backend performs all rendering operations with X Render extension. It is what `xcompmgr` uses, and is generally a safe fallback when you encounter rendering artifacts or instability.
* `glx` (OpenGL) backend performs all rendering operations with OpenGL. It is more friendly to some VSync methods, and has significantly superior performance on color inversion (`--invert-color-include`) or blur (`--blur-background`). It requires proper OpenGL 2.0 support from your driver and hardware. You may wish to look at the GLX performance optimization options below.
* `glx` (OpenGL) backend performs all rendering operations with OpenGL. It is more friendly to some VSync methods, and has significantly superior performance on color inversion (`--invert-color-include`) or blur (`--blur-background`). It requires proper OpenGL 2.0 support from your driver and hardware. You may wish to look at the GLX performance optimization options below. `--xrender-sync` and `--xrender-sync-fence` might be needed on some systems to avoid delay in changes of screen contents.
* `xr_glx_hybrid` backend renders the updated screen contents with X Render and presents it on the screen with GLX. It attempts to address the rendering issues some users encountered with GLX backend and enables the better VSync of GLX backends. `--vsync-use-glfinish` might fix some rendering issues with this backend.
--

Expand All @@ -258,6 +258,12 @@ May also be one of the predefined kernels: `3x3box` (default), `5x5box`, `7x7box
*--glx-use-gpushader4*::
GLX backend: Use 'GL_EXT_gpu_shader4' for some optimization on blur GLSL code. My tests on GTX 670 show no noticeable effect.

*--xrender-sync*::
Attempt to synchronize client applications' draw calls with `XSync()`, used on GLX backend to ensure up-to-date window content is painted.

*--xrender-sync-fence*::
Additionally use X Sync fence to sync clients' draw calls. Needed on nvidia-drivers with GLX backend for some users. May be disabled at compile time with `NO_XSYNC=1`.

*--glx-fshader-win* 'SHADER'::
GLX backend: Use specified GLSL fragment shader for rendering window contents. See `compton-default-fshader-win.glsl` and `compton-fake-transparency-fshader-win.glsl` in the source tree for examples.

Expand Down
6 changes: 3 additions & 3 deletions src/c2.c
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ c2_match_once(session_t *ps, win *w, const c2_ptr_t cond);
* Parse a condition string.
*/
c2_lptr_t *
c2_parsed(session_t *ps, c2_lptr_t **pcondlst, const char *pattern,
c2_parse(session_t *ps, c2_lptr_t **pcondlst, const char *pattern,
void *data) {
if (!pattern)
return NULL;
Expand Down Expand Up @@ -1645,9 +1645,9 @@ c2_match_once(session_t *ps, win *w, const c2_ptr_t cond) {
* @return true if matched, false otherwise.
*/
bool
c2_matchd(session_t *ps, win *w, const c2_lptr_t *condlst,
c2_match(session_t *ps, win *w, const c2_lptr_t *condlst,
const c2_lptr_t **cache, void **pdata) {
assert(IsViewable == w->a.map_state);
assert(w->a.map_state == XCB_MAP_STATE_VIEWABLE);

// Check if the cached entry matches firstly
if (cache && *cache && c2_match_once(ps, w, (*cache)->ptr)) {
Expand Down
9 changes: 2 additions & 7 deletions src/c2.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,12 @@ typedef struct session session_t;
typedef struct win win;

c2_lptr_t *
c2_parsed(session_t *ps, c2_lptr_t **pcondlst, const char *pattern,
c2_parse(session_t *ps, c2_lptr_t **pcondlst, const char *pattern,
void *data);

#define c2_parse(ps, pcondlst, pattern) c2_parsed((ps), (pcondlst), (pattern), NULL)

c2_lptr_t *
c2_free_lptr(c2_lptr_t *lp);

bool
c2_matchd(session_t *ps, win *w, const c2_lptr_t *condlst,
c2_match(session_t *ps, win *w, const c2_lptr_t *condlst,
const c2_lptr_t **cache, void **pdata);

#define c2_match(ps, w, condlst, cache) c2_matchd((ps), (w), (condlst), \
(cache), NULL)
77 changes: 71 additions & 6 deletions src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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>
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -1437,7 +1452,7 @@ glx_has_context(session_t *ps) {
*/
static inline bool
win_is_focused_real(session_t *ps, const win *w) {
return IsViewable == w->a.map_state && ps->active_win == w;
return w->a.map_state == XCB_MAP_STATE_VIEWABLE && ps->active_win == w;
}

/**
Expand All @@ -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.
*/
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
*/
///@{
Expand Down
Loading

0 comments on commit a34dfd3

Please sign in to comment.