VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp@ 47566

Last change on this file since 47566 was 47566, checked in by vboxsync, 12 years ago

crOpenGL/wddm: TexPresent fixes, irq handling fix

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.0 KB
Line 
1/* $Id: server_presenter.cpp 47566 2013-08-06 22:20:23Z vboxsync $ */
2
3/** @file
4 * Presenter API
5 */
6
7/*
8 * Copyright (C) 2012-2013 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18#include "cr_spu.h"
19#include "chromium.h"
20#include "cr_error.h"
21#include "cr_net.h"
22#include "cr_rand.h"
23#include "server_dispatch.h"
24#include "server.h"
25#include "cr_mem.h"
26#include "cr_string.h"
27#include <cr_vreg.h>
28
29#include <iprt/cdefs.h>
30#include <iprt/types.h>
31#include <iprt/asm.h>
32#include <iprt/mem.h>
33#include <iprt/list.h>
34#include <iprt/memcache.h>
35
36
37/* DISPLAY */
38
39//static DECLCALLBACK(int) crDpCbRegionsChanged(struct CR_PRESENTER *pPresenter)
40//{
41// uint32_t cRegions;
42// const RTRECT *paRegions;
43// int rc = CrPtGetRegions(pPresenter, &cRegions, &paRegions);
44// if (!RT_SUCCESS(rc))
45// {
46// crWarning("CrPtGetRegions failed, rc %d", rc);
47// return rc;
48// }
49//
50// PCR_DISPLAY pDisplay = CR_DISPLAY_FROM_PRESENTER(pPresenter);
51//
52// cr_server.head_spu->dispatch_table.WindowVisibleRegion(pDisplay->Mural.spuWindow, cRegions, (GLint*)paRegions);
53//
54// if (pDisplay->Mural.pvOutputRedirectInstance)
55// {
56// /* @todo the code assumes that RTRECT == four GLInts. */
57// cr_server.outputRedirect.CRORVisibleRegion(pDisplay->Mural.pvOutputRedirectInstance,
58// cRegions, paRegions);
59// }
60//
61// return VINF_SUCCESS;
62//}
63
64int CrDpInit(PCR_DISPLAY pDisplay)
65{
66 const GLint visBits = cr_server.MainContextInfo.CreateInfo.visualBits;
67 if (crServerMuralInit(&pDisplay->Mural, "", visBits, -1, GL_FALSE) < 0)
68 {
69 crWarning("crServerMuralInit failed!");
70 return VERR_GENERAL_FAILURE;
71 }
72 pDisplay->fForcePresent = GL_FALSE;
73 return VINF_SUCCESS;
74}
75
76void CrDpTerm(PCR_DISPLAY pDisplay)
77{
78 crServerMuralTerm(&pDisplay->Mural);
79}
80
81void CrDpResize(PCR_DISPLAY pDisplay, int32_t xPos, int32_t yPos, uint32_t width, uint32_t height)
82{
83 crServerMuralVisibleRegion(&pDisplay->Mural, 0, NULL);
84 crServerMutalPosition(&pDisplay->Mural, xPos, yPos);
85 crServerMuralSize(&pDisplay->Mural, width, height);
86 crServerMuralShow(&pDisplay->Mural, GL_TRUE);
87 CrVrScrCompositorSetStretching(&pDisplay->Mural.Compositor, 1., 1.);
88}
89
90int CrDpSaveState(PCR_DISPLAY pDisplay, PSSMHANDLE pSSM)
91{
92 VBOXVR_SCR_COMPOSITOR_ITERATOR Iter;
93 CrVrScrCompositorIterInit(&pDisplay->Mural.Compositor, &Iter);
94 PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry;
95 uint32_t u32 = 0;
96 while ((pEntry = CrVrScrCompositorIterNext(&Iter)) != NULL)
97 {
98 ++u32;
99 }
100
101 int rc = SSMR3PutU32(pSSM, u32);
102 AssertRCReturn(rc, rc);
103
104 CrVrScrCompositorIterInit(&pDisplay->Mural.Compositor, &Iter);
105
106 while ((pEntry = CrVrScrCompositorIterNext(&Iter)) != NULL)
107 {
108 CR_DISPLAY_ENTRY *pDEntry = CR_DENTRY_FROM_CENTRY(pEntry);
109 rc = CrDemEntrySaveState(pDEntry, pSSM);
110 AssertRCReturn(rc, rc);
111
112 u32 = CrVrScrCompositorEntryFlagsGet(&pDEntry->CEntry);
113 rc = SSMR3PutU32(pSSM, u32);
114 AssertRCReturn(rc, rc);
115
116 rc = SSMR3PutS32(pSSM, CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->x);
117 AssertRCReturn(rc, rc);
118
119 rc = SSMR3PutS32(pSSM, CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->y);
120 AssertRCReturn(rc, rc);
121
122 const RTRECT * pRects;
123 rc = CrVrScrCompositorEntryRegionsGet(&pDisplay->Mural.Compositor, &pDEntry->CEntry, &u32, NULL, NULL, &pRects);
124 AssertRCReturn(rc, rc);
125
126 rc = SSMR3PutU32(pSSM, u32);
127 AssertRCReturn(rc, rc);
128
129 if (u32)
130 {
131 rc = SSMR3PutMem(pSSM, pRects, u32 * sizeof (*pRects));
132 AssertRCReturn(rc, rc);
133 }
134 }
135
136 return VINF_SUCCESS;
137}
138
139int CrDpLoadState(PCR_DISPLAY pDisplay, PSSMHANDLE pSSM, uint32_t version)
140{
141 uint32_t u32 = 0;
142 int rc = SSMR3GetU32(pSSM, &u32);
143 AssertRCReturn(rc, rc);
144
145 if (!u32)
146 return VINF_SUCCESS;
147
148 CrDpEnter(pDisplay);
149
150 for (uint32_t i = 0; i < u32; ++i)
151 {
152 CR_DISPLAY_ENTRY *pDEntry;
153 rc = CrDemEntryLoadState(&cr_server.PresentTexturepMap, &pDEntry, pSSM);
154 AssertRCReturn(rc, rc);
155
156 uint32_t fFlags;
157 rc = SSMR3GetU32(pSSM, &fFlags);
158 AssertRCReturn(rc, rc);
159
160 CrVrScrCompositorEntryFlagsSet(&pDEntry->CEntry, fFlags);
161
162 RTPOINT Pos;
163 rc = SSMR3GetS32(pSSM, &Pos.x);
164 AssertRCReturn(rc, rc);
165
166 rc = SSMR3GetS32(pSSM, &Pos.y);
167 AssertRCReturn(rc, rc);
168
169 uint32_t cRects;
170 rc = SSMR3GetU32(pSSM, &cRects);
171 AssertRCReturn(rc, rc);
172
173 RTRECT * pRects = NULL;
174 if (cRects)
175 {
176 pRects = (RTRECT *)crAlloc(cRects * sizeof (*pRects));
177 AssertReturn(pRects, VERR_NO_MEMORY);
178
179 rc = SSMR3GetMem(pSSM, pRects, cRects * sizeof (*pRects));
180 AssertRCReturn(rc, rc);
181 }
182
183 rc = CrDpEntryRegionsAdd(pDisplay, pDEntry, &Pos, (uint32_t)cRects, (const RTRECT*)pRects);
184 AssertRCReturn(rc, rc);
185
186 if (pRects)
187 crFree(pRects);
188 }
189
190 CrDpLeave(pDisplay);
191
192 return VINF_SUCCESS;
193}
194
195
196int CrDpEntryRegionsSet(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions)
197{
198 int rc = CrVrScrCompositorEntryRegionsSet(&pDisplay->Mural.Compositor, pEntry ? &pEntry->CEntry : NULL, pPos, cRegions, paRegions, false, NULL);
199 return rc;
200}
201
202void crDbgDumpRect(uint32_t i, const RTRECT *pRect)
203{
204 crDebug("%d: (%d;%d) X (%d;%d)", i, pRect->xLeft, pRect->yTop, pRect->xRight, pRect->yBottom);
205}
206
207void crDbgDumpRects(uint32_t cRects, const RTRECT *paRects)
208{
209 crDebug("Dumping rects (%d)", cRects);
210 for (uint32_t i = 0; i < cRects; ++i)
211 {
212 crDbgDumpRect(i, &paRects[i]);
213 }
214 crDebug("End Dumping rects (%d)", cRects);
215}
216
217int CrDpEntryRegionsAdd(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions)
218{
219 uint32_t fChangeFlags = 0;
220 int rc = CrVrScrCompositorEntryRegionsAdd(&pDisplay->Mural.Compositor, pEntry ? &pEntry->CEntry : NULL, pPos, cRegions, paRegions, false, &fChangeFlags);
221 if (RT_SUCCESS(rc))
222 {
223 if (fChangeFlags & VBOXVR_COMPOSITOR_CF_REGIONS_CHANGED)
224 {
225 uint32_t cRects;
226 const RTRECT *pRects;
227 rc = CrVrScrCompositorRegionsGet(&pDisplay->Mural.Compositor, &cRects, NULL, &pRects, NULL);
228 if (RT_SUCCESS(rc))
229 crServerMuralVisibleRegion(&pDisplay->Mural, cRects, (GLint *)pRects);
230 else
231 crWarning("CrVrScrCompositorRegionsGet failed, rc %d", rc);
232 }
233 }
234 else
235 crWarning("CrVrScrCompositorEntryRegionsAdd failed, rc %d", rc);
236
237 return rc;
238}
239
240void CrDpEntryRegionsClear(PCR_DISPLAY pDisplay)
241{
242 bool fChanged = false;
243 CrVrScrCompositorRegionsClear(&pDisplay->Mural.Compositor, &fChanged);
244 if (fChanged)
245 {
246 crServerMuralVisibleRegion(&pDisplay->Mural, 0, NULL);
247 }
248}
249
250#define PCR_DISPLAY_ENTRY_FROM_CENTRY(_pe) ((PCR_DISPLAY_ENTRY)((uint8_t*)(_pe) - RT_OFFSETOF(CR_DISPLAY_ENTRY, CEntry)))
251static DECLCALLBACK(void) crDpEntryCEntryReleaseCB(const struct VBOXVR_SCR_COMPOSITOR *pCompositor, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pReplacingEntry)
252{
253 PCR_DISPLAY_ENTRY pCEntry = PCR_DISPLAY_ENTRY_FROM_CENTRY(pEntry);
254 CrDemEntryRelease(pCEntry);
255}
256
257void CrDpEntryInit(PCR_DISPLAY_ENTRY pEntry, const VBOXVR_TEXTURE *pTextureData)
258{
259 CrVrScrCompositorEntryInit(&pEntry->CEntry, pTextureData, crDpEntryCEntryReleaseCB);
260 CrVrScrCompositorEntryFlagsSet(&pEntry->CEntry, CRBLT_F_INVERT_SRC_YCOORDS);
261 CrVrScrCompositorEntryInit(&pEntry->RootVrCEntry, pTextureData, NULL);
262 CrVrScrCompositorEntryFlagsSet(&pEntry->RootVrCEntry, CRBLT_F_INVERT_SRC_YCOORDS);
263}
264
265void CrDpEntryCleanup(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry)
266{
267 CrVrScrCompositorEntryRemove(&pDisplay->Mural.Compositor, &pEntry->CEntry);
268}
269
270void CrDpEnter(PCR_DISPLAY pDisplay)
271{
272 pDisplay->fForcePresent = crServerVBoxCompositionPresentNeeded(&pDisplay->Mural);
273 crServerVBoxCompositionDisableEnter(&pDisplay->Mural);
274}
275
276void CrDpLeave(PCR_DISPLAY pDisplay)
277{
278 pDisplay->Mural.fDataPresented = GL_TRUE;
279 crServerVBoxCompositionDisableLeave(&pDisplay->Mural, pDisplay->fForcePresent);
280}
281
282typedef struct CR_DEM_ENTRY_INFO
283{
284 CRTextureObj *pTobj;
285 uint32_t cEntries;
286} CR_DEM_ENTRY_INFO;
287
288typedef struct CR_DEM_ENTRY
289{
290 CR_DISPLAY_ENTRY Entry;
291 CR_DEM_ENTRY_INFO *pInfo;
292 CR_DISPLAY_ENTRY_MAP *pMap;
293} CR_DEM_ENTRY;
294
295#define PCR_DEM_ENTRY_FROM_ENTRY(_pEntry) ((CR_DEM_ENTRY*)((uint8_t*)(_pEntry) - RT_OFFSETOF(CR_DEM_ENTRY, Entry)))
296
297static RTMEMCACHE g_VBoxCrDemLookasideList;
298static RTMEMCACHE g_VBoxCrDemInfoLookasideList;
299
300int CrDemGlobalInit()
301{
302 int rc = RTMemCacheCreate(&g_VBoxCrDemLookasideList, sizeof (CR_DEM_ENTRY),
303 0, /* size_t cbAlignment */
304 UINT32_MAX, /* uint32_t cMaxObjects */
305 NULL, /* PFNMEMCACHECTOR pfnCtor*/
306 NULL, /* PFNMEMCACHEDTOR pfnDtor*/
307 NULL, /* void *pvUser*/
308 0 /* uint32_t fFlags*/
309 );
310 if (RT_SUCCESS(rc))
311 {
312 rc = RTMemCacheCreate(&g_VBoxCrDemInfoLookasideList, sizeof (CR_DEM_ENTRY_INFO),
313 0, /* size_t cbAlignment */
314 UINT32_MAX, /* uint32_t cMaxObjects */
315 NULL, /* PFNMEMCACHECTOR pfnCtor*/
316 NULL, /* PFNMEMCACHEDTOR pfnDtor*/
317 NULL, /* void *pvUser*/
318 0 /* uint32_t fFlags*/
319 );
320 if (RT_SUCCESS(rc))
321 return VINF_SUCCESS;
322 else
323 crWarning("RTMemCacheCreate failed rc %d", rc);
324
325 RTMemCacheDestroy(g_VBoxCrDemLookasideList);
326 }
327 else
328 crWarning("RTMemCacheCreate failed rc %d", rc);
329 return VINF_SUCCESS;
330}
331
332void CrDemTeGlobalTerm()
333{
334 RTMemCacheDestroy(g_VBoxCrDemLookasideList);
335 RTMemCacheDestroy(g_VBoxCrDemInfoLookasideList);
336}
337
338static CR_DEM_ENTRY* crDemEntryAlloc()
339{
340 return (CR_DEM_ENTRY*)RTMemCacheAlloc(g_VBoxCrDemLookasideList);
341}
342
343static CR_DEM_ENTRY_INFO* crDemEntryInfoAlloc()
344{
345 return (CR_DEM_ENTRY_INFO*)RTMemCacheAlloc(g_VBoxCrDemInfoLookasideList);
346}
347
348static void crDemEntryFree(CR_DEM_ENTRY* pDemEntry)
349{
350 RTMemCacheFree(g_VBoxCrDemLookasideList, pDemEntry);
351}
352
353static void crDemEntryInfoFree(CR_DEM_ENTRY_INFO* pDemEntryInfo)
354{
355 RTMemCacheFree(g_VBoxCrDemInfoLookasideList, pDemEntryInfo);
356}
357
358void crDemEntryRelease(PCR_DISPLAY_ENTRY_MAP pMap, CR_DEM_ENTRY *pDemEntry)
359{
360 CR_DEM_ENTRY_INFO *pInfo = pDemEntry->pInfo;
361 CRTextureObj *pTobj = pInfo->pTobj;
362
363 --pInfo->cEntries;
364
365 if (!pInfo->cEntries)
366 {
367 CR_STATE_SHAREDOBJ_USAGE_CLEAR(pInfo->pTobj, cr_server.MainContextInfo.pContext);
368
369 crHashtableDelete(pMap->pTexIdToDemInfoMap, pTobj->id, NULL);
370
371 crDemEntryInfoFree(pInfo);
372 }
373
374 if (!CR_STATE_SHAREDOBJ_USAGE_IS_USED(pTobj))
375 {
376 CRSharedState *pShared = crStateGlobalSharedAcquire();
377
378 CRASSERT(pShared);
379 /* on the host side, we need to delete an ogl texture object here as well, which crStateDeleteTextureCallback will do
380 * in addition to calling crStateDeleteTextureObject to delete a state object */
381 crHashtableDelete(pShared->textureTable, pTobj->id, crStateDeleteTextureCallback);
382
383 crStateGlobalSharedRelease();
384 }
385
386 crDemEntryFree(pDemEntry);
387
388 crStateGlobalSharedRelease();
389}
390
391int CrDemInit(PCR_DISPLAY_ENTRY_MAP pMap)
392{
393 pMap->pTexIdToDemInfoMap = crAllocHashtable();
394 if (pMap->pTexIdToDemInfoMap)
395 return VINF_SUCCESS;
396
397 crWarning("crAllocHashtable failed");
398 return VERR_NO_MEMORY;
399}
400
401void CrDemTerm(PCR_DISPLAY_ENTRY_MAP pMap)
402{
403 crFreeHashtable(pMap->pTexIdToDemInfoMap, NULL);
404 pMap->pTexIdToDemInfoMap = NULL;
405}
406
407void CrDemEntryRelease(PCR_DISPLAY_ENTRY pEntry)
408{
409 CR_DEM_ENTRY *pDemEntry = PCR_DEM_ENTRY_FROM_ENTRY(pEntry);
410 crDemEntryRelease(pDemEntry->pMap, pDemEntry);
411}
412
413int CrDemEntrySaveState(PCR_DISPLAY_ENTRY pEntry, PSSMHANDLE pSSM)
414{
415 CR_DEM_ENTRY *pDemEntry = PCR_DEM_ENTRY_FROM_ENTRY(pEntry);
416 int rc = SSMR3PutU32(pSSM, pDemEntry->pInfo->pTobj->id);
417 AssertRCReturn(rc, rc);
418 return rc;
419}
420
421int CrDemEntryLoadState(PCR_DISPLAY_ENTRY_MAP pMap, PCR_DISPLAY_ENTRY *ppEntry, PSSMHANDLE pSSM)
422{
423 uint32_t u32;
424 int rc = SSMR3GetU32(pSSM, &u32);
425 AssertRCReturn(rc, rc);
426
427 PCR_DISPLAY_ENTRY pEntry = CrDemEntryAcquire(pMap, u32);
428 if (!pEntry)
429 {
430 crWarning("CrDemEntryAcquire failed");
431 return VERR_NO_MEMORY;
432 }
433
434 *ppEntry = pEntry;
435 return VINF_SUCCESS;
436}
437
438PCR_DISPLAY_ENTRY CrDemEntryAcquire(PCR_DISPLAY_ENTRY_MAP pMap, GLuint idTexture)
439{
440 CR_DEM_ENTRY *pDemEntry = NULL;
441
442 CRSharedState *pShared = crStateGlobalSharedAcquire();
443 if (!pShared)
444 {
445 crWarning("pShared is null!");
446 return NULL;
447 }
448
449 CRTextureObj *pTobj = (CRTextureObj*)crHashtableSearch(pShared->textureTable, idTexture);
450 if (!pTobj)
451 {
452 crWarning("pTobj is null!");
453 crStateGlobalSharedRelease();
454 return NULL;
455 }
456
457 Assert(pTobj->id == idTexture);
458
459 GLuint hwId = crStateGetTextureObjHWID(pTobj);
460 if (!hwId)
461 {
462 crWarning("hwId is null!");
463 crStateGlobalSharedRelease();
464 return NULL;
465 }
466
467 VBOXVR_TEXTURE TextureData;
468 TextureData.width = pTobj->level[0]->width;
469 TextureData.height = pTobj->level[0]->height;
470 TextureData.target = pTobj->target;
471 TextureData.hwid = hwId;
472
473 pDemEntry = crDemEntryAlloc();
474 if (!pDemEntry)
475 {
476 crWarning("crDemEntryAlloc failed allocating CR_DEM_ENTRY");
477 crStateGlobalSharedRelease();
478 return NULL;
479 }
480
481 CrDpEntryInit(&pDemEntry->Entry, &TextureData);
482
483 CR_DEM_ENTRY_INFO *pInfo = (CR_DEM_ENTRY_INFO*)crHashtableSearch(pMap->pTexIdToDemInfoMap, pTobj->id);
484 if (!pInfo)
485 {
486 pInfo = crDemEntryInfoAlloc();
487 CRASSERT(pInfo);
488 crHashtableAdd(pMap->pTexIdToDemInfoMap, pTobj->id, pInfo);
489 pInfo->cEntries = 0;
490 pInfo->pTobj = pTobj;
491 }
492
493 ++pInfo->cEntries;
494 pDemEntry->pInfo = pInfo;
495 pDemEntry->pMap = pMap;
496
497 /* just use main context info's context to hold the texture reference */
498 CR_STATE_SHAREDOBJ_USAGE_SET(pTobj, cr_server.MainContextInfo.pContext);
499
500 return &pDemEntry->Entry;
501}
502
503PCR_DISPLAY crServerDisplayGetInitialized(uint32_t idScreen)
504{
505 if (ASMBitTest(cr_server.DisplaysInitMap, idScreen))
506 return &cr_server.aDispplays[idScreen];
507 return NULL;
508}
509
510static PCR_DISPLAY crServerDisplayGet(uint32_t idScreen)
511{
512 if (idScreen >= CR_MAX_GUEST_MONITORS)
513 {
514 crWarning("invalid idScreen %d", idScreen);
515 return NULL;
516 }
517
518 if (ASMBitTest(cr_server.DisplaysInitMap, idScreen))
519 return &cr_server.aDispplays[idScreen];
520
521 int rc = CrDpInit(&cr_server.aDispplays[idScreen]);
522 if (RT_SUCCESS(rc))
523 {
524 CrDpResize(&cr_server.aDispplays[idScreen],
525 cr_server.screen[idScreen].x, cr_server.screen[idScreen].y,
526 cr_server.screen[idScreen].w, cr_server.screen[idScreen].h);
527 ASMBitSet(cr_server.DisplaysInitMap, idScreen);
528 return &cr_server.aDispplays[idScreen];
529 }
530 else
531 {
532 crWarning("CrDpInit failed for screen %d", idScreen);
533 }
534
535 return NULL;
536}
537
538int crServerDisplaySaveState(PSSMHANDLE pSSM)
539{
540 int rc;
541 int cDisplays = 0, i;
542 for (i = 0; i < cr_server.screenCount; ++i)
543 {
544 if (ASMBitTest(cr_server.DisplaysInitMap, i) && !CrDpIsEmpty(&cr_server.aDispplays[i]))
545 ++cDisplays;
546 }
547
548 rc = SSMR3PutS32(pSSM, cDisplays);
549 AssertRCReturn(rc, rc);
550
551 for (i = 0; i < cr_server.screenCount; ++i)
552 {
553 if (ASMBitTest(cr_server.DisplaysInitMap, i) && !CrDpIsEmpty(&cr_server.aDispplays[i]))
554 {
555 rc = SSMR3PutS32(pSSM, i);
556 AssertRCReturn(rc, rc);
557
558 rc = CrDpSaveState(&cr_server.aDispplays[i], pSSM);
559 AssertRCReturn(rc, rc);
560 }
561 }
562
563 return VINF_SUCCESS;
564}
565
566int crServerDisplayLoadState(PSSMHANDLE pSSM, uint32_t u32Version)
567{
568 int rc;
569 int s32, i;
570
571 rc = SSMR3GetS32(pSSM, &s32);
572 AssertRCReturn(rc, rc);
573
574 for (i = 0; i < s32; ++i)
575 {
576 int iScreen;
577
578 rc = SSMR3GetS32(pSSM, &iScreen);
579 AssertRCReturn(rc, rc);
580
581 PCR_DISPLAY pDisplay = crServerDisplayGet((uint32_t)iScreen);
582 if (!pDisplay)
583 {
584 crWarning("crServerDisplayGet failed");
585 return VERR_GENERAL_FAILURE;
586 }
587
588 rc = CrDpLoadState(pDisplay, pSSM, u32Version);
589 AssertRCReturn(rc, rc);
590 }
591
592 return VINF_SUCCESS;
593}
594
595void crServerDisplayTermAll()
596{
597 int i;
598 for (i = 0; i < cr_server.screenCount; ++i)
599 {
600 if (ASMBitTest(cr_server.DisplaysInitMap, i))
601 {
602 CrDpTerm(&cr_server.aDispplays[i]);
603 ASMBitClear(cr_server.DisplaysInitMap, i);
604 }
605 }
606}
607
608void CrHlpFreeTexImage(CRContext *pCurCtx, GLuint idPBO, void *pvData)
609{
610 if (idPBO)
611 {
612 cr_server.head_spu->dispatch_table.UnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
613 if (pCurCtx)
614 cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pCurCtx->bufferobject.packBuffer->hwid);
615 else
616 cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
617 }
618 else
619 {
620 crFree(pvData);
621 if (pCurCtx && crStateIsBufferBoundForCtx(pCurCtx, GL_PIXEL_PACK_BUFFER_ARB))
622 cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pCurCtx->bufferobject.packBuffer->hwid);
623 }
624}
625
626void CrHlpPutTexImage(CRContext *pCurCtx, PVBOXVR_TEXTURE pTexture, GLenum enmFormat, void *pvData)
627{
628 CRASSERT(pTexture->hwid);
629 cr_server.head_spu->dispatch_table.BindTexture(pTexture->target, pTexture->hwid);
630
631 if (!pCurCtx || crStateIsBufferBoundForCtx(pCurCtx, GL_PIXEL_UNPACK_BUFFER_ARB))
632 {
633 cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
634 }
635
636 /*read the texture, note pixels are NULL for PBO case as it's offset in the buffer*/
637 cr_server.head_spu->dispatch_table.TexSubImage2D(GL_TEXTURE_2D, 0 /* level*/, 0 /*xoffset*/, 0 /*yoffset*/, pTexture->width, pTexture->height, enmFormat, GL_UNSIGNED_BYTE, pvData);
638
639 /*restore gl state*/
640 if (pCurCtx)
641 {
642 CRTextureObj *pTObj;
643 CRTextureLevel *pTImg;
644 crStateGetTextureObjectAndImage(pCurCtx, pTexture->target, 0, &pTObj, &pTImg);
645
646 GLuint uid = pTObj->hwid;
647 cr_server.head_spu->dispatch_table.BindTexture(pTexture->target, uid);
648 }
649 else
650 {
651 cr_server.head_spu->dispatch_table.BindTexture(pTexture->target, 0);
652 }
653
654 if (pCurCtx && crStateIsBufferBoundForCtx(pCurCtx, GL_PIXEL_UNPACK_BUFFER_ARB))
655 cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pCurCtx->bufferobject.unpackBuffer->hwid);
656}
657
658void* CrHlpGetTexImage(CRContext *pCurCtx, PVBOXVR_TEXTURE pTexture, GLuint idPBO, GLenum enmFormat)
659{
660 void *pvData = NULL;
661 cr_server.head_spu->dispatch_table.BindTexture(pTexture->target, pTexture->hwid);
662
663 if (idPBO)
664 {
665 cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, idPBO);
666 }
667 else
668 {
669 if (!pCurCtx || crStateIsBufferBoundForCtx(pCurCtx, GL_PIXEL_PACK_BUFFER_ARB))
670 {
671 cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
672 }
673
674 pvData = crAlloc(4*pTexture->width*pTexture->height);
675 if (!pvData)
676 {
677 crWarning("Out of memory in CrHlpGetTexImage");
678 return NULL;
679 }
680 }
681
682 /*read the texture, note pixels are NULL for PBO case as it's offset in the buffer*/
683 cr_server.head_spu->dispatch_table.GetTexImage(GL_TEXTURE_2D, 0, enmFormat, GL_UNSIGNED_BYTE, pvData);
684
685 /*restore gl state*/
686 if (pCurCtx)
687 {
688 CRTextureObj *pTObj;
689 CRTextureLevel *pTImg;
690 crStateGetTextureObjectAndImage(pCurCtx, pTexture->target, 0, &pTObj, &pTImg);
691
692 GLuint uid = pTObj->hwid;
693 cr_server.head_spu->dispatch_table.BindTexture(pTexture->target, uid);
694 }
695 else
696 {
697 cr_server.head_spu->dispatch_table.BindTexture(pTexture->target, 0);
698 }
699
700 if (idPBO)
701 {
702 pvData = cr_server.head_spu->dispatch_table.MapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
703 if (!pvData)
704 {
705 crWarning("Failed to MapBuffer in CrHlpGetTexImage");
706 return NULL;
707 }
708 }
709
710 CRASSERT(pvData);
711 return pvData;
712}
713
714void SERVER_DISPATCH_APIENTRY
715crServerDispatchVBoxTexPresent(GLuint texture, GLuint cfg, GLint xPos, GLint yPos, GLint cRects, const GLint *pRects)
716{
717 uint32_t idScreen = CR_PRESENT_GET_SCREEN(cfg);
718 PCR_DISPLAY pDisplay = crServerDisplayGet(idScreen);
719 if (!pDisplay)
720 {
721 crWarning("crServerDisplayGet Failed");
722 return;
723 }
724
725 PCR_DISPLAY_ENTRY pEntry = NULL;
726 if (texture)
727 {
728 pEntry = CrDemEntryAcquire(&cr_server.PresentTexturepMap, texture);
729 if (!pEntry)
730 {
731 crWarning("CrDemEntryAcquire Failed");
732 return;
733 }
734 }
735
736 CrDpEnter(pDisplay);
737
738 if (!(cfg & CR_PRESENT_FLAG_CLEAR_RECTS))
739 {
740 RTPOINT Point = {xPos, yPos};
741 int rc = CrDpEntryRegionsAdd(pDisplay, pEntry, &Point, (uint32_t)cRects, (const RTRECT*)pRects);
742 if (!RT_SUCCESS(rc))
743 {
744 crWarning("CrDpEntryRegionsAdd Failed rc %d", rc);
745// if (pEntry)
746// CrDemEntryRelease(pEntry);
747 return;
748 }
749 }
750 else
751 {
752 CrDpEntryRegionsClear(pDisplay);
753 }
754
755 CrDpLeave(pDisplay);
756}
Note: See TracBrowser for help on using the repository browser.

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