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:
Yuxuan Shui
2018-11-08 14:53:13 +00:00
parent ab7a2f1872
commit b18d46bcbd
9 changed files with 174 additions and 23 deletions

View File

@ -248,6 +248,7 @@ static inline void
free_win_res(session_t *ps, win *w) {
free_win_res_glx(ps, w);
free_paint(ps, &w->paint);
free_fence(ps, &w->fence);
pixman_region32_fini(&w->bounding_shape);
free_paint(ps, &w->shadow_paint);
// BadDamage may be thrown if the window is destroyed
@ -886,6 +887,9 @@ win_build_shadow(session_t *ps, win *w, double opacity) {
assert(!w->shadow_paint.pict);
w->shadow_paint.pict = shadow_picture_argb;
// Sync it once and only once
xr_sync(ps, w->shadow_paint.pixmap, NULL);
xcb_free_gc(ps->c, gc);
xcb_image_destroy(shadow_image);
xcb_free_pixmap(ps->c, shadow_pixmap);
@ -1627,6 +1631,8 @@ paint_one(session_t *ps, win *w, const region_t *reg_paint) {
w->paint.pixmap = xcb_generate_id(ps->c);
set_ignore_cookie(ps,
xcb_composite_name_window_pixmap(ps->c, w->id, w->paint.pixmap));
if (w->paint.pixmap)
free_fence(ps, &w->fence);
}
Drawable draw = w->paint.pixmap;
@ -1643,6 +1649,9 @@ paint_one(session_t *ps, win *w, const region_t *reg_paint) {
draw, XCB_RENDER_CP_SUBWINDOW_MODE, &pa);
}
if (IsViewable == w->a.map_state)
xr_sync(ps, draw, &w->fence);
// GLX: Build texture
// Let glx_bind_pixmap() determine pixmap size, because if the user
// is resizing windows, the width and height we get may not be up-to-date,
@ -2023,9 +2032,12 @@ paint_all(session_t *ps, region_t *region, const region_t *region_real, win * co
glFlush();
glXWaitX();
assert(ps->tgt_buffer.pixmap);
xr_sync(ps, ps->tgt_buffer.pixmap, &ps->tgt_buffer_fence);
paint_bind_tex(ps, &ps->tgt_buffer,
ps->root_width, ps->root_height, ps->depth,
!ps->o.glx_no_rebind_pixmap);
// See #163
xr_sync(ps, ps->tgt_buffer.pixmap, &ps->tgt_buffer_fence);
if (ps->o.vsync_use_glfinish)
glFinish();
else
@ -2259,6 +2271,11 @@ unmap_win(session_t *ps, win **_w) {
if (w->destroyed) return;
// One last synchronization
if (w->paint.pixmap)
xr_sync(ps, w->paint.pixmap, &w->fence);
free_fence(ps, &w->fence);
// Set focus out
win_set_focused(ps, w, false);
@ -2723,6 +2740,14 @@ ev_name(session_t *ps, xcb_generic_event_t *ev) {
if (ps->shape_exists && ev->response_type == ps->shape_event)
return "ShapeNotify";
if (ps->xsync_exists) {
int o = ev->response_type - ps->xsync_event;
switch (o) {
CASESTRRET(XSyncCounterNotify);
CASESTRRET(XSyncAlarmNotify);
}
}
sprintf(buf, "Event %d", ev->response_type);
return buf;
@ -3570,7 +3595,6 @@ usage(int ret) {
"--backend backend\n"
" Choose backend. Possible choices are xrender, glx, and\n"
" xr_glx_hybrid" WARNING ".\n"
#undef WARNING
"\n"
"--glx-no-stencil\n"
" GLX backend: Avoid using stencil buffer. Might cause issues\n"
@ -3595,6 +3619,16 @@ usage(int ret) {
" GLX backend: Use GL_EXT_gpu_shader4 for some optimization on blur\n"
" GLSL code. My tests on GTX 670 show no noticeable effect.\n"
"\n"
"--xrender-sync\n"
" Attempt to synchronize client applications' draw calls with XSync(),\n"
" used on GLX backend to ensure up-to-date window content is painted.\n"
#undef WARNING
#define WARNING
"\n"
"--xrender-sync-fence\n"
" Additionally use X Sync fence to sync clients' draw calls. Needed\n"
" on nvidia-drivers with GLX backend for some users." WARNING "\n"
"\n"
"--glx-fshader-win shader\n"
" GLX backend: Use specified GLSL fragment shader for rendering window\n"
" contents.\n"
@ -3612,7 +3646,6 @@ usage(int ret) {
"--dbus\n"
" Enable remote control via D-Bus. See the D-BUS API section in the\n"
" man page for more details." WARNING "\n"
#undef WARNING
"\n"
"--benchmark cycles\n"
" Benchmark mode. Repeatedly paint until reaching the specified cycles.\n"
@ -3626,6 +3659,7 @@ usage(int ret) {
;
FILE *f = (ret ? stderr: stdout);
fputs(usage_text, f);
#undef WARNING
#undef WARNING_DISABLED
exit(ret);
@ -4154,12 +4188,8 @@ get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass) {
ps->o.write_pid_path = mstrcpy(optarg);
break;
P_CASEBOOL(311, vsync_use_glfinish);
case 312:
printf_errf("(): --xrender-sync %s", deprecation_message);
break;
case 313:
printf_errf("(): --xrender-sync-fence %s", deprecation_message);
break;
P_CASEBOOL(312, xrender_sync);
P_CASEBOOL(313, xrender_sync_fence);
P_CASEBOOL(315, no_fading_destroyed_argb);
P_CASEBOOL(316, force_win_blend);
case 317:
@ -4216,6 +4246,9 @@ get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass) {
if (ps->o.blur_background_frame)
ps->o.blur_background = true;
if (ps->o.xrender_sync_fence)
ps->o.xrender_sync = true;
// Other variables determined by options
// Determine whether we need to track focus changes
@ -4789,8 +4822,10 @@ redir_stop(session_t *ps) {
// Destroy all Pictures as they expire once windows are unredirected
// If we don't destroy them here, looks like the resources are just
// kept inaccessible somehow
for (win *w = ps->list; w; w = w->next)
for (win *w = ps->list; w; w = w->next) {
free_paint(ps, &w->paint);
free_fence(ps, &w->fence);
}
xcb_composite_unredirect_subwindows(ps->c, ps->root, XCB_COMPOSITE_REDIRECT_MANUAL);
// Unmap overlay window
@ -5301,6 +5336,20 @@ session_init(session_t *ps_old, int argc, char **argv) {
ps->present_exists = true;
}
// Query X Sync
if (XSyncQueryExtension(ps->dpy, &ps->xsync_event, &ps->xsync_error)) {
// TODO: Fencing may require version >= 3.0?
int major_version_return = 0, minor_version_return = 0;
if (XSyncInitialize(ps->dpy, &major_version_return, &minor_version_return))
ps->xsync_exists = true;
}
if (!ps->xsync_exists && ps->o.xrender_sync_fence) {
printf_errf("(): X Sync extension not found. No X Sync fence sync is "
"possible.");
exit(1);
}
// Query X RandR
if ((ps->o.sw_opti && !ps->o.refresh_rate) || ps->o.xinerama_shadow_crop) {
if (!ps->randr_exists) {
@ -5614,6 +5663,7 @@ session_destroy(session_t *ps) {
ps->tgt_picture = None;
else
free_picture(ps, &ps->tgt_picture);
free_fence(ps, &ps->tgt_buffer_fence);
free_picture(ps, &ps->root_picture);
free_paint(ps, &ps->tgt_buffer);