VirtualBox

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

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

crOpenGL: some host bits for buffer-based command submission

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id
檔案大小: 25.8 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
15static GLboolean crServerWindowCalcIsVisible(CRMuralInfo *pMural)
16{
17 uint32_t cRegions;
18 int rc;
19 if (!pMural->width || !pMural->height)
20 return GL_FALSE;
21
22 if (!pMural->bVisible || !(pMural->fPresentMode & CR_SERVER_REDIR_F_DISPLAY))
23 return GL_FALSE;
24
25 rc = CrVrScrCompositorRegionsGet(pMural->fRootVrOn ? &pMural->RootVrCompositor : &pMural->Compositor, &cRegions, NULL, NULL, NULL);
26 if (RT_FAILURE(rc))
27 {
28 crWarning("CrVrScrCompositorRegionsGet failed, rc %d", rc);
29 return GL_FALSE;
30 }
31
32 if (!cRegions)
33 return GL_FALSE;
34
35 return GL_TRUE;
36}
37
38void crServerWindowSetIsVisible(CRMuralInfo *pMural, GLboolean fIsVisible)
39{
40 if (!fIsVisible == !pMural->fIsVisible)
41 return;
42
43 pMural->fIsVisible = fIsVisible;
44
45 CRASSERT(pMural->screenId < cr_server.screenCount);
46
47 if (fIsVisible)
48 {
49 ++cr_server.aWinVisibilityInfos[pMural->screenId].cVisibleWindows;
50 cr_server.aWinVisibilityInfos[pMural->screenId].fVisibleChanged = 1;
51 }
52 else
53 {
54 --cr_server.aWinVisibilityInfos[pMural->screenId].cVisibleWindows;
55 CRASSERT(cr_server.aWinVisibilityInfos[pMural->screenId].cVisibleWindows < UINT32_MAX/2);
56 if (!cr_server.aWinVisibilityInfos[pMural->screenId].cVisibleWindows)
57 cr_server.aWinVisibilityInfos[pMural->screenId].fVisibleChanged = 0;
58 }
59
60 crVBoxServerCheckVisibilityEvent(pMural->screenId);
61}
62
63void crServerWindowCheckIsVisible(CRMuralInfo *pMural)
64{
65 GLboolean fIsVisible = crServerWindowCalcIsVisible(pMural);
66
67 crServerWindowSetIsVisible(pMural, fIsVisible);
68}
69
70void crServerWindowSize(CRMuralInfo *pMural)
71{
72 cr_server.head_spu->dispatch_table.WindowSize(pMural->spuWindow, pMural->width, pMural->height);
73
74 crServerWindowCheckIsVisible(pMural);
75}
76
77void crServerWindowShow(CRMuralInfo *pMural)
78{
79 cr_server.head_spu->dispatch_table.WindowShow(pMural->spuWindow,
80 !!(pMural->fPresentMode & CR_SERVER_REDIR_F_DISPLAY) && pMural->bVisible);
81
82 crServerWindowCheckIsVisible(pMural);
83}
84
85void crServerWindowVisibleRegion(CRMuralInfo *pMural)
86{
87 uint32_t cRects;
88 const RTRECT *pRects;
89 int rc = CrVrScrCompositorRegionsGet(pMural->fRootVrOn ? &pMural->RootVrCompositor : &pMural->Compositor, &cRects, NULL, &pRects, NULL);
90 if (RT_SUCCESS(rc))
91 {
92 cr_server.head_spu->dispatch_table.WindowVisibleRegion(pMural->spuWindow, cRects, (const GLint*)pRects);
93
94 crServerWindowCheckIsVisible(pMural);
95 }
96 else
97 crWarning("CrVrScrCompositorRegionsGet failed rc %d", rc);
98
99}
100
101void crServerWindowReparent(CRMuralInfo *pMural)
102{
103 crServerVBoxCompositionDisableEnter(pMural);
104
105 pMural->fHasParentWindow = !!cr_server.screen[pMural->screenId].winID;
106
107 renderspuReparentWindow(pMural->spuWindow);
108
109 crServerVBoxCompositionDisableLeave(pMural, GL_FALSE);
110}
111
112GLint SERVER_DISPATCH_APIENTRY
113crServerDispatchWindowCreate(const char *dpyName, GLint visBits)
114{
115 return crServerDispatchWindowCreateEx(dpyName, visBits, -1);
116}
117
118static DECLCALLBACK(void) crServerMuralDefaultEntryReleasedCB(const struct VBOXVR_SCR_COMPOSITOR *pCompositor, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pReplacingEntry)
119{
120 CR_DISPLAY_ENTRY *pDEntry = CR_DENTRY_FROM_CENTRY(pEntry);
121 CrDpEntryCleanup(pDEntry);
122}
123
124GLint crServerMuralInit(CRMuralInfo *mural, const char *dpyName, GLint visBits, GLint preloadWinID, GLboolean fUseDefaultDEntry)
125{
126 CRMuralInfo *defaultMural;
127 GLint dims[2];
128 GLint windowID = -1;
129 GLint spuWindow;
130 int rc;
131
132 crMemset(mural, 0, sizeof (*mural));
133
134 CrVrScrCompositorInit(&mural->Compositor);
135
136 if (cr_server.fRootVrOn)
137 {
138 CrVrScrCompositorInit(&mural->RootVrCompositor);
139 }
140
141 /*
142 * Have first SPU make a new window.
143 */
144 spuWindow = cr_server.head_spu->dispatch_table.WindowCreate( dpyName, visBits );
145 if (spuWindow < 0) {
146 CrVrScrCompositorClear(&mural->Compositor);
147 if (cr_server.fRootVrOn)
148 CrVrScrCompositorClear(&mural->RootVrCompositor);
149 return spuWindow;
150 }
151
152 /* get initial window size */
153 cr_server.head_spu->dispatch_table.GetChromiumParametervCR(GL_WINDOW_SIZE_CR, spuWindow, GL_INT, 2, dims);
154
155 mural->fUseDefaultDEntry = fUseDefaultDEntry;
156
157 if (fUseDefaultDEntry)
158 {
159 VBOXVR_TEXTURE Tex = {0};
160 Tex.width = dims[0];
161 Tex.height = dims[1];
162 Tex.target = GL_TEXTURE_2D;
163 Tex.hwid = 0;
164
165 CrDpEntryInit(&mural->DefaultDEntry, &Tex, 0, crServerMuralDefaultEntryReleasedCB);
166
167 mural->fRootVrOn = cr_server.fRootVrOn;
168 }
169
170 defaultMural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, 0);
171 CRASSERT(defaultMural);
172 mural->gX = 0;
173 mural->gY = 0;
174 mural->width = dims[0];
175 mural->height = dims[1];
176
177 mural->spuWindow = spuWindow;
178 mural->screenId = 0;
179 mural->fHasParentWindow = !!cr_server.screen[0].winID;
180 mural->bVisible = !cr_server.bWindowsInitiallyHidden;
181 mural->fPresentMode = CR_SERVER_REDIR_F_NONE;
182
183 mural->cVisibleRects = 0;
184 mural->pVisibleRects = NULL;
185 mural->bReceivedRects = GL_FALSE;
186
187 /* generate ID for this new window/mural (special-case for file conns) */
188 if (cr_server.curClient && cr_server.curClient->conn->type == CR_FILE)
189 windowID = spuWindow;
190 else
191 windowID = preloadWinID<0 ? (GLint)crHashtableAllocKeys( cr_server.muralTable, 1 ) : preloadWinID;
192
193 mural->CreateInfo.visualBits = visBits;
194 mural->CreateInfo.externalID = windowID;
195 mural->CreateInfo.pszDpyName = dpyName ? crStrdup(dpyName) : NULL;
196
197 CR_STATE_SHAREDOBJ_USAGE_INIT(mural);
198
199 if (fUseDefaultDEntry)
200 {
201 RTRECT Rect;
202 Rect.xLeft = 0;
203 Rect.xRight = mural->width;
204 Rect.yTop = 0;
205 Rect.yBottom = mural->height;
206 rc = CrVrScrCompositorEntryRegionsSet(&mural->Compositor, &mural->DefaultDEntry.CEntry, NULL, 1, &Rect, false, NULL);
207 if (!RT_SUCCESS(rc))
208 {
209 crWarning("CrVrScrCompositorEntryRegionsSet failed, rc %d", rc);
210 return -1;
211 }
212 }
213
214 if (mural->fRootVrOn)
215 {
216 uint32_t cRects;
217 const RTRECT *pRects;
218 int rc = crServerMuralSynchRootVr(mural, NULL);
219 if (RT_SUCCESS(rc))
220 {
221 rc = CrVrScrCompositorRegionsGet(&mural->RootVrCompositor, &cRects, NULL, &pRects, NULL);
222 if (RT_SUCCESS(rc))
223 {
224 if (cRects != 1
225 || pRects[0].xLeft != 0 || pRects[0].yTop != 0
226 || pRects[0].xRight != mural->width || pRects[0].yBottom != mural->height)
227 {
228 /* do visible rects only if they differ from the default */
229 crServerWindowVisibleRegion(mural);
230 }
231 }
232 else
233 {
234 crWarning("CrVrScrCompositorRegionsGet failed, rc %d", rc);
235 }
236 }
237 }
238
239 return windowID;
240}
241
242GLint
243crServerDispatchWindowCreateEx(const char *dpyName, GLint visBits, GLint preloadWinID)
244{
245 CRMuralInfo *mural;
246 GLint windowID = -1;
247
248 dpyName = "";
249
250 if (cr_server.sharedWindows) {
251 int pos, j;
252
253 /* find empty position in my (curclient) windowList */
254 for (pos = 0; pos < CR_MAX_WINDOWS; pos++) {
255 if (cr_server.curClient->windowList[pos] == 0) {
256 break;
257 }
258 }
259 if (pos == CR_MAX_WINDOWS) {
260 crWarning("Too many windows in crserver!");
261 return -1;
262 }
263
264 /* Look if any other client has a window for this slot */
265 for (j = 0; j < cr_server.numClients; j++) {
266 if (cr_server.clients[j]->windowList[pos] != 0) {
267 /* use that client's window */
268 windowID = cr_server.clients[j]->windowList[pos];
269 cr_server.curClient->windowList[pos] = windowID;
270 crServerReturnValue( &windowID, sizeof(windowID) ); /* real return value */
271 crDebug("CRServer: client %p sharing window %d",
272 cr_server.curClient, windowID);
273 return windowID;
274 }
275 }
276 }
277
278
279 /*
280 * Create a new mural for the new window.
281 */
282 mural = (CRMuralInfo *) crCalloc(sizeof(CRMuralInfo));
283 if (!mural)
284 {
285 crWarning("crCalloc failed!");
286 return -1;
287 }
288
289 windowID = crServerMuralInit(mural, dpyName, visBits, preloadWinID, GL_TRUE);
290 if (windowID < 0)
291 {
292 crWarning("crServerMuralInit failed!");
293 crServerReturnValue( &windowID, sizeof(windowID) );
294 crFree(mural);
295 return windowID;
296 }
297
298 crHashtableAdd(cr_server.muralTable, windowID, mural);
299
300 crDebug("CRServer: client %p created new window %d (SPU window %d)",
301 cr_server.curClient, windowID, mural->spuWindow);
302
303 if (windowID != -1 && !cr_server.bIsInLoadingState) {
304 int pos;
305 for (pos = 0; pos < CR_MAX_WINDOWS; pos++) {
306 if (cr_server.curClient->windowList[pos] == 0) {
307 cr_server.curClient->windowList[pos] = windowID;
308 break;
309 }
310 }
311 }
312
313 /* ensure we have a dummy mural created right away to avoid potential deadlocks on VM shutdown */
314 crServerGetDummyMural(mural->CreateInfo.visualBits);
315
316 crServerReturnValue( &windowID, sizeof(windowID) );
317 return windowID;
318}
319
320static void crServerVBoxRootVrTranslateForMural(CRMuralInfo *mural)
321{
322 int32_t dx = cr_server.RootVrCurPoint.x - mural->gX;
323 int32_t dy = cr_server.RootVrCurPoint.y - mural->gY;
324
325 cr_server.RootVrCurPoint.x = mural->gX;
326 cr_server.RootVrCurPoint.y = mural->gY;
327
328 VBoxVrListTranslate(&cr_server.RootVr, dx, dy);
329}
330
331static int crServerRemoveClientWindow(CRClient *pClient, GLint window)
332{
333 int pos;
334
335 for (pos = 0; pos < CR_MAX_WINDOWS; ++pos)
336 {
337 if (pClient->windowList[pos] == window)
338 {
339 pClient->windowList[pos] = 0;
340 return true;
341 }
342 }
343
344 return false;
345}
346
347void crServerMuralTerm(CRMuralInfo *mural)
348{
349 crServerRedirMuralFBO(mural, CR_SERVER_REDIR_F_NONE);
350 crServerDeleteMuralFBO(mural);
351
352 if (cr_server.currentMural == mural)
353 {
354 CRMuralInfo *dummyMural = crServerGetDummyMural(cr_server.MainContextInfo.CreateInfo.visualBits);
355 /* reset the current context to some dummy values to ensure render spu does not switch to a default "0" context,
356 * which might lead to muralFBO (offscreen rendering) gl entities being created in a scope of that context */
357 cr_server.head_spu->dispatch_table.MakeCurrent(dummyMural->spuWindow, 0, cr_server.MainContextInfo.SpuContext);
358 cr_server.currentWindow = -1;
359 cr_server.currentMural = NULL;
360 }
361 else
362 {
363 CRASSERT(cr_server.currentWindow != mural->CreateInfo.externalID);
364 }
365
366
367 cr_server.head_spu->dispatch_table.WindowDestroy( mural->spuWindow );
368
369 if (mural->pVisibleRects)
370 {
371 crFree(mural->pVisibleRects);
372 }
373
374 if (mural->CreateInfo.pszDpyName)
375 crFree(mural->CreateInfo.pszDpyName);
376
377 CrVrScrCompositorClear(&mural->Compositor);
378
379 if (mural->fRootVrOn)
380 CrVrScrCompositorClear(&mural->RootVrCompositor);
381}
382
383static void crServerCleanupCtxMuralRefsCB(unsigned long key, void *data1, void *data2)
384{
385 CRContextInfo *ctxInfo = (CRContextInfo *) data1;
386 CRMuralInfo *mural = (CRMuralInfo *) data2;
387
388 if (ctxInfo->currentMural == mural)
389 ctxInfo->currentMural = NULL;
390}
391
392void SERVER_DISPATCH_APIENTRY
393crServerDispatchWindowDestroy( GLint window )
394{
395 CRMuralInfo *mural;
396 int32_t client;
397 CRClientNode *pNode;
398 int found=false;
399
400 if (!window)
401 {
402 crWarning("Unexpected attempt to delete default mural, ignored!");
403 return;
404 }
405
406 mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
407 if (!mural) {
408 crWarning("CRServer: invalid window %d passed to WindowDestroy()", window);
409 return;
410 }
411
412 crDebug("CRServer: Destroying window %d (spu window %d)", window, mural->spuWindow);
413
414 crHashtableWalk(cr_server.contextTable, crServerCleanupCtxMuralRefsCB, mural);
415
416 crServerMuralTerm(mural);
417
418 CRASSERT(cr_server.currentWindow != window);
419
420 if (cr_server.curClient)
421 {
422 if (cr_server.curClient->currentMural == mural)
423 {
424 cr_server.curClient->currentMural = NULL;
425 cr_server.curClient->currentWindow = -1;
426 }
427
428 found = crServerRemoveClientWindow(cr_server.curClient, window);
429
430 /*Same as with contexts, some apps destroy it not in a thread where it was created*/
431 if (!found)
432 {
433 for (client=0; client<cr_server.numClients; ++client)
434 {
435 if (cr_server.clients[client]==cr_server.curClient)
436 continue;
437
438 found = crServerRemoveClientWindow(cr_server.clients[client], window);
439
440 if (found) break;
441 }
442 }
443
444 if (!found)
445 {
446 pNode=cr_server.pCleanupClient;
447
448 while (pNode && !found)
449 {
450 found = crServerRemoveClientWindow(pNode->pClient, window);
451 pNode = pNode->next;
452 }
453 }
454
455 CRASSERT(found);
456 }
457
458 /*Make sure this window isn't active in other clients*/
459 for (client=0; client<cr_server.numClients; ++client)
460 {
461 if (cr_server.clients[client]->currentMural == mural)
462 {
463 cr_server.clients[client]->currentMural = NULL;
464 cr_server.clients[client]->currentWindow = -1;
465 }
466 }
467
468 pNode=cr_server.pCleanupClient;
469 while (pNode)
470 {
471 if (pNode->pClient->currentMural == mural)
472 {
473 pNode->pClient->currentMural = NULL;
474 pNode->pClient->currentWindow = -1;
475 }
476 pNode = pNode->next;
477 }
478
479 crHashtableDelete(cr_server.muralTable, window, crFree);
480}
481
482static DECLCALLBACK(VBOXVR_SCR_COMPOSITOR_ENTRY*) crServerMuralGetRootVrCEntry(VBOXVR_SCR_COMPOSITOR_ENTRY*pEntry, void *pvContext)
483{
484 CR_DISPLAY_ENTRY *pDEntry = CR_DENTRY_FROM_CENTRY(pEntry);
485 Assert(!CrVrScrCompositorEntryIsUsed(&pDEntry->RootVrCEntry));
486 CrVrScrCompositorEntryInit(&pDEntry->RootVrCEntry, CrVrScrCompositorEntryTexGet(pEntry), NULL);
487 CrVrScrCompositorEntryFlagsSet(&pDEntry->RootVrCEntry, CrVrScrCompositorEntryFlagsGet(pEntry));
488 return &pDEntry->RootVrCEntry;
489}
490
491int crServerMuralSynchRootVr(CRMuralInfo *mural, bool *pfChanged)
492{
493 int rc;
494
495 crServerVBoxRootVrTranslateForMural(mural);
496
497 /* ensure the rootvr compositor does not hold any data,
498 * i.e. cleanup all rootvr entries data */
499 CrVrScrCompositorClear(&mural->RootVrCompositor);
500
501 rc = CrVrScrCompositorIntersectedList(&mural->Compositor, &cr_server.RootVr, &mural->RootVrCompositor, crServerMuralGetRootVrCEntry, NULL, pfChanged);
502 if (!RT_SUCCESS(rc))
503 {
504 crWarning("CrVrScrCompositorIntersectedList failed, rc %d", rc);
505 return rc;
506 }
507
508 return VINF_SUCCESS;
509}
510
511GLboolean crServerMuralSize(CRMuralInfo *mural, GLint width, GLint height)
512{
513 RTRECT Rect;
514 VBOXVR_TEXTURE Tex;
515 int rc = VINF_SUCCESS;
516 Tex.width = width;
517 Tex.height = height;
518 Tex.target = GL_TEXTURE_2D;
519 Tex.hwid = 0;
520
521 if (mural->width == width && mural->height == height)
522 return GL_FALSE;
523
524
525 /* since we're going to change the current compositor & the window we need to avoid
526 * renderspu fron dealing with inconsistent data, i.e. modified compositor and
527 * still unmodified window.
528 * So what we do is:
529 * 1. tell renderspu to stop using the current compositor -> renderspu would do necessary synchronization with its redraw thread to ensure compositor is no longer used
530 * 2. do necessary modifications
531 * 3. (so far not needed for resize, but in case it is in the future) re-set the compositor */
532
533 /* 1. tell renderspu to stop using the current compositor (see above comment) */
534 crServerVBoxCompositionDisableEnter(mural);
535
536 /* 2. do necessary modifications (see above comment) */
537 /* NOTE: we can do it even if mural->fPresentMode == CR_SERVER_REDIR_F_NONE to make sure the compositor data is always up to date */
538 /* the compositor lock is not needed actually since we have prevented renderspu from using the compositor */
539 /* CrVrScrCompositorLock(&mural->Compositor); */
540 if (mural->fUseDefaultDEntry)
541 {
542 if (!mural->bReceivedRects)
543 {
544 rc = CrVrScrCompositorEntryRemove(&mural->Compositor, &mural->DefaultDEntry.CEntry);
545 if (!RT_SUCCESS(rc))
546 {
547 crWarning("CrVrScrCompositorEntryRemove failed, rc %d", rc);
548 goto end;
549 }
550 CrVrScrCompositorEntryInit(&mural->DefaultDEntry.CEntry, &Tex, NULL);
551 /* initially set regions to all visible since this is what some guest assume
552 * and will not post any more visible regions command */
553 Rect.xLeft = 0;
554 Rect.xRight = width;
555 Rect.yTop = 0;
556 Rect.yBottom = height;
557 rc = CrVrScrCompositorEntryRegionsSet(&mural->Compositor, &mural->DefaultDEntry.CEntry, NULL, 1, &Rect, false, NULL);
558 if (!RT_SUCCESS(rc))
559 {
560 crWarning("CrVrScrCompositorEntryRegionsSet failed, rc %d", rc);
561 goto end;
562 }
563 }
564 else
565 {
566 rc = CrVrScrCompositorEntryTexUpdate(&mural->Compositor, &mural->DefaultDEntry.CEntry, &Tex);
567 if (!RT_SUCCESS(rc))
568 {
569 crWarning("CrVrScrCompositorEntryTexUpdate failed, rc %d", rc);
570 goto end;
571 }
572 }
573 }
574 else
575 {
576 CrVrScrCompositorClear(&mural->Compositor);
577 }
578
579 /* CrVrScrCompositorUnlock(&mural->Compositor); */
580 mural->width = width;
581 mural->height = height;
582
583 mural->fDataPresented = GL_FALSE;
584
585 if (cr_server.curClient && cr_server.curClient->currentMural == mural)
586 {
587 crStateGetCurrent()->buffer.width = mural->width;
588 crStateGetCurrent()->buffer.height = mural->height;
589 }
590
591 if (mural->fRootVrOn)
592 {
593 rc = crServerMuralSynchRootVr(mural, NULL);
594 if (!RT_SUCCESS(rc))
595 {
596 crWarning("crServerMuralSynchRootVr failed, rc %d", rc);
597 goto end;
598 }
599 }
600
601 crServerCheckMuralGeometry(mural);
602
603 crServerWindowSize(mural);
604
605 crServerWindowVisibleRegion(mural);
606
607 crServerDEntryAllResized(mural);
608end:
609 /* 3. (so far not needed for resize, but in case it is in the future) re-set the compositor (see above comment) */
610 /* uncomment when needed */
611 /* NOTE: !!! we have mural->fHasPresentationData set to GL_FALSE above, so crServerVBoxCompositionReenable will have no effect in any way
612
613 */
614 crServerVBoxCompositionDisableLeave(mural, GL_FALSE);
615
616 return GL_TRUE;
617}
618
619void SERVER_DISPATCH_APIENTRY
620crServerDispatchWindowSize( GLint window, GLint width, GLint height )
621{
622 CRMuralInfo *mural;
623
624 /* crDebug("CRServer: Window %d size %d x %d", window, width, height);*/
625 mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
626 if (!mural) {
627#if EXTRA_WARN
628 crWarning("CRServer: invalid window %d passed to WindowSize()", window);
629#endif
630 return;
631 }
632
633 crServerMuralSize(mural, width, height);
634
635 if (cr_server.currentMural == mural)
636 {
637 crServerPerformMakeCurrent( mural, cr_server.currentCtxInfo );
638 }
639}
640
641void crServerMuralPosition(CRMuralInfo *mural, GLint x, GLint y, GLboolean fSkipCheckGeometry)
642{
643 GLboolean fForcePresent = GL_FALSE;
644 /* crDebug("CRServer: Window %d pos %d, %d", window, x, y);*/
645
646// if (mural->gX != x || mural->gY != y)
647 {
648 /* since we're going to change the current compositor & the window we need to avoid
649 * renderspu fron dealing with inconsistent data, i.e. modified compositor and
650 * still unmodified window.
651 * So what we do is:
652 * 1. tell renderspu to stop using the current compositor -> renderspu would do necessary synchronization with its redraw thread to ensure compositor is no longer used
653 * 2. do necessary modifications
654 * 3. re-set the compositor */
655
656 /* 1. tell renderspu to stop using the current compositor (see above comment) */
657 crServerVBoxCompositionDisableEnter(mural);
658
659 /* 2. do necessary modifications (see above comment) */
660 /* NOTE: we can do it even if !(mural->fPresentMode & CR_SERVER_REDIR_F_DISPLAY) to make sure the compositor data is always up to date */
661
662 if (mural->gX != x || mural->gY != y)
663 {
664 if (mural->fRootVrOn)
665 {
666 fForcePresent = crServerVBoxCompositionPresentNeeded(mural);
667 }
668
669 mural->gX = x;
670 mural->gY = y;
671
672 /* no need to set position because the position is relative to window */
673 /*CrVrScrCompositorEntryPosSet(&mural->Compositor, &mural->CEntry, &Pos);*/
674
675 if (mural->fRootVrOn)
676 {
677 int rc = crServerMuralSynchRootVr(mural, NULL);
678 if (RT_SUCCESS(rc))
679 {
680 crServerWindowVisibleRegion(mural);
681 }
682 else
683 {
684 crWarning("crServerMuralSynchRootVr failed, rc %d", rc);
685 }
686 }
687 }
688
689 if (!fSkipCheckGeometry)
690 crServerCheckMuralGeometry(mural);
691
692 crServerDEntryAllMoved(mural);
693
694 /* 3. re-set the compositor (see above comment) */
695 crServerVBoxCompositionDisableLeave(mural, fForcePresent);
696 }
697}
698
699void SERVER_DISPATCH_APIENTRY
700crServerDispatchWindowPosition( GLint window, GLint x, GLint y )
701{
702 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
703 if (!mural) {
704#if EXTRA_WARN
705 crWarning("CRServer: invalid window %d passed to WindowPosition()", window);
706#endif
707 return;
708 }
709 crServerMuralPosition(mural, x, y, GL_FALSE);
710}
711
712void crServerMuralVisibleRegion( CRMuralInfo *mural, GLint cRects, const GLint *pRects )
713{
714 GLboolean fForcePresent = crServerVBoxCompositionPresentNeeded(mural);
715 bool fRegionsChanged = false;
716 int rc = VINF_SUCCESS;
717
718 /* since we're going to change the current compositor & the window we need to avoid
719 * renderspu fron dealing with inconsistent data, i.e. modified compositor and
720 * still unmodified window.
721 * So what we do is:
722 * 1. tell renderspu to stop using the current compositor -> renderspu would do necessary synchronization with its redraw thread to ensure compositor is no longer used
723 * 2. do necessary modifications
724 * 3. re-set the compositor */
725
726 /* 1. tell renderspu to stop using the current compositor (see above comment) */
727 crServerVBoxCompositionDisableEnter(mural);
728
729 /* 2. do necessary modifications (see above comment) */
730 if (mural->pVisibleRects)
731 {
732 crFree(mural->pVisibleRects);
733 mural->pVisibleRects = NULL;
734 }
735
736 mural->cVisibleRects = cRects;
737 mural->bReceivedRects = GL_TRUE;
738 if (cRects)
739 {
740 mural->pVisibleRects = (GLint*) crAlloc(4*sizeof(GLint)*cRects);
741 if (!mural->pVisibleRects)
742 {
743 crError("Out of memory in crServerDispatchWindowVisibleRegion");
744 }
745 crMemcpy(mural->pVisibleRects, pRects, 4*sizeof(GLint)*cRects);
746 }
747
748 Assert(mural->fUseDefaultDEntry);
749 /* NOTE: we can do it even if !(mural->fPresentMode & CR_SERVER_REDIR_F_DISPLAY) to make sure the compositor data is always up to date */
750 /* the compositor lock is not needed actually since we have prevented renderspu from using the compositor */
751 /* CrVrScrCompositorLock(&mural->Compositor); */
752 rc = CrVrScrCompositorEntryRegionsSet(&mural->Compositor, &mural->DefaultDEntry.CEntry, NULL, cRects, (const RTRECT *)pRects, false, &fRegionsChanged);
753 /*CrVrScrCompositorUnlock(&mural->Compositor);*/
754 if (!RT_SUCCESS(rc))
755 {
756 crWarning("CrVrScrCompositorEntryRegionsSet failed, rc %d", rc);
757 goto end;
758 }
759
760 if (fRegionsChanged)
761 {
762 if (mural->fRootVrOn)
763 {
764 rc = crServerMuralSynchRootVr(mural, NULL);
765 if (!RT_SUCCESS(rc))
766 {
767 crWarning("crServerMuralSynchRootVr failed, rc %d", rc);
768 goto end;
769 }
770 }
771
772 crServerWindowVisibleRegion(mural);
773
774 crServerDEntryAllVibleRegions(mural);
775 }
776end:
777 /* 3. re-set the compositor (see above comment) */
778 crServerVBoxCompositionDisableLeave(mural, fForcePresent);
779}
780
781void SERVER_DISPATCH_APIENTRY
782crServerDispatchWindowVisibleRegion( GLint window, GLint cRects, const GLint *pRects )
783{
784 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
785 if (!mural) {
786#if EXTRA_WARN
787 crWarning("CRServer: invalid window %d passed to WindowVisibleRegion()", window);
788#endif
789 return;
790 }
791
792 crServerMuralVisibleRegion( mural, cRects, pRects );
793}
794
795void crServerMuralShow( CRMuralInfo *mural, GLint state )
796{
797 mural->bVisible = !!state;
798
799 if (mural->fPresentMode & CR_SERVER_REDIR_F_DISPLAY)
800 crServerWindowShow(mural);
801}
802
803void SERVER_DISPATCH_APIENTRY
804crServerDispatchWindowShow( GLint window, GLint state )
805{
806 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
807 if (!mural) {
808#if EXTRA_WARN
809 crWarning("CRServer: invalid window %d passed to WindowShow()", window);
810#endif
811 return;
812 }
813
814 crServerMuralShow( mural, state );
815}
816
817GLint
818crServerSPUWindowID(GLint serverWindow)
819{
820 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, serverWindow);
821 if (!mural) {
822#if EXTRA_WARN
823 crWarning("CRServer: invalid window %d passed to crServerSPUWindowID()",
824 serverWindow);
825#endif
826 return -1;
827 }
828 return mural->spuWindow;
829}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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