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 33struct present_fence { 34 SyncTrigger trigger; 35 SyncFence *fence; 36 void (*callback)(void *param); 37 void *param; 38}; 39 40/* 41 * SyncTrigger callbacks 42 */ 43static Bool 44present_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 51static void 52present_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 60static void 61present_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 68struct present_fence * 69present_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 90void 91present_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 100void 101present_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 108Bool 109present_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 118void 119present_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 127XID 128present_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} 136