VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.cpp@ 80064

最後變更 在這個檔案從80064是 78375,由 vboxsync 提交於 6 年 前

Additions/common/crOpengl,GuestHost/OpenGL,HostServices/SharedOpenGL: Eliminate all global variables from the state tracker library (state_tracker) in preparation of the SPU DLL merging, bugref:9435

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id Revision
檔案大小: 13.3 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_string.h"
11
12#include "render/renderspu.h"
13
14GLint SERVER_DISPATCH_APIENTRY
15crServerDispatchWindowCreate(const char *dpyName, GLint visBits)
16{
17 return crServerDispatchWindowCreateEx(dpyName, visBits, -1);
18}
19
20GLint crServerMuralInit(CRMuralInfo *mural, GLboolean fGuestWindow, GLint visBits, GLint preloadWinID)
21{
22 RT_NOREF(fGuestWindow);
23
24 CRMuralInfo *defaultMural;
25 GLint dims[2];
26 GLint windowID = -1;
27 GLint spuWindow = 0;
28 GLint realVisBits = visBits;
29 const char *dpyName = "";
30
31 crMemset(mural, 0, sizeof (*mural));
32
33 if (cr_server.fVisualBitsDefault)
34 realVisBits = cr_server.fVisualBitsDefault;
35
36#ifdef RT_OS_DARWIN
37 if (fGuestWindow)
38 {
39 CRMuralInfo *dummy = crServerGetDummyMural(realVisBits);
40 if (!dummy)
41 {
42 WARN(("crServerGetDummyMural failed"));
43 return -1;
44 }
45 spuWindow = dummy->spuWindow;
46 mural->fIsDummyRefference = GL_TRUE;
47
48 dims[0] = dummy->width;
49 dims[1] = dummy->height;
50 }
51 else
52#endif
53 {
54 /*
55 * Have first SPU make a new window.
56 */
57 spuWindow = cr_server.head_spu->dispatch_table.WindowCreate( dpyName, realVisBits );
58 if (spuWindow < 0) {
59 return spuWindow;
60 }
61 mural->fIsDummyRefference = GL_FALSE;
62
63 /* get initial window size */
64 cr_server.head_spu->dispatch_table.GetChromiumParametervCR(GL_WINDOW_SIZE_CR, spuWindow, GL_INT, 2, dims);
65 }
66
67 defaultMural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, 0);
68 CRASSERT(defaultMural);
69 mural->gX = 0;
70 mural->gY = 0;
71 mural->width = dims[0];
72 mural->height = dims[1];
73
74 mural->spuWindow = spuWindow;
75 mural->screenId = 0;
76 mural->fHasParentWindow = !!cr_server.screen[0].winID;
77 mural->bVisible = !cr_server.bWindowsInitiallyHidden;
78
79 mural->cVisibleRects = 0;
80 mural->pVisibleRects = NULL;
81 mural->bReceivedRects = GL_FALSE;
82
83 /* generate ID for this new window/mural. */
84 windowID = preloadWinID<0 ? (GLint)crHashtableAllocKeys( cr_server.muralTable, 1 ) : preloadWinID;
85
86 mural->CreateInfo.realVisualBits = realVisBits;
87 mural->CreateInfo.requestedVisualBits = visBits;
88 mural->CreateInfo.externalID = windowID;
89 mural->CreateInfo.pszDpyName = dpyName ? crStrdup(dpyName) : NULL;
90
91 CR_STATE_SHAREDOBJ_USAGE_INIT(mural);
92
93 return windowID;
94}
95
96GLint crServerDispatchWindowCreateEx(const char *dpyName, GLint visBits, GLint preloadWinID)
97{
98 CRMuralInfo *mural;
99 GLint windowID = -1;
100
101 NOREF(dpyName);
102
103 if (cr_server.sharedWindows) {
104 int pos, j;
105
106 /* find empty position in my (curclient) windowList */
107 for (pos = 0; pos < CR_MAX_WINDOWS; pos++) {
108 if (cr_server.curClient->windowList[pos] == 0) {
109 break;
110 }
111 }
112 if (pos == CR_MAX_WINDOWS) {
113 crWarning("Too many windows in crserver!");
114 return -1;
115 }
116
117 /* Look if any other client has a window for this slot */
118 for (j = 0; j < cr_server.numClients; j++) {
119 if (cr_server.clients[j]->windowList[pos] != 0) {
120 /* use that client's window */
121 windowID = cr_server.clients[j]->windowList[pos];
122 cr_server.curClient->windowList[pos] = windowID;
123 crServerReturnValue( &windowID, sizeof(windowID) ); /* real return value */
124 crDebug("CRServer: client %p sharing window %d",
125 cr_server.curClient, windowID);
126 return windowID;
127 }
128 }
129 }
130
131
132 /*
133 * Create a new mural for the new window.
134 */
135 mural = (CRMuralInfo *) crCalloc(sizeof(CRMuralInfo));
136 if (!mural)
137 {
138 crWarning("crCalloc failed!");
139 return -1;
140 }
141
142 windowID = crServerMuralInit(mural, GL_TRUE, visBits, preloadWinID);
143 if (windowID < 0)
144 {
145 crWarning("crServerMuralInit failed!");
146 crServerReturnValue( &windowID, sizeof(windowID) );
147 crFree(mural);
148 return windowID;
149 }
150
151 crHashtableAdd(cr_server.muralTable, windowID, mural);
152
153 crDebug("CRServer: client %p created new window %d (SPU window %d)",
154 cr_server.curClient, windowID, mural->spuWindow);
155
156 if (windowID != -1 && !cr_server.bIsInLoadingState) {
157 int pos;
158 for (pos = 0; pos < CR_MAX_WINDOWS; pos++) {
159 if (cr_server.curClient->windowList[pos] == 0) {
160 cr_server.curClient->windowList[pos] = windowID;
161 break;
162 }
163 }
164 }
165
166 /* ensure we have a dummy mural created right away to avoid potential deadlocks on VM shutdown */
167 crServerGetDummyMural(mural->CreateInfo.realVisualBits);
168
169 crServerReturnValue( &windowID, sizeof(windowID) );
170 return windowID;
171}
172
173static int crServerRemoveClientWindow(CRClient *pClient, GLint window)
174{
175 int pos;
176
177 for (pos = 0; pos < CR_MAX_WINDOWS; ++pos)
178 {
179 if (pClient->windowList[pos] == window)
180 {
181 pClient->windowList[pos] = 0;
182 return true;
183 }
184 }
185
186 return false;
187}
188
189void crServerMuralTerm(CRMuralInfo *mural)
190{
191 PCR_BLITTER pBlitter;
192 crServerRedirMuralFBO(mural, false);
193 crServerDeleteMuralFBO(mural);
194
195 if (cr_server.currentMural == mural)
196 {
197 CRMuralInfo *dummyMural = crServerGetDummyMural(cr_server.MainContextInfo.CreateInfo.realVisualBits);
198 /* reset the current context to some dummy values to ensure render spu does not switch to a default "0" context,
199 * which might lead to muralFBO (offscreen rendering) gl entities being created in a scope of that context */
200 cr_server.head_spu->dispatch_table.MakeCurrent(dummyMural->spuWindow, 0, cr_server.MainContextInfo.SpuContext);
201 cr_server.currentWindow = -1;
202 cr_server.currentMural = dummyMural;
203 }
204 else
205 {
206 CRASSERT(cr_server.currentMural != mural);
207 }
208
209 pBlitter = crServerVBoxBlitterGetInitialized();
210 if (pBlitter)
211 {
212 const CR_BLITTER_WINDOW * pWindow = CrBltMuralGetCurrentInfo(pBlitter);
213 if (pWindow && pWindow->Base.id == mural->spuWindow)
214 {
215 CRMuralInfo *dummy = crServerGetDummyMural(mural->CreateInfo.realVisualBits);
216 CR_BLITTER_WINDOW DummyInfo;
217 CRASSERT(dummy);
218 crServerVBoxBlitterWinInit(&DummyInfo, dummy);
219 CrBltMuralSetCurrentInfo(pBlitter, &DummyInfo);
220 }
221 }
222
223 if (!mural->fIsDummyRefference)
224 cr_server.head_spu->dispatch_table.WindowDestroy( mural->spuWindow );
225
226 mural->spuWindow = 0;
227
228 if (mural->pVisibleRects)
229 {
230 crFree(mural->pVisibleRects);
231 }
232
233 if (mural->CreateInfo.pszDpyName)
234 crFree(mural->CreateInfo.pszDpyName);
235
236 crServerRedirMuralFbClear(mural);
237}
238
239static void crServerCleanupCtxMuralRefsCB(unsigned long key, void *data1, void *data2)
240{
241 RT_NOREF(key);
242
243 CRContextInfo *ctxInfo = (CRContextInfo *) data1;
244 CRMuralInfo *mural = (CRMuralInfo *) data2;
245
246 if (ctxInfo->currentMural == mural)
247 ctxInfo->currentMural = NULL;
248}
249
250void SERVER_DISPATCH_APIENTRY
251crServerDispatchWindowDestroy( GLint window )
252{
253 CRMuralInfo *mural;
254 int32_t client;
255 CRClientNode *pNode;
256 int found=false;
257
258 if (!window)
259 {
260 crWarning("Unexpected attempt to delete default mural, ignored!");
261 return;
262 }
263
264 mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
265 if (!mural) {
266 crWarning("CRServer: invalid window %d passed to WindowDestroy()", window);
267 return;
268 }
269
270 crDebug("CRServer: Destroying window %d (spu window %d)", window, mural->spuWindow);
271
272 crHashtableWalk(cr_server.contextTable, crServerCleanupCtxMuralRefsCB, mural);
273
274 crServerMuralTerm(mural);
275
276 CRASSERT(cr_server.currentWindow != window);
277
278 if (cr_server.curClient)
279 {
280 if (cr_server.curClient->currentMural == mural)
281 {
282 cr_server.curClient->currentMural = NULL;
283 cr_server.curClient->currentWindow = -1;
284 }
285
286 found = crServerRemoveClientWindow(cr_server.curClient, window);
287
288 /*Same as with contexts, some apps destroy it not in a thread where it was created*/
289 if (!found)
290 {
291 for (client=0; client<cr_server.numClients; ++client)
292 {
293 if (cr_server.clients[client]==cr_server.curClient)
294 continue;
295
296 found = crServerRemoveClientWindow(cr_server.clients[client], window);
297
298 if (found) break;
299 }
300 }
301
302 if (!found)
303 {
304 pNode=cr_server.pCleanupClient;
305
306 while (pNode && !found)
307 {
308 found = crServerRemoveClientWindow(pNode->pClient, window);
309 pNode = pNode->next;
310 }
311 }
312
313 CRASSERT(found);
314 }
315
316 /*Make sure this window isn't active in other clients*/
317 for (client=0; client<cr_server.numClients; ++client)
318 {
319 if (cr_server.clients[client]->currentMural == mural)
320 {
321 cr_server.clients[client]->currentMural = NULL;
322 cr_server.clients[client]->currentWindow = -1;
323 }
324 }
325
326 pNode=cr_server.pCleanupClient;
327 while (pNode)
328 {
329 if (pNode->pClient->currentMural == mural)
330 {
331 pNode->pClient->currentMural = NULL;
332 pNode->pClient->currentWindow = -1;
333 }
334 pNode = pNode->next;
335 }
336
337 crHashtableDelete(cr_server.muralTable, window, crFree);
338
339 crServerCheckAllMuralGeometry(NULL);
340}
341
342GLboolean crServerMuralSize(CRMuralInfo *mural, GLuint width, GLuint height)
343{
344 if (mural->width == width && mural->height == height)
345 return GL_FALSE;
346
347 mural->width = width;
348 mural->height = height;
349
350 if (cr_server.curClient && cr_server.curClient->currentMural == mural
351 && !mural->fRedirected)
352 {
353 crStateGetCurrent(&cr_server.StateTracker)->buffer.width = mural->width;
354 crStateGetCurrent(&cr_server.StateTracker)->buffer.height = mural->height;
355 }
356
357 crServerCheckAllMuralGeometry(mural);
358
359 return GL_TRUE;
360}
361
362void SERVER_DISPATCH_APIENTRY
363crServerDispatchWindowSize( GLint window, GLint width, GLint height )
364{
365 CRMuralInfo *mural;
366
367 /* crDebug("CRServer: Window %d size %d x %d", window, width, height);*/
368 mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
369 if (!mural) {
370#ifdef EXTRA_WARN
371 crWarning("CRServer: invalid window %d passed to WindowSize()", window);
372#endif
373 return;
374 }
375
376 crServerMuralSize(mural, width, height);
377
378 if (cr_server.currentMural == mural)
379 {
380 crServerPerformMakeCurrent( mural, cr_server.currentCtxInfo );
381 }
382}
383
384void crServerMuralPosition(CRMuralInfo *mural, GLint x, GLint y)
385{
386 if (mural->gX == x && mural->gY == y)
387 return;
388
389 mural->gX = x;
390 mural->gY = y;
391
392 crServerCheckAllMuralGeometry(mural);
393}
394
395void SERVER_DISPATCH_APIENTRY
396crServerDispatchWindowPosition( GLint window, GLint x, GLint y )
397{
398 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
399 if (!mural) {
400#ifdef EXTRA_WARN
401 crWarning("CRServer: invalid window %d passed to WindowPosition()", window);
402#endif
403 return;
404 }
405 crServerMuralPosition(mural, x, y);
406}
407
408void crServerMuralVisibleRegion( CRMuralInfo *mural, GLint cRects, const GLint *pRects )
409{
410 if (mural->pVisibleRects)
411 {
412 crFree(mural->pVisibleRects);
413 mural->pVisibleRects = NULL;
414 }
415
416 mural->cVisibleRects = cRects;
417 mural->bReceivedRects = GL_TRUE;
418 if (cRects)
419 {
420 mural->pVisibleRects = (GLint*) crAlloc(4*sizeof(GLint)*cRects);
421 if (!mural->pVisibleRects)
422 {
423 crError("Out of memory in crServerDispatchWindowVisibleRegion");
424 }
425 crMemcpy(mural->pVisibleRects, pRects, 4*sizeof(GLint)*cRects);
426 }
427
428 crServerCheckAllMuralGeometry(mural);
429}
430
431void SERVER_DISPATCH_APIENTRY
432crServerDispatchWindowVisibleRegion( GLint window, GLint cRects, const GLint *pRects )
433{
434 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
435 if (!mural) {
436#ifdef EXTRA_WARN
437 crWarning("CRServer: invalid window %d passed to WindowVisibleRegion()", window);
438#endif
439 return;
440 }
441
442 crServerMuralVisibleRegion( mural, cRects, pRects );
443}
444
445void crServerMuralShow( CRMuralInfo *mural, GLint state )
446{
447 if (!mural->bVisible == !state)
448 return;
449
450 mural->bVisible = !!state;
451
452 if (mural->bVisible)
453 crServerCheckMuralGeometry(mural);
454 else
455 crServerCheckAllMuralGeometry(mural);
456}
457
458void SERVER_DISPATCH_APIENTRY
459crServerDispatchWindowShow( GLint window, GLint state )
460{
461 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
462 if (!mural) {
463#ifdef EXTRA_WARN
464 crWarning("CRServer: invalid window %d passed to WindowShow()", window);
465#endif
466 return;
467 }
468
469 crServerMuralShow( mural, state );
470}
471
472GLint
473crServerSPUWindowID(GLint serverWindow)
474{
475 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, serverWindow);
476 if (!mural) {
477#ifdef EXTRA_WARN
478 crWarning("CRServer: invalid window %d passed to crServerSPUWindowID()",
479 serverWindow);
480#endif
481 return -1;
482 }
483 return mural->spuWindow;
484}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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