VirtualBox

Changeset 50123 in vbox for trunk


Ignore:
Timestamp:
Jan 20, 2014 4:30:32 PM (11 years ago)
Author:
vboxsync
Message:

crOpenGL: bugfixes

Location:
trunk/src/VBox/HostServices/SharedOpenGL/crserverlib
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h

    r50095 r50123  
    132132
    133133void crServerCheckMuralGeometry(CRMuralInfo *mural);
     134void crServerCheckAllMuralGeometry(CRMuralInfo *pMI);
    134135GLboolean crServerSupportRedirMuralFBO(void);
    135136
     
    150151GLint crServerMuralFBOIdxFromBufferName(CRMuralInfo *mural, GLenum buffer);
    151152void crServerMuralFBOSwapBuffers(CRMuralInfo *mural);
     153
     154HCR_FRAMEBUFFER CrPMgrFbGetFirstEnabled();
     155HCR_FRAMEBUFFER CrPMgrFbGetNextEnabled(HCR_FRAMEBUFFER hFb);
     156HCR_FRAMEBUFFER CrPMgrFbGetFirstInitialized();
     157HCR_FRAMEBUFFER CrPMgrFbGetNextInitialized(HCR_FRAMEBUFFER hFb);
    152158
    153159
     
    364370int crServerVBoxParseNumerics(const char *pszStr, const int defaultVal);
    365371
     372typedef struct CR_FBMAP
     373{
     374    uint8_t Map[(CR_MAX_GUEST_MONITORS+7)/8];
     375} CR_FBMAP;
     376
     377DECLINLINE(void) CrFBmInit(CR_FBMAP *pMap)
     378{
     379    memset(pMap, 0, sizeof (*pMap));
     380}
     381
     382DECLINLINE(bool) CrFBmIsSet(CR_FBMAP *pMap, uint32_t i)
     383{
     384    return ASMBitTest(&pMap->Map, i);
     385}
     386
     387DECLINLINE(void) CrFBmSet(CR_FBMAP *pMap, uint32_t i)
     388{
     389    return ASMBitSet(&pMap->Map, i);
     390}
     391
     392DECLINLINE(void) CrFBmClear(CR_FBMAP *pMap, uint32_t i)
     393{
     394    return ASMBitClear(&pMap->Map, i);
     395}
     396
    366397/*helper function that calls CrFbUpdateBegin for all enabled framebuffers */
    367 int CrPMgrHlpGlblUpdateBegin();
     398int CrPMgrHlpGlblUpdateBegin(CR_FBMAP *pMap);
    368399/*helper function that calls CrFbUpdateEnd for all framebuffers being updated */
    369 void CrPMgrHlpGlblUpdateEnd();
     400void CrPMgrHlpGlblUpdateEnd(CR_FBMAP *pMap);
    370401HCR_FRAMEBUFFER CrPMgrFbGetFirstEnabled();
    371402HCR_FRAMEBUFFER CrPMgrFbGetNextEnabled(HCR_FRAMEBUFFER hFb);
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.cpp

    r50095 r50123  
    4747    crServerRedirMuralFBO(mural, true);
    4848    crServerRedirMuralFbSync(mural);
     49}
     50
     51static 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
     62void 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);
    4978}
    5079
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp

    r50108 r50123  
    101101    CRHashTable *pFbTexMap;
    102102    CR_FBDISPLAY_INFO aDisplayInfos[CR_MAX_GUEST_MONITORS];
    103     uint8_t aFramebufferInitMap[(CR_MAX_GUEST_MONITORS+7)/8];
     103    CR_FBMAP FramebufferInitMap;
    104104    CR_FRAMEBUFFER aFramebuffers[CR_MAX_GUEST_MONITORS];
    105105} CR_PRESENTER_GLOBALS;
     
    215215        return;
    216216    }
     217    uint32_t idScreen = pFb->ScreenInfo.u32ViewIndex;
     218
    217219    CrVrScrCompositorClear(&pFb->Compositor);
    218220    CrHTableDestroy(&pFb->SlotTable);
    219221    memset(pFb, 0, sizeof (*pFb));
     222
     223    pFb->ScreenInfo.u16Flags = VBVA_SCREEN_F_DISABLED;
     224    pFb->ScreenInfo.u32ViewIndex = idScreen;
    220225}
    221226
     
    277282
    278283static int crPMgrModeModifyGlobal(uint32_t u32Mode, bool fEnable);
     284
     285static 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
     294static 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
     303static 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
     312static 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
     322DECLCALLBACK(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
     353void 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
     360static 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
     376CR_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
     388static 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
     445static 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
     455static 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
     463DECLINLINE(uint32_t) crFbEntryAddRef(CR_FRAMEBUFFER_ENTRY* pEntry)
     464{
     465    return ++pEntry->cRefs;
     466}
     467
     468DECLINLINE(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
     476static 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
     506static 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
     523int 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
     541int 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
     562int 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
     583void CrFbEntryAddRef(CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry)
     584{
     585    ++hEntry->cRefs;
     586}
     587
     588void CrFbEntryRelease(CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry)
     589{
     590    crFbEntryRelease(pFb, hEntry);
     591}
     592
     593int 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
     612int 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
     678int 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
     735const struct VBOXVR_SCR_COMPOSITOR_ENTRY* CrFbEntryGetCompositorEntry(HCR_FRAMEBUFFER_ENTRY hEntry)
     736{
     737    return &hEntry->Entry;
     738}
     739
     740HCR_FRAMEBUFFER_ENTRY CrFbEntryFromCompositorEntry(const struct VBOXVR_SCR_COMPOSITOR_ENTRY* pCEntry)
     741{
     742    return RT_FROM_MEMBER(pCEntry, CR_FRAMEBUFFER_ENTRY, Entry);
     743}
     744
     745CRHTABLE_HANDLE CrFbDDataAllocSlot(CR_FRAMEBUFFER *pFb)
     746{
     747    return CrHTablePut(&pFb->SlotTable, (void*)1);
     748}
     749
     750void CrFbDDataReleaseSlot(CR_FRAMEBUFFER *pFb, CRHTABLE_HANDLE hSlot)
     751{
     752    CrHTableRemove(&pFb->SlotTable, hSlot);
     753}
     754
     755int CrFbDDataEntryPut(HCR_FRAMEBUFFER_ENTRY hEntry, CRHTABLE_HANDLE hSlot, void *pvData)
     756{
     757    return CrHTablePutToSlot(&hEntry->HTable, hSlot, pvData);
     758}
     759
     760void* CrFbDDataEntryGet(HCR_FRAMEBUFFER_ENTRY hEntry, CRHTABLE_HANDLE hSlot)
     761{
     762    return CrHTableGet(&hEntry->HTable, hSlot);
     763}
     764
     765class CrFbDisplayBase : public ICrFbDisplay
     766{
     767public:
     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;
     948protected:
     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
     1041private:
     1042    struct CR_FRAMEBUFFER *mpFb;
     1043    uint32_t mcUpdates;
     1044    CRHTABLE_HANDLE mhSlot;
     1045};
     1046
     1047class CrFbDisplayComposite : public CrFbDisplayBase
     1048{
     1049public:
     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    }
     1348private:
     1349    RTLISTNODE mDisplays;
     1350    uint32_t mcDisplays;
     1351};
     1352
     1353typedef 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
     1365class CrFbWindow
     1366{
     1367public:
     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    }
     1595protected:
     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    }
     1642private:
     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
     1654class CrFbDisplayWindow : public CrFbDisplayBase
     1655{
     1656public:
     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
     1878protected:
     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;}
     2008private:
     2009    CrFbWindow *mpWindow;
     2010    RTRECT mViewportRect;
     2011};
     2012
     2013class CrFbDisplayWindowRootVr : public CrFbDisplayWindow
     2014{
     2015public:
     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
     2165protected:
     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    }
     2323private:
     2324    VBOXVR_SCR_COMPOSITOR mCompositor;
     2325    RTPOINT mPos;
     2326};
     2327
     2328class CrFbDisplayVrdp : public CrFbDisplayBase
     2329{
     2330public:
     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
     2452protected:
     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    }
     2485protected:
     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    }
     2637private:
     2638    RTPOINT mPos;
     2639};
     2640
     2641CrFbDisplayBase::~CrFbDisplayBase()
     2642{
     2643    Assert(!mcUpdates);
     2644
     2645    if (mpContainer)
     2646        mpContainer->remove(this);
     2647}
     2648
     2649
     2650#if 0
     2651
     2652
     2653
     2654
     2655
     2656void 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
     2661void 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
     2671int 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
     2720int crServerDisplayLoadState(PSSMHANDLE pSSM, uint32_t u32Version)
     2721{
     2722
     2723}
     2724#endif
    2792725
    2802726int CrPMgrInit()
     
    3492795void CrPMgrTerm()
    3502796{
     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
    3512819#ifndef VBOXVDBG_MEMCACHE_DISABLE
    3522820    RTMemCacheDestroy(g_CrPresenter.FbEntryLookasideList);
     
    3552823#endif
    3562824    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}
    27992828
    28002829HCR_FRAMEBUFFER CrPMgrFbGet(uint32_t idScreen)
     
    28062835    }
    28072836
    2808     if (!ASMBitTest(g_CrPresenter.aFramebufferInitMap, idScreen))
     2837    if (!CrFBmIsSet(&g_CrPresenter.FramebufferInitMap, idScreen))
    28092838    {
    28102839        CrFbInit(&g_CrPresenter.aFramebuffers[idScreen], idScreen);
    2811         ASMBitSet(g_CrPresenter.aFramebufferInitMap, idScreen);
     2840        CrFBmSet(&g_CrPresenter.FramebufferInitMap, idScreen);
    28122841    }
    28132842    else
     
    28172846}
    28182847
    2819 HCR_FRAMEBUFFER CrPMgrFbGetEnabled(uint32_t idScreen)
     2848HCR_FRAMEBUFFER CrPMgrFbGetInitialized(uint32_t idScreen)
    28202849{
    28212850    if (idScreen >= CR_MAX_GUEST_MONITORS)
     
    28252854    }
    28262855
    2827     if (!ASMBitTest(g_CrPresenter.aFramebufferInitMap, idScreen))
     2856    if (!CrFBmIsSet(&g_CrPresenter.FramebufferInitMap, idScreen))
    28282857    {
    28292858        return NULL;
     
    28322861        Assert(g_CrPresenter.aFramebuffers[idScreen].ScreenInfo.u32ViewIndex == idScreen);
    28332862
    2834     HCR_FRAMEBUFFER hFb = &g_CrPresenter.aFramebuffers[idScreen];
    2835 
    2836     if(CrFbIsEnabled(hFb))
     2863    return &g_CrPresenter.aFramebuffers[idScreen];
     2864}
     2865
     2866HCR_FRAMEBUFFER CrPMgrFbGetEnabled(uint32_t idScreen)
     2867{
     2868    HCR_FRAMEBUFFER hFb = CrPMgrFbGetInitialized(idScreen);
     2869
     2870    if(hFb && CrFbIsEnabled(hFb))
    28372871        return hFb;
    28382872
     
    28452879    {
    28462880        HCR_FRAMEBUFFER hFb = CrPMgrFbGetEnabled(i);
     2881        if (hFb)
     2882            return hFb;
     2883    }
     2884
     2885    return NULL;
     2886}
     2887
     2888static HCR_FRAMEBUFFER crPMgrFbGetNextInitialized(uint32_t i)
     2889{
     2890    for (;i < cr_server.screenCount; ++i)
     2891    {
     2892        HCR_FRAMEBUFFER hFb = CrPMgrFbGetInitialized(i);
    28472893        if (hFb)
    28482894            return hFb;
     
    28632909{
    28642910    return crPMgrFbGetNextEnabled(hFb->ScreenInfo.u32ViewIndex+1);
     2911}
     2912
     2913HCR_FRAMEBUFFER CrPMgrFbGetFirstInitialized()
     2914{
     2915    HCR_FRAMEBUFFER hFb = crPMgrFbGetNextInitialized(0);
     2916//    if (!hFb)
     2917//        WARN(("no initialized framebuffer found"));
     2918    return hFb;
     2919}
     2920
     2921HCR_FRAMEBUFFER CrPMgrFbGetNextInitialized(HCR_FRAMEBUFFER hFb)
     2922{
     2923    return crPMgrFbGetNextInitialized(hFb->ScreenInfo.u32ViewIndex+1);
    28652924}
    28662925
     
    31113170
    31123171/*helper function that calls CrFbUpdateBegin for all enabled framebuffers */
    3113 int CrPMgrHlpGlblUpdateBegin()
    3114 {
     3172int CrPMgrHlpGlblUpdateBegin(CR_FBMAP *pMap)
     3173{
     3174    CrFBmInit(pMap);
    31153175    for (HCR_FRAMEBUFFER hFb = CrPMgrFbGetFirstEnabled();
    31163176            hFb;
     
    31263186            {
    31273187                CrFbUpdateEnd(hTmpFb);
     3188                CrFBmClear(pMap, CrFbGetScreenInfo(hFb)->u32ViewIndex);
    31283189            }
    31293190            return rc;
    31303191        }
     3192
     3193        CrFBmSet(pMap, CrFbGetScreenInfo(hFb)->u32ViewIndex);
    31313194    }
    31323195
     
    31353198
    31363199/*helper function that calls CrFbUpdateEnd for all framebuffers being updated */
    3137 void CrPMgrHlpGlblUpdateEnd()
     3200void CrPMgrHlpGlblUpdateEnd(CR_FBMAP *pMap)
    31383201{
    31393202    for (uint32_t i = 0; i < cr_server.screenCount; ++i)
    31403203    {
    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);
    31453210    }
    31463211}
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c

    r50095 r50123  
    310310
    311311    crHashtableDelete(cr_server.muralTable, window, crFree);
     312
     313    crServerCheckAllMuralGeometry(NULL);
    312314}
    313315
     
    329331    }
    330332
    331     crServerCheckMuralGeometry(mural);
     333    crServerCheckAllMuralGeometry(mural);
    332334
    333335    return GL_TRUE;
     
    364366    mural->gY = y;
    365367
    366     crServerCheckMuralGeometry(mural);
     368    crServerCheckAllMuralGeometry(mural);
    367369}
    368370
     
    400402    }
    401403
    402     crServerCheckMuralGeometry(mural);
     404    crServerCheckAllMuralGeometry(mural);
    403405}
    404406
     
    422424        return;
    423425
    424     crServerCheckMuralGeometry(mural);
     426    if (mural->bVisible)
     427        crServerCheckMuralGeometry(mural);
     428    else
     429        crServerCheckAllMuralGeometry(mural);
    425430}
    426431
Note: See TracChangeset for help on using the changeset viewer.

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