1 #include "ws_dri_fencemgr.h"
8 * Note: Locking order is
9 * _DriFenceObject::mutex
15 * Constant members. Need no mutex protection.
17 struct _DriFenceMgrCreateInfo info
;
21 * These members are protected by this->mutex
23 _glthread_Mutex mutex
;
29 struct _DriFenceObject
{
32 * These members are constant and need no mutex protection.
34 struct _DriFenceMgr
*mgr
;
39 * These members are protected by mgr->mutex.
45 * These members are protected by this->mutex.
47 _glthread_Mutex mutex
;
48 uint32_t signaled_type
;
53 driFenceType(struct _DriFenceObject
*fence
)
55 return fence
->fence_type
;
59 driFenceMgrCreate(const struct _DriFenceMgrCreateInfo
*info
)
61 struct _DriFenceMgr
*tmp
;
64 tmp
= calloc(1, sizeof(*tmp
));
68 _glthread_INIT_MUTEX(tmp
->mutex
);
69 _glthread_LOCK_MUTEX(tmp
->mutex
);
73 tmp
->heads
= calloc(tmp
->info
.num_classes
, sizeof(*tmp
->heads
));
77 for (i
=0; i
<tmp
->info
.num_classes
; ++i
) {
78 DRMINITLISTHEAD(&tmp
->heads
[i
]);
80 _glthread_UNLOCK_MUTEX(tmp
->mutex
);
90 driFenceMgrUnrefUnlock(struct _DriFenceMgr
**pMgr
)
92 struct _DriFenceMgr
*mgr
= *pMgr
;
95 if (--mgr
->refCount
== 0)
98 _glthread_UNLOCK_MUTEX(mgr
->mutex
);
102 driFenceMgrUnReference(struct _DriFenceMgr
**pMgr
)
104 _glthread_LOCK_MUTEX((*pMgr
)->mutex
);
105 driFenceMgrUnrefUnlock(pMgr
);
109 driFenceUnReferenceLocked(struct _DriFenceObject
**pFence
)
111 struct _DriFenceObject
*fence
= *pFence
;
112 struct _DriFenceMgr
*mgr
= fence
->mgr
;
115 if (--fence
->refCount
== 0) {
116 DRMLISTDELINIT(&fence
->head
);
118 mgr
->info
.unreference(mgr
, &fence
->private);
129 driSignalPreviousFencesLocked(struct _DriFenceMgr
*mgr
,
131 uint32_t fence_class
,
134 struct _DriFenceObject
*entry
;
137 while(list
!= &mgr
->heads
[fence_class
]) {
138 entry
= DRMLISTENTRY(struct _DriFenceObject
, list
, head
);
141 * Up refcount so that entry doesn't disappear from under us
142 * when we unlock-relock mgr to get the correct locking order.
146 _glthread_UNLOCK_MUTEX(mgr
->mutex
);
147 _glthread_LOCK_MUTEX(entry
->mutex
);
148 _glthread_LOCK_MUTEX(mgr
->mutex
);
154 if (list
->prev
== list
) {
157 * Somebody else removed the entry from the list.
160 _glthread_UNLOCK_MUTEX(entry
->mutex
);
161 driFenceUnReferenceLocked(&entry
);
165 entry
->signaled_type
|= (fence_type
& entry
->fence_type
);
166 if (entry
->signaled_type
== entry
->fence_type
) {
167 DRMLISTDELINIT(list
);
168 mgr
->info
.unreference(mgr
, &entry
->private);
170 _glthread_UNLOCK_MUTEX(entry
->mutex
);
171 driFenceUnReferenceLocked(&entry
);
178 driFenceFinish(struct _DriFenceObject
*fence
, uint32_t fence_type
,
181 struct _DriFenceMgr
*mgr
= fence
->mgr
;
184 _glthread_LOCK_MUTEX(fence
->mutex
);
186 if ((fence
->signaled_type
& fence_type
) == fence_type
)
189 ret
= mgr
->info
.finish(mgr
, fence
->private, fence_type
, lazy_hint
);
193 _glthread_LOCK_MUTEX(mgr
->mutex
);
194 _glthread_UNLOCK_MUTEX(fence
->mutex
);
196 driSignalPreviousFencesLocked(mgr
, &fence
->head
, fence
->fence_class
,
198 _glthread_UNLOCK_MUTEX(mgr
->mutex
);
202 _glthread_UNLOCK_MUTEX(fence
->mutex
);
206 uint32_t driFenceSignaledTypeCached(struct _DriFenceObject
*fence
)
210 _glthread_LOCK_MUTEX(fence
->mutex
);
211 ret
= fence
->signaled_type
;
212 _glthread_UNLOCK_MUTEX(fence
->mutex
);
218 driFenceSignaledType(struct _DriFenceObject
*fence
, uint32_t flush_type
,
222 struct _DriFenceMgr
*mgr
;
224 _glthread_LOCK_MUTEX(fence
->mutex
);
226 *signaled
= fence
->signaled_type
;
227 if ((fence
->signaled_type
& flush_type
) == flush_type
)
230 ret
= mgr
->info
.signaled(mgr
, fence
->private, flush_type
, signaled
);
232 *signaled
= fence
->signaled_type
;
236 if ((fence
->signaled_type
| *signaled
) == fence
->signaled_type
)
239 _glthread_LOCK_MUTEX(mgr
->mutex
);
240 _glthread_UNLOCK_MUTEX(fence
->mutex
);
242 driSignalPreviousFencesLocked(mgr
, &fence
->head
, fence
->fence_class
,
245 _glthread_UNLOCK_MUTEX(mgr
->mutex
);
248 _glthread_UNLOCK_MUTEX(fence
->mutex
);
252 struct _DriFenceObject
*
253 driFenceReference(struct _DriFenceObject
*fence
)
255 _glthread_LOCK_MUTEX(fence
->mgr
->mutex
);
257 _glthread_UNLOCK_MUTEX(fence
->mgr
->mutex
);
262 driFenceUnReference(struct _DriFenceObject
**pFence
)
264 struct _DriFenceMgr
*mgr
;
269 mgr
= (*pFence
)->mgr
;
270 _glthread_LOCK_MUTEX(mgr
->mutex
);
272 driFenceUnReferenceLocked(pFence
);
273 driFenceMgrUnrefUnlock(&mgr
);
276 struct _DriFenceObject
277 *driFenceCreate(struct _DriFenceMgr
*mgr
, uint32_t fence_class
,
278 uint32_t fence_type
, void *private, size_t private_size
)
280 struct _DriFenceObject
*fence
;
281 size_t fence_size
= sizeof(*fence
);
284 fence_size
= ((fence_size
+ 15) & ~15);
286 fence
= calloc(1, fence_size
+ private_size
);
289 int ret
= mgr
->info
.finish(mgr
, private, fence_type
, 0);
297 _glthread_INIT_MUTEX(fence
->mutex
);
298 _glthread_LOCK_MUTEX(fence
->mutex
);
299 _glthread_LOCK_MUTEX(mgr
->mutex
);
301 DRMLISTADDTAIL(&fence
->head
, &mgr
->heads
[fence_class
]);
305 _glthread_UNLOCK_MUTEX(mgr
->mutex
);
306 fence
->fence_class
= fence_class
;
307 fence
->fence_type
= fence_type
;
308 fence
->signaled_type
= 0;
309 fence
->private = private;
311 fence
->private = (void *)(((uint8_t *) fence
) + fence_size
);
312 memcpy(fence
->private, private, private_size
);
315 _glthread_UNLOCK_MUTEX(fence
->mutex
);
321 tSignaled(struct _DriFenceMgr
*mgr
, void *private, uint32_t flush_type
,
322 uint32_t *signaled_type
)
324 long fd
= (long) mgr
->private;
326 drmFence
*fence
= (drmFence
*) private;
330 ret
= drmFenceSignaled((int) fd
, fence
, flush_type
, &dummy
);
334 *signaled_type
= fence
->signaled
;
340 tFinish(struct _DriFenceMgr
*mgr
, void *private, uint32_t fence_type
,
343 long fd
= (long) mgr
->private;
344 unsigned flags
= lazy_hint
? DRM_FENCE_FLAG_WAIT_LAZY
: 0;
346 return drmFenceWait((int)fd
, flags
, (drmFence
*) private, fence_type
);
350 tUnref(struct _DriFenceMgr
*mgr
, void **private)
352 long fd
= (long) mgr
->private;
353 drmFence
*fence
= (drmFence
*) *private;
356 return drmFenceUnreference(fd
, fence
);
359 struct _DriFenceMgr
*driFenceMgrTTMInit(int fd
)
361 struct _DriFenceMgrCreateInfo info
;
362 struct _DriFenceMgr
*mgr
;
364 info
.flags
= DRI_FENCE_CLASS_ORDERED
;
365 info
.num_classes
= 4;
366 info
.signaled
= tSignaled
;
367 info
.finish
= tFinish
;
368 info
.unreference
= tUnref
;
370 mgr
= driFenceMgrCreate(&info
);
374 mgr
->private = (void *) (long) fd
;