Changeset 50095 in vbox for trunk/src/VBox/HostServices/SharedOpenGL
- Timestamp:
- Jan 17, 2014 4:34:07 PM (11 years ago)
- svn:sync-xref-src-repo-rev:
- 91620
- Location:
- trunk/src/VBox/HostServices/SharedOpenGL
- Files:
-
- 21 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostServices/SharedOpenGL/Makefile.kmk
r50041 r50095 132 132 crserverlib/server_framebuffer.c \ 133 133 crserverlib/server_glsl.c \ 134 crserverlib/server_muralfbo.c \134 crserverlib/server_muralfbo.cpp \ 135 135 crserverlib/server_texture.c \ 136 crserverlib/server_vertattr.c \ 136 137 crserverlib/server_presenter.cpp \ 137 138 crserverlib/server_rpw.cpp \ -
trunk/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp
r49474 r50095 1174 1174 break; 1175 1175 } 1176 case SHCRGL_HOST_FN_DEV_RESIZE: 1177 { 1178 Log(("svcCall: SHCRGL_HOST_FN_DEV_RESIZE\n")); 1179 1180 /* Verify parameter count and types. */ 1181 if (cParms != SHCRGL_CPARMS_DEV_RESIZE) 1182 { 1183 LogRel(("SHCRGL_HOST_FN_DEV_RESIZE: cParms invalid - %d", cParms)); 1184 rc = VERR_INVALID_PARAMETER; 1185 break; 1186 } 1187 1188 for (int i = 0; i < SHCRGL_CPARMS_DEV_RESIZE; ++i) 1189 { 1190 if (paParms[i].type != VBOX_HGCM_SVC_PARM_PTR 1191 || !paParms[i].u.pointer.addr) 1192 { 1193 AssertMsgFailed(("invalid param\n")); 1194 return VERR_INVALID_PARAMETER; 1195 } 1196 } 1197 1198 rc = crVBoxServerNotifyResize((const VBVAINFOSCREEN *)paParms[0].u.pointer.addr, paParms[1].u.pointer.addr); 1199 break; 1200 } 1176 1201 case SHCRGL_HOST_FN_VIEWPORT_CHANGED: 1177 1202 { … … 1252 1277 if (pOutputRedirect->H3DORBegin != NULL) 1253 1278 { 1254 rc = crVBoxServerSetOffscreenRendering(GL_TRUE); 1255 1279 CROutputRedirect outputRedirect; 1280 outputRedirect.pvContext = pOutputRedirect->pvContext; 1281 outputRedirect.CRORBegin = pOutputRedirect->H3DORBegin; 1282 outputRedirect.CRORGeometry = pOutputRedirect->H3DORGeometry; 1283 outputRedirect.CRORVisibleRegion = pOutputRedirect->H3DORVisibleRegion; 1284 outputRedirect.CRORFrame = pOutputRedirect->H3DORFrame; 1285 outputRedirect.CROREnd = pOutputRedirect->H3DOREnd; 1286 outputRedirect.CRORContextProperty = pOutputRedirect->H3DORContextProperty; 1287 rc = crVBoxServerOutputRedirectSet(&outputRedirect); 1256 1288 if (RT_SUCCESS(rc)) 1257 1289 { 1258 CROutputRedirect outputRedirect; 1259 outputRedirect.pvContext = pOutputRedirect->pvContext; 1260 outputRedirect.CRORBegin = pOutputRedirect->H3DORBegin; 1261 outputRedirect.CRORGeometry = pOutputRedirect->H3DORGeometry; 1262 outputRedirect.CRORVisibleRegion = pOutputRedirect->H3DORVisibleRegion; 1263 outputRedirect.CRORFrame = pOutputRedirect->H3DORFrame; 1264 outputRedirect.CROREnd = pOutputRedirect->H3DOREnd; 1265 outputRedirect.CRORContextProperty = pOutputRedirect->H3DORContextProperty; 1266 rc = crVBoxServerOutputRedirectSet(&outputRedirect); 1290 rc = crVBoxServerSetOffscreenRendering(GL_TRUE); 1267 1291 } 1268 1292 } -
trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h
r50041 r50095 15 15 16 16 #include "cr_server.h" 17 #include <cr_htable.h> 18 #include <cr_compositor.h> 17 19 18 20 #ifdef VBOX_WITH_CRHGSMI … … 114 116 GLint crServerDispatchCreateContextEx(const char *dpyName, GLint visualBits, GLint shareCtx, GLint preloadCtxID, int32_t internalID); 115 117 GLint crServerDispatchWindowCreateEx(const char *dpyName, GLint visBits, GLint preloadWinID); 116 GLint crServerMuralInit(CRMuralInfo *mural, const char *dpyName, GLint visBits, GLint preloadWinID , GLboolean fUseDefaultDEntry);118 GLint crServerMuralInit(CRMuralInfo *mural, const char *dpyName, GLint visBits, GLint preloadWinID); 117 119 void crServerMuralTerm(CRMuralInfo *mural); 118 120 GLboolean crServerMuralSize(CRMuralInfo *mural, GLint width, GLint height); 119 void crServerMuralPosition(CRMuralInfo *mural, GLint x, GLint y , GLboolean fSkipCheckGeometry);121 void crServerMuralPosition(CRMuralInfo *mural, GLint x, GLint y); 120 122 void crServerMuralVisibleRegion( CRMuralInfo *mural, GLint cRects, const GLint *pRects ); 121 123 void crServerMuralShow( CRMuralInfo *mural, GLint state ); 122 int crServerMuralSynchRootVr(CRMuralInfo *mural, bool *pfChanged);123 124 124 125 GLint crServerGenerateID(GLint *pCounter); … … 129 130 130 131 CRMuralInfo * crServerGetDummyMural(GLint visualBits); 131 132 void crServerPresentOutputRedirect(CRMuralInfo *pMural);133 void crServerOutputRedirectCheckEnableDisable(CRMuralInfo *pMural);134 132 135 133 void crServerCheckMuralGeometry(CRMuralInfo *mural); 136 134 GLboolean crServerSupportRedirMuralFBO(void); 137 135 136 void crVBoxServerMuralFbResizeBegin(HCR_FRAMEBUFFER hFb); 137 void crVBoxServerMuralFbResizeEnd(HCR_FRAMEBUFFER hFb); 138 138 139 void crVBoxServerNotifyEvent(int32_t idScreen, uint32_t uEvent, void*pvData); 139 140 void crVBoxServerCheckVisibilityEvent(int32_t idScreen); 140 141 141 void crServerDisplayTermAll(); 142 143 void crServerWindowSize(CRMuralInfo *pMural); 144 void crServerWindowShow(CRMuralInfo *pMural); 145 void crServerWindowVisibleRegion(CRMuralInfo *pMural); 142 void crServerRedirMuralFbClear(CRMuralInfo *mural); 143 146 144 void crServerWindowReparent(CRMuralInfo *pMural); 147 145 148 void crServerWindowSetIsVisible(CRMuralInfo *pMural, GLboolean fIsVisible); 149 void crServerWindowCheckIsVisible(CRMuralInfo *pMural); 150 151 int crVBoxServerUpdateMuralRootVisibleRegion(CRMuralInfo *pMI); 152 153 #define CR_SERVER_REDIR_F_NONE 0x00 154 /* the data should be displayed on host (unset when is on or when CR_SERVER_REDIR_F_FBO_RAM_VMFB is set) */ 155 #define CR_SERVER_REDIR_F_DISPLAY 0x01 156 /* guest window data get redirected to FBO on host */ 157 #define CR_SERVER_REDIR_F_FBO 0x02 158 /* used with CR_SERVER_REDIR_F_FBO only 159 * indicates that FBO data should be copied to RAM for further processing */ 160 #define CR_SERVER_REDIR_F_FBO_RAM 0x04 161 /* used with CR_SERVER_REDIR_F_FBO_RAM only 162 * indicates that FBO data should be passed to VRDP backend */ 163 #define CR_SERVER_REDIR_F_FBO_RAM_VRDP 0x08 164 /* used with CR_SERVER_REDIR_F_FBO_RAM only 165 * indicates that FBO data should be passed to VM Framebuffer */ 166 #define CR_SERVER_REDIR_F_FBO_RAM_VMFB 0x10 167 /* used with CR_SERVER_REDIR_F_FBO_RAM only 168 * makes the RPW (Read Pixels Worker) mechanism to be used for GPU memory aquisition */ 169 #define CR_SERVER_REDIR_F_FBO_RPW 0x20 170 171 172 #define CR_SERVER_REDIR_F_ALL 0x3f 173 174 #define CR_SERVER_REDIR_FGROUP_REQUIRE_FBO (CR_SERVER_REDIR_F_ALL & ~CR_SERVER_REDIR_F_DISPLAY) 175 #define CR_SERVER_REDIR_FGROUP_REQUIRE_FBO_RAM (CR_SERVER_REDIR_F_FBO_RAM_VRDP | CR_SERVER_REDIR_F_FBO_RAM_VMFB | CR_SERVER_REDIR_F_FBO_RPW) 176 177 DECLINLINE(GLuint) crServerRedirModeAdjust(GLuint value) 178 { 179 /* sanitize values */ 180 value &= CR_SERVER_REDIR_F_ALL; 181 182 if (value & CR_SERVER_REDIR_FGROUP_REQUIRE_FBO) 183 value |= CR_SERVER_REDIR_F_FBO; 184 if (value & CR_SERVER_REDIR_FGROUP_REQUIRE_FBO_RAM) 185 value |= CR_SERVER_REDIR_F_FBO_RAM; 186 187 return value; 188 } 189 190 int32_t crServerSetOffscreenRenderingMode(GLuint value); 191 void crServerRedirMuralFBO(CRMuralInfo *mural, GLuint redir); 146 void crServerRedirMuralFBO(CRMuralInfo *mural, bool fEnabled); 192 147 void crServerDeleteMuralFBO(CRMuralInfo *mural); 193 148 void crServerPresentFBO(CRMuralInfo *mural); … … 196 151 void crServerMuralFBOSwapBuffers(CRMuralInfo *mural); 197 152 198 void crServerVBoxCompositionDisableEnter(CRMuralInfo *mural);199 void crServerVBoxCompositionDisableLeave(CRMuralInfo *mural, GLboolean fForcePresentOnEnabled);200 void crServerVBoxCompositionPresent(CRMuralInfo *mural);201 DECLINLINE(GLboolean) crServerVBoxCompositionPresentNeeded(CRMuralInfo *mural)202 {203 return mural->bVisible204 && mural->width205 && mural->height206 && !mural->fRootVrOn ? !CrVrScrCompositorIsEmpty(&mural->Compositor) : !CrVrScrCompositorIsEmpty(&mural->RootVrCompositor);207 }208 153 209 154 #define CR_SERVER_FBO_BB_IDX(_mural) ((_mural)->iBbBuffer) … … 219 164 int32_t crVBoxServerInternalClientRead(CRClient *pClient, uint8_t *pBuffer, uint32_t *pcbBuffer); 220 165 221 PCR_DISPLAY crServerDisplayGetInitialized(uint32_t idScreen);222 223 166 void crServerPerformMakeCurrent( CRMuralInfo *mural, CRContextInfo *ctxInfo ); 224 167 225 168 PCR_BLITTER crServerVBoxBlitterGet(); 169 PCR_BLITTER crServerVBoxBlitterGetInitialized(); 226 170 227 171 DECLINLINE(void) crServerVBoxBlitterWinInit(CR_BLITTER_WINDOW *win, CRMuralInfo *mural) … … 420 364 int crServerVBoxParseNumerics(const char *pszStr, const int defaultVal); 421 365 422 void CrDpRootUpdate(PCR_DISPLAY pDisplay); 423 void CrDpEnter(PCR_DISPLAY pDisplay); 424 void CrDpLeave(PCR_DISPLAY pDisplay); 425 int CrDpInit(PCR_DISPLAY pDisplay); 426 void CrDpTerm(PCR_DISPLAY pDisplay); 427 428 DECLINLINE(bool) CrDpIsEmpty(PCR_DISPLAY pDisplay) 429 { 430 return CrVrScrCompositorIsEmpty(&pDisplay->Mural.Compositor); 431 } 432 433 int CrDpSaveState(PCR_DISPLAY pDisplay, PSSMHANDLE pSSM); 434 int CrDpLoadState(PCR_DISPLAY pDisplay, PSSMHANDLE pSSM, uint32_t version); 435 436 void CrDpReparent(PCR_DISPLAY pDisplay, CRScreenInfo *pScreen); 437 438 void CrDpResize(PCR_DISPLAY pDisplay, int32_t xPos, int32_t yPos, uint32_t width, uint32_t height); 439 void CrDpEntryInit(PCR_DISPLAY_ENTRY pEntry, const VBOXVR_TEXTURE *pTextureData, uint32_t fFlags, PFNVBOXVRSCRCOMPOSITOR_ENTRY_RELEASED pfnEntryReleased); 440 void CrDpEntryCleanup(PCR_DISPLAY_ENTRY pEntry); 441 int CrDpEntryRegionsSet(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions); 442 int CrDpEntryRegionsAdd(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, CR_DISPLAY_ENTRY_MAP *pMap); 443 void CrDpRegionsClear(PCR_DISPLAY pDisplay); 444 DECLINLINE(bool) CrDpEntryIsUsed(PCR_DISPLAY_ENTRY pEntry) 445 { 446 return CrVrScrCompositorEntryIsInList(&pEntry->CEntry); 447 } 448 449 DECLINLINE(CRMuralInfo*) CrDpGetMural(PCR_DISPLAY pDisplay) 450 { 451 return &pDisplay->Mural; 452 } 453 454 int CrDemGlobalInit(); 455 void CrDemTeGlobalTerm(); 456 void CrDemEnter(PCR_DISPLAY_ENTRY_MAP pMap); 457 void CrDemLeave(PCR_DISPLAY_ENTRY_MAP pMap, PCR_DISPLAY_ENTRY pNewEntry, PCR_DISPLAY_ENTRY pReplacedEntry); 458 int CrDemInit(PCR_DISPLAY_ENTRY_MAP pMap); 459 void CrDemTerm(PCR_DISPLAY_ENTRY_MAP pMap); 460 PCR_DISPLAY_ENTRY CrDemEntryAcquire(PCR_DISPLAY_ENTRY_MAP pMap, GLuint idTexture, uint32_t fFlags); 461 void CrDemEntryRelease(PCR_DISPLAY_ENTRY pEntry); 462 int CrDemEntrySaveState(PCR_DISPLAY_ENTRY pEntry, PSSMHANDLE pSSM); 463 int CrDemEntryLoadState(PCR_DISPLAY_ENTRY_MAP pMap, PCR_DISPLAY_ENTRY *ppEntry, PSSMHANDLE pSSM); 464 465 int crServerDisplaySaveState(PSSMHANDLE pSSM); 466 int crServerDisplayLoadState(PSSMHANDLE pSSM, uint32_t u32Version); 467 468 469 void crServerDEntryResized(CRMuralInfo *pMural, CR_DISPLAY_ENTRY *pDEntry); 470 void crServerDEntryMoved(CRMuralInfo *pMural, CR_DISPLAY_ENTRY *pDEntry); 471 void crServerDEntryVibleRegions(CRMuralInfo *pMural, CR_DISPLAY_ENTRY *pDEntry); 472 void crServerDEntryCheckFBO(CRMuralInfo *pMural, CR_DISPLAY_ENTRY *pDEntry, CRContext *ctx); 473 474 void crServerDEntryAllResized(CRMuralInfo *pMural); 475 void crServerDEntryAllMoved(CRMuralInfo *pMural); 476 void crServerDEntryAllVibleRegions(CRMuralInfo *pMural); 366 /*helper function that calls CrFbUpdateBegin for all enabled framebuffers */ 367 int CrPMgrHlpGlblUpdateBegin(); 368 /*helper function that calls CrFbUpdateEnd for all framebuffers being updated */ 369 void CrPMgrHlpGlblUpdateEnd(); 370 HCR_FRAMEBUFFER CrPMgrFbGetFirstEnabled(); 371 HCR_FRAMEBUFFER CrPMgrFbGetNextEnabled(HCR_FRAMEBUFFER hFb); 372 int CrPMgrModeVrdp(bool fEnable); 373 int CrPMgrModeRootVr(bool fEnable); 374 int CrPMgrRootVrUpdate(); 375 int CrPMgrViewportUpdate(uint32_t idScreen); 376 int CrPMgrScreenChanged(uint32_t idScreen); 377 int CrPMgrNotifyResize(HCR_FRAMEBUFFER hFb); 378 int CrPMgrSaveState(PSSMHANDLE pSSM); 379 int CrPMgrLoadState(PSSMHANDLE pSSM, uint32_t version); 380 HCR_FRAMEBUFFER CrPMgrFbGet(uint32_t idScreen); 381 /*cleanup stuff*/ 382 383 int CrPMgrInit(); 384 void CrPMgrTerm(); 385 386 int CrFbResize(HCR_FRAMEBUFFER hFb, const struct VBVAINFOSCREEN * pScreen, void *pvVRAM); 387 bool CrFbIsEnabled(HCR_FRAMEBUFFER hFb); 388 int CrFbEntryCreateForTexId(HCR_FRAMEBUFFER hFb, GLuint idTex, uint32_t fFlags, HCR_FRAMEBUFFER_ENTRY *phEntry); 389 int CrFbEntryCreateForTexData(HCR_FRAMEBUFFER hFb, struct CR_TEXDATA *pTex, uint32_t fFlags, HCR_FRAMEBUFFER_ENTRY *phEntry); 390 void CrFbEntryAddRef(HCR_FRAMEBUFFER hFb, HCR_FRAMEBUFFER_ENTRY hEntry); 391 void CrFbEntryRelease(HCR_FRAMEBUFFER hFb, HCR_FRAMEBUFFER_ENTRY hEntry); 392 const struct VBVAINFOSCREEN* CrFbGetScreenInfo(HCR_FRAMEBUFFER hFb); 393 const struct VBOXVR_SCR_COMPOSITOR* CrFbGetCompositor(HCR_FRAMEBUFFER hFb); 394 const struct VBOXVR_SCR_COMPOSITOR_ENTRY* CrFbEntryGetCompositorEntry(HCR_FRAMEBUFFER_ENTRY hEntry); 395 396 /* start doing modifications to the framebuffer */ 397 int CrFbUpdateBegin(HCR_FRAMEBUFFER hFb); 398 /*below commands can only be used in Framebuffer update mode, i.e. after the CrFbUpdateBegin succeeded */ 399 int CrFbEntryRegions(HCR_FRAMEBUFFER hFb, HCR_FRAMEBUFFER_ENTRY hEntry); 400 401 /* complete doing modifications to the framebuffer */ 402 void CrFbUpdateEnd(HCR_FRAMEBUFFER hFb); 403 404 int CrFbEntryRegionsAdd(HCR_FRAMEBUFFER hFb, HCR_FRAMEBUFFER_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, bool fPosRelated); 405 int CrFbEntryRegionsSet(HCR_FRAMEBUFFER hFb, HCR_FRAMEBUFFER_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, bool fPosRelated); 406 407 int CrFbEntryTexDataUpdate(HCR_FRAMEBUFFER hFb, HCR_FRAMEBUFFER_ENTRY pEntry, struct CR_TEXDATA *pTex); 408 409 CRHTABLE_HANDLE CrFbDDataAllocSlot(HCR_FRAMEBUFFER hFb); 410 void CrFbDDataReleaseSlot(HCR_FRAMEBUFFER hFb, CRHTABLE_HANDLE hSlot); 411 int CrFbDDataEntryPut(HCR_FRAMEBUFFER_ENTRY hEntry, CRHTABLE_HANDLE hSlot, void *pvData); 412 void* CrFbDDataEntryGet(HCR_FRAMEBUFFER_ENTRY hEntry, CRHTABLE_HANDLE hSlot); 413 414 CR_TEXDATA* CrFbTexDataCreate(const VBOXVR_TEXTURE *pTex); 415 void CrFbTexDataInit(CR_TEXDATA* pFbTex, const VBOXVR_TEXTURE *pTex, PFNCRTEXDATA_RELEASED pfnTextureReleased); 477 416 478 417 //#define VBOX_WITH_CRSERVER_DUMPER -
trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_clear.c
r46368 r50095 444 444 { 445 445 cr_server.head_spu->dispatch_table.SwapBuffers( mural->spuWindow, flags ); 446 if (crServerVBoxCompositionPresentNeeded(mural))447 mural->fDataPresented = GL_TRUE;448 446 } 449 447 … … 464 462 if (crServerIsRedirectedToFBO()) 465 463 crServerPresentFBO(mural); 466 else if (crServerVBoxCompositionPresentNeeded(mural))467 mural->fDataPresented = GL_TRUE;468 464 } 469 465 … … 488 484 if (crServerIsRedirectedToFBO()) 489 485 crServerPresentFBO(mural); 490 else if (crServerVBoxCompositionPresentNeeded(mural))491 mural->fDataPresented = GL_TRUE;492 486 } 493 487 -
trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_config.c
r49591 r50095 52 52 53 53 cr_server.screenCount = 0; 54 cr_server.fPresentMode = CR_SERVER_REDIR_F_NONE;55 cr_server.fPresentModeDefault = cr_server.fPresentMode;56 cr_server.fVramPresentModeDefault = CR_SERVER_REDIR_F_FBO_RAM;57 54 cr_server.bUsePBOForReadback = GL_FALSE; 58 cr_server.bUseOutputRedirect = GL_FALSE;59 55 cr_server.bWindowsInitiallyHidden = GL_FALSE; 60 56 … … 217 213 crSPULoadChain(num_spus, spu_ids, spu_names, spu_dir, &cr_server); 218 214 219 env = crGetenv( "CR_SERVER_DEFAULT_ RENDER_TYPE" );215 env = crGetenv( "CR_SERVER_DEFAULT_VISUAL_BITS" ); 220 216 if (env != NULL && env[0] != '\0') 221 217 { 222 unsigned int redir = (unsigned int)crServerVBoxParseNumerics(env, CR_SERVER_REDIR_F_NONE); 223 if (redir <= CR_SERVER_REDIR_F_ALL) 224 { 225 int rc = crServerSetOffscreenRenderingMode(redir); 226 if (!RT_SUCCESS(rc)) 227 crWarning("offscreen rendering unsupported, no offscreen rendering will be used.."); 228 } 218 unsigned int bits = (unsigned int)crServerVBoxParseNumerics(env, 0); 219 if (bits <= CR_ALL_BITS) 220 cr_server.fVisualBitsDefault = bits; 229 221 else 230 crWarning("invalid redir option %c", redir); 231 } 232 #if defined(RT_OS_DARWIN) || defined(RT_OS_WINDOWS) || defined(GLX) 233 if (cr_server.fPresentMode == CR_SERVER_REDIR_F_NONE) 234 { 235 /* the CR_SERVER_REDIR_F_FBO_BLT is set only if parent window is received, which means we are not in headles */ 236 int rc = crServerSetOffscreenRenderingMode(CR_SERVER_REDIR_F_FBO | CR_SERVER_REDIR_F_DISPLAY); 237 if (!RT_SUCCESS(rc)) 238 crWarning("offscreen rendering unsupported, no offscreen rendering will be used.."); 239 240 } 241 #endif 242 cr_server.fPresentModeDefault = cr_server.fPresentMode; 243 cr_server.fVramPresentModeDefault = CR_SERVER_REDIR_F_FBO_RAM/* | CR_SERVER_REDIR_F_FBO_RPW*/; 222 crWarning("invalid bits option %c", bits); 223 } 224 else 225 cr_server.fVisualBitsDefault = CR_RGB_BIT | CR_ALPHA_BIT | CR_DOUBLE_BIT; 244 226 245 227 env = crGetenv("CR_SERVER_CAPS"); … … 258 240 } 259 241 260 if (!(cr_server.fPresentModeDefault & CR_SERVER_REDIR_F_FBO)) 261 { 262 /* can not do tex present in case CR_SERVER_REDIR_F_FBO is disabled */ 263 cr_server.u32Caps &= ~CR_VBOX_CAP_TEX_PRESENT; 264 } 265 266 crInfo("Cfg: fPresentModeDefault(%#x), fVramPresentModeDefault(%#x), u32Caps(%#x)", 267 cr_server.fPresentModeDefault, cr_server.fVramPresentModeDefault, cr_server.u32Caps); 242 crInfo("Cfg: u32Caps(%#x), fVisualBitsDefault(%#x)", 243 cr_server.u32Caps, 244 cr_server.fVisualBitsDefault); 268 245 269 246 /* Need to do this as early as possible */ … … 385 362 return; 386 363 387 env = crGetenv( "CR_SERVER_DEFAULT_RENDER_TYPE" ); 364 365 env = crGetenv( "CR_SERVER_DEFAULT_VISUAL_BITS" ); 388 366 if (env != NULL && env[0] != '\0') 389 367 { 390 unsigned int redir = (unsigned int)crServerVBoxParseNumerics(env, CR_SERVER_REDIR_F_NONE); 391 if (redir <= CR_SERVER_REDIR_F_ALL) 392 { 393 int rc = crServerSetOffscreenRenderingMode(redir); 394 if (!RT_SUCCESS(rc)) 395 crWarning("offscreen rendering unsupported, no offscreen rendering will be used.."); 396 } 368 unsigned int bits = (unsigned int)crServerVBoxParseNumerics(env, 0); 369 if (bits <= CR_ALL_BITS) 370 cr_server.fVisualBitsDefault = bits; 397 371 else 398 crWarning("invalid redir option %c", redir); 399 } 400 #if defined(RT_OS_DARWIN) || defined(RT_OS_WINDOWS) || defined(GLX) 401 if (cr_server.fPresentMode == CR_SERVER_REDIR_F_NONE) 402 { 403 /* the CR_SERVER_REDIR_F_FBO_BLT is set only if parent window is received, which means we are not in headles */ 404 int rc = crServerSetOffscreenRenderingMode(CR_SERVER_REDIR_F_FBO | CR_SERVER_REDIR_F_DISPLAY); 405 if (!RT_SUCCESS(rc)) 406 crWarning("offscreen rendering unsupported, no offscreen rendering will be used.."); 407 408 } 409 #endif 410 cr_server.fPresentModeDefault = cr_server.fPresentMode; 411 cr_server.fVramPresentModeDefault = CR_SERVER_REDIR_F_FBO_RAM/* | CR_SERVER_REDIR_F_FBO_RPW*/; 372 crWarning("invalid bits option %c", bits); 373 } 374 else 375 cr_server.fVisualBitsDefault = CR_RGB_BIT | CR_ALPHA_BIT | CR_DOUBLE_BIT; 412 376 413 377 env = crGetenv("CR_SERVER_CAPS"); … … 425 389 } 426 390 427 if (!(cr_server.fPresentModeDefault & CR_SERVER_REDIR_F_FBO)) 428 { 429 /* can not do tex present in case CR_SERVER_REDIR_F_FBO is disabled */ 430 cr_server.u32Caps &= ~CR_VBOX_CAP_TEX_PRESENT; 431 } 432 433 crInfo("Cfg: fPresentModeDefault(%#x), fVramPresentModeDefault(%#x), u32Caps(%#x)", 434 cr_server.fPresentModeDefault, cr_server.fVramPresentModeDefault, cr_server.u32Caps); 391 crInfo("Cfg: u32Caps(%#x), fVisualBitsDefault(%#x)", 392 cr_server.u32Caps, 393 cr_server.fVisualBitsDefault); 435 394 436 395 cr_server.head_spu->dispatch_table.GetChromiumParametervCR(GL_WINDOW_POSITION_CR, 0, GL_INT, 2, &dims[0]); -
trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_context.c
r48079 r50095 29 29 30 30 dpyName = ""; 31 if (cr_server.fVisualBitsDefault) 32 visualBits = cr_server.fVisualBitsDefault; 31 33 32 34 if (shareCtx > 0) { … … 301 303 * while crStateSwitchPostprocess restores it back to the original values */ 302 304 oldCtx = crStateGetCurrent(); 303 if (oldMural && (oldMural->fPresentMode & CR_SERVER_REDIR_F_FBO)&& crServerSupportRedirMuralFBO())305 if (oldMural && oldMural->fRedirected && crServerSupportRedirMuralFBO()) 304 306 { 305 307 idDrawFBO = CR_SERVER_FBO_FOR_IDX(oldMural, oldMural->iCurDrawBuffer); … … 383 385 crStateMakeCurrent( ctx ); 384 386 385 if (mural && (mural->fPresentMode & CR_SERVER_REDIR_F_FBO)&& crServerSupportRedirMuralFBO())387 if (mural && mural->fRedirected && crServerSupportRedirMuralFBO()) 386 388 { 387 389 GLuint id = crServerMuralFBOIdxFromBufferName(mural, ctx->buffer.drawBuffer); … … 414 416 cr_server.curClient->currentMural->bFbDraw = GL_TRUE; 415 417 416 if (! (mural->fPresentMode & CR_SERVER_REDIR_F_FBO))418 if (!mural->fRedirected) 417 419 { 418 420 ctx->buffer.width = mural->width; -
trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_lists.c
r50041 r50095 61 61 crServerDispatchNewList( GLuint list, GLenum mode ) 62 62 { 63 Assert(0); 63 64 if (mode == GL_COMPILE_AND_EXECUTE) 64 65 crWarning("using glNewList(GL_COMPILE_AND_EXECUTE) can confuse the crserver"); … … 74 75 CRClient *client = cr_server.curClient; 75 76 CRMuralInfo *mural = client ? client->currentMural : NULL; 76 if (mural && mural->f PresentMode & CR_SERVER_REDIR_F_FBO)77 if (mural && mural->fRedirected) 77 78 { 78 79 fbFbo = mural->aidFBOs[CR_SERVER_FBO_FB_IDX(mural)]; … … 292 293 } 293 294 295 for (i = 0; i < n; ++i) 296 { 297 crDebug("DeleteTexture: %d, pid %d, ctx %d", textures[i], (uint32_t)cr_server.curClient->pid, cr_server.currentCtxInfo->pContext->id); 298 } 299 300 294 301 crStateDeleteTextures(n, textures); 295 302 cr_server.head_spu->dispatch_table.DeleteTextures(n, newTextures); -
trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
r50041 r50095 188 188 crFreeHashtable(cr_server.muralTable, deleteMuralInfoCallback); 189 189 190 crServerDisplayTermAll(); 191 CrDemTerm(&cr_server.PresentTexturepMap); 192 CrDemTeGlobalTerm(); 193 memset(cr_server.DisplaysInitMap, 0, sizeof (cr_server.DisplaysInitMap)); 194 memset(cr_server.aDispplays, 0, sizeof (cr_server.aDispplays)); 190 CrPMgrTerm(); 195 191 196 192 for (i = 0; i < cr_server.numClients; i++) { … … 369 365 cr_server.dummyMuralTable = crAllocHashtable(); 370 366 371 CrDemGlobalInit(); 372 373 CrDemInit(&cr_server.PresentTexturepMap); 374 memset(cr_server.DisplaysInitMap, 0, sizeof (cr_server.DisplaysInitMap)); 375 memset(cr_server.aDispplays, 0, sizeof (cr_server.aDispplays)); 367 CrPMgrInit(); 376 368 377 369 cr_server.fRootVrOn = GL_FALSE; … … 486 478 cr_server.dummyMuralTable = crAllocHashtable(); 487 479 488 CrDemGlobalInit(); 489 490 CrDemInit(&cr_server.PresentTexturepMap); 491 memset(cr_server.DisplaysInitMap, 0, sizeof (cr_server.DisplaysInitMap)); 492 memset(cr_server.aDispplays, 0, sizeof (cr_server.aDispplays)); 480 CrPMgrInit(); 493 481 494 482 cr_server.fRootVrOn = GL_FALSE; … … 1005 993 return NULL; 1006 994 } 1007 id = crServerMuralInit(pMural, "", visualBits, 0 , GL_TRUE);995 id = crServerMuralInit(pMural, "", visualBits, 0); 1008 996 if (id < 0) 1009 997 { … … 1149 1137 1150 1138 pEl = &pData->aElements[pData->cElements]; 1151 pEl->idFBO = pMural && (pMural->fPresentMode & CR_SERVER_REDIR_F_FBO)? pMural->aidFBOs[CR_SERVER_FBO_FB_IDX(pMural)] : 0;1139 pEl->idFBO = pMural && pMural->fRedirected ? pMural->aidFBOs[CR_SERVER_FBO_FB_IDX(pMural)] : 0; 1152 1140 pEl->enmBuffer = pData->aElements[1].idFBO ? GL_COLOR_ATTACHMENT0 : GL_FRONT; 1153 1141 pEl->posX = 0; … … 1176 1164 { 1177 1165 pEl = &pData->aElements[pData->cElements]; 1178 pEl->idFBO = pMural && (pMural->fPresentMode & CR_SERVER_REDIR_F_FBO)? pMural->aidFBOs[CR_SERVER_FBO_BB_IDX(pMural)] : 0;1166 pEl->idFBO = pMural && pMural->fRedirected ? pMural->aidFBOs[CR_SERVER_FBO_BB_IDX(pMural)] : 0; 1179 1167 pEl->enmBuffer = pData->aElements[1].idFBO ? GL_COLOR_ATTACHMENT0 : GL_BACK; 1180 1168 pEl->posX = 0; … … 1206 1194 AssertCompile(sizeof (GLfloat) == 4); 1207 1195 pEl = &pData->aElements[pData->cElements]; 1208 pEl->idFBO = pMural && (pMural->fPresentMode & CR_SERVER_REDIR_F_FBO)? pMural->aidFBOs[CR_SERVER_FBO_FB_IDX(pMural)] : 0;1196 pEl->idFBO = pMural && pMural->fRedirected ? pMural->aidFBOs[CR_SERVER_FBO_FB_IDX(pMural)] : 0; 1209 1197 pEl->enmBuffer = 0; /* we do not care */ 1210 1198 pEl->posX = 0; … … 1237 1225 AssertCompile(sizeof (GLuint) == 4); 1238 1226 pEl = &pData->aElements[pData->cElements]; 1239 pEl->idFBO = pMural && (pMural->fPresentMode & CR_SERVER_REDIR_F_FBO)? pMural->aidFBOs[CR_SERVER_FBO_FB_IDX(pMural)] : 0;1227 pEl->idFBO = pMural && pMural->fRedirected ? pMural->aidFBOs[CR_SERVER_FBO_FB_IDX(pMural)] : 0; 1240 1228 pEl->enmBuffer = 0; /* we do not care */ 1241 1229 pEl->posX = 0; … … 1262 1250 { 1263 1251 pEl = &pData->aElements[pData->cElements]; 1264 pEl->idFBO = pMural && (pMural->fPresentMode & CR_SERVER_REDIR_F_FBO)? pMural->aidFBOs[CR_SERVER_FBO_FB_IDX(pMural)] : 0;1252 pEl->idFBO = pMural && pMural->fRedirected ? pMural->aidFBOs[CR_SERVER_FBO_FB_IDX(pMural)] : 0; 1265 1253 pEl->enmBuffer = 0; /* we do not care */ 1266 1254 pEl->posX = 0; … … 1719 1707 } 1720 1708 1721 rc = crServerDisplaySaveState(pSSM);1709 rc = CrPMgrSaveState(pSSM); 1722 1710 AssertRCReturn(rc, rc); 1723 1711 … … 2137 2125 crFree(muralInfo.pVisibleRects); 2138 2126 } 2139 2140 Assert(!pActualMural->fDataPresented);2141 2142 if (version >= SHCROGL_SSM_VERSION_WITH_PRESENT_STATE)2143 pActualMural->fDataPresented = muralInfo.fDataPresented;2144 else2145 pActualMural->fDataPresented = crServerVBoxCompositionPresentNeeded(pActualMural);2146 2127 } 2147 2128 … … 2231 2212 crVBoxServerFBImageDataTerm(&Data.data); 2232 2213 2233 if ((pMural->fPresentMode & CR_SERVER_REDIR_F_FBO) && pMural->fDataPresented && crServerVBoxCompositionPresentNeeded(pMural)) 2234 { 2235 crServerPresentFBO(pMural); 2236 } 2214 crServerPresentFBO(pMural); 2237 2215 2238 2216 CRASSERT(cr_server.currentMural); … … 2610 2588 if (version >= SHCROGL_SSM_VERSION_WITH_SCREEN_INFO) 2611 2589 { 2612 rc = crServerDisplayLoadState(pSSM, version); 2590 HCR_FRAMEBUFFER hFb; 2591 2592 rc = CrPMgrLoadState(pSSM, version); 2613 2593 AssertRCReturn(rc, rc); 2614 2594 } … … 2682 2662 } 2683 2663 2664 void crServerWindowReparent(CRMuralInfo *pMural) 2665 { 2666 pMural->fHasParentWindow = !!cr_server.screen[pMural->screenId].winID; 2667 2668 renderspuReparentWindow(pMural->spuWindow); 2669 } 2670 2684 2671 static void crVBoxServerReparentMuralCB(unsigned long key, void *data1, void *data2) 2685 2672 { … … 2687 2674 int *sIndex = (int*) data2; 2688 2675 2689 Assert(pMI->cDisabled);2690 2691 2676 if (pMI->screenId == *sIndex) 2692 2677 { 2693 2678 crServerWindowReparent(pMI); 2694 2679 } 2695 }2696 2697 static void crVBoxServerCheckMuralCB(unsigned long key, void *data1, void *data2)2698 {2699 CRMuralInfo *pMI = (CRMuralInfo*) data1;2700 (void) data2;2701 2702 crServerCheckMuralGeometry(pMI);2703 2680 } 2704 2681 … … 2737 2714 if (MAPPED(SCREEN(sIndex))) 2738 2715 { 2739 PCR_DISPLAY pDisplay = crServerDisplayGetInitialized(sIndex);2740 2741 2716 SCREEN(sIndex).winID = 0; 2742 2717 renderspuSetWindowId(0); … … 2746 2721 crHashtableWalk(cr_server.dummyMuralTable, crVBoxServerReparentMuralCB, &sIndex); 2747 2722 2748 if (pDisplay) 2749 CrDpReparent(pDisplay, &SCREEN(sIndex)); 2723 CrPMgrScreenChanged((uint32_t)sIndex); 2750 2724 } 2751 2725 2752 2726 renderspuSetWindowId(SCREEN(0).winID); 2753 2754 crHashtableWalk(cr_server.muralTable, crVBoxServerCheckMuralCB, NULL);2755 2727 2756 2728 /* crVBoxServerNotifyEvent(sIndex, VBOX3D_NOTIFY_EVENT_TYPE_VISIBLE_3DDATA, NULL); */ … … 2783 2755 crHashtableWalk(cr_server.dummyMuralTable, crVBoxServerReparentMuralCB, &sIndex); 2784 2756 renderspuSetWindowId(SCREEN(0).winID); 2785 2786 crHashtableWalk(cr_server.muralTable, crVBoxServerCheckMuralCB, NULL);2787 2757 2788 2758 #ifndef WINDOWS … … 2819 2789 #endif 2820 2790 2821 { 2822 PCR_DISPLAY pDisplay = crServerDisplayGetInitialized(sIndex); 2823 if (pDisplay) 2824 CrDpReparent(pDisplay, &SCREEN(sIndex)); 2825 } 2791 CrPMgrScreenChanged((uint32_t)sIndex); 2826 2792 2827 2793 crVBoxServerNotifyEvent(sIndex, VBOX3D_NOTIFY_EVENT_TYPE_VISIBLE_3DDATA, … … 2831 2797 } 2832 2798 2833 int crVBoxServerUpdateMuralRootVisibleRegion(CRMuralInfo *pMI)2834 {2835 GLboolean fForcePresent;2836 2837 int rc = VINF_SUCCESS;2838 2839 fForcePresent = crServerVBoxCompositionPresentNeeded(pMI);2840 2841 crServerVBoxCompositionDisableEnter(pMI);2842 2843 if (cr_server.fRootVrOn)2844 {2845 if (!pMI->fRootVrOn)2846 {2847 CrVrScrCompositorInit(&pMI->RootVrCompositor);2848 }2849 2850 rc = crServerMuralSynchRootVr(pMI, NULL);2851 if (!RT_SUCCESS(rc))2852 {2853 crWarning("crServerMuralSynchRootVr failed, rc %d", rc);2854 goto end;2855 }2856 }2857 else2858 {2859 CrVrScrCompositorClear(&pMI->RootVrCompositor);2860 }2861 2862 pMI->fRootVrOn = cr_server.fRootVrOn;2863 2864 crServerWindowVisibleRegion(pMI);2865 2866 end:2867 crServerVBoxCompositionDisableLeave(pMI, fForcePresent);2868 2869 return rc;2870 }2871 2872 static void crVBoxServerSetRootVisibleRegionCB(unsigned long key, void *data1, void *data2)2873 {2874 CRMuralInfo *pMI = (CRMuralInfo*) data1;2875 2876 if (!pMI->CreateInfo.externalID)2877 return;2878 (void) data2;2879 2880 crVBoxServerUpdateMuralRootVisibleRegion(pMI);2881 }2882 2883 2799 DECLEXPORT(int32_t) crVBoxServerSetRootVisibleRegion(GLint cRects, const RTRECT *pRects) 2884 2800 { 2885 2801 int32_t rc = VINF_SUCCESS; 2886 int i;2802 GLboolean fOldRootVrOn = cr_server.fRootVrOn; 2887 2803 2888 2804 /* non-zero rects pointer indicate rects are present and switched on … … 2911 2827 } 2912 2828 2913 crHashtableWalk(cr_server.muralTable, crVBoxServerSetRootVisibleRegionCB, NULL); 2914 2915 for (i = 0; i < cr_server.screenCount; ++i) 2916 { 2917 PCR_DISPLAY pDisplay = crServerDisplayGetInitialized((uint32_t)i); 2918 if (!pDisplay) 2919 continue; 2920 2921 CrDpRootUpdate(pDisplay); 2829 if (!fOldRootVrOn != !cr_server.fRootVrOn) 2830 { 2831 rc = CrPMgrModeRootVr(cr_server.fRootVrOn); 2832 if (!RT_SUCCESS(rc)) 2833 { 2834 crWarning("CrPMgrModeRootVr failed rc %d", rc); 2835 return rc; 2836 } 2837 } 2838 else if (cr_server.fRootVrOn) 2839 { 2840 rc = CrPMgrRootVrUpdate(); 2841 if (!RT_SUCCESS(rc)) 2842 { 2843 crWarning("CrPMgrRootVrUpdate failed rc %d", rc); 2844 return rc; 2845 } 2922 2846 } 2923 2847 … … 2930 2854 } 2931 2855 2932 int32_t crServerSetOffscreenRenderingMode(GLuint value)2933 {2934 /* sanitize values */2935 value = crServerRedirModeAdjust(value);2936 2937 if (value == CR_SERVER_REDIR_F_NONE)2938 {2939 crWarning("crServerSetOffscreenRenderingMode: value undefined");2940 }2941 2942 if (cr_server.fPresentMode==value)2943 {2944 return VINF_SUCCESS;2945 }2946 2947 if ((value & CR_SERVER_REDIR_F_FBO) && !crServerSupportRedirMuralFBO())2948 {2949 crWarning("crServerSetOffscreenRenderingMode: FBO not supported");2950 return VERR_NOT_SUPPORTED;2951 }2952 2953 cr_server.fPresentMode=value;2954 2955 crHashtableWalk(cr_server.muralTable, crVBoxServerCheckMuralCB, NULL);2956 2957 return VINF_SUCCESS;2958 }2959 2960 2856 DECLEXPORT(int32_t) crVBoxServerSetOffscreenRendering(GLboolean value) 2961 2857 { 2962 return crServerSetOffscreenRenderingMode(value ? 2963 cr_server.fPresentModeDefault | CR_SERVER_REDIR_F_FBO_RAM_VRDP | cr_server.fVramPresentModeDefault 2964 : cr_server.fPresentModeDefault); 2965 } 2966 2967 static void crVBoxServerOutputRedirectCB(unsigned long key, void *data1, void *data2) 2968 { 2969 CRMuralInfo *mural = (CRMuralInfo*) data1; 2970 2971 if (!mural->CreateInfo.externalID) 2972 return; 2973 2974 if (cr_server.bUseOutputRedirect) 2975 crServerPresentOutputRedirect(mural); 2976 else 2977 crServerOutputRedirectCheckEnableDisable(mural); 2858 return CrPMgrModeVrdp(value); 2978 2859 } 2979 2860 … … 2984 2865 { 2985 2866 cr_server.outputRedirect = *pCallbacks; 2986 cr_server.bUseOutputRedirect = true;2987 2867 } 2988 2868 else 2989 2869 { 2990 cr_server.bUseOutputRedirect = false; 2991 } 2992 2993 /* dynamically intercept already existing output */ 2994 crHashtableWalk(cr_server.muralTable, crVBoxServerOutputRedirectCB, NULL); 2870 memset (&cr_server.outputRedirect, 0, sizeof (cr_server.outputRedirect)); 2871 } 2995 2872 2996 2873 return VINF_SUCCESS; 2997 2874 } 2998 2875 2999 static void crVBoxServerUpdateScreenViewportCB(unsigned long key, void *data1, void *data2)3000 {3001 CRMuralInfo *mural = (CRMuralInfo*) data1;3002 int *sIndex = (int*) data2;3003 3004 if (mural->screenId != *sIndex)3005 return;3006 3007 crServerCheckMuralGeometry(mural);3008 }3009 3010 3011 2876 DECLEXPORT(int32_t) crVBoxServerSetScreenViewport(int sIndex, int32_t x, int32_t y, uint32_t w, uint32_t h) 3012 2877 { 3013 CRScreenViewportInfo *pVieport; 3014 GLboolean fPosChanged, fSizeChanged; 2878 CRScreenViewportInfo *pViewport; 2879 RTRECT NewRect; 2880 GLboolean fChanged; 2881 int rc; 3015 2882 3016 2883 crDebug("crVBoxServerSetScreenViewport(%i)", sIndex); … … 3022 2889 } 3023 2890 3024 pVieport = &cr_server.screenVieport[sIndex]; 3025 fPosChanged = (pVieport->x != x || pVieport->y != y); 3026 fSizeChanged = (pVieport->w != w || pVieport->h != h); 3027 3028 if (!fPosChanged && !fSizeChanged) 2891 NewRect.xLeft = x; 2892 NewRect.yTop = y; 2893 NewRect.xRight = x + w; 2894 NewRect.yBottom = y + h; 2895 2896 pViewport = &cr_server.screenVieport[sIndex]; 2897 2898 fChanged = !!memcmp(&NewRect, &pViewport->Rect, sizeof (NewRect)); 2899 if (!fChanged) 3029 2900 { 3030 2901 crDebug("crVBoxServerSetScreenViewport: no changes"); … … 3032 2903 } 3033 2904 3034 if (fPosChanged) 3035 { 3036 pVieport->x = x; 3037 pVieport->y = y; 3038 3039 crHashtableWalk(cr_server.muralTable, crVBoxServerUpdateScreenViewportCB, &sIndex); 3040 } 3041 3042 if (fSizeChanged) 3043 { 3044 pVieport->w = w; 3045 pVieport->h = h; 3046 3047 /* no need to do anything here actually */ 3048 } 3049 3050 if (fPosChanged || fSizeChanged) 3051 { 3052 PCR_DISPLAY pDisplay = crServerDisplayGetInitialized(sIndex); 3053 if (pDisplay) 3054 CrDpResize(pDisplay, SCREEN(sIndex).x, SCREEN(sIndex).y, SCREEN(sIndex).w, SCREEN(sIndex).h); 3055 } 2905 pViewport->Rect = NewRect; 2906 rc = CrPMgrViewportUpdate((uint32_t)sIndex); 2907 if (!RT_SUCCESS(rc)) 2908 { 2909 crWarning("CrPMgrViewportUpdate failed %d", rc); 2910 return rc; 2911 } 2912 3056 2913 return VINF_SUCCESS; 3057 2914 } … … 3371 3228 } 3372 3229 3373 3374 3230 int32_t crVBoxServerCrHgsmiCmd(struct VBOXVDMACMD_CHROMIUM_CMD *pCmd, uint32_t cbCmd) 3375 3231 { -
trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_misc.c
r50044 r50095 688 688 } 689 689 690 PCR_BLITTER crServerVBoxBlitterGetInitialized() 691 { 692 if (CrBltIsInitialized(&cr_server.Blitter)) 693 return &cr_server.Blitter; 694 return NULL; 695 } 696 697 690 698 int crServerVBoxBlitterTexInit(CRContext *ctx, CRMuralInfo *mural, PVBOXVR_TEXTURE pTex, GLboolean fDraw) 691 699 { … … 702 710 GLuint hwid; 703 711 704 if (! (mural->fPresentMode & CR_SERVER_REDIR_F_FBO))712 if (!mural->fRedirected) 705 713 return VERR_NOT_IMPLEMENTED; 706 714 … … 847 855 crServerVBoxBlitterCtxInit(&Ctx, cr_server.curClient->currentCtxInfo); 848 856 849 CrBltMuralSetCurrent (pBlitter, &BltInfo);857 CrBltMuralSetCurrentInfo(pBlitter, &BltInfo); 850 858 851 859 idDrawFBO = CR_SERVER_FBO_FOR_IDX(mural, mural->iCurDrawBuffer); … … 854 862 crStateSwitchPrepare(NULL, ctx, idDrawFBO, idReadFBO); 855 863 856 rc = CrBltEnter(pBlitter , &Ctx, &BltInfo);864 rc = CrBltEnter(pBlitter); 857 865 if (RT_SUCCESS(rc)) 858 866 { … … 1481 1489 } 1482 1490 1483 rc = CrBltMuralSetCurrent (&cr_server.RecorderBlitter, &BltWin);1491 rc = CrBltMuralSetCurrentInfo(&cr_server.RecorderBlitter, &BltWin); 1484 1492 if (!RT_SUCCESS(rc)) 1485 1493 { 1486 crWarning("CrBltMuralSetCurrent failed rc %d", rc);1494 crWarning("CrBltMuralSetCurrentInfo failed rc %d", rc); 1487 1495 return rc; 1488 1496 } -
trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.cpp
r50078 r50095 23 23 #include "render/renderspu.h" 24 24 25 static int crServerGetPointScreen(GLint x, GLint y) 26 { 27 int i; 28 29 for (i=0; i<cr_server.screenCount; ++i) 30 { 31 if ((x>=cr_server.screen[i].x && x<cr_server.screen[i].x+(int)cr_server.screen[i].w) 32 && (y>=cr_server.screen[i].y && y<cr_server.screen[i].y+(int)cr_server.screen[i].h)) 33 { 34 return i; 35 } 36 } 37 38 return -1; 39 } 40 41 static GLboolean crServerMuralCoverScreen(CRMuralInfo *mural, int sId) 42 { 43 return mural->gX < cr_server.screen[sId].x 44 && mural->gX+(int)mural->width > cr_server.screen[sId].x+(int)cr_server.screen[sId].w 45 && mural->gY < cr_server.screen[sId].y 46 && mural->gY+(int)mural->height > cr_server.screen[sId].y+(int)cr_server.screen[sId].h; 47 } 48 49 void crServerDEntryResized(CRMuralInfo *pMural, CR_DISPLAY_ENTRY *pDEntry) 50 { 51 /*PBO*/ 52 if (pDEntry->idPBO) 53 { 54 CRASSERT(cr_server.bUsePBOForReadback); 55 cr_server.head_spu->dispatch_table.DeleteBuffersARB(1, &pDEntry->idPBO); 56 pDEntry->idPBO = 0; 57 } 58 59 if (pDEntry->idInvertTex) 60 { 61 cr_server.head_spu->dispatch_table.DeleteTextures(1, &pDEntry->idInvertTex); 62 pDEntry->idInvertTex = 0; 63 } 64 65 if (pDEntry->pvORInstance) 66 { 67 cr_server.outputRedirect.CRORGeometry(pDEntry->pvORInstance, 68 pMural->hX + CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->x, 69 pMural->hY + CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->y, 70 CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->width, 71 CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->height); 72 73 crServerDEntryVibleRegions(pMural, pDEntry); 74 } 75 } 76 77 void crServerDEntryMoved(CRMuralInfo *pMural, CR_DISPLAY_ENTRY *pDEntry) 78 { 79 if (pDEntry->pvORInstance) 80 { 81 cr_server.outputRedirect.CRORGeometry(pDEntry->pvORInstance, 82 pMural->hX + CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->x, 83 pMural->hY + CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->y, 84 CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->width, 85 CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->height); 86 87 crServerDEntryVibleRegions(pMural, pDEntry); 88 } 89 90 } 91 92 void crServerDEntryVibleRegions(CRMuralInfo *pMural, CR_DISPLAY_ENTRY *pDEntry) 93 { 94 if (pDEntry->pvORInstance) 95 { 96 uint32_t cRects; 97 const RTRECT *pRects; 98 99 int rc = CrVrScrCompositorEntryRegionsGet(&pMural->Compositor, &pDEntry->CEntry, &cRects, NULL, &pRects, NULL); 100 if (!RT_SUCCESS(rc)) 101 { 102 crWarning("CrVrScrCompositorEntryRegionsGet failed, rc %d", rc); 103 return; 104 } 105 106 cr_server.outputRedirect.CRORVisibleRegion(pDEntry->pvORInstance, cRects, pRects); 107 } 108 } 109 110 /***/ 111 void crServerDEntryAllResized(CRMuralInfo *pMural) 112 { 113 VBOXVR_SCR_COMPOSITOR_ITERATOR Iter; 114 PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry; 115 116 CrVrScrCompositorIterInit(&pMural->Compositor, &Iter); 117 while ((pEntry = CrVrScrCompositorIterNext(&Iter)) != NULL) 118 { 119 CR_DISPLAY_ENTRY *pDEntry = CR_DENTRY_FROM_CENTRY(pEntry); 120 crServerDEntryResized(pMural, pDEntry); 121 } 122 } 123 124 void crServerDEntryAllMoved(CRMuralInfo *pMural) 125 { 126 VBOXVR_SCR_COMPOSITOR_ITERATOR Iter; 127 PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry; 128 129 CrVrScrCompositorIterInit(&pMural->Compositor, &Iter); 130 131 while ((pEntry = CrVrScrCompositorIterNext(&Iter)) != NULL) 132 { 133 CR_DISPLAY_ENTRY *pDEntry = CR_DENTRY_FROM_CENTRY(pEntry); 134 crServerDEntryMoved(pMural, pDEntry); 135 } 136 } 137 138 void crServerDEntryAllVibleRegions(CRMuralInfo *pMural) 139 { 140 VBOXVR_SCR_COMPOSITOR_ITERATOR Iter; 141 PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry; 142 143 CrVrScrCompositorIterInit(&pMural->Compositor, &Iter); 144 145 while ((pEntry = CrVrScrCompositorIterNext(&Iter)) != NULL) 146 { 147 CR_DISPLAY_ENTRY *pDEntry = CR_DENTRY_FROM_CENTRY(pEntry); 148 crServerDEntryVibleRegions(pMural, pDEntry); 149 } 150 } 151 /**/ 152 153 void crServerDEntryCheckFBO(CRMuralInfo *pMural, CR_DISPLAY_ENTRY *pDEntry, CRContext *ctx) 154 { 155 if (!cr_server.bUsePBOForReadback == !pDEntry->idPBO) 156 return; 157 158 if (cr_server.bUsePBOForReadback) 159 { 160 Assert(!pDEntry->idPBO); 161 cr_server.head_spu->dispatch_table.GenBuffersARB(1, &pDEntry->idPBO); 162 cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pDEntry->idPBO); 163 cr_server.head_spu->dispatch_table.BufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, 164 CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->width*CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->height*4, 165 0, GL_STREAM_READ_ARB); 166 cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, ctx->bufferobject.packBuffer->hwid); 167 168 if (!pDEntry->idPBO) 169 { 170 crWarning("PBO create failed"); 171 } 172 } 173 } 174 175 void crServerDEntryCheckInvertTex(CRMuralInfo *pMural, CR_DISPLAY_ENTRY *pDEntry, CRContext *ctx) 176 { 177 CRContextInfo *pMuralContextInfo; 178 179 if (pDEntry->idInvertTex) 180 return; 181 182 pMuralContextInfo = cr_server.currentCtxInfo; 183 if (!pMuralContextInfo) 184 { 185 /* happens on saved state load */ 186 CRASSERT(cr_server.MainContextInfo.SpuContext); 187 pMuralContextInfo = &cr_server.MainContextInfo; 188 cr_server.head_spu->dispatch_table.MakeCurrent(pMural->spuWindow, 0, cr_server.MainContextInfo.SpuContext); 189 } 190 191 if (pMuralContextInfo->CreateInfo.visualBits != pMural->CreateInfo.visualBits) 192 { 193 crWarning("mural visual bits do not match with current context visual bits!"); 194 } 195 196 if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB)) 197 { 198 cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0); 199 } 200 201 cr_server.head_spu->dispatch_table.GenTextures(1, &pDEntry->idInvertTex); 202 CRASSERT(pDEntry->idInvertTex); 203 cr_server.head_spu->dispatch_table.BindTexture(GL_TEXTURE_2D, pDEntry->idInvertTex); 204 cr_server.head_spu->dispatch_table.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 205 cr_server.head_spu->dispatch_table.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 206 cr_server.head_spu->dispatch_table.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); 207 cr_server.head_spu->dispatch_table.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); 208 cr_server.head_spu->dispatch_table.TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 209 CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->width, 210 CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->height, 211 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); 212 213 214 /*Restore gl state*/ 215 cr_server.head_spu->dispatch_table.BindTexture(GL_TEXTURE_2D, 216 ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->hwid); 217 218 if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB)) 219 { 220 cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, ctx->bufferobject.unpackBuffer->hwid); 221 } 222 223 if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB)) 224 { 225 cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, ctx->bufferobject.packBuffer->hwid); 226 } 227 else 228 { 229 cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0); 230 } 231 } 232 233 void crServerDEntryImgRelease(CRMuralInfo *pMural, CR_DISPLAY_ENTRY *pDEntry, void*pvImg) 234 { 235 GLuint idPBO; 236 CRContext *ctx = crStateGetCurrent(); 237 238 idPBO = cr_server.bUsePBOForReadback ? pDEntry->idPBO : 0; 239 240 CrHlpFreeTexImage(ctx, idPBO, pvImg); 241 } 242 243 244 void* crServerDEntryImgAcquire(CRMuralInfo *pMural, CR_DISPLAY_ENTRY *pDEntry, GLenum enmFormat) 245 { 246 void* pvData; 247 GLuint idPBO; 248 VBOXVR_TEXTURE Tex; 249 const VBOXVR_TEXTURE * pTex; 250 CRContext *ctx = crStateGetCurrent(); 251 252 crServerDEntryCheckFBO(pMural, pDEntry, ctx); 253 254 if (cr_server.bUsePBOForReadback && !pDEntry->idPBO) 255 { 256 crWarning("Mural doesn't have PBO even though bUsePBOForReadback is set!"); 257 } 258 259 idPBO = cr_server.bUsePBOForReadback ? pDEntry->idPBO : 0; 260 261 if (!(CrVrScrCompositorEntryFlagsGet(&pDEntry->CEntry) & CRBLT_F_INVERT_SRC_YCOORDS)) 262 pTex = CrVrScrCompositorEntryTexGet(&pDEntry->CEntry); 263 else 264 { 265 CRMuralInfo *pCurrentMural = cr_server.currentMural; 266 CRContextInfo *pCurCtxInfo = cr_server.currentCtxInfo; 267 PCR_BLITTER pBlitter = crServerVBoxBlitterGet(); 268 CRMuralInfo *pBlitterMural; 269 CR_SERVER_CTX_SWITCH CtxSwitch; 270 RTRECT SrcRect, DstRect; 271 CR_BLITTER_WINDOW BlitterBltInfo, CurrentBltInfo; 272 CR_BLITTER_CONTEXT CtxBltInfo; 273 int rc; 274 275 crServerDEntryCheckInvertTex(pMural, pDEntry, ctx); 276 if (!pDEntry->idInvertTex) 277 { 278 crWarning("crServerDEntryCheckInvertTex failed"); 279 return NULL; 280 } 281 282 Tex = *CrVrScrCompositorEntryTexGet(&pDEntry->CEntry); 283 Tex.hwid = pDEntry->idInvertTex; 284 285 SrcRect.xLeft = 0; 286 SrcRect.yTop = Tex.height; 287 SrcRect.xRight = Tex.width; 288 SrcRect.yBottom = 0; 289 290 DstRect.xLeft = 0; 291 DstRect.yTop = 0; 292 DstRect.xRight = Tex.width; 293 DstRect.yBottom = Tex.height; 294 295 if (pCurrentMural && pCurrentMural->CreateInfo.visualBits == CrBltGetVisBits(pBlitter)) 296 { 297 pBlitterMural = pCurrentMural; 298 } 299 else 300 { 301 pBlitterMural = crServerGetDummyMural(pCurrentMural->CreateInfo.visualBits); 302 if (!pBlitterMural) 303 { 304 crWarning("crServerGetDummyMural failed for blitter mural"); 305 return NULL; 306 } 307 } 308 309 crServerCtxSwitchPrepare(&CtxSwitch, NULL); 310 311 crServerVBoxBlitterWinInit(&CurrentBltInfo, pCurrentMural); 312 crServerVBoxBlitterWinInit(&BlitterBltInfo, pBlitterMural); 313 crServerVBoxBlitterCtxInit(&CtxBltInfo, pCurCtxInfo); 314 315 CrBltMuralSetCurrent(pBlitter, &BlitterBltInfo); 316 317 rc = CrBltEnter(pBlitter, &CtxBltInfo, &CurrentBltInfo); 318 if (RT_SUCCESS(rc)) 319 { 320 CrBltBlitTexTex(pBlitter, CrVrScrCompositorEntryTexGet(&pDEntry->CEntry), &SrcRect, &Tex, &DstRect, 1, 0); 321 CrBltLeave(pBlitter); 322 } 323 else 324 { 325 crWarning("CrBltEnter failed rc %d", rc); 326 } 327 328 crServerCtxSwitchPostprocess(&CtxSwitch); 329 330 pTex = &Tex; 331 } 332 333 pvData = CrHlpGetTexImage(ctx, pTex, idPBO, enmFormat); 334 if (!pvData) 335 crWarning("CrHlpGetTexImage failed in crServerPresentFBO"); 336 337 return pvData; 338 } 339 340 341 /* Called when a new CRMuralInfo is created 342 * or when OutputRedirect status is changed. 343 */ 344 void crServerSetupOutputRedirectEntry(CRMuralInfo *mural, CR_DISPLAY_ENTRY *pDEntry) 345 { 346 /* Unset the previous redirect. */ 347 if (pDEntry->pvORInstance) 348 { 349 cr_server.outputRedirect.CROREnd(pDEntry->pvORInstance); 350 pDEntry->pvORInstance = NULL; 351 } 352 353 /* Setup a new redirect. */ 354 if (cr_server.bUseOutputRedirect) 355 { 356 /* Query supported formats. */ 357 uint32_t cbFormats = 4096; 358 char *pachFormats = (char *)crAlloc(cbFormats); 359 360 if (pachFormats) 361 { 362 int rc = cr_server.outputRedirect.CRORContextProperty(cr_server.outputRedirect.pvContext, 363 0 /* H3DOR_PROP_FORMATS */, // @todo from a header 364 pachFormats, cbFormats, &cbFormats); 365 if (RT_SUCCESS(rc)) 366 { 367 if (RTStrStr(pachFormats, "H3DOR_FMT_RGBA_TOPDOWN")) 368 { 369 cr_server.outputRedirect.CRORBegin(cr_server.outputRedirect.pvContext, 370 &pDEntry->pvORInstance, 371 "H3DOR_FMT_RGBA_TOPDOWN"); // @todo from a header 372 } 373 } 374 375 crFree(pachFormats); 376 } 377 378 /* If this is not NULL then there was a supported format. */ 379 if (pDEntry->pvORInstance) 380 { 381 uint32_t cRects; 382 const RTRECT *pRects; 383 384 int rc = CrVrScrCompositorEntryRegionsGet(&mural->Compositor, &pDEntry->CEntry, &cRects, NULL, &pRects, NULL); 385 if (!RT_SUCCESS(rc)) 386 { 387 crWarning("CrVrScrCompositorEntryRegionsGet failed, rc %d", rc); 388 return; 389 } 390 391 cr_server.outputRedirect.CRORGeometry(pDEntry->pvORInstance, 392 mural->hX + CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->x, 393 mural->hY + CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->y, 394 CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->width, 395 CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->height); 396 397 cr_server.outputRedirect.CRORVisibleRegion(pDEntry->pvORInstance, cRects, pRects); 398 //!! 399 // crServerPresentFBO(mural); 400 } 401 } 402 } 25 static void crServerRedirMuralFbSync(CRMuralInfo *mural); 403 26 404 27 void crServerCheckMuralGeometry(CRMuralInfo *mural) 405 28 { 406 int tlS, brS, trS, blS;407 int overlappingScreenCount = 0, primaryS = -1 , i;408 uint64_t winID = 0;409 GLuint fPresentMode;410 411 29 if (!mural->CreateInfo.externalID) 412 30 return; … … 415 33 CRASSERT(mural->spuWindow != CR_RENDER_DEFAULT_WINDOW_ID); 416 34 417 crServerVBoxCompositionDisableEnter(mural); 35 if (!mural->width || !mural->height 36 || mural->fboWidth != mural->width 37 || mural->fboHeight != mural->height) 38 { 39 crServerRedirMuralFbClear(mural); 40 crServerRedirMuralFBO(mural, false); 41 crServerDeleteMuralFBO(mural); 42 } 418 43 419 44 if (!mural->width || !mural->height) 420 {421 crServerRedirMuralFBO(mural, CR_SERVER_REDIR_F_NONE);422 crServerDeleteMuralFBO(mural);423 crServerVBoxCompositionDisableLeave(mural, GL_FALSE);424 45 return; 425 } 426 427 tlS = crServerGetPointScreen(mural->gX, mural->gY); 428 brS = crServerGetPointScreen(mural->gX+mural->width-1, mural->gY+mural->height-1); 429 430 if ((tlS==brS && tlS>=0) || cr_server.screenCount <= 1) 431 { 432 if (cr_server.screenCount <= 1) 433 { 434 if (tlS != brS) 435 { 436 if (tlS >= 0) 437 brS = tlS; 438 else 439 tlS = brS; 440 } 441 442 primaryS = 0; 443 } 444 else 445 { 446 Assert(brS == tlS); 447 448 primaryS = brS; 449 } 450 451 452 Assert(brS == tlS); 453 454 if (tlS>=0 && cr_server.screen[tlS].winID) 455 { 456 overlappingScreenCount = 1; 457 } 458 } 459 else 460 { 461 bool fFoundWindIdScreen = false; 462 trS = crServerGetPointScreen(mural->gX+mural->width-1, mural->gY); 463 blS = crServerGetPointScreen(mural->gX, mural->gY+mural->height-1); 464 465 primaryS = -1; overlappingScreenCount = 0; 466 for (i=0; i<cr_server.screenCount; ++i) 467 { 468 if ((i==tlS) || (i==brS) || (i==trS) || (i==blS) 469 || crServerMuralCoverScreen(mural, i)) 470 { 471 if ((!fFoundWindIdScreen && cr_server.screen[i].winID) || primaryS<0) 472 primaryS = i; 473 474 if (cr_server.screen[i].winID) 475 { 476 overlappingScreenCount++; 477 fFoundWindIdScreen = true; 478 } 479 } 480 } 481 482 if (primaryS<0) 483 { 484 primaryS = 0; 485 } 486 } 487 488 CRASSERT(primaryS >= 0); 489 490 winID = overlappingScreenCount ? cr_server.screen[primaryS].winID : 0; 491 492 if (!winID != !mural->fHasParentWindow 493 || (winID && primaryS!=mural->screenId)) 494 { 495 mural->fHasParentWindow = !!winID; 496 497 renderspuSetWindowId(winID); 498 renderspuReparentWindow(mural->spuWindow); 499 renderspuSetWindowId(cr_server.screen[0].winID); 500 } 501 502 if (primaryS != mural->screenId) 503 { 504 /* mark it invisible on the old screen */ 505 crServerWindowSetIsVisible(mural, GL_FALSE); 506 mural->screenId = primaryS; 507 /* check if mural is visivle on the new screen, and mark it as such */ 508 crServerWindowCheckIsVisible(mural); 509 } 510 511 mural->hX = mural->gX-cr_server.screen[primaryS].x; 512 mural->hY = mural->gY-cr_server.screen[primaryS].y; 513 514 fPresentMode = cr_server.fPresentMode; 515 516 if (!mural->fHasParentWindow) 517 fPresentMode &= ~CR_SERVER_REDIR_F_DISPLAY; 518 519 if (!overlappingScreenCount) 520 fPresentMode &= ~CR_SERVER_REDIR_F_DISPLAY; 521 else if (overlappingScreenCount > 1) 522 fPresentMode = (fPresentMode | CR_SERVER_REDIR_F_FBO_RAM_VMFB | cr_server.fVramPresentModeDefault) & ~CR_SERVER_REDIR_F_DISPLAY; 523 524 if (!mural->fUseDefaultDEntry) 525 { 526 /* only display matters */ 527 fPresentMode &= CR_SERVER_REDIR_F_DISPLAY; 528 } 529 530 fPresentMode = crServerRedirModeAdjust(fPresentMode); 531 532 if (!(fPresentMode & CR_SERVER_REDIR_F_FBO)) 533 { 534 crServerRedirMuralFBO(mural, fPresentMode); 535 crServerDeleteMuralFBO(mural); 536 } 537 else 538 { 539 if (mural->fPresentMode & CR_SERVER_REDIR_F_FBO) 540 { 541 if (mural->width!=mural->fboWidth 542 || mural->height!=mural->fboHeight) 543 { 544 crServerRedirMuralFBO(mural, fPresentMode & CR_SERVER_REDIR_F_DISPLAY); 545 crServerDeleteMuralFBO(mural); 546 } 547 } 548 549 crServerRedirMuralFBO(mural, fPresentMode); 550 } 551 552 if (mural->fPresentMode & CR_SERVER_REDIR_F_DISPLAY) 553 { 554 CRScreenViewportInfo *pVieport = &cr_server.screenVieport[mural->screenId]; 555 556 cr_server.head_spu->dispatch_table.WindowPosition(mural->spuWindow, mural->hX - pVieport->x, mural->hY - pVieport->y); 557 } 558 559 crServerVBoxCompositionDisableLeave(mural, GL_FALSE); 46 47 crServerRedirMuralFBO(mural, true); 48 crServerRedirMuralFbSync(mural); 560 49 } 561 50 … … 576 65 } 577 66 578 static void crServerDentryPresentVRAM(CRMuralInfo *mural, CR_DISPLAY_ENTRY *pDEntry, char *pixels);579 580 #define CR_SERVER_MURAL_FROM_RPW_ENTRY(_pEntry) ((CRMuralInfo*)(((uint8_t*)(_pEntry)) - RT_OFFSETOF(CRMuralInfo, RpwEntry)))581 582 static DECLCALLBACK(void) crServerMuralRpwDataCB(const struct CR_SERVER_RPW_ENTRY* pEntry, void *pvEntryTexData)583 {584 CRMuralInfo *pMural = CR_SERVER_MURAL_FROM_RPW_ENTRY(pEntry);585 586 Assert(&pMural->RpwEntry == pEntry);587 crError("port me!");588 // crServerPresentMuralVRAM(pMural, pvEntryTexData);589 }590 591 67 static void crServerCreateMuralFBO(CRMuralInfo *mural); 592 68 593 static bool crServerEnableMuralRpw(CRMuralInfo *mural, GLboolean fEnable) 594 { 69 void crServerRedirMuralFbClear(CRMuralInfo *mural) 70 { 71 uint32_t i; 72 for (i = 0; i < mural->cUsedFBDatas; ++i) 73 { 74 CR_FBDATA *pData = mural->apUsedFBDatas[i]; 75 int rc = CrFbUpdateBegin(pData->hFb); 76 if (RT_SUCCESS(rc)) 77 { 78 CrFbEntryRegionsSet(pData->hFb, pData->hFbEntry, NULL, 0, NULL, false); 79 CrFbUpdateEnd(pData->hFb); 80 } 81 else 82 WARN(("CrFbUpdateBegin failed rc %d", rc)); 83 } 84 mural->cUsedFBDatas = 0; 85 86 for (i = 0; i < cr_server.screenCount; ++i) 87 { 88 GLuint j; 89 CR_FBDATA *pData = &mural->aFBDatas[i]; 90 if (!pData->hFb) 91 continue; 92 93 CrFbEntryRelease(pData->hFb, pData->hFbEntry); 94 pData->hFbEntry = NULL; 95 96 for (j = 0; j < mural->cBuffers; ++j) 97 { 98 CrTdRelease(pData->apTexDatas[j]); 99 pData->apTexDatas[j] = NULL; 100 } 101 102 pData->hFb = NULL; 103 } 104 } 105 106 static int crServerRedirMuralDbSyncFb(CRMuralInfo *mural, HCR_FRAMEBUFFER hFb, CR_FBDATA **ppData) 107 { 108 CR_FBDATA *pData; 109 const struct VBVAINFOSCREEN* pScreenInfo = CrFbGetScreenInfo(hFb); 110 const struct VBOXVR_SCR_COMPOSITOR* pCompositor = CrFbGetCompositor(hFb); 111 RTRECT FbRect = *CrVrScrCompositorRectGet(pCompositor); 112 RTRECT DefaultRegionsRect; 113 const RTRECT * pRegions; 114 uint32_t cRegions; 115 RTPOINT Pos; 116 RTRECT MuralRect; 117 int rc; 118 119 CRASSERT(mural->fRedirected); 120 121 *ppData = NULL; 122 123 if (!mural->bVisible) 124 return VINF_SUCCESS; 125 126 MuralRect.xLeft = mural->gX; 127 MuralRect.yTop = mural->gY; 128 MuralRect.xRight = MuralRect.xLeft + mural->width; 129 MuralRect.yBottom = MuralRect.yTop + mural->height; 130 131 Pos.x = mural->gX - pScreenInfo->i32OriginX; 132 Pos.y = mural->gY - pScreenInfo->i32OriginY; 133 134 VBoxRectTranslate(&FbRect, pScreenInfo->i32OriginX, pScreenInfo->i32OriginY); 135 136 VBoxRectIntersect(&FbRect, &MuralRect); 137 138 if (VBoxRectIsZero(&FbRect)) 139 return VINF_SUCCESS; 140 141 if (mural->bReceivedRects) 142 { 143 pRegions = (const RTRECT*)mural->pVisibleRects; 144 cRegions = mural->cVisibleRects; 145 } 146 else 147 { 148 DefaultRegionsRect.xLeft = 0; 149 DefaultRegionsRect.yTop = 0; 150 DefaultRegionsRect.xRight = mural->width; 151 DefaultRegionsRect.yBottom = mural->height; 152 pRegions = &DefaultRegionsRect; 153 cRegions = 1; 154 } 155 156 if (!cRegions) 157 return VINF_SUCCESS; 158 159 pData = &mural->aFBDatas[pScreenInfo->u32ViewIndex]; 160 161 if (!pData->hFb) 162 { 163 pData->hFb = hFb; 164 165 for (uint32_t i = 0; i < mural->cBuffers; ++i) 166 { 167 VBOXVR_TEXTURE Tex; 168 int rc; 169 Tex.width = mural->width; 170 Tex.height = mural->height; 171 Tex.hwid = mural->aidColorTexs[i]; 172 Tex.target = GL_TEXTURE_2D; 173 174 pData->apTexDatas[i] = CrFbTexDataCreate(&Tex); 175 } 176 177 rc = CrFbEntryCreateForTexData(hFb, pData->apTexDatas[CR_SERVER_FBO_FB_IDX(mural)], 0, &pData->hFbEntry); 178 if (!RT_SUCCESS(rc)) 179 { 180 WARN(("CrFbEntryCreateForTexData failed rc %d", rc)); 181 } 182 } 183 else 184 { 185 CRASSERT(pData->hFb == hFb); 186 } 187 188 rc = CrFbUpdateBegin(hFb); 189 if (!RT_SUCCESS(rc)) 190 { 191 WARN(("CrFbUpdateBegin failed rc %d", rc)); 192 return rc; 193 } 194 195 rc = CrFbEntryRegionsSet(hFb, pData->hFbEntry, &Pos, cRegions, pRegions, true); 196 if (!RT_SUCCESS(rc)) 197 { 198 WARN(("CrFbEntryRegionsSet failed rc %d", rc)); 199 } 200 201 CrFbUpdateEnd(hFb); 202 203 const struct VBOXVR_SCR_COMPOSITOR_ENTRY* pCEntry = CrFbEntryGetCompositorEntry(pData->hFbEntry); 204 if (CrVrScrCompositorEntryIsUsed(pCEntry)) 205 *ppData = pData; 206 207 return rc; 208 } 209 210 static void crServerRedirMuralFbSync(CRMuralInfo *mural) 211 { 212 uint32_t i; 213 uint32_t cUsedFBs = 0; 214 HCR_FRAMEBUFFER ahUsedFbs[CR_MAX_GUEST_MONITORS]; 215 HCR_FRAMEBUFFER hFb; 216 217 for (i = 0; i < mural->cUsedFBDatas; ++i) 218 { 219 CR_FBDATA *pData = mural->apUsedFBDatas[i]; 220 int rc = CrFbUpdateBegin(pData->hFb); 221 if (RT_SUCCESS(rc)) 222 { 223 ahUsedFbs[cUsedFBs] = pData->hFb; 224 CrFbEntryRegionsSet(pData->hFb, pData->hFbEntry, NULL, 0, NULL, false); 225 ++cUsedFBs; 226 } 227 else 228 WARN(("CrFbUpdateBegin failed rc %d", rc)); 229 } 230 mural->cUsedFBDatas = 0; 231 232 if (!mural->width 233 || !mural->height 234 || !mural->bVisible 235 ) 236 goto end; 237 238 CRASSERT(mural->fRedirected); 239 240 for (hFb = CrPMgrFbGetFirstEnabled(); 241 hFb; 242 hFb = CrPMgrFbGetNextEnabled(hFb)) 243 { 244 CR_FBDATA *pData = NULL; 245 int rc = crServerRedirMuralDbSyncFb(mural, hFb, &pData); 246 if (!RT_SUCCESS(rc)) 247 { 248 WARN(("crServerRedirMuralDbSyncFb failed %d", rc)); 249 continue; 250 } 251 252 if (!pData) 253 continue; 254 255 mural->apUsedFBDatas[mural->cUsedFBDatas] = pData; 256 ++mural->cUsedFBDatas; 257 } 258 259 end: 260 261 for (i = 0; i < cUsedFBs; ++i) 262 { 263 CrFbUpdateEnd(ahUsedFbs[i]); 264 } 265 } 266 267 static void crVBoxServerMuralFbCleanCB(unsigned long key, void *data1, void *data2) 268 { 269 CRMuralInfo *pMI = (CRMuralInfo*) data1; 270 HCR_FRAMEBUFFER hFb = (HCR_FRAMEBUFFER)data2; 271 uint32_t i; 272 for (i = 0; i < pMI->cUsedFBDatas; ++i) 273 { 274 CR_FBDATA *pData = pMI->apUsedFBDatas[i]; 275 if (hFb != pData->hFb) 276 continue; 277 278 CrFbEntryRegionsSet(pData->hFb, pData->hFbEntry, NULL, 0, NULL, false); 279 break; 280 } 281 } 282 283 static void crVBoxServerMuralFbSetCB(unsigned long key, void *data1, void *data2) 284 { 285 CRMuralInfo *pMI = (CRMuralInfo*) data1; 286 HCR_FRAMEBUFFER hFb = (HCR_FRAMEBUFFER)data2; 287 uint32_t i; 288 CR_FBDATA *pData = NULL; 289 bool fFbWasUsed = false; 290 291 Assert(hFb); 292 293 if (!pMI->fRedirected) 294 { 295 Assert(!pMI->cUsedFBDatas); 296 return; 297 } 298 299 for (i = 0; i < pMI->cUsedFBDatas; ++i) 300 { 301 CR_FBDATA *pData = pMI->apUsedFBDatas[i]; 302 if (hFb != pData->hFb) 303 continue; 304 305 fFbWasUsed = true; 306 break; 307 } 308 309 if (CrFbIsEnabled(hFb)) 310 { 311 int rc = crServerRedirMuralDbSyncFb(pMI, hFb, &pData); 312 if (!RT_SUCCESS(rc)) 313 { 314 WARN(("crServerRedirMuralDbSyncFb failed %d", rc)); 315 pData = NULL; 316 } 317 } 318 319 if (pData) 320 { 321 if (!fFbWasUsed) 322 { 323 uint32_t idScreen = CrFbGetScreenInfo(hFb)->u32ViewIndex; 324 for (i = 0; i < pMI->cUsedFBDatas; ++i) 325 { 326 CR_FBDATA *pData = pMI->apUsedFBDatas[i]; 327 uint32_t idCurScreen = CrFbGetScreenInfo(pData->hFb)->u32ViewIndex; 328 if (idCurScreen > idScreen) 329 break; 330 331 Assert(idCurScreen != idScreen); 332 } 333 334 for (int j = pMI->cUsedFBDatas; j > i; --j) 335 { 336 pMI->apUsedFBDatas[j] = pMI->apUsedFBDatas[j-1]; 337 } 338 339 pMI->apUsedFBDatas[i] = pData; 340 ++pMI->cUsedFBDatas; 341 } 342 /* else - nothing to do */ 343 } 344 else 345 { 346 if (fFbWasUsed) 347 { 348 for (int j = i; j < pMI->cUsedFBDatas - 1; ++j) 349 { 350 pMI->apUsedFBDatas[j] = pMI->apUsedFBDatas[j+1]; 351 } 352 --pMI->cUsedFBDatas; 353 } 354 /* else - nothing to do */ 355 } 356 } 357 358 void crVBoxServerMuralFbResizeEnd(HCR_FRAMEBUFFER hFb) 359 { 360 crHashtableWalk(cr_server.muralTable, crVBoxServerMuralFbSetCB, hFb); 361 } 362 363 void crVBoxServerMuralFbResizeBegin(HCR_FRAMEBUFFER hFb) 364 { 365 crHashtableWalk(cr_server.muralTable, crVBoxServerMuralFbCleanCB, hFb); 366 } 367 368 DECLEXPORT(int) crVBoxServerNotifyResize(const struct VBVAINFOSCREEN *pScreen, void *pvVRAM) 369 { 370 int rc; 371 HCR_FRAMEBUFFER hFb = CrPMgrFbGet(pScreen->u32ViewIndex); 372 if (!hFb) 373 { 374 WARN(("CrPMgrFbGet failed")); 375 return VERR_INVALID_PARAMETER; 376 } 377 378 rc = CrFbUpdateBegin(hFb); 379 if (!RT_SUCCESS(rc)) 380 { 381 WARN(("CrFbUpdateBegin failed %d", rc)); 382 return rc; 383 } 384 385 crVBoxServerMuralFbResizeBegin(hFb); 386 387 rc = CrFbResize(hFb, pScreen, pvVRAM); 388 if (!RT_SUCCESS(rc)) 389 { 390 WARN(("CrFbResize failed %d", rc)); 391 } 392 393 crVBoxServerMuralFbResizeEnd(hFb); 394 395 CrFbUpdateEnd(hFb); 396 397 CrPMgrNotifyResize(hFb); 398 399 return rc; 400 } 401 402 void crServerRedirMuralFBO(CRMuralInfo *mural, bool fEnabled) 403 { 404 if (!mural->fRedirected == !fEnabled) 405 { 406 return; 407 } 408 595 409 if (!mural->CreateInfo.externalID) 596 410 { 597 crWarning("trying to change Rpw setting for internal mural %d", mural->spuWindow); 598 return !fEnable; 599 } 600 601 if (fEnable) 602 { 603 if (!(mural->fPresentMode & CR_SERVER_REDIR_F_FBO_RPW)) 604 { 605 int rc; 606 if (!crServerRpwIsInitialized(&cr_server.RpwWorker)) 607 { 608 rc = crServerRpwInit(&cr_server.RpwWorker); 609 if (!RT_SUCCESS(rc)) 610 { 611 crWarning("crServerRpwInit failed rc %d", rc); 612 return false; 613 } 614 } 615 616 CRASSERT(!mural->RpwEntry.Size.cx); 617 CRASSERT(!mural->RpwEntry.Size.cy); 618 619 if (!crServerRpwEntryIsInitialized(&mural->RpwEntry)) 620 { 621 rc = crServerRpwEntryInit(&cr_server.RpwWorker, &mural->RpwEntry, mural->width, mural->height, crServerMuralRpwDataCB); 622 if (!RT_SUCCESS(rc)) 623 { 624 crWarning("crServerRpwEntryInit failed rc %d", rc); 625 return false; 626 } 627 } 628 else 629 { 630 rc = crServerRpwEntryResize(&cr_server.RpwWorker, &mural->RpwEntry, mural->width, mural->height); 631 if (!RT_SUCCESS(rc)) 632 { 633 crWarning("crServerRpwEntryResize failed rc %d", rc); 634 return false; 635 } 636 } 637 638 mural->fPresentMode |= CR_SERVER_REDIR_F_FBO_RPW; 639 } 640 } 641 else 642 { 643 if ((mural->fPresentMode & CR_SERVER_REDIR_F_FBO_RPW)) 644 { 645 // crServerRpwEntryCleanup(&cr_server.RpwWorker, &mural->RpwEntry); 646 mural->fPresentMode &= ~CR_SERVER_REDIR_F_FBO_RPW; 647 } 648 } 649 650 return true; 651 } 652 653 static void crServerEnableDisplayMuralFBO(CRMuralInfo *mural, GLboolean fEnable) 654 { 655 if (!mural->CreateInfo.externalID) 656 { 657 crWarning("trying to change display setting for internal mural %d", mural->spuWindow); 411 WARN(("trying to change redir setting for internal mural %d", mural->spuWindow)); 658 412 return; 659 413 } 660 414 661 if (fEnable) 662 { 663 if (!(mural->fPresentMode & CR_SERVER_REDIR_F_DISPLAY)) 664 { 665 mural->fPresentMode |= CR_SERVER_REDIR_F_DISPLAY; 666 667 if (mural->bVisible) 668 crServerWindowShow(mural); 669 } 670 } 671 else 672 { 673 if ((mural->fPresentMode & CR_SERVER_REDIR_F_DISPLAY)) 674 { 675 mural->fPresentMode &= ~CR_SERVER_REDIR_F_DISPLAY; 676 677 if (mural->bVisible) 678 crServerWindowShow(mural); 679 } 680 } 681 } 682 683 void crServerRedirMuralFBO(CRMuralInfo *mural, GLuint redir) 684 { 685 if (mural->fPresentMode == redir) 686 { 687 // if (redir) 688 // crWarning("crServerRedirMuralFBO called with the same redir status %d", redir); 689 return; 690 } 691 692 if (!mural->CreateInfo.externalID) 693 { 694 crWarning("trying to change redir setting for internal mural %d", mural->spuWindow); 695 return; 696 } 697 698 crServerVBoxCompositionDisableEnter(mural); 699 700 if (redir & CR_SERVER_REDIR_F_FBO) 415 if (fEnabled) 701 416 { 702 417 if (!crServerSupportRedirMuralFBO()) 703 418 { 704 crWarning("FBO not supported, can't redirect window output");705 goto end;706 } 707 708 if (mural-> fUseDefaultDEntry && mural->aidFBOs[0]==0)419 WARN(("FBO not supported, can't redirect window output")); 420 return; 421 } 422 423 if (mural->aidFBOs[0]==0) 709 424 { 710 425 crServerCreateMuralFBO(mural); … … 744 459 } 745 460 746 crServerEnableMuralRpw(mural, !!(redir & CR_SERVER_REDIR_F_FBO_RPW)); 747 748 crServerEnableDisplayMuralFBO(mural, !!(redir & CR_SERVER_REDIR_F_DISPLAY)); 749 750 mural->fPresentMode = redir; 751 752 end: 753 crServerVBoxCompositionDisableLeave(mural, GL_FALSE); 461 mural->fRedirected = !!fEnabled; 754 462 } 755 463 … … 764 472 CRASSERT(mural->aidFBOs[0]==0); 765 473 CRASSERT(mural->aidFBOs[1]==0); 766 CRASSERT(mural->fUseDefaultDEntry);767 CRASSERT(mural->width == mural->DefaultDEntry.CEntry.Tex.width);768 CRASSERT(mural->height == mural->DefaultDEntry.CEntry.Tex.height);769 474 770 475 pMuralContextInfo = cr_server.currentCtxInfo; … … 779 484 if (pMuralContextInfo->CreateInfo.visualBits != mural->CreateInfo.visualBits) 780 485 { 781 crWarning("mural visual bits do not match with current context visual bits!");486 WARN(("mural visual bits do not match with current context visual bits!")); 782 487 } 783 488 … … 825 530 if (status!=GL_FRAMEBUFFER_COMPLETE_EXT) 826 531 { 827 crWarning("FBO status(0x%x) isn't complete", status);532 WARN(("FBO status(0x%x) isn't complete", status)); 828 533 } 829 534 } … … 866 571 867 572 CRASSERT(mural->aidColorTexs[CR_SERVER_FBO_FB_IDX(mural)]); 868 869 CrVrScrCompositorEntryTexNameUpdate(&mural->DefaultDEntry.CEntry, mural->aidColorTexs[CR_SERVER_FBO_FB_IDX(mural)]);870 871 // if (mural->fRootVrOn)872 // CrVrScrCompositorEntryTexNameUpdate(&mural->DefaultDEntry.RootVrCEntry, mural->aidColorTexs[CR_SERVER_FBO_FB_IDX(mural)]);873 573 } 874 574 875 575 void crServerDeleteMuralFBO(CRMuralInfo *mural) 876 576 { 877 CRASSERT(!(mural->fPresentMode & CR_SERVER_REDIR_F_FBO));878 879 577 if (mural->aidFBOs[0]!=0) 880 578 { … … 897 595 898 596 mural->cBuffers = 0; 899 900 if (crServerRpwEntryIsInitialized(&mural->RpwEntry))901 crServerRpwEntryCleanup(&cr_server.RpwWorker, &mural->RpwEntry);902 597 } 903 598 … … 917 612 } 918 613 919 static GLboolean crServerIntersectScreen(CRMuralInfo *mural, CR_DISPLAY_ENTRY *pDEntry, int sId, CRrecti *rect)920 {921 rect->x1 = MAX(mural->gX + CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->x, cr_server.screen[sId].x);922 rect->x2 = MIN(mural->gX + CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->x923 + (int)CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->width,924 cr_server.screen[sId].x+(int)cr_server.screen[sId].w);925 rect->y1 = MAX(mural->gY + CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->y, cr_server.screen[sId].y);926 rect->y2 = MIN(mural->gY + CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->y927 + (int)CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->height,928 cr_server.screen[sId].y+(int)cr_server.screen[sId].h);929 930 return (rect->x2>rect->x1) && (rect->y2>rect->y1);931 }932 933 614 static void crServerCopySubImage(char *pDst, char* pSrc, CRrecti *pRect, int srcWidth, int srcHeight) 934 615 { … … 949 630 } 950 631 951 static void crServerTransformRect(CRrecti *pDst, CRrecti *pSrc, int dx, int dy)952 {953 pDst->x1 = pSrc->x1+dx;954 pDst->x2 = pSrc->x2+dx;955 pDst->y1 = pSrc->y1+dy;956 pDst->y2 = pSrc->y2+dy;957 }958 959 static void crServerVBoxCompositionPresentPerform(CRMuralInfo *mural)960 {961 CRMuralInfo *currentMural = cr_server.currentMural;962 CRContextInfo *curCtxInfo = cr_server.currentCtxInfo;963 GLuint idDrawFBO, idReadFBO;964 CRContext *curCtx = curCtxInfo ? curCtxInfo->pContext : NULL;965 966 CRASSERT(curCtx == crStateGetCurrent());967 968 Assert((mural->fPresentMode & CR_SERVER_REDIR_F_FBO) || !mural->fUseDefaultDEntry);969 Assert(mural->fPresentMode & CR_SERVER_REDIR_F_DISPLAY);970 971 mural->fDataPresented = GL_TRUE;972 973 if (currentMural)974 {975 idDrawFBO = CR_SERVER_FBO_FOR_IDX(currentMural, currentMural->iCurDrawBuffer);976 idReadFBO = CR_SERVER_FBO_FOR_IDX(currentMural, currentMural->iCurReadBuffer);977 }978 else979 {980 idDrawFBO = 0;981 idReadFBO = 0;982 }983 984 crStateSwitchPrepare(NULL, curCtx, idDrawFBO, idReadFBO);985 986 if (!mural->fRootVrOn)987 cr_server.head_spu->dispatch_table.VBoxPresentComposition(mural->spuWindow, &mural->Compositor, NULL);988 else989 cr_server.head_spu->dispatch_table.VBoxPresentComposition(mural->spuWindow, &mural->RootVrCompositor, NULL);990 991 crStateSwitchPostprocess(curCtx, NULL, idDrawFBO, idReadFBO);992 }993 994 void crServerVBoxCompositionPresent(CRMuralInfo *mural)995 {996 if (!crServerVBoxCompositionPresentNeeded(mural))997 return;998 crServerVBoxCompositionPresentPerform(mural);999 }1000 1001 static void crServerVBoxCompositionReenable(CRMuralInfo *mural)1002 {1003 GLboolean fForcePresent = mural->fForcePresentState;1004 GLboolean fOrPresentOnReenable = mural->fOrPresentOnReenable;1005 1006 mural->fForcePresentState = GL_FALSE;1007 mural->fOrPresentOnReenable = GL_FALSE;1008 1009 if ((mural->fUseDefaultDEntry && !(mural->fPresentMode & CR_SERVER_REDIR_F_FBO))1010 || !mural->fDataPresented1011 || (!fForcePresent1012 && !crServerVBoxCompositionPresentNeeded(mural)))1013 return;1014 1015 if (mural->fPresentMode & CR_SERVER_REDIR_F_DISPLAY)1016 crServerVBoxCompositionPresentPerform(mural);1017 1018 if (fOrPresentOnReenable1019 && cr_server.bUseOutputRedirect1020 && crServerVBoxCompositionPresentNeeded(mural))1021 crServerPresentOutputRedirect(mural);1022 }1023 1024 static void crServerVBoxCompositionDisable(CRMuralInfo *mural)1025 {1026 if (!(mural->fPresentMode & CR_SERVER_REDIR_F_DISPLAY)1027 || (mural->fUseDefaultDEntry && !(mural->fPresentMode & CR_SERVER_REDIR_F_FBO))1028 || !mural->fDataPresented)1029 return;1030 cr_server.head_spu->dispatch_table.VBoxPresentComposition(mural->spuWindow, NULL, NULL);1031 }1032 1033 void crServerVBoxCompositionDisableEnter(CRMuralInfo *mural)1034 {1035 ++cr_server.cDisableEvents;1036 Assert(cr_server.cDisableEvents);1037 1038 ++mural->cDisabled;1039 Assert(mural->cDisabled);1040 if (mural->cDisabled == 1)1041 {1042 crServerVBoxCompositionDisable(mural);1043 }1044 }1045 1046 void crServerVBoxCompositionDisableLeave(CRMuralInfo *mural, GLboolean fForcePresentOnEnabled)1047 {1048 mural->fForcePresentState |= fForcePresentOnEnabled;1049 --mural->cDisabled;1050 Assert(mural->cDisabled < UINT32_MAX/2);1051 if (!mural->cDisabled)1052 {1053 crServerVBoxCompositionReenable(mural);1054 }1055 1056 --cr_server.cDisableEvents;1057 Assert(cr_server.cDisableEvents < UINT32_MAX/2);1058 crVBoxServerCheckVisibilityEvent(-1);1059 }1060 1061 static void crServerVBoxCompositionSetEnableStateGlobalCB(unsigned long key, void *data1, void *data2)1062 {1063 CRMuralInfo *mural = (CRMuralInfo *)data1;1064 1065 if (data2)1066 crServerVBoxCompositionDisableLeave(mural, GL_FALSE);1067 else1068 crServerVBoxCompositionDisableEnter(mural);1069 }1070 1071 632 DECLEXPORT(void) crServerVBoxCompositionSetEnableStateGlobal(GLboolean fEnable) 1072 633 { 1073 int i; 1074 1075 crHashtableWalk(cr_server.muralTable, crServerVBoxCompositionSetEnableStateGlobalCB, (void*)(uintptr_t)fEnable); 1076 1077 crHashtableWalk(cr_server.dummyMuralTable, crServerVBoxCompositionSetEnableStateGlobalCB, (void*)(uintptr_t)fEnable);1078 1079 for (i = 0; i < cr_server.screenCount; ++i)1080 {1081 PCR_DISPLAY pDisplay = crServerDisplayGetInitialized((uint32_t)i);1082 if ( !pDisplay)1083 continue;1084 1085 if (!fEnable)1086 CrDpEnter(pDisplay);634 } 635 636 void crServerPresentFBO(CRMuralInfo *mural) 637 { 638 uint32_t i; 639 for (i = 0; i < mural->cUsedFBDatas; ++i) 640 { 641 CR_FBDATA *pData = mural->apUsedFBDatas[i]; 642 int rc = CrFbUpdateBegin(pData->hFb); 643 if (RT_SUCCESS(rc)) 644 { 645 CrFbEntryTexDataUpdate(pData->hFb, pData->hFbEntry, pData->apTexDatas[CR_SERVER_FBO_FB_IDX(mural)]); 646 CrFbUpdateEnd(pData->hFb); 647 } 1087 648 else 1088 CrDpLeave(pDisplay); 1089 } 1090 } 1091 1092 static void crServerDentryPresentVRAM(CRMuralInfo *mural, CR_DISPLAY_ENTRY *pDEntry, char *pixels) 1093 { 1094 char *tmppixels; 1095 CRrecti rect, rectwr, sectr; 1096 int i, rc; 1097 uint32_t j; 1098 1099 if (mural->fPresentMode & CR_SERVER_REDIR_F_FBO_RAM_VMFB) 1100 { 1101 for (i=0; i<cr_server.screenCount; ++i) 1102 { 1103 if (crServerIntersectScreen(mural, pDEntry, i, &rect)) 1104 { 1105 uint32_t cRects; 1106 const RTRECT *pRects; 1107 1108 /* rect in window relative coords */ 1109 crServerTransformRect(&rectwr, &rect, -mural->gX, -mural->gY); 1110 1111 rc = CrVrScrCompositorEntryRegionsGet(&mural->Compositor, &pDEntry->CEntry, &cRects, NULL, &pRects, NULL); 1112 if (RT_SUCCESS(rc)) 1113 { 1114 /*we don't get any rects info for guest compiz windows, so we treat windows as visible unless explicitly received 0 visible rects*/ 1115 for (j=0; j<cRects; ++j) 1116 { 1117 if (crServerIntersectRect(&rectwr, (CRrecti*)&pRects[j], §r)) 1118 { 1119 tmppixels = crAlloc(4*(sectr.x2-sectr.x1)*(sectr.y2-sectr.y1)); 1120 if (!tmppixels) 1121 { 1122 crWarning("Out of memory in crServerPresentFBO"); 1123 crFree(pixels); 1124 return; 1125 } 1126 1127 crServerCopySubImage(tmppixels, pixels, §r, CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->width, CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->height); 1128 /*Note: pfnPresentFBO would free tmppixels*/ 1129 cr_server.pfnPresentFBO(tmppixels, i, 1130 sectr.x1+mural->gX+CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->x-cr_server.screen[i].x, 1131 sectr.y1+mural->gY+CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->y-cr_server.screen[i].y, 1132 sectr.x2-sectr.x1, sectr.y2-sectr.y1); 1133 } 1134 } 1135 } 1136 else 1137 { 1138 crWarning("CrVrScrCompositorEntryRegionsGet failed, rc %d", rc); 1139 } 1140 } 1141 } 1142 } 1143 1144 if (pDEntry->pvORInstance) 1145 { 1146 /* @todo find out why presentfbo is not called but crorframe is called. */ 1147 cr_server.outputRedirect.CRORFrame(pDEntry->pvORInstance, 1148 pixels, 1149 4 * CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->width * CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->height); 1150 } 1151 } 1152 1153 void crServerPresentOutputRedirectEntry(CRMuralInfo *pMural, CR_DISPLAY_ENTRY *pDEntry) 1154 { 1155 char *pixels=NULL; 1156 1157 if (!pDEntry->pvORInstance) 1158 { 1159 crServerSetupOutputRedirectEntry(pMural, pDEntry); 1160 if (!pDEntry->pvORInstance) 1161 { 1162 crWarning("crServerSetupOutputRedirectEntry failed!"); 1163 return; 1164 } 1165 } 1166 1167 if (pMural->fPresentMode & CR_SERVER_REDIR_F_FBO_RPW) 1168 { 1169 crError("port me!"); 1170 #if 0 1171 /* 1. blit to RPW entry draw texture */ 1172 CRMuralInfo *pCurrentMural = cr_server.currentMural; 1173 CRContextInfo *pCurCtxInfo = cr_server.currentCtxInfo; 1174 PCR_BLITTER pBlitter = crServerVBoxBlitterGet(); 1175 CRMuralInfo *pBlitterMural; 1176 CR_SERVER_CTX_SWITCH CtxSwitch; 1177 RTRECT Rect; 1178 VBOXVR_TEXTURE DstTex; 1179 CR_BLITTER_WINDOW BlitterBltInfo, CurrentBltInfo; 1180 CR_BLITTER_CONTEXT CtxBltInfo; 1181 int rc; 1182 1183 Rect.xLeft = 0; 1184 Rect.yTop = 0; 1185 Rect.xRight = Tex.width; 1186 Rect.yBottom = Tex.height; 1187 1188 if (pCurrentMural && pCurrentMural->CreateInfo.visualBits == CrBltGetVisBits(pBlitter)) 1189 { 1190 pBlitterMural = pCurrentMural; 1191 } 1192 else 1193 { 1194 pBlitterMural = crServerGetDummyMural(pCurrentMural->CreateInfo.visualBits); 1195 if (!pBlitterMural) 1196 { 1197 crWarning("crServerGetDummyMural failed for blitter mural"); 1198 return; 1199 } 1200 } 1201 1202 crServerRpwEntryDrawSettingsToTex(&mural->RpwEntry, &DstTex); 1203 1204 crServerCtxSwitchPrepare(&CtxSwitch, NULL); 1205 1206 crServerVBoxBlitterWinInit(&CurrentBltInfo, pCurrentMural); 1207 crServerVBoxBlitterWinInit(&BlitterBltInfo, pBlitterMural); 1208 crServerVBoxBlitterCtxInit(&CtxBltInfo, pCurCtxInfo); 1209 1210 CrBltMuralSetCurrent(pBlitter, &BlitterBltInfo); 1211 1212 rc = CrBltEnter(pBlitter, &CtxBltInfo, &CurrentBltInfo); 1213 if (RT_SUCCESS(rc)) 1214 { 1215 CrBltBlitTexTex(pBlitter, &Tex, &Rect, &DstTex, &Rect, 1, 0); 1216 CrBltLeave(pBlitter); 1217 } 1218 else 1219 { 1220 crWarning("CrBltEnter failed rc %d", rc); 1221 } 1222 1223 crServerCtxSwitchPostprocess(&CtxSwitch); 1224 1225 #if 1 1226 if (RT_SUCCESS(rc)) 1227 { 1228 /* 2. submit RPW entry */ 1229 rc = crServerRpwEntrySubmit(&cr_server.RpwWorker, &mural->RpwEntry); 1230 if (!RT_SUCCESS(rc)) 1231 { 1232 crWarning("crServerRpwEntrySubmit failed rc %d", rc); 1233 } 1234 } 1235 #endif 1236 #endif 1237 return; 1238 } 1239 1240 pixels = crServerDEntryImgAcquire(pMural, pDEntry, GL_BGRA); 1241 if (!pixels) 1242 { 1243 crWarning("CrHlpGetTexImage failed in crServerPresentFBO"); 1244 return; 1245 } 1246 1247 crServerDentryPresentVRAM(pMural, pDEntry, pixels); 1248 1249 crServerDEntryImgRelease(pMural, pDEntry, pixels); 1250 } 1251 1252 void crServerPresentOutputRedirect(CRMuralInfo *pMural) 1253 { 1254 VBOXVR_SCR_COMPOSITOR_ITERATOR Iter; 1255 PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry; 1256 1257 CrVrScrCompositorIterInit(&pMural->Compositor, &Iter); 1258 1259 while ((pEntry = CrVrScrCompositorIterNext(&Iter)) != NULL) 1260 { 1261 CR_DISPLAY_ENTRY *pDEntry = CR_DENTRY_FROM_CENTRY(pEntry); 1262 crServerPresentOutputRedirectEntry(pMural, pDEntry); 1263 } 1264 } 1265 1266 void crServerOutputRedirectCheckEnableDisable(CRMuralInfo *pMural) 1267 { 1268 VBOXVR_SCR_COMPOSITOR_ITERATOR Iter; 1269 PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry; 1270 1271 CrVrScrCompositorIterInit(&pMural->Compositor, &Iter); 1272 1273 while ((pEntry = CrVrScrCompositorIterNext(&Iter)) != NULL) 1274 { 1275 CR_DISPLAY_ENTRY *pDEntry = CR_DENTRY_FROM_CENTRY(pEntry); 1276 crServerSetupOutputRedirectEntry(pMural, pDEntry); 1277 } 1278 } 1279 1280 void crServerPresentFBO(CRMuralInfo *mural) 1281 { 1282 CRASSERT(mural->fPresentMode & CR_SERVER_REDIR_F_FBO); 1283 CRASSERT(cr_server.pfnPresentFBO || (mural->fPresentMode & CR_SERVER_REDIR_F_DISPLAY)); 1284 1285 if (!crServerVBoxCompositionPresentNeeded(mural)) 1286 return; 1287 1288 mural->fDataPresented = GL_TRUE; 1289 1290 if (mural->fPresentMode & CR_SERVER_REDIR_F_DISPLAY) 1291 crServerVBoxCompositionPresentPerform(mural); 1292 1293 if (mural->fPresentMode & CR_SERVER_REDIR_FGROUP_REQUIRE_FBO_RAM) 1294 crServerPresentOutputRedirect(mural); 649 WARN(("CrFbUpdateBegin failed rc %d", rc)); 650 } 1295 651 } 1296 652 … … 1307 663 return cr_server.curClient 1308 664 && cr_server.curClient->currentMural 1309 && (cr_server.curClient->currentMural->fPresentMode & CR_SERVER_REDIR_F_FBO);665 && cr_server.curClient->currentMural->fRedirected; 1310 666 } 1311 667 … … 1332 688 return -1; 1333 689 default: 1334 crWarning("crServerMuralFBOIdxFromBufferName: invalid buffer passed 0x%x", buffer);690 WARN(("crServerMuralFBOIdxFromBufferName: invalid buffer passed 0x%x", buffer)); 1335 691 return -2; 1336 692 } … … 1358 714 } 1359 715 Assert(mural->aidColorTexs[CR_SERVER_FBO_FB_IDX(mural)]); 1360 Assert(mural->fUseDefaultDEntry); 1361 CrVrScrCompositorEntryTexNameUpdate(&mural->DefaultDEntry.CEntry, mural->aidColorTexs[CR_SERVER_FBO_FB_IDX(mural)]); 1362 if (mural->fRootVrOn) 1363 CrVrScrCompositorEntryTexNameUpdate(&mural->DefaultDEntry.RootVrCEntry, mural->aidColorTexs[CR_SERVER_FBO_FB_IDX(mural)]); 1364 } 716 } -
trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp
r49448 r50095 26 26 #include "cr_string.h" 27 27 #include <cr_vreg.h> 28 #include <cr_htable.h> 28 29 29 30 #include <iprt/cdefs.h> … … 32 33 #include <iprt/mem.h> 33 34 #include <iprt/list.h> 34 #include <iprt/memcache.h> 35 36 37 #ifdef DEBUG_misha 38 # define VBOXVDBG_MEMCACHE_DISABLE 39 #endif 40 41 #ifndef VBOXVDBG_MEMCACHE_DISABLE 42 # include <iprt/memcache.h> 43 #endif 35 44 36 45 #include "render/renderspu.h" 37 46 38 /* DISPLAY */ 39 40 int CrDpInit(PCR_DISPLAY pDisplay) 41 { 42 const GLint visBits = cr_server.MainContextInfo.CreateInfo.visualBits; 43 if (crServerMuralInit(&pDisplay->Mural, "", visBits, -1, GL_FALSE) < 0) 44 { 45 crWarning("crServerMuralInit failed!"); 46 return VERR_GENERAL_FAILURE; 47 } 48 49 crServerWindowVisibleRegion(&pDisplay->Mural); 50 crServerDEntryAllVibleRegions(&pDisplay->Mural); 51 52 crServerMuralShow(&pDisplay->Mural, GL_TRUE); 53 54 pDisplay->fForcePresent = GL_FALSE; 47 class ICrFbDisplay 48 { 49 public: 50 virtual int UpdateBegin(struct CR_FRAMEBUFFER *pFb) = 0; 51 virtual void UpdateEnd(struct CR_FRAMEBUFFER *pFb) = 0; 52 53 virtual int EntryCreated(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) = 0; 54 virtual int EntryAdded(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) = 0; 55 virtual int EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry) = 0; 56 virtual int EntryTexChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) = 0; 57 virtual int EntryRemoved(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) = 0; 58 virtual int EntryDestroyed(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) = 0; 59 virtual int EntryPosChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) = 0; 60 61 virtual int RegionsChanged(struct CR_FRAMEBUFFER *pFb) = 0; 62 63 virtual int FramebufferChanged(struct CR_FRAMEBUFFER *pFb) = 0; 64 65 virtual ~ICrFbDisplay() {} 66 }; 67 68 class CrFbDisplayComposite; 69 class CrFbDisplayBase; 70 class CrFbDisplayWindow; 71 class CrFbDisplayWindowRootVr; 72 class CrFbDisplayVrdp; 73 74 typedef struct CR_FRAMEBUFFER 75 { 76 VBOXVR_SCR_COMPOSITOR Compositor; 77 struct VBVAINFOSCREEN ScreenInfo; 78 void *pvVram; 79 ICrFbDisplay *pDisplay; 80 CRHTABLE SlotTable; 81 uint32_t cUpdating; 82 } CR_FRAMEBUFFER; 83 84 typedef struct CR_FBDISPLAY_INFO 85 { 86 uint32_t u32Mode; 87 CrFbDisplayWindow *pDpWin; 88 CrFbDisplayWindowRootVr *pDpWinRootVr; 89 CrFbDisplayVrdp *pDpVrdp; 90 CrFbDisplayComposite *pDpComposite; 91 } CR_FBDISPLAY_INFO; 92 93 typedef struct CR_PRESENTER_GLOBALS 94 { 95 #ifndef VBOXVDBG_MEMCACHE_DISABLE 96 RTMEMCACHE FbEntryLookasideList; 97 RTMEMCACHE FbTexLookasideList; 98 RTMEMCACHE CEntryLookasideList; 99 #endif 100 uint32_t u32DisplayMode; 101 CRHashTable *pFbTexMap; 102 CR_FBDISPLAY_INFO aDisplayInfos[CR_MAX_GUEST_MONITORS]; 103 uint8_t aFramebufferInitMap[(CR_MAX_GUEST_MONITORS+7)/8]; 104 CR_FRAMEBUFFER aFramebuffers[CR_MAX_GUEST_MONITORS]; 105 } CR_PRESENTER_GLOBALS; 106 107 static CR_PRESENTER_GLOBALS g_CrPresenter; 108 109 /* FRAMEBUFFER */ 110 111 void CrFbInit(CR_FRAMEBUFFER *pFb, uint32_t idScreen) 112 { 113 RTRECT Rect; 114 Rect.xLeft = 0; 115 Rect.yTop = 0; 116 Rect.xRight = 1; 117 Rect.yBottom = 1; 118 memset(pFb, 0, sizeof (*pFb)); 119 pFb->ScreenInfo.u16Flags = VBVA_SCREEN_F_DISABLED; 120 pFb->ScreenInfo.u32ViewIndex = idScreen; 121 CrVrScrCompositorInit(&pFb->Compositor, &Rect); 122 CrHTableCreate(&pFb->SlotTable, 0); 123 } 124 125 bool CrFbIsEnabled(CR_FRAMEBUFFER *pFb) 126 { 127 return !(pFb->ScreenInfo.u16Flags & VBVA_SCREEN_F_DISABLED); 128 } 129 130 HCR_FRAMEBUFFER_ENTRY CrFbEntryFromCompositorEntry(const struct VBOXVR_SCR_COMPOSITOR_ENTRY* pCEntry); 131 132 const struct VBOXVR_SCR_COMPOSITOR* CrFbGetCompositor(CR_FRAMEBUFFER *pFb) 133 { 134 return &pFb->Compositor; 135 } 136 137 DECLINLINE(CR_FRAMEBUFFER*) CrFbFromCompositor(const struct VBOXVR_SCR_COMPOSITOR* pCompositor) 138 { 139 return RT_FROM_MEMBER(pCompositor, CR_FRAMEBUFFER, Compositor); 140 } 141 142 const struct VBVAINFOSCREEN* CrFbGetScreenInfo(HCR_FRAMEBUFFER hFb) 143 { 144 return &hFb->ScreenInfo; 145 } 146 147 148 int CrFbUpdateBegin(CR_FRAMEBUFFER *pFb) 149 { 150 ++pFb->cUpdating; 151 152 if (pFb->cUpdating == 1) 153 { 154 if (pFb->pDisplay) 155 pFb->pDisplay->UpdateBegin(pFb); 156 } 157 55 158 return VINF_SUCCESS; 56 159 } 57 160 58 void CrDpTerm(PCR_DISPLAY pDisplay) 59 { 60 crServerMuralTerm(&pDisplay->Mural); 61 } 62 63 void CrDpResize(PCR_DISPLAY pDisplay, int32_t xPos, int32_t yPos, uint32_t width, uint32_t height) 64 { 65 if (xPos != pDisplay->Mural.gX 66 || yPos != pDisplay->Mural.gY 67 || width != pDisplay->Mural.width 68 || height != pDisplay->Mural.height) 69 { 70 crServerMuralPosition(&pDisplay->Mural, xPos, yPos, GL_TRUE); 71 if (!crServerMuralSize(&pDisplay->Mural, width, height)) 72 crServerCheckMuralGeometry(&pDisplay->Mural); 161 void CrFbUpdateEnd(CR_FRAMEBUFFER *pFb) 162 { 163 if (!pFb->cUpdating) 164 { 165 WARN(("invalid UpdateEnd call!")); 166 return; 167 } 168 169 --pFb->cUpdating; 170 171 if (!pFb->cUpdating) 172 { 173 if (pFb->pDisplay) 174 pFb->pDisplay->UpdateEnd(pFb); 175 } 176 } 177 178 bool CrFbIsUpdating(const CR_FRAMEBUFFER *pFb) 179 { 180 return !!pFb->cUpdating; 181 } 182 183 int CrFbResize(CR_FRAMEBUFFER *pFb, const struct VBVAINFOSCREEN * pScreen, void *pvVRAM) 184 { 185 if (!pFb->cUpdating) 186 { 187 WARN(("no update in progress")); 188 return VERR_INVALID_STATE; 189 } 190 RTRECT Rect; 191 Rect.xLeft = 0; 192 Rect.yTop = 0; 193 Rect.xRight = pScreen->u32Width; 194 Rect.yBottom = pScreen->u32Height; 195 int rc = CrVrScrCompositorRectSet(&pFb->Compositor, &Rect, NULL); 196 if (!RT_SUCCESS(rc)) 197 { 198 WARN(("CrVrScrCompositorRectSet failed rc %d", rc)); 199 return rc; 200 } 201 202 pFb->ScreenInfo = *pScreen; 203 pFb->pvVram = pvVRAM; 204 205 if (pFb->pDisplay) 206 pFb->pDisplay->FramebufferChanged(pFb); 207 return VINF_SUCCESS; 208 } 209 210 void CrFbTerm(CR_FRAMEBUFFER *pFb) 211 { 212 if (pFb->cUpdating) 213 { 214 WARN(("update in progress")); 215 return; 216 } 217 CrVrScrCompositorClear(&pFb->Compositor); 218 CrHTableDestroy(&pFb->SlotTable); 219 memset(pFb, 0, sizeof (*pFb)); 220 } 221 222 ICrFbDisplay* CrFbDisplayGet(CR_FRAMEBUFFER *pFb) 223 { 224 return pFb->pDisplay; 225 } 226 227 int CrFbDisplaySet(CR_FRAMEBUFFER *pFb, ICrFbDisplay *pDisplay) 228 { 229 if (pFb->cUpdating) 230 { 231 WARN(("update in progress")); 232 return VERR_INVALID_STATE; 233 } 234 235 if (pFb->pDisplay == pDisplay) 236 return VINF_SUCCESS; 237 238 CrHTableEmpty(&pFb->SlotTable); 239 240 pFb->pDisplay = pDisplay; 241 242 return VINF_SUCCESS; 243 } 244 245 typedef union CR_FBENTRY_FLAGS 246 { 247 struct { 248 uint32_t fCreateNotified : 1; 249 uint32_t Reserved : 31; 250 }; 251 uint32_t Value; 252 } CR_FBENTRY_FLAGS; 253 254 typedef struct CR_FRAMEBUFFER_ENTRY 255 { 256 VBOXVR_SCR_COMPOSITOR_ENTRY Entry; 257 uint32_t cRefs; 258 CR_FBENTRY_FLAGS Flags; 259 CRHTABLE HTable; 260 } CR_FRAMEBUFFER_ENTRY; 261 262 typedef struct CR_FBTEX 263 { 264 CR_TEXDATA Tex; 265 CRTextureObj *pTobj; 266 } CR_FBTEX; 267 268 #define PCR_FBTEX_FROM_TEX(_pTex) ((CR_FBTEX*)((uint8_t*)(_pTex) - RT_OFFSETOF(CR_FBTEX, Tex))) 269 #define PCR_FRAMEBUFFER_FROM_COMPOSITOR(_pCompositor) ((CR_FRAMEBUFFER*)((uint8_t*)(_pCompositor) - RT_OFFSETOF(CR_FRAMEBUFFER, Compositor))) 270 #define PCR_FBENTRY_FROM_ENTRY(_pEntry) ((CR_FRAMEBUFFER_ENTRY*)((uint8_t*)(_pEntry) - RT_OFFSETOF(CR_FRAMEBUFFER_ENTRY, Entry))) 271 272 #define CR_PMGR_MODE_WINDOW 0x1 273 /* CR_PMGR_MODE_WINDOW gets automatically set with it */ 274 #define CR_PMGR_MODE_ROOTVR 0x2 275 #define CR_PMGR_MODE_VRDP 0x4 276 #define CR_PMGR_MODE_ALL 0x7 277 278 static int crPMgrModeModifyGlobal(uint32_t u32Mode, bool fEnable); 279 280 int CrPMgrInit() 281 { 282 int rc = VINF_SUCCESS; 283 memset(&g_CrPresenter, 0, sizeof (g_CrPresenter)); 284 g_CrPresenter.pFbTexMap = crAllocHashtable(); 285 if (g_CrPresenter.pFbTexMap) 286 { 287 #ifndef VBOXVDBG_MEMCACHE_DISABLE 288 rc = RTMemCacheCreate(&g_CrPresenter.FbEntryLookasideList, sizeof (CR_FRAMEBUFFER_ENTRY), 289 0, /* size_t cbAlignment */ 290 UINT32_MAX, /* uint32_t cMaxObjects */ 291 NULL, /* PFNMEMCACHECTOR pfnCtor*/ 292 NULL, /* PFNMEMCACHEDTOR pfnDtor*/ 293 NULL, /* void *pvUser*/ 294 0 /* uint32_t fFlags*/ 295 ); 296 if (RT_SUCCESS(rc)) 297 { 298 rc = RTMemCacheCreate(&g_CrPresenter.FbTexLookasideList, sizeof (CR_FBTEX), 299 0, /* size_t cbAlignment */ 300 UINT32_MAX, /* uint32_t cMaxObjects */ 301 NULL, /* PFNMEMCACHECTOR pfnCtor*/ 302 NULL, /* PFNMEMCACHEDTOR pfnDtor*/ 303 NULL, /* void *pvUser*/ 304 0 /* uint32_t fFlags*/ 305 ); 306 if (RT_SUCCESS(rc)) 307 { 308 rc = RTMemCacheCreate(&g_CrPresenter.CEntryLookasideList, sizeof (VBOXVR_SCR_COMPOSITOR_ENTRY), 309 0, /* size_t cbAlignment */ 310 UINT32_MAX, /* uint32_t cMaxObjects */ 311 NULL, /* PFNMEMCACHECTOR pfnCtor*/ 312 NULL, /* PFNMEMCACHEDTOR pfnDtor*/ 313 NULL, /* void *pvUser*/ 314 0 /* uint32_t fFlags*/ 315 ); 316 if (RT_SUCCESS(rc)) 317 { 318 #endif 319 rc = crPMgrModeModifyGlobal(CR_PMGR_MODE_WINDOW, true); 320 if (RT_SUCCESS(rc)) 321 return VINF_SUCCESS; 322 else 323 WARN(("crPMgrModeModifyGlobal failed rc %d", rc)); 324 #ifndef VBOXVDBG_MEMCACHE_DISABLE 325 RTMemCacheDestroy(g_CrPresenter.CEntryLookasideList); 326 } 327 else 328 WARN(("RTMemCacheCreate failed rc %d", rc)); 329 330 RTMemCacheDestroy(g_CrPresenter.FbTexLookasideList); 331 } 332 else 333 WARN(("RTMemCacheCreate failed rc %d", rc)); 334 335 RTMemCacheDestroy(g_CrPresenter.FbEntryLookasideList); 336 } 337 else 338 WARN(("RTMemCacheCreate failed rc %d", rc)); 339 #endif 73 340 } 74 341 else 75 crServerCheckMuralGeometry(&pDisplay->Mural); 76 } 77 78 void CrDpReparent(PCR_DISPLAY pDisplay, CRScreenInfo *pScreen) 79 { 80 renderspuSetWindowId(pScreen->winID); 81 crServerWindowReparent(&pDisplay->Mural); 82 renderspuSetWindowId(cr_server.screen[0].winID); 83 84 CrDpResize(pDisplay, pScreen->x, pScreen->y, pScreen->w, pScreen->h); 85 86 if (pScreen->winID) 87 { 88 /* need to do this on win, since otherwise the window ends up being with empty visible regions for some reason */ 89 crServerWindowVisibleRegion(&pDisplay->Mural); 90 } 91 } 92 93 94 int CrDpSaveState(PCR_DISPLAY pDisplay, PSSMHANDLE pSSM) 95 { 96 VBOXVR_SCR_COMPOSITOR_ITERATOR Iter; 97 CrVrScrCompositorIterInit(&pDisplay->Mural.Compositor, &Iter); 98 PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry; 342 { 343 WARN(("crAllocHashtable failed")); 344 rc = VERR_NO_MEMORY; 345 } 346 return rc; 347 } 348 349 void CrPMgrTerm() 350 { 351 #ifndef VBOXVDBG_MEMCACHE_DISABLE 352 RTMemCacheDestroy(g_CrPresenter.FbEntryLookasideList); 353 RTMemCacheDestroy(g_CrPresenter.FbTexLookasideList); 354 RTMemCacheDestroy(g_CrPresenter.CEntryLookasideList); 355 #endif 356 crFreeHashtable(g_CrPresenter.pFbTexMap, NULL); 357 } 358 359 static CR_FBTEX* crFbTexAlloc() 360 { 361 #ifndef VBOXVDBG_MEMCACHE_DISABLE 362 return (CR_FBTEX*)RTMemCacheAlloc(g_CrPresenter.FbTexLookasideList); 363 #else 364 return (CR_FBTEX*)RTMemAlloc(sizeof (CR_FBTEX)); 365 #endif 366 } 367 368 static void crFbTexFree(CR_FBTEX *pTex) 369 { 370 #ifndef VBOXVDBG_MEMCACHE_DISABLE 371 RTMemCacheFree(g_CrPresenter.FbTexLookasideList, pTex); 372 #else 373 RTMemFree(pTex); 374 #endif 375 } 376 377 static CR_FRAMEBUFFER_ENTRY* crFbEntryAlloc() 378 { 379 #ifndef VBOXVDBG_MEMCACHE_DISABLE 380 return (CR_FRAMEBUFFER_ENTRY*)RTMemCacheAlloc(g_CrPresenter.FbEntryLookasideList); 381 #else 382 return (CR_FRAMEBUFFER_ENTRY*)RTMemAlloc(sizeof (CR_FRAMEBUFFER_ENTRY)); 383 #endif 384 } 385 386 static void crFbEntryFree(CR_FRAMEBUFFER_ENTRY *pEntry) 387 { 388 Assert(!CrVrScrCompositorEntryIsUsed(&pEntry->Entry)); 389 #ifndef VBOXVDBG_MEMCACHE_DISABLE 390 RTMemCacheFree(g_CrPresenter.FbEntryLookasideList, pEntry); 391 #else 392 RTMemFree(pEntry); 393 #endif 394 } 395 396 DECLCALLBACK(void) crFbTexRelease(CR_TEXDATA *pTex) 397 { 398 CR_FBTEX *pFbTex = PCR_FBTEX_FROM_TEX(pTex); 399 CRTextureObj *pTobj = pFbTex->pTobj; 400 401 CrTdBltDataCleanup(pTex); 402 403 if (pTobj) 404 { 405 CR_STATE_SHAREDOBJ_USAGE_CLEAR(pTobj, cr_server.MainContextInfo.pContext); 406 407 crHashtableDelete(g_CrPresenter.pFbTexMap, pTobj->id, NULL); 408 409 if (!CR_STATE_SHAREDOBJ_USAGE_IS_USED(pTobj)) 410 { 411 CRSharedState *pShared = crStateGlobalSharedAcquire(); 412 413 CRASSERT(pShared); 414 /* on the host side, we need to delete an ogl texture object here as well, which crStateDeleteTextureCallback will do 415 * in addition to calling crStateDeleteTextureObject to delete a state object */ 416 crHashtableDelete(pShared->textureTable, pTobj->id, crStateDeleteTextureCallback); 417 418 crStateGlobalSharedRelease(); 419 } 420 421 crStateGlobalSharedRelease(); 422 } 423 424 crFbTexFree(pFbTex); 425 } 426 427 void CrFbTexDataInit(CR_TEXDATA* pFbTex, const VBOXVR_TEXTURE *pTex, PFNCRTEXDATA_RELEASED pfnTextureReleased) 428 { 429 PCR_BLITTER pBlitter = crServerVBoxBlitterGet(); 430 431 CrTdInit(pFbTex, pTex, pBlitter, pfnTextureReleased); 432 } 433 434 static CR_FBTEX* crFbTexCreate(const VBOXVR_TEXTURE *pTex) 435 { 436 CR_FBTEX *pFbTex = crFbTexAlloc(); 437 if (!pFbTex) 438 { 439 WARN(("crFbTexAlloc failed!")); 440 return NULL; 441 } 442 443 CrFbTexDataInit(&pFbTex->Tex, pTex, crFbTexRelease); 444 pFbTex->pTobj = NULL; 445 446 return pFbTex; 447 } 448 449 450 CR_TEXDATA* CrFbTexDataCreate(const VBOXVR_TEXTURE *pTex) 451 { 452 CR_FBTEX *pFbTex = crFbTexCreate(pTex); 453 if (!pFbTex) 454 { 455 WARN(("crFbTexCreate failed!")); 456 return NULL; 457 } 458 459 return &pFbTex->Tex; 460 } 461 462 static CR_FBTEX* crFbTexAcquire(GLuint idTexture) 463 { 464 CR_FBTEX *pFbTex = (CR_FBTEX *)crHashtableSearch(g_CrPresenter.pFbTexMap, idTexture); 465 if (pFbTex) 466 { 467 CrTdAddRef(&pFbTex->Tex); 468 return pFbTex; 469 } 470 471 CRSharedState *pShared = crStateGlobalSharedAcquire(); 472 if (!pShared) 473 { 474 WARN(("pShared is null!")); 475 return NULL; 476 } 477 478 CRTextureObj *pTobj = (CRTextureObj*)crHashtableSearch(pShared->textureTable, idTexture); 479 if (!pTobj) 480 { 481 WARN(("pTobj is null!")); 482 crStateGlobalSharedRelease(); 483 return NULL; 484 } 485 486 Assert(pTobj->id == idTexture); 487 488 GLuint hwid = crStateGetTextureObjHWID(pTobj); 489 if (!hwid) 490 { 491 WARN(("hwId is null!")); 492 crStateGlobalSharedRelease(); 493 return NULL; 494 } 495 496 VBOXVR_TEXTURE Tex; 497 Tex.width = pTobj->level[0]->width; 498 Tex.height = pTobj->level[0]->height; 499 Tex.hwid = hwid; 500 Tex.target = pTobj->target; 501 502 pFbTex = crFbTexCreate(&Tex); 503 if (!pFbTex) 504 { 505 WARN(("crFbTexCreate failed!")); 506 crStateGlobalSharedRelease(); 507 return NULL; 508 } 509 510 CR_STATE_SHAREDOBJ_USAGE_SET(pTobj, cr_server.MainContextInfo.pContext); 511 512 pFbTex->pTobj = pTobj; 513 514 crHashtableAdd(g_CrPresenter.pFbTexMap, idTexture, pFbTex); 515 516 return pFbTex; 517 } 518 519 static void crFbEntryMarkDestroyed(CR_FRAMEBUFFER *pFb, CR_FRAMEBUFFER_ENTRY* pEntry) 520 { 521 if (pEntry->Flags.fCreateNotified) 522 { 523 pEntry->Flags.fCreateNotified = 0; 524 if (pFb->pDisplay) 525 pFb->pDisplay->EntryDestroyed(pFb, pEntry); 526 } 527 } 528 529 static void crFbEntryDestroy(CR_FRAMEBUFFER *pFb, CR_FRAMEBUFFER_ENTRY* pEntry) 530 { 531 crFbEntryMarkDestroyed(pFb, pEntry); 532 CrVrScrCompositorEntryCleanup(&pEntry->Entry); 533 CrHTableDestroy(&pEntry->HTable); 534 crFbEntryFree(pEntry); 535 } 536 537 DECLINLINE(uint32_t) crFbEntryAddRef(CR_FRAMEBUFFER_ENTRY* pEntry) 538 { 539 return ++pEntry->cRefs; 540 } 541 542 DECLINLINE(uint32_t) crFbEntryRelease(CR_FRAMEBUFFER *pFb, CR_FRAMEBUFFER_ENTRY* pEntry) 543 { 544 uint32_t cRefs = --pEntry->cRefs; 545 if (!cRefs) 546 crFbEntryDestroy(pFb, pEntry); 547 return cRefs; 548 } 549 550 static DECLCALLBACK(void) crFbEntryReleased(const struct VBOXVR_SCR_COMPOSITOR *pCompositor, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pReplacingEntry) 551 { 552 CR_FRAMEBUFFER *pFb = PCR_FRAMEBUFFER_FROM_COMPOSITOR(pCompositor); 553 CR_FRAMEBUFFER_ENTRY *pFbEntry = PCR_FBENTRY_FROM_ENTRY(pEntry); 554 CR_FRAMEBUFFER_ENTRY *pFbReplacingEntry = pReplacingEntry ? PCR_FBENTRY_FROM_ENTRY(pReplacingEntry) : NULL; 555 if (pFbReplacingEntry) 556 { 557 /*replace operation implies the replaced entry gets auto-destroyed, 558 * while all its data gets moved to the *clean* replacing entry 559 * 1. ensure the replacing entry is cleaned up */ 560 crFbEntryMarkDestroyed(pFb, pFbReplacingEntry); 561 562 CrHTableMoveTo(&pFbEntry->HTable, &pFbReplacingEntry->HTable); 563 if (pFb->pDisplay) 564 pFb->pDisplay->EntryReplaced(pFb, pFbReplacingEntry, pFbEntry); 565 566 /* 2. mark the replaced entry is destroyed */ 567 Assert(pFbEntry->Flags.fCreateNotified); 568 pFbEntry->Flags.fCreateNotified = 0; 569 pFbReplacingEntry->Flags.fCreateNotified = 1; 570 } 571 else 572 { 573 if (pFb->pDisplay) 574 pFb->pDisplay->EntryRemoved(pFb, pFbEntry); 575 } 576 577 crFbEntryRelease(pFb, pFbEntry); 578 } 579 580 static CR_FRAMEBUFFER_ENTRY* crFbEntryCreate(CR_FRAMEBUFFER *pFb, CR_TEXDATA* pTex, const RTRECT *pRect, uint32_t fFlags) 581 { 582 CR_FRAMEBUFFER_ENTRY *pEntry = crFbEntryAlloc(); 583 if (!pEntry) 584 { 585 WARN(("crFbEntryAlloc failed!")); 586 return NULL; 587 } 588 589 CrVrScrCompositorEntryInit(&pEntry->Entry, pRect, pTex, crFbEntryReleased); 590 CrVrScrCompositorEntryFlagsSet(&pEntry->Entry, fFlags); 591 pEntry->cRefs = 1; 592 CrHTableCreate(&pEntry->HTable, 0); 593 594 return pEntry; 595 } 596 597 int CrFbEntryCreateForTexData(CR_FRAMEBUFFER *pFb, struct CR_TEXDATA *pTex, uint32_t fFlags, HCR_FRAMEBUFFER_ENTRY *phEntry) 598 { 599 RTRECT Rect; 600 Rect.xLeft = 0; 601 Rect.yTop = 0; 602 Rect.xRight = pTex->Tex.width; 603 Rect.yBottom = pTex->Tex.height; 604 CR_FRAMEBUFFER_ENTRY* pEntry = crFbEntryCreate(pFb, pTex, &Rect, fFlags); 605 if (!pEntry) 606 { 607 WARN(("crFbEntryCreate failed")); 608 return VERR_NO_MEMORY; 609 } 610 611 *phEntry = pEntry; 612 return VINF_SUCCESS; 613 } 614 615 int CrFbEntryTexDataUpdate(CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY pEntry, struct CR_TEXDATA *pTex) 616 { 617 if (!pFb->cUpdating) 618 { 619 WARN(("framebuffer not updating")); 620 return VERR_INVALID_STATE; 621 } 622 623 if (pTex) 624 CrVrScrCompositorEntryTexSet(&pEntry->Entry, pTex); 625 626 if (CrVrScrCompositorEntryIsUsed(&pEntry->Entry)) 627 { 628 if (pFb->pDisplay) 629 pFb->pDisplay->EntryTexChanged(pFb, pEntry); 630 } 631 632 return VINF_SUCCESS; 633 } 634 635 636 int CrFbEntryCreateForTexId(CR_FRAMEBUFFER *pFb, GLuint idTexture, uint32_t fFlags, HCR_FRAMEBUFFER_ENTRY *phEntry) 637 { 638 CR_FBTEX* pFbTex = crFbTexAcquire(idTexture); 639 if (!pFbTex) 640 { 641 WARN(("crFbTexAcquire failed")); 642 return VERR_INVALID_PARAMETER; 643 } 644 645 CR_TEXDATA* pTex = &pFbTex->Tex; 646 int rc = CrFbEntryCreateForTexData(pFb, pTex, fFlags, phEntry); 647 if (!RT_SUCCESS(rc)) 648 { 649 WARN(("CrFbEntryCreateForTexData failed rc %d", rc)); 650 } 651 652 /*always release the tex, the CrFbEntryCreateForTexData will do incref as necessary */ 653 CrTdRelease(pTex); 654 return rc; 655 } 656 657 void CrFbEntryAddRef(CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 658 { 659 ++hEntry->cRefs; 660 } 661 662 void CrFbEntryRelease(CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 663 { 664 crFbEntryRelease(pFb, hEntry); 665 } 666 667 int CrFbRegionsClear(HCR_FRAMEBUFFER hFb) 668 { 669 if (!hFb->cUpdating) 670 { 671 WARN(("framebuffer not updating")); 672 return VERR_INVALID_STATE; 673 } 674 675 bool fChanged = false; 676 CrVrScrCompositorRegionsClear(&hFb->Compositor, &fChanged); 677 if (fChanged) 678 { 679 if (hFb->pDisplay) 680 hFb->pDisplay->RegionsChanged(hFb); 681 } 682 683 return VINF_SUCCESS; 684 } 685 686 int CrFbEntryRegionsAdd(CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, bool fPosRelated) 687 { 688 if (!pFb->cUpdating) 689 { 690 WARN(("framebuffer not updating")); 691 return VERR_INVALID_STATE; 692 } 693 694 uint32_t fChangeFlags = 0; 695 VBOXVR_SCR_COMPOSITOR_ENTRY *pReplacedScrEntry = NULL; 696 VBOXVR_SCR_COMPOSITOR_ENTRY *pNewEntry; 697 bool fEntryWasInList; 698 699 if (hEntry) 700 { 701 crFbEntryAddRef(hEntry); 702 pNewEntry = &hEntry->Entry; 703 fEntryWasInList = CrVrScrCompositorEntryIsUsed(pNewEntry); 704 } 705 else 706 { 707 pNewEntry = NULL; 708 fEntryWasInList = false; 709 } 710 711 int rc = CrVrScrCompositorEntryRegionsAdd(&pFb->Compositor, hEntry ? &hEntry->Entry : NULL, pPos, cRegions, paRegions, fPosRelated, &pReplacedScrEntry, &fChangeFlags); 712 if (RT_SUCCESS(rc)) 713 { 714 if (fChangeFlags & VBOXVR_COMPOSITOR_CF_REGIONS_CHANGED) 715 { 716 if (!fEntryWasInList && pNewEntry) 717 { 718 Assert(CrVrScrCompositorEntryIsUsed(pNewEntry)); 719 if (!hEntry->Flags.fCreateNotified) 720 { 721 hEntry->Flags.fCreateNotified = 1; 722 if (pFb->pDisplay) 723 pFb->pDisplay->EntryCreated(pFb, hEntry); 724 } 725 726 if (pFb->pDisplay) 727 pFb->pDisplay->EntryAdded(pFb, hEntry); 728 } 729 if (pFb->pDisplay) 730 pFb->pDisplay->RegionsChanged(pFb); 731 732 Assert(!pReplacedScrEntry); 733 } 734 else if (fChangeFlags & VBOXVR_COMPOSITOR_CF_ENTRY_REPLACED) 735 { 736 Assert(pReplacedScrEntry); 737 /* we have already processed that in a "release" callback */ 738 Assert(hEntry); 739 } 740 else 741 { 742 Assert(!fChangeFlags); 743 Assert(!pReplacedScrEntry); 744 } 745 } 746 else 747 WARN(("CrVrScrCompositorEntryRegionsAdd failed, rc %d", rc)); 748 749 return rc; 750 } 751 752 int CrFbEntryRegionsSet(CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, bool fPosRelated) 753 { 754 if (!pFb->cUpdating) 755 { 756 WARN(("framebuffer not updating")); 757 return VERR_INVALID_STATE; 758 } 759 760 bool fChanged = 0; 761 VBOXVR_SCR_COMPOSITOR_ENTRY *pReplacedScrEntry = NULL; 762 VBOXVR_SCR_COMPOSITOR_ENTRY *pNewEntry; 763 bool fEntryWasInList; 764 765 if (hEntry) 766 { 767 crFbEntryAddRef(hEntry); 768 pNewEntry = &hEntry->Entry; 769 fEntryWasInList = CrVrScrCompositorEntryIsUsed(pNewEntry); 770 } 771 else 772 { 773 pNewEntry = NULL; 774 fEntryWasInList = false; 775 } 776 777 int rc = CrVrScrCompositorEntryRegionsSet(&pFb->Compositor, pNewEntry, pPos, cRegions, paRegions, fPosRelated, &fChanged); 778 if (RT_SUCCESS(rc)) 779 { 780 if (fChanged) 781 { 782 if (!fEntryWasInList && pNewEntry) 783 { 784 if (CrVrScrCompositorEntryIsUsed(pNewEntry)) 785 { 786 if (!hEntry->Flags.fCreateNotified) 787 { 788 hEntry->Flags.fCreateNotified = 1; 789 790 if (pFb->pDisplay) 791 pFb->pDisplay->EntryCreated(pFb, hEntry); 792 } 793 794 if (pFb->pDisplay) 795 pFb->pDisplay->EntryAdded(pFb, hEntry); 796 } 797 } 798 799 if (pFb->pDisplay) 800 pFb->pDisplay->RegionsChanged(pFb); 801 } 802 } 803 else 804 WARN(("CrVrScrCompositorEntryRegionsSet failed, rc %d", rc)); 805 806 return rc; 807 } 808 809 const struct VBOXVR_SCR_COMPOSITOR_ENTRY* CrFbEntryGetCompositorEntry(HCR_FRAMEBUFFER_ENTRY hEntry) 810 { 811 return &hEntry->Entry; 812 } 813 814 HCR_FRAMEBUFFER_ENTRY CrFbEntryFromCompositorEntry(const struct VBOXVR_SCR_COMPOSITOR_ENTRY* pCEntry) 815 { 816 return RT_FROM_MEMBER(pCEntry, CR_FRAMEBUFFER_ENTRY, Entry); 817 } 818 819 CRHTABLE_HANDLE CrFbDDataAllocSlot(CR_FRAMEBUFFER *pFb) 820 { 821 return CrHTablePut(&pFb->SlotTable, (void*)1); 822 } 823 824 void CrFbDDataReleaseSlot(CR_FRAMEBUFFER *pFb, CRHTABLE_HANDLE hSlot) 825 { 826 CrHTableRemove(&pFb->SlotTable, hSlot); 827 } 828 829 int CrFbDDataEntryPut(HCR_FRAMEBUFFER_ENTRY hEntry, CRHTABLE_HANDLE hSlot, void *pvData) 830 { 831 return CrHTablePutToSlot(&hEntry->HTable, hSlot, pvData); 832 } 833 834 void* CrFbDDataEntryGet(HCR_FRAMEBUFFER_ENTRY hEntry, CRHTABLE_HANDLE hSlot) 835 { 836 return CrHTableGet(&hEntry->HTable, hSlot); 837 } 838 839 class CrFbDisplayBase : public ICrFbDisplay 840 { 841 public: 842 CrFbDisplayBase() : 843 mpContainer(NULL), 844 mpFb(NULL), 845 mcUpdates(0), 846 mhSlot(CRHTABLE_HANDLE_INVALID) 847 {} 848 849 virtual bool isComposite() 850 { 851 return false; 852 } 853 854 class CrFbDisplayComposite* getContainer() 855 { 856 return mpContainer; 857 } 858 859 bool isInList() 860 { 861 return !!mpContainer; 862 } 863 864 bool isUpdating() 865 { 866 return !!mcUpdates; 867 } 868 869 int setFramebuffer(struct CR_FRAMEBUFFER *pFb) 870 { 871 if (mcUpdates) 872 { 873 WARN(("trying to set framebuffer while update is in progress")); 874 return VERR_INVALID_STATE; 875 } 876 877 if (mpFb == pFb) 878 return VINF_SUCCESS; 879 880 int rc = setFramebufferBegin(pFb); 881 if (!RT_SUCCESS(rc)) 882 { 883 WARN(("err")); 884 return rc; 885 } 886 887 if (mpFb) 888 { 889 rc = fbCleanup(); 890 if (!RT_SUCCESS(rc)) 891 { 892 WARN(("err")); 893 setFramebufferEnd(pFb); 894 return rc; 895 } 896 } 897 898 mpFb = pFb; 899 900 if (mpFb) 901 { 902 rc = fbSync(); 903 if (!RT_SUCCESS(rc)) 904 { 905 WARN(("err")); 906 setFramebufferEnd(pFb); 907 return rc; 908 } 909 } 910 911 setFramebufferEnd(pFb); 912 return VINF_SUCCESS; 913 } 914 915 struct CR_FRAMEBUFFER* getFramebuffer() 916 { 917 return mpFb; 918 } 919 920 virtual int UpdateBegin(struct CR_FRAMEBUFFER *pFb) 921 { 922 ++mcUpdates; 923 return VINF_SUCCESS; 924 } 925 926 virtual void UpdateEnd(struct CR_FRAMEBUFFER *pFb) 927 { 928 --mcUpdates; 929 Assert(mcUpdates < UINT32_MAX/2); 930 } 931 932 virtual int EntryCreated(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 933 { 934 if (!mcUpdates) 935 { 936 WARN(("err")); 937 return VERR_INVALID_STATE; 938 } 939 return VINF_SUCCESS; 940 } 941 942 virtual int EntryAdded(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 943 { 944 if (!mcUpdates) 945 { 946 WARN(("err")); 947 return VERR_INVALID_STATE; 948 } 949 return VINF_SUCCESS; 950 } 951 952 virtual int EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry) 953 { 954 if (!mcUpdates) 955 { 956 WARN(("err")); 957 return VERR_INVALID_STATE; 958 } 959 return VINF_SUCCESS; 960 } 961 962 virtual int EntryTexChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 963 { 964 if (!mcUpdates) 965 { 966 WARN(("err")); 967 return VERR_INVALID_STATE; 968 } 969 return VINF_SUCCESS; 970 } 971 972 virtual int EntryRemoved(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 973 { 974 if (!mcUpdates) 975 { 976 WARN(("err")); 977 return VERR_INVALID_STATE; 978 } 979 return VINF_SUCCESS; 980 } 981 982 virtual int EntryDestroyed(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 983 { 984 return VINF_SUCCESS; 985 } 986 987 virtual int EntryPosChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 988 { 989 if (!mcUpdates) 990 { 991 WARN(("err")); 992 return VERR_INVALID_STATE; 993 } 994 return VINF_SUCCESS; 995 } 996 997 virtual int RegionsChanged(struct CR_FRAMEBUFFER *pFb) 998 { 999 if (!mcUpdates) 1000 { 1001 WARN(("err")); 1002 return VERR_INVALID_STATE; 1003 } 1004 return VINF_SUCCESS; 1005 } 1006 1007 virtual int FramebufferChanged(struct CR_FRAMEBUFFER *pFb) 1008 { 1009 if (!mcUpdates) 1010 { 1011 WARN(("err")); 1012 return VERR_INVALID_STATE; 1013 } 1014 return VINF_SUCCESS; 1015 } 1016 1017 virtual ~CrFbDisplayBase(); 1018 1019 /*@todo: move to protected and switch from RTLISTNODE*/ 1020 RTLISTNODE mNode; 1021 class CrFbDisplayComposite* mpContainer; 1022 protected: 1023 int fbSynchAddAllEntries() 1024 { 1025 VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR Iter; 1026 const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry; 1027 1028 CrVrScrCompositorConstIterInit(CrFbGetCompositor(mpFb), &Iter); 1029 1030 int rc = VINF_SUCCESS; 1031 1032 while ((pEntry = CrVrScrCompositorConstIterNext(&Iter)) != NULL) 1033 { 1034 HCR_FRAMEBUFFER_ENTRY hEntry = CrFbEntryFromCompositorEntry(pEntry); 1035 rc = EntryAdded(mpFb, hEntry); 1036 if (!RT_SUCCESS(rc)) 1037 { 1038 WARN(("err")); 1039 break; 1040 } 1041 } 1042 1043 return rc; 1044 } 1045 1046 int fbCleanupRemoveAllEntries(bool fNotifyDestroy) 1047 { 1048 VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR Iter; 1049 const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry; 1050 1051 CrVrScrCompositorConstIterInit(CrFbGetCompositor(mpFb), &Iter); 1052 1053 int rc = VINF_SUCCESS; 1054 1055 while ((pEntry = CrVrScrCompositorConstIterNext(&Iter)) != NULL) 1056 { 1057 HCR_FRAMEBUFFER_ENTRY hEntry = CrFbEntryFromCompositorEntry(pEntry); 1058 rc = EntryRemoved(mpFb, hEntry); 1059 if (!RT_SUCCESS(rc)) 1060 { 1061 WARN(("err")); 1062 break; 1063 } 1064 1065 if (fNotifyDestroy) 1066 { 1067 rc = EntryDestroyed(mpFb, hEntry); 1068 if (!RT_SUCCESS(rc)) 1069 { 1070 WARN(("err")); 1071 break; 1072 } 1073 } 1074 } 1075 1076 return rc; 1077 } 1078 1079 virtual int setFramebufferBegin(struct CR_FRAMEBUFFER *pFb) 1080 { 1081 return UpdateBegin(pFb); 1082 } 1083 virtual void setFramebufferEnd(struct CR_FRAMEBUFFER *pFb) 1084 { 1085 UpdateEnd(pFb); 1086 } 1087 1088 virtual int fbCleanup() 1089 { 1090 if (mhSlot) 1091 { 1092 CrFbDDataReleaseSlot(mpFb, mhSlot); 1093 mhSlot = 0; 1094 } 1095 mpFb = NULL; 1096 return VINF_SUCCESS; 1097 } 1098 1099 virtual int fbSync() 1100 { 1101 return VINF_SUCCESS; 1102 } 1103 1104 CRHTABLE_HANDLE slotGet() 1105 { 1106 if (!mhSlot) 1107 { 1108 if (mpFb) 1109 mhSlot = CrFbDDataAllocSlot(mpFb); 1110 } 1111 1112 return mhSlot; 1113 } 1114 1115 private: 1116 struct CR_FRAMEBUFFER *mpFb; 1117 uint32_t mcUpdates; 1118 CRHTABLE_HANDLE mhSlot; 1119 }; 1120 1121 class CrFbDisplayComposite : public CrFbDisplayBase 1122 { 1123 public: 1124 CrFbDisplayComposite() : 1125 mcDisplays(0) 1126 { 1127 RTListInit(&mDisplays); 1128 } 1129 1130 virtual bool isComposite() 1131 { 1132 return true; 1133 } 1134 1135 uint32_t getDisplayCount() 1136 { 1137 return mcDisplays; 1138 } 1139 1140 bool add(CrFbDisplayBase *pDisplay) 1141 { 1142 if (pDisplay->isInList()) 1143 { 1144 WARN(("entry in list already")); 1145 return false; 1146 } 1147 1148 RTListAppend(&mDisplays, &pDisplay->mNode); 1149 pDisplay->mpContainer = this; 1150 pDisplay->setFramebuffer(getFramebuffer()); 1151 ++mcDisplays; 1152 return true; 1153 } 1154 1155 bool remove(CrFbDisplayBase *pDisplay, bool fCleanupDisplay = true) 1156 { 1157 if (pDisplay->getContainer() != this) 1158 { 1159 WARN(("invalid entry container")); 1160 return false; 1161 } 1162 1163 RTListNodeRemove(&pDisplay->mNode); 1164 pDisplay->mpContainer = NULL; 1165 if (fCleanupDisplay) 1166 pDisplay->setFramebuffer(NULL); 1167 --mcDisplays; 1168 return true; 1169 } 1170 1171 CrFbDisplayBase* first() 1172 { 1173 return RTListGetFirstCpp(&mDisplays, CrFbDisplayBase, mNode); 1174 } 1175 1176 CrFbDisplayBase* next(CrFbDisplayBase* pDisplay) 1177 { 1178 if (pDisplay->getContainer() != this) 1179 { 1180 WARN(("invalid entry container")); 1181 return NULL; 1182 } 1183 1184 return RTListGetNextCpp(&mDisplays, pDisplay, CrFbDisplayBase, mNode); 1185 } 1186 1187 virtual int setFramebuffer(struct CR_FRAMEBUFFER *pFb) 1188 { 1189 CrFbDisplayBase::setFramebuffer(pFb); 1190 1191 CrFbDisplayBase *pIter; 1192 RTListForEachCpp(&mDisplays, pIter, CrFbDisplayBase, mNode) 1193 { 1194 pIter->setFramebuffer(pFb); 1195 } 1196 1197 return VINF_SUCCESS; 1198 } 1199 1200 virtual int UpdateBegin(struct CR_FRAMEBUFFER *pFb) 1201 { 1202 int rc = CrFbDisplayBase::UpdateBegin(pFb); 1203 if (!RT_SUCCESS(rc)) 1204 { 1205 WARN(("err")); 1206 return rc; 1207 } 1208 1209 CrFbDisplayBase *pIter; 1210 RTListForEachCpp(&mDisplays, pIter, CrFbDisplayBase, mNode) 1211 { 1212 rc = pIter->UpdateBegin(pFb); 1213 if (!RT_SUCCESS(rc)) 1214 { 1215 WARN(("err")); 1216 return rc; 1217 } 1218 } 1219 return VINF_SUCCESS; 1220 } 1221 1222 virtual void UpdateEnd(struct CR_FRAMEBUFFER *pFb) 1223 { 1224 CrFbDisplayBase *pIter; 1225 RTListForEachCpp(&mDisplays, pIter, CrFbDisplayBase, mNode) 1226 { 1227 pIter->UpdateEnd(pFb); 1228 } 1229 1230 CrFbDisplayBase::UpdateEnd(pFb); 1231 } 1232 1233 virtual int EntryAdded(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 1234 { 1235 int rc = CrFbDisplayBase::EntryAdded(pFb, hEntry); 1236 if (!RT_SUCCESS(rc)) 1237 { 1238 WARN(("err")); 1239 return rc; 1240 } 1241 1242 CrFbDisplayBase *pIter; 1243 RTListForEachCpp(&mDisplays, pIter, CrFbDisplayBase, mNode) 1244 { 1245 int rc = pIter->EntryAdded(pFb, hEntry); 1246 if (!RT_SUCCESS(rc)) 1247 { 1248 WARN(("err")); 1249 return rc; 1250 } 1251 } 1252 return VINF_SUCCESS; 1253 } 1254 1255 virtual int EntryCreated(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 1256 { 1257 int rc = CrFbDisplayBase::EntryAdded(pFb, hEntry); 1258 if (!RT_SUCCESS(rc)) 1259 { 1260 WARN(("err")); 1261 return rc; 1262 } 1263 1264 CrFbDisplayBase *pIter; 1265 RTListForEachCpp(&mDisplays, pIter, CrFbDisplayBase, mNode) 1266 { 1267 int rc = pIter->EntryCreated(pFb, hEntry); 1268 if (!RT_SUCCESS(rc)) 1269 { 1270 WARN(("err")); 1271 return rc; 1272 } 1273 } 1274 return VINF_SUCCESS; 1275 } 1276 1277 virtual int EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry) 1278 { 1279 int rc = CrFbDisplayBase::EntryReplaced(pFb, hNewEntry, hReplacedEntry); 1280 if (!RT_SUCCESS(rc)) 1281 { 1282 WARN(("err")); 1283 return rc; 1284 } 1285 1286 CrFbDisplayBase *pIter; 1287 RTListForEachCpp(&mDisplays, pIter, CrFbDisplayBase, mNode) 1288 { 1289 int rc = pIter->EntryReplaced(pFb, hNewEntry, hReplacedEntry); 1290 if (!RT_SUCCESS(rc)) 1291 { 1292 WARN(("err")); 1293 return rc; 1294 } 1295 } 1296 return VINF_SUCCESS; 1297 } 1298 1299 virtual int EntryTexChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 1300 { 1301 int rc = CrFbDisplayBase::EntryTexChanged(pFb, hEntry); 1302 if (!RT_SUCCESS(rc)) 1303 { 1304 WARN(("err")); 1305 return rc; 1306 } 1307 1308 CrFbDisplayBase *pIter; 1309 RTListForEachCpp(&mDisplays, pIter, CrFbDisplayBase, mNode) 1310 { 1311 int rc = pIter->EntryTexChanged(pFb, hEntry); 1312 if (!RT_SUCCESS(rc)) 1313 { 1314 WARN(("err")); 1315 return rc; 1316 } 1317 } 1318 return VINF_SUCCESS; 1319 } 1320 1321 virtual int EntryRemoved(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 1322 { 1323 int rc = CrFbDisplayBase::EntryRemoved(pFb, hEntry); 1324 if (!RT_SUCCESS(rc)) 1325 { 1326 WARN(("err")); 1327 return rc; 1328 } 1329 1330 CrFbDisplayBase *pIter; 1331 RTListForEachCpp(&mDisplays, pIter, CrFbDisplayBase, mNode) 1332 { 1333 int rc = pIter->EntryRemoved(pFb, hEntry); 1334 if (!RT_SUCCESS(rc)) 1335 { 1336 WARN(("err")); 1337 return rc; 1338 } 1339 } 1340 return VINF_SUCCESS; 1341 } 1342 1343 virtual int EntryDestroyed(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 1344 { 1345 int rc = CrFbDisplayBase::EntryDestroyed(pFb, hEntry); 1346 if (!RT_SUCCESS(rc)) 1347 { 1348 WARN(("err")); 1349 return rc; 1350 } 1351 1352 CrFbDisplayBase *pIter; 1353 RTListForEachCpp(&mDisplays, pIter, CrFbDisplayBase, mNode) 1354 { 1355 int rc = pIter->EntryDestroyed(pFb, hEntry); 1356 if (!RT_SUCCESS(rc)) 1357 { 1358 WARN(("err")); 1359 return rc; 1360 } 1361 } 1362 return VINF_SUCCESS; 1363 } 1364 1365 virtual int RegionsChanged(struct CR_FRAMEBUFFER *pFb) 1366 { 1367 int rc = CrFbDisplayBase::RegionsChanged(pFb); 1368 if (!RT_SUCCESS(rc)) 1369 { 1370 WARN(("err")); 1371 return rc; 1372 } 1373 1374 CrFbDisplayBase *pIter; 1375 RTListForEachCpp(&mDisplays, pIter, CrFbDisplayBase, mNode) 1376 { 1377 int rc = pIter->RegionsChanged(pFb); 1378 if (!RT_SUCCESS(rc)) 1379 { 1380 WARN(("err")); 1381 return rc; 1382 } 1383 } 1384 return VINF_SUCCESS; 1385 } 1386 1387 virtual int FramebufferChanged(struct CR_FRAMEBUFFER *pFb) 1388 { 1389 int rc = CrFbDisplayBase::FramebufferChanged(pFb); 1390 if (!RT_SUCCESS(rc)) 1391 { 1392 WARN(("err")); 1393 return rc; 1394 } 1395 1396 CrFbDisplayBase *pIter; 1397 RTListForEachCpp(&mDisplays, pIter, CrFbDisplayBase, mNode) 1398 { 1399 int rc = pIter->FramebufferChanged(pFb); 1400 if (!RT_SUCCESS(rc)) 1401 { 1402 WARN(("err")); 1403 return rc; 1404 } 1405 } 1406 return VINF_SUCCESS; 1407 } 1408 1409 virtual ~CrFbDisplayComposite() 1410 { 1411 cleanup(); 1412 } 1413 1414 void cleanup(bool fCleanupDisplays = true) 1415 { 1416 CrFbDisplayBase *pIter, *pIterNext; 1417 RTListForEachSafeCpp(&mDisplays, pIter, pIterNext, CrFbDisplayBase, mNode) 1418 { 1419 remove(pIter, fCleanupDisplays); 1420 } 1421 } 1422 private: 1423 RTLISTNODE mDisplays; 1424 uint32_t mcDisplays; 1425 }; 1426 1427 typedef union CR_FBWIN_FLAGS 1428 { 1429 struct { 1430 uint32_t fVisible : 1; 1431 uint32_t fDataPresented : 1; 1432 uint32_t fForcePresentOnReenable : 1; 1433 uint32_t fCompositoEntriesModified : 1; 1434 uint32_t Reserved : 28; 1435 }; 1436 uint32_t Value; 1437 } CR_FBWIN_FLAGS; 1438 1439 class CrFbWindow 1440 { 1441 public: 1442 CrFbWindow(uint64_t parentId) : 1443 mSpuWindow(0), 1444 mpCompositor(NULL), 1445 mcUpdates(0), 1446 mxPos(0), 1447 myPos(0), 1448 mWidth(0), 1449 mHeight(0), 1450 mParentId(parentId) 1451 { 1452 mFlags.Value = 0; 1453 } 1454 1455 bool IsCreated() 1456 { 1457 return !!mSpuWindow; 1458 } 1459 1460 void Destroy() 1461 { 1462 CRASSERT(!mcUpdates); 1463 1464 if (!mSpuWindow) 1465 return; 1466 1467 cr_server.head_spu->dispatch_table.WindowDestroy(mSpuWindow); 1468 1469 mSpuWindow = 0; 1470 mFlags.fDataPresented = 0; 1471 } 1472 1473 int Reparent(uint64_t parentId) 1474 { 1475 if (!checkInitedUpdating()) 1476 { 1477 WARN(("err")); 1478 return VERR_INVALID_STATE; 1479 } 1480 1481 mParentId = parentId; 1482 1483 if (!parentId) 1484 cr_server.head_spu->dispatch_table.WindowShow(mSpuWindow, false); 1485 1486 if (mSpuWindow) 1487 { 1488 renderspuSetWindowId(mParentId); 1489 renderspuReparentWindow(mSpuWindow); 1490 renderspuSetWindowId(cr_server.screen[0].winID); 1491 } 1492 1493 return VINF_SUCCESS; 1494 } 1495 1496 int SetVisible(bool fVisible) 1497 { 1498 if (!checkInitedUpdating()) 1499 { 1500 WARN(("err")); 1501 return VERR_INVALID_STATE; 1502 } 1503 1504 LOG(("CrWIN: Vidible [%d]", fVisible)); 1505 1506 if (!fVisible != !mFlags.fVisible) 1507 { 1508 mFlags.fVisible = fVisible; 1509 if (mSpuWindow && mParentId) 1510 cr_server.head_spu->dispatch_table.WindowShow(mSpuWindow, fVisible); 1511 } 1512 1513 return VINF_SUCCESS; 1514 } 1515 1516 int SetSize(uint32_t width, uint32_t height) 1517 { 1518 if (!checkInitedUpdating()) 1519 { 1520 WARN(("err")); 1521 return VERR_INVALID_STATE; 1522 } 1523 1524 LOG(("CrWIN: Size [%d ; %d]", width, height)); 1525 1526 if (mWidth != width || mHeight != height) 1527 { 1528 mFlags.fCompositoEntriesModified = 1; 1529 mWidth = width; 1530 mHeight = height; 1531 if (mSpuWindow) 1532 cr_server.head_spu->dispatch_table.WindowSize(mSpuWindow, width, height); 1533 } 1534 1535 return VINF_SUCCESS; 1536 } 1537 1538 int SetPosition(int32_t x, int32_t y) 1539 { 1540 if (!checkInitedUpdating()) 1541 { 1542 WARN(("err")); 1543 return VERR_INVALID_STATE; 1544 } 1545 1546 LOG(("CrWIN: Pos [%d ; %d]", x, y)); 1547 1548 if (x != mxPos || y != myPos) 1549 { 1550 mxPos = x; 1551 myPos = y; 1552 if (mSpuWindow) 1553 cr_server.head_spu->dispatch_table.WindowPosition(mSpuWindow, x, y); 1554 } 1555 1556 return VINF_SUCCESS; 1557 } 1558 1559 int SetVisibleRegionsChanged() 1560 { 1561 if (!checkInitedUpdating()) 1562 { 1563 WARN(("err")); 1564 return VERR_INVALID_STATE; 1565 } 1566 1567 mFlags.fCompositoEntriesModified = 1; 1568 return VINF_SUCCESS; 1569 } 1570 1571 int SetCompositor(const struct VBOXVR_SCR_COMPOSITOR * pCompositor) 1572 { 1573 if (!checkInitedUpdating()) 1574 { 1575 WARN(("err")); 1576 return VERR_INVALID_STATE; 1577 } 1578 1579 mpCompositor = pCompositor; 1580 mFlags.fCompositoEntriesModified = 1; 1581 return VINF_SUCCESS; 1582 } 1583 1584 int UpdateBegin() 1585 { 1586 ++mcUpdates; 1587 if (mcUpdates > 1) 1588 return VINF_SUCCESS; 1589 1590 Assert(!mFlags.fForcePresentOnReenable); 1591 // Assert(!mFlags.fCompositoEntriesModified); 1592 1593 if (mFlags.fDataPresented) 1594 { 1595 Assert(mSpuWindow); 1596 cr_server.head_spu->dispatch_table.VBoxPresentComposition(mSpuWindow, NULL, NULL); 1597 mFlags.fForcePresentOnReenable = isPresentNeeded(); 1598 } 1599 1600 return VINF_SUCCESS; 1601 } 1602 1603 void UpdateEnd() 1604 { 1605 --mcUpdates; 1606 Assert(mcUpdates < UINT32_MAX/2); 1607 if (mcUpdates) 1608 return; 1609 1610 checkRegions(); 1611 1612 if (mSpuWindow) 1613 { 1614 bool fPresentNeeded = isPresentNeeded(); 1615 if (fPresentNeeded || mFlags.fForcePresentOnReenable) 1616 { 1617 mFlags.fForcePresentOnReenable = false; 1618 cr_server.head_spu->dispatch_table.VBoxPresentComposition(mSpuWindow, mpCompositor, NULL); 1619 } 1620 1621 /* even if the above branch is entered due to mFlags.fForcePresentOnReenable, 1622 * the backend should clean up the compositor as soon as presentation is performed */ 1623 mFlags.fDataPresented = fPresentNeeded; 1624 } 1625 else 1626 { 1627 Assert(!mFlags.fDataPresented); 1628 Assert(!mFlags.fForcePresentOnReenable); 1629 } 1630 } 1631 1632 uint64_t GetParentId() 1633 { 1634 return mParentId; 1635 } 1636 1637 int Create() 1638 { 1639 if (mSpuWindow) 1640 { 1641 //WARN(("window already created")); 1642 return VINF_ALREADY_INITIALIZED; 1643 } 1644 1645 CRASSERT(cr_server.fVisualBitsDefault); 1646 renderspuSetWindowId(mParentId); 1647 mSpuWindow = cr_server.head_spu->dispatch_table.WindowCreate("", cr_server.fVisualBitsDefault); 1648 renderspuSetWindowId(cr_server.screen[0].winID); 1649 if (mSpuWindow < 0) { 1650 WARN(("WindowCreate failed")); 1651 return VERR_GENERAL_FAILURE; 1652 } 1653 1654 cr_server.head_spu->dispatch_table.WindowSize(mSpuWindow, mWidth, mHeight); 1655 cr_server.head_spu->dispatch_table.WindowPosition(mSpuWindow, mxPos, myPos); 1656 1657 checkRegions(); 1658 1659 if (mParentId && mFlags.fVisible) 1660 cr_server.head_spu->dispatch_table.WindowShow(mSpuWindow, true); 1661 1662 return VINF_SUCCESS; 1663 } 1664 1665 ~CrFbWindow() 1666 { 1667 Destroy(); 1668 } 1669 protected: 1670 void checkRegions() 1671 { 1672 if (!mSpuWindow) 1673 return; 1674 1675 if (!mFlags.fCompositoEntriesModified) 1676 return; 1677 1678 uint32_t cRects; 1679 const RTRECT *pRects; 1680 if (mpCompositor) 1681 { 1682 int rc = CrVrScrCompositorRegionsGet(mpCompositor, &cRects, NULL, &pRects, NULL); 1683 if (!RT_SUCCESS(rc)) 1684 { 1685 WARN(("CrVrScrCompositorRegionsGet failed rc %d", rc)); 1686 cRects = 0; 1687 pRects = NULL; 1688 } 1689 } 1690 else 1691 { 1692 cRects = 0; 1693 pRects = NULL; 1694 } 1695 1696 cr_server.head_spu->dispatch_table.WindowVisibleRegion(mSpuWindow, cRects, (const GLint*)pRects); 1697 1698 mFlags.fCompositoEntriesModified = 0; 1699 } 1700 1701 bool isPresentNeeded() 1702 { 1703 return mFlags.fVisible && mWidth && mHeight && mpCompositor && !CrVrScrCompositorIsEmpty(mpCompositor); 1704 } 1705 1706 bool checkInitedUpdating() 1707 { 1708 if (!mcUpdates) 1709 { 1710 WARN(("not updating")); 1711 return false; 1712 } 1713 1714 return true; 1715 } 1716 private: 1717 GLint mSpuWindow; 1718 const struct VBOXVR_SCR_COMPOSITOR * mpCompositor; 1719 uint32_t mcUpdates; 1720 int32_t mxPos; 1721 int32_t myPos; 1722 uint32_t mWidth; 1723 uint32_t mHeight; 1724 CR_FBWIN_FLAGS mFlags; 1725 uint64_t mParentId; 1726 }; 1727 1728 class CrFbDisplayWindow : public CrFbDisplayBase 1729 { 1730 public: 1731 CrFbDisplayWindow(CrFbWindow *pWindow, const RTRECT *pViewportRect) : 1732 mpWindow(pWindow), 1733 mViewportRect(*pViewportRect) 1734 { 1735 CRASSERT(pWindow); 1736 } 1737 1738 virtual ~CrFbDisplayWindow() 1739 { 1740 if (mpWindow) 1741 delete mpWindow; 1742 } 1743 1744 virtual int UpdateBegin(struct CR_FRAMEBUFFER *pFb) 1745 { 1746 int rc = CrFbDisplayBase::UpdateBegin(pFb); 1747 if (!RT_SUCCESS(rc)) 1748 { 1749 WARN(("err")); 1750 return rc; 1751 } 1752 1753 return mpWindow->UpdateBegin(); 1754 } 1755 1756 virtual void UpdateEnd(struct CR_FRAMEBUFFER *pFb) 1757 { 1758 mpWindow->UpdateEnd(); 1759 1760 CrFbDisplayBase::UpdateEnd(pFb); 1761 } 1762 1763 virtual int EntryCreated(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 1764 { 1765 int rc = CrFbDisplayBase::EntryCreated(pFb, hEntry); 1766 if (!RT_SUCCESS(rc)) 1767 { 1768 WARN(("err")); 1769 return rc; 1770 } 1771 1772 if (mpWindow->GetParentId()) 1773 { 1774 rc = mpWindow->Create(); 1775 if (!RT_SUCCESS(rc)) 1776 { 1777 WARN(("err")); 1778 return rc; 1779 } 1780 } 1781 1782 return VINF_SUCCESS; 1783 } 1784 1785 virtual int EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry) 1786 { 1787 int rc = CrFbDisplayBase::EntryReplaced(pFb, hNewEntry, hReplacedEntry); 1788 if (!RT_SUCCESS(rc)) 1789 { 1790 WARN(("err")); 1791 return rc; 1792 } 1793 1794 if (mpWindow->GetParentId()) 1795 { 1796 rc = mpWindow->Create(); 1797 if (!RT_SUCCESS(rc)) 1798 { 1799 WARN(("err")); 1800 return rc; 1801 } 1802 } 1803 1804 return VINF_SUCCESS; 1805 } 1806 1807 virtual int EntryRemoved(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 1808 { 1809 int rc = CrFbDisplayBase::EntryRemoved(pFb, hEntry); 1810 if (!RT_SUCCESS(rc)) 1811 { 1812 WARN(("err")); 1813 return rc; 1814 } 1815 1816 return mpWindow->SetVisibleRegionsChanged(); 1817 } 1818 1819 virtual int EntryPosChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 1820 { 1821 int rc = CrFbDisplayBase::EntryPosChanged(pFb, hEntry); 1822 if (!RT_SUCCESS(rc)) 1823 { 1824 WARN(("err")); 1825 return rc; 1826 } 1827 1828 return mpWindow->SetVisibleRegionsChanged(); 1829 } 1830 1831 virtual int RegionsChanged(struct CR_FRAMEBUFFER *pFb) 1832 { 1833 int rc = CrFbDisplayBase::RegionsChanged(pFb); 1834 if (!RT_SUCCESS(rc)) 1835 { 1836 WARN(("err")); 1837 return rc; 1838 } 1839 1840 return mpWindow->SetVisibleRegionsChanged(); 1841 } 1842 1843 virtual int FramebufferChanged(struct CR_FRAMEBUFFER *pFb) 1844 { 1845 int rc = CrFbDisplayBase::FramebufferChanged(pFb); 1846 if (!RT_SUCCESS(rc)) 1847 { 1848 WARN(("err")); 1849 return rc; 1850 } 1851 1852 return screenChanged(); 1853 } 1854 1855 virtual int setViewportRect(const RTRECT *pViewportRect) 1856 { 1857 if (!isUpdating()) 1858 { 1859 WARN(("not updating!")); 1860 return VERR_INVALID_STATE; 1861 } 1862 1863 if (pViewportRect->xLeft != mViewportRect.xLeft || pViewportRect->yTop != mViewportRect.yTop) 1864 { 1865 const RTRECT* pRect = CrVrScrCompositorRectGet(getCompositor()); 1866 int rc = mpWindow->SetPosition(pRect->xLeft - mViewportRect.xLeft, pRect->yTop - mViewportRect.yTop); 1867 if (!RT_SUCCESS(rc)) 1868 { 1869 WARN(("SetPosition failed")); 1870 return rc; 1871 } 1872 } 1873 1874 mViewportRect = *pViewportRect; 1875 1876 return VINF_SUCCESS; 1877 } 1878 1879 virtual CrFbWindow * windowDetach() 1880 { 1881 if (isUpdating()) 1882 { 1883 WARN(("updating!")); 1884 return NULL; 1885 } 1886 1887 CrFbWindow * pWindow = mpWindow; 1888 if (mpWindow) 1889 { 1890 windowCleanup(); 1891 mpWindow = NULL; 1892 } 1893 return pWindow; 1894 } 1895 1896 virtual CrFbWindow * windowAttach(CrFbWindow * pNewWindow) 1897 { 1898 if (isUpdating()) 1899 { 1900 WARN(("updating!")); 1901 return NULL; 1902 } 1903 1904 CrFbWindow * pOld = mpWindow; 1905 if (mpWindow) 1906 windowDetach(); 1907 1908 mpWindow = pNewWindow; 1909 if (pNewWindow) 1910 windowSync(); 1911 1912 return mpWindow; 1913 } 1914 1915 virtual int reparent(uint64_t parentId) 1916 { 1917 if (!isUpdating()) 1918 { 1919 WARN(("not updating!")); 1920 return VERR_INVALID_STATE; 1921 } 1922 1923 int rc = mpWindow->Reparent(parentId); 1924 if (!RT_SUCCESS(rc)) 1925 WARN(("window reparent failed")); 1926 1927 return rc; 1928 } 1929 1930 protected: 1931 virtual int screenChanged() 1932 { 1933 if (!isUpdating()) 1934 { 1935 WARN(("not updating!")); 1936 return VERR_INVALID_STATE; 1937 } 1938 1939 const RTRECT* pRect = CrVrScrCompositorRectGet(getCompositor()); 1940 int rc = mpWindow->SetPosition(pRect->xLeft - mViewportRect.xLeft, pRect->yTop - mViewportRect.yTop); 1941 if (!RT_SUCCESS(rc)) 1942 { 1943 WARN(("SetComposition failed rc %d", rc)); 1944 return rc; 1945 } 1946 1947 mpWindow->SetVisibleRegionsChanged(); 1948 1949 return mpWindow->SetSize((uint32_t)(pRect->xRight - pRect->xLeft), (uint32_t)(pRect->yBottom - pRect->yTop)); 1950 } 1951 1952 virtual int windowCleanup() 1953 { 1954 int rc = mpWindow->UpdateBegin(); 1955 if (!RT_SUCCESS(rc)) 1956 { 1957 WARN(("err")); 1958 return rc; 1959 } 1960 1961 rc = mpWindow->SetVisible(false); 1962 if (!RT_SUCCESS(rc)) 1963 { 1964 WARN(("err")); 1965 mpWindow->UpdateEnd(); 1966 return rc; 1967 } 1968 1969 rc = mpWindow->SetCompositor(NULL); 1970 if (!RT_SUCCESS(rc)) 1971 { 1972 WARN(("err")); 1973 mpWindow->UpdateEnd(); 1974 return rc; 1975 } 1976 1977 mpWindow->UpdateEnd(); 1978 1979 return VINF_SUCCESS; 1980 } 1981 1982 virtual int fbCleanup() 1983 { 1984 int rc = windowCleanup(); 1985 if (!RT_SUCCESS(rc)) 1986 { 1987 WARN(("windowCleanup failed")); 1988 return rc; 1989 } 1990 return CrFbDisplayBase::fbCleanup(); 1991 } 1992 1993 virtual int windowSync() 1994 { 1995 const struct VBOXVR_SCR_COMPOSITOR* pCompositor = getCompositor(); 1996 const RTRECT* pRect = CrVrScrCompositorRectGet(pCompositor); 1997 1998 int rc = mpWindow->UpdateBegin(); 1999 if (!RT_SUCCESS(rc)) 2000 { 2001 WARN(("err")); 2002 return rc; 2003 } 2004 2005 rc = mpWindow->SetCompositor(pCompositor); 2006 if (!RT_SUCCESS(rc)) 2007 { 2008 WARN(("err")); 2009 mpWindow->UpdateEnd(); 2010 return rc; 2011 } 2012 2013 rc = mpWindow->SetPosition(pRect->xLeft - mViewportRect.xLeft, pRect->yTop - mViewportRect.yTop); 2014 if (!RT_SUCCESS(rc)) 2015 { 2016 WARN(("err")); 2017 mpWindow->UpdateEnd(); 2018 return rc; 2019 } 2020 2021 rc = mpWindow->SetSize((uint32_t)(pRect->xRight - pRect->xLeft), (uint32_t)(pRect->yBottom - pRect->yTop)); 2022 if (!RT_SUCCESS(rc)) 2023 { 2024 WARN(("err")); 2025 mpWindow->UpdateEnd(); 2026 return rc; 2027 } 2028 2029 rc = mpWindow->SetVisible(true); 2030 if (!RT_SUCCESS(rc)) 2031 { 2032 WARN(("err")); 2033 mpWindow->UpdateEnd(); 2034 return rc; 2035 } 2036 2037 mpWindow->UpdateEnd(); 2038 2039 return rc; 2040 } 2041 2042 virtual int fbSync() 2043 { 2044 int rc = CrFbDisplayBase::fbSync(); 2045 if (!RT_SUCCESS(rc)) 2046 { 2047 WARN(("err")); 2048 return rc; 2049 } 2050 2051 return windowSync(); 2052 } 2053 2054 virtual const struct VBOXVR_SCR_COMPOSITOR* getCompositor() 2055 { 2056 return CrFbGetCompositor(getFramebuffer()); 2057 } 2058 2059 CrFbWindow* getWindow() {return mpWindow;} 2060 private: 2061 CrFbWindow *mpWindow; 2062 RTRECT mViewportRect; 2063 }; 2064 2065 class CrFbDisplayWindowRootVr : public CrFbDisplayWindow 2066 { 2067 public: 2068 CrFbDisplayWindowRootVr(CrFbWindow *pWindow, const RTRECT *pViewportRect) : 2069 CrFbDisplayWindow(pWindow, pViewportRect) 2070 { 2071 CrVrScrCompositorInit(&mCompositor, NULL); 2072 memset(&mPos, 0, sizeof (mPos)); 2073 } 2074 2075 virtual int EntryCreated(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2076 { 2077 int rc = CrFbDisplayWindow::EntryCreated(pFb, hEntry); 2078 if (!RT_SUCCESS(rc)) 2079 { 2080 WARN(("err")); 2081 return rc; 2082 } 2083 2084 Assert(!CrFbDDataEntryGet(hEntry, slotGet())); 2085 2086 const VBOXVR_SCR_COMPOSITOR_ENTRY* pSrcEntry = CrFbEntryGetCompositorEntry(hEntry); 2087 VBOXVR_SCR_COMPOSITOR_ENTRY *pMyEntry = entryAlloc(); 2088 CrVrScrCompositorEntryInit(pMyEntry, CrVrScrCompositorEntryRectGet(pSrcEntry), CrVrScrCompositorEntryTexGet(pSrcEntry), NULL); 2089 CrVrScrCompositorEntryFlagsSet(pMyEntry, CrVrScrCompositorEntryFlagsGet(pSrcEntry)); 2090 rc = CrFbDDataEntryPut(hEntry, slotGet(), pMyEntry); 2091 if (!RT_SUCCESS(rc)) 2092 { 2093 WARN(("CrFbDDataEntryPut failed rc %d", rc)); 2094 entryFree(pMyEntry); 2095 return rc; 2096 } 2097 2098 return VINF_SUCCESS; 2099 } 2100 2101 virtual int EntryAdded(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2102 { 2103 int rc = CrFbDisplayWindow::EntryAdded(pFb, hEntry); 2104 if (!RT_SUCCESS(rc)) 2105 { 2106 WARN(("err")); 2107 return rc; 2108 } 2109 2110 const VBOXVR_SCR_COMPOSITOR_ENTRY* pSrcEntry = CrFbEntryGetCompositorEntry(hEntry); 2111 VBOXVR_SCR_COMPOSITOR_ENTRY *pMyEntry = (VBOXVR_SCR_COMPOSITOR_ENTRY*)CrFbDDataEntryGet(hEntry, slotGet()); 2112 Assert(pMyEntry); 2113 CrVrScrCompositorEntryTexSet(pMyEntry, CrVrScrCompositorEntryTexGet(pSrcEntry)); 2114 2115 return VINF_SUCCESS; 2116 } 2117 2118 virtual int EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry) 2119 { 2120 int rc = CrFbDisplayWindow::EntryReplaced(pFb, hNewEntry, hReplacedEntry); 2121 if (!RT_SUCCESS(rc)) 2122 { 2123 WARN(("err")); 2124 return rc; 2125 } 2126 2127 const VBOXVR_SCR_COMPOSITOR_ENTRY* pSrcNewEntry = CrFbEntryGetCompositorEntry(hNewEntry); 2128 VBOXVR_SCR_COMPOSITOR_ENTRY *pMyEntry = (VBOXVR_SCR_COMPOSITOR_ENTRY*)CrFbDDataEntryGet(hNewEntry, slotGet()); 2129 CrVrScrCompositorEntryTexSet(pMyEntry, CrVrScrCompositorEntryTexGet(pSrcNewEntry)); 2130 2131 return VINF_SUCCESS; 2132 } 2133 2134 virtual int EntryTexChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2135 { 2136 int rc = CrFbDisplayWindow::EntryTexChanged(pFb, hEntry); 2137 if (!RT_SUCCESS(rc)) 2138 { 2139 WARN(("err")); 2140 return rc; 2141 } 2142 2143 const VBOXVR_SCR_COMPOSITOR_ENTRY* pSrcEntry = CrFbEntryGetCompositorEntry(hEntry); 2144 VBOXVR_SCR_COMPOSITOR_ENTRY *pMyEntry = (VBOXVR_SCR_COMPOSITOR_ENTRY*)CrFbDDataEntryGet(hEntry, slotGet()); 2145 CrVrScrCompositorEntryTexSet(pMyEntry, CrVrScrCompositorEntryTexGet(pSrcEntry)); 2146 2147 return VINF_SUCCESS; 2148 } 2149 2150 virtual int EntryRemoved(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2151 { 2152 int rc = CrFbDisplayWindow::EntryRemoved(pFb, hEntry); 2153 if (!RT_SUCCESS(rc)) 2154 { 2155 WARN(("err")); 2156 return rc; 2157 } 2158 2159 return VINF_SUCCESS; 2160 } 2161 2162 virtual int EntryDestroyed(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2163 { 2164 int rc = CrFbDisplayWindow::EntryDestroyed(pFb, hEntry); 2165 if (!RT_SUCCESS(rc)) 2166 { 2167 WARN(("err")); 2168 return rc; 2169 } 2170 2171 const VBOXVR_SCR_COMPOSITOR_ENTRY* pSrcEntry = CrFbEntryGetCompositorEntry(hEntry); 2172 VBOXVR_SCR_COMPOSITOR_ENTRY *pMyEntry = (VBOXVR_SCR_COMPOSITOR_ENTRY*)CrFbDDataEntryGet(hEntry, slotGet()); 2173 CrVrScrCompositorEntryCleanup(pMyEntry); 2174 entryFree(pMyEntry); 2175 2176 return VINF_SUCCESS; 2177 } 2178 2179 virtual int RegionsChanged(struct CR_FRAMEBUFFER *pFb) 2180 { 2181 int rc = CrFbDisplayWindow::RegionsChanged(pFb); 2182 if (!RT_SUCCESS(rc)) 2183 { 2184 WARN(("err")); 2185 return rc; 2186 } 2187 2188 rc = synchCompositorRegions(); 2189 if (!RT_SUCCESS(rc)) 2190 { 2191 WARN(("err")); 2192 return rc; 2193 } 2194 2195 return VINF_SUCCESS; 2196 } 2197 2198 virtual int setViewportRect(const RTRECT *pViewportRect) 2199 { 2200 int rc = CrFbDisplayWindow::setViewportRect(pViewportRect); 2201 if (!RT_SUCCESS(rc)) 2202 { 2203 WARN(("err")); 2204 return rc; 2205 } 2206 2207 rc = synchCompositorData(); 2208 if (!RT_SUCCESS(rc)) 2209 { 2210 WARN(("err")); 2211 return rc; 2212 } 2213 2214 return VINF_SUCCESS; 2215 } 2216 2217 protected: 2218 virtual int screenChanged() 2219 { 2220 int rc = CrFbDisplayWindow::screenChanged(); 2221 if (!RT_SUCCESS(rc)) 2222 { 2223 WARN(("screenChanged failed %d", rc)); 2224 return rc; 2225 } 2226 2227 rc = synchCompositorData(); 2228 if (!RT_SUCCESS(rc)) 2229 { 2230 WARN(("err")); 2231 return rc; 2232 } 2233 2234 return VINF_SUCCESS; 2235 } 2236 2237 virtual int fbCleanup() 2238 { 2239 int rc = clearCompositor(); 2240 if (!RT_SUCCESS(rc)) 2241 { 2242 WARN(("err")); 2243 return rc; 2244 } 2245 2246 return CrFbDisplayWindow::fbCleanup(); 2247 } 2248 2249 virtual int fbSync() 2250 { 2251 int rc = synchCompositor(); 2252 if (!RT_SUCCESS(rc)) 2253 { 2254 WARN(("err")); 2255 return rc; 2256 } 2257 2258 return CrFbDisplayWindow::fbSync(); 2259 } 2260 2261 VBOXVR_SCR_COMPOSITOR_ENTRY* entryAlloc() 2262 { 2263 #ifndef VBOXVDBG_MEMCACHE_DISABLE 2264 return (VBOXVR_SCR_COMPOSITOR_ENTRY*)RTMemCacheAlloc(g_CrPresenter.CEntryLookasideList); 2265 #else 2266 return (VBOXVR_SCR_COMPOSITOR_ENTRY*)RTMemAlloc(sizeof (VBOXVR_SCR_COMPOSITOR_ENTRY)); 2267 #endif 2268 } 2269 2270 void entryFree(VBOXVR_SCR_COMPOSITOR_ENTRY* pEntry) 2271 { 2272 Assert(!CrVrScrCompositorEntryIsUsed(pEntry)); 2273 #ifndef VBOXVDBG_MEMCACHE_DISABLE 2274 RTMemCacheFree(g_CrPresenter.CEntryLookasideList, pEntry); 2275 #else 2276 RTMemFree(pEntry); 2277 #endif 2278 } 2279 2280 int synchCompositorRegions() 2281 { 2282 int rc; 2283 2284 rootVrTranslateForPos(); 2285 2286 /* ensure the rootvr compositor does not hold any data, 2287 * i.e. cleanup all rootvr entries data */ 2288 CrVrScrCompositorClear(&mCompositor); 2289 2290 rc = CrVrScrCompositorIntersectedList(CrFbGetCompositor(getFramebuffer()), &cr_server.RootVr, &mCompositor, rootVrGetCEntry, this, NULL); 2291 if (!RT_SUCCESS(rc)) 2292 { 2293 WARN(("CrVrScrCompositorIntersectedList failed, rc %d", rc)); 2294 return rc; 2295 } 2296 2297 return getWindow()->SetVisibleRegionsChanged(); 2298 } 2299 2300 int synchCompositorData() 2301 { 2302 CrVrScrCompositorClear(&mCompositor); 2303 2304 const struct VBVAINFOSCREEN* pScreenInfo = CrFbGetScreenInfo(getFramebuffer()); 2305 mPos.x = pScreenInfo->i32OriginX; 2306 mPos.y = pScreenInfo->i32OriginY; 2307 2308 int rc = CrVrScrCompositorRectSet(&mCompositor, CrVrScrCompositorRectGet(CrFbGetCompositor(getFramebuffer())), NULL); 2309 if (!RT_SUCCESS(rc)) 2310 { 2311 WARN(("CrVrScrCompositorRectSet failed, rc %d", rc)); 2312 return rc; 2313 } 2314 rc = synchCompositorRegions(); 2315 if (!RT_SUCCESS(rc)) 2316 { 2317 WARN(("synchCompositorRegions failed, rc %d", rc)); 2318 return rc; 2319 } 2320 2321 return rc; 2322 } 2323 2324 virtual int synchCompositor() 2325 { 2326 int rc = CrVrScrCompositorRectSet(&mCompositor, CrVrScrCompositorRectGet(CrFbGetCompositor(getFramebuffer())), NULL); 2327 if (!RT_SUCCESS(rc)) 2328 { 2329 WARN(("CrVrScrCompositorRectSet failed, rc %d", rc)); 2330 return rc; 2331 } 2332 2333 rc = fbSynchAddAllEntries(); 2334 if (!RT_SUCCESS(rc)) 2335 { 2336 WARN(("fbSynchAddAllEntries failed, rc %d", rc)); 2337 return rc; 2338 } 2339 2340 rc = synchCompositorRegions(); 2341 if (!RT_SUCCESS(rc)) 2342 { 2343 WARN(("synchCompositorRegions failed, rc %d", rc)); 2344 return rc; 2345 } 2346 2347 return rc; 2348 } 2349 2350 virtual int clearCompositor() 2351 { 2352 return fbCleanupRemoveAllEntries(true); 2353 } 2354 2355 void rootVrTranslateForPos() 2356 { 2357 int32_t dx = cr_server.RootVrCurPoint.x - mPos.x; 2358 int32_t dy = cr_server.RootVrCurPoint.y - mPos.y; 2359 2360 cr_server.RootVrCurPoint.x = mPos.x; 2361 cr_server.RootVrCurPoint.y = mPos.y; 2362 2363 VBoxVrListTranslate(&cr_server.RootVr, dx, dy); 2364 } 2365 2366 static DECLCALLBACK(VBOXVR_SCR_COMPOSITOR_ENTRY*) rootVrGetCEntry(const VBOXVR_SCR_COMPOSITOR_ENTRY*pEntry, void *pvContext) 2367 { 2368 CrFbDisplayWindowRootVr *pThis = (CrFbDisplayWindowRootVr*)pvContext; 2369 HCR_FRAMEBUFFER_ENTRY hEntry = CrFbEntryFromCompositorEntry(pEntry); 2370 VBOXVR_SCR_COMPOSITOR_ENTRY *pMyEntry = (VBOXVR_SCR_COMPOSITOR_ENTRY*)CrFbDDataEntryGet(hEntry, pThis->slotGet()); 2371 Assert(!CrVrScrCompositorEntryIsUsed(pMyEntry)); 2372 CrVrScrCompositorEntryRectSet(&pThis->mCompositor, pMyEntry, CrVrScrCompositorEntryRectGet(pEntry)); 2373 return pMyEntry; 2374 } 2375 private: 2376 VBOXVR_SCR_COMPOSITOR mCompositor; 2377 RTPOINT mPos; 2378 }; 2379 2380 class CrFbDisplayVrdp : public CrFbDisplayBase 2381 { 2382 public: 2383 CrFbDisplayVrdp() 2384 { 2385 memset(&mPos, 0, sizeof (mPos)); 2386 } 2387 2388 virtual int EntryCreated(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2389 { 2390 int rc = CrFbDisplayBase::EntryCreated(pFb, hEntry); 2391 if (!RT_SUCCESS(rc)) 2392 { 2393 WARN(("EntryAdded failed rc %d", rc)); 2394 return rc; 2395 } 2396 2397 Assert(!CrFbDDataEntryGet(hEntry, slotGet())); 2398 rc = vrdpCreate(pFb, hEntry); 2399 if (!RT_SUCCESS(rc)) 2400 { 2401 WARN(("vrdpCreate failed rc %d", rc)); 2402 return rc; 2403 } 2404 2405 return VINF_SUCCESS; 2406 } 2407 2408 virtual int EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry) 2409 { 2410 int rc = CrFbDisplayBase::EntryReplaced(pFb, hNewEntry, hReplacedEntry); 2411 if (!RT_SUCCESS(rc)) 2412 { 2413 WARN(("err")); 2414 return rc; 2415 } 2416 2417 return vrdpFrame(hNewEntry); 2418 } 2419 2420 virtual int EntryTexChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2421 { 2422 int rc = CrFbDisplayBase::EntryTexChanged(pFb, hEntry); 2423 if (!RT_SUCCESS(rc)) 2424 { 2425 WARN(("err")); 2426 return rc; 2427 } 2428 2429 return vrdpFrame(hEntry); 2430 } 2431 2432 virtual int EntryRemoved(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2433 { 2434 int rc = CrFbDisplayBase::EntryRemoved(pFb, hEntry); 2435 if (!RT_SUCCESS(rc)) 2436 { 2437 WARN(("err")); 2438 return rc; 2439 } 2440 2441 return vrdpRegions(pFb, hEntry); 2442 } 2443 2444 virtual int EntryDestroyed(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2445 { 2446 int rc = CrFbDisplayBase::EntryDestroyed(pFb, hEntry); 2447 if (!RT_SUCCESS(rc)) 2448 { 2449 WARN(("err")); 2450 return rc; 2451 } 2452 2453 vrdpDestroy(hEntry); 2454 return VINF_SUCCESS; 2455 } 2456 2457 virtual int EntryPosChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2458 { 2459 int rc = CrFbDisplayBase::EntryPosChanged(pFb, hEntry); 2460 if (!RT_SUCCESS(rc)) 2461 { 2462 WARN(("err")); 2463 return rc; 2464 } 2465 2466 vrdpGeometry(hEntry); 2467 2468 return VINF_SUCCESS; 2469 } 2470 2471 virtual int RegionsChanged(struct CR_FRAMEBUFFER *pFb) 2472 { 2473 int rc = CrFbDisplayBase::RegionsChanged(pFb); 2474 if (!RT_SUCCESS(rc)) 2475 { 2476 WARN(("err")); 2477 return rc; 2478 } 2479 2480 return vrdpRegionsAll(pFb); 2481 } 2482 2483 virtual int FramebufferChanged(struct CR_FRAMEBUFFER *pFb) 2484 { 2485 int rc = CrFbDisplayBase::FramebufferChanged(pFb); 2486 if (!RT_SUCCESS(rc)) 2487 { 2488 WARN(("err")); 2489 return rc; 2490 } 2491 2492 syncPos(); 2493 2494 rc = vrdpSyncEntryAll(pFb); 2495 if (!RT_SUCCESS(rc)) 2496 { 2497 WARN(("err")); 2498 return rc; 2499 } 2500 2501 return vrdpRegionsAll(pFb); 2502 } 2503 2504 protected: 2505 void syncPos() 2506 { 2507 const struct VBVAINFOSCREEN* pScreenInfo = CrFbGetScreenInfo(getFramebuffer()); 2508 mPos.x = pScreenInfo->i32OriginX; 2509 mPos.y = pScreenInfo->i32OriginY; 2510 } 2511 2512 virtual int fbCleanup() 2513 { 2514 int rc = fbCleanupRemoveAllEntries(true); 2515 if (!RT_SUCCESS(rc)) 2516 { 2517 WARN(("err")); 2518 return rc; 2519 } 2520 2521 return CrFbDisplayBase::fbCleanup(); 2522 } 2523 2524 virtual int fbSync() 2525 { 2526 syncPos(); 2527 2528 int rc = fbSynchAddAllEntries(); 2529 if (!RT_SUCCESS(rc)) 2530 { 2531 WARN(("err")); 2532 return rc; 2533 } 2534 2535 return CrFbDisplayBase::fbSync(); 2536 } 2537 protected: 2538 void vrdpDestroy(HCR_FRAMEBUFFER_ENTRY hEntry) 2539 { 2540 void *pVrdp = CrFbDDataEntryGet(hEntry, slotGet()); 2541 cr_server.outputRedirect.CROREnd(pVrdp); 2542 } 2543 2544 void vrdpGeometry(HCR_FRAMEBUFFER_ENTRY hEntry) 2545 { 2546 void *pVrdp = CrFbDDataEntryGet(hEntry, slotGet()); 2547 const VBOXVR_SCR_COMPOSITOR_ENTRY* pEntry = CrFbEntryGetCompositorEntry(hEntry); 2548 2549 cr_server.outputRedirect.CRORGeometry(pVrdp, 2550 mPos.x + CrVrScrCompositorEntryRectGet(pEntry)->xLeft, 2551 mPos.y + CrVrScrCompositorEntryRectGet(pEntry)->yTop, 2552 CrVrScrCompositorEntryTexGet(pEntry)->Tex.width, 2553 CrVrScrCompositorEntryTexGet(pEntry)->Tex.height); 2554 } 2555 2556 int vrdpRegions(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2557 { 2558 void *pVrdp = CrFbDDataEntryGet(hEntry, slotGet()); 2559 const struct VBOXVR_SCR_COMPOSITOR* pCompositor = CrFbGetCompositor(pFb); 2560 const VBOXVR_SCR_COMPOSITOR_ENTRY* pEntry = CrFbEntryGetCompositorEntry(hEntry); 2561 uint32_t cRects; 2562 const RTRECT *pRects; 2563 2564 int rc = CrVrScrCompositorEntryRegionsGet(pCompositor, pEntry, &cRects, NULL, &pRects, NULL); 2565 if (!RT_SUCCESS(rc)) 2566 { 2567 WARN(("CrVrScrCompositorEntryRegionsGet failed, rc %d", rc)); 2568 return rc; 2569 } 2570 2571 cr_server.outputRedirect.CRORVisibleRegion(pVrdp, cRects, pRects); 2572 return VINF_SUCCESS; 2573 } 2574 2575 int vrdpFrame(HCR_FRAMEBUFFER_ENTRY hEntry) 2576 { 2577 void *pVrdp = CrFbDDataEntryGet(hEntry, slotGet()); 2578 const VBOXVR_SCR_COMPOSITOR_ENTRY* pEntry = CrFbEntryGetCompositorEntry(hEntry); 2579 CR_TEXDATA *pTex = CrVrScrCompositorEntryTexGet(pEntry); 2580 const CR_BLITTER_IMG *pImg; 2581 int rc = CrTdBltDataAcquire(pTex, GL_BGRA, !!(CrVrScrCompositorEntryFlagsGet(pEntry) & CRBLT_F_INVERT_SRC_YCOORDS), &pImg); 2582 if (!RT_SUCCESS(rc)) 2583 { 2584 WARN(("CrTdBltDataAcquire failed rc %d", rc)); 2585 return rc; 2586 } 2587 2588 cr_server.outputRedirect.CRORFrame(pVrdp, pImg->pvData, pImg->cbData); 2589 CrTdBltDataRelease(pTex); 2590 return VINF_SUCCESS; 2591 } 2592 2593 int vrdpRegionsAll(struct CR_FRAMEBUFFER *pFb) 2594 { 2595 const struct VBOXVR_SCR_COMPOSITOR* pCompositor = CrFbGetCompositor(pFb); 2596 VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR Iter; 2597 CrVrScrCompositorConstIterInit(pCompositor, &Iter); 2598 const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry; 2599 while ((pEntry = CrVrScrCompositorConstIterNext(&Iter)) != NULL) 2600 { 2601 HCR_FRAMEBUFFER_ENTRY hEntry = CrFbEntryFromCompositorEntry(pEntry); 2602 vrdpRegions(pFb, hEntry); 2603 } 2604 2605 return VINF_SUCCESS; 2606 } 2607 2608 int vrdpSynchEntry(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2609 { 2610 vrdpGeometry(hEntry); 2611 2612 return vrdpRegions(pFb, hEntry);; 2613 } 2614 2615 int vrdpSyncEntryAll(struct CR_FRAMEBUFFER *pFb) 2616 { 2617 const struct VBOXVR_SCR_COMPOSITOR* pCompositor = CrFbGetCompositor(pFb); 2618 VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR Iter; 2619 CrVrScrCompositorConstIterInit(pCompositor, &Iter); 2620 const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry; 2621 while ((pEntry = CrVrScrCompositorConstIterNext(&Iter)) != NULL) 2622 { 2623 HCR_FRAMEBUFFER_ENTRY hEntry = CrFbEntryFromCompositorEntry(pEntry); 2624 int rc = vrdpSynchEntry(pFb, hEntry); 2625 if (!RT_SUCCESS(rc)) 2626 { 2627 WARN(("vrdpSynchEntry failed rc %d", rc)); 2628 return rc; 2629 } 2630 } 2631 2632 return VINF_SUCCESS; 2633 } 2634 2635 int vrdpCreate(HCR_FRAMEBUFFER hFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2636 { 2637 void *pVrdp; 2638 2639 /* Query supported formats. */ 2640 uint32_t cbFormats = 4096; 2641 char *pachFormats = (char *)crAlloc(cbFormats); 2642 2643 if (!pachFormats) 2644 { 2645 WARN(("crAlloc failed")); 2646 return VERR_NO_MEMORY; 2647 } 2648 2649 int rc = cr_server.outputRedirect.CRORContextProperty(cr_server.outputRedirect.pvContext, 2650 0 /* H3DOR_PROP_FORMATS */, // @todo from a header 2651 pachFormats, cbFormats, &cbFormats); 2652 if (RT_SUCCESS(rc)) 2653 { 2654 if (RTStrStr(pachFormats, "H3DOR_FMT_RGBA_TOPDOWN")) 2655 { 2656 cr_server.outputRedirect.CRORBegin(cr_server.outputRedirect.pvContext, 2657 &pVrdp, 2658 "H3DOR_FMT_RGBA_TOPDOWN"); // @todo from a header 2659 2660 if (pVrdp) 2661 { 2662 rc = CrFbDDataEntryPut(hEntry, slotGet(), pVrdp); 2663 if (RT_SUCCESS(rc)) 2664 { 2665 vrdpGeometry(hEntry); 2666 vrdpRegions(hFb, hEntry); 2667 vrdpFrame(hEntry); 2668 return VINF_SUCCESS; 2669 } 2670 else 2671 WARN(("CrFbDDataEntryPut failed rc %d", rc)); 2672 2673 cr_server.outputRedirect.CROREnd(pVrdp); 2674 } 2675 else 2676 { 2677 WARN(("CRORBegin failed")); 2678 rc = VERR_GENERAL_FAILURE; 2679 } 2680 } 2681 } 2682 else 2683 WARN(("CRORContextProperty failed rc %d", rc)); 2684 2685 crFree(pachFormats); 2686 2687 return rc; 2688 } 2689 private: 2690 RTPOINT mPos; 2691 }; 2692 2693 CrFbDisplayBase::~CrFbDisplayBase() 2694 { 2695 Assert(!mcUpdates); 2696 2697 if (mpContainer) 2698 mpContainer->remove(this); 2699 } 2700 2701 2702 #if 0 2703 2704 2705 2706 2707 2708 void crDbgDumpRect(uint32_t i, const RTRECT *pRect) 2709 { 2710 crDebug("%d: (%d;%d) X (%d;%d)", i, pRect->xLeft, pRect->yTop, pRect->xRight, pRect->yBottom); 2711 } 2712 2713 void crDbgDumpRects(uint32_t cRects, const RTRECT *paRects) 2714 { 2715 crDebug("Dumping rects (%d)", cRects); 2716 for (uint32_t i = 0; i < cRects; ++i) 2717 { 2718 crDbgDumpRect(i, &paRects[i]); 2719 } 2720 crDebug("End Dumping rects (%d)", cRects); 2721 } 2722 2723 int crServerDisplaySaveState(PSSMHANDLE pSSM) 2724 { 2725 int rc; 2726 int cDisplays = 0, i; 2727 for (i = 0; i < cr_server.screenCount; ++i) 2728 { 2729 if (ASMBitTest(cr_server.DisplaysInitMap, i) && !CrDpIsEmpty(&cr_server.aDispplays[i])) 2730 ++cDisplays; 2731 } 2732 2733 rc = SSMR3PutS32(pSSM, cDisplays); 2734 AssertRCReturn(rc, rc); 2735 2736 if (!cDisplays) 2737 return VINF_SUCCESS; 2738 2739 rc = SSMR3PutS32(pSSM, cr_server.screenCount); 2740 AssertRCReturn(rc, rc); 2741 2742 for (i = 0; i < cr_server.screenCount; ++i) 2743 { 2744 rc = SSMR3PutS32(pSSM, cr_server.screen[i].x); 2745 AssertRCReturn(rc, rc); 2746 2747 rc = SSMR3PutS32(pSSM, cr_server.screen[i].y); 2748 AssertRCReturn(rc, rc); 2749 2750 rc = SSMR3PutU32(pSSM, cr_server.screen[i].w); 2751 AssertRCReturn(rc, rc); 2752 2753 rc = SSMR3PutU32(pSSM, cr_server.screen[i].h); 2754 AssertRCReturn(rc, rc); 2755 } 2756 2757 for (i = 0; i < cr_server.screenCount; ++i) 2758 { 2759 if (ASMBitTest(cr_server.DisplaysInitMap, i) && !CrDpIsEmpty(&cr_server.aDispplays[i])) 2760 { 2761 rc = SSMR3PutS32(pSSM, i); 2762 AssertRCReturn(rc, rc); 2763 2764 rc = CrDpSaveState(&cr_server.aDispplays[i], pSSM); 2765 AssertRCReturn(rc, rc); 2766 } 2767 } 2768 2769 return VINF_SUCCESS; 2770 } 2771 2772 int crServerDisplayLoadState(PSSMHANDLE pSSM, uint32_t u32Version) 2773 { 2774 2775 } 2776 #endif 2777 2778 HCR_FRAMEBUFFER CrPMgrFbGet(uint32_t idScreen) 2779 { 2780 if (idScreen >= CR_MAX_GUEST_MONITORS) 2781 { 2782 WARN(("invalid idScreen %d", idScreen)); 2783 return NULL; 2784 } 2785 2786 if (!ASMBitTest(g_CrPresenter.aFramebufferInitMap, idScreen)) 2787 { 2788 CrFbInit(&g_CrPresenter.aFramebuffers[idScreen], idScreen); 2789 ASMBitSet(g_CrPresenter.aFramebufferInitMap, idScreen); 2790 } 2791 else 2792 Assert(g_CrPresenter.aFramebuffers[idScreen].ScreenInfo.u32ViewIndex == idScreen); 2793 2794 return &g_CrPresenter.aFramebuffers[idScreen]; 2795 } 2796 2797 HCR_FRAMEBUFFER CrPMgrFbGetEnabled(uint32_t idScreen) 2798 { 2799 if (idScreen >= CR_MAX_GUEST_MONITORS) 2800 { 2801 WARN(("invalid idScreen %d", idScreen)); 2802 return NULL; 2803 } 2804 2805 if (!ASMBitTest(g_CrPresenter.aFramebufferInitMap, idScreen)) 2806 { 2807 return NULL; 2808 } 2809 else 2810 Assert(g_CrPresenter.aFramebuffers[idScreen].ScreenInfo.u32ViewIndex == idScreen); 2811 2812 HCR_FRAMEBUFFER hFb = &g_CrPresenter.aFramebuffers[idScreen]; 2813 2814 if(CrFbIsEnabled(hFb)) 2815 return hFb; 2816 2817 return NULL; 2818 } 2819 2820 static HCR_FRAMEBUFFER crPMgrFbGetNextEnabled(uint32_t i) 2821 { 2822 for (;i < cr_server.screenCount; ++i) 2823 { 2824 HCR_FRAMEBUFFER hFb = CrPMgrFbGetEnabled(i); 2825 if (hFb) 2826 return hFb; 2827 } 2828 2829 return NULL; 2830 } 2831 2832 HCR_FRAMEBUFFER CrPMgrFbGetFirstEnabled() 2833 { 2834 HCR_FRAMEBUFFER hFb = crPMgrFbGetNextEnabled(0); 2835 if (!hFb) 2836 WARN(("no enabled framebuffer found")); 2837 return hFb; 2838 } 2839 2840 HCR_FRAMEBUFFER CrPMgrFbGetNextEnabled(HCR_FRAMEBUFFER hFb) 2841 { 2842 return crPMgrFbGetNextEnabled(hFb->ScreenInfo.u32ViewIndex+1); 2843 } 2844 2845 static uint32_t crPMgrModeAdjustVal(uint32_t u32Mode) 2846 { 2847 u32Mode = CR_PMGR_MODE_ALL & u32Mode; 2848 if (CR_PMGR_MODE_ROOTVR & u32Mode) 2849 u32Mode |= CR_PMGR_MODE_WINDOW; 2850 return u32Mode; 2851 } 2852 2853 int CrPMgrScreenChanged(uint32_t idScreen) 2854 { 2855 if (idScreen >= CR_MAX_GUEST_MONITORS) 2856 { 2857 WARN(("invalid idScreen %d", idScreen)); 2858 return NULL; 2859 } 2860 2861 CR_FBDISPLAY_INFO *pInfo = &g_CrPresenter.aDisplayInfos[idScreen]; 2862 if (pInfo->pDpWin) 2863 { 2864 HCR_FRAMEBUFFER hFb = CrPMgrFbGet(idScreen); 2865 if (CrFbIsUpdating(hFb)) 2866 { 2867 WARN(("trying to update viewport while framebuffer is being updated")); 2868 return VERR_INVALID_STATE; 2869 } 2870 2871 int rc = pInfo->pDpWin->UpdateBegin(hFb); 2872 if (RT_SUCCESS(rc)) 2873 { 2874 pInfo->pDpWin->reparent(cr_server.screen[idScreen].winID); 2875 2876 pInfo->pDpWin->UpdateEnd(hFb); 2877 } 2878 else 2879 WARN(("UpdateBegin failed %d", rc)); 2880 } 2881 2882 return VINF_SUCCESS; 2883 } 2884 2885 int CrPMgrViewportUpdate(uint32_t idScreen) 2886 { 2887 if (idScreen >= CR_MAX_GUEST_MONITORS) 2888 { 2889 WARN(("invalid idScreen %d", idScreen)); 2890 return VERR_INVALID_PARAMETER; 2891 } 2892 2893 CR_FBDISPLAY_INFO *pInfo = &g_CrPresenter.aDisplayInfos[idScreen]; 2894 if (pInfo->pDpWin) 2895 { 2896 HCR_FRAMEBUFFER hFb = CrPMgrFbGet(idScreen); 2897 if (CrFbIsUpdating(hFb)) 2898 { 2899 WARN(("trying to update viewport while framebuffer is being updated")); 2900 return VERR_INVALID_STATE; 2901 } 2902 2903 int rc = pInfo->pDpWin->UpdateBegin(hFb); 2904 if (RT_SUCCESS(rc)) 2905 { 2906 pInfo->pDpWin->setViewportRect(&cr_server.screenVieport[idScreen].Rect); 2907 pInfo->pDpWin->UpdateEnd(hFb); 2908 } 2909 else 2910 WARN(("UpdateBegin failed %d", rc)); 2911 } 2912 2913 return VINF_SUCCESS; 2914 } 2915 2916 int CrPMgrModeModify(HCR_FRAMEBUFFER hFb, uint32_t u32ModeAdd, uint32_t u32ModeRemove) 2917 { 2918 uint32_t idScreen = CrFbGetScreenInfo(hFb)->u32ViewIndex; 2919 2920 CR_FBDISPLAY_INFO *pInfo = &g_CrPresenter.aDisplayInfos[idScreen]; 2921 u32ModeRemove = crPMgrModeAdjustVal(u32ModeRemove); 2922 u32ModeAdd = crPMgrModeAdjustVal(u32ModeAdd); 2923 u32ModeRemove &= pInfo->u32Mode; 2924 u32ModeAdd &= ~(u32ModeRemove | pInfo->u32Mode); 2925 if (!u32ModeRemove && !u32ModeAdd) 2926 return VINF_SUCCESS; 2927 2928 if (!pInfo->pDpComposite) 2929 { 2930 pInfo->pDpComposite = new CrFbDisplayComposite(); 2931 pInfo->pDpComposite->setFramebuffer(hFb); 2932 } 2933 2934 CrFbWindow * pOldWin = NULL; 2935 2936 if (u32ModeRemove & CR_PMGR_MODE_ROOTVR) 2937 { 2938 CRASSERT(pInfo->pDpWinRootVr); 2939 CRASSERT(pInfo->pDpWin == pInfo->pDpWinRootVr); 2940 pInfo->pDpComposite->remove(pInfo->pDpWinRootVr); 2941 pOldWin = pInfo->pDpWinRootVr->windowDetach(); 2942 CRASSERT(pOldWin); 2943 delete pInfo->pDpWinRootVr; 2944 pInfo->pDpWinRootVr = NULL; 2945 pInfo->pDpWin = NULL; 2946 2947 if (!(u32ModeRemove & CR_PMGR_MODE_WINDOW)) 2948 { 2949 /* ensure the window is re-created */ 2950 u32ModeAdd |= CR_PMGR_MODE_WINDOW; 2951 } 2952 } 2953 else if (u32ModeRemove & CR_PMGR_MODE_WINDOW) 2954 { 2955 CRASSERT(!pInfo->pDpWinRootVr); 2956 CRASSERT(pInfo->pDpWin); 2957 pInfo->pDpComposite->remove(pInfo->pDpWin); 2958 pOldWin = pInfo->pDpWin->windowDetach(); 2959 CRASSERT(pOldWin); 2960 delete pInfo->pDpWin; 2961 pInfo->pDpWin = NULL; 2962 } 2963 2964 if (u32ModeRemove & CR_PMGR_MODE_VRDP) 2965 { 2966 CRASSERT(pInfo->pDpVrdp); 2967 if (pInfo->pDpComposite) 2968 pInfo->pDpComposite->remove(pInfo->pDpVrdp); 2969 else 2970 CrFbDisplaySet(hFb, NULL); 2971 2972 delete pInfo->pDpVrdp; 2973 pInfo->pDpVrdp = NULL; 2974 } 2975 2976 CrFbDisplayBase *pDpToSet = NULL; 2977 2978 if (u32ModeAdd & CR_PMGR_MODE_ROOTVR) 2979 { 2980 CRASSERT(!pInfo->pDpWin); 2981 CRASSERT(!pInfo->pDpWinRootVr); 2982 2983 if (!pOldWin) 2984 pOldWin = new CrFbWindow(cr_server.screen[idScreen].winID); 2985 2986 pInfo->pDpWinRootVr = new CrFbDisplayWindowRootVr(pOldWin, &cr_server.screenVieport[idScreen].Rect); 2987 pOldWin = NULL; 2988 pInfo->pDpWin = pInfo->pDpWinRootVr; 2989 pInfo->pDpComposite->add(pInfo->pDpWinRootVr); 2990 } 2991 else if (u32ModeAdd & CR_PMGR_MODE_WINDOW) 2992 { 2993 CRASSERT(!pInfo->pDpWin); 2994 CRASSERT(!pInfo->pDpWinRootVr); 2995 2996 if (!pOldWin) 2997 pOldWin = new CrFbWindow(cr_server.screen[idScreen].winID); 2998 2999 pInfo->pDpWin = new CrFbDisplayWindow(pOldWin, &cr_server.screenVieport[idScreen].Rect); 3000 pOldWin = NULL; 3001 pInfo->pDpComposite->add(pInfo->pDpWin); 3002 } 3003 3004 if (u32ModeAdd & CR_PMGR_MODE_VRDP) 3005 { 3006 CRASSERT(!pInfo->pDpVrdp); 3007 pInfo->pDpVrdp = new CrFbDisplayVrdp(); 3008 pInfo->pDpComposite->add(pInfo->pDpVrdp); 3009 } 3010 3011 if (pInfo->pDpComposite->getDisplayCount() > 1) 3012 { 3013 ICrFbDisplay* pCur = CrFbDisplayGet(hFb); 3014 if (pCur != (ICrFbDisplay*)pInfo->pDpComposite) 3015 CrFbDisplaySet(hFb, pInfo->pDpComposite); 3016 } 3017 else 3018 { 3019 ICrFbDisplay* pCur = CrFbDisplayGet(hFb); 3020 ICrFbDisplay* pFirst = pInfo->pDpComposite->first(); 3021 if (pCur != pFirst) 3022 CrFbDisplaySet(hFb, pFirst); 3023 } 3024 3025 if (pOldWin) 3026 delete pOldWin; 3027 3028 pInfo->u32Mode = ((pInfo->u32Mode | u32ModeAdd) & ~u32ModeRemove); 3029 3030 return VINF_SUCCESS; 3031 } 3032 3033 static int crPMgrModeModifyGlobal(uint32_t u32Mode, bool fEnable) 3034 { 3035 uint32_t u32ModeAdd, u32ModeRemove; 3036 if (fEnable) 3037 { 3038 u32ModeAdd = u32Mode; 3039 u32ModeRemove = 0; 3040 } 3041 else 3042 { 3043 u32ModeAdd = 0; 3044 u32ModeRemove = u32Mode; 3045 } 3046 3047 g_CrPresenter.u32DisplayMode = (g_CrPresenter.u32DisplayMode | u32ModeAdd) & ~u32ModeRemove; 3048 3049 for (HCR_FRAMEBUFFER hFb = CrPMgrFbGetFirstEnabled(); 3050 hFb; 3051 hFb = CrPMgrFbGetNextEnabled(hFb)) 3052 { 3053 CrPMgrModeModify(hFb, u32ModeAdd, u32ModeRemove); 3054 } 3055 3056 return VINF_SUCCESS; 3057 } 3058 3059 int CrPMgrModeVrdp(bool fEnable) 3060 { 3061 return crPMgrModeModifyGlobal(CR_PMGR_MODE_VRDP, fEnable); 3062 } 3063 3064 int CrPMgrModeRootVr(bool fEnable) 3065 { 3066 return crPMgrModeModifyGlobal(CR_PMGR_MODE_ROOTVR, fEnable); 3067 } 3068 3069 int CrPMgrRootVrUpdate() 3070 { 3071 for (HCR_FRAMEBUFFER hFb = CrPMgrFbGetFirstEnabled(); 3072 hFb; 3073 hFb = CrPMgrFbGetNextEnabled(hFb)) 3074 { 3075 uint32_t idScreen = CrFbGetScreenInfo(hFb)->u32ViewIndex; 3076 CR_FBDISPLAY_INFO *pInfo = &g_CrPresenter.aDisplayInfos[idScreen]; 3077 int rc = CrFbUpdateBegin(hFb); 3078 if (RT_SUCCESS(rc)) 3079 { 3080 pInfo->pDpWinRootVr->RegionsChanged(hFb); 3081 CrFbUpdateEnd(hFb); 3082 } 3083 else 3084 WARN(("CrFbUpdateBegin failed %d", rc)); 3085 } 3086 3087 return VINF_SUCCESS; 3088 } 3089 3090 /*helper function that calls CrFbUpdateBegin for all enabled framebuffers */ 3091 int CrPMgrHlpGlblUpdateBegin() 3092 { 3093 for (HCR_FRAMEBUFFER hFb = CrPMgrFbGetFirstEnabled(); 3094 hFb; 3095 hFb = CrPMgrFbGetNextEnabled(hFb)) 3096 { 3097 int rc = CrFbUpdateBegin(hFb); 3098 if (!RT_SUCCESS(rc)) 3099 { 3100 WARN(("UpdateBegin failed, rc %d", rc)); 3101 for (HCR_FRAMEBUFFER hTmpFb = CrPMgrFbGetFirstEnabled(); 3102 hFb != hTmpFb; 3103 hTmpFb = CrPMgrFbGetNextEnabled(hTmpFb)) 3104 { 3105 CrFbUpdateEnd(hTmpFb); 3106 } 3107 return rc; 3108 } 3109 } 3110 3111 return VINF_SUCCESS; 3112 } 3113 3114 /*helper function that calls CrFbUpdateEnd for all framebuffers being updated */ 3115 void CrPMgrHlpGlblUpdateEnd() 3116 { 3117 for (uint32_t i = 0; i < cr_server.screenCount; ++i) 3118 { 3119 HCR_FRAMEBUFFER hFb = CrPMgrFbGet(i); 3120 Assert(hFb); 3121 if (CrFbIsUpdating(hFb)) 3122 CrFbUpdateEnd(hFb); 3123 } 3124 } 3125 3126 /*client should notify the manager about the framebuffer resize via this function */ 3127 int CrPMgrNotifyResize(HCR_FRAMEBUFFER hFb) 3128 { 3129 int rc = VINF_SUCCESS; 3130 if (CrFbIsEnabled(hFb)) 3131 { 3132 rc = CrPMgrModeModify(hFb, g_CrPresenter.u32DisplayMode, 0); 3133 if (!RT_SUCCESS(rc)) 3134 { 3135 WARN(("CrPMgrModeModify failed rc %d", rc)); 3136 return rc; 3137 } 3138 } 3139 else 3140 { 3141 rc = CrPMgrModeModify(hFb, 0, CR_PMGR_MODE_ALL); 3142 if (!RT_SUCCESS(rc)) 3143 { 3144 WARN(("CrPMgrModeModify failed rc %d", rc)); 3145 return rc; 3146 } 3147 } 3148 3149 return VINF_SUCCESS; 3150 } 3151 3152 int CrFbEntrySaveState(CR_FRAMEBUFFER *pFb, CR_FRAMEBUFFER_ENTRY *hEntry, PSSMHANDLE pSSM) 3153 { 3154 const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry = CrFbEntryGetCompositorEntry(hEntry); 3155 CR_TEXDATA *pTexData = CrVrScrCompositorEntryTexGet(pEntry); 3156 CR_FBTEX *pFbTex = PCR_FBTEX_FROM_TEX(pTexData); 3157 int rc = SSMR3PutU32(pSSM, pFbTex->pTobj->id); 3158 AssertRCReturn(rc, rc); 99 3159 uint32_t u32 = 0; 100 while ((pEntry = CrVrScrCompositorIterNext(&Iter)) != NULL) 101 { 102 ++u32; 3160 3161 u32 = CrVrScrCompositorEntryFlagsGet(pEntry); 3162 rc = SSMR3PutU32(pSSM, u32); 3163 AssertRCReturn(rc, rc); 3164 3165 const RTRECT *pRect = CrVrScrCompositorEntryRectGet(pEntry); 3166 3167 rc = SSMR3PutS32(pSSM, pRect->xLeft); 3168 AssertRCReturn(rc, rc); 3169 rc = SSMR3PutS32(pSSM, pRect->yTop); 3170 AssertRCReturn(rc, rc); 3171 #if 0 3172 rc = SSMR3PutS32(pSSM, pRect->xRight); 3173 AssertRCReturn(rc, rc); 3174 rc = SSMR3PutS32(pSSM, pRect->yBottom); 3175 AssertRCReturn(rc, rc); 3176 #endif 3177 3178 rc = CrVrScrCompositorEntryRegionsGet(&pFb->Compositor, pEntry, &u32, NULL, NULL, &pRect); 3179 AssertRCReturn(rc, rc); 3180 3181 rc = SSMR3PutU32(pSSM, u32); 3182 AssertRCReturn(rc, rc); 3183 3184 if (u32) 3185 { 3186 rc = SSMR3PutMem(pSSM, pRect, u32 * sizeof (*pRect)); 3187 AssertRCReturn(rc, rc); 3188 } 3189 return rc; 3190 } 3191 3192 int CrFbSaveState(CR_FRAMEBUFFER *pFb, PSSMHANDLE pSSM) 3193 { 3194 VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR Iter; 3195 CrVrScrCompositorConstIterInit(&pFb->Compositor, &Iter); 3196 const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry; 3197 uint32_t u32 = 0; 3198 while ((pEntry = CrVrScrCompositorConstIterNext(&Iter)) != NULL) 3199 { 3200 CR_TEXDATA *pTexData = CrVrScrCompositorEntryTexGet(pEntry); 3201 CRASSERT(pTexData); 3202 CR_FBTEX *pFbTex = PCR_FBTEX_FROM_TEX(pTexData); 3203 if (pFbTex->pTobj) 3204 ++u32; 103 3205 } 104 3206 … … 106 3208 AssertRCReturn(rc, rc); 107 3209 108 CrVrScrCompositor IterInit(&pDisplay->Mural.Compositor, &Iter);109 110 while ((pEntry = CrVrScrCompositor IterNext(&Iter)) != NULL)111 { 112 CR_DISPLAY_ENTRY *pDEntry = CR_DENTRY_FROM_CENTRY(pEntry);113 rc = Cr DemEntrySaveState(pDEntry, pSSM);3210 CrVrScrCompositorConstIterInit(&pFb->Compositor, &Iter); 3211 3212 while ((pEntry = CrVrScrCompositorConstIterNext(&Iter)) != NULL) 3213 { 3214 HCR_FRAMEBUFFER_ENTRY hEntry = CrFbEntryFromCompositorEntry(pEntry); 3215 rc = CrFbEntrySaveState(pFb, hEntry, pSSM); 114 3216 AssertRCReturn(rc, rc); 115 116 u32 = CrVrScrCompositorEntryFlagsGet(&pDEntry->CEntry); 117 rc = SSMR3PutU32(pSSM, u32); 3217 } 3218 3219 return VINF_SUCCESS; 3220 } 3221 3222 int CrPMgrSaveState(PSSMHANDLE pSSM) 3223 { 3224 int rc; 3225 int cDisplays = 0, i; 3226 for (i = 0; i < cr_server.screenCount; ++i) 3227 { 3228 if (CrPMgrFbGetEnabled(i)) 3229 ++cDisplays; 3230 } 3231 3232 rc = SSMR3PutS32(pSSM, cDisplays); 3233 AssertRCReturn(rc, rc); 3234 3235 if (!cDisplays) 3236 return VINF_SUCCESS; 3237 3238 rc = SSMR3PutS32(pSSM, cr_server.screenCount); 3239 AssertRCReturn(rc, rc); 3240 3241 for (i = 0; i < cr_server.screenCount; ++i) 3242 { 3243 CR_FRAMEBUFFER *hFb = CrPMgrFbGetEnabled(i); 3244 if (hFb) 3245 { 3246 Assert(hFb->ScreenInfo.u32ViewIndex == i); 3247 rc = SSMR3PutU32(pSSM, hFb->ScreenInfo.u32ViewIndex); 3248 AssertRCReturn(rc, rc); 3249 3250 rc = SSMR3PutS32(pSSM, hFb->ScreenInfo.i32OriginX); 3251 AssertRCReturn(rc, rc); 3252 3253 rc = SSMR3PutS32(pSSM, hFb->ScreenInfo.i32OriginY); 3254 AssertRCReturn(rc, rc); 3255 3256 rc = SSMR3PutU32(pSSM, hFb->ScreenInfo.u32StartOffset); 3257 AssertRCReturn(rc, rc); 3258 3259 rc = SSMR3PutU32(pSSM, hFb->ScreenInfo.u32LineSize); 3260 AssertRCReturn(rc, rc); 3261 3262 rc = SSMR3PutU32(pSSM, hFb->ScreenInfo.u32Width); 3263 AssertRCReturn(rc, rc); 3264 3265 rc = SSMR3PutU32(pSSM, hFb->ScreenInfo.u32Height); 3266 AssertRCReturn(rc, rc); 3267 3268 rc = SSMR3PutU16(pSSM, hFb->ScreenInfo.u16BitsPerPixel); 3269 AssertRCReturn(rc, rc); 3270 3271 rc = SSMR3PutU16(pSSM, hFb->ScreenInfo.u16Flags); 3272 AssertRCReturn(rc, rc); 3273 3274 rc = SSMR3PutU32(pSSM, (uint32_t)(((uintptr_t)hFb->pvVram) - ((uintptr_t)g_pvVRamBase))); 3275 AssertRCReturn(rc, rc); 3276 3277 rc = CrFbSaveState(hFb, pSSM); 3278 AssertRCReturn(rc, rc); 3279 } 3280 } 3281 3282 return VINF_SUCCESS; 3283 } 3284 3285 int CrFbEntryLoadState(CR_FRAMEBUFFER *pFb, PSSMHANDLE pSSM, uint32_t version) 3286 { 3287 uint32_t texture; 3288 int rc = SSMR3GetU32(pSSM, &texture); 3289 AssertRCReturn(rc, rc); 3290 3291 uint32_t fFlags; 3292 rc = SSMR3GetU32(pSSM, &fFlags); 3293 AssertRCReturn(rc, rc); 3294 3295 3296 HCR_FRAMEBUFFER_ENTRY hEntry; 3297 3298 rc = CrFbEntryCreateForTexId(pFb, texture, fFlags, &hEntry); 3299 if (!RT_SUCCESS(rc)) 3300 { 3301 WARN(("CrFbEntryCreateForTexId Failed")); 3302 return rc; 3303 } 3304 3305 Assert(hEntry); 3306 3307 const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry = CrFbEntryGetCompositorEntry(hEntry); 3308 CR_TEXDATA *pTexData = CrVrScrCompositorEntryTexGet(pEntry); 3309 CR_FBTEX *pFbTex = PCR_FBTEX_FROM_TEX(pTexData); 3310 3311 RTPOINT Point; 3312 rc = SSMR3GetS32(pSSM, &Point.x); 3313 AssertRCReturn(rc, rc); 3314 3315 rc = SSMR3GetS32(pSSM, &Point.y); 3316 AssertRCReturn(rc, rc); 3317 3318 uint32_t cRects; 3319 rc = SSMR3GetU32(pSSM, &cRects); 3320 AssertRCReturn(rc, rc); 3321 3322 RTRECT * pRects = NULL; 3323 if (cRects) 3324 { 3325 pRects = (RTRECT *)crAlloc(cRects * sizeof (*pRects)); 3326 AssertReturn(pRects, VERR_NO_MEMORY); 3327 3328 rc = SSMR3GetMem(pSSM, pRects, cRects * sizeof (*pRects)); 118 3329 AssertRCReturn(rc, rc); 119 120 rc = SSMR3PutS32(pSSM, CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->x); 121 AssertRCReturn(rc, rc); 122 123 rc = SSMR3PutS32(pSSM, CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->y); 124 AssertRCReturn(rc, rc); 125 126 const RTRECT * pRects; 127 rc = CrVrScrCompositorEntryRegionsGet(&pDisplay->Mural.Compositor, &pDEntry->CEntry, &u32, NULL, NULL, &pRects); 128 AssertRCReturn(rc, rc); 129 130 rc = SSMR3PutU32(pSSM, u32); 131 AssertRCReturn(rc, rc); 132 133 if (u32) 134 { 135 rc = SSMR3PutMem(pSSM, pRects, u32 * sizeof (*pRects)); 136 AssertRCReturn(rc, rc); 137 } 138 } 3330 } 3331 3332 rc = CrFbEntryRegionsSet(pFb, hEntry, &Point, cRects, pRects, false); 3333 AssertRCReturn(rc, rc); 3334 3335 if (pRects) 3336 crFree(pRects); 139 3337 140 3338 return VINF_SUCCESS; 141 3339 } 142 3340 143 int Cr DpLoadState(PCR_DISPLAY pDisplay, PSSMHANDLE pSSM, uint32_t version)3341 int CrFbLoadState(CR_FRAMEBUFFER *pFb, PSSMHANDLE pSSM, uint32_t version) 144 3342 { 145 3343 uint32_t u32 = 0; … … 150 3348 return VINF_SUCCESS; 151 3349 152 CrDpEnter(pDisplay); 3350 rc = CrFbUpdateBegin(pFb); 3351 AssertRCReturn(rc, rc); 153 3352 154 3353 for (uint32_t i = 0; i < u32; ++i) 155 3354 { 156 CR_DISPLAY_ENTRY *pDEntry; 157 rc = CrDemEntryLoadState(&cr_server.PresentTexturepMap, &pDEntry, pSSM); 3355 rc = CrFbEntryLoadState(pFb, pSSM, version); 158 3356 AssertRCReturn(rc, rc); 159 3357 160 uint32_t fFlags; 161 rc = SSMR3GetU32(pSSM, &fFlags); 162 AssertRCReturn(rc, rc); 163 164 CrVrScrCompositorEntryFlagsSet(&pDEntry->CEntry, fFlags); 165 166 RTPOINT Pos; 167 rc = SSMR3GetS32(pSSM, &Pos.x); 168 AssertRCReturn(rc, rc); 169 170 rc = SSMR3GetS32(pSSM, &Pos.y); 171 AssertRCReturn(rc, rc); 172 173 uint32_t cRects; 174 rc = SSMR3GetU32(pSSM, &cRects); 175 AssertRCReturn(rc, rc); 176 177 RTRECT * pRects = NULL; 178 if (cRects) 179 { 180 pRects = (RTRECT *)crAlloc(cRects * sizeof (*pRects)); 181 AssertReturn(pRects, VERR_NO_MEMORY); 182 183 rc = SSMR3GetMem(pSSM, pRects, cRects * sizeof (*pRects)); 184 AssertRCReturn(rc, rc); 185 } 186 187 rc = CrDpEntryRegionsAdd(pDisplay, pDEntry, &Pos, (uint32_t)cRects, (const RTRECT*)pRects, NULL); 188 AssertRCReturn(rc, rc); 189 190 if (pRects) 191 crFree(pRects); 192 } 193 194 CrDpLeave(pDisplay); 3358 } 3359 3360 CrFbUpdateEnd(pFb); 195 3361 196 3362 return VINF_SUCCESS; 197 3363 } 198 3364 199 200 int CrDpEntryRegionsSet(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions) 201 { 202 int rc = CrVrScrCompositorEntryRegionsSet(&pDisplay->Mural.Compositor, pEntry ? &pEntry->CEntry : NULL, pPos, cRegions, paRegions, false, NULL); 203 return rc; 204 } 205 206 void crDbgDumpRect(uint32_t i, const RTRECT *pRect) 207 { 208 crDebug("%d: (%d;%d) X (%d;%d)", i, pRect->xLeft, pRect->yTop, pRect->xRight, pRect->yBottom); 209 } 210 211 void crDbgDumpRects(uint32_t cRects, const RTRECT *paRects) 212 { 213 crDebug("Dumping rects (%d)", cRects); 214 for (uint32_t i = 0; i < cRects; ++i) 215 { 216 crDbgDumpRect(i, &paRects[i]); 217 } 218 crDebug("End Dumping rects (%d)", cRects); 219 } 220 221 int CrDpEntryRegionsAdd(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, CR_DISPLAY_ENTRY_MAP *pMap) 222 { 223 uint32_t fChangeFlags = 0; 224 VBOXVR_SCR_COMPOSITOR_ENTRY *pReplacedScrEntry = NULL; 225 226 if (pMap) 227 CrDemEnter(pMap); 228 229 int rc = CrVrScrCompositorEntryRegionsAdd(&pDisplay->Mural.Compositor, pEntry ? &pEntry->CEntry : NULL, pPos, cRegions, paRegions, false, &pReplacedScrEntry, &fChangeFlags); 230 if (RT_SUCCESS(rc)) 231 { 232 if (fChangeFlags & VBOXVR_COMPOSITOR_CF_REGIONS_CHANGED) 233 { 234 bool fChanged = true; 235 if (pDisplay->Mural.fRootVrOn) 236 { 237 int rc = crServerMuralSynchRootVr(&pDisplay->Mural, &fChanged); 238 if (!RT_SUCCESS(rc)) 239 { 240 crWarning("crServerMuralSynchRootVr failed, rc %d", rc); 241 fChanged = false; 242 } 243 } 244 245 if (fChanged) 246 crServerWindowVisibleRegion(&pDisplay->Mural); 247 248 crServerDEntryAllVibleRegions(&pDisplay->Mural); 249 250 Assert(!pReplacedScrEntry); 251 } 252 else if (fChangeFlags & VBOXVR_COMPOSITOR_CF_ENTRY_REGIONS_CHANGED) 253 { 254 if (fChangeFlags & VBOXVR_COMPOSITOR_CF_ENTRY_REPLACED) 255 { 256 Assert(pReplacedScrEntry); 257 Assert(pEntry); 258 if (pDisplay->Mural.fRootVrOn) 259 { 260 CR_DISPLAY_ENTRY *pReplacedDEntry = CR_DENTRY_FROM_CENTRY(pReplacedScrEntry); 261 Assert(CrVrScrCompositorEntryIsUsed(&pReplacedDEntry->RootVrCEntry)); 262 Assert(!CrVrScrCompositorEntryIsUsed(&pEntry->RootVrCEntry)); 263 CrVrScrCompositorEntryInit(&pEntry->RootVrCEntry, CrVrScrCompositorEntryTexGet(&pEntry->CEntry), NULL); 264 CrVrScrCompositorEntryFlagsSet(&pEntry->RootVrCEntry, CrVrScrCompositorEntryFlagsGet(&pEntry->CEntry)); 265 CrVrScrCompositorEntryReplace(&pDisplay->Mural.RootVrCompositor, &pReplacedDEntry->RootVrCEntry, &pEntry->RootVrCEntry); 266 } 267 } 268 else 269 { 270 Assert(!pReplacedScrEntry); 271 if (pDisplay->Mural.fRootVrOn) 272 { 273 bool fChanged = false; 274 int rc = crServerMuralSynchRootVr(&pDisplay->Mural, &fChanged); 275 if (RT_SUCCESS(rc)) 276 { 277 if (fChanged) 278 crServerWindowVisibleRegion(&pDisplay->Mural); 279 } 280 else 281 crWarning("crServerMuralSynchRootVr failed, rc %d", rc); 282 } 283 } 284 } 285 else 286 { 287 Assert(!(fChangeFlags & VBOXVR_COMPOSITOR_CF_ENTRY_REPLACED)); 288 Assert(!pReplacedScrEntry); 289 } 290 } 291 else 292 crWarning("CrVrScrCompositorEntryRegionsAdd failed, rc %d", rc); 293 294 if (pMap) 295 CrDemLeave(pMap, CR_DENTRY_FROM_CENTRY(pEntry), CR_DENTRY_FROM_CENTRY(pReplacedScrEntry)); 296 297 return rc; 298 } 299 300 void CrDpRegionsClear(PCR_DISPLAY pDisplay) 301 { 302 bool fChanged = false; 303 CrVrScrCompositorRegionsClear(&pDisplay->Mural.Compositor, &fChanged); 304 if (fChanged) 305 { 306 crServerMuralVisibleRegion(&pDisplay->Mural, 0, NULL); 307 } 308 } 309 310 #define PCR_DISPLAY_ENTRY_FROM_CENTRY(_pe) ((PCR_DISPLAY_ENTRY)((uint8_t*)(_pe) - RT_OFFSETOF(CR_DISPLAY_ENTRY, CEntry))) 311 static DECLCALLBACK(void) crDpEntryCEntryReleaseCB(const struct VBOXVR_SCR_COMPOSITOR *pCompositor, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pReplacingEntry) 312 { 313 PCR_DISPLAY_ENTRY pCEntry = PCR_DISPLAY_ENTRY_FROM_CENTRY(pEntry); 314 CrDemEntryRelease(pCEntry); 315 } 316 317 void CrDpEntryInit(PCR_DISPLAY_ENTRY pEntry, const VBOXVR_TEXTURE *pTextureData, uint32_t fFlags, PFNVBOXVRSCRCOMPOSITOR_ENTRY_RELEASED pfnEntryReleased) 318 { 319 CrVrScrCompositorEntryInit(&pEntry->CEntry, pTextureData, pfnEntryReleased); 320 CrVrScrCompositorEntryFlagsSet(&pEntry->CEntry, fFlags); 321 CrVrScrCompositorEntryInit(&pEntry->RootVrCEntry, pTextureData, NULL); 322 CrVrScrCompositorEntryFlagsSet(&pEntry->RootVrCEntry, fFlags); 323 pEntry->pvORInstance = NULL; 324 pEntry->idPBO = 0; 325 pEntry->idInvertTex = 0; 326 } 327 328 void CrDpEntryCleanup(PCR_DISPLAY_ENTRY pDEntry) 329 { 330 if (pDEntry->idPBO) 331 { 332 CRASSERT(cr_server.bUsePBOForReadback); 333 cr_server.head_spu->dispatch_table.DeleteBuffersARB(1, &pDEntry->idPBO); 334 pDEntry->idPBO = 0; 335 } 336 337 if (pDEntry->idInvertTex) 338 { 339 cr_server.head_spu->dispatch_table.DeleteTextures(1, &pDEntry->idInvertTex); 340 pDEntry->idInvertTex = 0; 341 } 342 343 if (pDEntry->pvORInstance) 344 { 345 cr_server.outputRedirect.CROREnd(pDEntry->pvORInstance); 346 pDEntry->pvORInstance = NULL; 347 } 348 } 349 350 void CrDpEnter(PCR_DISPLAY pDisplay) 351 { 352 pDisplay->fForcePresent |= crServerVBoxCompositionPresentNeeded(&pDisplay->Mural); 353 crServerVBoxCompositionDisableEnter(&pDisplay->Mural); 354 } 355 356 void CrDpLeave(PCR_DISPLAY pDisplay) 357 { 358 pDisplay->Mural.fDataPresented = GL_TRUE; 359 pDisplay->Mural.fOrPresentOnReenable = GL_TRUE; 360 crServerVBoxCompositionDisableLeave(&pDisplay->Mural, pDisplay->fForcePresent); 361 pDisplay->fForcePresent = GL_FALSE; 362 } 363 364 void CrDpRootUpdate(PCR_DISPLAY pDisplay) 365 { 366 crVBoxServerUpdateMuralRootVisibleRegion(&pDisplay->Mural); 367 } 368 369 370 typedef struct CR_DEM_ENTRY_INFO 371 { 372 CRTextureObj *pTobj; 373 uint32_t cEntries; 374 } CR_DEM_ENTRY_INFO; 375 376 typedef struct CR_DEM_ENTRY 377 { 378 CR_DISPLAY_ENTRY Entry; 379 CR_DEM_ENTRY_INFO *pInfo; 380 CR_DISPLAY_ENTRY_MAP *pMap; 381 RTLISTNODE Node; 382 } CR_DEM_ENTRY; 383 384 #define PCR_DEM_ENTRY_FROM_ENTRY(_pEntry) ((CR_DEM_ENTRY*)((uint8_t*)(_pEntry) - RT_OFFSETOF(CR_DEM_ENTRY, Entry))) 385 386 static RTMEMCACHE g_VBoxCrDemLookasideList; 387 static RTMEMCACHE g_VBoxCrDemInfoLookasideList; 388 389 int CrDemGlobalInit() 390 { 391 int rc = RTMemCacheCreate(&g_VBoxCrDemLookasideList, sizeof (CR_DEM_ENTRY), 392 0, /* size_t cbAlignment */ 393 UINT32_MAX, /* uint32_t cMaxObjects */ 394 NULL, /* PFNMEMCACHECTOR pfnCtor*/ 395 NULL, /* PFNMEMCACHEDTOR pfnDtor*/ 396 NULL, /* void *pvUser*/ 397 0 /* uint32_t fFlags*/ 398 ); 399 if (RT_SUCCESS(rc)) 400 { 401 rc = RTMemCacheCreate(&g_VBoxCrDemInfoLookasideList, sizeof (CR_DEM_ENTRY_INFO), 402 0, /* size_t cbAlignment */ 403 UINT32_MAX, /* uint32_t cMaxObjects */ 404 NULL, /* PFNMEMCACHECTOR pfnCtor*/ 405 NULL, /* PFNMEMCACHEDTOR pfnDtor*/ 406 NULL, /* void *pvUser*/ 407 0 /* uint32_t fFlags*/ 408 ); 409 if (RT_SUCCESS(rc)) 410 return VINF_SUCCESS; 411 else 412 crWarning("RTMemCacheCreate failed rc %d", rc); 413 414 RTMemCacheDestroy(g_VBoxCrDemLookasideList); 415 } 416 else 417 crWarning("RTMemCacheCreate failed rc %d", rc); 418 return VINF_SUCCESS; 419 } 420 421 void CrDemTeGlobalTerm() 422 { 423 RTMemCacheDestroy(g_VBoxCrDemLookasideList); 424 RTMemCacheDestroy(g_VBoxCrDemInfoLookasideList); 425 } 426 427 static CR_DEM_ENTRY* crDemEntryAlloc() 428 { 429 return (CR_DEM_ENTRY*)RTMemCacheAlloc(g_VBoxCrDemLookasideList); 430 } 431 432 static CR_DEM_ENTRY_INFO* crDemEntryInfoAlloc() 433 { 434 return (CR_DEM_ENTRY_INFO*)RTMemCacheAlloc(g_VBoxCrDemInfoLookasideList); 435 } 436 437 static void crDemEntryFree(CR_DEM_ENTRY* pDemEntry) 438 { 439 CrDpEntryCleanup(&pDemEntry->Entry); 440 RTMemCacheFree(g_VBoxCrDemLookasideList, pDemEntry); 441 } 442 443 static void crDemEntryInfoFree(CR_DEM_ENTRY_INFO* pDemEntryInfo) 444 { 445 RTMemCacheFree(g_VBoxCrDemInfoLookasideList, pDemEntryInfo); 446 } 447 448 void crDemEntryRelease(PCR_DISPLAY_ENTRY_MAP pMap, CR_DEM_ENTRY *pDemEntry) 449 { 450 CR_DEM_ENTRY_INFO *pInfo = pDemEntry->pInfo; 451 CRTextureObj *pTobj = pInfo->pTobj; 452 453 --pInfo->cEntries; 454 455 if (!pInfo->cEntries) 456 { 457 CR_STATE_SHAREDOBJ_USAGE_CLEAR(pInfo->pTobj, cr_server.MainContextInfo.pContext); 458 459 crHashtableDelete(pMap->pTexIdToDemInfoMap, pTobj->id, NULL); 460 461 crDemEntryInfoFree(pInfo); 462 } 463 464 if (!CR_STATE_SHAREDOBJ_USAGE_IS_USED(pTobj)) 465 { 466 CRSharedState *pShared = crStateGlobalSharedAcquire(); 467 468 CRASSERT(pShared); 469 /* on the host side, we need to delete an ogl texture object here as well, which crStateDeleteTextureCallback will do 470 * in addition to calling crStateDeleteTextureObject to delete a state object */ 471 crHashtableDelete(pShared->textureTable, pTobj->id, crStateDeleteTextureCallback); 472 473 crStateGlobalSharedRelease(); 474 } 475 476 crStateGlobalSharedRelease(); 477 478 if (!pMap->cEntered) 479 crDemEntryFree(pDemEntry); 480 else 481 RTListNodeInsertAfter(&pMap->ReleasedList, &pDemEntry->Node); 482 } 483 484 int CrDemInit(PCR_DISPLAY_ENTRY_MAP pMap) 485 { 486 pMap->pTexIdToDemInfoMap = crAllocHashtable(); 487 if (pMap->pTexIdToDemInfoMap) 488 { 489 RTListInit(&pMap->ReleasedList); 490 return VINF_SUCCESS; 491 } 492 493 crWarning("crAllocHashtable failed"); 494 return VERR_NO_MEMORY; 495 } 496 497 void CrDemTerm(PCR_DISPLAY_ENTRY_MAP pMap) 498 { 499 CRASSERT(RTListIsEmpty(&pMap->ReleasedList)); 500 CRASSERT(!pMap->cEntered); 501 crFreeHashtable(pMap->pTexIdToDemInfoMap, NULL); 502 pMap->pTexIdToDemInfoMap = NULL; 503 } 504 505 void CrDemEnter(PCR_DISPLAY_ENTRY_MAP pMap) 506 { 507 ++pMap->cEntered; 508 Assert(pMap->cEntered); 509 } 510 511 void CrDemLeave(PCR_DISPLAY_ENTRY_MAP pMap, PCR_DISPLAY_ENTRY pNewEntry, PCR_DISPLAY_ENTRY pReplacedEntry) 512 { 513 Assert(pMap->cEntered); 514 --pMap->cEntered; 515 Assert(!pReplacedEntry || pNewEntry); 516 if (pNewEntry && pReplacedEntry) 517 { 518 CR_DEM_ENTRY *pNewDemEntry = PCR_DEM_ENTRY_FROM_ENTRY(pNewEntry); 519 CR_DEM_ENTRY *pReplacedDemEntry = PCR_DEM_ENTRY_FROM_ENTRY(pReplacedEntry); 520 Assert(!RTListIsEmpty(&pMap->ReleasedList)); 521 Assert(!RTListIsEmpty(&pReplacedDemEntry->Node)); 522 Assert(RTListIsEmpty(&pNewDemEntry->Node)); 523 Assert(!pNewDemEntry->Entry.pvORInstance); 524 if (!pNewDemEntry->Entry.pvORInstance) 525 { 526 pNewDemEntry->Entry.pvORInstance = pReplacedDemEntry->Entry.pvORInstance; 527 pReplacedDemEntry->Entry.pvORInstance = NULL; 528 } 529 RTListNodeRemove(&pReplacedDemEntry->Node); 530 crDemEntryFree(pReplacedDemEntry); 531 } 532 533 if (!pMap->cEntered) 534 { 535 CR_DEM_ENTRY *pCurEntry, *pNextEntry; 536 RTListForEachSafe(&pMap->ReleasedList, pCurEntry, pNextEntry, CR_DEM_ENTRY, Node) 537 { 538 RTListNodeRemove(&pCurEntry->Node); 539 crDemEntryFree(pCurEntry); 540 } 541 } 542 } 543 544 void CrDemEntryRelease(PCR_DISPLAY_ENTRY pEntry) 545 { 546 CR_DEM_ENTRY *pDemEntry = PCR_DEM_ENTRY_FROM_ENTRY(pEntry); 547 crDemEntryRelease(pDemEntry->pMap, pDemEntry); 548 } 549 550 int CrDemEntrySaveState(PCR_DISPLAY_ENTRY pEntry, PSSMHANDLE pSSM) 551 { 552 CR_DEM_ENTRY *pDemEntry = PCR_DEM_ENTRY_FROM_ENTRY(pEntry); 553 int rc = SSMR3PutU32(pSSM, pDemEntry->pInfo->pTobj->id); 554 AssertRCReturn(rc, rc); 555 return rc; 556 } 557 558 int CrDemEntryLoadState(PCR_DISPLAY_ENTRY_MAP pMap, PCR_DISPLAY_ENTRY *ppEntry, PSSMHANDLE pSSM) 559 { 560 uint32_t u32; 561 int rc = SSMR3GetU32(pSSM, &u32); 562 AssertRCReturn(rc, rc); 563 564 PCR_DISPLAY_ENTRY pEntry = CrDemEntryAcquire(pMap, u32, CRBLT_F_INVERT_SRC_YCOORDS); 565 if (!pEntry) 566 { 567 crWarning("CrDemEntryAcquire failed"); 568 return VERR_NO_MEMORY; 569 } 570 571 *ppEntry = pEntry; 572 return VINF_SUCCESS; 573 } 574 575 PCR_DISPLAY_ENTRY CrDemEntryAcquire(PCR_DISPLAY_ENTRY_MAP pMap, GLuint idTexture, uint32_t fFlags) 576 { 577 CR_DEM_ENTRY *pDemEntry = NULL; 578 579 CRSharedState *pShared = crStateGlobalSharedAcquire(); 580 if (!pShared) 581 { 582 crWarning("pShared is null!"); 583 return NULL; 584 } 585 586 CRTextureObj *pTobj = (CRTextureObj*)crHashtableSearch(pShared->textureTable, idTexture); 587 if (!pTobj) 588 { 589 crWarning("pTobj is null!"); 590 crStateGlobalSharedRelease(); 591 return NULL; 592 } 593 594 Assert(pTobj->id == idTexture); 595 596 GLuint hwId = crStateGetTextureObjHWID(pTobj); 597 if (!hwId) 598 { 599 crWarning("hwId is null!"); 600 crStateGlobalSharedRelease(); 601 return NULL; 602 } 603 604 VBOXVR_TEXTURE TextureData; 605 TextureData.width = pTobj->level[0]->width; 606 TextureData.height = pTobj->level[0]->height; 607 TextureData.target = pTobj->target; 608 TextureData.hwid = hwId; 609 610 pDemEntry = crDemEntryAlloc(); 611 if (!pDemEntry) 612 { 613 crWarning("crDemEntryAlloc failed allocating CR_DEM_ENTRY"); 614 crStateGlobalSharedRelease(); 615 return NULL; 616 } 617 618 CrDpEntryInit(&pDemEntry->Entry, &TextureData, fFlags, crDpEntryCEntryReleaseCB); 619 620 CR_DEM_ENTRY_INFO *pInfo = (CR_DEM_ENTRY_INFO*)crHashtableSearch(pMap->pTexIdToDemInfoMap, pTobj->id); 621 if (!pInfo) 622 { 623 pInfo = crDemEntryInfoAlloc(); 624 CRASSERT(pInfo); 625 crHashtableAdd(pMap->pTexIdToDemInfoMap, pTobj->id, pInfo); 626 pInfo->cEntries = 0; 627 pInfo->pTobj = pTobj; 628 } 629 630 ++pInfo->cEntries; 631 pDemEntry->pInfo = pInfo; 632 pDemEntry->pMap = pMap; 633 RTListInit(&pDemEntry->Node); 634 635 /* just use main context info's context to hold the texture reference */ 636 CR_STATE_SHAREDOBJ_USAGE_SET(pTobj, cr_server.MainContextInfo.pContext); 637 638 return &pDemEntry->Entry; 639 } 640 641 PCR_DISPLAY crServerDisplayGetInitialized(uint32_t idScreen) 642 { 643 if (idScreen >= CR_MAX_GUEST_MONITORS) 644 { 645 crWarning("invalid idScreen %d", idScreen); 646 return NULL; 647 } 648 649 if (ASMBitTest(cr_server.DisplaysInitMap, idScreen)) 650 { 651 Assert(cr_server.aDispplays[idScreen].Mural.screenId == idScreen); 652 return &cr_server.aDispplays[idScreen]; 653 } 654 return NULL; 655 } 656 657 static PCR_DISPLAY crServerDisplayGet(uint32_t idScreen) 658 { 659 if (idScreen >= CR_MAX_GUEST_MONITORS) 660 { 661 crWarning("invalid idScreen %d", idScreen); 662 return NULL; 663 } 664 665 if (ASMBitTest(cr_server.DisplaysInitMap, idScreen)) 666 { 667 Assert(cr_server.aDispplays[idScreen].Mural.screenId == idScreen); 668 return &cr_server.aDispplays[idScreen]; 669 } 670 671 int rc = CrDpInit(&cr_server.aDispplays[idScreen]); 672 if (RT_SUCCESS(rc)) 673 { 674 CrDpResize(&cr_server.aDispplays[idScreen], 675 cr_server.screen[idScreen].x, cr_server.screen[idScreen].y, 676 cr_server.screen[idScreen].w, cr_server.screen[idScreen].h); 677 ASMBitSet(cr_server.DisplaysInitMap, idScreen); 678 return &cr_server.aDispplays[idScreen]; 679 } 680 else 681 { 682 crWarning("CrDpInit failed for screen %d", idScreen); 683 } 684 685 return NULL; 686 } 687 688 int crServerDisplaySaveState(PSSMHANDLE pSSM) 689 { 690 int rc; 691 int cDisplays = 0, i; 692 for (i = 0; i < cr_server.screenCount; ++i) 693 { 694 if (ASMBitTest(cr_server.DisplaysInitMap, i) && !CrDpIsEmpty(&cr_server.aDispplays[i])) 695 ++cDisplays; 696 } 697 698 rc = SSMR3PutS32(pSSM, cDisplays); 699 AssertRCReturn(rc, rc); 700 701 if (!cDisplays) 702 return VINF_SUCCESS; 703 704 rc = SSMR3PutS32(pSSM, cr_server.screenCount); 705 AssertRCReturn(rc, rc); 706 707 for (i = 0; i < cr_server.screenCount; ++i) 708 { 709 rc = SSMR3PutS32(pSSM, cr_server.screen[i].x); 710 AssertRCReturn(rc, rc); 711 712 rc = SSMR3PutS32(pSSM, cr_server.screen[i].y); 713 AssertRCReturn(rc, rc); 714 715 rc = SSMR3PutU32(pSSM, cr_server.screen[i].w); 716 AssertRCReturn(rc, rc); 717 718 rc = SSMR3PutU32(pSSM, cr_server.screen[i].h); 719 AssertRCReturn(rc, rc); 720 } 721 722 for (i = 0; i < cr_server.screenCount; ++i) 723 { 724 if (ASMBitTest(cr_server.DisplaysInitMap, i) && !CrDpIsEmpty(&cr_server.aDispplays[i])) 725 { 726 rc = SSMR3PutS32(pSSM, i); 727 AssertRCReturn(rc, rc); 728 729 rc = CrDpSaveState(&cr_server.aDispplays[i], pSSM); 730 AssertRCReturn(rc, rc); 731 } 732 } 733 734 return VINF_SUCCESS; 735 } 736 737 int crServerDisplayLoadState(PSSMHANDLE pSSM, uint32_t u32Version) 3365 int CrPMgrLoadState(PSSMHANDLE pSSM, uint32_t version) 738 3366 { 739 3367 int rc; … … 751 3379 CRASSERT(screenCount == cr_server.screenCount); 752 3380 753 crServerVBoxCompositionSetEnableStateGlobal(GL_FALSE); 754 755 for (i = 0; i < cr_server.screenCount; ++i) 756 { 757 int32_t x, y; 758 uint32_t w, h; 759 rc = SSMR3GetS32(pSSM, &x); 760 AssertRCReturn(rc, rc); 761 762 rc = SSMR3GetS32(pSSM, &y); 763 AssertRCReturn(rc, rc); 764 765 rc = SSMR3GetU32(pSSM, &w); 766 AssertRCReturn(rc, rc); 767 768 rc = SSMR3GetU32(pSSM, &h); 769 AssertRCReturn(rc, rc); 770 771 rc = crVBoxServerMapScreen(i, x, y, w, h, cr_server.screen[i].winID); 772 AssertRCReturn(rc, rc); 773 } 774 775 crServerVBoxCompositionSetEnableStateGlobal(GL_TRUE); 3381 CRScreenInfo screen[CR_MAX_GUEST_MONITORS]; 3382 3383 if (version < SHCROGL_SSM_VERSION_WITH_FB_INFO) 3384 { 3385 for (i = 0; i < cr_server.screenCount; ++i) 3386 { 3387 rc = SSMR3GetS32(pSSM, &screen[i].x); 3388 AssertRCReturn(rc, rc); 3389 3390 rc = SSMR3GetS32(pSSM, &screen[i].y); 3391 AssertRCReturn(rc, rc); 3392 3393 rc = SSMR3GetU32(pSSM, &screen[i].w); 3394 AssertRCReturn(rc, rc); 3395 3396 rc = SSMR3GetU32(pSSM, &screen[i].h); 3397 AssertRCReturn(rc, rc); 3398 } 3399 } 776 3400 777 3401 for (i = 0; i < cDisplays; ++i) … … 782 3406 AssertRCReturn(rc, rc); 783 3407 784 PCR_DISPLAY pDisplay = crServerDisplayGet((uint32_t)iScreen); 785 if (!pDisplay) 786 { 787 crWarning("crServerDisplayGet failed"); 788 return VERR_GENERAL_FAILURE; 789 } 790 791 rc = CrDpLoadState(pDisplay, pSSM, u32Version); 3408 CR_FRAMEBUFFER *pFb = CrPMgrFbGet(iScreen); 3409 Assert(pFb); 3410 3411 rc = CrFbUpdateBegin(pFb); 3412 if (!RT_SUCCESS(rc)) 3413 { 3414 WARN(("CrFbUpdateBegin failed %d", rc)); 3415 return rc; 3416 } 3417 3418 VBVAINFOSCREEN Screen; 3419 void *pvVRAM; 3420 3421 Screen.u32ViewIndex = iScreen; 3422 3423 if (version < SHCROGL_SSM_VERSION_WITH_FB_INFO) 3424 { 3425 memset(&Screen, 0, sizeof (Screen)); 3426 Screen.u32LineSize = 4 * screen[iScreen].w; 3427 Screen.u32Width = screen[iScreen].w; 3428 Screen.u32Height = screen[iScreen].h; 3429 Screen.u16BitsPerPixel = 4; 3430 Screen.u16Flags = VBVA_SCREEN_F_ACTIVE; 3431 3432 pvVRAM = g_pvVRamBase; 3433 } 3434 else 3435 { 3436 rc = SSMR3GetS32(pSSM, &Screen.i32OriginX); 3437 AssertRCReturn(rc, rc); 3438 3439 rc = SSMR3GetS32(pSSM, &Screen.i32OriginY); 3440 AssertRCReturn(rc, rc); 3441 3442 rc = SSMR3GetU32(pSSM, &Screen.u32StartOffset); 3443 AssertRCReturn(rc, rc); 3444 3445 rc = SSMR3GetU32(pSSM, &Screen.u32LineSize); 3446 AssertRCReturn(rc, rc); 3447 3448 rc = SSMR3GetU32(pSSM, &Screen.u32Width); 3449 AssertRCReturn(rc, rc); 3450 3451 rc = SSMR3GetU32(pSSM, &Screen.u32Height); 3452 AssertRCReturn(rc, rc); 3453 3454 rc = SSMR3GetU16(pSSM, &Screen.u16BitsPerPixel); 3455 AssertRCReturn(rc, rc); 3456 3457 rc = SSMR3GetU16(pSSM, &Screen.u16Flags); 3458 AssertRCReturn(rc, rc); 3459 3460 uint32_t offVram = 0; 3461 rc = SSMR3GetU32(pSSM, &offVram); 3462 AssertRCReturn(rc, rc); 3463 3464 pvVRAM = (void*)(((uintptr_t)g_pvVRamBase) + offVram); 3465 } 3466 3467 crVBoxServerMuralFbResizeBegin(pFb); 3468 3469 rc = CrFbResize(pFb, &Screen, pvVRAM); 3470 if (!RT_SUCCESS(rc)) 3471 { 3472 WARN(("CrFbResize failed %d", rc)); 3473 return rc; 3474 } 3475 3476 rc = CrFbLoadState(pFb, pSSM, version); 792 3477 AssertRCReturn(rc, rc); 3478 3479 crVBoxServerMuralFbResizeEnd(pFb); 3480 3481 CrFbUpdateEnd(pFb); 3482 3483 CrPMgrNotifyResize(pFb); 793 3484 } 794 3485 … … 796 3487 } 797 3488 798 void crServerDisplayTermAll()799 {800 int i;801 for (i = 0; i < cr_server.screenCount; ++i)802 {803 if (ASMBitTest(cr_server.DisplaysInitMap, i))804 {805 CrDpTerm(&cr_server.aDispplays[i]);806 ASMBitClear(cr_server.DisplaysInitMap, i);807 }808 }809 }810 811 void CrHlpFreeTexImage(CRContext *pCurCtx, GLuint idPBO, void *pvData)812 {813 if (idPBO)814 {815 cr_server.head_spu->dispatch_table.UnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);816 if (pCurCtx)817 cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pCurCtx->bufferobject.packBuffer->hwid);818 else819 cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);820 }821 else822 {823 crFree(pvData);824 if (pCurCtx && crStateIsBufferBoundForCtx(pCurCtx, GL_PIXEL_PACK_BUFFER_ARB))825 cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pCurCtx->bufferobject.packBuffer->hwid);826 }827 }828 829 void CrHlpPutTexImage(CRContext *pCurCtx, const VBOXVR_TEXTURE *pTexture, GLenum enmFormat, void *pvData)830 {831 CRASSERT(pTexture->hwid);832 cr_server.head_spu->dispatch_table.BindTexture(pTexture->target, pTexture->hwid);833 834 if (!pCurCtx || crStateIsBufferBoundForCtx(pCurCtx, GL_PIXEL_UNPACK_BUFFER_ARB))835 {836 cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);837 }838 839 /*read the texture, note pixels are NULL for PBO case as it's offset in the buffer*/840 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);841 842 /*restore gl state*/843 if (pCurCtx)844 {845 CRTextureObj *pTObj;846 CRTextureLevel *pTImg;847 crStateGetTextureObjectAndImage(pCurCtx, pTexture->target, 0, &pTObj, &pTImg);848 849 GLuint uid = pTObj->hwid;850 cr_server.head_spu->dispatch_table.BindTexture(pTexture->target, uid);851 }852 else853 {854 cr_server.head_spu->dispatch_table.BindTexture(pTexture->target, 0);855 }856 857 if (pCurCtx && crStateIsBufferBoundForCtx(pCurCtx, GL_PIXEL_UNPACK_BUFFER_ARB))858 cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pCurCtx->bufferobject.unpackBuffer->hwid);859 }860 861 void* CrHlpGetTexImage(CRContext *pCurCtx, const VBOXVR_TEXTURE *pTexture, GLuint idPBO, GLenum enmFormat)862 {863 void *pvData = NULL;864 cr_server.head_spu->dispatch_table.BindTexture(pTexture->target, pTexture->hwid);865 866 if (idPBO)867 {868 cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, idPBO);869 }870 else871 {872 if (!pCurCtx || crStateIsBufferBoundForCtx(pCurCtx, GL_PIXEL_PACK_BUFFER_ARB))873 {874 cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);875 }876 877 pvData = crAlloc(4*pTexture->width*pTexture->height);878 if (!pvData)879 {880 crWarning("Out of memory in CrHlpGetTexImage");881 return NULL;882 }883 }884 885 /*read the texture, note pixels are NULL for PBO case as it's offset in the buffer*/886 cr_server.head_spu->dispatch_table.GetTexImage(GL_TEXTURE_2D, 0, enmFormat, GL_UNSIGNED_BYTE, pvData);887 888 /*restore gl state*/889 if (pCurCtx)890 {891 CRTextureObj *pTObj;892 CRTextureLevel *pTImg;893 crStateGetTextureObjectAndImage(pCurCtx, pTexture->target, 0, &pTObj, &pTImg);894 895 GLuint uid = pTObj->hwid;896 cr_server.head_spu->dispatch_table.BindTexture(pTexture->target, uid);897 }898 else899 {900 cr_server.head_spu->dispatch_table.BindTexture(pTexture->target, 0);901 }902 903 if (idPBO)904 {905 pvData = cr_server.head_spu->dispatch_table.MapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);906 if (!pvData)907 {908 crWarning("Failed to MapBuffer in CrHlpGetTexImage");909 return NULL;910 }911 }912 913 CRASSERT(pvData);914 return pvData;915 }916 3489 917 3490 void SERVER_DISPATCH_APIENTRY … … 921 3494 if (idScreen >= CR_MAX_GUEST_MONITORS) 922 3495 { 923 crWarning("Invalid guest screen");3496 WARN(("Invalid guest screen")); 924 3497 return; 925 3498 } 926 3499 927 PCR_DISPLAY pDisplay; 928 PCR_DISPLAY_ENTRY pEntry = NULL; 929 3500 HCR_FRAMEBUFFER hFb = CrPMgrFbGetEnabled(idScreen); 3501 if (!hFb) 3502 { 3503 WARN(("request to present on disabled framebuffer, ignore")); 3504 return; 3505 } 3506 3507 HCR_FRAMEBUFFER_ENTRY hEntry; 3508 int rc; 930 3509 if (texture) 931 3510 { 932 pEntry = CrDemEntryAcquire(&cr_server.PresentTexturepMap, texture, (cfg & CR_PRESENT_FLAG_TEX_NONINVERT_YCOORD) ? 0 : CRBLT_F_INVERT_SRC_YCOORDS);933 if (! pEntry)934 { 935 crWarning("CrDemEntryAcquire Failed");3511 rc = CrFbEntryCreateForTexId(hFb, texture, (cfg & CR_PRESENT_FLAG_TEX_NONINVERT_YCOORD) ? 0 : CRBLT_F_INVERT_SRC_YCOORDS, &hEntry); 3512 if (!RT_SUCCESS(rc)) 3513 { 3514 WARN(("CrFbEntryCreateForTexId Failed")); 936 3515 return; 937 3516 } 938 3517 939 pDisplay = crServerDisplayGet(idScreen); 940 if (!pDisplay) 941 { 942 crWarning("crServerDisplayGet Failed"); 943 CrDemEntryRelease(pEntry); 944 return; 945 } 3518 Assert(hEntry); 3519 3520 #if 0 3521 if (!(cfg & CR_PRESENT_FLAG_CLEAR_RECTS)) 3522 { 3523 CR_SERVER_DUMP_TEXPRESENT(&pEntry->CEntry.Tex); 3524 } 3525 #endif 946 3526 } 947 3527 else 948 { 949 pDisplay = crServerDisplayGetInitialized(idScreen); 950 if (!pDisplay) 951 { 952 /* no display initialized, and nothing to present */ 953 return; 954 } 955 } 956 957 if (!(cfg & CR_PRESENT_FLAG_CLEAR_RECTS)) 958 { 959 CR_SERVER_DUMP_TEXPRESENT(&pEntry->CEntry.Tex); 960 } 961 962 CrDpEnter(pDisplay); 963 964 if (!(cfg & CR_PRESENT_FLAG_CLEAR_RECTS)) 965 { 966 RTPOINT Point = {xPos, yPos}; 967 int rc = CrDpEntryRegionsAdd(pDisplay, pEntry, &Point, (uint32_t)cRects, (const RTRECT*)pRects, &cr_server.PresentTexturepMap); 968 if (!RT_SUCCESS(rc)) 969 { 970 crWarning("CrDpEntryRegionsAdd Failed rc %d", rc); 971 /* no need to release anything, as CrDpEntryRegionsAdd would do everything for us as needed */ 972 // if (pEntry) 973 // CrDemEntryRelease(pEntry); 974 } 3528 hEntry = NULL; 3529 3530 rc = CrFbUpdateBegin(hFb); 3531 if (RT_SUCCESS(rc)) 3532 { 3533 if (!(cfg & CR_PRESENT_FLAG_CLEAR_RECTS)) 3534 { 3535 RTPOINT Point = {xPos, yPos}; 3536 rc = CrFbEntryRegionsAdd(hFb, hEntry, &Point, (uint32_t)cRects, (const RTRECT*)pRects, false); 3537 } 3538 else 3539 { 3540 CrFbRegionsClear(hFb); 3541 } 3542 3543 CrFbUpdateEnd(hFb); 975 3544 } 976 3545 else 977 3546 { 978 if (pEntry) 979 CrDemEntryRelease(pEntry); 980 CrDpRegionsClear(pDisplay); 981 } 982 983 CrDpLeave(pDisplay); 984 } 3547 WARN(("CrFbUpdateBegin Failed")); 3548 } 3549 3550 if (hEntry) 3551 CrFbEntryRelease(hFb, hEntry); 3552 } -
trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_stream.c
r44290 r50095 442 442 uint32_t cbWriteback = pCmdData->cbWriteback; 443 443 rc = crVBoxServerInternalClientRead(conn->pClient, (uint8_t*)pCmdData->pWriteback, &cbWriteback); 444 CRASSERT(rc == VINF_SUCCESS || rc == VERR_BUFFER_OVERFLOW);444 Assert(rc == VINF_SUCCESS || rc == VERR_BUFFER_OVERFLOW); 445 445 *pCmdData->pcbWriteback = cbWriteback; 446 446 } -
trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c
r49474 r50095 13 13 #include "render/renderspu.h" 14 14 15 static 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 38 void 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 else53 {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 63 void crServerWindowCheckIsVisible(CRMuralInfo *pMural)64 {65 GLboolean fIsVisible = crServerWindowCalcIsVisible(pMural);66 67 crServerWindowSetIsVisible(pMural, fIsVisible);68 }69 70 void crServerWindowSize(CRMuralInfo *pMural)71 {72 cr_server.head_spu->dispatch_table.WindowSize(pMural->spuWindow, pMural->width, pMural->height);73 74 crServerWindowCheckIsVisible(pMural);75 }76 77 void 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 85 void 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 else97 crWarning("CrVrScrCompositorRegionsGet failed rc %d", rc);98 99 }100 101 void 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 112 15 GLint SERVER_DISPATCH_APIENTRY 113 16 crServerDispatchWindowCreate(const char *dpyName, GLint visBits) … … 116 19 } 117 20 118 static 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 124 GLint crServerMuralInit(CRMuralInfo *mural, const char *dpyName, GLint visBits, GLint preloadWinID, GLboolean fUseDefaultDEntry) 21 GLint crServerMuralInit(CRMuralInfo *mural, const char *dpyName, GLint visBits, GLint preloadWinID) 125 22 { 126 23 CRMuralInfo *defaultMural; … … 132 29 crMemset(mural, 0, sizeof (*mural)); 133 30 134 CrVrScrCompositorInit(&mural->Compositor);135 136 if (cr_server.fRootVrOn)137 {138 CrVrScrCompositorInit(&mural->RootVrCompositor);139 }140 141 31 /* 142 32 * Have first SPU make a new window. … … 144 34 spuWindow = cr_server.head_spu->dispatch_table.WindowCreate( dpyName, visBits ); 145 35 if (spuWindow < 0) { 146 CrVrScrCompositorClear(&mural->Compositor);147 if (cr_server.fRootVrOn)148 CrVrScrCompositorClear(&mural->RootVrCompositor);149 36 return spuWindow; 150 37 } … … 152 39 /* get initial window size */ 153 40 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 41 170 42 defaultMural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, 0); … … 174 46 mural->width = dims[0]; 175 47 mural->height = dims[1]; 176 48 177 49 mural->spuWindow = spuWindow; 178 50 mural->screenId = 0; 179 51 mural->fHasParentWindow = !!cr_server.screen[0].winID; 180 52 mural->bVisible = !cr_server.bWindowsInitiallyHidden; 181 mural->fPresentMode = CR_SERVER_REDIR_F_NONE;182 53 183 54 mural->cVisibleRects = 0; … … 197 68 CR_STATE_SHAREDOBJ_USAGE_INIT(mural); 198 69 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 != 1225 || pRects[0].xLeft != 0 || pRects[0].yTop != 0226 || 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 else233 {234 crWarning("CrVrScrCompositorRegionsGet failed, rc %d", rc);235 }236 }237 }238 239 70 return windowID; 240 71 } 241 72 242 GLint 243 crServerDispatchWindowCreateEx(const char *dpyName, GLint visBits, GLint preloadWinID) 73 GLint crServerDispatchWindowCreateEx(const char *dpyName, GLint visBits, GLint preloadWinID) 244 74 { 245 75 CRMuralInfo *mural; … … 247 77 248 78 dpyName = ""; 79 80 if (cr_server.fVisualBitsDefault) 81 visBits = cr_server.fVisualBitsDefault; 249 82 250 83 if (cr_server.sharedWindows) { … … 287 120 } 288 121 289 windowID = crServerMuralInit(mural, dpyName, visBits, preloadWinID , GL_TRUE);122 windowID = crServerMuralInit(mural, dpyName, visBits, preloadWinID); 290 123 if (windowID < 0) 291 124 { … … 318 151 } 319 152 320 static 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 331 153 static int crServerRemoveClientWindow(CRClient *pClient, GLint window) 332 154 { … … 347 169 void crServerMuralTerm(CRMuralInfo *mural) 348 170 { 349 crServerRedirMuralFBO(mural, CR_SERVER_REDIR_F_NONE); 171 PCR_BLITTER pBlitter; 172 crServerRedirMuralFBO(mural, false); 350 173 crServerDeleteMuralFBO(mural); 351 174 … … 364 187 } 365 188 189 pBlitter = crServerVBoxBlitterGetInitialized(); 190 if (pBlitter) 191 { 192 const CR_BLITTER_WINDOW * pWindow = CrBltMuralGetCurrentInfo(pBlitter); 193 if (pWindow && pWindow->Base.id == mural->spuWindow) 194 { 195 CRMuralInfo *dummy = crServerGetDummyMural(mural->CreateInfo.visualBits); 196 CR_BLITTER_WINDOW DummyInfo; 197 CRASSERT(dummy); 198 CrBltMuralSetCurrentInfo(pBlitter, &DummyInfo); 199 } 200 } 366 201 367 202 cr_server.head_spu->dispatch_table.WindowDestroy( mural->spuWindow ); … … 375 210 crFree(mural->CreateInfo.pszDpyName); 376 211 377 CrVrScrCompositorClear(&mural->Compositor); 378 379 if (mural->fRootVrOn) 380 CrVrScrCompositorClear(&mural->RootVrCompositor); 212 crServerRedirMuralFbClear(mural); 381 213 } 382 214 … … 480 312 } 481 313 482 static 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 491 int 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 511 314 GLboolean crServerMuralSize(CRMuralInfo *mural, GLint width, GLint height) 512 315 { 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 316 if (mural->width == width && mural->height == height) 522 317 return GL_FALSE; 523 318 524 525 /* since we're going to change the current compositor & the window we need to avoid526 * renderspu fron dealing with inconsistent data, i.e. modified compositor and527 * 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 used530 * 2. do necessary modifications531 * 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 assume552 * 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 else565 {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 else575 {576 CrVrScrCompositorClear(&mural->Compositor);577 }578 579 /* CrVrScrCompositorUnlock(&mural->Compositor); */580 319 mural->width = width; 581 320 mural->height = height; 582 321 583 mural->fDataPresented = GL_FALSE; 584 585 if (cr_server.curClient && cr_server.curClient->currentMural == mural) 322 cr_server.head_spu->dispatch_table.WindowSize(mural->spuWindow, mural->width, mural->height); 323 324 if (cr_server.curClient && cr_server.curClient->currentMural == mural 325 && !mural->fRedirected) 586 326 { 587 327 crStateGetCurrent()->buffer.width = mural->width; … … 589 329 } 590 330 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 331 crServerCheckMuralGeometry(mural); 602 603 crServerWindowSize(mural);604 605 crServerWindowVisibleRegion(mural);606 607 crServerDEntryAllResized(mural);608 end: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 way612 613 */614 crServerVBoxCompositionDisableLeave(mural, GL_FALSE);615 332 616 333 return GL_TRUE; … … 639 356 } 640 357 641 void 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 } 358 void crServerMuralPosition(CRMuralInfo *mural, GLint x, GLint y) 359 { 360 if (mural->gX == x && mural->gY == y) 361 return; 362 363 mural->gX = x; 364 mural->gY = y; 365 366 crServerCheckMuralGeometry(mural); 697 367 } 698 368 … … 707 377 return; 708 378 } 709 crServerMuralPosition(mural, x, y , GL_FALSE);379 crServerMuralPosition(mural, x, y); 710 380 } 711 381 712 382 void crServerMuralVisibleRegion( CRMuralInfo *mural, GLint cRects, const GLint *pRects ) 713 383 { 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 avoid719 * renderspu fron dealing with inconsistent data, i.e. modified compositor and720 * 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 used723 * 2. do necessary modifications724 * 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 384 if (mural->pVisibleRects) 731 385 { … … 746 400 } 747 401 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 } 776 end: 777 /* 3. re-set the compositor (see above comment) */ 778 crServerVBoxCompositionDisableLeave(mural, fForcePresent); 402 crServerCheckMuralGeometry(mural); 779 403 } 780 404 … … 795 419 void crServerMuralShow( CRMuralInfo *mural, GLint state ) 796 420 { 797 mural->bVisible = !!state;798 799 if (mural->fPresentMode & CR_SERVER_REDIR_F_DISPLAY) 800 crServerWindowShow(mural);421 if (!mural->bVisible == !state) 422 return; 423 424 crServerCheckMuralGeometry(mural); 801 425 } 802 426 -
trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu.c
r50041 r50095 766 766 767 767 static void RENDER_APIENTRY 768 renderspuVBoxPresentComposition( GLint win, struct VBOXVR_SCR_COMPOSITOR * pCompositor,struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry )768 renderspuVBoxPresentComposition( GLint win, const struct VBOXVR_SCR_COMPOSITOR * pCompositor, const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry ) 769 769 { 770 770 WindowInfo *window; … … 789 789 } 790 790 791 void renderspuVBoxCompositorBlitStretched ( struct VBOXVR_SCR_COMPOSITOR * pCompositor, PCR_BLITTER pBlitter, GLfloat scaleX, GLfloat scaleY)792 { 793 VBOXVR_SCR_COMPOSITOR_ ITERATOR CIter;794 PVBOXVR_SCR_COMPOSITOR_ENTRYpEntry;795 CrVrScrCompositor IterInit(pCompositor, &CIter);796 while ((pEntry = CrVrScrCompositor IterNext(&CIter)) != NULL)791 void renderspuVBoxCompositorBlitStretched ( const struct VBOXVR_SCR_COMPOSITOR * pCompositor, PCR_BLITTER pBlitter, GLfloat scaleX, GLfloat scaleY) 792 { 793 VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR CIter; 794 const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry; 795 CrVrScrCompositorConstIterInit(pCompositor, &CIter); 796 while ((pEntry = CrVrScrCompositorConstIterNext(&CIter)) != NULL) 797 797 { 798 798 uint32_t cRegions; … … 806 806 { 807 807 RTRECT DstRect; 808 const CR_TEXDATA *pTexData = CrVrScrCompositorEntryTexGet(pEntry); 808 809 DstRect.xLeft = paDstRegions[i].xLeft * scaleX; 809 810 DstRect.yTop = paDstRegions[i].yTop * scaleY; 810 811 DstRect.xRight = paDstRegions[i].xRight * scaleX; 811 812 DstRect.yBottom = paDstRegions[i].yBottom * scaleY; 812 CrBltBlitTexMural(pBlitter, true, &pEntry->Tex, &paSrcRegions[i], &DstRect, 1, fFlags);813 CrBltBlitTexMural(pBlitter, true, CrTdTexGet(pTexData), &paSrcRegions[i], &DstRect, 1, fFlags); 813 814 } 814 815 } … … 820 821 } 821 822 822 void renderspuVBoxCompositorBlit ( struct VBOXVR_SCR_COMPOSITOR * pCompositor, PCR_BLITTER pBlitter)823 { 824 VBOXVR_SCR_COMPOSITOR_ ITERATOR CIter;825 PVBOXVR_SCR_COMPOSITOR_ENTRYpEntry;826 CrVrScrCompositor IterInit(pCompositor, &CIter);827 while ((pEntry = CrVrScrCompositor IterNext(&CIter)) != NULL)823 void renderspuVBoxCompositorBlit ( const struct VBOXVR_SCR_COMPOSITOR * pCompositor, PCR_BLITTER pBlitter) 824 { 825 VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR CIter; 826 const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry; 827 CrVrScrCompositorConstIterInit(pCompositor, &CIter); 828 while ((pEntry = CrVrScrCompositorConstIterNext(&CIter)) != NULL) 828 829 { 829 830 uint32_t cRegions; … … 833 834 if (RT_SUCCESS(rc)) 834 835 { 835 CrBltBlitTexMural(pBlitter, true, &pEntry->Tex, paSrcRegions, paDstRegions, cRegions, fFlags); 836 const CR_TEXDATA *pTexData = CrVrScrCompositorEntryTexGet(pEntry); 837 CrBltBlitTexMural(pBlitter, true, CrTdTexGet(pTexData), paSrcRegions, paDstRegions, cRegions, fFlags); 836 838 } 837 839 else … … 850 852 { 851 853 const CR_BLITTER_WINDOW * pBltInfo = CrBltMuralGetCurrentInfo(window->pBlitter); 852 if (pBltInfo ->Base.id == window->BltInfo.Base.id)853 { 854 CrBltMuralSetCurrent (window->pBlitter, NULL);854 if (pBltInfo && pBltInfo->Base.id == window->BltInfo.Base.id) 855 { 856 CrBltMuralSetCurrentInfo(window->pBlitter, NULL); 855 857 } 856 858 } … … 858 860 { 859 861 CRASSERT(CrBltMuralGetCurrentInfo(window->pBlitter)->Base.id == window->BltInfo.Base.id); 860 CrBltMuralSetCurrent (window->pBlitter, NULL);862 CrBltMuralSetCurrentInfo(window->pBlitter, NULL); 861 863 CrBltTerm(window->pBlitter); 862 864 } … … 895 897 } 896 898 897 rc = CrBltInit(pBlitter, &pDefaultCtxInfo->BltInfo, true, true, NULL, render_spu.blitterDispatch);899 rc = CrBltInit(pBlitter, &pDefaultCtxInfo->BltInfo, true, true, NULL, &render_spu.blitterDispatch); 898 900 899 901 /* we can release it either way, since it will be retained when used as a shared context */ … … 920 922 } 921 923 922 CrBltMuralSetCurrent (pBlitter, &window->BltInfo);924 CrBltMuralSetCurrentInfo(pBlitter, &window->BltInfo); 923 925 return pBlitter; 924 926 } … … 927 929 { 928 930 int rc; 929 PCR_BLITTER_CONTEXT pCtxInfo = NULL;930 PCR_BLITTER_WINDOW pWindowInfo = NULL;931 GET_CONTEXT(pCtx);932 933 if (pCtx)934 {935 if (pCtx->currentWindow)936 {937 pCtxInfo = &pCtx->BltInfo;938 pWindowInfo = &pCtx->currentWindow->BltInfo;939 }940 }941 931 942 932 CrBltSetMakeCurrentUserData(pBlitter, i32MakeCurrentUserData); 943 933 944 rc = CrBltEnter(pBlitter , pCtxInfo, pWindowInfo);934 rc = CrBltEnter(pBlitter); 945 935 if (!RT_SUCCESS(rc)) 946 936 { … … 969 959 if (!window->pBlitter) 970 960 { 971 struct VBOXVR_SCR_COMPOSITOR * pTmpCompositor;961 const struct VBOXVR_SCR_COMPOSITOR * pTmpCompositor; 972 962 /* just use compositor lock to synchronize */ 973 963 pTmpCompositor = renderspuVBoxCompositorAcquire(window); … … 1006 996 } 1007 997 1008 void renderspuVBoxPresentCompositionGeneric( WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR * pCompositor,struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry, int32_t i32MakeCurrentUserData )998 void renderspuVBoxPresentCompositionGeneric( WindowInfo *window, const struct VBOXVR_SCR_COMPOSITOR * pCompositor, const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry, int32_t i32MakeCurrentUserData ) 1009 999 { 1010 1000 PCR_BLITTER pBlitter = renderspuVBoxPresentBlitterGetAndEnter(window, i32MakeCurrentUserData); … … 1019 1009 } 1020 1010 1021 void renderspuVBoxCompositorSet( WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR * pCompositor)1011 void renderspuVBoxCompositorSet( WindowInfo *window, const struct VBOXVR_SCR_COMPOSITOR * pCompositor) 1022 1012 { 1023 1013 int rc; … … 1056 1046 } 1057 1047 1058 struct VBOXVR_SCR_COMPOSITOR * renderspuVBoxCompositorAcquire( WindowInfo *window)1048 const struct VBOXVR_SCR_COMPOSITOR * renderspuVBoxCompositorAcquire( WindowInfo *window) 1059 1049 { 1060 1050 int rc = RTCritSectEnter(&window->CompositorLock); 1061 1051 if (RT_SUCCESS(rc)) 1062 1052 { 1063 VBOXVR_SCR_COMPOSITOR * pCompositor = window->pCompositor;1053 const VBOXVR_SCR_COMPOSITOR * pCompositor = window->pCompositor; 1064 1054 if (pCompositor) 1065 1055 return pCompositor; … … 1089 1079 } 1090 1080 1091 int renderspuVBoxCompositorTryAcquire(WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR **ppCompositor)1081 int renderspuVBoxCompositorTryAcquire(WindowInfo *window, const struct VBOXVR_SCR_COMPOSITOR **ppCompositor) 1092 1082 { 1093 1083 int rc = RTCritSectTryEnter(&window->CompositorLock); … … 1551 1541 break; 1552 1542 1543 case GL_HH_SET_TMPCTX_MAKE_CURRENT: 1544 if (type == GL_BYTE && count == sizeof (void*)) 1545 memcpy(&render_spu.blitterDispatch.MakeCurrent, values, count); 1546 else 1547 crWarning("unexpected type(%#x) - count(%d) pair", type, count); 1548 break; 1549 1553 1550 default: 1554 1551 #if 0 -
trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu.h
r50041 r50095 29 29 #include "cr_server.h" 30 30 #include "cr_blitter.h" 31 #include "cr_compositor.h" 31 32 32 33 #include <iprt/cdefs.h> … … 103 104 char *title; 104 105 105 PVBOXVR_SCR_COMPOSITORpCompositor;106 const VBOXVR_SCR_COMPOSITOR *pCompositor; 106 107 /* the composotor lock is used to synchronize the current compositor access, 107 108 * i.e. the compositor can be accessed by a gui refraw thread, … … 285 286 CRConnection **swap_conns; 286 287 287 SPUDispatchTable *blitterDispatch;288 SPUDispatchTable blitterDispatch; 288 289 CRHashTable *blitterTable; 289 290 … … 406 407 extern void renderspu_SystemSwapBuffers( WindowInfo *window, GLint flags ); 407 408 extern void renderspu_SystemReparentWindow(WindowInfo *window); 408 extern void renderspu_SystemVBoxPresentComposition( WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry );409 extern void renderspu_SystemVBoxPresentComposition( WindowInfo *window, const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry ); 409 410 uint32_t renderspu_SystemPostprocessFunctions(SPUNamedFunctionTable *aFunctions, uint32_t cFunctions, uint32_t cTable); 410 411 extern void renderspu_GCWindow(void); 411 412 extern int renderspuCreateFunctions( SPUNamedFunctionTable table[] ); 412 extern void renderspuVBoxCompositorSet( WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR * pCompositor);413 extern void renderspuVBoxCompositorSet( WindowInfo *window, const struct VBOXVR_SCR_COMPOSITOR * pCompositor); 413 414 extern void renderspuVBoxCompositorClearAll(); 414 415 extern int renderspuVBoxCompositorLock(WindowInfo *window); 415 416 extern int renderspuVBoxCompositorUnlock(WindowInfo *window); 416 extern struct VBOXVR_SCR_COMPOSITOR * renderspuVBoxCompositorAcquire( WindowInfo *window);417 extern int renderspuVBoxCompositorTryAcquire(WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR **ppCompositor);417 extern const struct VBOXVR_SCR_COMPOSITOR * renderspuVBoxCompositorAcquire( WindowInfo *window); 418 extern int renderspuVBoxCompositorTryAcquire(WindowInfo *window, const struct VBOXVR_SCR_COMPOSITOR **ppCompositor); 418 419 extern void renderspuVBoxCompositorRelease( WindowInfo *window); 419 extern void renderspuVBoxPresentCompositionGeneric( WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR * pCompositor,struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry, int32_t i32MakeCurrentUserData );420 extern void renderspuVBoxPresentCompositionGeneric( WindowInfo *window, const struct VBOXVR_SCR_COMPOSITOR * pCompositor, const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry, int32_t i32MakeCurrentUserData ); 420 421 extern PCR_BLITTER renderspuVBoxPresentBlitterGet( WindowInfo *window ); 421 422 void renderspuVBoxPresentBlitterCleanup( WindowInfo *window ); … … 429 430 extern GLboolean renderspuWindowInitWithVisual( WindowInfo *window, VisualInfo *visual, GLboolean showIt, GLint id ); 430 431 extern GLboolean renderspuInitVisual(VisualInfo *pVisInfo, const char *displayName, GLbitfield visAttribs); 431 extern void renderspuVBoxCompositorBlit ( struct VBOXVR_SCR_COMPOSITOR * pCompositor, PCR_BLITTER pBlitter);432 extern void renderspuVBoxCompositorBlitStretched ( struct VBOXVR_SCR_COMPOSITOR * pCompositor, PCR_BLITTER pBlitter, GLfloat scaleX, GLfloat scaleY);432 extern void renderspuVBoxCompositorBlit ( const struct VBOXVR_SCR_COMPOSITOR * pCompositor, PCR_BLITTER pBlitter); 433 extern void renderspuVBoxCompositorBlitStretched ( const struct VBOXVR_SCR_COMPOSITOR * pCompositor, PCR_BLITTER pBlitter, GLfloat scaleX, GLfloat scaleY); 433 434 extern GLint renderspuCreateContextEx(const char *dpyName, GLint visBits, GLint id, GLint shareCtx); 434 435 extern GLint renderspuWindowCreateEx( const char *dpyName, GLint visBits, GLint id ); -
trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_agl.c
r48291 r50095 608 608 } 609 609 610 void renderspu_SystemVBoxPresentComposition( WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR * pCompositor,struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry )610 void renderspu_SystemVBoxPresentComposition( WindowInfo *window, const struct VBOXVR_SCR_COMPOSITOR * pCompositor, const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry ) 611 611 { 612 612 renderspuVBoxPresentCompositionGeneric(window, pCompositor, pChangedEntry, 0); -
trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa.c
r50041 r50095 155 155 } 156 156 157 void renderspu_SystemVBoxPresentComposition( WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry )157 void renderspu_SystemVBoxPresentComposition( WindowInfo *window, const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry ) 158 158 { 159 159 cocoaViewPresentComposition(window->window, pChangedEntry); … … 271 271 if (!CrGlslIsInited(&render_spu.GlobalShaders)) 272 272 { 273 CrGlslInit(&render_spu.GlobalShaders, render_spu.blitterDispatch);273 CrGlslInit(&render_spu.GlobalShaders, &render_spu.blitterDispatch); 274 274 } 275 275 -
trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.h
r45132 r50095 23 23 #include <OpenGL/OpenGL.h> 24 24 #include <cr_vreg.h> 25 #include <cr_compositor.h> 26 25 27 26 28 RT_C_DECLS_BEGIN … … 47 49 void cocoaViewMakeCurrentContext(NativeNSViewRef pView, NativeNSOpenGLContextRef pCtx); 48 50 void cocoaViewSetVisibleRegion(NativeNSViewRef pView, GLint cRects, const GLint* paRects); 49 void cocoaViewPresentComposition(NativeNSViewRef pView, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry);51 void cocoaViewPresentComposition(NativeNSViewRef pView, const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry); 50 52 51 53 RT_C_DECLS_END -
trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.m
r49868 r50095 373 373 - (void)vboxTryDraw; 374 374 - (void)vboxTryDrawUI; 375 - (void)vboxPresent:( PVBOXVR_SCR_COMPOSITOR)pCompositor;376 - (void)vboxPresentCS:( PVBOXVR_SCR_COMPOSITOR)pCompositor;377 - (void)vboxPresentToDockTileCS:( PVBOXVR_SCR_COMPOSITOR)pCompositor;378 - (void)vboxPresentToViewCS:( PVBOXVR_SCR_COMPOSITOR)pCompositor;379 - (void)presentComposition:( PVBOXVR_SCR_COMPOSITOR_ENTRY)pChangedEntry;375 - (void)vboxPresent:(const VBOXVR_SCR_COMPOSITOR*)pCompositor; 376 - (void)vboxPresentCS:(const VBOXVR_SCR_COMPOSITOR*)pCompositor; 377 - (void)vboxPresentToDockTileCS:(const VBOXVR_SCR_COMPOSITOR*)pCompositor; 378 - (void)vboxPresentToViewCS:(const VBOXVR_SCR_COMPOSITOR*)pCompositor; 379 - (void)presentComposition:(const VBOXVR_SCR_COMPOSITOR_ENTRY*)pChangedEntry; 380 380 - (void)vboxBlitterSyncWindow; 381 381 … … 790 790 [self deleteDockTile]; 791 791 792 if (m_pGLCtx) 793 { 794 if ([m_pGLCtx view] == self) 795 [m_pGLCtx clearDrawable]; 796 797 m_pGLCtx = nil; 798 } 792 [self setGLCtx:nil]; 793 799 794 if (m_pSharedGLCtx) 800 795 { … … 808 803 CrBltTerm(m_pBlitter); 809 804 805 RTMemFree(m_pBlitter); 806 810 807 m_pBlitter = nil; 811 808 } … … 836 833 /* ensure the context drawable is cleared to avoid holding a reference to inexistent view */ 837 834 if (m_pGLCtx) 835 { 838 836 [m_pGLCtx clearDrawable]; 837 [m_pGLCtx release]; 838 /*[m_pGLCtx performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:NO];*/ 839 } 839 840 840 841 m_pGLCtx = pCtx; 842 if (pCtx) 843 [pCtx retain]; 841 844 } 842 845 … … 1113 1116 if ([self lockFocusIfCanDraw]) 1114 1117 { 1115 VBOXVR_SCR_COMPOSITOR *pCompositor = NULL;1118 const const VBOXVR_SCR_COMPOSITOR *pCompositor = NULL; 1116 1119 if (!m_pSharedGLCtx) 1117 1120 { … … 1123 1126 if (m_pBlitter) 1124 1127 { 1125 int rc = CrBltInit(m_pBlitter, NULL, false, false, &render_spu.GlobalShaders, render_spu.blitterDispatch);1128 int rc = CrBltInit(m_pBlitter, NULL, false, false, &render_spu.GlobalShaders, &render_spu.blitterDispatch); 1126 1129 if (RT_SUCCESS(rc)) 1127 1130 { … … 1218 1221 * while here we do a reverse order: acquire compositor lock being in gui thread. 1219 1222 * this is why we do only try acquire and re-submit repaint event if compositor lock is busy */ 1220 VBOXVR_SCR_COMPOSITOR *pCompositor = NULL;1223 const VBOXVR_SCR_COMPOSITOR *pCompositor = NULL; 1221 1224 int rc = renderspuVBoxCompositorTryAcquire(m_pWinInfo, &pCompositor); 1222 1225 if (RT_SUCCESS(rc)) … … 1228 1231 else if (rc == VERR_SEM_BUSY) 1229 1232 { 1233 Assert(!pCompositor); 1230 1234 /* re-issue to the gui thread */ 1231 1235 # ifdef DEBUG_misha … … 1234 1238 [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(vboxTryDrawUI) userInfo:nil repeats:NO]; 1235 1239 } 1236 else 1240 else if (rc != VERR_INVALID_STATE) /* VERR_INVALID_STATE means no compositor, which is ok */ 1237 1241 { 1242 Assert(!pCompositor); 1238 1243 /* this is somewhat we do not expect */ 1239 1244 DEBUG_WARN(("renderspuVBoxCompositorTryAcquire failed rc %d", rc)); 1240 1245 } 1241 1246 #else 1242 VBOXVR_SCR_COMPOSITOR *pCompositor = renderspuVBoxCompositorAcquire(m_pWinInfo);1247 const VBOXVR_SCR_COMPOSITOR *pCompositor = renderspuVBoxCompositorAcquire(m_pWinInfo); 1243 1248 if (pCompositor) 1244 1249 { … … 1261 1266 } 1262 1267 1263 - (void)vboxPresent:( PVBOXVR_SCR_COMPOSITOR)pCompositor1268 - (void)vboxPresent:(const VBOXVR_SCR_COMPOSITOR*)pCompositor 1264 1269 { 1265 1270 VBOX_CR_RENDER_CTX_INFO CtxInfo; … … 1285 1290 } 1286 1291 1287 - (void)vboxPresentCS:( PVBOXVR_SCR_COMPOSITOR)pCompositor1292 - (void)vboxPresentCS:(const VBOXVR_SCR_COMPOSITOR*)pCompositor 1288 1293 { 1289 1294 { … … 1338 1343 } 1339 1344 1340 - (void)vboxPresentToViewCS:( PVBOXVR_SCR_COMPOSITOR)pCompositor1345 - (void)vboxPresentToViewCS:(const VBOXVR_SCR_COMPOSITOR*)pCompositor 1341 1346 { 1342 1347 NSRect r = [self frame]; … … 1345 1350 1346 1351 #if 1 /* Set to 0 to see the docktile instead of the real output */ 1347 VBOXVR_SCR_COMPOSITOR_ ITERATOR CIter;1348 PVBOXVR_SCR_COMPOSITOR_ENTRYpEntry;1352 VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR CIter; 1353 const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry; 1349 1354 1350 CrVrScrCompositor IterInit(pCompositor, &CIter);1355 CrVrScrCompositorConstIterInit(pCompositor, &CIter); 1351 1356 1352 1357 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0); … … 1358 1363 CrVrScrCompositorGetStretching(pCompositor, &xStretch, &yStretch); 1359 1364 1360 while ((pEntry = CrVrScrCompositor IterNext(&CIter)) != NULL)1365 while ((pEntry = CrVrScrCompositorConstIterNext(&CIter)) != NULL) 1361 1366 { 1362 1367 uint32_t cRegions; … … 1367 1372 { 1368 1373 uint32_t i; 1369 int rc = CrBltEnter(m_pBlitter , NULL, NULL);1374 int rc = CrBltEnter(m_pBlitter); 1370 1375 if (RT_SUCCESS(rc)) 1371 1376 { … … 1374 1379 const RTRECT * pSrcRect = &paSrcRegions[i]; 1375 1380 const RTRECT * pDstRect = &paDstRegions[i]; 1376 RTRECT SrcRect, DstRect, RestrictSrcRect, RestrictDstRect; 1377 1381 RTRECT DstRect, RestrictDstRect; 1382 RTRECT SrcRect, RestrictSrcRect; 1383 1378 1384 vboxNSRectToRect(&m_RootRect, &RestrictDstRect); 1379 1385 VBoxRectIntersected(&RestrictDstRect, pDstRect, &DstRect); … … 1383 1389 1384 1390 VBoxRectTranslate(&DstRect, -RestrictDstRect.xLeft, -RestrictDstRect.yTop); 1385 1391 1386 1392 vboxNSRectToRectUnstretched(&m_RootRect, &RestrictSrcRect, xStretch, yStretch); 1393 VBoxRectTranslate(&RestrictSrcRect, -CrVrScrCompositorEntryRectGet(pEntry)->xLeft, -CrVrScrCompositorEntryRectGet(pEntry)->yTop); 1387 1394 VBoxRectIntersected(&RestrictSrcRect, pSrcRect, &SrcRect); 1388 1395 … … 1393 1400 pDstRect = &DstRect; 1394 1401 1395 CrBltBlitTexMural(m_pBlitter, true, &pEntry->Tex, pSrcRect, pDstRect, 1, fFlags | CRBLT_F_NOALPHA); 1402 const CR_TEXDATA *pTexData = CrVrScrCompositorEntryTexGet(pEntry); 1403 1404 CrBltBlitTexMural(m_pBlitter, true, CrTdTexGet(pTexData), pSrcRect, pDstRect, 1, fFlags | CRBLT_F_NOALPHA); 1396 1405 } 1397 1406 CrBltLeave(m_pBlitter); … … 1416 1425 } 1417 1426 1418 - (void)presentComposition:( PVBOXVR_SCR_COMPOSITOR_ENTRY)pChangedEntry1427 - (void)presentComposition:(const VBOXVR_SCR_COMPOSITOR_ENTRY*)pChangedEntry 1419 1428 { 1420 1429 [self vboxTryDraw]; … … 1438 1447 Assert(WinInfo.height = m_RootRect.size.height); 1439 1448 1440 /*CrBltMuralSetCurrent (m_pBlitter, NULL);*/1441 1442 CrBltMuralSetCurrent (m_pBlitter, &WinInfo);1449 /*CrBltMuralSetCurrentInfo(m_pBlitter, NULL);*/ 1450 1451 CrBltMuralSetCurrentInfo(m_pBlitter, &WinInfo); 1443 1452 CrBltCheckUpdateViewport(m_pBlitter); 1444 1453 } … … 1447 1456 static int g_cVBoxTgaCtr = 0; 1448 1457 #endif 1449 - (void)vboxPresentToDockTileCS:( PVBOXVR_SCR_COMPOSITOR)pCompositor1458 - (void)vboxPresentToDockTileCS:(const VBOXVR_SCR_COMPOSITOR*)pCompositor 1450 1459 { 1451 1460 NSRect r = [self frame]; … … 1460 1469 * heavy performance wise. */ 1461 1470 uint64_t uiNewTime = RTTimeMilliTS(); 1462 VBOXVR_SCR_COMPOSITOR_ ITERATOR CIter;1463 PVBOXVR_SCR_COMPOSITOR_ENTRYpEntry;1471 VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR CIter; 1472 const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry; 1464 1473 1465 1474 if (uiNewTime - m_uiDockUpdateTime > 200) … … 1492 1501 CrVrScrCompositorGetStretching(pCompositor, &xStretch, &yStretch); 1493 1502 1494 CrVrScrCompositor IterInit(pCompositor, &CIter);1495 while ((pEntry = CrVrScrCompositor IterNext(&CIter)) != NULL)1503 CrVrScrCompositorConstIterInit(pCompositor, &CIter); 1504 while ((pEntry = CrVrScrCompositorConstIterNext(&CIter)) != NULL) 1496 1505 { 1497 1506 uint32_t cRegions; … … 1502 1511 { 1503 1512 uint32_t i; 1504 int rc = CrBltEnter(m_pBlitter , NULL, NULL);1513 int rc = CrBltEnter(m_pBlitter); 1505 1514 if (RT_SUCCESS(rc)) 1506 1515 { … … 1522 1531 1523 1532 vboxNSRectToRectUnstretched(&m_RootRect, &RestrictSrcRect, xStretch, yStretch); 1533 VBoxRectTranslate(&RestrictSrcRect, -CrVrScrCompositorEntryRectGet(pEntry)->xLeft, -CrVrScrCompositorEntryRectGet(pEntry)->yTop); 1524 1534 VBoxRectIntersected(&RestrictSrcRect, pSrcRect, &SrcRect); 1525 1535 … … 1530 1540 pDstRect = &DstRect; 1531 1541 1532 CrBltBlitTexMural(m_pBlitter, true, &pEntry->Tex, pSrcRect, pDstRect, 1, fFlags); 1542 const CR_TEXDATA *pTexData = CrVrScrCompositorEntryTexGet(pEntry); 1543 1544 CrBltBlitTexMural(m_pBlitter, true, CrTdTexGet(pTexData), pSrcRect, pDstRect, 1, fFlags); 1533 1545 } 1534 1546 CrBltLeave(m_pBlitter); … … 1747 1759 NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init]; 1748 1760 1749 /*1750 1761 [pCtx release]; 1751 */1762 /*[pCtx performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:NO];*/ 1752 1763 1753 1764 [pPool release]; … … 1906 1917 } 1907 1918 1908 void cocoaViewPresentComposition(NativeNSViewRef pView, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry)1919 void cocoaViewPresentComposition(NativeNSViewRef pView, const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry) 1909 1920 { 1910 1921 NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init]; -
trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_glx.c
r50041 r50095 579 579 if (pWindow) 580 580 { 581 struct VBOXVR_SCR_COMPOSITOR * pCompositor;581 const struct VBOXVR_SCR_COMPOSITOR * pCompositor; 582 582 583 583 pCompositor = renderspuVBoxCompositorAcquire(pWindow); … … 1969 1969 } 1970 1970 1971 void renderspu_SystemVBoxPresentComposition( WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry )1971 void renderspu_SystemVBoxPresentComposition( WindowInfo *window, const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry ) 1972 1972 { 1973 1973 /* the CR_RENDER_FORCE_PRESENT_MAIN_THREAD is actually inherited from cocoa backend impl, … … 1976 1976 * @todo: change to some more generic macro name */ 1977 1977 #ifndef CR_RENDER_FORCE_PRESENT_MAIN_THREAD 1978 struct VBOXVR_SCR_COMPOSITOR *pCompositor;1978 const struct VBOXVR_SCR_COMPOSITOR *pCompositor; 1979 1979 /* we do not want to be blocked with the GUI thread here, so only draw her eif we are really able to do that w/o bllocking */ 1980 1980 int rc = renderspuVBoxCompositorTryAcquire(window, &pCompositor); -
trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_init.c
r50041 r50095 386 386 crSPUCopyDispatchTable( &(render_spu.self), self ); 387 387 388 render_spu.blitterDispatch = &(render_spu.self); 388 crSPUInitDispatchTable( &(render_spu.blitterDispatch) ); 389 crSPUCopyDispatchTable( &(render_spu.blitterDispatch), self ); 389 390 390 391 render_spu.server = (CRServer *)(self->server); -
trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c
r50041 r50095 431 431 if (pWindow) 432 432 { 433 struct VBOXVR_SCR_COMPOSITOR * pCompositor;433 const struct VBOXVR_SCR_COMPOSITOR * pCompositor; 434 434 435 435 pCompositor = renderspuVBoxCompositorAcquire(pWindow); … … 1252 1252 } 1253 1253 1254 void renderspu_SystemVBoxPresentComposition( WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry )1254 void renderspu_SystemVBoxPresentComposition( WindowInfo *window, const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry ) 1255 1255 { 1256 1256 /* the CR_RENDER_FORCE_PRESENT_MAIN_THREAD is actually inherited from cocoa backend impl, … … 1259 1259 * @todo: change to some more generic macro name */ 1260 1260 #ifndef CR_RENDER_FORCE_PRESENT_MAIN_THREAD 1261 struct VBOXVR_SCR_COMPOSITOR *pCompositor;1261 const struct VBOXVR_SCR_COMPOSITOR *pCompositor; 1262 1262 /* we do not want to be blocked with the GUI thread here, so only draw her eif we are really able to do that w/o bllocking */ 1263 1263 int rc = renderspuVBoxCompositorTryAcquire(window, &pCompositor);
Note:
See TracChangeset
for help on using the changeset viewer.