1/* 2 * Copyright © 2010 NVIDIA Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24#ifdef HAVE_DIX_CONFIG_H 25#include <dix-config.h> 26#endif 27 28#include "scrnintstr.h" 29#include "misync.h" 30#include "misyncstr.h" 31 32static DevPrivateKeyRec syncScreenPrivateKeyRec; 33static DevPrivateKey syncScreenPrivateKey = &syncScreenPrivateKeyRec; 34 35#define SYNC_SCREEN_PRIV(pScreen) \ 36 (SyncScreenPrivPtr) dixLookupPrivate(&pScreen->devPrivates, \ 37 syncScreenPrivateKey) 38 39typedef struct _syncScreenPriv { 40 /* Wrappable sync-specific screen functions */ 41 SyncScreenFuncsRec funcs; 42 43 /* Wrapped screen functions */ 44 CloseScreenProcPtr CloseScreen; 45} SyncScreenPrivRec, *SyncScreenPrivPtr; 46 47/* Default implementations of the sync screen functions */ 48void 49miSyncScreenCreateFence(ScreenPtr pScreen, SyncFence* pFence, 50 Bool initially_triggered) 51{ 52 (void)pScreen; 53 54 pFence->triggered = initially_triggered; 55} 56 57void miSyncScreenDestroyFence(ScreenPtr pScreen, SyncFence* pFence) 58{ 59 (void)pScreen; 60 (void)pFence; 61} 62 63/* Default implementations of the per-object functions */ 64static void 65miSyncFenceSetTriggered(SyncFence* pFence) 66{ 67 pFence->triggered = TRUE; 68} 69 70static void 71miSyncFenceReset(SyncFence* pFence) 72{ 73 pFence->triggered = FALSE; 74} 75 76static Bool 77miSyncFenceCheckTriggered(SyncFence* pFence) 78{ 79 return pFence->triggered; 80} 81 82static void 83miSyncFenceAddTrigger(SyncTrigger* pTrigger) 84{ 85 (void)pTrigger; 86 87 return; 88} 89 90static void 91miSyncFenceDeleteTrigger(SyncTrigger* pTrigger) 92{ 93 (void)pTrigger; 94 95 return; 96} 97 98/* Machine independent portion of the fence sync object implementation */ 99void 100miSyncInitFence(ScreenPtr pScreen, SyncFence* pFence, Bool initially_triggered) 101{ 102 SyncScreenPrivPtr pScreenPriv = SYNC_SCREEN_PRIV(pScreen); 103 static const SyncFenceFuncsRec miSyncFenceFuncs = { 104 &miSyncFenceSetTriggered, 105 &miSyncFenceReset, 106 &miSyncFenceCheckTriggered, 107 &miSyncFenceAddTrigger, 108 &miSyncFenceDeleteTrigger 109 }; 110 111 pFence->pScreen = pScreen; 112 pFence->funcs = miSyncFenceFuncs; 113 114 pScreenPriv->funcs.CreateFence(pScreen, pFence, initially_triggered); 115} 116 117void 118miSyncDestroyFence(SyncFence* pFence) 119{ 120 ScreenPtr pScreen = pFence->pScreen; 121 SyncScreenPrivPtr pScreenPriv = SYNC_SCREEN_PRIV(pScreen); 122 SyncTriggerList *ptl, *pNext; 123 124 pFence->sync.beingDestroyed = TRUE; 125 /* tell all the fence's triggers that the counter has been destroyed */ 126 for (ptl = pFence->sync.pTriglist; ptl; ptl = pNext) 127 { 128 (*ptl->pTrigger->CounterDestroyed)(ptl->pTrigger); 129 pNext = ptl->next; 130 free(ptl); /* destroy the trigger list as we go */ 131 } 132 133 pScreenPriv->funcs.DestroyFence(pScreen, pFence); 134 135 dixFreeObjectWithPrivates(pFence, PRIVATE_SYNC_FENCE); 136} 137 138void 139miSyncTriggerFence(SyncFence* pFence) 140{ 141 SyncTriggerList *ptl, *pNext; 142 CARD64 unused; 143 144 pFence->funcs.SetTriggered(pFence); 145 146 XSyncIntToValue(&unused, 0L); 147 148 /* run through triggers to see if any fired */ 149 for (ptl = pFence->sync.pTriglist; ptl; ptl = pNext) 150 { 151 pNext = ptl->next; 152 if ((*ptl->pTrigger->CheckTrigger)(ptl->pTrigger, unused)) 153 (*ptl->pTrigger->TriggerFired)(ptl->pTrigger); 154 } 155} 156 157SyncScreenFuncsPtr miSyncGetScreenFuncs(ScreenPtr pScreen) 158{ 159 SyncScreenPrivPtr pScreenPriv = SYNC_SCREEN_PRIV(pScreen); 160 161 return &pScreenPriv->funcs; 162} 163 164static Bool 165SyncCloseScreen (int i, ScreenPtr pScreen) 166{ 167 SyncScreenPrivPtr pScreenPriv = SYNC_SCREEN_PRIV(pScreen); 168 169 pScreen->CloseScreen = pScreenPriv->CloseScreen; 170 171 return (*pScreen->CloseScreen) (i, pScreen); 172} 173 174Bool 175miSyncSetup(ScreenPtr pScreen) 176{ 177 SyncScreenPrivPtr pScreenPriv; 178 179 static const SyncScreenFuncsRec miSyncScreenFuncs = { 180 &miSyncScreenCreateFence, 181 &miSyncScreenDestroyFence 182 }; 183 184 if (dixPrivateKeyRegistered(syncScreenPrivateKey)) 185 return TRUE; 186 187 if (!dixRegisterPrivateKey(syncScreenPrivateKey, PRIVATE_SCREEN, 188 sizeof(SyncScreenPrivRec))) 189 return FALSE; 190 191 pScreenPriv = SYNC_SCREEN_PRIV(pScreen); 192 193 pScreenPriv->funcs = miSyncScreenFuncs; 194 195 /* Wrap CloseScreen to clean up */ 196 pScreenPriv->CloseScreen = pScreen->CloseScreen; 197 pScreen->CloseScreen = SyncCloseScreen; 198 199 return TRUE; 200} 201