VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c@ 21576

最後變更 在這個檔案從21576是 21576,由 vboxsync 提交於 16 年 前

crOpenGL: fix deadlocks and context/window tracking for multithreaded apps(public #3922)

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id
檔案大小: 9.1 KB
 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#include "server.h"
8#include "server_dispatch.h"
9#include "cr_mem.h"
10#include "cr_rand.h"
11#include "cr_string.h"
12
13GLint SERVER_DISPATCH_APIENTRY
14crServerDispatchWindowCreate(const char *dpyName, GLint visBits)
15{
16 return crServerDispatchWindowCreateEx(dpyName, visBits, -1);
17}
18
19
20GLint
21crServerDispatchWindowCreateEx(const char *dpyName, GLint visBits, GLint preloadWinID)
22{
23 CRMuralInfo *mural;
24 GLint windowID = -1;
25 GLint spuWindow;
26 GLint dims[2];
27 CRCreateInfo_t *pCreateInfo;
28
29 if (cr_server.sharedWindows) {
30 int pos, j;
31
32 /* find empty position in my (curclient) windowList */
33 for (pos = 0; pos < CR_MAX_WINDOWS; pos++) {
34 if (cr_server.curClient->windowList[pos] == 0) {
35 break;
36 }
37 }
38 if (pos == CR_MAX_WINDOWS) {
39 crWarning("Too many windows in crserver!");
40 return -1;
41 }
42
43 /* Look if any other client has a window for this slot */
44 for (j = 0; j < cr_server.numClients; j++) {
45 if (cr_server.clients[j]->windowList[pos] != 0) {
46 /* use that client's window */
47 windowID = cr_server.clients[j]->windowList[pos];
48 cr_server.curClient->windowList[pos] = windowID;
49 crServerReturnValue( &windowID, sizeof(windowID) ); /* real return value */
50 crDebug("CRServer: client %p sharing window %d",
51 cr_server.curClient, windowID);
52 return windowID;
53 }
54 }
55 }
56
57 /*
58 * Have first SPU make a new window.
59 */
60 spuWindow = cr_server.head_spu->dispatch_table.WindowCreate( dpyName, visBits );
61 if (spuWindow < 0) {
62 crServerReturnValue( &spuWindow, sizeof(spuWindow) );
63 return spuWindow;
64 }
65
66 /* get initial window size */
67 cr_server.head_spu->dispatch_table.GetChromiumParametervCR(GL_WINDOW_SIZE_CR, spuWindow, GL_INT, 2, dims);
68
69 /*
70 * Create a new mural for the new window.
71 */
72 mural = (CRMuralInfo *) crCalloc(sizeof(CRMuralInfo));
73 if (mural) {
74 CRMuralInfo *defaultMural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, 0);
75 CRASSERT(defaultMural);
76 mural->width = defaultMural->width;
77 mural->height = defaultMural->height;
78 mural->optimizeBucket = 0; /* might get enabled later */
79 mural->numExtents = defaultMural->numExtents;
80 mural->curExtent = 0;
81 crMemcpy(mural->extents, defaultMural->extents,
82 defaultMural->numExtents * sizeof(CRExtent));
83 mural->underlyingDisplay[0] = 0;
84 mural->underlyingDisplay[1] = 0;
85 mural->underlyingDisplay[2] = dims[0];
86 mural->underlyingDisplay[3] = dims[1];
87
88 mural->spuWindow = spuWindow;
89 crServerInitializeTiling(mural);
90
91 /* generate ID for this new window/mural (special-case for file conns) */
92 if (cr_server.curClient && cr_server.curClient->conn->type == CR_FILE)
93 windowID = spuWindow;
94 else
95 windowID = preloadWinID<0 ? crServerGenerateID(&cr_server.idsPool.freeWindowID) : preloadWinID;
96 crHashtableAdd(cr_server.muralTable, windowID, mural);
97
98 pCreateInfo = (CRCreateInfo_t *) crAlloc(sizeof(CRCreateInfo_t));
99 pCreateInfo->pszDpyName = dpyName ? crStrdup(dpyName) : NULL;
100 pCreateInfo->visualBits = visBits;
101 crHashtableAdd(cr_server.pWindowCreateInfoTable, windowID, pCreateInfo);
102 }
103
104 crDebug("CRServer: client %p created new window %d (SPU window %d)",
105 cr_server.curClient, windowID, spuWindow);
106
107 if (windowID != -1 && !cr_server.bIsInLoadingState) {
108 int pos;
109 for (pos = 0; pos < CR_MAX_WINDOWS; pos++) {
110 if (cr_server.curClient->windowList[pos] == 0) {
111 cr_server.curClient->windowList[pos] = windowID;
112 break;
113 }
114 }
115 }
116
117 crServerReturnValue( &windowID, sizeof(windowID) );
118 return windowID;
119}
120
121void crServerCheckCurrentCtxWindowCB(unsigned long key, void *data1, void *data2)
122{
123 CRContext *crCtx = (CRContext *) data1;
124 GLint window = *(GLint*)data2;
125
126 (void) key;
127}
128
129void SERVER_DISPATCH_APIENTRY
130crServerDispatchWindowDestroy( GLint window )
131{
132 CRMuralInfo *mural;
133 int pos;
134
135 mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
136 if (!mural) {
137 crWarning("CRServer: invalid window %d passed to WindowDestroy()", window);
138 return;
139 }
140
141 crDebug("CRServer: Destroying window %d (spu window %d)", window, mural->spuWindow);
142 cr_server.head_spu->dispatch_table.WindowDestroy( mural->spuWindow );
143
144 if (cr_server.curClient)
145 {
146 if (cr_server.curClient->currentMural == mural)
147 {
148 cr_server.curClient->currentMural = NULL;
149 cr_server.curClient->currentWindow = -1;
150 }
151
152 for (pos = 0; pos < CR_MAX_WINDOWS; ++pos)
153 if (cr_server.curClient->windowList[pos] == window)
154 {
155 cr_server.curClient->windowList[pos] = 0;
156 break;
157 }
158
159 /*Same as with contexts, some apps destroy it not in a thread where it was created*/
160 if (CR_MAX_WINDOWS==pos)
161 {
162 int32_t client;
163
164 for (client=0; client<cr_server.numClients; ++client)
165 {
166 if (cr_server.clients[client]==cr_server.curClient)
167 continue;
168
169 for (pos = 0; pos < CR_MAX_WINDOWS; ++pos)
170 if (cr_server.clients[client]->windowList[pos] == window)
171 {
172 cr_server.clients[client]->windowList[pos] = 0;
173 break;
174 }
175
176 if (pos<CR_MAX_WINDOWS)
177 {
178 if (cr_server.clients[client]->currentMural == mural)
179 {
180 cr_server.clients[client]->currentMural = NULL;
181 cr_server.clients[client]->currentWindow = -1;
182 }
183 break;
184 }
185 }
186 }
187
188 CRASSERT(pos<CR_MAX_WINDOWS);
189 }
190
191 if (cr_server.currentWindow == window)
192 {
193 cr_server.currentWindow = -1;
194 }
195
196 crHashtableWalk(cr_server.contextTable, crServerCheckCurrentCtxWindowCB, &window);
197 crHashtableDelete(cr_server.pWindowCreateInfoTable, window, crServerCreateInfoDeleteCB);
198 crHashtableDelete(cr_server.muralTable, window, crFree);
199}
200
201
202void SERVER_DISPATCH_APIENTRY
203crServerDispatchWindowSize( GLint window, GLint width, GLint height )
204{
205 CRMuralInfo *mural;
206
207 /* crDebug("CRServer: Window %d size %d x %d", window, width, height);*/
208 mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
209 if (!mural) {
210#if EXTRA_WARN
211 crWarning("CRServer: invalid window %d passed to WindowSize()", window);
212#endif
213 return;
214 }
215 mural->underlyingDisplay[2] = width;
216 mural->underlyingDisplay[3] = height;
217 crServerInitializeTiling(mural);
218
219 cr_server.head_spu->dispatch_table.WindowSize(mural->spuWindow, width, height);
220}
221
222
223void SERVER_DISPATCH_APIENTRY
224crServerDispatchWindowPosition( GLint window, GLint x, GLint y )
225{
226 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
227 /* crDebug("CRServer: Window %d pos %d, %d", window, x, y);*/
228 if (!mural) {
229#if EXTRA_WARN
230 crWarning("CRServer: invalid window %d passed to WindowPosition()", window);
231#endif
232 return;
233 }
234 mural->underlyingDisplay[0] = x;
235 mural->underlyingDisplay[1] = y;
236
237#if EXTRA_WARN /* don't believe this is needed */
238 crServerInitializeTiling(mural);
239#endif
240 cr_server.head_spu->dispatch_table.WindowPosition(mural->spuWindow, x, y);
241}
242
243void SERVER_DISPATCH_APIENTRY
244crServerDispatchWindowVisibleRegion( GLint window, GLint cRects, GLint *pRects )
245{
246 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
247 if (!mural) {
248#if EXTRA_WARN
249 crWarning("CRServer: invalid window %d passed to WindowVisibleRegion()", window);
250#endif
251 return;
252 }
253#if EXTRA_WARN /* don't believe this is needed */
254 crServerInitializeTiling(mural);
255#endif
256 cr_server.head_spu->dispatch_table.WindowVisibleRegion(mural->spuWindow, cRects, pRects);
257}
258
259
260
261void SERVER_DISPATCH_APIENTRY
262crServerDispatchWindowShow( GLint window, GLint state )
263{
264 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
265 if (!mural) {
266#if EXTRA_WARN
267 crWarning("CRServer: invalid window %d passed to WindowShow()", window);
268#endif
269 return;
270 }
271 cr_server.head_spu->dispatch_table.WindowShow(mural->spuWindow, state);
272}
273
274
275GLint
276crServerSPUWindowID(GLint serverWindow)
277{
278 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, serverWindow);
279 if (!mural) {
280#if EXTRA_WARN
281 crWarning("CRServer: invalid window %d passed to crServerSPUWindowID()",
282 serverWindow);
283#endif
284 return -1;
285 }
286 return mural->spuWindow;
287}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette