[PATCH] glamor: Add support for SHM sync fences

Keith Packard keithp at keithp.com
Fri Jul 18 11:27:12 PDT 2014


This hooks up SHM sync fences to complete the requirements for DRI3
running on Glamor.

Signed-off-by: Keith Packard <keithp at keithp.com>
---
 glamor/Makefile.am   |   1 +
 glamor/glamor.c      |   2 +
 glamor/glamor_priv.h |  15 +++++++
 glamor/glamor_sync.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 135 insertions(+)
 create mode 100644 glamor/glamor_sync.c

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 334d8fc..db72cb1 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -47,6 +47,7 @@ libglamor_la_SOURCES = \
 	glamor_utils.c\
 	glamor_utils.h\
 	glamor_xv.c \
+	glamor_sync.c \
 	glamor.h
 
 libglamor_egl_stubs_la_SOURCES = glamor_egl_stubs.c
diff --git a/glamor/glamor.c b/glamor/glamor.c
index d7b8b09..521bc25 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -519,6 +519,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 #endif
     glamor_pixmap_init(screen);
     glamor_glyphs_init(screen);
+    glamor_sync_init(screen);
 
     glamor_priv->screen = screen;
 
@@ -588,6 +589,7 @@ glamor_close_screen(ScreenPtr screen)
 #endif
     glamor_priv = glamor_get_screen_private(screen);
     flags = glamor_priv->flags;
+    glamor_sync_close(screen);
     glamor_glyphs_fini(screen);
     screen->CloseScreen = glamor_priv->saved_procs.close_screen;
     screen->CreateScreenResources =
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 2a9ecce..57a4687 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -33,6 +33,11 @@
 #include "glamor.h"
 #include "xvdix.h"
 
+#if XSYNC
+#include "misyncshm.h"
+#include "misyncstr.h"
+#endif
+
 #include <epoxy/gl.h>
 #if GLAMOR_HAS_GBM
 #define MESA_EGL_NO_X11_HEADERS
@@ -184,6 +189,9 @@ struct glamor_saved_procs {
     DestroyPictureProcPtr destroy_picture;
     UnrealizeGlyphProcPtr unrealize_glyph;
     SetWindowPixmapProcPtr set_window_pixmap;
+#if XSYNC
+    SyncScreenFuncsRec sync_screen_funcs;
+#endif
 };
 
 #define CACHE_FORMAT_COUNT 3
@@ -978,6 +986,13 @@ void glamor_composite_rectangles(CARD8 op,
                                  xRenderColor *color,
                                  int num_rects, xRectangle *rects);
 
+/* glamor_sync.c */
+Bool
+glamor_sync_init(ScreenPtr screen);
+
+void
+glamor_sync_close(ScreenPtr screen);
+
 /* glamor_util.c */
 void
 glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
diff --git a/glamor/glamor_sync.c b/glamor/glamor_sync.c
new file mode 100644
index 0000000..d3d64a9
--- /dev/null
+++ b/glamor/glamor_sync.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright © 2014 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+
+#include "glamor_priv.h"
+#include "misyncshm.h"
+#include "misyncstr.h"
+
+#if XSYNC
+/*
+ * This whole file exists to wrap a sync fence trigger operation so
+ * that we can flush GL to provide serialization between the server
+ * and the shm fence client
+ */
+
+static DevPrivateKeyRec glamor_sync_fence_key;
+
+struct glamor_sync_fence {
+        SyncFenceSetTriggeredFunc set_triggered;
+};
+
+static inline struct glamor_sync_fence *
+glamor_get_sync_fence(SyncFence *fence)
+{
+    return (struct glamor_sync_fence *) dixLookupPrivate(&fence->devPrivates, &glamor_sync_fence_key);
+}
+
+static void
+glamor_sync_fence_set_triggered (SyncFence *fence)
+{
+	ScreenPtr screen = fence->pScreen;
+	glamor_screen_private *glamor = glamor_get_screen_private(screen);
+	struct glamor_sync_fence *glamor_fence = glamor_get_sync_fence(fence);
+
+	/* Flush pending rendering operations */
+        glamor_make_current(glamor);
+        glFinish();
+
+	fence->funcs.SetTriggered = glamor_fence->set_triggered;
+	fence->funcs.SetTriggered(fence);
+	glamor_fence->set_triggered = fence->funcs.SetTriggered;
+	fence->funcs.SetTriggered = glamor_sync_fence_set_triggered;
+}
+
+static void
+glamor_sync_create_fence(ScreenPtr screen,
+                        SyncFence *fence,
+                        Bool initially_triggered)
+{
+	glamor_screen_private *glamor = glamor_get_screen_private(screen);
+	SyncScreenFuncsPtr screen_funcs = miSyncGetScreenFuncs(screen);
+	struct glamor_sync_fence *glamor_fence = glamor_get_sync_fence(fence);
+
+	screen_funcs->CreateFence = glamor->saved_procs.sync_screen_funcs.CreateFence;
+	screen_funcs->CreateFence(screen, fence, initially_triggered);
+	glamor->saved_procs.sync_screen_funcs.CreateFence = screen_funcs->CreateFence;
+	screen_funcs->CreateFence = glamor_sync_create_fence;
+
+	glamor_fence->set_triggered = fence->funcs.SetTriggered;
+	fence->funcs.SetTriggered = glamor_sync_fence_set_triggered;
+}
+#endif
+
+Bool
+glamor_sync_init(ScreenPtr screen)
+{
+#if XSYNC
+	glamor_screen_private   *glamor = glamor_get_screen_private(screen);
+	SyncScreenFuncsPtr      screen_funcs;
+
+	if (!dixPrivateKeyRegistered(&glamor_sync_fence_key)) {
+		if (!dixRegisterPrivateKey(&glamor_sync_fence_key,
+					   PRIVATE_SYNC_FENCE,
+					   sizeof (struct glamor_sync_fence)))
+			return FALSE;
+	}
+
+	if (!miSyncShmScreenInit(screen))
+		return FALSE;
+
+	screen_funcs = miSyncGetScreenFuncs(screen);
+	glamor->saved_procs.sync_screen_funcs.CreateFence = screen_funcs->CreateFence;
+	screen_funcs->CreateFence = glamor_sync_create_fence;
+#endif
+	return TRUE;
+}
+
+void
+glamor_sync_close(ScreenPtr screen)
+{
+#if XSYNC
+        glamor_screen_private   *glamor = glamor_get_screen_private(screen);
+        SyncScreenFuncsPtr      screen_funcs = miSyncGetScreenFuncs(screen);
+
+        if (screen_funcs)
+                screen_funcs->CreateFence = glamor->saved_procs.sync_screen_funcs.CreateFence;
+#endif
+}
-- 
2.0.1



More information about the xorg-devel mailing list