diff options
Diffstat (limited to 'glamor')
-rw-r--r-- | glamor/Makefile.am | 1 | ||||
-rw-r--r-- | glamor/glamor.c | 2 | ||||
-rw-r--r-- | glamor/glamor_priv.h | 15 | ||||
-rw-r--r-- | glamor/glamor_sync.c | 117 |
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 +} |