135c4bbdfSmrg/* 235c4bbdfSmrg * Copyright © 2013 Keith Packard 335c4bbdfSmrg * 435c4bbdfSmrg * Permission to use, copy, modify, distribute, and sell this software and its 535c4bbdfSmrg * documentation for any purpose is hereby granted without fee, provided that 635c4bbdfSmrg * the above copyright notice appear in all copies and that both that copyright 735c4bbdfSmrg * notice and this permission notice appear in supporting documentation, and 835c4bbdfSmrg * that the name of the copyright holders not be used in advertising or 935c4bbdfSmrg * publicity pertaining to distribution of the software without specific, 1035c4bbdfSmrg * written prior permission. The copyright holders make no representations 1135c4bbdfSmrg * about the suitability of this software for any purpose. It is provided "as 1235c4bbdfSmrg * is" without express or implied warranty. 1335c4bbdfSmrg * 1435c4bbdfSmrg * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1535c4bbdfSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 1635c4bbdfSmrg * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1735c4bbdfSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 1835c4bbdfSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 1935c4bbdfSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 2035c4bbdfSmrg * OF THIS SOFTWARE. 2135c4bbdfSmrg */ 2235c4bbdfSmrg 2335c4bbdfSmrg#include "present_priv.h" 2435c4bbdfSmrg#include <gcstruct.h> 2535c4bbdfSmrg#include <misync.h> 2635c4bbdfSmrg#include <misyncstr.h> 2735c4bbdfSmrg 2835c4bbdfSmrg/* 2935c4bbdfSmrg * Wraps SyncFence objects so we can add a SyncTrigger to find out 3035c4bbdfSmrg * when the SyncFence gets destroyed and clean up appropriately 3135c4bbdfSmrg */ 3235c4bbdfSmrg 3335c4bbdfSmrgstruct present_fence { 3435c4bbdfSmrg SyncTrigger trigger; 3535c4bbdfSmrg SyncFence *fence; 3635c4bbdfSmrg void (*callback)(void *param); 3735c4bbdfSmrg void *param; 3835c4bbdfSmrg}; 3935c4bbdfSmrg 4035c4bbdfSmrg/* 4135c4bbdfSmrg * SyncTrigger callbacks 4235c4bbdfSmrg */ 4335c4bbdfSmrgstatic Bool 441b5d61b8Smrgpresent_fence_sync_check_trigger(SyncTrigger *trigger, int64_t oldval) 4535c4bbdfSmrg{ 4635c4bbdfSmrg struct present_fence *present_fence = container_of(trigger, struct present_fence, trigger); 4735c4bbdfSmrg 4835c4bbdfSmrg return present_fence->callback != NULL; 4935c4bbdfSmrg} 5035c4bbdfSmrg 5135c4bbdfSmrgstatic void 5235c4bbdfSmrgpresent_fence_sync_trigger_fired(SyncTrigger *trigger) 5335c4bbdfSmrg{ 5435c4bbdfSmrg struct present_fence *present_fence = container_of(trigger, struct present_fence, trigger); 5535c4bbdfSmrg 5635c4bbdfSmrg if (present_fence->callback) 5735c4bbdfSmrg (*present_fence->callback)(present_fence->param); 5835c4bbdfSmrg} 5935c4bbdfSmrg 6035c4bbdfSmrgstatic void 6135c4bbdfSmrgpresent_fence_sync_counter_destroyed(SyncTrigger *trigger) 6235c4bbdfSmrg{ 6335c4bbdfSmrg struct present_fence *present_fence = container_of(trigger, struct present_fence, trigger); 6435c4bbdfSmrg 6535c4bbdfSmrg present_fence->fence = NULL; 6635c4bbdfSmrg} 6735c4bbdfSmrg 6835c4bbdfSmrgstruct present_fence * 6935c4bbdfSmrgpresent_fence_create(SyncFence *fence) 7035c4bbdfSmrg{ 7135c4bbdfSmrg struct present_fence *present_fence; 7235c4bbdfSmrg 7335c4bbdfSmrg present_fence = calloc (1, sizeof (struct present_fence)); 7435c4bbdfSmrg if (!present_fence) 7535c4bbdfSmrg return NULL; 7635c4bbdfSmrg 7735c4bbdfSmrg present_fence->fence = fence; 7835c4bbdfSmrg present_fence->trigger.pSync = (SyncObject *) fence; 7935c4bbdfSmrg present_fence->trigger.CheckTrigger = present_fence_sync_check_trigger; 8035c4bbdfSmrg present_fence->trigger.TriggerFired = present_fence_sync_trigger_fired; 8135c4bbdfSmrg present_fence->trigger.CounterDestroyed = present_fence_sync_counter_destroyed; 8235c4bbdfSmrg 8335c4bbdfSmrg if (SyncAddTriggerToSyncObject(&present_fence->trigger) != Success) { 8435c4bbdfSmrg free (present_fence); 8535c4bbdfSmrg return NULL; 8635c4bbdfSmrg } 8735c4bbdfSmrg return present_fence; 8835c4bbdfSmrg} 8935c4bbdfSmrg 9035c4bbdfSmrgvoid 9135c4bbdfSmrgpresent_fence_destroy(struct present_fence *present_fence) 9235c4bbdfSmrg{ 9335c4bbdfSmrg if (present_fence) { 9435c4bbdfSmrg if (present_fence->fence) 9535c4bbdfSmrg SyncDeleteTriggerFromSyncObject(&present_fence->trigger); 9635c4bbdfSmrg free(present_fence); 9735c4bbdfSmrg } 9835c4bbdfSmrg} 9935c4bbdfSmrg 10035c4bbdfSmrgvoid 10135c4bbdfSmrgpresent_fence_set_triggered(struct present_fence *present_fence) 10235c4bbdfSmrg{ 10335c4bbdfSmrg if (present_fence) 10435c4bbdfSmrg if (present_fence->fence) 10535c4bbdfSmrg (*present_fence->fence->funcs.SetTriggered) (present_fence->fence); 10635c4bbdfSmrg} 10735c4bbdfSmrg 10835c4bbdfSmrgBool 10935c4bbdfSmrgpresent_fence_check_triggered(struct present_fence *present_fence) 11035c4bbdfSmrg{ 11135c4bbdfSmrg if (!present_fence) 11235c4bbdfSmrg return TRUE; 11335c4bbdfSmrg if (!present_fence->fence) 11435c4bbdfSmrg return TRUE; 11535c4bbdfSmrg return (*present_fence->fence->funcs.CheckTriggered)(present_fence->fence); 11635c4bbdfSmrg} 11735c4bbdfSmrg 11835c4bbdfSmrgvoid 11935c4bbdfSmrgpresent_fence_set_callback(struct present_fence *present_fence, 12035c4bbdfSmrg void (*callback) (void *param), 12135c4bbdfSmrg void *param) 12235c4bbdfSmrg{ 12335c4bbdfSmrg present_fence->callback = callback; 12435c4bbdfSmrg present_fence->param = param; 12535c4bbdfSmrg} 12635c4bbdfSmrg 12735c4bbdfSmrgXID 12835c4bbdfSmrgpresent_fence_id(struct present_fence *present_fence) 12935c4bbdfSmrg{ 13035c4bbdfSmrg if (!present_fence) 13135c4bbdfSmrg return None; 13235c4bbdfSmrg if (!present_fence->fence) 13335c4bbdfSmrg return None; 13435c4bbdfSmrg return present_fence->fence->sync.id; 13535c4bbdfSmrg} 136