VirtualBox

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

最後變更 在這個檔案從52095是 51064,由 vboxsync 提交於 11 年 前

crOpenGL: fix to switch on/off new command submission

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

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