- Timestamp:
- Jan 20, 2014 4:30:32 PM (11 years ago)
- Location:
- trunk/src/VBox/HostServices/SharedOpenGL/crserverlib
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h
r50095 r50123 132 132 133 133 void crServerCheckMuralGeometry(CRMuralInfo *mural); 134 void crServerCheckAllMuralGeometry(CRMuralInfo *pMI); 134 135 GLboolean crServerSupportRedirMuralFBO(void); 135 136 … … 150 151 GLint crServerMuralFBOIdxFromBufferName(CRMuralInfo *mural, GLenum buffer); 151 152 void crServerMuralFBOSwapBuffers(CRMuralInfo *mural); 153 154 HCR_FRAMEBUFFER CrPMgrFbGetFirstEnabled(); 155 HCR_FRAMEBUFFER CrPMgrFbGetNextEnabled(HCR_FRAMEBUFFER hFb); 156 HCR_FRAMEBUFFER CrPMgrFbGetFirstInitialized(); 157 HCR_FRAMEBUFFER CrPMgrFbGetNextInitialized(HCR_FRAMEBUFFER hFb); 152 158 153 159 … … 364 370 int crServerVBoxParseNumerics(const char *pszStr, const int defaultVal); 365 371 372 typedef struct CR_FBMAP 373 { 374 uint8_t Map[(CR_MAX_GUEST_MONITORS+7)/8]; 375 } CR_FBMAP; 376 377 DECLINLINE(void) CrFBmInit(CR_FBMAP *pMap) 378 { 379 memset(pMap, 0, sizeof (*pMap)); 380 } 381 382 DECLINLINE(bool) CrFBmIsSet(CR_FBMAP *pMap, uint32_t i) 383 { 384 return ASMBitTest(&pMap->Map, i); 385 } 386 387 DECLINLINE(void) CrFBmSet(CR_FBMAP *pMap, uint32_t i) 388 { 389 return ASMBitSet(&pMap->Map, i); 390 } 391 392 DECLINLINE(void) CrFBmClear(CR_FBMAP *pMap, uint32_t i) 393 { 394 return ASMBitClear(&pMap->Map, i); 395 } 396 366 397 /*helper function that calls CrFbUpdateBegin for all enabled framebuffers */ 367 int CrPMgrHlpGlblUpdateBegin( );398 int CrPMgrHlpGlblUpdateBegin(CR_FBMAP *pMap); 368 399 /*helper function that calls CrFbUpdateEnd for all framebuffers being updated */ 369 void CrPMgrHlpGlblUpdateEnd( );400 void CrPMgrHlpGlblUpdateEnd(CR_FBMAP *pMap); 370 401 HCR_FRAMEBUFFER CrPMgrFbGetFirstEnabled(); 371 402 HCR_FRAMEBUFFER CrPMgrFbGetNextEnabled(HCR_FRAMEBUFFER hFb); -
trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.cpp
r50095 r50123 47 47 crServerRedirMuralFBO(mural, true); 48 48 crServerRedirMuralFbSync(mural); 49 } 50 51 static void crServerCheckMuralGeometryCB(unsigned long key, void *data1, void *data2) 52 { 53 CRMuralInfo *pMI = (CRMuralInfo*) data1; 54 55 if (!pMI->fRedirected || pMI == data2) 56 return; 57 58 crServerCheckMuralGeometry(pMI); 59 } 60 61 62 void crServerCheckAllMuralGeometry(CRMuralInfo *pMI) 63 { 64 CR_FBMAP Map; 65 int rc = CrPMgrHlpGlblUpdateBegin(&Map); 66 if (!RT_SUCCESS(rc)) 67 { 68 WARN(("CrPMgrHlpGlblUpdateBegin failed %d", rc)); 69 return; 70 } 71 72 crHashtableWalk(cr_server.muralTable, crServerCheckMuralGeometryCB, pMI); 73 74 if (pMI) 75 crServerCheckMuralGeometry(pMI); 76 77 CrPMgrHlpGlblUpdateEnd(&Map); 49 78 } 50 79 -
trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp
r50108 r50123 101 101 CRHashTable *pFbTexMap; 102 102 CR_FBDISPLAY_INFO aDisplayInfos[CR_MAX_GUEST_MONITORS]; 103 uint8_t aFramebufferInitMap[(CR_MAX_GUEST_MONITORS+7)/8];103 CR_FBMAP FramebufferInitMap; 104 104 CR_FRAMEBUFFER aFramebuffers[CR_MAX_GUEST_MONITORS]; 105 105 } CR_PRESENTER_GLOBALS; … … 215 215 return; 216 216 } 217 uint32_t idScreen = pFb->ScreenInfo.u32ViewIndex; 218 217 219 CrVrScrCompositorClear(&pFb->Compositor); 218 220 CrHTableDestroy(&pFb->SlotTable); 219 221 memset(pFb, 0, sizeof (*pFb)); 222 223 pFb->ScreenInfo.u16Flags = VBVA_SCREEN_F_DISABLED; 224 pFb->ScreenInfo.u32ViewIndex = idScreen; 220 225 } 221 226 … … 277 282 278 283 static int crPMgrModeModifyGlobal(uint32_t u32Mode, bool fEnable); 284 285 static CR_FBTEX* crFbTexAlloc() 286 { 287 #ifndef VBOXVDBG_MEMCACHE_DISABLE 288 return (CR_FBTEX*)RTMemCacheAlloc(g_CrPresenter.FbTexLookasideList); 289 #else 290 return (CR_FBTEX*)RTMemAlloc(sizeof (CR_FBTEX)); 291 #endif 292 } 293 294 static void crFbTexFree(CR_FBTEX *pTex) 295 { 296 #ifndef VBOXVDBG_MEMCACHE_DISABLE 297 RTMemCacheFree(g_CrPresenter.FbTexLookasideList, pTex); 298 #else 299 RTMemFree(pTex); 300 #endif 301 } 302 303 static CR_FRAMEBUFFER_ENTRY* crFbEntryAlloc() 304 { 305 #ifndef VBOXVDBG_MEMCACHE_DISABLE 306 return (CR_FRAMEBUFFER_ENTRY*)RTMemCacheAlloc(g_CrPresenter.FbEntryLookasideList); 307 #else 308 return (CR_FRAMEBUFFER_ENTRY*)RTMemAlloc(sizeof (CR_FRAMEBUFFER_ENTRY)); 309 #endif 310 } 311 312 static void crFbEntryFree(CR_FRAMEBUFFER_ENTRY *pEntry) 313 { 314 Assert(!CrVrScrCompositorEntryIsUsed(&pEntry->Entry)); 315 #ifndef VBOXVDBG_MEMCACHE_DISABLE 316 RTMemCacheFree(g_CrPresenter.FbEntryLookasideList, pEntry); 317 #else 318 RTMemFree(pEntry); 319 #endif 320 } 321 322 DECLCALLBACK(void) crFbTexRelease(CR_TEXDATA *pTex) 323 { 324 CR_FBTEX *pFbTex = PCR_FBTEX_FROM_TEX(pTex); 325 CRTextureObj *pTobj = pFbTex->pTobj; 326 327 CrTdBltDataCleanup(pTex); 328 329 if (pTobj) 330 { 331 CR_STATE_SHAREDOBJ_USAGE_CLEAR(pTobj, cr_server.MainContextInfo.pContext); 332 333 crHashtableDelete(g_CrPresenter.pFbTexMap, pTobj->id, NULL); 334 335 if (!CR_STATE_SHAREDOBJ_USAGE_IS_USED(pTobj)) 336 { 337 CRSharedState *pShared = crStateGlobalSharedAcquire(); 338 339 CRASSERT(pShared); 340 /* on the host side, we need to delete an ogl texture object here as well, which crStateDeleteTextureCallback will do 341 * in addition to calling crStateDeleteTextureObject to delete a state object */ 342 crHashtableDelete(pShared->textureTable, pTobj->id, crStateDeleteTextureCallback); 343 344 crStateGlobalSharedRelease(); 345 } 346 347 crStateGlobalSharedRelease(); 348 } 349 350 crFbTexFree(pFbTex); 351 } 352 353 void CrFbTexDataInit(CR_TEXDATA* pFbTex, const VBOXVR_TEXTURE *pTex, PFNCRTEXDATA_RELEASED pfnTextureReleased) 354 { 355 PCR_BLITTER pBlitter = crServerVBoxBlitterGet(); 356 357 CrTdInit(pFbTex, pTex, pBlitter, pfnTextureReleased); 358 } 359 360 static CR_FBTEX* crFbTexCreate(const VBOXVR_TEXTURE *pTex) 361 { 362 CR_FBTEX *pFbTex = crFbTexAlloc(); 363 if (!pFbTex) 364 { 365 WARN(("crFbTexAlloc failed!")); 366 return NULL; 367 } 368 369 CrFbTexDataInit(&pFbTex->Tex, pTex, crFbTexRelease); 370 pFbTex->pTobj = NULL; 371 372 return pFbTex; 373 } 374 375 376 CR_TEXDATA* CrFbTexDataCreate(const VBOXVR_TEXTURE *pTex) 377 { 378 CR_FBTEX *pFbTex = crFbTexCreate(pTex); 379 if (!pFbTex) 380 { 381 WARN(("crFbTexCreate failed!")); 382 return NULL; 383 } 384 385 return &pFbTex->Tex; 386 } 387 388 static CR_FBTEX* crFbTexAcquire(GLuint idTexture) 389 { 390 CR_FBTEX *pFbTex = (CR_FBTEX *)crHashtableSearch(g_CrPresenter.pFbTexMap, idTexture); 391 if (pFbTex) 392 { 393 CrTdAddRef(&pFbTex->Tex); 394 return pFbTex; 395 } 396 397 CRSharedState *pShared = crStateGlobalSharedAcquire(); 398 if (!pShared) 399 { 400 WARN(("pShared is null!")); 401 return NULL; 402 } 403 404 CRTextureObj *pTobj = (CRTextureObj*)crHashtableSearch(pShared->textureTable, idTexture); 405 if (!pTobj) 406 { 407 WARN(("pTobj is null!")); 408 crStateGlobalSharedRelease(); 409 return NULL; 410 } 411 412 Assert(pTobj->id == idTexture); 413 414 GLuint hwid = crStateGetTextureObjHWID(pTobj); 415 if (!hwid) 416 { 417 WARN(("hwId is null!")); 418 crStateGlobalSharedRelease(); 419 return NULL; 420 } 421 422 VBOXVR_TEXTURE Tex; 423 Tex.width = pTobj->level[0]->width; 424 Tex.height = pTobj->level[0]->height; 425 Tex.hwid = hwid; 426 Tex.target = pTobj->target; 427 428 pFbTex = crFbTexCreate(&Tex); 429 if (!pFbTex) 430 { 431 WARN(("crFbTexCreate failed!")); 432 crStateGlobalSharedRelease(); 433 return NULL; 434 } 435 436 CR_STATE_SHAREDOBJ_USAGE_SET(pTobj, cr_server.MainContextInfo.pContext); 437 438 pFbTex->pTobj = pTobj; 439 440 crHashtableAdd(g_CrPresenter.pFbTexMap, idTexture, pFbTex); 441 442 return pFbTex; 443 } 444 445 static void crFbEntryMarkDestroyed(CR_FRAMEBUFFER *pFb, CR_FRAMEBUFFER_ENTRY* pEntry) 446 { 447 if (pEntry->Flags.fCreateNotified) 448 { 449 pEntry->Flags.fCreateNotified = 0; 450 if (pFb->pDisplay) 451 pFb->pDisplay->EntryDestroyed(pFb, pEntry); 452 } 453 } 454 455 static void crFbEntryDestroy(CR_FRAMEBUFFER *pFb, CR_FRAMEBUFFER_ENTRY* pEntry) 456 { 457 crFbEntryMarkDestroyed(pFb, pEntry); 458 CrVrScrCompositorEntryCleanup(&pEntry->Entry); 459 CrHTableDestroy(&pEntry->HTable); 460 crFbEntryFree(pEntry); 461 } 462 463 DECLINLINE(uint32_t) crFbEntryAddRef(CR_FRAMEBUFFER_ENTRY* pEntry) 464 { 465 return ++pEntry->cRefs; 466 } 467 468 DECLINLINE(uint32_t) crFbEntryRelease(CR_FRAMEBUFFER *pFb, CR_FRAMEBUFFER_ENTRY* pEntry) 469 { 470 uint32_t cRefs = --pEntry->cRefs; 471 if (!cRefs) 472 crFbEntryDestroy(pFb, pEntry); 473 return cRefs; 474 } 475 476 static DECLCALLBACK(void) crFbEntryReleased(const struct VBOXVR_SCR_COMPOSITOR *pCompositor, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pReplacingEntry) 477 { 478 CR_FRAMEBUFFER *pFb = PCR_FRAMEBUFFER_FROM_COMPOSITOR(pCompositor); 479 CR_FRAMEBUFFER_ENTRY *pFbEntry = PCR_FBENTRY_FROM_ENTRY(pEntry); 480 CR_FRAMEBUFFER_ENTRY *pFbReplacingEntry = pReplacingEntry ? PCR_FBENTRY_FROM_ENTRY(pReplacingEntry) : NULL; 481 if (pFbReplacingEntry) 482 { 483 /*replace operation implies the replaced entry gets auto-destroyed, 484 * while all its data gets moved to the *clean* replacing entry 485 * 1. ensure the replacing entry is cleaned up */ 486 crFbEntryMarkDestroyed(pFb, pFbReplacingEntry); 487 488 CrHTableMoveTo(&pFbEntry->HTable, &pFbReplacingEntry->HTable); 489 if (pFb->pDisplay) 490 pFb->pDisplay->EntryReplaced(pFb, pFbReplacingEntry, pFbEntry); 491 492 /* 2. mark the replaced entry is destroyed */ 493 Assert(pFbEntry->Flags.fCreateNotified); 494 pFbEntry->Flags.fCreateNotified = 0; 495 pFbReplacingEntry->Flags.fCreateNotified = 1; 496 } 497 else 498 { 499 if (pFb->pDisplay) 500 pFb->pDisplay->EntryRemoved(pFb, pFbEntry); 501 } 502 503 crFbEntryRelease(pFb, pFbEntry); 504 } 505 506 static CR_FRAMEBUFFER_ENTRY* crFbEntryCreate(CR_FRAMEBUFFER *pFb, CR_TEXDATA* pTex, const RTRECT *pRect, uint32_t fFlags) 507 { 508 CR_FRAMEBUFFER_ENTRY *pEntry = crFbEntryAlloc(); 509 if (!pEntry) 510 { 511 WARN(("crFbEntryAlloc failed!")); 512 return NULL; 513 } 514 515 CrVrScrCompositorEntryInit(&pEntry->Entry, pRect, pTex, crFbEntryReleased); 516 CrVrScrCompositorEntryFlagsSet(&pEntry->Entry, fFlags); 517 pEntry->cRefs = 1; 518 CrHTableCreate(&pEntry->HTable, 0); 519 520 return pEntry; 521 } 522 523 int CrFbEntryCreateForTexData(CR_FRAMEBUFFER *pFb, struct CR_TEXDATA *pTex, uint32_t fFlags, HCR_FRAMEBUFFER_ENTRY *phEntry) 524 { 525 RTRECT Rect; 526 Rect.xLeft = 0; 527 Rect.yTop = 0; 528 Rect.xRight = pTex->Tex.width; 529 Rect.yBottom = pTex->Tex.height; 530 CR_FRAMEBUFFER_ENTRY* pEntry = crFbEntryCreate(pFb, pTex, &Rect, fFlags); 531 if (!pEntry) 532 { 533 WARN(("crFbEntryCreate failed")); 534 return VERR_NO_MEMORY; 535 } 536 537 *phEntry = pEntry; 538 return VINF_SUCCESS; 539 } 540 541 int CrFbEntryTexDataUpdate(CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY pEntry, struct CR_TEXDATA *pTex) 542 { 543 if (!pFb->cUpdating) 544 { 545 WARN(("framebuffer not updating")); 546 return VERR_INVALID_STATE; 547 } 548 549 if (pTex) 550 CrVrScrCompositorEntryTexSet(&pEntry->Entry, pTex); 551 552 if (CrVrScrCompositorEntryIsUsed(&pEntry->Entry)) 553 { 554 if (pFb->pDisplay) 555 pFb->pDisplay->EntryTexChanged(pFb, pEntry); 556 } 557 558 return VINF_SUCCESS; 559 } 560 561 562 int CrFbEntryCreateForTexId(CR_FRAMEBUFFER *pFb, GLuint idTexture, uint32_t fFlags, HCR_FRAMEBUFFER_ENTRY *phEntry) 563 { 564 CR_FBTEX* pFbTex = crFbTexAcquire(idTexture); 565 if (!pFbTex) 566 { 567 WARN(("crFbTexAcquire failed")); 568 return VERR_INVALID_PARAMETER; 569 } 570 571 CR_TEXDATA* pTex = &pFbTex->Tex; 572 int rc = CrFbEntryCreateForTexData(pFb, pTex, fFlags, phEntry); 573 if (!RT_SUCCESS(rc)) 574 { 575 WARN(("CrFbEntryCreateForTexData failed rc %d", rc)); 576 } 577 578 /*always release the tex, the CrFbEntryCreateForTexData will do incref as necessary */ 579 CrTdRelease(pTex); 580 return rc; 581 } 582 583 void CrFbEntryAddRef(CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 584 { 585 ++hEntry->cRefs; 586 } 587 588 void CrFbEntryRelease(CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 589 { 590 crFbEntryRelease(pFb, hEntry); 591 } 592 593 int CrFbRegionsClear(HCR_FRAMEBUFFER hFb) 594 { 595 if (!hFb->cUpdating) 596 { 597 WARN(("framebuffer not updating")); 598 return VERR_INVALID_STATE; 599 } 600 601 bool fChanged = false; 602 CrVrScrCompositorRegionsClear(&hFb->Compositor, &fChanged); 603 if (fChanged) 604 { 605 if (hFb->pDisplay) 606 hFb->pDisplay->RegionsChanged(hFb); 607 } 608 609 return VINF_SUCCESS; 610 } 611 612 int CrFbEntryRegionsAdd(CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, bool fPosRelated) 613 { 614 if (!pFb->cUpdating) 615 { 616 WARN(("framebuffer not updating")); 617 return VERR_INVALID_STATE; 618 } 619 620 uint32_t fChangeFlags = 0; 621 VBOXVR_SCR_COMPOSITOR_ENTRY *pReplacedScrEntry = NULL; 622 VBOXVR_SCR_COMPOSITOR_ENTRY *pNewEntry; 623 bool fEntryWasInList; 624 625 if (hEntry) 626 { 627 crFbEntryAddRef(hEntry); 628 pNewEntry = &hEntry->Entry; 629 fEntryWasInList = CrVrScrCompositorEntryIsUsed(pNewEntry); 630 } 631 else 632 { 633 pNewEntry = NULL; 634 fEntryWasInList = false; 635 } 636 637 int rc = CrVrScrCompositorEntryRegionsAdd(&pFb->Compositor, hEntry ? &hEntry->Entry : NULL, pPos, cRegions, paRegions, fPosRelated, &pReplacedScrEntry, &fChangeFlags); 638 if (RT_SUCCESS(rc)) 639 { 640 if (fChangeFlags & VBOXVR_COMPOSITOR_CF_REGIONS_CHANGED) 641 { 642 if (!fEntryWasInList && pNewEntry) 643 { 644 Assert(CrVrScrCompositorEntryIsUsed(pNewEntry)); 645 if (!hEntry->Flags.fCreateNotified) 646 { 647 hEntry->Flags.fCreateNotified = 1; 648 if (pFb->pDisplay) 649 pFb->pDisplay->EntryCreated(pFb, hEntry); 650 } 651 652 if (pFb->pDisplay) 653 pFb->pDisplay->EntryAdded(pFb, hEntry); 654 } 655 if (pFb->pDisplay) 656 pFb->pDisplay->RegionsChanged(pFb); 657 658 Assert(!pReplacedScrEntry); 659 } 660 else if (fChangeFlags & VBOXVR_COMPOSITOR_CF_ENTRY_REPLACED) 661 { 662 Assert(pReplacedScrEntry); 663 /* we have already processed that in a "release" callback */ 664 Assert(hEntry); 665 } 666 else 667 { 668 Assert(!fChangeFlags); 669 Assert(!pReplacedScrEntry); 670 } 671 } 672 else 673 WARN(("CrVrScrCompositorEntryRegionsAdd failed, rc %d", rc)); 674 675 return rc; 676 } 677 678 int CrFbEntryRegionsSet(CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, bool fPosRelated) 679 { 680 if (!pFb->cUpdating) 681 { 682 WARN(("framebuffer not updating")); 683 return VERR_INVALID_STATE; 684 } 685 686 bool fChanged = 0; 687 VBOXVR_SCR_COMPOSITOR_ENTRY *pReplacedScrEntry = NULL; 688 VBOXVR_SCR_COMPOSITOR_ENTRY *pNewEntry; 689 bool fEntryWasInList; 690 691 if (hEntry) 692 { 693 crFbEntryAddRef(hEntry); 694 pNewEntry = &hEntry->Entry; 695 fEntryWasInList = CrVrScrCompositorEntryIsUsed(pNewEntry); 696 } 697 else 698 { 699 pNewEntry = NULL; 700 fEntryWasInList = false; 701 } 702 703 int rc = CrVrScrCompositorEntryRegionsSet(&pFb->Compositor, pNewEntry, pPos, cRegions, paRegions, fPosRelated, &fChanged); 704 if (RT_SUCCESS(rc)) 705 { 706 if (fChanged) 707 { 708 if (!fEntryWasInList && pNewEntry) 709 { 710 if (CrVrScrCompositorEntryIsUsed(pNewEntry)) 711 { 712 if (!hEntry->Flags.fCreateNotified) 713 { 714 hEntry->Flags.fCreateNotified = 1; 715 716 if (pFb->pDisplay) 717 pFb->pDisplay->EntryCreated(pFb, hEntry); 718 } 719 720 if (pFb->pDisplay) 721 pFb->pDisplay->EntryAdded(pFb, hEntry); 722 } 723 } 724 725 if (pFb->pDisplay) 726 pFb->pDisplay->RegionsChanged(pFb); 727 } 728 } 729 else 730 WARN(("CrVrScrCompositorEntryRegionsSet failed, rc %d", rc)); 731 732 return rc; 733 } 734 735 const struct VBOXVR_SCR_COMPOSITOR_ENTRY* CrFbEntryGetCompositorEntry(HCR_FRAMEBUFFER_ENTRY hEntry) 736 { 737 return &hEntry->Entry; 738 } 739 740 HCR_FRAMEBUFFER_ENTRY CrFbEntryFromCompositorEntry(const struct VBOXVR_SCR_COMPOSITOR_ENTRY* pCEntry) 741 { 742 return RT_FROM_MEMBER(pCEntry, CR_FRAMEBUFFER_ENTRY, Entry); 743 } 744 745 CRHTABLE_HANDLE CrFbDDataAllocSlot(CR_FRAMEBUFFER *pFb) 746 { 747 return CrHTablePut(&pFb->SlotTable, (void*)1); 748 } 749 750 void CrFbDDataReleaseSlot(CR_FRAMEBUFFER *pFb, CRHTABLE_HANDLE hSlot) 751 { 752 CrHTableRemove(&pFb->SlotTable, hSlot); 753 } 754 755 int CrFbDDataEntryPut(HCR_FRAMEBUFFER_ENTRY hEntry, CRHTABLE_HANDLE hSlot, void *pvData) 756 { 757 return CrHTablePutToSlot(&hEntry->HTable, hSlot, pvData); 758 } 759 760 void* CrFbDDataEntryGet(HCR_FRAMEBUFFER_ENTRY hEntry, CRHTABLE_HANDLE hSlot) 761 { 762 return CrHTableGet(&hEntry->HTable, hSlot); 763 } 764 765 class CrFbDisplayBase : public ICrFbDisplay 766 { 767 public: 768 CrFbDisplayBase() : 769 mpContainer(NULL), 770 mpFb(NULL), 771 mcUpdates(0), 772 mhSlot(CRHTABLE_HANDLE_INVALID) 773 {} 774 775 virtual bool isComposite() 776 { 777 return false; 778 } 779 780 class CrFbDisplayComposite* getContainer() 781 { 782 return mpContainer; 783 } 784 785 bool isInList() 786 { 787 return !!mpContainer; 788 } 789 790 bool isUpdating() 791 { 792 return !!mcUpdates; 793 } 794 795 int setFramebuffer(struct CR_FRAMEBUFFER *pFb) 796 { 797 if (mcUpdates) 798 { 799 WARN(("trying to set framebuffer while update is in progress")); 800 return VERR_INVALID_STATE; 801 } 802 803 if (mpFb == pFb) 804 return VINF_SUCCESS; 805 806 int rc = setFramebufferBegin(pFb); 807 if (!RT_SUCCESS(rc)) 808 { 809 WARN(("err")); 810 return rc; 811 } 812 813 if (mpFb) 814 { 815 rc = fbCleanup(); 816 if (!RT_SUCCESS(rc)) 817 { 818 WARN(("err")); 819 setFramebufferEnd(pFb); 820 return rc; 821 } 822 } 823 824 mpFb = pFb; 825 826 if (mpFb) 827 { 828 rc = fbSync(); 829 if (!RT_SUCCESS(rc)) 830 { 831 WARN(("err")); 832 setFramebufferEnd(pFb); 833 return rc; 834 } 835 } 836 837 setFramebufferEnd(pFb); 838 return VINF_SUCCESS; 839 } 840 841 struct CR_FRAMEBUFFER* getFramebuffer() 842 { 843 return mpFb; 844 } 845 846 virtual int UpdateBegin(struct CR_FRAMEBUFFER *pFb) 847 { 848 ++mcUpdates; 849 return VINF_SUCCESS; 850 } 851 852 virtual void UpdateEnd(struct CR_FRAMEBUFFER *pFb) 853 { 854 --mcUpdates; 855 Assert(mcUpdates < UINT32_MAX/2); 856 } 857 858 virtual int EntryCreated(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 859 { 860 if (!mcUpdates) 861 { 862 WARN(("err")); 863 return VERR_INVALID_STATE; 864 } 865 return VINF_SUCCESS; 866 } 867 868 virtual int EntryAdded(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 869 { 870 if (!mcUpdates) 871 { 872 WARN(("err")); 873 return VERR_INVALID_STATE; 874 } 875 return VINF_SUCCESS; 876 } 877 878 virtual int EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry) 879 { 880 if (!mcUpdates) 881 { 882 WARN(("err")); 883 return VERR_INVALID_STATE; 884 } 885 return VINF_SUCCESS; 886 } 887 888 virtual int EntryTexChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 889 { 890 if (!mcUpdates) 891 { 892 WARN(("err")); 893 return VERR_INVALID_STATE; 894 } 895 return VINF_SUCCESS; 896 } 897 898 virtual int EntryRemoved(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 899 { 900 if (!mcUpdates) 901 { 902 WARN(("err")); 903 return VERR_INVALID_STATE; 904 } 905 return VINF_SUCCESS; 906 } 907 908 virtual int EntryDestroyed(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 909 { 910 return VINF_SUCCESS; 911 } 912 913 virtual int EntryPosChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 914 { 915 if (!mcUpdates) 916 { 917 WARN(("err")); 918 return VERR_INVALID_STATE; 919 } 920 return VINF_SUCCESS; 921 } 922 923 virtual int RegionsChanged(struct CR_FRAMEBUFFER *pFb) 924 { 925 if (!mcUpdates) 926 { 927 WARN(("err")); 928 return VERR_INVALID_STATE; 929 } 930 return VINF_SUCCESS; 931 } 932 933 virtual int FramebufferChanged(struct CR_FRAMEBUFFER *pFb) 934 { 935 if (!mcUpdates) 936 { 937 WARN(("err")); 938 return VERR_INVALID_STATE; 939 } 940 return VINF_SUCCESS; 941 } 942 943 virtual ~CrFbDisplayBase(); 944 945 /*@todo: move to protected and switch from RTLISTNODE*/ 946 RTLISTNODE mNode; 947 class CrFbDisplayComposite* mpContainer; 948 protected: 949 int fbSynchAddAllEntries() 950 { 951 VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR Iter; 952 const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry; 953 954 CrVrScrCompositorConstIterInit(CrFbGetCompositor(mpFb), &Iter); 955 956 int rc = VINF_SUCCESS; 957 958 while ((pEntry = CrVrScrCompositorConstIterNext(&Iter)) != NULL) 959 { 960 HCR_FRAMEBUFFER_ENTRY hEntry = CrFbEntryFromCompositorEntry(pEntry); 961 rc = EntryAdded(mpFb, hEntry); 962 if (!RT_SUCCESS(rc)) 963 { 964 WARN(("err")); 965 break; 966 } 967 } 968 969 return rc; 970 } 971 972 int fbCleanupRemoveAllEntries(bool fNotifyDestroy) 973 { 974 VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR Iter; 975 const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry; 976 977 CrVrScrCompositorConstIterInit(CrFbGetCompositor(mpFb), &Iter); 978 979 int rc = VINF_SUCCESS; 980 981 while ((pEntry = CrVrScrCompositorConstIterNext(&Iter)) != NULL) 982 { 983 HCR_FRAMEBUFFER_ENTRY hEntry = CrFbEntryFromCompositorEntry(pEntry); 984 rc = EntryRemoved(mpFb, hEntry); 985 if (!RT_SUCCESS(rc)) 986 { 987 WARN(("err")); 988 break; 989 } 990 991 if (fNotifyDestroy) 992 { 993 rc = EntryDestroyed(mpFb, hEntry); 994 if (!RT_SUCCESS(rc)) 995 { 996 WARN(("err")); 997 break; 998 } 999 } 1000 } 1001 1002 return rc; 1003 } 1004 1005 virtual int setFramebufferBegin(struct CR_FRAMEBUFFER *pFb) 1006 { 1007 return UpdateBegin(pFb); 1008 } 1009 virtual void setFramebufferEnd(struct CR_FRAMEBUFFER *pFb) 1010 { 1011 UpdateEnd(pFb); 1012 } 1013 1014 virtual int fbCleanup() 1015 { 1016 if (mhSlot) 1017 { 1018 CrFbDDataReleaseSlot(mpFb, mhSlot); 1019 mhSlot = 0; 1020 } 1021 mpFb = NULL; 1022 return VINF_SUCCESS; 1023 } 1024 1025 virtual int fbSync() 1026 { 1027 return VINF_SUCCESS; 1028 } 1029 1030 CRHTABLE_HANDLE slotGet() 1031 { 1032 if (!mhSlot) 1033 { 1034 if (mpFb) 1035 mhSlot = CrFbDDataAllocSlot(mpFb); 1036 } 1037 1038 return mhSlot; 1039 } 1040 1041 private: 1042 struct CR_FRAMEBUFFER *mpFb; 1043 uint32_t mcUpdates; 1044 CRHTABLE_HANDLE mhSlot; 1045 }; 1046 1047 class CrFbDisplayComposite : public CrFbDisplayBase 1048 { 1049 public: 1050 CrFbDisplayComposite() : 1051 mcDisplays(0) 1052 { 1053 RTListInit(&mDisplays); 1054 } 1055 1056 virtual bool isComposite() 1057 { 1058 return true; 1059 } 1060 1061 uint32_t getDisplayCount() 1062 { 1063 return mcDisplays; 1064 } 1065 1066 bool add(CrFbDisplayBase *pDisplay) 1067 { 1068 if (pDisplay->isInList()) 1069 { 1070 WARN(("entry in list already")); 1071 return false; 1072 } 1073 1074 RTListAppend(&mDisplays, &pDisplay->mNode); 1075 pDisplay->mpContainer = this; 1076 pDisplay->setFramebuffer(getFramebuffer()); 1077 ++mcDisplays; 1078 return true; 1079 } 1080 1081 bool remove(CrFbDisplayBase *pDisplay, bool fCleanupDisplay = true) 1082 { 1083 if (pDisplay->getContainer() != this) 1084 { 1085 WARN(("invalid entry container")); 1086 return false; 1087 } 1088 1089 RTListNodeRemove(&pDisplay->mNode); 1090 pDisplay->mpContainer = NULL; 1091 if (fCleanupDisplay) 1092 pDisplay->setFramebuffer(NULL); 1093 --mcDisplays; 1094 return true; 1095 } 1096 1097 CrFbDisplayBase* first() 1098 { 1099 return RTListGetFirstCpp(&mDisplays, CrFbDisplayBase, mNode); 1100 } 1101 1102 CrFbDisplayBase* next(CrFbDisplayBase* pDisplay) 1103 { 1104 if (pDisplay->getContainer() != this) 1105 { 1106 WARN(("invalid entry container")); 1107 return NULL; 1108 } 1109 1110 return RTListGetNextCpp(&mDisplays, pDisplay, CrFbDisplayBase, mNode); 1111 } 1112 1113 virtual int setFramebuffer(struct CR_FRAMEBUFFER *pFb) 1114 { 1115 CrFbDisplayBase::setFramebuffer(pFb); 1116 1117 CrFbDisplayBase *pIter; 1118 RTListForEachCpp(&mDisplays, pIter, CrFbDisplayBase, mNode) 1119 { 1120 pIter->setFramebuffer(pFb); 1121 } 1122 1123 return VINF_SUCCESS; 1124 } 1125 1126 virtual int UpdateBegin(struct CR_FRAMEBUFFER *pFb) 1127 { 1128 int rc = CrFbDisplayBase::UpdateBegin(pFb); 1129 if (!RT_SUCCESS(rc)) 1130 { 1131 WARN(("err")); 1132 return rc; 1133 } 1134 1135 CrFbDisplayBase *pIter; 1136 RTListForEachCpp(&mDisplays, pIter, CrFbDisplayBase, mNode) 1137 { 1138 rc = pIter->UpdateBegin(pFb); 1139 if (!RT_SUCCESS(rc)) 1140 { 1141 WARN(("err")); 1142 return rc; 1143 } 1144 } 1145 return VINF_SUCCESS; 1146 } 1147 1148 virtual void UpdateEnd(struct CR_FRAMEBUFFER *pFb) 1149 { 1150 CrFbDisplayBase *pIter; 1151 RTListForEachCpp(&mDisplays, pIter, CrFbDisplayBase, mNode) 1152 { 1153 pIter->UpdateEnd(pFb); 1154 } 1155 1156 CrFbDisplayBase::UpdateEnd(pFb); 1157 } 1158 1159 virtual int EntryAdded(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 1160 { 1161 int rc = CrFbDisplayBase::EntryAdded(pFb, hEntry); 1162 if (!RT_SUCCESS(rc)) 1163 { 1164 WARN(("err")); 1165 return rc; 1166 } 1167 1168 CrFbDisplayBase *pIter; 1169 RTListForEachCpp(&mDisplays, pIter, CrFbDisplayBase, mNode) 1170 { 1171 int rc = pIter->EntryAdded(pFb, hEntry); 1172 if (!RT_SUCCESS(rc)) 1173 { 1174 WARN(("err")); 1175 return rc; 1176 } 1177 } 1178 return VINF_SUCCESS; 1179 } 1180 1181 virtual int EntryCreated(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 1182 { 1183 int rc = CrFbDisplayBase::EntryAdded(pFb, hEntry); 1184 if (!RT_SUCCESS(rc)) 1185 { 1186 WARN(("err")); 1187 return rc; 1188 } 1189 1190 CrFbDisplayBase *pIter; 1191 RTListForEachCpp(&mDisplays, pIter, CrFbDisplayBase, mNode) 1192 { 1193 int rc = pIter->EntryCreated(pFb, hEntry); 1194 if (!RT_SUCCESS(rc)) 1195 { 1196 WARN(("err")); 1197 return rc; 1198 } 1199 } 1200 return VINF_SUCCESS; 1201 } 1202 1203 virtual int EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry) 1204 { 1205 int rc = CrFbDisplayBase::EntryReplaced(pFb, hNewEntry, hReplacedEntry); 1206 if (!RT_SUCCESS(rc)) 1207 { 1208 WARN(("err")); 1209 return rc; 1210 } 1211 1212 CrFbDisplayBase *pIter; 1213 RTListForEachCpp(&mDisplays, pIter, CrFbDisplayBase, mNode) 1214 { 1215 int rc = pIter->EntryReplaced(pFb, hNewEntry, hReplacedEntry); 1216 if (!RT_SUCCESS(rc)) 1217 { 1218 WARN(("err")); 1219 return rc; 1220 } 1221 } 1222 return VINF_SUCCESS; 1223 } 1224 1225 virtual int EntryTexChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 1226 { 1227 int rc = CrFbDisplayBase::EntryTexChanged(pFb, hEntry); 1228 if (!RT_SUCCESS(rc)) 1229 { 1230 WARN(("err")); 1231 return rc; 1232 } 1233 1234 CrFbDisplayBase *pIter; 1235 RTListForEachCpp(&mDisplays, pIter, CrFbDisplayBase, mNode) 1236 { 1237 int rc = pIter->EntryTexChanged(pFb, hEntry); 1238 if (!RT_SUCCESS(rc)) 1239 { 1240 WARN(("err")); 1241 return rc; 1242 } 1243 } 1244 return VINF_SUCCESS; 1245 } 1246 1247 virtual int EntryRemoved(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 1248 { 1249 int rc = CrFbDisplayBase::EntryRemoved(pFb, hEntry); 1250 if (!RT_SUCCESS(rc)) 1251 { 1252 WARN(("err")); 1253 return rc; 1254 } 1255 1256 CrFbDisplayBase *pIter; 1257 RTListForEachCpp(&mDisplays, pIter, CrFbDisplayBase, mNode) 1258 { 1259 int rc = pIter->EntryRemoved(pFb, hEntry); 1260 if (!RT_SUCCESS(rc)) 1261 { 1262 WARN(("err")); 1263 return rc; 1264 } 1265 } 1266 return VINF_SUCCESS; 1267 } 1268 1269 virtual int EntryDestroyed(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 1270 { 1271 int rc = CrFbDisplayBase::EntryDestroyed(pFb, hEntry); 1272 if (!RT_SUCCESS(rc)) 1273 { 1274 WARN(("err")); 1275 return rc; 1276 } 1277 1278 CrFbDisplayBase *pIter; 1279 RTListForEachCpp(&mDisplays, pIter, CrFbDisplayBase, mNode) 1280 { 1281 int rc = pIter->EntryDestroyed(pFb, hEntry); 1282 if (!RT_SUCCESS(rc)) 1283 { 1284 WARN(("err")); 1285 return rc; 1286 } 1287 } 1288 return VINF_SUCCESS; 1289 } 1290 1291 virtual int RegionsChanged(struct CR_FRAMEBUFFER *pFb) 1292 { 1293 int rc = CrFbDisplayBase::RegionsChanged(pFb); 1294 if (!RT_SUCCESS(rc)) 1295 { 1296 WARN(("err")); 1297 return rc; 1298 } 1299 1300 CrFbDisplayBase *pIter; 1301 RTListForEachCpp(&mDisplays, pIter, CrFbDisplayBase, mNode) 1302 { 1303 int rc = pIter->RegionsChanged(pFb); 1304 if (!RT_SUCCESS(rc)) 1305 { 1306 WARN(("err")); 1307 return rc; 1308 } 1309 } 1310 return VINF_SUCCESS; 1311 } 1312 1313 virtual int FramebufferChanged(struct CR_FRAMEBUFFER *pFb) 1314 { 1315 int rc = CrFbDisplayBase::FramebufferChanged(pFb); 1316 if (!RT_SUCCESS(rc)) 1317 { 1318 WARN(("err")); 1319 return rc; 1320 } 1321 1322 CrFbDisplayBase *pIter; 1323 RTListForEachCpp(&mDisplays, pIter, CrFbDisplayBase, mNode) 1324 { 1325 int rc = pIter->FramebufferChanged(pFb); 1326 if (!RT_SUCCESS(rc)) 1327 { 1328 WARN(("err")); 1329 return rc; 1330 } 1331 } 1332 return VINF_SUCCESS; 1333 } 1334 1335 virtual ~CrFbDisplayComposite() 1336 { 1337 cleanup(); 1338 } 1339 1340 void cleanup(bool fCleanupDisplays = true) 1341 { 1342 CrFbDisplayBase *pIter, *pIterNext; 1343 RTListForEachSafeCpp(&mDisplays, pIter, pIterNext, CrFbDisplayBase, mNode) 1344 { 1345 remove(pIter, fCleanupDisplays); 1346 } 1347 } 1348 private: 1349 RTLISTNODE mDisplays; 1350 uint32_t mcDisplays; 1351 }; 1352 1353 typedef union CR_FBWIN_FLAGS 1354 { 1355 struct { 1356 uint32_t fVisible : 1; 1357 uint32_t fDataPresented : 1; 1358 uint32_t fForcePresentOnReenable : 1; 1359 uint32_t fCompositoEntriesModified : 1; 1360 uint32_t Reserved : 28; 1361 }; 1362 uint32_t Value; 1363 } CR_FBWIN_FLAGS; 1364 1365 class CrFbWindow 1366 { 1367 public: 1368 CrFbWindow(uint64_t parentId) : 1369 mSpuWindow(0), 1370 mpCompositor(NULL), 1371 mcUpdates(0), 1372 mxPos(0), 1373 myPos(0), 1374 mWidth(0), 1375 mHeight(0), 1376 mParentId(parentId) 1377 { 1378 mFlags.Value = 0; 1379 } 1380 1381 bool IsCreated() 1382 { 1383 return !!mSpuWindow; 1384 } 1385 1386 void Destroy() 1387 { 1388 CRASSERT(!mcUpdates); 1389 1390 if (!mSpuWindow) 1391 return; 1392 1393 cr_server.head_spu->dispatch_table.WindowDestroy(mSpuWindow); 1394 1395 mSpuWindow = 0; 1396 mFlags.fDataPresented = 0; 1397 } 1398 1399 int Reparent(uint64_t parentId) 1400 { 1401 if (!checkInitedUpdating()) 1402 { 1403 WARN(("err")); 1404 return VERR_INVALID_STATE; 1405 } 1406 1407 mParentId = parentId; 1408 1409 if (!parentId) 1410 cr_server.head_spu->dispatch_table.WindowShow(mSpuWindow, false); 1411 1412 if (mSpuWindow) 1413 { 1414 renderspuSetWindowId(mParentId); 1415 renderspuReparentWindow(mSpuWindow); 1416 renderspuSetWindowId(cr_server.screen[0].winID); 1417 } 1418 1419 return VINF_SUCCESS; 1420 } 1421 1422 int SetVisible(bool fVisible) 1423 { 1424 if (!checkInitedUpdating()) 1425 { 1426 WARN(("err")); 1427 return VERR_INVALID_STATE; 1428 } 1429 1430 LOG(("CrWIN: Vidible [%d]", fVisible)); 1431 1432 if (!fVisible != !mFlags.fVisible) 1433 { 1434 mFlags.fVisible = fVisible; 1435 if (mSpuWindow && mParentId) 1436 cr_server.head_spu->dispatch_table.WindowShow(mSpuWindow, fVisible); 1437 } 1438 1439 return VINF_SUCCESS; 1440 } 1441 1442 int SetSize(uint32_t width, uint32_t height) 1443 { 1444 if (!checkInitedUpdating()) 1445 { 1446 WARN(("err")); 1447 return VERR_INVALID_STATE; 1448 } 1449 1450 LOG(("CrWIN: Size [%d ; %d]", width, height)); 1451 1452 if (mWidth != width || mHeight != height) 1453 { 1454 mFlags.fCompositoEntriesModified = 1; 1455 mWidth = width; 1456 mHeight = height; 1457 if (mSpuWindow) 1458 cr_server.head_spu->dispatch_table.WindowSize(mSpuWindow, width, height); 1459 } 1460 1461 return VINF_SUCCESS; 1462 } 1463 1464 int SetPosition(int32_t x, int32_t y) 1465 { 1466 if (!checkInitedUpdating()) 1467 { 1468 WARN(("err")); 1469 return VERR_INVALID_STATE; 1470 } 1471 1472 LOG(("CrWIN: Pos [%d ; %d]", x, y)); 1473 1474 if (x != mxPos || y != myPos) 1475 { 1476 mxPos = x; 1477 myPos = y; 1478 if (mSpuWindow) 1479 cr_server.head_spu->dispatch_table.WindowPosition(mSpuWindow, x, y); 1480 } 1481 1482 return VINF_SUCCESS; 1483 } 1484 1485 int SetVisibleRegionsChanged() 1486 { 1487 if (!checkInitedUpdating()) 1488 { 1489 WARN(("err")); 1490 return VERR_INVALID_STATE; 1491 } 1492 1493 mFlags.fCompositoEntriesModified = 1; 1494 return VINF_SUCCESS; 1495 } 1496 1497 int SetCompositor(const struct VBOXVR_SCR_COMPOSITOR * pCompositor) 1498 { 1499 if (!checkInitedUpdating()) 1500 { 1501 WARN(("err")); 1502 return VERR_INVALID_STATE; 1503 } 1504 1505 mpCompositor = pCompositor; 1506 mFlags.fCompositoEntriesModified = 1; 1507 return VINF_SUCCESS; 1508 } 1509 1510 int UpdateBegin() 1511 { 1512 ++mcUpdates; 1513 if (mcUpdates > 1) 1514 return VINF_SUCCESS; 1515 1516 Assert(!mFlags.fForcePresentOnReenable); 1517 // Assert(!mFlags.fCompositoEntriesModified); 1518 1519 if (mFlags.fDataPresented) 1520 { 1521 Assert(mSpuWindow); 1522 cr_server.head_spu->dispatch_table.VBoxPresentComposition(mSpuWindow, NULL, NULL); 1523 mFlags.fForcePresentOnReenable = isPresentNeeded(); 1524 } 1525 1526 return VINF_SUCCESS; 1527 } 1528 1529 void UpdateEnd() 1530 { 1531 --mcUpdates; 1532 Assert(mcUpdates < UINT32_MAX/2); 1533 if (mcUpdates) 1534 return; 1535 1536 checkRegions(); 1537 1538 if (mSpuWindow) 1539 { 1540 bool fPresentNeeded = isPresentNeeded(); 1541 if (fPresentNeeded || mFlags.fForcePresentOnReenable) 1542 { 1543 mFlags.fForcePresentOnReenable = false; 1544 cr_server.head_spu->dispatch_table.VBoxPresentComposition(mSpuWindow, mpCompositor, NULL); 1545 } 1546 1547 /* even if the above branch is entered due to mFlags.fForcePresentOnReenable, 1548 * the backend should clean up the compositor as soon as presentation is performed */ 1549 mFlags.fDataPresented = fPresentNeeded; 1550 } 1551 else 1552 { 1553 Assert(!mFlags.fDataPresented); 1554 Assert(!mFlags.fForcePresentOnReenable); 1555 } 1556 } 1557 1558 uint64_t GetParentId() 1559 { 1560 return mParentId; 1561 } 1562 1563 int Create() 1564 { 1565 if (mSpuWindow) 1566 { 1567 //WARN(("window already created")); 1568 return VINF_ALREADY_INITIALIZED; 1569 } 1570 1571 CRASSERT(cr_server.fVisualBitsDefault); 1572 renderspuSetWindowId(mParentId); 1573 mSpuWindow = cr_server.head_spu->dispatch_table.WindowCreate("", cr_server.fVisualBitsDefault); 1574 renderspuSetWindowId(cr_server.screen[0].winID); 1575 if (mSpuWindow < 0) { 1576 WARN(("WindowCreate failed")); 1577 return VERR_GENERAL_FAILURE; 1578 } 1579 1580 cr_server.head_spu->dispatch_table.WindowSize(mSpuWindow, mWidth, mHeight); 1581 cr_server.head_spu->dispatch_table.WindowPosition(mSpuWindow, mxPos, myPos); 1582 1583 checkRegions(); 1584 1585 if (mParentId && mFlags.fVisible) 1586 cr_server.head_spu->dispatch_table.WindowShow(mSpuWindow, true); 1587 1588 return VINF_SUCCESS; 1589 } 1590 1591 ~CrFbWindow() 1592 { 1593 Destroy(); 1594 } 1595 protected: 1596 void checkRegions() 1597 { 1598 if (!mSpuWindow) 1599 return; 1600 1601 if (!mFlags.fCompositoEntriesModified) 1602 return; 1603 1604 uint32_t cRects; 1605 const RTRECT *pRects; 1606 if (mpCompositor) 1607 { 1608 int rc = CrVrScrCompositorRegionsGet(mpCompositor, &cRects, NULL, &pRects, NULL); 1609 if (!RT_SUCCESS(rc)) 1610 { 1611 WARN(("CrVrScrCompositorRegionsGet failed rc %d", rc)); 1612 cRects = 0; 1613 pRects = NULL; 1614 } 1615 } 1616 else 1617 { 1618 cRects = 0; 1619 pRects = NULL; 1620 } 1621 1622 cr_server.head_spu->dispatch_table.WindowVisibleRegion(mSpuWindow, cRects, (const GLint*)pRects); 1623 1624 mFlags.fCompositoEntriesModified = 0; 1625 } 1626 1627 bool isPresentNeeded() 1628 { 1629 return mFlags.fVisible && mWidth && mHeight && mpCompositor && !CrVrScrCompositorIsEmpty(mpCompositor); 1630 } 1631 1632 bool checkInitedUpdating() 1633 { 1634 if (!mcUpdates) 1635 { 1636 WARN(("not updating")); 1637 return false; 1638 } 1639 1640 return true; 1641 } 1642 private: 1643 GLint mSpuWindow; 1644 const struct VBOXVR_SCR_COMPOSITOR * mpCompositor; 1645 uint32_t mcUpdates; 1646 int32_t mxPos; 1647 int32_t myPos; 1648 uint32_t mWidth; 1649 uint32_t mHeight; 1650 CR_FBWIN_FLAGS mFlags; 1651 uint64_t mParentId; 1652 }; 1653 1654 class CrFbDisplayWindow : public CrFbDisplayBase 1655 { 1656 public: 1657 CrFbDisplayWindow(CrFbWindow *pWindow, const RTRECT *pViewportRect) : 1658 mpWindow(pWindow), 1659 mViewportRect(*pViewportRect) 1660 { 1661 CRASSERT(pWindow); 1662 } 1663 1664 virtual ~CrFbDisplayWindow() 1665 { 1666 if (mpWindow) 1667 delete mpWindow; 1668 } 1669 1670 virtual int UpdateBegin(struct CR_FRAMEBUFFER *pFb) 1671 { 1672 int rc = CrFbDisplayBase::UpdateBegin(pFb); 1673 if (!RT_SUCCESS(rc)) 1674 { 1675 WARN(("err")); 1676 return rc; 1677 } 1678 1679 return mpWindow->UpdateBegin(); 1680 } 1681 1682 virtual void UpdateEnd(struct CR_FRAMEBUFFER *pFb) 1683 { 1684 mpWindow->UpdateEnd(); 1685 1686 CrFbDisplayBase::UpdateEnd(pFb); 1687 } 1688 1689 virtual int EntryCreated(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 1690 { 1691 int rc = CrFbDisplayBase::EntryCreated(pFb, hEntry); 1692 if (!RT_SUCCESS(rc)) 1693 { 1694 WARN(("err")); 1695 return rc; 1696 } 1697 1698 if (mpWindow->GetParentId()) 1699 { 1700 rc = mpWindow->Create(); 1701 if (!RT_SUCCESS(rc)) 1702 { 1703 WARN(("err")); 1704 return rc; 1705 } 1706 } 1707 1708 return VINF_SUCCESS; 1709 } 1710 1711 virtual int EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry) 1712 { 1713 int rc = CrFbDisplayBase::EntryReplaced(pFb, hNewEntry, hReplacedEntry); 1714 if (!RT_SUCCESS(rc)) 1715 { 1716 WARN(("err")); 1717 return rc; 1718 } 1719 1720 if (mpWindow->GetParentId()) 1721 { 1722 rc = mpWindow->Create(); 1723 if (!RT_SUCCESS(rc)) 1724 { 1725 WARN(("err")); 1726 return rc; 1727 } 1728 } 1729 1730 return VINF_SUCCESS; 1731 } 1732 1733 virtual int EntryTexChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 1734 { 1735 int rc = CrFbDisplayBase::EntryTexChanged(pFb, hEntry); 1736 if (!RT_SUCCESS(rc)) 1737 { 1738 WARN(("err")); 1739 return rc; 1740 } 1741 1742 if (mpWindow->GetParentId()) 1743 { 1744 rc = mpWindow->Create(); 1745 if (!RT_SUCCESS(rc)) 1746 { 1747 WARN(("err")); 1748 return rc; 1749 } 1750 } 1751 1752 return VINF_SUCCESS; 1753 } 1754 1755 virtual int EntryRemoved(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 1756 { 1757 int rc = CrFbDisplayBase::EntryRemoved(pFb, hEntry); 1758 if (!RT_SUCCESS(rc)) 1759 { 1760 WARN(("err")); 1761 return rc; 1762 } 1763 1764 return mpWindow->SetVisibleRegionsChanged(); 1765 } 1766 1767 virtual int EntryPosChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 1768 { 1769 int rc = CrFbDisplayBase::EntryPosChanged(pFb, hEntry); 1770 if (!RT_SUCCESS(rc)) 1771 { 1772 WARN(("err")); 1773 return rc; 1774 } 1775 1776 return mpWindow->SetVisibleRegionsChanged(); 1777 } 1778 1779 virtual int RegionsChanged(struct CR_FRAMEBUFFER *pFb) 1780 { 1781 int rc = CrFbDisplayBase::RegionsChanged(pFb); 1782 if (!RT_SUCCESS(rc)) 1783 { 1784 WARN(("err")); 1785 return rc; 1786 } 1787 1788 return mpWindow->SetVisibleRegionsChanged(); 1789 } 1790 1791 virtual int FramebufferChanged(struct CR_FRAMEBUFFER *pFb) 1792 { 1793 int rc = CrFbDisplayBase::FramebufferChanged(pFb); 1794 if (!RT_SUCCESS(rc)) 1795 { 1796 WARN(("err")); 1797 return rc; 1798 } 1799 1800 return screenChanged(); 1801 } 1802 1803 virtual int setViewportRect(const RTRECT *pViewportRect) 1804 { 1805 if (!isUpdating()) 1806 { 1807 WARN(("not updating!")); 1808 return VERR_INVALID_STATE; 1809 } 1810 1811 if (pViewportRect->xLeft != mViewportRect.xLeft || pViewportRect->yTop != mViewportRect.yTop) 1812 { 1813 const RTRECT* pRect = CrVrScrCompositorRectGet(getCompositor()); 1814 int rc = mpWindow->SetPosition(pRect->xLeft - mViewportRect.xLeft, pRect->yTop - mViewportRect.yTop); 1815 if (!RT_SUCCESS(rc)) 1816 { 1817 WARN(("SetPosition failed")); 1818 return rc; 1819 } 1820 } 1821 1822 mViewportRect = *pViewportRect; 1823 1824 return VINF_SUCCESS; 1825 } 1826 1827 virtual CrFbWindow * windowDetach() 1828 { 1829 if (isUpdating()) 1830 { 1831 WARN(("updating!")); 1832 return NULL; 1833 } 1834 1835 CrFbWindow * pWindow = mpWindow; 1836 if (mpWindow) 1837 { 1838 windowCleanup(); 1839 mpWindow = NULL; 1840 } 1841 return pWindow; 1842 } 1843 1844 virtual CrFbWindow * windowAttach(CrFbWindow * pNewWindow) 1845 { 1846 if (isUpdating()) 1847 { 1848 WARN(("updating!")); 1849 return NULL; 1850 } 1851 1852 CrFbWindow * pOld = mpWindow; 1853 if (mpWindow) 1854 windowDetach(); 1855 1856 mpWindow = pNewWindow; 1857 if (pNewWindow) 1858 windowSync(); 1859 1860 return mpWindow; 1861 } 1862 1863 virtual int reparent(uint64_t parentId) 1864 { 1865 if (!isUpdating()) 1866 { 1867 WARN(("not updating!")); 1868 return VERR_INVALID_STATE; 1869 } 1870 1871 int rc = mpWindow->Reparent(parentId); 1872 if (!RT_SUCCESS(rc)) 1873 WARN(("window reparent failed")); 1874 1875 return rc; 1876 } 1877 1878 protected: 1879 virtual int screenChanged() 1880 { 1881 if (!isUpdating()) 1882 { 1883 WARN(("not updating!")); 1884 return VERR_INVALID_STATE; 1885 } 1886 1887 const RTRECT* pRect = CrVrScrCompositorRectGet(getCompositor()); 1888 int rc = mpWindow->SetPosition(pRect->xLeft - mViewportRect.xLeft, pRect->yTop - mViewportRect.yTop); 1889 if (!RT_SUCCESS(rc)) 1890 { 1891 WARN(("SetComposition failed rc %d", rc)); 1892 return rc; 1893 } 1894 1895 mpWindow->SetVisibleRegionsChanged(); 1896 1897 return mpWindow->SetSize((uint32_t)(pRect->xRight - pRect->xLeft), (uint32_t)(pRect->yBottom - pRect->yTop)); 1898 } 1899 1900 virtual int windowCleanup() 1901 { 1902 int rc = mpWindow->UpdateBegin(); 1903 if (!RT_SUCCESS(rc)) 1904 { 1905 WARN(("err")); 1906 return rc; 1907 } 1908 1909 rc = mpWindow->SetVisible(false); 1910 if (!RT_SUCCESS(rc)) 1911 { 1912 WARN(("err")); 1913 mpWindow->UpdateEnd(); 1914 return rc; 1915 } 1916 1917 rc = mpWindow->SetCompositor(NULL); 1918 if (!RT_SUCCESS(rc)) 1919 { 1920 WARN(("err")); 1921 mpWindow->UpdateEnd(); 1922 return rc; 1923 } 1924 1925 mpWindow->UpdateEnd(); 1926 1927 return VINF_SUCCESS; 1928 } 1929 1930 virtual int fbCleanup() 1931 { 1932 int rc = windowCleanup(); 1933 if (!RT_SUCCESS(rc)) 1934 { 1935 WARN(("windowCleanup failed")); 1936 return rc; 1937 } 1938 return CrFbDisplayBase::fbCleanup(); 1939 } 1940 1941 virtual int windowSync() 1942 { 1943 const struct VBOXVR_SCR_COMPOSITOR* pCompositor = getCompositor(); 1944 const RTRECT* pRect = CrVrScrCompositorRectGet(pCompositor); 1945 1946 int rc = mpWindow->UpdateBegin(); 1947 if (!RT_SUCCESS(rc)) 1948 { 1949 WARN(("err")); 1950 return rc; 1951 } 1952 1953 rc = mpWindow->SetCompositor(pCompositor); 1954 if (!RT_SUCCESS(rc)) 1955 { 1956 WARN(("err")); 1957 mpWindow->UpdateEnd(); 1958 return rc; 1959 } 1960 1961 rc = mpWindow->SetPosition(pRect->xLeft - mViewportRect.xLeft, pRect->yTop - mViewportRect.yTop); 1962 if (!RT_SUCCESS(rc)) 1963 { 1964 WARN(("err")); 1965 mpWindow->UpdateEnd(); 1966 return rc; 1967 } 1968 1969 rc = mpWindow->SetSize((uint32_t)(pRect->xRight - pRect->xLeft), (uint32_t)(pRect->yBottom - pRect->yTop)); 1970 if (!RT_SUCCESS(rc)) 1971 { 1972 WARN(("err")); 1973 mpWindow->UpdateEnd(); 1974 return rc; 1975 } 1976 1977 rc = mpWindow->SetVisible(true); 1978 if (!RT_SUCCESS(rc)) 1979 { 1980 WARN(("err")); 1981 mpWindow->UpdateEnd(); 1982 return rc; 1983 } 1984 1985 mpWindow->UpdateEnd(); 1986 1987 return rc; 1988 } 1989 1990 virtual int fbSync() 1991 { 1992 int rc = CrFbDisplayBase::fbSync(); 1993 if (!RT_SUCCESS(rc)) 1994 { 1995 WARN(("err")); 1996 return rc; 1997 } 1998 1999 return windowSync(); 2000 } 2001 2002 virtual const struct VBOXVR_SCR_COMPOSITOR* getCompositor() 2003 { 2004 return CrFbGetCompositor(getFramebuffer()); 2005 } 2006 2007 CrFbWindow* getWindow() {return mpWindow;} 2008 private: 2009 CrFbWindow *mpWindow; 2010 RTRECT mViewportRect; 2011 }; 2012 2013 class CrFbDisplayWindowRootVr : public CrFbDisplayWindow 2014 { 2015 public: 2016 CrFbDisplayWindowRootVr(CrFbWindow *pWindow, const RTRECT *pViewportRect) : 2017 CrFbDisplayWindow(pWindow, pViewportRect) 2018 { 2019 CrVrScrCompositorInit(&mCompositor, NULL); 2020 memset(&mPos, 0, sizeof (mPos)); 2021 } 2022 2023 virtual int EntryCreated(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2024 { 2025 int rc = CrFbDisplayWindow::EntryCreated(pFb, hEntry); 2026 if (!RT_SUCCESS(rc)) 2027 { 2028 WARN(("err")); 2029 return rc; 2030 } 2031 2032 Assert(!CrFbDDataEntryGet(hEntry, slotGet())); 2033 2034 const VBOXVR_SCR_COMPOSITOR_ENTRY* pSrcEntry = CrFbEntryGetCompositorEntry(hEntry); 2035 VBOXVR_SCR_COMPOSITOR_ENTRY *pMyEntry = entryAlloc(); 2036 CrVrScrCompositorEntryInit(pMyEntry, CrVrScrCompositorEntryRectGet(pSrcEntry), CrVrScrCompositorEntryTexGet(pSrcEntry), NULL); 2037 CrVrScrCompositorEntryFlagsSet(pMyEntry, CrVrScrCompositorEntryFlagsGet(pSrcEntry)); 2038 rc = CrFbDDataEntryPut(hEntry, slotGet(), pMyEntry); 2039 if (!RT_SUCCESS(rc)) 2040 { 2041 WARN(("CrFbDDataEntryPut failed rc %d", rc)); 2042 entryFree(pMyEntry); 2043 return rc; 2044 } 2045 2046 return VINF_SUCCESS; 2047 } 2048 2049 virtual int EntryAdded(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2050 { 2051 int rc = CrFbDisplayWindow::EntryAdded(pFb, hEntry); 2052 if (!RT_SUCCESS(rc)) 2053 { 2054 WARN(("err")); 2055 return rc; 2056 } 2057 2058 const VBOXVR_SCR_COMPOSITOR_ENTRY* pSrcEntry = CrFbEntryGetCompositorEntry(hEntry); 2059 VBOXVR_SCR_COMPOSITOR_ENTRY *pMyEntry = (VBOXVR_SCR_COMPOSITOR_ENTRY*)CrFbDDataEntryGet(hEntry, slotGet()); 2060 Assert(pMyEntry); 2061 CrVrScrCompositorEntryTexSet(pMyEntry, CrVrScrCompositorEntryTexGet(pSrcEntry)); 2062 2063 return VINF_SUCCESS; 2064 } 2065 2066 virtual int EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry) 2067 { 2068 int rc = CrFbDisplayWindow::EntryReplaced(pFb, hNewEntry, hReplacedEntry); 2069 if (!RT_SUCCESS(rc)) 2070 { 2071 WARN(("err")); 2072 return rc; 2073 } 2074 2075 const VBOXVR_SCR_COMPOSITOR_ENTRY* pSrcNewEntry = CrFbEntryGetCompositorEntry(hNewEntry); 2076 VBOXVR_SCR_COMPOSITOR_ENTRY *pMyEntry = (VBOXVR_SCR_COMPOSITOR_ENTRY*)CrFbDDataEntryGet(hNewEntry, slotGet()); 2077 CrVrScrCompositorEntryTexSet(pMyEntry, CrVrScrCompositorEntryTexGet(pSrcNewEntry)); 2078 2079 return VINF_SUCCESS; 2080 } 2081 2082 virtual int EntryTexChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2083 { 2084 int rc = CrFbDisplayWindow::EntryTexChanged(pFb, hEntry); 2085 if (!RT_SUCCESS(rc)) 2086 { 2087 WARN(("err")); 2088 return rc; 2089 } 2090 2091 const VBOXVR_SCR_COMPOSITOR_ENTRY* pSrcEntry = CrFbEntryGetCompositorEntry(hEntry); 2092 VBOXVR_SCR_COMPOSITOR_ENTRY *pMyEntry = (VBOXVR_SCR_COMPOSITOR_ENTRY*)CrFbDDataEntryGet(hEntry, slotGet()); 2093 CrVrScrCompositorEntryTexSet(pMyEntry, CrVrScrCompositorEntryTexGet(pSrcEntry)); 2094 2095 return VINF_SUCCESS; 2096 } 2097 2098 virtual int EntryRemoved(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2099 { 2100 int rc = CrFbDisplayWindow::EntryRemoved(pFb, hEntry); 2101 if (!RT_SUCCESS(rc)) 2102 { 2103 WARN(("err")); 2104 return rc; 2105 } 2106 2107 return VINF_SUCCESS; 2108 } 2109 2110 virtual int EntryDestroyed(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2111 { 2112 int rc = CrFbDisplayWindow::EntryDestroyed(pFb, hEntry); 2113 if (!RT_SUCCESS(rc)) 2114 { 2115 WARN(("err")); 2116 return rc; 2117 } 2118 2119 const VBOXVR_SCR_COMPOSITOR_ENTRY* pSrcEntry = CrFbEntryGetCompositorEntry(hEntry); 2120 VBOXVR_SCR_COMPOSITOR_ENTRY *pMyEntry = (VBOXVR_SCR_COMPOSITOR_ENTRY*)CrFbDDataEntryGet(hEntry, slotGet()); 2121 CrVrScrCompositorEntryCleanup(pMyEntry); 2122 entryFree(pMyEntry); 2123 2124 return VINF_SUCCESS; 2125 } 2126 2127 virtual int RegionsChanged(struct CR_FRAMEBUFFER *pFb) 2128 { 2129 int rc = CrFbDisplayWindow::RegionsChanged(pFb); 2130 if (!RT_SUCCESS(rc)) 2131 { 2132 WARN(("err")); 2133 return rc; 2134 } 2135 2136 rc = synchCompositorRegions(); 2137 if (!RT_SUCCESS(rc)) 2138 { 2139 WARN(("err")); 2140 return rc; 2141 } 2142 2143 return VINF_SUCCESS; 2144 } 2145 2146 virtual int setViewportRect(const RTRECT *pViewportRect) 2147 { 2148 int rc = CrFbDisplayWindow::setViewportRect(pViewportRect); 2149 if (!RT_SUCCESS(rc)) 2150 { 2151 WARN(("err")); 2152 return rc; 2153 } 2154 2155 rc = synchCompositorData(); 2156 if (!RT_SUCCESS(rc)) 2157 { 2158 WARN(("err")); 2159 return rc; 2160 } 2161 2162 return VINF_SUCCESS; 2163 } 2164 2165 protected: 2166 virtual int screenChanged() 2167 { 2168 int rc = CrFbDisplayWindow::screenChanged(); 2169 if (!RT_SUCCESS(rc)) 2170 { 2171 WARN(("screenChanged failed %d", rc)); 2172 return rc; 2173 } 2174 2175 rc = synchCompositorData(); 2176 if (!RT_SUCCESS(rc)) 2177 { 2178 WARN(("err")); 2179 return rc; 2180 } 2181 2182 return VINF_SUCCESS; 2183 } 2184 2185 virtual int fbCleanup() 2186 { 2187 int rc = clearCompositor(); 2188 if (!RT_SUCCESS(rc)) 2189 { 2190 WARN(("err")); 2191 return rc; 2192 } 2193 2194 return CrFbDisplayWindow::fbCleanup(); 2195 } 2196 2197 virtual int fbSync() 2198 { 2199 int rc = synchCompositor(); 2200 if (!RT_SUCCESS(rc)) 2201 { 2202 WARN(("err")); 2203 return rc; 2204 } 2205 2206 return CrFbDisplayWindow::fbSync(); 2207 } 2208 2209 VBOXVR_SCR_COMPOSITOR_ENTRY* entryAlloc() 2210 { 2211 #ifndef VBOXVDBG_MEMCACHE_DISABLE 2212 return (VBOXVR_SCR_COMPOSITOR_ENTRY*)RTMemCacheAlloc(g_CrPresenter.CEntryLookasideList); 2213 #else 2214 return (VBOXVR_SCR_COMPOSITOR_ENTRY*)RTMemAlloc(sizeof (VBOXVR_SCR_COMPOSITOR_ENTRY)); 2215 #endif 2216 } 2217 2218 void entryFree(VBOXVR_SCR_COMPOSITOR_ENTRY* pEntry) 2219 { 2220 Assert(!CrVrScrCompositorEntryIsUsed(pEntry)); 2221 #ifndef VBOXVDBG_MEMCACHE_DISABLE 2222 RTMemCacheFree(g_CrPresenter.CEntryLookasideList, pEntry); 2223 #else 2224 RTMemFree(pEntry); 2225 #endif 2226 } 2227 2228 int synchCompositorRegions() 2229 { 2230 int rc; 2231 2232 rootVrTranslateForPos(); 2233 2234 /* ensure the rootvr compositor does not hold any data, 2235 * i.e. cleanup all rootvr entries data */ 2236 CrVrScrCompositorClear(&mCompositor); 2237 2238 rc = CrVrScrCompositorIntersectedList(CrFbGetCompositor(getFramebuffer()), &cr_server.RootVr, &mCompositor, rootVrGetCEntry, this, NULL); 2239 if (!RT_SUCCESS(rc)) 2240 { 2241 WARN(("CrVrScrCompositorIntersectedList failed, rc %d", rc)); 2242 return rc; 2243 } 2244 2245 return getWindow()->SetVisibleRegionsChanged(); 2246 } 2247 2248 int synchCompositorData() 2249 { 2250 CrVrScrCompositorClear(&mCompositor); 2251 2252 const struct VBVAINFOSCREEN* pScreenInfo = CrFbGetScreenInfo(getFramebuffer()); 2253 mPos.x = pScreenInfo->i32OriginX; 2254 mPos.y = pScreenInfo->i32OriginY; 2255 2256 int rc = CrVrScrCompositorRectSet(&mCompositor, CrVrScrCompositorRectGet(CrFbGetCompositor(getFramebuffer())), NULL); 2257 if (!RT_SUCCESS(rc)) 2258 { 2259 WARN(("CrVrScrCompositorRectSet failed, rc %d", rc)); 2260 return rc; 2261 } 2262 rc = synchCompositorRegions(); 2263 if (!RT_SUCCESS(rc)) 2264 { 2265 WARN(("synchCompositorRegions failed, rc %d", rc)); 2266 return rc; 2267 } 2268 2269 return rc; 2270 } 2271 2272 virtual int synchCompositor() 2273 { 2274 int rc = CrVrScrCompositorRectSet(&mCompositor, CrVrScrCompositorRectGet(CrFbGetCompositor(getFramebuffer())), NULL); 2275 if (!RT_SUCCESS(rc)) 2276 { 2277 WARN(("CrVrScrCompositorRectSet failed, rc %d", rc)); 2278 return rc; 2279 } 2280 2281 rc = fbSynchAddAllEntries(); 2282 if (!RT_SUCCESS(rc)) 2283 { 2284 WARN(("fbSynchAddAllEntries failed, rc %d", rc)); 2285 return rc; 2286 } 2287 2288 rc = synchCompositorRegions(); 2289 if (!RT_SUCCESS(rc)) 2290 { 2291 WARN(("synchCompositorRegions failed, rc %d", rc)); 2292 return rc; 2293 } 2294 2295 return rc; 2296 } 2297 2298 virtual int clearCompositor() 2299 { 2300 return fbCleanupRemoveAllEntries(true); 2301 } 2302 2303 void rootVrTranslateForPos() 2304 { 2305 int32_t dx = cr_server.RootVrCurPoint.x - mPos.x; 2306 int32_t dy = cr_server.RootVrCurPoint.y - mPos.y; 2307 2308 cr_server.RootVrCurPoint.x = mPos.x; 2309 cr_server.RootVrCurPoint.y = mPos.y; 2310 2311 VBoxVrListTranslate(&cr_server.RootVr, dx, dy); 2312 } 2313 2314 static DECLCALLBACK(VBOXVR_SCR_COMPOSITOR_ENTRY*) rootVrGetCEntry(const VBOXVR_SCR_COMPOSITOR_ENTRY*pEntry, void *pvContext) 2315 { 2316 CrFbDisplayWindowRootVr *pThis = (CrFbDisplayWindowRootVr*)pvContext; 2317 HCR_FRAMEBUFFER_ENTRY hEntry = CrFbEntryFromCompositorEntry(pEntry); 2318 VBOXVR_SCR_COMPOSITOR_ENTRY *pMyEntry = (VBOXVR_SCR_COMPOSITOR_ENTRY*)CrFbDDataEntryGet(hEntry, pThis->slotGet()); 2319 Assert(!CrVrScrCompositorEntryIsUsed(pMyEntry)); 2320 CrVrScrCompositorEntryRectSet(&pThis->mCompositor, pMyEntry, CrVrScrCompositorEntryRectGet(pEntry)); 2321 return pMyEntry; 2322 } 2323 private: 2324 VBOXVR_SCR_COMPOSITOR mCompositor; 2325 RTPOINT mPos; 2326 }; 2327 2328 class CrFbDisplayVrdp : public CrFbDisplayBase 2329 { 2330 public: 2331 CrFbDisplayVrdp() 2332 { 2333 memset(&mPos, 0, sizeof (mPos)); 2334 } 2335 2336 virtual int EntryCreated(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2337 { 2338 int rc = CrFbDisplayBase::EntryCreated(pFb, hEntry); 2339 if (!RT_SUCCESS(rc)) 2340 { 2341 WARN(("EntryAdded failed rc %d", rc)); 2342 return rc; 2343 } 2344 2345 Assert(!CrFbDDataEntryGet(hEntry, slotGet())); 2346 rc = vrdpCreate(pFb, hEntry); 2347 if (!RT_SUCCESS(rc)) 2348 { 2349 WARN(("vrdpCreate failed rc %d", rc)); 2350 return rc; 2351 } 2352 2353 return VINF_SUCCESS; 2354 } 2355 2356 virtual int EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry) 2357 { 2358 int rc = CrFbDisplayBase::EntryReplaced(pFb, hNewEntry, hReplacedEntry); 2359 if (!RT_SUCCESS(rc)) 2360 { 2361 WARN(("err")); 2362 return rc; 2363 } 2364 2365 return vrdpFrame(hNewEntry); 2366 } 2367 2368 virtual int EntryTexChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2369 { 2370 int rc = CrFbDisplayBase::EntryTexChanged(pFb, hEntry); 2371 if (!RT_SUCCESS(rc)) 2372 { 2373 WARN(("err")); 2374 return rc; 2375 } 2376 2377 return vrdpFrame(hEntry); 2378 } 2379 2380 virtual int EntryRemoved(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2381 { 2382 int rc = CrFbDisplayBase::EntryRemoved(pFb, hEntry); 2383 if (!RT_SUCCESS(rc)) 2384 { 2385 WARN(("err")); 2386 return rc; 2387 } 2388 2389 return vrdpRegions(pFb, hEntry); 2390 } 2391 2392 virtual int EntryDestroyed(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2393 { 2394 int rc = CrFbDisplayBase::EntryDestroyed(pFb, hEntry); 2395 if (!RT_SUCCESS(rc)) 2396 { 2397 WARN(("err")); 2398 return rc; 2399 } 2400 2401 vrdpDestroy(hEntry); 2402 return VINF_SUCCESS; 2403 } 2404 2405 virtual int EntryPosChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2406 { 2407 int rc = CrFbDisplayBase::EntryPosChanged(pFb, hEntry); 2408 if (!RT_SUCCESS(rc)) 2409 { 2410 WARN(("err")); 2411 return rc; 2412 } 2413 2414 vrdpGeometry(hEntry); 2415 2416 return VINF_SUCCESS; 2417 } 2418 2419 virtual int RegionsChanged(struct CR_FRAMEBUFFER *pFb) 2420 { 2421 int rc = CrFbDisplayBase::RegionsChanged(pFb); 2422 if (!RT_SUCCESS(rc)) 2423 { 2424 WARN(("err")); 2425 return rc; 2426 } 2427 2428 return vrdpRegionsAll(pFb); 2429 } 2430 2431 virtual int FramebufferChanged(struct CR_FRAMEBUFFER *pFb) 2432 { 2433 int rc = CrFbDisplayBase::FramebufferChanged(pFb); 2434 if (!RT_SUCCESS(rc)) 2435 { 2436 WARN(("err")); 2437 return rc; 2438 } 2439 2440 syncPos(); 2441 2442 rc = vrdpSyncEntryAll(pFb); 2443 if (!RT_SUCCESS(rc)) 2444 { 2445 WARN(("err")); 2446 return rc; 2447 } 2448 2449 return vrdpRegionsAll(pFb); 2450 } 2451 2452 protected: 2453 void syncPos() 2454 { 2455 const struct VBVAINFOSCREEN* pScreenInfo = CrFbGetScreenInfo(getFramebuffer()); 2456 mPos.x = pScreenInfo->i32OriginX; 2457 mPos.y = pScreenInfo->i32OriginY; 2458 } 2459 2460 virtual int fbCleanup() 2461 { 2462 int rc = fbCleanupRemoveAllEntries(true); 2463 if (!RT_SUCCESS(rc)) 2464 { 2465 WARN(("err")); 2466 return rc; 2467 } 2468 2469 return CrFbDisplayBase::fbCleanup(); 2470 } 2471 2472 virtual int fbSync() 2473 { 2474 syncPos(); 2475 2476 int rc = fbSynchAddAllEntries(); 2477 if (!RT_SUCCESS(rc)) 2478 { 2479 WARN(("err")); 2480 return rc; 2481 } 2482 2483 return CrFbDisplayBase::fbSync(); 2484 } 2485 protected: 2486 void vrdpDestroy(HCR_FRAMEBUFFER_ENTRY hEntry) 2487 { 2488 void *pVrdp = CrFbDDataEntryGet(hEntry, slotGet()); 2489 cr_server.outputRedirect.CROREnd(pVrdp); 2490 } 2491 2492 void vrdpGeometry(HCR_FRAMEBUFFER_ENTRY hEntry) 2493 { 2494 void *pVrdp = CrFbDDataEntryGet(hEntry, slotGet()); 2495 const VBOXVR_SCR_COMPOSITOR_ENTRY* pEntry = CrFbEntryGetCompositorEntry(hEntry); 2496 2497 cr_server.outputRedirect.CRORGeometry(pVrdp, 2498 mPos.x + CrVrScrCompositorEntryRectGet(pEntry)->xLeft, 2499 mPos.y + CrVrScrCompositorEntryRectGet(pEntry)->yTop, 2500 CrVrScrCompositorEntryTexGet(pEntry)->Tex.width, 2501 CrVrScrCompositorEntryTexGet(pEntry)->Tex.height); 2502 } 2503 2504 int vrdpRegions(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2505 { 2506 void *pVrdp = CrFbDDataEntryGet(hEntry, slotGet()); 2507 const struct VBOXVR_SCR_COMPOSITOR* pCompositor = CrFbGetCompositor(pFb); 2508 const VBOXVR_SCR_COMPOSITOR_ENTRY* pEntry = CrFbEntryGetCompositorEntry(hEntry); 2509 uint32_t cRects; 2510 const RTRECT *pRects; 2511 2512 int rc = CrVrScrCompositorEntryRegionsGet(pCompositor, pEntry, &cRects, NULL, &pRects, NULL); 2513 if (!RT_SUCCESS(rc)) 2514 { 2515 WARN(("CrVrScrCompositorEntryRegionsGet failed, rc %d", rc)); 2516 return rc; 2517 } 2518 2519 cr_server.outputRedirect.CRORVisibleRegion(pVrdp, cRects, pRects); 2520 return VINF_SUCCESS; 2521 } 2522 2523 int vrdpFrame(HCR_FRAMEBUFFER_ENTRY hEntry) 2524 { 2525 void *pVrdp = CrFbDDataEntryGet(hEntry, slotGet()); 2526 const VBOXVR_SCR_COMPOSITOR_ENTRY* pEntry = CrFbEntryGetCompositorEntry(hEntry); 2527 CR_TEXDATA *pTex = CrVrScrCompositorEntryTexGet(pEntry); 2528 const CR_BLITTER_IMG *pImg; 2529 int rc = CrTdBltDataAcquire(pTex, GL_BGRA, !!(CrVrScrCompositorEntryFlagsGet(pEntry) & CRBLT_F_INVERT_SRC_YCOORDS), &pImg); 2530 if (!RT_SUCCESS(rc)) 2531 { 2532 WARN(("CrTdBltDataAcquire failed rc %d", rc)); 2533 return rc; 2534 } 2535 2536 cr_server.outputRedirect.CRORFrame(pVrdp, pImg->pvData, pImg->cbData); 2537 CrTdBltDataRelease(pTex); 2538 return VINF_SUCCESS; 2539 } 2540 2541 int vrdpRegionsAll(struct CR_FRAMEBUFFER *pFb) 2542 { 2543 const struct VBOXVR_SCR_COMPOSITOR* pCompositor = CrFbGetCompositor(pFb); 2544 VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR Iter; 2545 CrVrScrCompositorConstIterInit(pCompositor, &Iter); 2546 const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry; 2547 while ((pEntry = CrVrScrCompositorConstIterNext(&Iter)) != NULL) 2548 { 2549 HCR_FRAMEBUFFER_ENTRY hEntry = CrFbEntryFromCompositorEntry(pEntry); 2550 vrdpRegions(pFb, hEntry); 2551 } 2552 2553 return VINF_SUCCESS; 2554 } 2555 2556 int vrdpSynchEntry(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2557 { 2558 vrdpGeometry(hEntry); 2559 2560 return vrdpRegions(pFb, hEntry);; 2561 } 2562 2563 int vrdpSyncEntryAll(struct CR_FRAMEBUFFER *pFb) 2564 { 2565 const struct VBOXVR_SCR_COMPOSITOR* pCompositor = CrFbGetCompositor(pFb); 2566 VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR Iter; 2567 CrVrScrCompositorConstIterInit(pCompositor, &Iter); 2568 const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry; 2569 while ((pEntry = CrVrScrCompositorConstIterNext(&Iter)) != NULL) 2570 { 2571 HCR_FRAMEBUFFER_ENTRY hEntry = CrFbEntryFromCompositorEntry(pEntry); 2572 int rc = vrdpSynchEntry(pFb, hEntry); 2573 if (!RT_SUCCESS(rc)) 2574 { 2575 WARN(("vrdpSynchEntry failed rc %d", rc)); 2576 return rc; 2577 } 2578 } 2579 2580 return VINF_SUCCESS; 2581 } 2582 2583 int vrdpCreate(HCR_FRAMEBUFFER hFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2584 { 2585 void *pVrdp; 2586 2587 /* Query supported formats. */ 2588 uint32_t cbFormats = 4096; 2589 char *pachFormats = (char *)crAlloc(cbFormats); 2590 2591 if (!pachFormats) 2592 { 2593 WARN(("crAlloc failed")); 2594 return VERR_NO_MEMORY; 2595 } 2596 2597 int rc = cr_server.outputRedirect.CRORContextProperty(cr_server.outputRedirect.pvContext, 2598 0 /* H3DOR_PROP_FORMATS */, // @todo from a header 2599 pachFormats, cbFormats, &cbFormats); 2600 if (RT_SUCCESS(rc)) 2601 { 2602 if (RTStrStr(pachFormats, "H3DOR_FMT_RGBA_TOPDOWN")) 2603 { 2604 cr_server.outputRedirect.CRORBegin(cr_server.outputRedirect.pvContext, 2605 &pVrdp, 2606 "H3DOR_FMT_RGBA_TOPDOWN"); // @todo from a header 2607 2608 if (pVrdp) 2609 { 2610 rc = CrFbDDataEntryPut(hEntry, slotGet(), pVrdp); 2611 if (RT_SUCCESS(rc)) 2612 { 2613 vrdpGeometry(hEntry); 2614 vrdpRegions(hFb, hEntry); 2615 vrdpFrame(hEntry); 2616 return VINF_SUCCESS; 2617 } 2618 else 2619 WARN(("CrFbDDataEntryPut failed rc %d", rc)); 2620 2621 cr_server.outputRedirect.CROREnd(pVrdp); 2622 } 2623 else 2624 { 2625 WARN(("CRORBegin failed")); 2626 rc = VERR_GENERAL_FAILURE; 2627 } 2628 } 2629 } 2630 else 2631 WARN(("CRORContextProperty failed rc %d", rc)); 2632 2633 crFree(pachFormats); 2634 2635 return rc; 2636 } 2637 private: 2638 RTPOINT mPos; 2639 }; 2640 2641 CrFbDisplayBase::~CrFbDisplayBase() 2642 { 2643 Assert(!mcUpdates); 2644 2645 if (mpContainer) 2646 mpContainer->remove(this); 2647 } 2648 2649 2650 #if 0 2651 2652 2653 2654 2655 2656 void crDbgDumpRect(uint32_t i, const RTRECT *pRect) 2657 { 2658 crDebug("%d: (%d;%d) X (%d;%d)", i, pRect->xLeft, pRect->yTop, pRect->xRight, pRect->yBottom); 2659 } 2660 2661 void crDbgDumpRects(uint32_t cRects, const RTRECT *paRects) 2662 { 2663 crDebug("Dumping rects (%d)", cRects); 2664 for (uint32_t i = 0; i < cRects; ++i) 2665 { 2666 crDbgDumpRect(i, &paRects[i]); 2667 } 2668 crDebug("End Dumping rects (%d)", cRects); 2669 } 2670 2671 int crServerDisplaySaveState(PSSMHANDLE pSSM) 2672 { 2673 int rc; 2674 int cDisplays = 0, i; 2675 for (i = 0; i < cr_server.screenCount; ++i) 2676 { 2677 if (ASMBitTest(cr_server.DisplaysInitMap, i) && !CrDpIsEmpty(&cr_server.aDispplays[i])) 2678 ++cDisplays; 2679 } 2680 2681 rc = SSMR3PutS32(pSSM, cDisplays); 2682 AssertRCReturn(rc, rc); 2683 2684 if (!cDisplays) 2685 return VINF_SUCCESS; 2686 2687 rc = SSMR3PutS32(pSSM, cr_server.screenCount); 2688 AssertRCReturn(rc, rc); 2689 2690 for (i = 0; i < cr_server.screenCount; ++i) 2691 { 2692 rc = SSMR3PutS32(pSSM, cr_server.screen[i].x); 2693 AssertRCReturn(rc, rc); 2694 2695 rc = SSMR3PutS32(pSSM, cr_server.screen[i].y); 2696 AssertRCReturn(rc, rc); 2697 2698 rc = SSMR3PutU32(pSSM, cr_server.screen[i].w); 2699 AssertRCReturn(rc, rc); 2700 2701 rc = SSMR3PutU32(pSSM, cr_server.screen[i].h); 2702 AssertRCReturn(rc, rc); 2703 } 2704 2705 for (i = 0; i < cr_server.screenCount; ++i) 2706 { 2707 if (ASMBitTest(cr_server.DisplaysInitMap, i) && !CrDpIsEmpty(&cr_server.aDispplays[i])) 2708 { 2709 rc = SSMR3PutS32(pSSM, i); 2710 AssertRCReturn(rc, rc); 2711 2712 rc = CrDpSaveState(&cr_server.aDispplays[i], pSSM); 2713 AssertRCReturn(rc, rc); 2714 } 2715 } 2716 2717 return VINF_SUCCESS; 2718 } 2719 2720 int crServerDisplayLoadState(PSSMHANDLE pSSM, uint32_t u32Version) 2721 { 2722 2723 } 2724 #endif 279 2725 280 2726 int CrPMgrInit() … … 349 2795 void CrPMgrTerm() 350 2796 { 2797 crPMgrModeModifyGlobal(CR_PMGR_MODE_ALL, false); 2798 2799 HCR_FRAMEBUFFER hFb; 2800 2801 for (hFb = CrPMgrFbGetFirstInitialized(); 2802 hFb; 2803 hFb = CrPMgrFbGetNextInitialized(hFb)) 2804 { 2805 uint32_t idScreen = CrFbGetScreenInfo(hFb)->u32ViewIndex; 2806 CrFbDisplaySet(hFb, NULL); 2807 CR_FBDISPLAY_INFO *pInfo = &g_CrPresenter.aDisplayInfos[idScreen]; 2808 2809 if (pInfo->pDpComposite) 2810 delete pInfo->pDpComposite; 2811 2812 Assert(!pInfo->pDpWin); 2813 Assert(!pInfo->pDpWinRootVr); 2814 Assert(!pInfo->pDpVrdp); 2815 2816 CrFbTerm(hFb); 2817 } 2818 351 2819 #ifndef VBOXVDBG_MEMCACHE_DISABLE 352 2820 RTMemCacheDestroy(g_CrPresenter.FbEntryLookasideList); … … 355 2823 #endif 356 2824 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 EntryTexChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 1808 { 1809 int rc = CrFbDisplayBase::EntryTexChanged(pFb, hEntry); 1810 if (!RT_SUCCESS(rc)) 1811 { 1812 WARN(("err")); 1813 return rc; 1814 } 1815 1816 if (mpWindow->GetParentId()) 1817 { 1818 rc = mpWindow->Create(); 1819 if (!RT_SUCCESS(rc)) 1820 { 1821 WARN(("err")); 1822 return rc; 1823 } 1824 } 1825 1826 return VINF_SUCCESS; 1827 } 1828 1829 virtual int EntryRemoved(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 1830 { 1831 int rc = CrFbDisplayBase::EntryRemoved(pFb, hEntry); 1832 if (!RT_SUCCESS(rc)) 1833 { 1834 WARN(("err")); 1835 return rc; 1836 } 1837 1838 return mpWindow->SetVisibleRegionsChanged(); 1839 } 1840 1841 virtual int EntryPosChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 1842 { 1843 int rc = CrFbDisplayBase::EntryPosChanged(pFb, hEntry); 1844 if (!RT_SUCCESS(rc)) 1845 { 1846 WARN(("err")); 1847 return rc; 1848 } 1849 1850 return mpWindow->SetVisibleRegionsChanged(); 1851 } 1852 1853 virtual int RegionsChanged(struct CR_FRAMEBUFFER *pFb) 1854 { 1855 int rc = CrFbDisplayBase::RegionsChanged(pFb); 1856 if (!RT_SUCCESS(rc)) 1857 { 1858 WARN(("err")); 1859 return rc; 1860 } 1861 1862 return mpWindow->SetVisibleRegionsChanged(); 1863 } 1864 1865 virtual int FramebufferChanged(struct CR_FRAMEBUFFER *pFb) 1866 { 1867 int rc = CrFbDisplayBase::FramebufferChanged(pFb); 1868 if (!RT_SUCCESS(rc)) 1869 { 1870 WARN(("err")); 1871 return rc; 1872 } 1873 1874 return screenChanged(); 1875 } 1876 1877 virtual int setViewportRect(const RTRECT *pViewportRect) 1878 { 1879 if (!isUpdating()) 1880 { 1881 WARN(("not updating!")); 1882 return VERR_INVALID_STATE; 1883 } 1884 1885 if (pViewportRect->xLeft != mViewportRect.xLeft || pViewportRect->yTop != mViewportRect.yTop) 1886 { 1887 const RTRECT* pRect = CrVrScrCompositorRectGet(getCompositor()); 1888 int rc = mpWindow->SetPosition(pRect->xLeft - mViewportRect.xLeft, pRect->yTop - mViewportRect.yTop); 1889 if (!RT_SUCCESS(rc)) 1890 { 1891 WARN(("SetPosition failed")); 1892 return rc; 1893 } 1894 } 1895 1896 mViewportRect = *pViewportRect; 1897 1898 return VINF_SUCCESS; 1899 } 1900 1901 virtual CrFbWindow * windowDetach() 1902 { 1903 if (isUpdating()) 1904 { 1905 WARN(("updating!")); 1906 return NULL; 1907 } 1908 1909 CrFbWindow * pWindow = mpWindow; 1910 if (mpWindow) 1911 { 1912 windowCleanup(); 1913 mpWindow = NULL; 1914 } 1915 return pWindow; 1916 } 1917 1918 virtual CrFbWindow * windowAttach(CrFbWindow * pNewWindow) 1919 { 1920 if (isUpdating()) 1921 { 1922 WARN(("updating!")); 1923 return NULL; 1924 } 1925 1926 CrFbWindow * pOld = mpWindow; 1927 if (mpWindow) 1928 windowDetach(); 1929 1930 mpWindow = pNewWindow; 1931 if (pNewWindow) 1932 windowSync(); 1933 1934 return mpWindow; 1935 } 1936 1937 virtual int reparent(uint64_t parentId) 1938 { 1939 if (!isUpdating()) 1940 { 1941 WARN(("not updating!")); 1942 return VERR_INVALID_STATE; 1943 } 1944 1945 int rc = mpWindow->Reparent(parentId); 1946 if (!RT_SUCCESS(rc)) 1947 WARN(("window reparent failed")); 1948 1949 return rc; 1950 } 1951 1952 protected: 1953 virtual int screenChanged() 1954 { 1955 if (!isUpdating()) 1956 { 1957 WARN(("not updating!")); 1958 return VERR_INVALID_STATE; 1959 } 1960 1961 const RTRECT* pRect = CrVrScrCompositorRectGet(getCompositor()); 1962 int rc = mpWindow->SetPosition(pRect->xLeft - mViewportRect.xLeft, pRect->yTop - mViewportRect.yTop); 1963 if (!RT_SUCCESS(rc)) 1964 { 1965 WARN(("SetComposition failed rc %d", rc)); 1966 return rc; 1967 } 1968 1969 mpWindow->SetVisibleRegionsChanged(); 1970 1971 return mpWindow->SetSize((uint32_t)(pRect->xRight - pRect->xLeft), (uint32_t)(pRect->yBottom - pRect->yTop)); 1972 } 1973 1974 virtual int windowCleanup() 1975 { 1976 int rc = mpWindow->UpdateBegin(); 1977 if (!RT_SUCCESS(rc)) 1978 { 1979 WARN(("err")); 1980 return rc; 1981 } 1982 1983 rc = mpWindow->SetVisible(false); 1984 if (!RT_SUCCESS(rc)) 1985 { 1986 WARN(("err")); 1987 mpWindow->UpdateEnd(); 1988 return rc; 1989 } 1990 1991 rc = mpWindow->SetCompositor(NULL); 1992 if (!RT_SUCCESS(rc)) 1993 { 1994 WARN(("err")); 1995 mpWindow->UpdateEnd(); 1996 return rc; 1997 } 1998 1999 mpWindow->UpdateEnd(); 2000 2001 return VINF_SUCCESS; 2002 } 2003 2004 virtual int fbCleanup() 2005 { 2006 int rc = windowCleanup(); 2007 if (!RT_SUCCESS(rc)) 2008 { 2009 WARN(("windowCleanup failed")); 2010 return rc; 2011 } 2012 return CrFbDisplayBase::fbCleanup(); 2013 } 2014 2015 virtual int windowSync() 2016 { 2017 const struct VBOXVR_SCR_COMPOSITOR* pCompositor = getCompositor(); 2018 const RTRECT* pRect = CrVrScrCompositorRectGet(pCompositor); 2019 2020 int rc = mpWindow->UpdateBegin(); 2021 if (!RT_SUCCESS(rc)) 2022 { 2023 WARN(("err")); 2024 return rc; 2025 } 2026 2027 rc = mpWindow->SetCompositor(pCompositor); 2028 if (!RT_SUCCESS(rc)) 2029 { 2030 WARN(("err")); 2031 mpWindow->UpdateEnd(); 2032 return rc; 2033 } 2034 2035 rc = mpWindow->SetPosition(pRect->xLeft - mViewportRect.xLeft, pRect->yTop - mViewportRect.yTop); 2036 if (!RT_SUCCESS(rc)) 2037 { 2038 WARN(("err")); 2039 mpWindow->UpdateEnd(); 2040 return rc; 2041 } 2042 2043 rc = mpWindow->SetSize((uint32_t)(pRect->xRight - pRect->xLeft), (uint32_t)(pRect->yBottom - pRect->yTop)); 2044 if (!RT_SUCCESS(rc)) 2045 { 2046 WARN(("err")); 2047 mpWindow->UpdateEnd(); 2048 return rc; 2049 } 2050 2051 rc = mpWindow->SetVisible(true); 2052 if (!RT_SUCCESS(rc)) 2053 { 2054 WARN(("err")); 2055 mpWindow->UpdateEnd(); 2056 return rc; 2057 } 2058 2059 mpWindow->UpdateEnd(); 2060 2061 return rc; 2062 } 2063 2064 virtual int fbSync() 2065 { 2066 int rc = CrFbDisplayBase::fbSync(); 2067 if (!RT_SUCCESS(rc)) 2068 { 2069 WARN(("err")); 2070 return rc; 2071 } 2072 2073 return windowSync(); 2074 } 2075 2076 virtual const struct VBOXVR_SCR_COMPOSITOR* getCompositor() 2077 { 2078 return CrFbGetCompositor(getFramebuffer()); 2079 } 2080 2081 CrFbWindow* getWindow() {return mpWindow;} 2082 private: 2083 CrFbWindow *mpWindow; 2084 RTRECT mViewportRect; 2085 }; 2086 2087 class CrFbDisplayWindowRootVr : public CrFbDisplayWindow 2088 { 2089 public: 2090 CrFbDisplayWindowRootVr(CrFbWindow *pWindow, const RTRECT *pViewportRect) : 2091 CrFbDisplayWindow(pWindow, pViewportRect) 2092 { 2093 CrVrScrCompositorInit(&mCompositor, NULL); 2094 memset(&mPos, 0, sizeof (mPos)); 2095 } 2096 2097 virtual int EntryCreated(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2098 { 2099 int rc = CrFbDisplayWindow::EntryCreated(pFb, hEntry); 2100 if (!RT_SUCCESS(rc)) 2101 { 2102 WARN(("err")); 2103 return rc; 2104 } 2105 2106 Assert(!CrFbDDataEntryGet(hEntry, slotGet())); 2107 2108 const VBOXVR_SCR_COMPOSITOR_ENTRY* pSrcEntry = CrFbEntryGetCompositorEntry(hEntry); 2109 VBOXVR_SCR_COMPOSITOR_ENTRY *pMyEntry = entryAlloc(); 2110 CrVrScrCompositorEntryInit(pMyEntry, CrVrScrCompositorEntryRectGet(pSrcEntry), CrVrScrCompositorEntryTexGet(pSrcEntry), NULL); 2111 CrVrScrCompositorEntryFlagsSet(pMyEntry, CrVrScrCompositorEntryFlagsGet(pSrcEntry)); 2112 rc = CrFbDDataEntryPut(hEntry, slotGet(), pMyEntry); 2113 if (!RT_SUCCESS(rc)) 2114 { 2115 WARN(("CrFbDDataEntryPut failed rc %d", rc)); 2116 entryFree(pMyEntry); 2117 return rc; 2118 } 2119 2120 return VINF_SUCCESS; 2121 } 2122 2123 virtual int EntryAdded(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2124 { 2125 int rc = CrFbDisplayWindow::EntryAdded(pFb, hEntry); 2126 if (!RT_SUCCESS(rc)) 2127 { 2128 WARN(("err")); 2129 return rc; 2130 } 2131 2132 const VBOXVR_SCR_COMPOSITOR_ENTRY* pSrcEntry = CrFbEntryGetCompositorEntry(hEntry); 2133 VBOXVR_SCR_COMPOSITOR_ENTRY *pMyEntry = (VBOXVR_SCR_COMPOSITOR_ENTRY*)CrFbDDataEntryGet(hEntry, slotGet()); 2134 Assert(pMyEntry); 2135 CrVrScrCompositorEntryTexSet(pMyEntry, CrVrScrCompositorEntryTexGet(pSrcEntry)); 2136 2137 return VINF_SUCCESS; 2138 } 2139 2140 virtual int EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry) 2141 { 2142 int rc = CrFbDisplayWindow::EntryReplaced(pFb, hNewEntry, hReplacedEntry); 2143 if (!RT_SUCCESS(rc)) 2144 { 2145 WARN(("err")); 2146 return rc; 2147 } 2148 2149 const VBOXVR_SCR_COMPOSITOR_ENTRY* pSrcNewEntry = CrFbEntryGetCompositorEntry(hNewEntry); 2150 VBOXVR_SCR_COMPOSITOR_ENTRY *pMyEntry = (VBOXVR_SCR_COMPOSITOR_ENTRY*)CrFbDDataEntryGet(hNewEntry, slotGet()); 2151 CrVrScrCompositorEntryTexSet(pMyEntry, CrVrScrCompositorEntryTexGet(pSrcNewEntry)); 2152 2153 return VINF_SUCCESS; 2154 } 2155 2156 virtual int EntryTexChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2157 { 2158 int rc = CrFbDisplayWindow::EntryTexChanged(pFb, hEntry); 2159 if (!RT_SUCCESS(rc)) 2160 { 2161 WARN(("err")); 2162 return rc; 2163 } 2164 2165 const VBOXVR_SCR_COMPOSITOR_ENTRY* pSrcEntry = CrFbEntryGetCompositorEntry(hEntry); 2166 VBOXVR_SCR_COMPOSITOR_ENTRY *pMyEntry = (VBOXVR_SCR_COMPOSITOR_ENTRY*)CrFbDDataEntryGet(hEntry, slotGet()); 2167 CrVrScrCompositorEntryTexSet(pMyEntry, CrVrScrCompositorEntryTexGet(pSrcEntry)); 2168 2169 return VINF_SUCCESS; 2170 } 2171 2172 virtual int EntryRemoved(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2173 { 2174 int rc = CrFbDisplayWindow::EntryRemoved(pFb, hEntry); 2175 if (!RT_SUCCESS(rc)) 2176 { 2177 WARN(("err")); 2178 return rc; 2179 } 2180 2181 return VINF_SUCCESS; 2182 } 2183 2184 virtual int EntryDestroyed(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2185 { 2186 int rc = CrFbDisplayWindow::EntryDestroyed(pFb, hEntry); 2187 if (!RT_SUCCESS(rc)) 2188 { 2189 WARN(("err")); 2190 return rc; 2191 } 2192 2193 const VBOXVR_SCR_COMPOSITOR_ENTRY* pSrcEntry = CrFbEntryGetCompositorEntry(hEntry); 2194 VBOXVR_SCR_COMPOSITOR_ENTRY *pMyEntry = (VBOXVR_SCR_COMPOSITOR_ENTRY*)CrFbDDataEntryGet(hEntry, slotGet()); 2195 CrVrScrCompositorEntryCleanup(pMyEntry); 2196 entryFree(pMyEntry); 2197 2198 return VINF_SUCCESS; 2199 } 2200 2201 virtual int RegionsChanged(struct CR_FRAMEBUFFER *pFb) 2202 { 2203 int rc = CrFbDisplayWindow::RegionsChanged(pFb); 2204 if (!RT_SUCCESS(rc)) 2205 { 2206 WARN(("err")); 2207 return rc; 2208 } 2209 2210 rc = synchCompositorRegions(); 2211 if (!RT_SUCCESS(rc)) 2212 { 2213 WARN(("err")); 2214 return rc; 2215 } 2216 2217 return VINF_SUCCESS; 2218 } 2219 2220 virtual int setViewportRect(const RTRECT *pViewportRect) 2221 { 2222 int rc = CrFbDisplayWindow::setViewportRect(pViewportRect); 2223 if (!RT_SUCCESS(rc)) 2224 { 2225 WARN(("err")); 2226 return rc; 2227 } 2228 2229 rc = synchCompositorData(); 2230 if (!RT_SUCCESS(rc)) 2231 { 2232 WARN(("err")); 2233 return rc; 2234 } 2235 2236 return VINF_SUCCESS; 2237 } 2238 2239 protected: 2240 virtual int screenChanged() 2241 { 2242 int rc = CrFbDisplayWindow::screenChanged(); 2243 if (!RT_SUCCESS(rc)) 2244 { 2245 WARN(("screenChanged failed %d", rc)); 2246 return rc; 2247 } 2248 2249 rc = synchCompositorData(); 2250 if (!RT_SUCCESS(rc)) 2251 { 2252 WARN(("err")); 2253 return rc; 2254 } 2255 2256 return VINF_SUCCESS; 2257 } 2258 2259 virtual int fbCleanup() 2260 { 2261 int rc = clearCompositor(); 2262 if (!RT_SUCCESS(rc)) 2263 { 2264 WARN(("err")); 2265 return rc; 2266 } 2267 2268 return CrFbDisplayWindow::fbCleanup(); 2269 } 2270 2271 virtual int fbSync() 2272 { 2273 int rc = synchCompositor(); 2274 if (!RT_SUCCESS(rc)) 2275 { 2276 WARN(("err")); 2277 return rc; 2278 } 2279 2280 return CrFbDisplayWindow::fbSync(); 2281 } 2282 2283 VBOXVR_SCR_COMPOSITOR_ENTRY* entryAlloc() 2284 { 2285 #ifndef VBOXVDBG_MEMCACHE_DISABLE 2286 return (VBOXVR_SCR_COMPOSITOR_ENTRY*)RTMemCacheAlloc(g_CrPresenter.CEntryLookasideList); 2287 #else 2288 return (VBOXVR_SCR_COMPOSITOR_ENTRY*)RTMemAlloc(sizeof (VBOXVR_SCR_COMPOSITOR_ENTRY)); 2289 #endif 2290 } 2291 2292 void entryFree(VBOXVR_SCR_COMPOSITOR_ENTRY* pEntry) 2293 { 2294 Assert(!CrVrScrCompositorEntryIsUsed(pEntry)); 2295 #ifndef VBOXVDBG_MEMCACHE_DISABLE 2296 RTMemCacheFree(g_CrPresenter.CEntryLookasideList, pEntry); 2297 #else 2298 RTMemFree(pEntry); 2299 #endif 2300 } 2301 2302 int synchCompositorRegions() 2303 { 2304 int rc; 2305 2306 rootVrTranslateForPos(); 2307 2308 /* ensure the rootvr compositor does not hold any data, 2309 * i.e. cleanup all rootvr entries data */ 2310 CrVrScrCompositorClear(&mCompositor); 2311 2312 rc = CrVrScrCompositorIntersectedList(CrFbGetCompositor(getFramebuffer()), &cr_server.RootVr, &mCompositor, rootVrGetCEntry, this, NULL); 2313 if (!RT_SUCCESS(rc)) 2314 { 2315 WARN(("CrVrScrCompositorIntersectedList failed, rc %d", rc)); 2316 return rc; 2317 } 2318 2319 return getWindow()->SetVisibleRegionsChanged(); 2320 } 2321 2322 int synchCompositorData() 2323 { 2324 CrVrScrCompositorClear(&mCompositor); 2325 2326 const struct VBVAINFOSCREEN* pScreenInfo = CrFbGetScreenInfo(getFramebuffer()); 2327 mPos.x = pScreenInfo->i32OriginX; 2328 mPos.y = pScreenInfo->i32OriginY; 2329 2330 int rc = CrVrScrCompositorRectSet(&mCompositor, CrVrScrCompositorRectGet(CrFbGetCompositor(getFramebuffer())), NULL); 2331 if (!RT_SUCCESS(rc)) 2332 { 2333 WARN(("CrVrScrCompositorRectSet failed, rc %d", rc)); 2334 return rc; 2335 } 2336 rc = synchCompositorRegions(); 2337 if (!RT_SUCCESS(rc)) 2338 { 2339 WARN(("synchCompositorRegions failed, rc %d", rc)); 2340 return rc; 2341 } 2342 2343 return rc; 2344 } 2345 2346 virtual int synchCompositor() 2347 { 2348 int rc = CrVrScrCompositorRectSet(&mCompositor, CrVrScrCompositorRectGet(CrFbGetCompositor(getFramebuffer())), NULL); 2349 if (!RT_SUCCESS(rc)) 2350 { 2351 WARN(("CrVrScrCompositorRectSet failed, rc %d", rc)); 2352 return rc; 2353 } 2354 2355 rc = fbSynchAddAllEntries(); 2356 if (!RT_SUCCESS(rc)) 2357 { 2358 WARN(("fbSynchAddAllEntries failed, rc %d", rc)); 2359 return rc; 2360 } 2361 2362 rc = synchCompositorRegions(); 2363 if (!RT_SUCCESS(rc)) 2364 { 2365 WARN(("synchCompositorRegions failed, rc %d", rc)); 2366 return rc; 2367 } 2368 2369 return rc; 2370 } 2371 2372 virtual int clearCompositor() 2373 { 2374 return fbCleanupRemoveAllEntries(true); 2375 } 2376 2377 void rootVrTranslateForPos() 2378 { 2379 int32_t dx = cr_server.RootVrCurPoint.x - mPos.x; 2380 int32_t dy = cr_server.RootVrCurPoint.y - mPos.y; 2381 2382 cr_server.RootVrCurPoint.x = mPos.x; 2383 cr_server.RootVrCurPoint.y = mPos.y; 2384 2385 VBoxVrListTranslate(&cr_server.RootVr, dx, dy); 2386 } 2387 2388 static DECLCALLBACK(VBOXVR_SCR_COMPOSITOR_ENTRY*) rootVrGetCEntry(const VBOXVR_SCR_COMPOSITOR_ENTRY*pEntry, void *pvContext) 2389 { 2390 CrFbDisplayWindowRootVr *pThis = (CrFbDisplayWindowRootVr*)pvContext; 2391 HCR_FRAMEBUFFER_ENTRY hEntry = CrFbEntryFromCompositorEntry(pEntry); 2392 VBOXVR_SCR_COMPOSITOR_ENTRY *pMyEntry = (VBOXVR_SCR_COMPOSITOR_ENTRY*)CrFbDDataEntryGet(hEntry, pThis->slotGet()); 2393 Assert(!CrVrScrCompositorEntryIsUsed(pMyEntry)); 2394 CrVrScrCompositorEntryRectSet(&pThis->mCompositor, pMyEntry, CrVrScrCompositorEntryRectGet(pEntry)); 2395 return pMyEntry; 2396 } 2397 private: 2398 VBOXVR_SCR_COMPOSITOR mCompositor; 2399 RTPOINT mPos; 2400 }; 2401 2402 class CrFbDisplayVrdp : public CrFbDisplayBase 2403 { 2404 public: 2405 CrFbDisplayVrdp() 2406 { 2407 memset(&mPos, 0, sizeof (mPos)); 2408 } 2409 2410 virtual int EntryCreated(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2411 { 2412 int rc = CrFbDisplayBase::EntryCreated(pFb, hEntry); 2413 if (!RT_SUCCESS(rc)) 2414 { 2415 WARN(("EntryAdded failed rc %d", rc)); 2416 return rc; 2417 } 2418 2419 Assert(!CrFbDDataEntryGet(hEntry, slotGet())); 2420 rc = vrdpCreate(pFb, hEntry); 2421 if (!RT_SUCCESS(rc)) 2422 { 2423 WARN(("vrdpCreate failed rc %d", rc)); 2424 return rc; 2425 } 2426 2427 return VINF_SUCCESS; 2428 } 2429 2430 virtual int EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry) 2431 { 2432 int rc = CrFbDisplayBase::EntryReplaced(pFb, hNewEntry, hReplacedEntry); 2433 if (!RT_SUCCESS(rc)) 2434 { 2435 WARN(("err")); 2436 return rc; 2437 } 2438 2439 return vrdpFrame(hNewEntry); 2440 } 2441 2442 virtual int EntryTexChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2443 { 2444 int rc = CrFbDisplayBase::EntryTexChanged(pFb, hEntry); 2445 if (!RT_SUCCESS(rc)) 2446 { 2447 WARN(("err")); 2448 return rc; 2449 } 2450 2451 return vrdpFrame(hEntry); 2452 } 2453 2454 virtual int EntryRemoved(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2455 { 2456 int rc = CrFbDisplayBase::EntryRemoved(pFb, hEntry); 2457 if (!RT_SUCCESS(rc)) 2458 { 2459 WARN(("err")); 2460 return rc; 2461 } 2462 2463 return vrdpRegions(pFb, hEntry); 2464 } 2465 2466 virtual int EntryDestroyed(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2467 { 2468 int rc = CrFbDisplayBase::EntryDestroyed(pFb, hEntry); 2469 if (!RT_SUCCESS(rc)) 2470 { 2471 WARN(("err")); 2472 return rc; 2473 } 2474 2475 vrdpDestroy(hEntry); 2476 return VINF_SUCCESS; 2477 } 2478 2479 virtual int EntryPosChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2480 { 2481 int rc = CrFbDisplayBase::EntryPosChanged(pFb, hEntry); 2482 if (!RT_SUCCESS(rc)) 2483 { 2484 WARN(("err")); 2485 return rc; 2486 } 2487 2488 vrdpGeometry(hEntry); 2489 2490 return VINF_SUCCESS; 2491 } 2492 2493 virtual int RegionsChanged(struct CR_FRAMEBUFFER *pFb) 2494 { 2495 int rc = CrFbDisplayBase::RegionsChanged(pFb); 2496 if (!RT_SUCCESS(rc)) 2497 { 2498 WARN(("err")); 2499 return rc; 2500 } 2501 2502 return vrdpRegionsAll(pFb); 2503 } 2504 2505 virtual int FramebufferChanged(struct CR_FRAMEBUFFER *pFb) 2506 { 2507 int rc = CrFbDisplayBase::FramebufferChanged(pFb); 2508 if (!RT_SUCCESS(rc)) 2509 { 2510 WARN(("err")); 2511 return rc; 2512 } 2513 2514 syncPos(); 2515 2516 rc = vrdpSyncEntryAll(pFb); 2517 if (!RT_SUCCESS(rc)) 2518 { 2519 WARN(("err")); 2520 return rc; 2521 } 2522 2523 return vrdpRegionsAll(pFb); 2524 } 2525 2526 protected: 2527 void syncPos() 2528 { 2529 const struct VBVAINFOSCREEN* pScreenInfo = CrFbGetScreenInfo(getFramebuffer()); 2530 mPos.x = pScreenInfo->i32OriginX; 2531 mPos.y = pScreenInfo->i32OriginY; 2532 } 2533 2534 virtual int fbCleanup() 2535 { 2536 int rc = fbCleanupRemoveAllEntries(true); 2537 if (!RT_SUCCESS(rc)) 2538 { 2539 WARN(("err")); 2540 return rc; 2541 } 2542 2543 return CrFbDisplayBase::fbCleanup(); 2544 } 2545 2546 virtual int fbSync() 2547 { 2548 syncPos(); 2549 2550 int rc = fbSynchAddAllEntries(); 2551 if (!RT_SUCCESS(rc)) 2552 { 2553 WARN(("err")); 2554 return rc; 2555 } 2556 2557 return CrFbDisplayBase::fbSync(); 2558 } 2559 protected: 2560 void vrdpDestroy(HCR_FRAMEBUFFER_ENTRY hEntry) 2561 { 2562 void *pVrdp = CrFbDDataEntryGet(hEntry, slotGet()); 2563 cr_server.outputRedirect.CROREnd(pVrdp); 2564 } 2565 2566 void vrdpGeometry(HCR_FRAMEBUFFER_ENTRY hEntry) 2567 { 2568 void *pVrdp = CrFbDDataEntryGet(hEntry, slotGet()); 2569 const VBOXVR_SCR_COMPOSITOR_ENTRY* pEntry = CrFbEntryGetCompositorEntry(hEntry); 2570 2571 cr_server.outputRedirect.CRORGeometry(pVrdp, 2572 mPos.x + CrVrScrCompositorEntryRectGet(pEntry)->xLeft, 2573 mPos.y + CrVrScrCompositorEntryRectGet(pEntry)->yTop, 2574 CrVrScrCompositorEntryTexGet(pEntry)->Tex.width, 2575 CrVrScrCompositorEntryTexGet(pEntry)->Tex.height); 2576 } 2577 2578 int vrdpRegions(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2579 { 2580 void *pVrdp = CrFbDDataEntryGet(hEntry, slotGet()); 2581 const struct VBOXVR_SCR_COMPOSITOR* pCompositor = CrFbGetCompositor(pFb); 2582 const VBOXVR_SCR_COMPOSITOR_ENTRY* pEntry = CrFbEntryGetCompositorEntry(hEntry); 2583 uint32_t cRects; 2584 const RTRECT *pRects; 2585 2586 int rc = CrVrScrCompositorEntryRegionsGet(pCompositor, pEntry, &cRects, NULL, &pRects, NULL); 2587 if (!RT_SUCCESS(rc)) 2588 { 2589 WARN(("CrVrScrCompositorEntryRegionsGet failed, rc %d", rc)); 2590 return rc; 2591 } 2592 2593 cr_server.outputRedirect.CRORVisibleRegion(pVrdp, cRects, pRects); 2594 return VINF_SUCCESS; 2595 } 2596 2597 int vrdpFrame(HCR_FRAMEBUFFER_ENTRY hEntry) 2598 { 2599 void *pVrdp = CrFbDDataEntryGet(hEntry, slotGet()); 2600 const VBOXVR_SCR_COMPOSITOR_ENTRY* pEntry = CrFbEntryGetCompositorEntry(hEntry); 2601 CR_TEXDATA *pTex = CrVrScrCompositorEntryTexGet(pEntry); 2602 const CR_BLITTER_IMG *pImg; 2603 int rc = CrTdBltDataAcquire(pTex, GL_BGRA, !!(CrVrScrCompositorEntryFlagsGet(pEntry) & CRBLT_F_INVERT_SRC_YCOORDS), &pImg); 2604 if (!RT_SUCCESS(rc)) 2605 { 2606 WARN(("CrTdBltDataAcquire failed rc %d", rc)); 2607 return rc; 2608 } 2609 2610 cr_server.outputRedirect.CRORFrame(pVrdp, pImg->pvData, pImg->cbData); 2611 CrTdBltDataRelease(pTex); 2612 return VINF_SUCCESS; 2613 } 2614 2615 int vrdpRegionsAll(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 vrdpRegions(pFb, hEntry); 2625 } 2626 2627 return VINF_SUCCESS; 2628 } 2629 2630 int vrdpSynchEntry(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2631 { 2632 vrdpGeometry(hEntry); 2633 2634 return vrdpRegions(pFb, hEntry);; 2635 } 2636 2637 int vrdpSyncEntryAll(struct CR_FRAMEBUFFER *pFb) 2638 { 2639 const struct VBOXVR_SCR_COMPOSITOR* pCompositor = CrFbGetCompositor(pFb); 2640 VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR Iter; 2641 CrVrScrCompositorConstIterInit(pCompositor, &Iter); 2642 const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry; 2643 while ((pEntry = CrVrScrCompositorConstIterNext(&Iter)) != NULL) 2644 { 2645 HCR_FRAMEBUFFER_ENTRY hEntry = CrFbEntryFromCompositorEntry(pEntry); 2646 int rc = vrdpSynchEntry(pFb, hEntry); 2647 if (!RT_SUCCESS(rc)) 2648 { 2649 WARN(("vrdpSynchEntry failed rc %d", rc)); 2650 return rc; 2651 } 2652 } 2653 2654 return VINF_SUCCESS; 2655 } 2656 2657 int vrdpCreate(HCR_FRAMEBUFFER hFb, HCR_FRAMEBUFFER_ENTRY hEntry) 2658 { 2659 void *pVrdp; 2660 2661 /* Query supported formats. */ 2662 uint32_t cbFormats = 4096; 2663 char *pachFormats = (char *)crAlloc(cbFormats); 2664 2665 if (!pachFormats) 2666 { 2667 WARN(("crAlloc failed")); 2668 return VERR_NO_MEMORY; 2669 } 2670 2671 int rc = cr_server.outputRedirect.CRORContextProperty(cr_server.outputRedirect.pvContext, 2672 0 /* H3DOR_PROP_FORMATS */, // @todo from a header 2673 pachFormats, cbFormats, &cbFormats); 2674 if (RT_SUCCESS(rc)) 2675 { 2676 if (RTStrStr(pachFormats, "H3DOR_FMT_RGBA_TOPDOWN")) 2677 { 2678 cr_server.outputRedirect.CRORBegin(cr_server.outputRedirect.pvContext, 2679 &pVrdp, 2680 "H3DOR_FMT_RGBA_TOPDOWN"); // @todo from a header 2681 2682 if (pVrdp) 2683 { 2684 rc = CrFbDDataEntryPut(hEntry, slotGet(), pVrdp); 2685 if (RT_SUCCESS(rc)) 2686 { 2687 vrdpGeometry(hEntry); 2688 vrdpRegions(hFb, hEntry); 2689 vrdpFrame(hEntry); 2690 return VINF_SUCCESS; 2691 } 2692 else 2693 WARN(("CrFbDDataEntryPut failed rc %d", rc)); 2694 2695 cr_server.outputRedirect.CROREnd(pVrdp); 2696 } 2697 else 2698 { 2699 WARN(("CRORBegin failed")); 2700 rc = VERR_GENERAL_FAILURE; 2701 } 2702 } 2703 } 2704 else 2705 WARN(("CRORContextProperty failed rc %d", rc)); 2706 2707 crFree(pachFormats); 2708 2709 return rc; 2710 } 2711 private: 2712 RTPOINT mPos; 2713 }; 2714 2715 CrFbDisplayBase::~CrFbDisplayBase() 2716 { 2717 Assert(!mcUpdates); 2718 2719 if (mpContainer) 2720 mpContainer->remove(this); 2721 } 2722 2723 2724 #if 0 2725 2726 2727 2728 2729 2730 void crDbgDumpRect(uint32_t i, const RTRECT *pRect) 2731 { 2732 crDebug("%d: (%d;%d) X (%d;%d)", i, pRect->xLeft, pRect->yTop, pRect->xRight, pRect->yBottom); 2733 } 2734 2735 void crDbgDumpRects(uint32_t cRects, const RTRECT *paRects) 2736 { 2737 crDebug("Dumping rects (%d)", cRects); 2738 for (uint32_t i = 0; i < cRects; ++i) 2739 { 2740 crDbgDumpRect(i, &paRects[i]); 2741 } 2742 crDebug("End Dumping rects (%d)", cRects); 2743 } 2744 2745 int crServerDisplaySaveState(PSSMHANDLE pSSM) 2746 { 2747 int rc; 2748 int cDisplays = 0, i; 2749 for (i = 0; i < cr_server.screenCount; ++i) 2750 { 2751 if (ASMBitTest(cr_server.DisplaysInitMap, i) && !CrDpIsEmpty(&cr_server.aDispplays[i])) 2752 ++cDisplays; 2753 } 2754 2755 rc = SSMR3PutS32(pSSM, cDisplays); 2756 AssertRCReturn(rc, rc); 2757 2758 if (!cDisplays) 2759 return VINF_SUCCESS; 2760 2761 rc = SSMR3PutS32(pSSM, cr_server.screenCount); 2762 AssertRCReturn(rc, rc); 2763 2764 for (i = 0; i < cr_server.screenCount; ++i) 2765 { 2766 rc = SSMR3PutS32(pSSM, cr_server.screen[i].x); 2767 AssertRCReturn(rc, rc); 2768 2769 rc = SSMR3PutS32(pSSM, cr_server.screen[i].y); 2770 AssertRCReturn(rc, rc); 2771 2772 rc = SSMR3PutU32(pSSM, cr_server.screen[i].w); 2773 AssertRCReturn(rc, rc); 2774 2775 rc = SSMR3PutU32(pSSM, cr_server.screen[i].h); 2776 AssertRCReturn(rc, rc); 2777 } 2778 2779 for (i = 0; i < cr_server.screenCount; ++i) 2780 { 2781 if (ASMBitTest(cr_server.DisplaysInitMap, i) && !CrDpIsEmpty(&cr_server.aDispplays[i])) 2782 { 2783 rc = SSMR3PutS32(pSSM, i); 2784 AssertRCReturn(rc, rc); 2785 2786 rc = CrDpSaveState(&cr_server.aDispplays[i], pSSM); 2787 AssertRCReturn(rc, rc); 2788 } 2789 } 2790 2791 return VINF_SUCCESS; 2792 } 2793 2794 int crServerDisplayLoadState(PSSMHANDLE pSSM, uint32_t u32Version) 2795 { 2796 2797 } 2798 #endif 2825 2826 memset(&g_CrPresenter, 0, sizeof (g_CrPresenter)); 2827 } 2799 2828 2800 2829 HCR_FRAMEBUFFER CrPMgrFbGet(uint32_t idScreen) … … 2806 2835 } 2807 2836 2808 if (! ASMBitTest(g_CrPresenter.aFramebufferInitMap, idScreen))2837 if (!CrFBmIsSet(&g_CrPresenter.FramebufferInitMap, idScreen)) 2809 2838 { 2810 2839 CrFbInit(&g_CrPresenter.aFramebuffers[idScreen], idScreen); 2811 ASMBitSet(g_CrPresenter.aFramebufferInitMap, idScreen);2840 CrFBmSet(&g_CrPresenter.FramebufferInitMap, idScreen); 2812 2841 } 2813 2842 else … … 2817 2846 } 2818 2847 2819 HCR_FRAMEBUFFER CrPMgrFbGet Enabled(uint32_t idScreen)2848 HCR_FRAMEBUFFER CrPMgrFbGetInitialized(uint32_t idScreen) 2820 2849 { 2821 2850 if (idScreen >= CR_MAX_GUEST_MONITORS) … … 2825 2854 } 2826 2855 2827 if (! ASMBitTest(g_CrPresenter.aFramebufferInitMap, idScreen))2856 if (!CrFBmIsSet(&g_CrPresenter.FramebufferInitMap, idScreen)) 2828 2857 { 2829 2858 return NULL; … … 2832 2861 Assert(g_CrPresenter.aFramebuffers[idScreen].ScreenInfo.u32ViewIndex == idScreen); 2833 2862 2834 HCR_FRAMEBUFFER hFb = &g_CrPresenter.aFramebuffers[idScreen]; 2835 2836 if(CrFbIsEnabled(hFb)) 2863 return &g_CrPresenter.aFramebuffers[idScreen]; 2864 } 2865 2866 HCR_FRAMEBUFFER CrPMgrFbGetEnabled(uint32_t idScreen) 2867 { 2868 HCR_FRAMEBUFFER hFb = CrPMgrFbGetInitialized(idScreen); 2869 2870 if(hFb && CrFbIsEnabled(hFb)) 2837 2871 return hFb; 2838 2872 … … 2845 2879 { 2846 2880 HCR_FRAMEBUFFER hFb = CrPMgrFbGetEnabled(i); 2881 if (hFb) 2882 return hFb; 2883 } 2884 2885 return NULL; 2886 } 2887 2888 static HCR_FRAMEBUFFER crPMgrFbGetNextInitialized(uint32_t i) 2889 { 2890 for (;i < cr_server.screenCount; ++i) 2891 { 2892 HCR_FRAMEBUFFER hFb = CrPMgrFbGetInitialized(i); 2847 2893 if (hFb) 2848 2894 return hFb; … … 2863 2909 { 2864 2910 return crPMgrFbGetNextEnabled(hFb->ScreenInfo.u32ViewIndex+1); 2911 } 2912 2913 HCR_FRAMEBUFFER CrPMgrFbGetFirstInitialized() 2914 { 2915 HCR_FRAMEBUFFER hFb = crPMgrFbGetNextInitialized(0); 2916 // if (!hFb) 2917 // WARN(("no initialized framebuffer found")); 2918 return hFb; 2919 } 2920 2921 HCR_FRAMEBUFFER CrPMgrFbGetNextInitialized(HCR_FRAMEBUFFER hFb) 2922 { 2923 return crPMgrFbGetNextInitialized(hFb->ScreenInfo.u32ViewIndex+1); 2865 2924 } 2866 2925 … … 3111 3170 3112 3171 /*helper function that calls CrFbUpdateBegin for all enabled framebuffers */ 3113 int CrPMgrHlpGlblUpdateBegin() 3114 { 3172 int CrPMgrHlpGlblUpdateBegin(CR_FBMAP *pMap) 3173 { 3174 CrFBmInit(pMap); 3115 3175 for (HCR_FRAMEBUFFER hFb = CrPMgrFbGetFirstEnabled(); 3116 3176 hFb; … … 3126 3186 { 3127 3187 CrFbUpdateEnd(hTmpFb); 3188 CrFBmClear(pMap, CrFbGetScreenInfo(hFb)->u32ViewIndex); 3128 3189 } 3129 3190 return rc; 3130 3191 } 3192 3193 CrFBmSet(pMap, CrFbGetScreenInfo(hFb)->u32ViewIndex); 3131 3194 } 3132 3195 … … 3135 3198 3136 3199 /*helper function that calls CrFbUpdateEnd for all framebuffers being updated */ 3137 void CrPMgrHlpGlblUpdateEnd( )3200 void CrPMgrHlpGlblUpdateEnd(CR_FBMAP *pMap) 3138 3201 { 3139 3202 for (uint32_t i = 0; i < cr_server.screenCount; ++i) 3140 3203 { 3141 HCR_FRAMEBUFFER hFb = CrPMgrFbGet(i); 3142 Assert(hFb); 3143 if (CrFbIsUpdating(hFb)) 3144 CrFbUpdateEnd(hFb); 3204 if (!CrFBmIsSet(pMap, i)) 3205 continue; 3206 3207 HCR_FRAMEBUFFER hFb = CrPMgrFbGetInitialized(i); 3208 CRASSERT(hFb); 3209 CrFbUpdateEnd(hFb); 3145 3210 } 3146 3211 } -
trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c
r50095 r50123 310 310 311 311 crHashtableDelete(cr_server.muralTable, window, crFree); 312 313 crServerCheckAllMuralGeometry(NULL); 312 314 } 313 315 … … 329 331 } 330 332 331 crServerCheck MuralGeometry(mural);333 crServerCheckAllMuralGeometry(mural); 332 334 333 335 return GL_TRUE; … … 364 366 mural->gY = y; 365 367 366 crServerCheck MuralGeometry(mural);368 crServerCheckAllMuralGeometry(mural); 367 369 } 368 370 … … 400 402 } 401 403 402 crServerCheck MuralGeometry(mural);404 crServerCheckAllMuralGeometry(mural); 403 405 } 404 406 … … 422 424 return; 423 425 424 crServerCheckMuralGeometry(mural); 426 if (mural->bVisible) 427 crServerCheckMuralGeometry(mural); 428 else 429 crServerCheckAllMuralGeometry(mural); 425 430 } 426 431
Note:
See TracChangeset
for help on using the changeset viewer.