Changeset 50095 in vbox for trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.cpp
- Timestamp:
- Jan 17, 2014 4:34:07 PM (11 years ago)
- svn:sync-xref-src-repo-rev:
- 91620
- File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
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 }
Note:
See TracChangeset
for help on using the changeset viewer.