summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2014-07-18 11:16:27 -0700
committerKeith Packard <keithp@keithp.com>2014-07-18 12:22:50 -0700
commitcfa302d6224d10860e60491333950544c4fb9b04 (patch)
treed3038f8ee415de14f56785483424e6ed2d68f8a8
parentac3acab1311c47cc73e2681e575f0407284c3c66 (diff)
glamor: Add support for SHM sync fences
This hooks up SHM sync fences to complete the requirements for DRI3 running on Glamor. Signed-off-by: Keith Packard <keithp@keithp.com> Reviewed-by: Eric Anholt <eric@anholt.net>
-rw-r--r--glamor/Makefile.am1
-rw-r--r--glamor/glamor.c2
-rw-r--r--glamor/glamor_priv.h15
-rw-r--r--glamor/glamor_sync.c117
4 files changed, 135 insertions, 0 deletions
diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 334d8fc20..db72cb11c 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 d7b8b09a9..521bc25c8 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 2a9eccef4..57a46873c 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 000000000..d3d64a925
--- /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
+}