[Xfce4-commits] [xfce/xfwm4] 05/11: compositor: Finer fence control
noreply at xfce.org
noreply at xfce.org
Wed May 15 22:51:26 CEST 2019
This is an automated email from the git hooks/post-receive script.
o l i v i e r p u s h e d a c o m m i t t o b r a n c h m a s t e r
in repository xfce/xfwm4.
commit 340f9e8275aac21944a7882a76c84593aa156aa1
Author: Olivier Fourdan <fourdan at xfce.org>
Date: Tue May 14 23:14:07 2019 +0200
compositor: Finer fence control
Basically, we want the fence to prevent GL from accessing the pixmap
buffer until its update is complete.
However, depending on the code path, we may update the buffer more than
once, so to prevent any flickering, we need a finer grain control over
the fence operations.
Split the fence support into different actions as we need them, i.e.
create, destroy, reset, trigger and wait.
Make sure we reset the fence before each time we are to update the
pixmap buffer and wait for the fence just before doing the GL swap.
Also create a different fence for each buffer, so if ever decide to use
multiple buffers with GL, the existing code will be able to support that
and not use the same fence for multiple pixmaps.
Signed-off-by: Olivier Fourdan <fourdan at xfce.org>
---
src/compositor.c | 124 ++++++++++++++++++++++++++++++++++++++++++++-----------
src/screen.h | 2 +-
2 files changed, 101 insertions(+), 25 deletions(-)
diff --git a/src/compositor.c b/src/compositor.c
index 4d91c1d..3ba9b4b 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -1449,36 +1449,93 @@ unbind_glx_texture (ScreenInfo *screen_info)
}
static void
-fence_sync_pixmap (ScreenInfo *screen_info, Pixmap pixmap)
+fence_await (ScreenInfo *screen_info, gushort buffer)
{
#ifdef HAVE_XSYNC
- Bool triggered = False;
+ if (screen_info->fence[buffer] == None)
+ {
+ return;
+ }
- if (screen_info->fence == None)
+ TRACE ("Awaiting fence for buffer %i", buffer);
+ XSyncAwaitFence(myScreenGetXDisplay (screen_info),
+ &screen_info->fence[buffer], 1);
+#endif /* HAVE_XSYNC */
+}
+
+static void
+fence_reset (ScreenInfo *screen_info, gushort buffer)
+{
+#ifdef HAVE_XSYNC
+ if (screen_info->fence[buffer] == None)
{
- screen_info->fence = XSyncCreateFence (myScreenGetXDisplay (screen_info), pixmap, FALSE);
+ return;
}
- if (!screen_info->fence)
+ DBG ("Reset fence for buffer %i", buffer);
+ XSyncResetFence(myScreenGetXDisplay (screen_info),
+ screen_info->fence[buffer]);
+#endif /* HAVE_XSYNC */
+}
+
+static void
+fence_create (ScreenInfo *screen_info, gushort buffer)
+{
+#ifdef HAVE_XSYNC
+ if (screen_info->fence[buffer] == None)
+ {
+ DBG ("Create fence for buffer %i", buffer);
+ screen_info->fence[buffer] =
+ XSyncCreateFence (myScreenGetXDisplay (screen_info),
+ screen_info->rootPixmap[buffer], FALSE);
+ }
+#endif /* HAVE_XSYNC */
+}
+
+static void
+fence_trigger (ScreenInfo *screen_info, gushort buffer)
+{
+#ifdef HAVE_XSYNC
+ Bool triggered = False;
+
+ if (screen_info->fence[buffer] == None)
{
- TRACE ("Cannot create fence\n");
+ DBG ("No fence for buffer %i", buffer);
return;
}
+
if (!XSyncQueryFence(myScreenGetXDisplay (screen_info),
- screen_info->fence, &triggered))
+ screen_info->fence[buffer], &triggered))
{
- TRACE ("Cannot query fence\n");
+ DBG ("Cannot query fence for buffer %i", buffer);
return;
}
+
if (triggered)
{
- TRACE ("Fence already triggered\n");
+ DBG ("Fence for buffer %i already triggered", buffer);
return;
}
- TRACE ("Awaiting fence of drawable 0x%x\n", pixmap);
- XSyncTriggerFence(myScreenGetXDisplay (screen_info), screen_info->fence);
- XSyncAwaitFence(myScreenGetXDisplay (screen_info), &screen_info->fence, 1);
- XSyncResetFence(myScreenGetXDisplay (screen_info), screen_info->fence);
- TRACE ("Fence for drawable 0x%x cleared\n", pixmap);
+
+
+ DBG ("Trigger fence for buffer %i", buffer);
+ XSyncTriggerFence(myScreenGetXDisplay (screen_info),
+ screen_info->fence[buffer]);
+#else
+ XSync (myScreenGetXDisplay (screen_info), FALSE);
+#endif /* HAVE_XSYNC */
+}
+
+static void
+fence_destroy (ScreenInfo *screen_info, gushort buffer)
+{
+#ifdef HAVE_XSYNC
+ if (screen_info->fence[buffer])
+ {
+ DBG ("Destroying fence for buffer %i", buffer);
+ XSyncDestroyFence (myScreenGetXDisplay (screen_info),
+ screen_info->fence[buffer]);
+ screen_info->fence[buffer] = None;
+ }
#endif /* HAVE_XSYNC */
}
@@ -1568,7 +1625,7 @@ redraw_glx_screen (ScreenInfo *screen_info)
}
static void
-redraw_glx_texture (ScreenInfo *screen_info, XserverRegion region)
+redraw_glx_texture (ScreenInfo *screen_info, XserverRegion region, gushort buffer)
{
g_return_if_fail (screen_info != NULL);
TRACE ("(re)Drawing GLX pixmap 0x%lx/texture 0x%x",
@@ -1597,6 +1654,8 @@ redraw_glx_texture (ScreenInfo *screen_info, XserverRegion region)
set_glx_scale (screen_info, screen_info->width, screen_info->height, zoom);
glTranslated (x, y, 0.0);
+
+ fence_await (screen_info, buffer);
redraw_glx_screen (screen_info);
}
else
@@ -1610,6 +1669,7 @@ redraw_glx_texture (ScreenInfo *screen_info, XserverRegion region)
rects = XFixesFetchRegionAndBounds (myScreenGetXDisplay (screen_info),
region, &nrects, &bounds);
+ fence_await (screen_info, buffer);
redraw_glx_rects (screen_info, rects, nrects);
XFree (rects);
}
@@ -1642,7 +1702,7 @@ present_error (DisplayInfo *display_info, int error_code)
}
static void
-present_flip (ScreenInfo *screen_info, XserverRegion region, Pixmap pixmap)
+present_flip (ScreenInfo *screen_info, XserverRegion region, gushort buffer)
{
static guint32 present_serial;
DisplayInfo *display_info;
@@ -1650,13 +1710,14 @@ present_flip (ScreenInfo *screen_info, XserverRegion region, Pixmap pixmap)
g_return_if_fail (screen_info != NULL);
g_return_if_fail (region != None);
- g_return_if_fail (pixmap != None);
+ g_return_if_fail (screen_info->rootPixmap[buffer] != None);
TRACE ("serial %d", present_serial);
display_info = screen_info->display_info;
myDisplayErrorTrapPush (display_info);
XPresentPixmap (display_info->dpy, screen_info->output,
- pixmap, present_serial++, None, region, 0, 0, None, None, None,
+ screen_info->rootPixmap[buffer],
+ present_serial++, None, region, 0, 0, None, None, None,
PresentOptionNone, 0, 1, 0, NULL, 0);
result = myDisplayErrorTrapPop (display_info);
@@ -2087,6 +2148,7 @@ paint_all (ScreenInfo *screen_info, XserverRegion region, gushort buffer)
{
bind_glx_texture (screen_info,
screen_info->rootPixmap[buffer]);
+ fence_create (screen_info, buffer);
}
#endif /* HAVE_EPOXY */
}
@@ -2183,6 +2245,12 @@ paint_all (ScreenInfo *screen_info, XserverRegion region, gushort buffer)
XFixesSetPictureClipRegion (dpy, paint_buffer, 0, 0, paint_region);
if (!is_region_empty (dpy, paint_region))
{
+#ifdef HAVE_EPOXY
+ if (screen_info->use_glx)
+ {
+ fence_reset (screen_info, buffer);
+ }
+#endif /* HAVE_EPOXY */
paint_root (screen_info, paint_buffer);
}
@@ -2249,6 +2317,7 @@ paint_all (ScreenInfo *screen_info, XserverRegion region, gushort buffer)
{
if (screen_info->zoomed)
{
+ fence_reset (screen_info, buffer);
paint_cursor (screen_info, region,
screen_info->rootBuffer[buffer]);
}
@@ -2292,9 +2361,8 @@ paint_all (ScreenInfo *screen_info, XserverRegion region, gushort buffer)
#ifdef HAVE_EPOXY
if (screen_info->use_glx)
{
- fence_sync_pixmap (screen_info,
- screen_info->rootPixmap[buffer]);
- redraw_glx_texture (screen_info, region);
+ fence_trigger (screen_info, buffer);
+ redraw_glx_texture (screen_info, region, buffer);
}
else
#endif /* HAVE_EPOXY */
@@ -4453,6 +4521,11 @@ compositorManageScreen (ScreenInfo *screen_info)
{
screen_info->rootPixmap[buffer] = None;
screen_info->rootBuffer[buffer] = None;
+#ifdef HAVE_EPOXY
+#ifdef HAVE_XSYNC
+ screen_info->fence[buffer] = None;
+#endif /* HAVE_XSYNC */
+#endif /* HAVE_EPOXY */
}
XClearArea (display_info->dpy, screen_info->output, 0, 0, 0, 0, TRUE);
TRACE ("manual compositing enabled");
@@ -4471,9 +4544,6 @@ compositorManageScreen (ScreenInfo *screen_info)
screen_info->rootTexture = None;
screen_info->glx_drawable = None;
screen_info->texture_filter = GL_LINEAR;
-#ifdef HAVE_XSYNC
- screen_info->fence = None;
-#endif /* HAVE_XSYNC */
screen_info->use_glx = init_glx (screen_info);
}
#else /* HAVE_EPOXY */
@@ -4592,6 +4662,9 @@ compositorUnmanageScreen (ScreenInfo *screen_info)
XRenderFreePicture (display_info->dpy, screen_info->rootBuffer[buffer]);
screen_info->rootBuffer[buffer] = None;
}
+#ifdef HAVE_EPOXY
+ fence_destroy (screen_info, buffer);
+#endif /* HAVE_EPOXY */
}
if (screen_info->allDamage)
@@ -4779,6 +4852,9 @@ compositorUpdateScreenSize (ScreenInfo *screen_info)
XRenderFreePicture (display_info->dpy, screen_info->rootBuffer[buffer]);
screen_info->rootBuffer[buffer] = None;
}
+#ifdef HAVE_EPOXY
+ fence_destroy (screen_info, buffer);
+#endif /* HAVE_EPOXY */
}
damage_screen (screen_info);
diff --git a/src/screen.h b/src/screen.h
index 60490f3..0370ed6 100644
--- a/src/screen.h
+++ b/src/screen.h
@@ -227,7 +227,7 @@ struct _ScreenInfo
GLXContext glx_context;
GLXWindow glx_window;
#ifdef HAVE_XSYNC
- XSyncFence fence;
+ XSyncFence fence[2];
#endif /* HAVE_XSYNC */
#endif /* HAVE_EPOXY */
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the Xfce4-commits
mailing list