present_fence.c (4201B)
1 /* 2 * Copyright © 2013 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 #include "present_priv.h" 24 #include <gcstruct.h> 25 #include <misync.h> 26 #include <misyncstr.h> 27 28 /* 29 * Wraps SyncFence objects so we can add a SyncTrigger to find out 30 * when the SyncFence gets destroyed and clean up appropriately 31 */ 32 33 struct present_fence { 34 SyncTrigger trigger; 35 SyncFence *fence; 36 void (*callback)(void *param); 37 void *param; 38 }; 39 40 /* 41 * SyncTrigger callbacks 42 */ 43 static Bool 44 present_fence_sync_check_trigger(SyncTrigger *trigger, int64_t oldval) 45 { 46 struct present_fence *present_fence = container_of(trigger, struct present_fence, trigger); 47 48 return present_fence->callback != NULL; 49 } 50 51 static void 52 present_fence_sync_trigger_fired(SyncTrigger *trigger) 53 { 54 struct present_fence *present_fence = container_of(trigger, struct present_fence, trigger); 55 56 if (present_fence->callback) 57 (*present_fence->callback)(present_fence->param); 58 } 59 60 static void 61 present_fence_sync_counter_destroyed(SyncTrigger *trigger) 62 { 63 struct present_fence *present_fence = container_of(trigger, struct present_fence, trigger); 64 65 present_fence->fence = NULL; 66 } 67 68 struct present_fence * 69 present_fence_create(SyncFence *fence) 70 { 71 struct present_fence *present_fence; 72 73 present_fence = calloc (1, sizeof (struct present_fence)); 74 if (!present_fence) 75 return NULL; 76 77 present_fence->fence = fence; 78 present_fence->trigger.pSync = (SyncObject *) fence; 79 present_fence->trigger.CheckTrigger = present_fence_sync_check_trigger; 80 present_fence->trigger.TriggerFired = present_fence_sync_trigger_fired; 81 present_fence->trigger.CounterDestroyed = present_fence_sync_counter_destroyed; 82 83 if (SyncAddTriggerToSyncObject(&present_fence->trigger) != Success) { 84 free (present_fence); 85 return NULL; 86 } 87 return present_fence; 88 } 89 90 void 91 present_fence_destroy(struct present_fence *present_fence) 92 { 93 if (present_fence) { 94 if (present_fence->fence) 95 SyncDeleteTriggerFromSyncObject(&present_fence->trigger); 96 free(present_fence); 97 } 98 } 99 100 void 101 present_fence_set_triggered(struct present_fence *present_fence) 102 { 103 if (present_fence) 104 if (present_fence->fence) 105 (*present_fence->fence->funcs.SetTriggered) (present_fence->fence); 106 } 107 108 Bool 109 present_fence_check_triggered(struct present_fence *present_fence) 110 { 111 if (!present_fence) 112 return TRUE; 113 if (!present_fence->fence) 114 return TRUE; 115 return (*present_fence->fence->funcs.CheckTriggered)(present_fence->fence); 116 } 117 118 void 119 present_fence_set_callback(struct present_fence *present_fence, 120 void (*callback) (void *param), 121 void *param) 122 { 123 present_fence->callback = callback; 124 present_fence->param = param; 125 } 126 127 XID 128 present_fence_id(struct present_fence *present_fence) 129 { 130 if (!present_fence) 131 return None; 132 if (!present_fence->fence) 133 return None; 134 return present_fence->fence->sync.id; 135 }