present_fence.c revision 35c4bbdf
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#ifdef HAVE_XORG_CONFIG_H
2435c4bbdfSmrg#include <xorg-config.h>
2535c4bbdfSmrg#endif
2635c4bbdfSmrg
2735c4bbdfSmrg#include "present_priv.h"
2835c4bbdfSmrg#include <gcstruct.h>
2935c4bbdfSmrg#include <misync.h>
3035c4bbdfSmrg#include <misyncstr.h>
3135c4bbdfSmrg
3235c4bbdfSmrg/*
3335c4bbdfSmrg * Wraps SyncFence objects so we can add a SyncTrigger to find out
3435c4bbdfSmrg * when the SyncFence gets destroyed and clean up appropriately
3535c4bbdfSmrg */
3635c4bbdfSmrg
3735c4bbdfSmrgstruct present_fence {
3835c4bbdfSmrg    SyncTrigger         trigger;
3935c4bbdfSmrg    SyncFence           *fence;
4035c4bbdfSmrg    void                (*callback)(void *param);
4135c4bbdfSmrg    void                *param;
4235c4bbdfSmrg};
4335c4bbdfSmrg
4435c4bbdfSmrg/*
4535c4bbdfSmrg * SyncTrigger callbacks
4635c4bbdfSmrg */
4735c4bbdfSmrgstatic Bool
4835c4bbdfSmrgpresent_fence_sync_check_trigger(SyncTrigger *trigger, XSyncValue oldval)
4935c4bbdfSmrg{
5035c4bbdfSmrg    struct present_fence        *present_fence = container_of(trigger, struct present_fence, trigger);
5135c4bbdfSmrg
5235c4bbdfSmrg    return present_fence->callback != NULL;
5335c4bbdfSmrg}
5435c4bbdfSmrg
5535c4bbdfSmrgstatic void
5635c4bbdfSmrgpresent_fence_sync_trigger_fired(SyncTrigger *trigger)
5735c4bbdfSmrg{
5835c4bbdfSmrg    struct present_fence        *present_fence = container_of(trigger, struct present_fence, trigger);
5935c4bbdfSmrg
6035c4bbdfSmrg    if (present_fence->callback)
6135c4bbdfSmrg        (*present_fence->callback)(present_fence->param);
6235c4bbdfSmrg}
6335c4bbdfSmrg
6435c4bbdfSmrgstatic void
6535c4bbdfSmrgpresent_fence_sync_counter_destroyed(SyncTrigger *trigger)
6635c4bbdfSmrg{
6735c4bbdfSmrg    struct present_fence        *present_fence = container_of(trigger, struct present_fence, trigger);
6835c4bbdfSmrg
6935c4bbdfSmrg    present_fence->fence = NULL;
7035c4bbdfSmrg}
7135c4bbdfSmrg
7235c4bbdfSmrgstruct present_fence *
7335c4bbdfSmrgpresent_fence_create(SyncFence *fence)
7435c4bbdfSmrg{
7535c4bbdfSmrg    struct present_fence        *present_fence;
7635c4bbdfSmrg
7735c4bbdfSmrg    present_fence = calloc (1, sizeof (struct present_fence));
7835c4bbdfSmrg    if (!present_fence)
7935c4bbdfSmrg        return NULL;
8035c4bbdfSmrg
8135c4bbdfSmrg    present_fence->fence = fence;
8235c4bbdfSmrg    present_fence->trigger.pSync = (SyncObject *) fence;
8335c4bbdfSmrg    present_fence->trigger.CheckTrigger = present_fence_sync_check_trigger;
8435c4bbdfSmrg    present_fence->trigger.TriggerFired = present_fence_sync_trigger_fired;
8535c4bbdfSmrg    present_fence->trigger.CounterDestroyed = present_fence_sync_counter_destroyed;
8635c4bbdfSmrg
8735c4bbdfSmrg    if (SyncAddTriggerToSyncObject(&present_fence->trigger) != Success) {
8835c4bbdfSmrg        free (present_fence);
8935c4bbdfSmrg        return NULL;
9035c4bbdfSmrg    }
9135c4bbdfSmrg    return present_fence;
9235c4bbdfSmrg}
9335c4bbdfSmrg
9435c4bbdfSmrgvoid
9535c4bbdfSmrgpresent_fence_destroy(struct present_fence *present_fence)
9635c4bbdfSmrg{
9735c4bbdfSmrg    if (present_fence) {
9835c4bbdfSmrg        if (present_fence->fence)
9935c4bbdfSmrg            SyncDeleteTriggerFromSyncObject(&present_fence->trigger);
10035c4bbdfSmrg        free(present_fence);
10135c4bbdfSmrg    }
10235c4bbdfSmrg}
10335c4bbdfSmrg
10435c4bbdfSmrgvoid
10535c4bbdfSmrgpresent_fence_set_triggered(struct present_fence *present_fence)
10635c4bbdfSmrg{
10735c4bbdfSmrg    if (present_fence)
10835c4bbdfSmrg        if (present_fence->fence)
10935c4bbdfSmrg            (*present_fence->fence->funcs.SetTriggered) (present_fence->fence);
11035c4bbdfSmrg}
11135c4bbdfSmrg
11235c4bbdfSmrgBool
11335c4bbdfSmrgpresent_fence_check_triggered(struct present_fence *present_fence)
11435c4bbdfSmrg{
11535c4bbdfSmrg    if (!present_fence)
11635c4bbdfSmrg        return TRUE;
11735c4bbdfSmrg    if (!present_fence->fence)
11835c4bbdfSmrg        return TRUE;
11935c4bbdfSmrg    return (*present_fence->fence->funcs.CheckTriggered)(present_fence->fence);
12035c4bbdfSmrg}
12135c4bbdfSmrg
12235c4bbdfSmrgvoid
12335c4bbdfSmrgpresent_fence_set_callback(struct present_fence *present_fence,
12435c4bbdfSmrg                           void (*callback) (void *param),
12535c4bbdfSmrg                           void *param)
12635c4bbdfSmrg{
12735c4bbdfSmrg    present_fence->callback = callback;
12835c4bbdfSmrg    present_fence->param = param;
12935c4bbdfSmrg}
13035c4bbdfSmrg
13135c4bbdfSmrgXID
13235c4bbdfSmrgpresent_fence_id(struct present_fence *present_fence)
13335c4bbdfSmrg{
13435c4bbdfSmrg    if (!present_fence)
13535c4bbdfSmrg        return None;
13635c4bbdfSmrg    if (!present_fence->fence)
13735c4bbdfSmrg        return None;
13835c4bbdfSmrg    return present_fence->fence->sync.id;
13935c4bbdfSmrg}
140