1 /*
2 * Copyright © 2014 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
24 #include "glamor_priv.h"
25 #include "misyncshm.h"
26 #include "misyncstr.h"
27
28 #if XSYNC
29 /*
30 * This whole file exists to wrap a sync fence trigger operation so
31 * that we can flush GL to provide serialization between the server
32 * and the shm fence client
33 */
34
35 static DevPrivateKeyRec glamor_sync_fence_key;
36
37 struct glamor_sync_fence {
38 SyncFenceSetTriggeredFunc set_triggered;
39 };
40
41 static inline struct glamor_sync_fence *
glamor_get_sync_fence(SyncFence * fence)42 glamor_get_sync_fence(SyncFence *fence)
43 {
44 return (struct glamor_sync_fence *) dixLookupPrivate(&fence->devPrivates, &glamor_sync_fence_key);
45 }
46
47 static void
glamor_sync_fence_set_triggered(SyncFence * fence)48 glamor_sync_fence_set_triggered (SyncFence *fence)
49 {
50 ScreenPtr screen = fence->pScreen;
51 struct glamor_sync_fence *glamor_fence = glamor_get_sync_fence(fence);
52
53 /* Flush pending rendering operations */
54 glamor_block_handler(screen);
55
56 fence->funcs.SetTriggered = glamor_fence->set_triggered;
57 fence->funcs.SetTriggered(fence);
58 glamor_fence->set_triggered = fence->funcs.SetTriggered;
59 fence->funcs.SetTriggered = glamor_sync_fence_set_triggered;
60 }
61
62 static void
glamor_sync_create_fence(ScreenPtr screen,SyncFence * fence,Bool initially_triggered)63 glamor_sync_create_fence(ScreenPtr screen,
64 SyncFence *fence,
65 Bool initially_triggered)
66 {
67 glamor_screen_private *glamor = glamor_get_screen_private(screen);
68 SyncScreenFuncsPtr screen_funcs = miSyncGetScreenFuncs(screen);
69 struct glamor_sync_fence *glamor_fence = glamor_get_sync_fence(fence);
70
71 screen_funcs->CreateFence = glamor->saved_procs.sync_screen_funcs.CreateFence;
72 screen_funcs->CreateFence(screen, fence, initially_triggered);
73 glamor->saved_procs.sync_screen_funcs.CreateFence = screen_funcs->CreateFence;
74 screen_funcs->CreateFence = glamor_sync_create_fence;
75
76 glamor_fence->set_triggered = fence->funcs.SetTriggered;
77 fence->funcs.SetTriggered = glamor_sync_fence_set_triggered;
78 }
79 #endif
80
81 Bool
glamor_sync_init(ScreenPtr screen)82 glamor_sync_init(ScreenPtr screen)
83 {
84 #if XSYNC
85 glamor_screen_private *glamor = glamor_get_screen_private(screen);
86 SyncScreenFuncsPtr screen_funcs;
87
88 if (!dixPrivateKeyRegistered(&glamor_sync_fence_key)) {
89 if (!dixRegisterPrivateKey(&glamor_sync_fence_key,
90 PRIVATE_SYNC_FENCE,
91 sizeof (struct glamor_sync_fence)))
92 return FALSE;
93 }
94
95 #ifdef HAVE_XSHMFENCE
96 if (!miSyncShmScreenInit(screen))
97 return FALSE;
98 #else
99 if (!miSyncSetup(screen))
100 return FALSE;
101 #endif
102
103 screen_funcs = miSyncGetScreenFuncs(screen);
104 glamor->saved_procs.sync_screen_funcs.CreateFence = screen_funcs->CreateFence;
105 screen_funcs->CreateFence = glamor_sync_create_fence;
106 #endif
107 return TRUE;
108 }
109
110 void
glamor_sync_close(ScreenPtr screen)111 glamor_sync_close(ScreenPtr screen)
112 {
113 #if XSYNC
114 glamor_screen_private *glamor = glamor_get_screen_private(screen);
115 SyncScreenFuncsPtr screen_funcs = miSyncGetScreenFuncs(screen);
116
117 if (screen_funcs)
118 screen_funcs->CreateFence = glamor->saved_procs.sync_screen_funcs.CreateFence;
119 #endif
120 }
121