xref: /OK3568_Linux_fs/external/xserver/glamor/glamor_sync.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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