135c4bbdfSmrg/*
235c4bbdfSmrg * Copyright © 2014 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
2435c4bbdfSmrg#include "glamor_priv.h"
2535c4bbdfSmrg#include "misyncshm.h"
2635c4bbdfSmrg#include "misyncstr.h"
2735c4bbdfSmrg
2835c4bbdfSmrg#if XSYNC
2935c4bbdfSmrg/*
3035c4bbdfSmrg * This whole file exists to wrap a sync fence trigger operation so
3135c4bbdfSmrg * that we can flush GL to provide serialization between the server
3235c4bbdfSmrg * and the shm fence client
3335c4bbdfSmrg */
3435c4bbdfSmrg
3535c4bbdfSmrgstatic DevPrivateKeyRec glamor_sync_fence_key;
3635c4bbdfSmrg
3735c4bbdfSmrgstruct glamor_sync_fence {
3835c4bbdfSmrg        SyncFenceSetTriggeredFunc set_triggered;
3935c4bbdfSmrg};
4035c4bbdfSmrg
4135c4bbdfSmrgstatic inline struct glamor_sync_fence *
4235c4bbdfSmrgglamor_get_sync_fence(SyncFence *fence)
4335c4bbdfSmrg{
4435c4bbdfSmrg    return (struct glamor_sync_fence *) dixLookupPrivate(&fence->devPrivates, &glamor_sync_fence_key);
4535c4bbdfSmrg}
4635c4bbdfSmrg
4735c4bbdfSmrgstatic void
4835c4bbdfSmrgglamor_sync_fence_set_triggered (SyncFence *fence)
4935c4bbdfSmrg{
5035c4bbdfSmrg	ScreenPtr screen = fence->pScreen;
5135c4bbdfSmrg	glamor_screen_private *glamor = glamor_get_screen_private(screen);
5235c4bbdfSmrg	struct glamor_sync_fence *glamor_fence = glamor_get_sync_fence(fence);
5335c4bbdfSmrg
5435c4bbdfSmrg	/* Flush pending rendering operations */
5535c4bbdfSmrg        glamor_make_current(glamor);
5635c4bbdfSmrg        glFlush();
5735c4bbdfSmrg
5835c4bbdfSmrg	fence->funcs.SetTriggered = glamor_fence->set_triggered;
5935c4bbdfSmrg	fence->funcs.SetTriggered(fence);
6035c4bbdfSmrg	glamor_fence->set_triggered = fence->funcs.SetTriggered;
6135c4bbdfSmrg	fence->funcs.SetTriggered = glamor_sync_fence_set_triggered;
6235c4bbdfSmrg}
6335c4bbdfSmrg
6435c4bbdfSmrgstatic void
6535c4bbdfSmrgglamor_sync_create_fence(ScreenPtr screen,
6635c4bbdfSmrg                        SyncFence *fence,
6735c4bbdfSmrg                        Bool initially_triggered)
6835c4bbdfSmrg{
6935c4bbdfSmrg	glamor_screen_private *glamor = glamor_get_screen_private(screen);
7035c4bbdfSmrg	SyncScreenFuncsPtr screen_funcs = miSyncGetScreenFuncs(screen);
7135c4bbdfSmrg	struct glamor_sync_fence *glamor_fence = glamor_get_sync_fence(fence);
7235c4bbdfSmrg
7335c4bbdfSmrg	screen_funcs->CreateFence = glamor->saved_procs.sync_screen_funcs.CreateFence;
7435c4bbdfSmrg	screen_funcs->CreateFence(screen, fence, initially_triggered);
7535c4bbdfSmrg	glamor->saved_procs.sync_screen_funcs.CreateFence = screen_funcs->CreateFence;
7635c4bbdfSmrg	screen_funcs->CreateFence = glamor_sync_create_fence;
7735c4bbdfSmrg
7835c4bbdfSmrg	glamor_fence->set_triggered = fence->funcs.SetTriggered;
7935c4bbdfSmrg	fence->funcs.SetTriggered = glamor_sync_fence_set_triggered;
8035c4bbdfSmrg}
8135c4bbdfSmrg#endif
8235c4bbdfSmrg
8335c4bbdfSmrgBool
8435c4bbdfSmrgglamor_sync_init(ScreenPtr screen)
8535c4bbdfSmrg{
8635c4bbdfSmrg#if XSYNC
8735c4bbdfSmrg	glamor_screen_private   *glamor = glamor_get_screen_private(screen);
8835c4bbdfSmrg	SyncScreenFuncsPtr      screen_funcs;
8935c4bbdfSmrg
9035c4bbdfSmrg	if (!dixPrivateKeyRegistered(&glamor_sync_fence_key)) {
9135c4bbdfSmrg		if (!dixRegisterPrivateKey(&glamor_sync_fence_key,
9235c4bbdfSmrg					   PRIVATE_SYNC_FENCE,
9335c4bbdfSmrg					   sizeof (struct glamor_sync_fence)))
9435c4bbdfSmrg			return FALSE;
9535c4bbdfSmrg	}
9635c4bbdfSmrg
9735c4bbdfSmrg#ifdef HAVE_XSHMFENCE
9835c4bbdfSmrg	if (!miSyncShmScreenInit(screen))
9935c4bbdfSmrg		return FALSE;
1001b5d61b8Smrg#else
1011b5d61b8Smrg	if (!miSyncSetup(screen))
1021b5d61b8Smrg		return FALSE;
10335c4bbdfSmrg#endif
10435c4bbdfSmrg
10535c4bbdfSmrg	screen_funcs = miSyncGetScreenFuncs(screen);
10635c4bbdfSmrg	glamor->saved_procs.sync_screen_funcs.CreateFence = screen_funcs->CreateFence;
10735c4bbdfSmrg	screen_funcs->CreateFence = glamor_sync_create_fence;
10835c4bbdfSmrg#endif
10935c4bbdfSmrg	return TRUE;
11035c4bbdfSmrg}
11135c4bbdfSmrg
11235c4bbdfSmrgvoid
11335c4bbdfSmrgglamor_sync_close(ScreenPtr screen)
11435c4bbdfSmrg{
11535c4bbdfSmrg#if XSYNC
11635c4bbdfSmrg        glamor_screen_private   *glamor = glamor_get_screen_private(screen);
11735c4bbdfSmrg        SyncScreenFuncsPtr      screen_funcs = miSyncGetScreenFuncs(screen);
11835c4bbdfSmrg
11935c4bbdfSmrg        if (screen_funcs)
12035c4bbdfSmrg                screen_funcs->CreateFence = glamor->saved_procs.sync_screen_funcs.CreateFence;
12135c4bbdfSmrg#endif
12235c4bbdfSmrg}
123