1/* 2 * Copyright © 2014 Keith Packard 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that copyright 7 * notice and this permission notice appear in supporting documentation, and 8 * that the name of the copyright holders not be used in advertising or 9 * publicity pertaining to distribution of the software without specific, 10 * written prior permission. The copyright holders make no representations 11 * about the suitability of this software for any purpose. It is provided "as 12 * is" without express or implied warranty. 13 * 14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 20 * OF THIS SOFTWARE. 21 */ 22 23 24#include "glamor_priv.h" 25#include "misyncshm.h" 26#include "misyncstr.h" 27 28#if XSYNC 29/* 30 * This whole file exists to wrap a sync fence trigger operation so 31 * that we can flush GL to provide serialization between the server 32 * and the shm fence client 33 */ 34 35static DevPrivateKeyRec glamor_sync_fence_key; 36 37struct glamor_sync_fence { 38 SyncFenceSetTriggeredFunc set_triggered; 39}; 40 41static inline struct glamor_sync_fence * 42glamor_get_sync_fence(SyncFence *fence) 43{ 44 return (struct glamor_sync_fence *) dixLookupPrivate(&fence->devPrivates, &glamor_sync_fence_key); 45} 46 47static void 48glamor_sync_fence_set_triggered (SyncFence *fence) 49{ 50 ScreenPtr screen = fence->pScreen; 51 glamor_screen_private *glamor = glamor_get_screen_private(screen); 52 struct glamor_sync_fence *glamor_fence = glamor_get_sync_fence(fence); 53 54 /* Flush pending rendering operations */ 55 glamor_make_current(glamor); 56 glFlush(); 57 58 fence->funcs.SetTriggered = glamor_fence->set_triggered; 59 fence->funcs.SetTriggered(fence); 60 glamor_fence->set_triggered = fence->funcs.SetTriggered; 61 fence->funcs.SetTriggered = glamor_sync_fence_set_triggered; 62} 63 64static void 65glamor_sync_create_fence(ScreenPtr screen, 66 SyncFence *fence, 67 Bool initially_triggered) 68{ 69 glamor_screen_private *glamor = glamor_get_screen_private(screen); 70 SyncScreenFuncsPtr screen_funcs = miSyncGetScreenFuncs(screen); 71 struct glamor_sync_fence *glamor_fence = glamor_get_sync_fence(fence); 72 73 screen_funcs->CreateFence = glamor->saved_procs.sync_screen_funcs.CreateFence; 74 screen_funcs->CreateFence(screen, fence, initially_triggered); 75 glamor->saved_procs.sync_screen_funcs.CreateFence = screen_funcs->CreateFence; 76 screen_funcs->CreateFence = glamor_sync_create_fence; 77 78 glamor_fence->set_triggered = fence->funcs.SetTriggered; 79 fence->funcs.SetTriggered = glamor_sync_fence_set_triggered; 80} 81#endif 82 83Bool 84glamor_sync_init(ScreenPtr screen) 85{ 86#if XSYNC 87 glamor_screen_private *glamor = glamor_get_screen_private(screen); 88 SyncScreenFuncsPtr screen_funcs; 89 90 if (!dixPrivateKeyRegistered(&glamor_sync_fence_key)) { 91 if (!dixRegisterPrivateKey(&glamor_sync_fence_key, 92 PRIVATE_SYNC_FENCE, 93 sizeof (struct glamor_sync_fence))) 94 return FALSE; 95 } 96 97#ifdef HAVE_XSHMFENCE 98 if (!miSyncShmScreenInit(screen)) 99 return FALSE; 100#else 101 if (!miSyncSetup(screen)) 102 return FALSE; 103#endif 104 105 screen_funcs = miSyncGetScreenFuncs(screen); 106 glamor->saved_procs.sync_screen_funcs.CreateFence = screen_funcs->CreateFence; 107 screen_funcs->CreateFence = glamor_sync_create_fence; 108#endif 109 return TRUE; 110} 111 112void 113glamor_sync_close(ScreenPtr screen) 114{ 115#if XSYNC 116 glamor_screen_private *glamor = glamor_get_screen_private(screen); 117 SyncScreenFuncsPtr screen_funcs = miSyncGetScreenFuncs(screen); 118 119 if (screen_funcs) 120 screen_funcs->CreateFence = glamor->saved_procs.sync_screen_funcs.CreateFence; 121#endif 122} 123