VirtualBox

Changeset 50095 in vbox for trunk


Ignore:
Timestamp:
Jan 17, 2014 4:34:07 PM (11 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
91620
Message:

crOpenGL: presentation infrastructure rework (still work in progress)

Location:
trunk
Files:
42 edited
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/HostServices/VBoxCrOpenGLSvc.h

    r49474 r50095  
    4444#define SHCRGL_HOST_FN_VIEWPORT_CHANGED (15)
    4545#define SHCRGL_HOST_FN_SET_OUTPUT_REDIRECT (20)
    46 #define SHCRGL_HOST_FN_CRCMD_NOTIFY_CMDS    (21)
     46#define SHCRGL_HOST_FN_CRCMD_NOTIFY_CMDS   (21)
     47#define SHCRGL_HOST_FN_DEV_RESIZE          (22)
    4748/* crOpenGL guest functions */
    4849#define SHCRGL_GUEST_FN_WRITE       (2)
     
    6566#define SHCRGL_CPARMS_SET_VERSION (2)
    6667#define SHCRGL_CPARMS_SCREEN_CHANGED (1)
     68#define SHCRGL_CPARMS_DEV_RESIZE (2)
    6769#define SHCRGL_CPARMS_INJECT (2)
    6870#define SHCRGL_CPARMS_SET_PID (1)
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.cpp

    r49591 r50095  
    198198//    vboxMpCrShgsmiBufCacheTerm(pCon, &pCon->CmdDrCache);
    199199}
    200 
    201 //typedef struct VBOXMP_CRHGSMICMD_HDR
    202 //{
    203 //    union
    204 //    {
    205 //        PFNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEREADASYNC_COMPLETION pfnWriteReadCompletion;
    206 //        PFNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEASYNC_COMPLETION pfnWriteCompletion;
    207 //    };
    208 //} VBOXMP_CRHGSMICMD_HDR, *PVBOXMP_CRHGSMICMD_HDR;
    209200
    210201typedef struct VBOXMP_CRHGSMICMD_BASE
     
    900891    if (RT_FAILURE(rc))
    901892        WARN(("VBoxMpCrCtlConDisconnect failed rc (%d), ignoring..", rc));
    902 #else
    903893#endif
    904894}
  • trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_misc.c

    r46059 r50095  
    723723#endif /*CHROMIUM_THREADSAFE*/
    724724
    725 void PACKSPU_APIENTRY packspu_VBoxPresentComposition(GLint win, struct VBOXVR_SCR_COMPOSITOR * pCompositor, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry)
     725void PACKSPU_APIENTRY packspu_VBoxPresentComposition(GLint win, const struct VBOXVR_SCR_COMPOSITOR * pCompositor, const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry)
    726726{
    727727}
  • trunk/src/VBox/GuestHost/OpenGL/Makefile.kmk

    r50041 r50095  
    8585        util/vreg.cpp \
    8686        util/blitter.cpp \
     87        util/compositor.cpp \
     88        util/htable.cpp \
    8789        util/vboxhgcm.c \
    8890        $(VBOX_PATH_CROGL_GENFILES)/debug_opcodes.c
  • trunk/src/VBox/GuestHost/OpenGL/glapi_parser/APIspec.txt

    r50041 r50095  
    85958595return      void
    85968596param       win              GLint
    8597 param       pCompositor      struct VBOXVR_SCR_COMPOSITOR *
    8598 param       pChangedEntry    struct VBOXVR_SCR_COMPOSITOR_ENTRY *
     8597param       pCompositor      const struct VBOXVR_SCR_COMPOSITOR *
     8598param       pChangedEntry    const struct VBOXVR_SCR_COMPOSITOR_ENTRY *
    85998599category    VBox
    86008600chromium    nopack
  • trunk/src/VBox/GuestHost/OpenGL/include/chromium.h

    r50041 r50095  
    727727#define GL_HH_SET_DEFAULT_SHARED_CTX  0x8B2D
    728728
     729#define GL_HH_SET_TMPCTX_MAKE_CURRENT 0x8B2E
     730
    729731/**********************************************************************/
    730732/*****                Chromium-specific API                       *****/
  • trunk/src/VBox/GuestHost/OpenGL/include/cr_blitter.h

    r48348 r50095  
    1919
    2020#include <iprt/cdefs.h>
     21#include <iprt/asm.h>
    2122#include "cr_spu.h"
    2223#include "cr_vreg.h"
     
    7475        uint32_t CtxCreated          : 1;
    7576        uint32_t SupportsFBO         : 1;
     77        uint32_t SupportsPBO         : 1;
    7678        uint32_t CurrentMuralChanged : 1;
    7779        uint32_t LastWasFBODraw      : 1;
    7880        uint32_t ForceDrawBlit       : 1;
    7981        uint32_t ShadersGloal        : 1;
    80         uint32_t Reserved            : 25;
     82        uint32_t Entered             : 1;
     83        uint32_t Reserved            : 23;
    8184    };
    8285    uint32_t Value;
     
    125128    CR_BLITTER_WINDOW CurrentMural;
    126129    CR_BLITTER_CONTEXT CtxInfo;
    127     const CR_BLITTER_CONTEXT *pRestoreCtxInfo;
    128     const CR_BLITTER_WINDOW *pRestoreMural;
    129130    int32_t i32MakeCurrentUserData;
    130131    SPUDispatchTable *pDispatch;
     
    142143VBOXBLITTERDECL(void) CrBltTerm(PCR_BLITTER pBlitter);
    143144
    144 VBOXBLITTERDECL(int) CrBltCleanup(PCR_BLITTER pBlitter, const CR_BLITTER_CONTEXT *pRestoreCtxInfo, const CR_BLITTER_WINDOW *pRestoreMural);
     145VBOXBLITTERDECL(int) CrBltCleanup(PCR_BLITTER pBlitter);
    145146
    146147DECLINLINE(GLboolean) CrBltSupportsTexTex(PCR_BLITTER pBlitter)
     
    151152DECLINLINE(GLboolean) CrBltIsEntered(PCR_BLITTER pBlitter)
    152153{
    153     return !!pBlitter->pRestoreCtxInfo;
     154    return pBlitter->Flags.Entered;
    154155}
    155156
     
    170171}
    171172
    172 VBOXBLITTERDECL(int) CrBltMuralSetCurrent(PCR_BLITTER pBlitter, const CR_BLITTER_WINDOW *pMural);
     173VBOXBLITTERDECL(int) CrBltMuralSetCurrentInfo(PCR_BLITTER pBlitter, const CR_BLITTER_WINDOW *pMural);
    173174DECLINLINE(const CR_BLITTER_WINDOW *) CrBltMuralGetCurrentInfo(PCR_BLITTER pBlitter)
    174175{
     
    179180
    180181VBOXBLITTERDECL(void) CrBltLeave(PCR_BLITTER pBlitter);
    181 VBOXBLITTERDECL(int) CrBltEnter(PCR_BLITTER pBlitter, const CR_BLITTER_CONTEXT *pRestoreCtxInfo, const CR_BLITTER_WINDOW *pRestoreMural);
     182VBOXBLITTERDECL(int) CrBltEnter(PCR_BLITTER pBlitter);
    182183VBOXBLITTERDECL(void) CrBltBlitTexMural(PCR_BLITTER pBlitter, bool fBb, const VBOXVR_TEXTURE *pSrc, const RTRECT *paSrcRects, const RTRECT *paDstRects, uint32_t cRects, uint32_t fFlags);
    183184VBOXBLITTERDECL(void) CrBltBlitTexTex(PCR_BLITTER pBlitter, const VBOXVR_TEXTURE *pSrc, const RTRECT *pSrcRect, const VBOXVR_TEXTURE *pDst, const RTRECT *pDstRect, uint32_t cRects, uint32_t fFlags);
     
    188189VBOXBLITTERDECL(void) CrBltPresent(PCR_BLITTER pBlitter);
    189190/* */
     191struct CR_TEXDATA;
     192
     193typedef DECLCALLBACK(void) FNCRTEXDATA_RELEASED(struct CR_TEXDATA *pTexture);
     194typedef FNCRTEXDATA_RELEASED *PFNCRTEXDATA_RELEASED;
     195
     196typedef union CR_TEXDATA_FLAGS
     197{
     198    struct
     199    {
     200        uint32_t DataInverted        : 1;
     201        uint32_t Entered             : 1;
     202        uint32_t BltEntered          : 1;
     203        uint32_t Reserved            : 29;
     204    };
     205    uint32_t Value;
     206} CR_TEXDATA_FLAGS, *PCR_TEXDATA_FLAGS;
     207
     208
     209typedef struct CR_TEXDATA
     210{
     211    VBOXVR_TEXTURE Tex;
     212    volatile uint32_t cRefs;
     213    /* fields specific to texture data download */
     214    uint32_t idInvertTex;
     215    uint32_t idPBO;
     216    CR_TEXDATA_FLAGS Flags;
     217    PCR_BLITTER pBlitter;
     218    CR_BLITTER_IMG Img;
     219    /*dtor*/
     220    PFNCRTEXDATA_RELEASED pfnTextureReleased;
     221} CR_TEXDATA, *PCR_TEXDATA;
     222
     223DECLINLINE(void) CrTdInit(PCR_TEXDATA pTex, const VBOXVR_TEXTURE *pVrTex, PCR_BLITTER pBlitter, PFNCRTEXDATA_RELEASED pfnTextureReleased)
     224{
     225    memset(pTex, 0, sizeof (*pTex));
     226    pTex->Tex = *pVrTex;
     227    pTex->cRefs = 1;
     228    pTex->pBlitter = pBlitter;
     229    pTex->pfnTextureReleased = pfnTextureReleased;
     230}
     231
     232DECLINLINE(const VBOXVR_TEXTURE*) CrTdTexGet(const CR_TEXDATA *pTex)
     233{
     234    return &pTex->Tex;
     235}
     236
     237DECLINLINE(int) CrTdBltEnter(PCR_TEXDATA pTex)
     238{
     239        if (pTex->Flags.Entered)
     240                return VERR_INVALID_STATE;
     241        if (!CrBltIsEntered(pTex->pBlitter))
     242        {
     243                int rc = CrBltEnter(pTex->pBlitter);
     244                if (!RT_SUCCESS(rc))
     245                {
     246                        crWarning("CrBltEnter failed rc %d", rc);
     247                        return rc;
     248                }
     249                pTex->Flags.BltEntered = 1;
     250        }
     251        pTex->Flags.Entered = 1;
     252        return VINF_SUCCESS;
     253}
     254
     255DECLINLINE(bool) CrTdBltIsEntered(PCR_TEXDATA pTex)
     256{
     257        return pTex->Flags.Entered;
     258}
     259
     260DECLINLINE(void) CrTdBltLeave(PCR_TEXDATA pTex)
     261{
     262        if (!pTex->Flags.Entered)
     263        {
     264                crWarning("invalid Blt Leave");
     265                return;
     266        }
     267
     268        if (pTex->Flags.BltEntered)
     269        {
     270                CrBltLeave(pTex->pBlitter);
     271                pTex->Flags.BltEntered = 0;
     272        }
     273
     274        pTex->Flags.Entered = 0;
     275}
     276
     277/* the CrTdBltXxx calls are done with the entered blitter */
     278/* acquire the texture data, returns the cached data in case it is cached.
     279 * the data remains cached in the CR_TEXDATA object until it is discarded with CrTdBltDataDiscard or CrTdBltDataCleanup.
     280 * */
     281VBOXBLITTERDECL(int) CrTdBltDataAcquire(PCR_TEXDATA pTex, GLenum enmFormat, bool fInverted, const CR_BLITTER_IMG**ppImg);
     282/* release the texture data, the data remains cached in the CR_TEXDATA object until it is discarded with CrTdBltDataDiscard or CrTdBltDataCleanup */
     283VBOXBLITTERDECL(void) CrTdBltDataRelease(PCR_TEXDATA pTex);
     284/* discard the texture data cached with previous CrTdBltDataAcquire.
     285 * Must be called wit data released (CrTdBltDataRelease) */
     286VBOXBLITTERDECL(void) CrTdBltDataDiscard(PCR_TEXDATA pTex);
     287/* does same as CrTdBltDataDiscard, and in addition cleans up.
     288 * this is kind of a texture destructor, which clients should call on texture object destruction, e.g. from the PFNCRTEXDATA_RELEASED callback */
     289VBOXBLITTERDECL(void) CrTdBltDataCleanup(PCR_TEXDATA pTex);
     290
     291DECLINLINE(uint32_t) CrTdAddRef(PCR_TEXDATA pTex)
     292{
     293    return ASMAtomicIncU32(&pTex->cRefs);
     294}
     295
     296DECLINLINE(uint32_t) CrTdRelease(PCR_TEXDATA pTex)
     297{
     298    uint32_t cRefs = ASMAtomicDecU32(&pTex->cRefs);
     299    if (!cRefs)
     300    {
     301        if (pTex->pfnTextureReleased)
     302            pTex->pfnTextureReleased(pTex);
     303        else
     304            CrTdBltDataCleanup(pTex);
     305        }
     306
     307    return cRefs;
     308}
    190309
    191310RT_C_DECLS_END
  • trunk/src/VBox/GuestHost/OpenGL/include/cr_compositor.h

    r49773 r50095  
    2323/* Compositor with Stretching & Cached Rectangles info */
    2424
     25RT_C_DECLS_BEGIN
     26
    2527struct VBOXVR_SCR_COMPOSITOR_ENTRY;
    2628struct VBOXVR_SCR_COMPOSITOR;
     
    122124}
    123125
    124 VBOXVREGDECL(int) CrVrScrCompositorEntryResize(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTRECT *pRect);
     126VBOXVREGDECL(int) CrVrScrCompositorEntryRectSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTRECT *pRect);
    125127VBOXVREGDECL(int) CrVrScrCompositorEntryTexAssign(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, CR_TEXDATA *pTex);
    126128VBOXVREGDECL(void) CrVrScrCompositorVisit(PVBOXVR_SCR_COMPOSITOR pCompositor, PFNVBOXVRSCRCOMPOSITOR_VISITOR pfnVisitor, void *pvVisitor);
     
    143145
    144146/* regions are valid until the next CrVrScrCompositor call */
    145 VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsGet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t *pcRegions, const RTRECT **ppaSrcRegions, const RTRECT **ppaDstRegions, const RTRECT **ppaDstUnstretchedRects);
     147VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsGet(const VBOXVR_SCR_COMPOSITOR *pCompositor, const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry, uint32_t *pcRegions, const RTRECT **ppaSrcRegions, const RTRECT **ppaDstRegions, const RTRECT **ppaDstUnstretchedRects);
    146148VBOXVREGDECL(int) CrVrScrCompositorEntryRemove(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry);
    147149VBOXVREGDECL(bool) CrVrScrCompositorEntryReplace(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, PVBOXVR_SCR_COMPOSITOR_ENTRY pNewEntry);
    148150VBOXVREGDECL(void) CrVrScrCompositorEntryFlagsSet(PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t fFlags);
    149 VBOXVREGDECL(uint32_t) CrVrScrCompositorEntryFlagsCombinedGet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry);
     151VBOXVREGDECL(uint32_t) CrVrScrCompositorEntryFlagsCombinedGet(const VBOXVR_SCR_COMPOSITOR *pCompositor, const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry);
    150152DECLINLINE(uint32_t) CrVrScrCompositorEntryFlagsGet(const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry)
    151153{
     
    166168typedef FNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR *PFNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR;
    167169
    168 VBOXVREGDECL(int) CrVrScrCompositorClone(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR pDstCompositor, PFNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR pfnEntryFor, void* pvEntryFor);
     170VBOXVREGDECL(int) CrVrScrCompositorClone(const VBOXVR_SCR_COMPOSITOR *pCompositor, PVBOXVR_SCR_COMPOSITOR pDstCompositor, PFNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR pfnEntryFor, void* pvEntryFor);
    169171VBOXVREGDECL(int) CrVrScrCompositorIntersectList(PVBOXVR_SCR_COMPOSITOR pCompositor, const VBOXVR_LIST *pVr, bool *pfChanged);
    170 VBOXVREGDECL(int) CrVrScrCompositorIntersectedList(PVBOXVR_SCR_COMPOSITOR pCompositor, const VBOXVR_LIST *pVr, PVBOXVR_SCR_COMPOSITOR pDstCompositor, PFNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR pfnEntryFor, void* pvEntryFor, bool *pfChanged);
     172VBOXVREGDECL(int) CrVrScrCompositorIntersectedList(const VBOXVR_SCR_COMPOSITOR *pCompositor, const VBOXVR_LIST *pVr, PVBOXVR_SCR_COMPOSITOR pDstCompositor, PFNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR pfnEntryFor, void* pvEntryFor, bool *pfChanged);
    171173#ifndef IN_RING0
    172174VBOXVREGDECL(void) CrVrScrCompositorSetStretching(PVBOXVR_SCR_COMPOSITOR pCompositor, float StretchX, float StretchY);
    173 DECLINLINE(void) CrVrScrCompositorGetStretching(PVBOXVR_SCR_COMPOSITOR pCompositor, float *pStretchX, float *pStretchY)
     175DECLINLINE(void) CrVrScrCompositorGetStretching(const VBOXVR_SCR_COMPOSITOR *pCompositor, float *pStretchX, float *pStretchY)
    174176{
    175177    if (pStretchX)
     
    181183#endif
    182184/* regions are valid until the next CrVrScrCompositor call */
    183 VBOXVREGDECL(int) CrVrScrCompositorRegionsGet(PVBOXVR_SCR_COMPOSITOR pCompositor, uint32_t *pcRegions, const RTRECT **ppaSrcRegions, const RTRECT **ppaDstRegions, const RTRECT **ppaDstUnstretchedRects);
     185VBOXVREGDECL(int) CrVrScrCompositorRegionsGet(const VBOXVR_SCR_COMPOSITOR *pCompositor, uint32_t *pcRegions, const RTRECT **ppaSrcRegions, const RTRECT **ppaDstRegions, const RTRECT **ppaDstUnstretchedRects);
    184186
    185187#define VBOXVR_SCR_COMPOSITOR_ENTRY_FROM_ENTRY(_p) ((PVBOXVR_SCR_COMPOSITOR_ENTRY)(((uint8_t*)(_p)) - RT_OFFSETOF(VBOXVR_SCR_COMPOSITOR_ENTRY, Ce)))
     188#define VBOXVR_SCR_COMPOSITOR_CONST_ENTRY_FROM_ENTRY(_p) ((const VBOXVR_SCR_COMPOSITOR_ENTRY*)(((uint8_t*)(_p)) - RT_OFFSETOF(VBOXVR_SCR_COMPOSITOR_ENTRY, Ce)))
    186189#define VBOXVR_SCR_COMPOSITOR_FROM_COMPOSITOR(_p) ((PVBOXVR_SCR_COMPOSITOR)(((uint8_t*)(_p)) - RT_OFFSETOF(VBOXVR_SCR_COMPOSITOR, Compositor)))
    187190
     
    191194} VBOXVR_SCR_COMPOSITOR_ITERATOR ,*PVBOXVR_SCR_COMPOSITOR_ITERATOR;
    192195
     196typedef struct VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR
     197{
     198    VBOXVR_COMPOSITOR_CONST_ITERATOR Base;
     199} VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR ,*PVBOXVR_SCR_COMPOSITOR_CONST_ITERATOR;
     200
    193201DECLINLINE(void) CrVrScrCompositorIterInit(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ITERATOR pIter)
    194202{
    195203    VBoxVrCompositorIterInit(&pCompositor->Compositor, &pIter->Base);
     204}
     205
     206DECLINLINE(void) CrVrScrCompositorConstIterInit(const VBOXVR_SCR_COMPOSITOR *pCompositor, PVBOXVR_SCR_COMPOSITOR_CONST_ITERATOR pIter)
     207{
     208    VBoxVrCompositorConstIterInit(&pCompositor->Compositor, &pIter->Base);
    196209}
    197210
     
    206219}
    207220
    208 
     221DECLINLINE(const VBOXVR_SCR_COMPOSITOR_ENTRY*) CrVrScrCompositorConstIterNext(PVBOXVR_SCR_COMPOSITOR_CONST_ITERATOR pIter)
     222{
     223    const VBOXVR_COMPOSITOR_ENTRY *pCe = VBoxVrCompositorConstIterNext(&pIter->Base);
     224    if (pCe)
     225    {
     226        return VBOXVR_SCR_COMPOSITOR_CONST_ENTRY_FROM_ENTRY(pCe);
     227    }
     228    return NULL;
     229}
     230
     231RT_C_DECLS_END
    209232
    210233#endif /* ___cr_compositor_h_ */
  • trunk/src/VBox/GuestHost/OpenGL/include/cr_error.h

    r46757 r50095  
    2525#endif
    2626
     27#ifndef IN_RING0
     28#define LOG(_m) do { crDebug _m ; } while (0)
     29#define LOGREL(_m) do { crDebug _m ; } while (0)
     30#define WARN(_m) do { crWarning _m ; AssertMsgFailed(_m); } while (0)
     31#else
     32#define LOG(_m) do { } while (0)
     33#define LOGREL(_m) do { } while (0)
     34#define WARN(_m) do { AssertMsgFailed(_m); } while (0)
     35#endif
     36
    2737DECLEXPORT(void) crEnableWarnings(int onOff);
    2838
    2939DECLEXPORT(void) crDebug(const char *format, ... ) PRINTF;
    30 #ifdef DEBUG_misha
     40#if defined(DEBUG_misha) && defined(RT_OS_WINDOWS)
    3141typedef void FNCRDEBUG(const char *format, ... ) PRINTF;
    3242typedef FNCRDEBUG *PFNCRDEBUG;
  • trunk/src/VBox/GuestHost/OpenGL/include/cr_htable.h

    r49772 r50095  
    2121#include <iprt/types.h>
    2222#include <iprt/cdefs.h>
     23
     24#include <cr_error.h>
    2325
    2426#ifndef IN_RING0
     
    7678    {
    7779        if (phHandle)
    78             *phHandle = NULL;
     80            *phHandle = 0;
    7981        return NULL;
    8082    }
     
    9496    }
    9597
    96     WARN(("interator concurent modification!"));
     98    crWarning("interator concurent modification!");
    9799    return NULL;
    98100}
     
    102104{
    103105    *pDstTbl = *pSrcTbl;
    104     CrHTableCreate(pSrcTbl);
     106    CrHTableCreate(pSrcTbl, 0);
    105107}
    106108VBOXHTABLEDECL(void) CrHTableEmpty(PCRHTABLE pTbl);
     
    114116VBOXHTABLEDECL(void*) CrHTableGet(PCRHTABLE pTbl, CRHTABLE_HANDLE hHandle);
    115117
     118RT_C_DECLS_END
    116119
    117120#endif /* #ifndef ___cr_htable_h_*/
  • trunk/src/VBox/GuestHost/OpenGL/include/cr_server.h

    r49474 r50095  
    2727#include <iprt/critsect.h>
    2828#include <iprt/semaphore.h>
     29#include <iprt/memcache.h>
    2930
    3031#include <VBox/vmm/ssm.h>
    3132
    32 #ifdef VBOX_WITH_CRHGSMI
    33 # include <VBox/VBoxVideo.h>
    34 #endif
     33#include <VBox/VBoxVideo.h>
    3534#include <VBox/Hardware/VBoxVideoVBE.h>
    3635#include <VBox/VBoxVideo3D.h>
     
    204203/* */
    205204
    206 /* DISPLAY */
    207 /* define display entry early so it can be used in MuralInfo */
    208 typedef struct CR_DISPLAY_ENTRY
     205/* FRAMEBUFFER */
     206typedef struct CR_FRAMEBUFFER *HCR_FRAMEBUFFER;
     207typedef struct CR_FRAMEBUFFER_ENTRY *HCR_FRAMEBUFFER_ENTRY;
     208/* */
     209
     210typedef struct CR_FBDATA
    209211{
    210     VBOXVR_SCR_COMPOSITOR_ENTRY CEntry;
    211     VBOXVR_SCR_COMPOSITOR_ENTRY RootVrCEntry;
    212     void *pvORInstance;
    213     GLuint idPBO;
    214     GLuint idInvertTex;
    215 } CR_DISPLAY_ENTRY, *PCR_DISPLAY_ENTRY;
    216 /**/
    217 
     212    HCR_FRAMEBUFFER hFb;
     213    HCR_FRAMEBUFFER_ENTRY hFbEntry;
     214    CR_TEXDATA* apTexDatas[2];
     215} CR_FBDATA;
    218216/**
    219217 * Mural info
     
    231229    GLubyte   u8Unused;       /*redirect to FBO instead of real host window*/
    232230    GLboolean bFbDraw;       /*GL_FRONT buffer is drawn to directly*/
    233     GLboolean fDataPresented;
     231    GLboolean fReserved;
    234232
    235233    GLint       cVisibleRects;    /*count of visible rects*/
     
    255253    GLuint fboWidth, fboHeight;
    256254
    257     GLuint cDisabled;
    258 
    259     GLuint   fPresentMode;       /*redirect to FBO instead of real host window*/
    260 
    261255    GLboolean fHasParentWindow;
    262256
    263     GLboolean fRootVrOn;
     257    GLboolean fRedirected;
    264258    GLboolean fForcePresentState;
    265259    GLboolean fOrPresentOnReenable;
    266260
    267     GLboolean fUseDefaultDEntry;
    268 
    269261    GLboolean fIsVisible;
    270262
    271     CR_DISPLAY_ENTRY DefaultDEntry;
    272 
    273     VBOXVR_SCR_COMPOSITOR Compositor;
    274 
    275     /* if root Visible regions are set, these two contain actual regions being passed to render spu */
    276     VBOXVR_SCR_COMPOSITOR RootVrCompositor;
    277 
    278     CR_SERVER_RPW_ENTRY RpwEntry;
     263    CR_TEXDATA aTexs[2];
     264    uint32_t cUsedFBDatas;
     265    CR_FBDATA *apUsedFBDatas[CR_MAX_GUEST_MONITORS];
     266    CR_FBDATA aFBDatas[CR_MAX_GUEST_MONITORS];
    279267
    280268    /* bitfield representing contexts the mural has been ever current with
     
    344332
    345333typedef struct {
    346     int32_t    x, y;
    347     uint32_t   w, h;
     334    RTRECT Rect;
    348335} CRScreenViewportInfo;
    349 
    350 
    351 /* DISPLAY */
    352 
    353 #define CR_DENTRY_FROM_CENTRY(_pCentry) ((CR_DISPLAY_ENTRY*)((uint8_t*)(_pCentry) - RT_OFFSETOF(CR_DISPLAY_ENTRY, CEntry)))
    354 
    355 
    356 /* @todo:
    357  * 1. use compositor stored inside mural to use current MuralFBO and window-related API
    358  * 2. CR_SERVER_REDIR_F_NONE and CR_SERVER_REDIR_F_FBO should be trated identically for presented window
    359  *    since we just need to blit the given textures to it if we are NOT in CR_SERVER_REDIR_F_FBO_RAM mode */
    360 typedef struct CR_DISPLAY
    361 {
    362     CRMuralInfo Mural;
    363     GLboolean fForcePresent;
    364 } CR_DISPLAY, *PCR_DISPLAY;
    365 
    366 
    367 typedef struct CR_DISPLAY_ENTRY_MAP
    368 {
    369     CRHashTable * pTexIdToDemInfoMap;
    370     uint32_t cEntered;
    371     RTLISTNODE ReleasedList;
    372 } CR_DISPLAY_ENTRY_MAP, *PCR_DISPLAY_ENTRY_MAP;
    373 
    374336
    375337typedef struct CRWinVisibilityInfo
     
    379341    uint32_t fVisibleChanged        : 1;
    380342} CRWinVisibilityInfo;
    381 
    382 /* */
    383 
    384 /* helpers */
    385 
    386 void CrHlpFreeTexImage(CRContext *pCurCtx, GLuint idPBO, void *pvData);
    387 void* CrHlpGetTexImage(CRContext *pCurCtx, const VBOXVR_TEXTURE *pTexture, GLuint idPBO, GLenum enmFormat);
    388 void CrHlpPutTexImage(CRContext *pCurCtx, const VBOXVR_TEXTURE *pTexture, GLenum enmFormat, void *pvData);
    389 
    390 /* */
    391343
    392344/* BFB (BlitFramebuffer Blitter) flags
     
    517469
    518470    PFNCRSERVERPRESENTFBO pfnPresentFBO;
    519     GLuint                fPresentMode; /*Force server to render 3d data offscreen
    520                                                      *using callback above to update vbox framebuffers*/
    521     GLuint                fPresentModeDefault; /*can be set with CR_SERVER_DEFAULT_RENDER_TYPE*/
    522     GLuint                fVramPresentModeDefault;
     471
     472    GLuint                fVisualBitsDefault;
    523473    GLboolean             bUsePBOForReadback;       /*Use PBO's for data readback*/
    524474
    525     GLboolean             bUseOutputRedirect;       /* Whether the output redirect was set. */
    526475    CROutputRedirect      outputRedirect;
    527476
     
    553502    int RcToGuest;
    554503    int RcToGuestOnce;
    555 
    556     /* @todo: should we use just one blitter?
    557      * we use two currently because the drawable attribs can differ*/
    558     CR_DISPLAY_ENTRY_MAP  PresentTexturepMap;
    559     uint32_t              DisplaysInitMap[(CR_MAX_GUEST_MONITORS + 31)/32];
    560     CR_DISPLAY            aDispplays[CR_MAX_GUEST_MONITORS];
    561504} CRServer;
    562505
     
    582525extern DECLEXPORT(int32_t) crVBoxServerLoadState(PSSMHANDLE pSSM, uint32_t version);
    583526
     527extern DECLEXPORT(void) crServerVBoxCompositionSetEnableStateGlobal(GLboolean fEnable);
    584528extern DECLEXPORT(int32_t) crVBoxServerSetScreenCount(int sCount);
    585529extern DECLEXPORT(int32_t) crVBoxServerUnmapScreen(int sIndex);
    586530extern DECLEXPORT(int32_t) crVBoxServerMapScreen(int sIndex, int32_t x, int32_t y, uint32_t w, uint32_t h, uint64_t winID);
    587531extern DECLEXPORT(void) crServerVBoxCompositionSetEnableStateGlobal(GLboolean fEnable);
     532struct VBVAINFOSCREEN;
     533extern DECLEXPORT(int) crVBoxServerNotifyResize(const struct VBVAINFOSCREEN *pScreen, void *pvVRAM);
    588534extern DECLEXPORT(int32_t) crVBoxServerSetRootVisibleRegion(GLint cRects, const RTRECT *pRects);
    589535
  • trunk/src/VBox/GuestHost/OpenGL/include/cr_version.h

    r49216 r50095  
    3939#define SHCROGL_SSM_VERSION_WITH_SCREEN_INFO                        40
    4040#define SHCROGL_SSM_VERSION_WITH_ALLOCATED_KEYS                     41
    41 #define SHCROGL_SSM_VERSION                                         41
     41#define SHCROGL_SSM_VERSION_WITH_FB_INFO                            42
     42#define SHCROGL_SSM_VERSION                                         42
    4243
    4344/* These define the Chromium release number.
  • trunk/src/VBox/GuestHost/OpenGL/include/cr_vreg.h

    r48726 r50095  
    2525#include <iprt/assert.h>
    2626#include <iprt/critsect.h>
     27#include <iprt/asm.h>
    2728
    2829#ifndef IN_RING0
     
    5051DECLINLINE(void) VBoxRectStretch(PRTRECT pRect, float xStretch, float yStretch)
    5152{
    52     pRect->xLeft = pRect->xLeft * xStretch;
    53     pRect->yTop = pRect->yTop * yStretch;
    54     pRect->xRight = pRect->xRight * xStretch;
    55     pRect->yBottom = pRect->yBottom * yStretch;
     53    pRect->xLeft = (int32_t)(pRect->xLeft * xStretch);
     54    pRect->yTop = (int32_t)(pRect->yTop * yStretch);
     55    pRect->xRight = (int32_t)(pRect->xRight * xStretch);
     56    pRect->yBottom = (int32_t)(pRect->yBottom * yStretch);
    5657}
    5758
     
    290291} VBOXVR_COMPOSITOR_ITERATOR ,*PVBOXVR_COMPOSITOR_ITERATOR;
    291292
     293typedef struct VBOXVR_COMPOSITOR_CONST_ITERATOR
     294{
     295    const VBOXVR_COMPOSITOR *pCompositor;
     296    const RTLISTNODE *pNextEntry;
     297} VBOXVR_COMPOSITOR_CONST_ITERATOR ,*PVBOXVR_COMPOSITOR_CONST_ITERATOR;
     298
    292299DECLINLINE(void) VBoxVrCompositorIterInit(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ITERATOR pIter)
    293300{
     
    296303}
    297304
     305DECLINLINE(void) VBoxVrCompositorConstIterInit(const VBOXVR_COMPOSITOR *pCompositor, PVBOXVR_COMPOSITOR_CONST_ITERATOR pIter)
     306{
     307    pIter->pCompositor = pCompositor;
     308    pIter->pNextEntry = pCompositor->List.pNext;
     309}
     310
    298311#define VBOXVR_COMPOSITOR_ENTRY_FROM_NODE(_p) ((PVBOXVR_COMPOSITOR_ENTRY)(((uint8_t*)(_p)) - RT_OFFSETOF(VBOXVR_COMPOSITOR_ENTRY, Node)))
     312#define VBOXVR_COMPOSITOR_CONST_ENTRY_FROM_NODE(_p) ((const VBOXVR_COMPOSITOR_ENTRY*)(((uint8_t*)(_p)) - RT_OFFSETOF(VBOXVR_COMPOSITOR_ENTRY, Node)))
    299313
    300314DECLINLINE(PVBOXVR_COMPOSITOR_ENTRY) VBoxVrCompositorIterNext(PVBOXVR_COMPOSITOR_ITERATOR pIter)
     
    310324}
    311325
    312 /* Compositor with Stretching & Cached Rectangles info */
     326DECLINLINE(const VBOXVR_COMPOSITOR_ENTRY*) VBoxVrCompositorConstIterNext(PVBOXVR_COMPOSITOR_CONST_ITERATOR pIter)
     327{
     328    const RTLISTNODE *pNextEntry = pIter->pNextEntry;
     329    if (pNextEntry != &pIter->pCompositor->List)
     330    {
     331        const VBOXVR_COMPOSITOR_ENTRY *pEntry = VBOXVR_COMPOSITOR_CONST_ENTRY_FROM_NODE(pNextEntry);
     332        pIter->pNextEntry = pNextEntry->pNext;
     333        return pEntry;
     334    }
     335    return NULL;
     336}
    313337
    314338typedef struct VBOXVR_TEXTURE
     
    320344} VBOXVR_TEXTURE, *PVBOXVR_TEXTURE;
    321345
    322 struct VBOXVR_SCR_COMPOSITOR_ENTRY;
    323 struct VBOXVR_SCR_COMPOSITOR;
    324 
    325 typedef DECLCALLBACK(void) FNVBOXVRSCRCOMPOSITOR_ENTRY_RELEASED(const struct VBOXVR_SCR_COMPOSITOR *pCompositor, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pReplacingEntry);
    326 typedef FNVBOXVRSCRCOMPOSITOR_ENTRY_RELEASED *PFNVBOXVRSCRCOMPOSITOR_ENTRY_RELEASED;
    327 
    328 
    329 typedef struct VBOXVR_SCR_COMPOSITOR_ENTRY
    330 {
    331     VBOXVR_COMPOSITOR_ENTRY Ce;
    332     VBOXVR_TEXTURE Tex;
    333     RTPOINT Pos;
    334     uint32_t fChanged;
    335     uint32_t fFlags;
    336     uint32_t cRects;
    337     PRTRECT paSrcRects;
    338     PRTRECT paDstRects;
    339     PRTRECT paDstUnstretchedRects;
    340     PFNVBOXVRSCRCOMPOSITOR_ENTRY_RELEASED pfnEntryReleased;
    341 } VBOXVR_SCR_COMPOSITOR_ENTRY, *PVBOXVR_SCR_COMPOSITOR_ENTRY;
    342 
    343 typedef struct VBOXVR_SCR_COMPOSITOR
    344 {
    345     VBOXVR_COMPOSITOR Compositor;
    346 #ifndef IN_RING0
    347     float StretchX;
    348     float StretchY;
    349 #endif
    350     uint32_t fFlags;
    351     uint32_t cRects;
    352     uint32_t cRectsBuffer;
    353     PRTRECT paSrcRects;
    354     PRTRECT paDstRects;
    355     PRTRECT paDstUnstretchedRects;
    356 } VBOXVR_SCR_COMPOSITOR, *PVBOXVR_SCR_COMPOSITOR;
    357 
    358 
    359 typedef DECLCALLBACK(bool) FNVBOXVRSCRCOMPOSITOR_VISITOR(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, void *pvVisitor);
    360 typedef FNVBOXVRSCRCOMPOSITOR_VISITOR *PFNVBOXVRSCRCOMPOSITOR_VISITOR;
    361 
    362 DECLINLINE(void) CrVrScrCompositorEntryInit(PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const VBOXVR_TEXTURE *pTex, PFNVBOXVRSCRCOMPOSITOR_ENTRY_RELEASED pfnEntryReleased)
    363 {
    364     VBoxVrCompositorEntryInit(&pEntry->Ce);
    365     pEntry->Tex = *pTex;
    366     memset(&pEntry->Pos, 0, sizeof (VBOXVR_SCR_COMPOSITOR_ENTRY) - RT_OFFSETOF(VBOXVR_SCR_COMPOSITOR_ENTRY, Pos));
    367     pEntry->pfnEntryReleased = pfnEntryReleased;
    368 }
    369 
    370 DECLINLINE(bool) CrVrScrCompositorEntryIsUsed(const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry)
    371 {
    372     return VBoxVrCompositorEntryIsInList(&pEntry->Ce);
    373 }
    374 
    375 DECLINLINE(void) CrVrScrCompositorEntrySetChanged(PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, bool fChanged)
    376 {
    377     pEntry->fChanged = !!fChanged;
    378 }
    379 
    380 DECLINLINE(void) CrVrScrCompositorEntryTexNameUpdate(PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t hwid)
    381 {
    382     pEntry->Tex.hwid = hwid;
    383     CrVrScrCompositorEntrySetChanged(pEntry, true);
    384 }
    385 
    386 DECLINLINE(const VBOXVR_TEXTURE *) CrVrScrCompositorEntryTexGet(const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry)
    387 {
    388     return &pEntry->Tex;
    389 }
    390 
    391 DECLINLINE(bool) CrVrScrCompositorEntryIsChanged(const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry)
    392 {
    393     return !!pEntry->fChanged;
    394 }
    395 
    396 DECLINLINE(bool) CrVrScrCompositorIsEmpty(const VBOXVR_SCR_COMPOSITOR *pCompositor)
    397 {
    398     return VBoxVrCompositorIsEmpty(&pCompositor->Compositor);
    399 }
    400 
    401 VBOXVREGDECL(int) CrVrScrCompositorEntryTexUpdate(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const VBOXVR_TEXTURE *pTex);
    402 VBOXVREGDECL(void) CrVrScrCompositorVisit(PVBOXVR_SCR_COMPOSITOR pCompositor, PFNVBOXVRSCRCOMPOSITOR_VISITOR pfnVisitor, void *pvVisitor);
    403 VBOXVREGDECL(void) CrVrScrCompositorEntrySetAllChanged(PVBOXVR_SCR_COMPOSITOR pCompositor, bool fChanged);
    404 DECLINLINE(bool) CrVrScrCompositorEntryIsInList(const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry)
    405 {
    406     return VBoxVrCompositorEntryIsInList(&pEntry->Ce);
    407 }
    408 VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsAdd(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, bool fPosRelated, VBOXVR_SCR_COMPOSITOR_ENTRY **ppReplacedScrEntry, uint32_t *pfChangeFlags);
    409 VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, bool fPosRelated, bool *pfChanged);
    410 VBOXVREGDECL(int) CrVrScrCompositorEntryListIntersect(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const VBOXVR_LIST *pList2, bool *pfChanged);
    411 VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsIntersect(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged);
    412 VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsIntersectAll(PVBOXVR_SCR_COMPOSITOR pCompositor, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged);
    413 VBOXVREGDECL(int) CrVrScrCompositorEntryListIntersectAll(PVBOXVR_SCR_COMPOSITOR pCompositor, const VBOXVR_LIST *pList2, bool *pfChanged);
    414 VBOXVREGDECL(int) CrVrScrCompositorEntryPosSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos);
    415 DECLINLINE(const RTPOINT*) CrVrScrCompositorEntryPosGet(const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry)
    416 {
    417     return &pEntry->Pos;
    418 }
    419 
    420 /* regions are valid until the next CrVrScrCompositor call */
    421 VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsGet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t *pcRegions, const RTRECT **ppaSrcRegions, const RTRECT **ppaDstRegions, const RTRECT **ppaDstUnstretchedRects);
    422 VBOXVREGDECL(int) CrVrScrCompositorEntryRemove(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry);
    423 VBOXVREGDECL(bool) CrVrScrCompositorEntryReplace(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, PVBOXVR_SCR_COMPOSITOR_ENTRY pNewEntry);
    424 VBOXVREGDECL(void) CrVrScrCompositorEntryFlagsSet(PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t fFlags);
    425 VBOXVREGDECL(uint32_t) CrVrScrCompositorEntryFlagsCombinedGet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry);
    426 DECLINLINE(uint32_t) CrVrScrCompositorEntryFlagsGet(PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry)
    427 {
    428     return pEntry->fFlags;
    429 }
    430 
    431 VBOXVREGDECL(void) CrVrScrCompositorInit(PVBOXVR_SCR_COMPOSITOR pCompositor);
    432 VBOXVREGDECL(void) CrVrScrCompositorClear(PVBOXVR_SCR_COMPOSITOR pCompositor);
    433 VBOXVREGDECL(void) CrVrScrCompositorRegionsClear(PVBOXVR_SCR_COMPOSITOR pCompositor, bool *pfChanged);
    434 
    435 typedef DECLCALLBACK(VBOXVR_SCR_COMPOSITOR_ENTRY*) FNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR(VBOXVR_SCR_COMPOSITOR_ENTRY*pEntry, void *pvContext);
    436 typedef FNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR *PFNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR;
    437 
    438 VBOXVREGDECL(int) CrVrScrCompositorClone(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR pDstCompositor, PFNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR pfnEntryFor, void* pvEntryFor);
    439 VBOXVREGDECL(int) CrVrScrCompositorIntersectList(PVBOXVR_SCR_COMPOSITOR pCompositor, const VBOXVR_LIST *pVr, bool *pfChanged);
    440 VBOXVREGDECL(int) CrVrScrCompositorIntersectedList(PVBOXVR_SCR_COMPOSITOR pCompositor, const VBOXVR_LIST *pVr, PVBOXVR_SCR_COMPOSITOR pDstCompositor, PFNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR pfnEntryFor, void* pvEntryFor, bool *pfChanged);
    441 #ifndef IN_RING0
    442 VBOXVREGDECL(void) CrVrScrCompositorSetStretching(PVBOXVR_SCR_COMPOSITOR pCompositor, float StretchX, float StretchY);
    443 DECLINLINE(void) CrVrScrCompositorGetStretching(PVBOXVR_SCR_COMPOSITOR pCompositor, float *pStretchX, float *pStretchY)
    444 {
    445     if (pStretchX)
    446         *pStretchX = pCompositor->StretchX;
    447 
    448     if (pStretchY)
    449         *pStretchY = pCompositor->StretchY;
    450 }
    451 #endif
    452 /* regions are valid until the next CrVrScrCompositor call */
    453 VBOXVREGDECL(int) CrVrScrCompositorRegionsGet(PVBOXVR_SCR_COMPOSITOR pCompositor, uint32_t *pcRegions, const RTRECT **ppaSrcRegions, const RTRECT **ppaDstRegions, const RTRECT **ppaDstUnstretchedRects);
    454 
    455 #define VBOXVR_SCR_COMPOSITOR_ENTRY_FROM_ENTRY(_p) ((PVBOXVR_SCR_COMPOSITOR_ENTRY)(((uint8_t*)(_p)) - RT_OFFSETOF(VBOXVR_SCR_COMPOSITOR_ENTRY, Ce)))
    456 #define VBOXVR_SCR_COMPOSITOR_FROM_COMPOSITOR(_p) ((PVBOXVR_SCR_COMPOSITOR)(((uint8_t*)(_p)) - RT_OFFSETOF(VBOXVR_SCR_COMPOSITOR, Compositor)))
    457 
    458 typedef struct VBOXVR_SCR_COMPOSITOR_ITERATOR
    459 {
    460     VBOXVR_COMPOSITOR_ITERATOR Base;
    461 } VBOXVR_SCR_COMPOSITOR_ITERATOR ,*PVBOXVR_SCR_COMPOSITOR_ITERATOR;
    462 
    463 DECLINLINE(void) CrVrScrCompositorIterInit(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ITERATOR pIter)
    464 {
    465     VBoxVrCompositorIterInit(&pCompositor->Compositor, &pIter->Base);
    466 }
    467 
    468 DECLINLINE(PVBOXVR_SCR_COMPOSITOR_ENTRY) CrVrScrCompositorIterNext(PVBOXVR_SCR_COMPOSITOR_ITERATOR pIter)
    469 {
    470     PVBOXVR_COMPOSITOR_ENTRY pCe = VBoxVrCompositorIterNext(&pIter->Base);
    471     if (pCe)
    472     {
    473         return VBOXVR_SCR_COMPOSITOR_ENTRY_FROM_ENTRY(pCe);
    474     }
    475     return NULL;
    476 }
    477 
    478346RT_C_DECLS_END
    479347
  • trunk/src/VBox/GuestHost/OpenGL/state_tracker/dump.cpp

    r50041 r50095  
    337337}
    338338
    339 void crRecDumpBuffer(CR_RECORDER *pRec, CRContext *ctx, CR_BLITTER_CONTEXT *pCurCtx, CR_BLITTER_WINDOW *pCurWin, GLint idRedirFBO, VBOXVR_TEXTURE *pRedirTex)
     339void crRecDumpBuffer(CR_RECORDER *pRec, CRContext *ctx, GLint idRedirFBO, VBOXVR_TEXTURE *pRedirTex)
    340340{
    341341    GLenum texTarget = 0;
     
    412412        pTl = &pTobj->level[0][hwTexLevel];
    413413
    414         rc = CrBltEnter(pRec->pBlitter, pCurCtx, pCurWin);
     414        rc = CrBltEnter(pRec->pBlitter);
    415415        if (!RT_SUCCESS(rc))
    416416        {
     
    447447        height = pRedirTex->height;
    448448
    449         rc = CrBltEnter(pRec->pBlitter, pCurCtx, pCurWin);
     449        rc = CrBltEnter(pRec->pBlitter);
    450450        if (!RT_SUCCESS(rc))
    451451        {
     
    13381338}
    13391339
    1340 void crRecDumpTextureV(CR_RECORDER *pRec, const VBOXVR_TEXTURE *pTex, CR_BLITTER_CONTEXT *pCurCtx, CR_BLITTER_WINDOW *pCurWin, const char *pszStr, va_list pArgList)
     1340void crRecDumpTextureV(CR_RECORDER *pRec, const VBOXVR_TEXTURE *pTex, const char *pszStr, va_list pArgList)
    13411341{
    13421342    CR_BLITTER_IMG Img = {0};
    1343     int rc = CrBltEnter(pRec->pBlitter, pCurCtx, pCurWin);
     1343    int rc = CrBltEnter(pRec->pBlitter);
    13441344    if (RT_SUCCESS(rc))
    13451345    {
     
    13761376}
    13771377
    1378 void crRecDumpTextureF(CR_RECORDER *pRec, const VBOXVR_TEXTURE *pTex, CR_BLITTER_CONTEXT *pCurCtx, CR_BLITTER_WINDOW *pCurWin, const char *pszStr, ...)
     1378void crRecDumpTextureF(CR_RECORDER *pRec, const VBOXVR_TEXTURE *pTex, const char *pszStr, ...)
    13791379{
    13801380    va_list pArgList;
    13811381    va_start(pArgList, pszStr);
    1382     crRecDumpTextureV(pRec, pTex, pCurCtx, pCurWin, pszStr, pArgList);
     1382    crRecDumpTextureV(pRec, pTex, pszStr, pArgList);
    13831383    va_end(pArgList);
    13841384}
    13851385
    1386 void crRecDumpTextureByIdV(CR_RECORDER *pRec, CRContext *ctx, GLint id, CR_BLITTER_CONTEXT *pCurCtx, CR_BLITTER_WINDOW *pCurWin, const char *pszStr, va_list pArgList)
     1386void crRecDumpTextureByIdV(CR_RECORDER *pRec, CRContext *ctx, GLint id, const char *pszStr, va_list pArgList)
    13871387{
    13881388    CRTextureObj *pTobj = (CRTextureObj *)crHashtableSearch(ctx->shared->textureTable, id);
     
    14061406    }
    14071407
    1408     crRecDumpTextureV(pRec, &Tex, pCurCtx, pCurWin, pszStr, pArgList);
    1409 }
    1410 
    1411 void crRecDumpTextureByIdF(CR_RECORDER *pRec, CRContext *ctx, GLint id, CR_BLITTER_CONTEXT *pCurCtx, CR_BLITTER_WINDOW *pCurWin, const char *pszStr, ...)
     1408    crRecDumpTextureV(pRec, &Tex, pszStr, pArgList);
     1409}
     1410
     1411void crRecDumpTextureByIdF(CR_RECORDER *pRec, CRContext *ctx, GLint id, const char *pszStr, ...)
    14121412{
    14131413    va_list pArgList;
    14141414    va_start(pArgList, pszStr);
    1415     crRecDumpTextureByIdV(pRec, ctx, id, pCurCtx, pCurWin, pszStr, pArgList);
     1415    crRecDumpTextureByIdV(pRec, ctx, id, pszStr, pArgList);
    14161416    va_end(pArgList);
    14171417}
    14181418
    1419 void crRecDumpTextures(CR_RECORDER *pRec, CRContext *ctx, CR_BLITTER_CONTEXT *pCurCtx, CR_BLITTER_WINDOW *pCurWin)
     1419void crRecDumpTextures(CR_RECORDER *pRec, CRContext *ctx)
    14201420{
    14211421    GLint maxUnits = 0;
     
    15101510                }
    15111511
    1512                 crRecDumpTextureF(pRec, &Tex, pCurCtx, pCurWin, "ctx(%d), Unit %d: TEXTURE_2D id(%d) hwid(%d), width(%d), height(%d)", ctx, i, pTobj->id, pTobj->hwid, width, height);
     1512                crRecDumpTextureF(pRec, &Tex, "ctx(%d), Unit %d: TEXTURE_2D id(%d) hwid(%d), width(%d), height(%d)", ctx, i, pTobj->id, pTobj->hwid, width, height);
    15131513            }
    15141514//            else
     
    15581558                Tex.hwid = hwTex;
    15591559
    1560                 rc = CrBltEnter(pRec->pBlitter, pCurCtx, pCurWin);
     1560                rc = CrBltEnter(pRec->pBlitter);
    15611561                if (RT_SUCCESS(rc))
    15621562                {
  • trunk/src/VBox/GuestHost/OpenGL/util/blitter.cpp

    r48366 r50095  
    4242 *                                     Also note that blitter caches the current window info, and assumes the current context's values are preserved
    4343 *                                     wrt that window before the calls, so if one uses different contexts for one blitter,
    44  *                                     the blitter current window values must be explicitly reset by doing CrBltMuralSetCurrent(pBlitter, NULL)
     44 *                                     the blitter current window values must be explicitly reset by doing CrBltMuralSetCurrentInfo(pBlitter, NULL)
    4545 * @param fForceDrawBlt - if true  - forces the blitter to always use glDrawXxx-based blits even if GL_EXT_framebuffer_blit.
    4646 *                                   This is needed because BlitFramebufferEXT is known to be often buggy, and glDrawXxx-based blits appear to be more reliable
     
    9494}
    9595
    96 VBOXBLITTERDECL(int) CrBltCleanup(PCR_BLITTER pBlitter, const CR_BLITTER_CONTEXT *pRestoreCtxInfo, const CR_BLITTER_WINDOW *pRestoreMural)
     96VBOXBLITTERDECL(int) CrBltCleanup(PCR_BLITTER pBlitter)
    9797{
    9898    if (CrBltIsEntered(pBlitter))
     
    105105        return VINF_SUCCESS;
    106106
    107     int rc = CrBltEnter(pBlitter, pRestoreCtxInfo, pRestoreMural);
     107    int rc = CrBltEnter(pBlitter);
    108108    if (!RT_SUCCESS(rc))
    109109    {
     
    126126}
    127127
    128 int CrBltMuralSetCurrent(PCR_BLITTER pBlitter, const CR_BLITTER_WINDOW *pMural)
     128int CrBltMuralSetCurrentInfo(PCR_BLITTER pBlitter, const CR_BLITTER_WINDOW *pMural)
    129129{
    130130    if (pMural)
     
    520520        crWarning("GL_EXT_framebuffer_object not supported, blitter can only blit to window");
    521521
     522    if (crStrstr(pszExtension, "GL_ARB_pixel_buffer_object"))
     523        pBlitter->Flags.SupportsPBO = 1;
     524    else
     525        crWarning("GL_ARB_pixel_buffer_object not supported");
     526
    522527    /* BlitFramebuffer seems to be buggy on Intel,
    523528     * try always glDrawXxx for now */
     
    559564
    560565    if (pBlitter->CtxInfo.Base.id)
    561     {
    562         if (pBlitter->pRestoreCtxInfo != &pBlitter->CtxInfo)
    563         {
    564             pBlitter->pDispatch->MakeCurrent(pBlitter->pRestoreMural->Base.id, 0, pBlitter->pRestoreCtxInfo->Base.id);
    565         }
    566         else
    567         {
    568             pBlitter->pDispatch->MakeCurrent(0, 0, 0);
    569         }
    570     }
    571 
    572     pBlitter->pRestoreCtxInfo = NULL;
    573 }
    574 
    575 int CrBltEnter(PCR_BLITTER pBlitter, const CR_BLITTER_CONTEXT *pRestoreCtxInfo, const CR_BLITTER_WINDOW *pRestoreMural)
     566        pBlitter->pDispatch->MakeCurrent(0, 0, 0);
     567
     568    pBlitter->Flags.Entered = 0;
     569}
     570
     571int CrBltEnter(PCR_BLITTER pBlitter)
    576572{
    577573    if (!pBlitter->CurrentMural.Base.id && pBlitter->CtxInfo.Base.id)
     
    589585    if (pBlitter->CurrentMural.Base.id) /* <- pBlitter->CurrentMural.Base.id can be null if the blitter is in a "no-context" mode (see comments to BltInit for detail)*/
    590586    {
    591         if (pRestoreCtxInfo)
    592             pBlitter->pDispatch->Flush();
    593587        pBlitter->pDispatch->MakeCurrent(pBlitter->CurrentMural.Base.id, pBlitter->i32MakeCurrentUserData, pBlitter->CtxInfo.Base.id);
    594588    }
    595     else
    596     {
    597         if (pRestoreCtxInfo)
    598         {
    599             crWarning("pRestoreCtxInfo is not NULL for \"no-context\" blitter");
    600             pRestoreCtxInfo = NULL;
    601         }
    602     }
    603 
    604     if (pRestoreCtxInfo)
    605     {
    606         pBlitter->pRestoreCtxInfo = pRestoreCtxInfo;
    607         pBlitter->pRestoreMural = pRestoreMural;
    608     }
    609     else
    610     {
    611         pBlitter->pRestoreCtxInfo = &pBlitter->CtxInfo;
    612     }
     589
     590    pBlitter->Flags.Entered = 1;
    613591
    614592    if (pBlitter->Flags.Initialized)
     
    718696}
    719697
    720 static int crBltImgCreateForTex(const VBOXVR_TEXTURE *pSrc, CR_BLITTER_IMG *pDst, GLenum enmFormat)
     698static int crBltImgInitBaseForTex(const VBOXVR_TEXTURE *pSrc, CR_BLITTER_IMG *pDst, GLenum enmFormat)
    721699{
    722700    memset(pDst, 0, sizeof (*pDst));
     
    732710    uint32_t pitch = ((bpp * pSrc->width) + 7) >> 3;
    733711    uint32_t cbData = pitch * pSrc->height;
    734     pDst->pvData = RTMemAllocZ(cbData);
    735     if (!pDst->pvData)
    736     {
    737         crWarning("RTMemAlloc failed");
    738         return VERR_NO_MEMORY;
    739     }
    740 
    741 #ifdef DEBUG_misha
    742     {
    743         char *pTmp = (char*)pDst->pvData;
    744         for (uint32_t i = 0; i < cbData; ++i)
    745         {
    746             pTmp[i] = (char)((1 << i) % 255);
    747         }
    748     }
    749 #endif
    750 
    751712    pDst->cbData = cbData;
    752713    pDst->enmFormat = enmFormat;
     
    755716    pDst->bpp = bpp;
    756717    pDst->pitch = pitch;
     718    return VINF_SUCCESS;
     719}
     720
     721static int crBltImgCreateForTex(const VBOXVR_TEXTURE *pSrc, CR_BLITTER_IMG *pDst, GLenum enmFormat)
     722{
     723    int rc = crBltImgInitBaseForTex(pSrc, pDst, enmFormat);
     724    if (!RT_SUCCESS(rc))
     725    {
     726        crWarning("crBltImgInitBaseForTex failed rc %d", rc);
     727        return rc;
     728    }
     729
     730    uint32_t cbData = pDst->cbData;
     731    pDst->pvData = RTMemAllocZ(cbData);
     732    if (!pDst->pvData)
     733    {
     734        crWarning("RTMemAlloc failed");
     735        return VERR_NO_MEMORY;
     736    }
     737
     738#ifdef DEBUG_misha
     739    {
     740        char *pTmp = (char*)pDst->pvData;
     741        for (uint32_t i = 0; i < cbData; ++i)
     742        {
     743            pTmp[i] = (char)((1 << i) % 255);
     744        }
     745    }
     746#endif
    757747    return VINF_SUCCESS;
    758748}
     
    11341124    memset(pCache, 0, sizeof (*pCache));
    11351125}
     1126
     1127
     1128/*TdBlt*/
     1129
     1130static void crTdBltCheckPBO(PCR_TEXDATA pTex)
     1131{
     1132    if (pTex->idPBO)
     1133        return;
     1134
     1135    PCR_BLITTER pBlitter = pTex->pBlitter;
     1136
     1137    if (!pBlitter->Flags.SupportsPBO)
     1138        return;
     1139
     1140    pBlitter->pDispatch->GenBuffersARB(1, &pTex->idPBO);
     1141    if (!pTex->idPBO)
     1142    {
     1143        crWarning("PBO create failed");
     1144        return;
     1145    }
     1146
     1147    pBlitter->pDispatch->BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pTex->idPBO);
     1148    pBlitter->pDispatch->BufferDataARB(GL_PIXEL_PACK_BUFFER_ARB,
     1149                pTex->Tex.width*pTex->Tex.height*4,
     1150                0, GL_STREAM_READ_ARB);
     1151    pBlitter->pDispatch->BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
     1152}
     1153
     1154static uint32_t crTdBltTexCreate(PCR_TEXDATA pTex)
     1155{
     1156        PCR_BLITTER pBlitter = pTex->pBlitter;
     1157    uint32_t tex = 0;
     1158    pBlitter->pDispatch->GenTextures(1, &tex);
     1159    if (!tex)
     1160    {
     1161        crWarning("Tex create failed");
     1162        return 0;
     1163    }
     1164
     1165    pBlitter->pDispatch->BindTexture(GL_TEXTURE_2D, tex);
     1166    pBlitter->pDispatch->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     1167    pBlitter->pDispatch->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     1168    pBlitter->pDispatch->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
     1169    pBlitter->pDispatch->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
     1170    pBlitter->pDispatch->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,
     1171            pTex->Tex.width,
     1172            pTex->Tex.height,
     1173            0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
     1174
     1175
     1176    /*Restore gl state*/
     1177    pBlitter->pDispatch->BindTexture(GL_TEXTURE_2D, 0);
     1178
     1179    return tex;
     1180}
     1181
     1182int crTdBltCheckInvertTex(PCR_TEXDATA pTex)
     1183{
     1184    if (pTex->idInvertTex)
     1185        return VINF_SUCCESS;
     1186
     1187    pTex->idInvertTex = crTdBltTexCreate(pTex);
     1188    if (!pTex->idInvertTex)
     1189    {
     1190        crWarning("Invert Tex create failed");
     1191        return VERR_GENERAL_FAILURE;
     1192    }
     1193    return VINF_SUCCESS;
     1194}
     1195
     1196void crTdBltImgFree(PCR_TEXDATA pTex)
     1197{
     1198    if (!pTex->Img.pvData)
     1199        return;
     1200
     1201    PCR_BLITTER pBlitter = pTex->pBlitter;
     1202
     1203    if (pTex->idPBO)
     1204    {
     1205        pBlitter->pDispatch->BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pTex->idPBO);
     1206        pBlitter->pDispatch->UnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
     1207        pBlitter->pDispatch->BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
     1208    }
     1209    else
     1210        RTMemFree(pTex->Img.pvData);
     1211
     1212    pTex->Img.pvData = NULL;
     1213}
     1214
     1215int crTdBltImgAcquire(PCR_TEXDATA pTex, GLenum enmFormat, bool fInverted)
     1216{
     1217    int rc = crBltImgInitBaseForTex(&pTex->Tex, &pTex->Img, enmFormat);
     1218    if (!RT_SUCCESS(rc))
     1219    {
     1220        crWarning("crBltImgInitBaseForTex failed rc %d", rc);
     1221        return rc;
     1222    }
     1223
     1224    PCR_BLITTER pBlitter = pTex->pBlitter;
     1225    void *pvData = NULL;
     1226    pBlitter->pDispatch->BindTexture(pTex->Tex.target, fInverted ? pTex->idInvertTex : pTex->Tex.hwid);
     1227
     1228    pBlitter->pDispatch->BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pTex->idPBO);
     1229
     1230    if (!pTex->idPBO)
     1231    {
     1232        pvData = RTMemAlloc(4*pTex->Tex.width*pTex->Tex.height);
     1233        if (!pvData)
     1234        {
     1235            crWarning("Out of memory in crTdBltImgAcquire");
     1236            return VERR_NO_MEMORY;
     1237        }
     1238    }
     1239
     1240    /*read the texture, note pixels are NULL for PBO case as it's offset in the buffer*/
     1241    pBlitter->pDispatch->GetTexImage(GL_TEXTURE_2D, 0, enmFormat, GL_UNSIGNED_BYTE, pvData);
     1242
     1243    /*restore gl state*/
     1244    pBlitter->pDispatch->BindTexture(pTex->Tex.target, 0);
     1245
     1246    if (pTex->idPBO)
     1247    {
     1248        pvData = pBlitter->pDispatch->MapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
     1249        if (!pvData)
     1250        {
     1251            crWarning("Failed to MapBuffer in CrHlpGetTexImage");
     1252            return VERR_GENERAL_FAILURE;
     1253        }
     1254
     1255        pBlitter->pDispatch->BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
     1256    }
     1257
     1258    CRASSERT(pvData);
     1259    pTex->Img.pvData = pvData;
     1260    pTex->Flags.DataInverted = fInverted;
     1261    return VINF_SUCCESS;
     1262}
     1263
     1264/* release the texture data, the data remains cached in the CR_TEXDATA object until it is discarded with CrTdBltDataDiscard or CrTdBltDataCleanup */
     1265VBOXBLITTERDECL(void) CrTdBltDataRelease(PCR_TEXDATA pTex)
     1266{
     1267    Assert(pTex->Img.pvData);
     1268}
     1269
     1270/* discard the texture data cached with previous CrTdBltDataAcquire.
     1271 * Must be called wit data released (CrTdBltDataRelease) */
     1272VBOXBLITTERDECL(void) CrTdBltDataDiscard(PCR_TEXDATA pTex)
     1273{
     1274    crTdBltImgFree(pTex);
     1275}
     1276/* does same as CrTdBltDataDiscard, and in addition cleans up */
     1277VBOXBLITTERDECL(void) CrTdBltDataCleanup(PCR_TEXDATA pTex)
     1278{
     1279    crTdBltImgFree(pTex);
     1280
     1281    PCR_BLITTER pBlitter = pTex->pBlitter;
     1282
     1283    if (pTex->idPBO)
     1284    {
     1285        pBlitter->pDispatch->DeleteBuffersARB(1, &pTex->idPBO);
     1286        pTex->idPBO = 0;
     1287    }
     1288
     1289    if (pTex->idInvertTex)
     1290    {
     1291        pBlitter->pDispatch->DeleteTextures(1, &pTex->idInvertTex);
     1292        pTex->idInvertTex = 0;
     1293    }
     1294}
     1295
     1296/* acquire the texture data, returns the cached data in case it is cached.
     1297 * the data remains cached in the CR_TEXDATA object until it is discarded with CrTdBltDataDiscard or CrTdBltDataCleanup.
     1298 * */
     1299VBOXBLITTERDECL(int) CrTdBltDataAcquire(PCR_TEXDATA pTex, GLenum enmFormat, bool fInverted, const CR_BLITTER_IMG**ppImg)
     1300{
     1301    if (pTex->Img.pvData && pTex->Img.enmFormat == enmFormat && !pTex->Flags.DataInverted == !fInverted)
     1302    {
     1303        *ppImg = &pTex->Img;
     1304        return VINF_SUCCESS;
     1305    }
     1306
     1307    crTdBltImgFree(pTex);
     1308
     1309    crTdBltCheckPBO(pTex);
     1310
     1311    int rc;
     1312
     1313    if (fInverted)
     1314    {
     1315        rc = crTdBltCheckInvertTex(pTex);
     1316        if (!RT_SUCCESS(rc))
     1317        {
     1318            crWarning("crTdBltCheckInvertTex failed rc %d", rc);
     1319            return rc;
     1320        }
     1321
     1322        RTRECT SrcRect, DstRect;
     1323        VBOXVR_TEXTURE InvertTex;
     1324
     1325        InvertTex = pTex->Tex;
     1326        InvertTex.hwid = pTex->idInvertTex;
     1327
     1328        SrcRect.xLeft = 0;
     1329        SrcRect.yTop = InvertTex.height;
     1330        SrcRect.xRight = InvertTex.width;
     1331        SrcRect.yBottom = 0;
     1332
     1333        DstRect.xLeft = 0;
     1334        DstRect.yTop = 0;
     1335        DstRect.xRight = InvertTex.width;
     1336        DstRect.yBottom = InvertTex.height;
     1337
     1338        CrBltBlitTexTex(pTex->pBlitter, &pTex->Tex, &SrcRect, &InvertTex, &DstRect, 1, 0);
     1339    }
     1340
     1341    rc = crTdBltImgAcquire(pTex, enmFormat, fInverted);
     1342    if (!RT_SUCCESS(rc))
     1343    {
     1344        crWarning("crTdBltImgAcquire failed rc %d", rc);
     1345        return rc;
     1346    }
     1347
     1348    *ppImg = &pTex->Img;
     1349
     1350    return VINF_SUCCESS;
     1351}
  • trunk/src/VBox/GuestHost/OpenGL/util/compositor.cpp

    r49773 r50095  
    2020#define VBOXVR_SCR_COMPOSITOR_RECTS_UNDEFINED UINT32_MAX
    2121
     22
    2223static int crVrScrCompositorRectsAssignBuffer(PVBOXVR_SCR_COMPOSITOR pCompositor, uint32_t cRects)
    2324{
     
    119120    AssertRC(rc);
    120121
    121     if (!pEntry->Pos.x && !pEntry->Pos.y)
     122    if (!pEntry->Rect.xLeft && !pEntry->Rect.yTop)
    122123    {
    123124        memcpy(pEntry->paSrcRects, pEntry->paDstUnstretchedRects, cRects * sizeof (*pEntry->paSrcRects));
     
    127128        for (uint32_t i = 0; i < cRects; ++i)
    128129        {
    129             pEntry->paSrcRects[i].xLeft = (int32_t)((pEntry->paDstUnstretchedRects[i].xLeft - pEntry->Pos.x));
    130             pEntry->paSrcRects[i].yTop = (int32_t)((pEntry->paDstUnstretchedRects[i].yTop - pEntry->Pos.y));
    131             pEntry->paSrcRects[i].xRight = (int32_t)((pEntry->paDstUnstretchedRects[i].xRight - pEntry->Pos.x));
    132             pEntry->paSrcRects[i].yBottom = (int32_t)((pEntry->paDstUnstretchedRects[i].yBottom - pEntry->Pos.y));
     130            pEntry->paSrcRects[i].xLeft = (int32_t)((pEntry->paDstUnstretchedRects[i].xLeft - pEntry->Rect.xLeft));
     131            pEntry->paSrcRects[i].yTop = (int32_t)((pEntry->paDstUnstretchedRects[i].yTop - pEntry->Rect.yTop));
     132            pEntry->paSrcRects[i].xRight = (int32_t)((pEntry->paDstUnstretchedRects[i].xRight - pEntry->Rect.xLeft));
     133            pEntry->paSrcRects[i].yBottom = (int32_t)((pEntry->paDstUnstretchedRects[i].yBottom - pEntry->Rect.yTop));
    133134        }
    134135    }
     
    200201}
    201202
    202 static int crVrScrCompositorRectsCheckInit(PVBOXVR_SCR_COMPOSITOR pCompositor)
    203 {
     203static int crVrScrCompositorRectsCheckInit(const VBOXVR_SCR_COMPOSITOR *pcCompositor)
     204{
     205    VBOXVR_SCR_COMPOSITOR *pCompositor = const_cast<VBOXVR_SCR_COMPOSITOR*>(pcCompositor);
     206
    204207    if (pCompositor->cRects != VBOXVR_SCR_COMPOSITOR_RECTS_UNDEFINED)
    205208        return VINF_SUCCESS;
     
    248251    else if (fChangedFlags & VBOXVR_COMPOSITOR_CF_ENTRY_REPLACED)
    249252    {
    250         Assert(!CrVrScrCompositorEntryIsInList(pReplacedScrEntry));
    251         Assert(CrVrScrCompositorEntryIsInList(pEntry));
    252         pEntry->cRects = pReplacedScrEntry->cRects;
    253         pEntry->paSrcRects = pReplacedScrEntry->paSrcRects;
    254         pEntry->paDstRects = pReplacedScrEntry->paDstRects;
    255         pEntry->paDstUnstretchedRects = pReplacedScrEntry->paDstUnstretchedRects;
     253        Assert(pReplacedScrEntry);
    256254    }
    257255
     
    321319        }
    322320
    323         pEntry->Pos = *pPos;
     321        VBoxRectMove(&pEntry->Rect, pPos->x, pPos->y);
    324322        CrVrScrCompositorEntrySetChanged(pEntry, true);
    325323
     
    335333    Rect.xLeft = RT_MAX(pCompositor->Rect.xLeft, pEntry->Rect.xLeft);
    336334    Rect.yTop = RT_MAX(pCompositor->Rect.yTop, pEntry->Rect.yTop);
    337     Rect.xRight = RT_MIN(pCompositor->Rect.xRight, pEntry->Rect.xLeft + pEntry->Rect.xRight);
    338     Rect.yBottom = RT_MIN(pCompositor->Rect.yBottom, pEntry->Rect.yTop + pEntry->Rect.yBottom);
     335    Rect.xRight = RT_MIN(pCompositor->Rect.xRight, pEntry->Rect.xRight);
     336    Rect.yBottom = RT_MIN(pCompositor->Rect.yBottom, pEntry->Rect.yBottom);
    339337    bool fChanged = false;
    340338
     
    375373        }
    376374
    377         if (cRegions && (pEntry->Pos.x || pEntry->Pos.y))
     375        if (cRegions && (pEntry->Rect.xLeft || pEntry->Rect.yTop))
    378376        {
    379377            paTranslatedRects = (RTRECT*)RTMemAlloc(sizeof (RTRECT) * cRegions);
     
    386384            for (uint32_t i = 0; i < cRegions; ++i)
    387385            {
    388                 VBoxRectTranslate(&paTranslatedRects[i], pEntry->Pos.x, pEntry->Pos.y);
     386                VBoxRectTranslate(&paTranslatedRects[i], pEntry->Rect.xLeft, pEntry->Rect.yTop);
    389387                paRegions = paTranslatedRects;
    390388            }
     
    440438}
    441439
    442 VBOXVREGDECL(int) CrVrScrCompositorEntryResize(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTRECT *pRect)
    443 {
     440VBOXVREGDECL(int) CrVrScrCompositorEntryRectSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTRECT *pRect)
     441{
     442    if (!memcmp(&pEntry->Rect, pRect, sizeof (*pRect)))
     443    {
     444        return VINF_SUCCESS;
     445    }
    444446    RTPOINT Point = {pRect->xLeft, pRect->yTop};
    445447    bool fChanged = false;
     
    469471{
    470472    if (pEntry->pTex == pTex)
    471         return VINF)SUCCESS;
     473        return VINF_SUCCESS;
    472474
    473475    if (pEntry->pTex)
     
    476478        CrTdAddRef(pTex);
    477479    pEntry->pTex = pTex;
    478     return VINF)SUCCESS;
     480    return VINF_SUCCESS;
    479481}
    480482
     
    510512        }
    511513
    512         if (cRegions && (pEntry->Pos.x || pEntry->Pos.y))
     514        if (cRegions && (pEntry->Rect.xLeft || pEntry->Rect.yTop))
    513515        {
    514516            paTranslatedRects = (RTRECT*)RTMemAlloc(sizeof (RTRECT) * cRegions);
     
    521523            for (uint32_t i = 0; i < cRegions; ++i)
    522524            {
    523                 VBoxRectTranslate(&paTranslatedRects[i], pEntry->Pos.x, pEntry->Pos.y);
     525                VBoxRectTranslate(&paTranslatedRects[i], pEntry->Rect.xLeft, pEntry->Rect.yTop);
    524526                paRegions = paTranslatedRects;
    525527            }
     
    583585
    584586    if (fChanged)
    585     {
    586         CrVrScrCompositorEntrySetChanged(pEntry, true);
    587587        crVrScrCompositorRectsInvalidate(pCompositor);
    588     }
    589588
    590589    if (pfChanged)
     
    672671
    673672/* regions are valid until the next CrVrScrCompositor call */
    674 VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsGet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t *pcRegions, const RTRECT **ppaSrcRegions, const RTRECT **ppaDstRegions, const RTRECT **ppaDstUnstretchedRects)
     673VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsGet(const VBOXVR_SCR_COMPOSITOR *pCompositor, const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry, uint32_t *pcRegions, const RTRECT **ppaSrcRegions, const RTRECT **ppaDstRegions, const RTRECT **ppaDstUnstretchedRects)
    675674{
    676675        if (CrVrScrCompositorEntryIsUsed(pEntry))
     
    697696}
    698697
    699 VBOXVREGDECL(uint32_t) CrVrScrCompositorEntryFlagsCombinedGet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry)
     698VBOXVREGDECL(uint32_t) CrVrScrCompositorEntryFlagsCombinedGet(const VBOXVR_SCR_COMPOSITOR *pCompositor, const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry)
    700699{
    701700    return CRBLT_FOP_COMBINE(pCompositor->fFlags, pEntry->fFlags);
     
    757756{
    758757    PVBOXVR_SCR_COMPOSITOR_ENTRY pCEntry = VBOXVR_SCR_COMPOSITOR_ENTRY_FROM_ENTRY(pEntry);
     758
    759759    CrVrScrCompositorEntrySetChanged(pCEntry, true);
     760
     761    Assert(!CrVrScrCompositorEntryIsInList(pCEntry));
     762
     763    if (pReplacingEntry)
     764    {
     765        PVBOXVR_SCR_COMPOSITOR_ENTRY pCReplacingEntry = VBOXVR_SCR_COMPOSITOR_ENTRY_FROM_ENTRY(pReplacingEntry);
     766        Assert(CrVrScrCompositorEntryIsInList(pCReplacingEntry));
     767        pCReplacingEntry->cRects = pCEntry->cRects;
     768        pCReplacingEntry->paSrcRects = pCEntry->paSrcRects;
     769        pCReplacingEntry->paDstRects = pCEntry->paDstRects;
     770        pCReplacingEntry->paDstUnstretchedRects = pCEntry->paDstUnstretchedRects;
     771    }
    760772
    761773    if (pCEntry->pfnEntryReleased)
     
    769781VBOXVREGDECL(int) CrVrScrCompositorRectSet(PVBOXVR_SCR_COMPOSITOR pCompositor, const RTRECT *pRect, bool *pfChanged)
    770782{
    771     if (!memcmp(&pCompositor->Rect, pRect, sizeof (pCompositor->Rect))
     783    if (!memcmp(&pCompositor->Rect, pRect, sizeof (pCompositor->Rect)))
    772784    {
    773785        if (pfChanged)
    774             *pfChanged = false
     786            *pfChanged = false;
    775787        return VINF_SUCCESS;
    776788    }
     
    799811    VBoxVrCompositorInit(&pCompositor->Compositor, crVrScrCompositorEntryReleasedCB);
    800812    pCompositor->fFlags = CRBLT_F_LINEAR | CRBLT_F_INVERT_YCOORDS;
    801     pCompositor->Rect = *pRect;
     813    if (pRect)
     814        pCompositor->Rect = *pRect;
    802815#ifndef IN_RING0
    803816    pCompositor->StretchX = 1.0;
     
    863876
    864877/* regions are valid until the next CrVrScrCompositor call */
    865 VBOXVREGDECL(int) CrVrScrCompositorRegionsGet(PVBOXVR_SCR_COMPOSITOR pCompositor, uint32_t *pcRegions, const RTRECT **ppaSrcRegions, const RTRECT **ppaDstRegions, const RTRECT **ppaDstUnstretchedRects)
     878VBOXVREGDECL(int) CrVrScrCompositorRegionsGet(const VBOXVR_SCR_COMPOSITOR *pCompositor, uint32_t *pcRegions, const RTRECT **ppaSrcRegions, const RTRECT **ppaDstRegions, const RTRECT **ppaDstUnstretchedRects)
    866879{
    867880    int rc = crVrScrCompositorRectsCheckInit(pCompositor);
     
    907920}
    908921
    909 VBOXVREGDECL(int) CrVrScrCompositorClone(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR pDstCompositor, PFNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR pfnEntryFor, void* pvEntryFor)
     922VBOXVREGDECL(int) CrVrScrCompositorClone(const VBOXVR_SCR_COMPOSITOR *pCompositor, PVBOXVR_SCR_COMPOSITOR pDstCompositor, PFNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR pfnEntryFor, void* pvEntryFor)
    910923{
    911924    /* for simplicity just copy from one to another */
    912     CrVrScrCompositorInit(pDstCompositor);
    913     VBOXVR_SCR_COMPOSITOR_ITERATOR CIter;
    914     PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry;
    915     CrVrScrCompositorIterInit(pCompositor, &CIter);
     925    CrVrScrCompositorInit(pDstCompositor, CrVrScrCompositorRectGet(pCompositor));
     926    VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR CIter;
     927    const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry;
     928    CrVrScrCompositorConstIterInit(pCompositor, &CIter);
    916929    int rc = VINF_SUCCESS;
    917930    uint32_t cRects;
    918931    const RTRECT *pRects;
    919932
    920     while ((pEntry = CrVrScrCompositorIterNext(&CIter)) != NULL)
     933    while ((pEntry = CrVrScrCompositorConstIterNext(&CIter)) != NULL)
    921934    {
    922935        /* get source rects, that will be non-stretched and entry pos - pased */
     
    935948        }
    936949
    937         rc = CrVrScrCompositorEntryRegionsSet(pDstCompositor, pDstEntry, CrVrScrCompositorEntryPosGet(pEntry), cRects, pRects, false, NULL);
     950        rc = CrVrScrCompositorEntryRegionsSet(pDstCompositor, pDstEntry, NULL, cRects, pRects, false, NULL);
    938951        if (!RT_SUCCESS(rc))
    939952        {
     
    974987}
    975988
    976 VBOXVREGDECL(int) CrVrScrCompositorIntersectedList(PVBOXVR_SCR_COMPOSITOR pCompositor, const VBOXVR_LIST *pVr, PVBOXVR_SCR_COMPOSITOR pDstCompositor, PFNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR pfnEntryFor, void* pvEntryFor, bool *pfChanged)
     989VBOXVREGDECL(int) CrVrScrCompositorIntersectedList(const VBOXVR_SCR_COMPOSITOR *pCompositor, const VBOXVR_LIST *pVr, PVBOXVR_SCR_COMPOSITOR pDstCompositor, PFNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR pfnEntryFor, void* pvEntryFor, bool *pfChanged)
    977990{
    978991    int rc  = CrVrScrCompositorClone(pCompositor, pDstCompositor, pfnEntryFor, pvEntryFor);
  • trunk/src/VBox/GuestHost/OpenGL/util/error.c

    r47487 r50095  
    499499#else
    500500    if (!output
     501#ifndef DEBUG_misha
    501502            || output==stderr
     503#endif
    502504            )
    503505    {
  • trunk/src/VBox/GuestHost/OpenGL/util/htable.cpp

    r49772 r50095  
    1616 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
    1717 */
    18 #include <cr_htable.h>
     18#include <iprt/cdefs.h>
     19#include <iprt/asm.h>
     20#include "cr_spu.h"
     21#include "cr_vreg.h"
     22
     23#include "cr_htable.h"
     24#include "cr_spu.h"
     25#include "chromium.h"
     26#include "cr_error.h"
     27#include "cr_net.h"
     28#include "cr_rand.h"
     29#include "cr_mem.h"
     30#include "cr_string.h"
     31
     32#include <iprt/cdefs.h>
     33#include <iprt/types.h>
    1934#include <iprt/mem.h>
    20 
    21 #include <cr_error.h>
    22 #define WARN(_m) do { crWarning _m ; } while (0)
     35#include <iprt/err.h>
    2336
    2437VBOXHTABLEDECL(int) CrHTableCreate(PCRHTABLE pTbl, uint32_t cSize)
     
    3750}
    3851
    39 VBOXHTABLEDECL(void) CrHTableDestroy(PCRHTABLE pTbl);
     52VBOXHTABLEDECL(void) CrHTableDestroy(PCRHTABLE pTbl)
    4053{
    4154    if (!pTbl->paData)
    4255        return;
    4356
    44     RTMemMemFree(pTbl->paData);
     57    RTMemFree(pTbl->paData);
    4558}
    4659
     
    5063    if (cNewSize > pTbl->cSize)
    5164    {
    52         void **pvNewData = (PVOID*)RTMemAllocZ(sizeof (pTbl->paData[0]) * cNewSize);
     65        void **pvNewData = (void**)RTMemAllocZ(sizeof (pTbl->paData[0]) * cNewSize);
    5366        if (!pvNewData)
    5467        {
     
    8699static void* crHTablePutToSlot(PCRHTABLE pTbl, uint32_t iSlot, void* pvData)
    87100{
    88     void* pvOld = pTbl->paData[i];
    89     pTbl->paData[i] = pvData;
     101    void* pvOld = pTbl->paData[iSlot];
     102    pTbl->paData[iSlot] = pvData;
    90103    if (!pvOld)
    91104        ++pTbl->cData;
    92105    Assert(pTbl->cData <= pTbl->cSize);
    93 
     106    return pvOld;
    94107}
    95108
     
    112125}
    113126
    114 VBOXHTABLEDECL(CRHTABLE_HANDLE) CrHTablePut(PCRHTABLE pTbl, PVOID pvData)
     127VBOXHTABLEDECL(CRHTABLE_HANDLE) CrHTablePut(PCRHTABLE pTbl, void* pvData)
    115128{
    116129    if (pTbl->cSize == pTbl->cData)
     
    123136        }
    124137    }
    125     for (UINT i = pTbl->iNext2Search; ; ++i, i %= pTbl->cSize)
     138    for (uint32_t i = pTbl->iNext2Search; ; ++i, i %= pTbl->cSize)
    126139    {
    127140        Assert(i < pTbl->cSize);
     
    145158    if (iIndex < pTbl->cSize)
    146159    {
    147         PVOID pvData = pTbl->paData[iIndex];
     160        void* pvData = pTbl->paData[iIndex];
    148161        pTbl->paData[iIndex] = NULL;
    149162        --pTbl->cData;
  • trunk/src/VBox/GuestHost/OpenGL/util/vreg.cpp

    r48733 r50095  
    2222
    2323#include <cr_error.h>
    24 #define WARN(_m) do { crWarning _m ; } while (0)
     24
     25#ifdef DEBUG_misha
     26# define VBOXVDBG_VR_LAL_DISABLE
     27#endif
    2528
    2629#ifndef IN_RING0
     
    119122#endif
    120123
    121 #ifdef DEBUG_misha
    122 //# define VBOXVDBG_VR_LAL_DISABLE
    123 #endif
    124 
    125 #ifndef VBOXVDBG_VR_LAL_DISABLE
    126124static volatile int32_t g_cVBoxVrInits = 0;
    127 #endif
    128125
    129126static PVBOXVR_REG vboxVrRegCreate()
     
    11581155    RTListForEach(&pList->ListHead, pReg, const VBOXVR_REG, ListEntry)
    11591156    {
    1160         PVBOXVR_REG pDstReg = (PVBOXVR_REG)vboxVrRegLaAlloc(g_VBoxVrLookasideList);
     1157        PVBOXVR_REG pDstReg = vboxVrRegCreate();
    11611158        if (!pDstReg)
    11621159        {
     
    12131210}
    12141211
    1215 DECLINLINE(void) vboxVrCompositorEntryAcquire(PVBOXVR_COMPOSITOR_ENTRY pEntry)
     1212DECLINLINE(void) vboxVrCompositorEntryAddRef(PVBOXVR_COMPOSITOR_ENTRY pEntry)
    12161213{
    12171214    ++pEntry->cRefs;
     
    12211218{
    12221219    RTListPrepend(&pCompositor->List, &pEntry->Node);
    1223     vboxVrCompositorEntryAcquire(pEntry);
     1220    vboxVrCompositorEntryAddRef(pEntry);
    12241221}
    12251222
     
    12401237    pEntry->Node.pPrev = NULL;
    12411238
    1242     vboxVrCompositorEntryAcquire(pReplacingEntry);
     1239    vboxVrCompositorEntryAddRef(pReplacingEntry);
    12431240    vboxVrCompositorEntryRelease(pCompositor, pEntry, pReplacingEntry);
    12441241}
     
    12571254        return false;
    12581255
    1259     vboxVrCompositorEntryAcquire(pEntry);
     1256    vboxVrCompositorEntryAddRef(pEntry);
    12601257
    12611258    VBoxVrListClear(&pEntry->Vr);
     
    12781275{
    12791276    bool fChanged;
    1280     vboxVrCompositorEntryAcquire(pEntry);
     1277    vboxVrCompositorEntryAddRef(pEntry);
    12811278
    12821279    int rc = VBoxVrListRectsSubst(&pEntry->Vr, cRects, paRects, &fChanged);
     
    13001297VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsAdd(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, uint32_t cRects, const RTRECT *paRects, PVBOXVR_COMPOSITOR_ENTRY *ppReplacedEntry, uint32_t *pfChangeFlags)
    13011298{
    1302     bool fOthersChanged = false, fCurChanged = false, fEntryChanged = false, fEntryWasInList = false, fEntryReplaced = false;
    1303     PVBOXVR_COMPOSITOR_ENTRY pCur, pNext;
     1299    bool fOthersChanged = false, fCurChanged = false, fEntryChanged = false, fEntryWasInList = false;
     1300    PVBOXVR_COMPOSITOR_ENTRY pCur, pNext, pReplacedEntry = NULL;
    13041301    int rc = VINF_SUCCESS;
    13051302
    13061303    if (pEntry)
    1307         vboxVrCompositorEntryAcquire(pEntry);
     1304        vboxVrCompositorEntryAddRef(pEntry);
    13081305
    13091306    if (!cRects)
     
    13481345    {
    13491346        Assert(!VBoxVrListIsEmpty(&pCur->Vr));
    1350         if (pCur == pEntry)
    1351         {
    1352             Assert(fEntryWasInList);
    1353         }
    1354         else
     1347        if (pCur != pEntry)
    13551348        {
    13561349            if (pEntry && !VBoxVrListCmp(&pCur->Vr, &pEntry->Vr))
    13571350            {
    13581351                VBoxVrListClear(&pCur->Vr);
     1352                pReplacedEntry = pCur;
     1353                vboxVrCompositorEntryAddRef(pReplacedEntry);
    13591354                vboxVrCompositorEntryRemove(pCompositor, pCur, pEntry);
    13601355                if (ppReplacedEntry)
    1361                     *ppReplacedEntry = pCur;
    1362                 fEntryReplaced = true;
     1356                    *ppReplacedEntry = pReplacedEntry;
    13631357                break;
    13641358            }
     
    13891383    }
    13901384
     1385    uint32_t fFlags = 0;
     1386    if (fOthersChanged)
     1387    {
     1388        Assert(!pReplacedEntry);
     1389        fFlags = VBOXVR_COMPOSITOR_CF_ENTRY_REGIONS_CHANGED | VBOXVR_COMPOSITOR_CF_REGIONS_CHANGED | VBOXVR_COMPOSITOR_CF_OTHER_ENTRIES_REGIONS_CHANGED;
     1390    }
     1391    else if (pReplacedEntry)
     1392    {
     1393        vboxVrCompositorEntryRelease(pCompositor, pReplacedEntry, pEntry);
     1394        Assert(fEntryChanged);
     1395        fFlags = VBOXVR_COMPOSITOR_CF_ENTRY_REGIONS_CHANGED | VBOXVR_COMPOSITOR_CF_ENTRY_REPLACED;
     1396    }
     1397    else if (fEntryChanged)
     1398    {
     1399        Assert(!pReplacedEntry);
     1400        fFlags = VBOXVR_COMPOSITOR_CF_ENTRY_REGIONS_CHANGED | VBOXVR_COMPOSITOR_CF_REGIONS_CHANGED;
     1401    }
     1402    else
     1403    {
     1404        Assert(!pReplacedEntry);
     1405    }
     1406
     1407    if (!fEntryWasInList)
     1408        Assert(fEntryChanged);
     1409
    13911410    if (pfChangeFlags)
    1392     {
    1393         uint32_t fFlags = 0;
    1394         if (fOthersChanged)
    1395             fFlags = VBOXVR_COMPOSITOR_CF_ENTRY_REGIONS_CHANGED | VBOXVR_COMPOSITOR_CF_REGIONS_CHANGED | VBOXVR_COMPOSITOR_CF_OTHER_ENTRIES_REGIONS_CHANGED;
    1396         else if (fEntryReplaced)
    1397         {
    1398             Assert(fEntryChanged);
    1399             fFlags = VBOXVR_COMPOSITOR_CF_ENTRY_REGIONS_CHANGED | VBOXVR_COMPOSITOR_CF_ENTRY_REPLACED;
    1400         }
    1401         else if (fEntryChanged)
    1402             fFlags = VBOXVR_COMPOSITOR_CF_ENTRY_REGIONS_CHANGED | VBOXVR_COMPOSITOR_CF_REGIONS_CHANGED;
    1403 
    1404         if (!fEntryWasInList)
    1405             Assert(fEntryChanged);
    1406 
    14071411        *pfChangeFlags = fFlags;
    1408     }
    14091412
    14101413    return VINF_SUCCESS;
     
    14211424    }
    14221425
    1423     vboxVrCompositorEntryAcquire(pEntry);
     1426    vboxVrCompositorEntryAddRef(pEntry);
    14241427
    14251428    if (VBoxVrListIsEmpty(&pEntry->Vr))
     
    14291432        vboxVrCompositorEntryRelease(pCompositor, pEntry, NULL);
    14301433        return VINF_SUCCESS;
    1431 
    14321434    }
    14331435
     
    14511453    }
    14521454
    1453     vboxVrCompositorEntryAcquire(pEntry);
     1455    vboxVrCompositorEntryAddRef(pEntry);
    14541456
    14551457    bool fChanged = false, fCurChanged = false;
     
    14791481    bool fChanged = false;
    14801482
    1481     vboxVrCompositorEntryAcquire(pEntry);
     1483    vboxVrCompositorEntryAddRef(pEntry);
    14821484
    14831485    if (VBoxVrCompositorEntryIsInList(pEntry))
     
    15111513    bool fChanged = false;
    15121514
    1513     vboxVrCompositorEntryAcquire(pEntry);
     1515    vboxVrCompositorEntryAddRef(pEntry);
    15141516
    15151517    if (VBoxVrCompositorEntryIsInList(pEntry))
     
    16061608    }
    16071609
    1608     vboxVrCompositorEntryAcquire(pEntry);
     1610    vboxVrCompositorEntryAddRef(pEntry);
    16091611
    16101612    if ((!x && !y)
     
    16811683    }
    16821684}
    1683 
    1684 
    1685 
    1686 #define VBOXVR_SCR_COMPOSITOR_RECTS_UNDEFINED UINT32_MAX
    1687 
    1688 static int crVrScrCompositorRectsAssignBuffer(PVBOXVR_SCR_COMPOSITOR pCompositor, uint32_t cRects)
    1689 {
    1690     Assert(cRects);
    1691 
    1692     if (pCompositor->cRectsBuffer >= cRects)
    1693     {
    1694         pCompositor->cRects = cRects;
    1695         return VINF_SUCCESS;
    1696     }
    1697 
    1698     if (pCompositor->cRectsBuffer)
    1699     {
    1700         Assert(pCompositor->paSrcRects);
    1701         RTMemFree(pCompositor->paSrcRects);
    1702         pCompositor->paSrcRects = NULL;
    1703         Assert(pCompositor->paDstRects);
    1704         RTMemFree(pCompositor->paDstRects);
    1705         pCompositor->paDstRects = NULL;
    1706         Assert(pCompositor->paDstUnstretchedRects);
    1707         RTMemFree(pCompositor->paDstUnstretchedRects);
    1708         pCompositor->paDstUnstretchedRects = NULL;
    1709     }
    1710     else
    1711     {
    1712         Assert(!pCompositor->paSrcRects);
    1713         Assert(!pCompositor->paDstRects);
    1714         Assert(!pCompositor->paDstUnstretchedRects);
    1715     }
    1716 
    1717     pCompositor->paSrcRects = (PRTRECT)RTMemAlloc(sizeof (*pCompositor->paSrcRects) * cRects);
    1718     if (pCompositor->paSrcRects)
    1719     {
    1720         pCompositor->paDstRects = (PRTRECT)RTMemAlloc(sizeof (*pCompositor->paDstRects) * cRects);
    1721         if (pCompositor->paDstRects)
    1722         {
    1723             pCompositor->paDstUnstretchedRects = (PRTRECT)RTMemAlloc(sizeof (*pCompositor->paDstUnstretchedRects) * cRects);
    1724             if (pCompositor->paDstUnstretchedRects)
    1725             {
    1726                 pCompositor->cRects = cRects;
    1727                 pCompositor->cRectsBuffer = cRects;
    1728                 return VINF_SUCCESS;
    1729             }
    1730 
    1731             RTMemFree(pCompositor->paDstRects);
    1732             pCompositor->paDstRects = NULL;
    1733         }
    1734         else
    1735         {
    1736             WARN(("RTMemAlloc failed!"));
    1737         }
    1738         RTMemFree(pCompositor->paSrcRects);
    1739         pCompositor->paSrcRects = NULL;
    1740     }
    1741     else
    1742     {
    1743         WARN(("RTMemAlloc failed!"));
    1744     }
    1745 
    1746     pCompositor->cRects = VBOXVR_SCR_COMPOSITOR_RECTS_UNDEFINED;
    1747     pCompositor->cRectsBuffer = 0;
    1748 
    1749     return VERR_NO_MEMORY;
    1750 }
    1751 
    1752 static void crVrScrCompositorRectsInvalidate(PVBOXVR_SCR_COMPOSITOR pCompositor)
    1753 {
    1754     pCompositor->cRects = VBOXVR_SCR_COMPOSITOR_RECTS_UNDEFINED;
    1755 }
    1756 
    1757 static DECLCALLBACK(bool) crVrScrCompositorRectsCounterCb(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, void *pvVisitor)
    1758 {
    1759     uint32_t* pCounter = (uint32_t*)pvVisitor;
    1760     Assert(VBoxVrListRectsCount(&pEntry->Vr));
    1761     *pCounter += VBoxVrListRectsCount(&pEntry->Vr);
    1762     return true;
    1763 }
    1764 
    1765 typedef struct VBOXVR_SCR_COMPOSITOR_RECTS_ASSIGNER
    1766 {
    1767     PRTRECT paSrcRects;
    1768     PRTRECT paDstRects;
    1769     PRTRECT paDstUnstretchedRects;
    1770     uint32_t cRects;
    1771 } VBOXVR_SCR_COMPOSITOR_RECTS_ASSIGNER, *PVBOXVR_SCR_COMPOSITOR_RECTS_ASSIGNER;
    1772 
    1773 static DECLCALLBACK(bool) crVrScrCompositorRectsAssignerCb(PVBOXVR_COMPOSITOR pCCompositor, PVBOXVR_COMPOSITOR_ENTRY pCEntry, void *pvVisitor)
    1774 {
    1775     PVBOXVR_SCR_COMPOSITOR_RECTS_ASSIGNER pData = (PVBOXVR_SCR_COMPOSITOR_RECTS_ASSIGNER)pvVisitor;
    1776     PVBOXVR_SCR_COMPOSITOR pCompositor = VBOXVR_SCR_COMPOSITOR_FROM_COMPOSITOR(pCCompositor);
    1777     PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry = VBOXVR_SCR_COMPOSITOR_ENTRY_FROM_ENTRY(pCEntry);
    1778     pEntry->paSrcRects = pData->paSrcRects;
    1779     pEntry->paDstRects = pData->paDstRects;
    1780     pEntry->paDstUnstretchedRects = pData->paDstUnstretchedRects;
    1781     uint32_t cRects = VBoxVrListRectsCount(&pCEntry->Vr);
    1782     Assert(cRects);
    1783     Assert(cRects <= pData->cRects);
    1784     int rc = VBoxVrListRectsGet(&pCEntry->Vr, cRects, pEntry->paDstUnstretchedRects);
    1785     AssertRC(rc);
    1786 
    1787     if (!pEntry->Pos.x && !pEntry->Pos.y)
    1788     {
    1789         memcpy(pEntry->paSrcRects, pEntry->paDstUnstretchedRects, cRects * sizeof (*pEntry->paSrcRects));
    1790     }
    1791     else
    1792     {
    1793         for (uint32_t i = 0; i < cRects; ++i)
    1794         {
    1795             pEntry->paSrcRects[i].xLeft = (int32_t)((pEntry->paDstUnstretchedRects[i].xLeft - pEntry->Pos.x));
    1796             pEntry->paSrcRects[i].yTop = (int32_t)((pEntry->paDstUnstretchedRects[i].yTop - pEntry->Pos.y));
    1797             pEntry->paSrcRects[i].xRight = (int32_t)((pEntry->paDstUnstretchedRects[i].xRight - pEntry->Pos.x));
    1798             pEntry->paSrcRects[i].yBottom = (int32_t)((pEntry->paDstUnstretchedRects[i].yBottom - pEntry->Pos.y));
    1799         }
    1800     }
    1801 
    1802 #ifndef IN_RING0
    1803     if (pCompositor->StretchX != 1. || pCompositor->StretchY != 1.)
    1804     {
    1805         for (uint32_t i = 0; i < cRects; ++i)
    1806         {
    1807             if (pCompositor->StretchX != 1.)
    1808             {
    1809                 pEntry->paDstRects[i].xLeft = (int32_t)(pEntry->paDstUnstretchedRects[i].xLeft * pCompositor->StretchX);
    1810                 pEntry->paDstRects[i].xRight = (int32_t)(pEntry->paDstUnstretchedRects[i].xRight * pCompositor->StretchX);
    1811             }
    1812             if (pCompositor->StretchY != 1.)
    1813             {
    1814                 pEntry->paDstRects[i].yTop = (int32_t)(pEntry->paDstUnstretchedRects[i].yTop * pCompositor->StretchY);
    1815                 pEntry->paDstRects[i].yBottom = (int32_t)(pEntry->paDstUnstretchedRects[i].yBottom * pCompositor->StretchY);
    1816             }
    1817         }
    1818     }
    1819     else
    1820 #endif
    1821     {
    1822         memcpy(pEntry->paDstRects, pEntry->paDstUnstretchedRects, cRects * sizeof (*pEntry->paDstUnstretchedRects));
    1823     }
    1824 
    1825 #if 0//ndef IN_RING0
    1826     bool canZeroX = (pCompositor->StretchX < 1.);
    1827     bool canZeroY = (pCompositor->StretchY < 1.);
    1828     if (canZeroX && canZeroY)
    1829     {
    1830         /* filter out zero rectangles*/
    1831         uint32_t iOrig, iNew;
    1832         for (iOrig = 0, iNew = 0; iOrig < cRects; ++iOrig)
    1833         {
    1834             PRTRECT pOrigRect = &pEntry->paDstRects[iOrig];
    1835             if (pOrigRect->xLeft != pOrigRect->xRight
    1836                     && pOrigRect->yTop != pOrigRect->yBottom)
    1837                 continue;
    1838 
    1839             if (iNew != iOrig)
    1840             {
    1841                 PRTRECT pNewRect = &pEntry->paSrcRects[iNew];
    1842                 *pNewRect = *pOrigRect;
    1843             }
    1844 
    1845             ++iNew;
    1846         }
    1847 
    1848         Assert(iNew <= iOrig);
    1849 
    1850         uint32_t cDiff = iOrig - iNew;
    1851 
    1852         if (cDiff)
    1853         {
    1854             pCompositor->cRects -= cDiff;
    1855             cRects -= cDiff;
    1856         }
    1857     }
    1858 #endif
    1859 
    1860     pEntry->cRects = cRects;
    1861     pData->paDstRects += cRects;
    1862     pData->paSrcRects += cRects;
    1863     pData->paDstUnstretchedRects += cRects;
    1864     pData->cRects -= cRects;
    1865     return true;
    1866 }
    1867 
    1868 static int crVrScrCompositorRectsCheckInit(PVBOXVR_SCR_COMPOSITOR pCompositor)
    1869 {
    1870     if (pCompositor->cRects != VBOXVR_SCR_COMPOSITOR_RECTS_UNDEFINED)
    1871         return VINF_SUCCESS;
    1872 
    1873     uint32_t cRects = 0;
    1874     VBoxVrCompositorVisit(&pCompositor->Compositor, crVrScrCompositorRectsCounterCb, &cRects);
    1875 
    1876     if (!cRects)
    1877     {
    1878         pCompositor->cRects = 0;
    1879         return VINF_SUCCESS;
    1880     }
    1881 
    1882     int rc = crVrScrCompositorRectsAssignBuffer(pCompositor, cRects);
    1883     if (!RT_SUCCESS(rc))
    1884         return rc;
    1885 
    1886     VBOXVR_SCR_COMPOSITOR_RECTS_ASSIGNER AssignerData;
    1887     AssignerData.paSrcRects = pCompositor->paSrcRects;
    1888     AssignerData.paDstRects = pCompositor->paDstRects;
    1889     AssignerData.paDstUnstretchedRects = pCompositor->paDstUnstretchedRects;
    1890     AssignerData.cRects = pCompositor->cRects;
    1891     VBoxVrCompositorVisit(&pCompositor->Compositor, crVrScrCompositorRectsAssignerCb, &AssignerData);
    1892     Assert(!AssignerData.cRects);
    1893     return VINF_SUCCESS;
    1894 }
    1895 
    1896 
    1897 static int crVrScrCompositorEntryRegionsAdd(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, VBOXVR_SCR_COMPOSITOR_ENTRY **ppReplacedScrEntry, uint32_t *pfChangedFlags)
    1898 {
    1899     uint32_t fChangedFlags = 0;
    1900     PVBOXVR_COMPOSITOR_ENTRY pReplacedEntry;
    1901     int rc = VBoxVrCompositorEntryRegionsAdd(&pCompositor->Compositor, pEntry ? &pEntry->Ce : NULL, cRegions, paRegions, &pReplacedEntry, &fChangedFlags);
    1902     if (!RT_SUCCESS(rc))
    1903     {
    1904         WARN(("VBoxVrCompositorEntryRegionsAdd failed, rc %d", rc));
    1905         return rc;
    1906     }
    1907 
    1908     VBOXVR_SCR_COMPOSITOR_ENTRY *pReplacedScrEntry = VBOXVR_SCR_COMPOSITOR_ENTRY_FROM_ENTRY(pReplacedEntry);
    1909 
    1910     if (fChangedFlags & VBOXVR_COMPOSITOR_CF_REGIONS_CHANGED)
    1911     {
    1912         crVrScrCompositorRectsInvalidate(pCompositor);
    1913     }
    1914     else if (fChangedFlags & VBOXVR_COMPOSITOR_CF_ENTRY_REPLACED)
    1915     {
    1916         Assert(!CrVrScrCompositorEntryIsInList(pReplacedScrEntry));
    1917         Assert(CrVrScrCompositorEntryIsInList(pEntry));
    1918         pEntry->cRects = pReplacedScrEntry->cRects;
    1919         pEntry->paSrcRects = pReplacedScrEntry->paSrcRects;
    1920         pEntry->paDstRects = pReplacedScrEntry->paDstRects;
    1921         pEntry->paDstUnstretchedRects = pReplacedScrEntry->paDstUnstretchedRects;
    1922     }
    1923 
    1924     if (fChangedFlags & VBOXVR_COMPOSITOR_CF_OTHER_ENTRIES_REGIONS_CHANGED)
    1925     {
    1926         CrVrScrCompositorEntrySetAllChanged(pCompositor, true);
    1927     }
    1928     else if ((fChangedFlags & VBOXVR_COMPOSITOR_CF_ENTRY_REGIONS_CHANGED) && pEntry)
    1929     {
    1930         CrVrScrCompositorEntrySetChanged(pEntry, true);
    1931     }
    1932 
    1933     if (pfChangedFlags)
    1934         *pfChangedFlags = fChangedFlags;
    1935 
    1936     if (ppReplacedScrEntry)
    1937         *ppReplacedScrEntry = pReplacedScrEntry;
    1938 
    1939     return VINF_SUCCESS;
    1940 }
    1941 
    1942 static int crVrScrCompositorEntryRegionsSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged)
    1943 {
    1944     bool fChanged;
    1945     CrVrScrCompositorEntryIsInList(pEntry);
    1946     int rc = VBoxVrCompositorEntryRegionsSet(&pCompositor->Compositor, &pEntry->Ce, cRegions, paRegions, &fChanged);
    1947     if (!RT_SUCCESS(rc))
    1948     {
    1949         WARN(("VBoxVrCompositorEntryRegionsSet failed, rc %d", rc));
    1950         return rc;
    1951     }
    1952 
    1953     if (fChanged)
    1954     {
    1955         CrVrScrCompositorEntrySetAllChanged(pCompositor, true);
    1956         if (!CrVrScrCompositorEntryIsInList(pEntry))
    1957         {
    1958             pEntry->cRects = 0;
    1959             pEntry->paSrcRects = NULL;
    1960             pEntry->paDstRects = NULL;
    1961             pEntry->paDstUnstretchedRects = NULL;
    1962         }
    1963         crVrScrCompositorRectsInvalidate(pCompositor);
    1964     }
    1965 
    1966 
    1967     if (pfChanged)
    1968         *pfChanged = fChanged;
    1969     return VINF_SUCCESS;
    1970 }
    1971 
    1972 static int crVrScrCompositorEntryPositionSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos, bool *pfChanged)
    1973 {
    1974     if (pfChanged)
    1975         *pfChanged = false;
    1976     if (pEntry && (pEntry->Pos.x != pPos->x || pEntry->Pos.y != pPos->y))
    1977     {
    1978         if (VBoxVrCompositorEntryIsInList(&pEntry->Ce))
    1979         {
    1980             int rc = VBoxVrCompositorEntryRegionsTranslate(&pCompositor->Compositor, &pEntry->Ce, pPos->x - pEntry->Pos.x, pPos->y - pEntry->Pos.y, pfChanged);
    1981             if (!RT_SUCCESS(rc))
    1982             {
    1983                 WARN(("VBoxVrCompositorEntryRegionsTranslate failed rc %d", rc));
    1984                 return rc;
    1985             }
    1986 
    1987             crVrScrCompositorRectsInvalidate(pCompositor);
    1988         }
    1989 
    1990         pEntry->Pos = *pPos;
    1991         CrVrScrCompositorEntrySetChanged(pEntry, true);
    1992 
    1993         if (pfChanged)
    1994             *pfChanged = true;
    1995     }
    1996     return VINF_SUCCESS;
    1997 }
    1998 
    1999 static int crVrScrCompositorEntryEnsureRegionsInTex(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, bool *pfChanged)
    2000 {
    2001     RTRECT Rect;
    2002     Rect.xLeft = pEntry->Pos.x;
    2003     Rect.yTop = pEntry->Pos.y;
    2004     Rect.xRight = pEntry->Pos.x + pEntry->Tex.width;
    2005     Rect.yBottom = pEntry->Pos.y + pEntry->Tex.height;
    2006     bool fChanged = false;
    2007 
    2008     if (pfChanged)
    2009         *pfChanged = false;
    2010 
    2011     int rc = CrVrScrCompositorEntryRegionsIntersect(pCompositor, pEntry, 1, &Rect, &fChanged);
    2012     if (!RT_SUCCESS(rc))
    2013         WARN(("CrVrScrCompositorEntryRegionsIntersect failed, rc %d", rc));
    2014 
    2015     if (fChanged)
    2016     {
    2017         CrVrScrCompositorEntrySetChanged(pEntry, true);
    2018         crVrScrCompositorRectsInvalidate(pCompositor);
    2019     }
    2020 
    2021     if (pfChanged)
    2022         *pfChanged = fChanged;
    2023     return rc;
    2024 }
    2025 
    2026 VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsAdd(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, bool fPosRelated, VBOXVR_SCR_COMPOSITOR_ENTRY **ppReplacedScrEntry, uint32_t *pfChangeFlags)
    2027 {
    2028     int rc;
    2029     uint32_t fChangeFlags = 0;
    2030     bool fPosChanged = false;
    2031     RTRECT *paTranslatedRects = NULL;
    2032     if (pPos)
    2033     {
    2034         rc = crVrScrCompositorEntryPositionSet(pCompositor, pEntry, pPos, &fPosChanged);
    2035         if (!RT_SUCCESS(rc))
    2036         {
    2037             WARN(("RegionsAdd: crVrScrCompositorEntryPositionSet failed rc %d", rc));
    2038             return rc;
    2039         }
    2040     }
    2041 
    2042     if (fPosRelated)
    2043     {
    2044         if (!pEntry)
    2045         {
    2046             WARN(("Entry is expected to be specified for pos-related regions"));
    2047             return VERR_INVALID_PARAMETER;
    2048         }
    2049 
    2050         if (cRegions && (pEntry->Pos.x || pEntry->Pos.y))
    2051         {
    2052             paTranslatedRects = (RTRECT*)RTMemAlloc(sizeof (RTRECT) * cRegions);
    2053             if (!paTranslatedRects)
    2054             {
    2055                 WARN(("RTMemAlloc failed"));
    2056                 return VERR_NO_MEMORY;
    2057             }
    2058             memcpy (paTranslatedRects, paRegions, sizeof (RTRECT) * cRegions);
    2059             for (uint32_t i = 0; i < cRegions; ++i)
    2060             {
    2061                 VBoxRectTranslate(&paTranslatedRects[i], pEntry->Pos.x, pEntry->Pos.y);
    2062                 paRegions = paTranslatedRects;
    2063             }
    2064         }
    2065     }
    2066 
    2067     rc = crVrScrCompositorEntryRegionsAdd(pCompositor, pEntry, cRegions, paRegions, ppReplacedScrEntry, &fChangeFlags);
    2068     if (!RT_SUCCESS(rc))
    2069     {
    2070         WARN(("crVrScrCompositorEntryRegionsAdd failed, rc %d", rc));
    2071         goto done;
    2072     }
    2073 
    2074     if ((fPosChanged || (fChangeFlags & VBOXVR_COMPOSITOR_CF_ENTRY_REGIONS_CHANGED)) && pEntry)
    2075     {
    2076         bool fAdjusted = false;
    2077         rc = crVrScrCompositorEntryEnsureRegionsInTex(pCompositor, pEntry, &fAdjusted);
    2078         if (!RT_SUCCESS(rc))
    2079         {
    2080             WARN(("crVrScrCompositorEntryEnsureRegionsInTex failed, rc %d", rc));
    2081             goto done;
    2082         }
    2083 
    2084         if (fAdjusted)
    2085         {
    2086             fChangeFlags &= ~VBOXVR_COMPOSITOR_CF_ENTRY_REPLACED;
    2087             fChangeFlags |= VBOXVR_COMPOSITOR_CF_REGIONS_CHANGED | VBOXVR_COMPOSITOR_CF_ENTRY_REGIONS_CHANGED;
    2088         }
    2089     }
    2090 
    2091     if (fChangeFlags & VBOXVR_COMPOSITOR_CF_ENTRY_REPLACED)
    2092         fPosChanged = false;
    2093     else if (ppReplacedScrEntry)
    2094         *ppReplacedScrEntry = NULL;
    2095 
    2096     if (pfChangeFlags)
    2097     {
    2098         if (fPosChanged)
    2099         {
    2100             /* means entry was in list and was moved, so regions changed */
    2101             *pfChangeFlags = VBOXVR_COMPOSITOR_CF_REGIONS_CHANGED | VBOXVR_COMPOSITOR_CF_ENTRY_REGIONS_CHANGED | VBOXVR_COMPOSITOR_CF_OTHER_ENTRIES_REGIONS_CHANGED;
    2102         }
    2103         else
    2104             *pfChangeFlags = fChangeFlags;
    2105     }
    2106 
    2107 done:
    2108 
    2109     if (paTranslatedRects)
    2110         RTMemFree(paTranslatedRects);
    2111 
    2112     return rc;
    2113 }
    2114 
    2115 VBOXVREGDECL(int) CrVrScrCompositorEntryTexUpdate(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const VBOXVR_TEXTURE *pTex)
    2116 {
    2117     bool fCompositorChanged = CrVrScrCompositorEntryIsUsed(pEntry) && (pEntry->Tex.width != pTex->width || pEntry->Tex.height != pTex->height);
    2118     pEntry->Tex = *pTex;
    2119     CrVrScrCompositorEntrySetChanged(pEntry, true);
    2120     if (fCompositorChanged)
    2121     {
    2122         int rc = crVrScrCompositorEntryEnsureRegionsInTex(pCompositor, pEntry, NULL);
    2123         if (!RT_SUCCESS(rc))
    2124         {
    2125             WARN(("crVrScrCompositorEntryEnsureRegionsInTex failed rc %d", rc));
    2126             return rc;
    2127         }
    2128     }
    2129     return VINF_SUCCESS;
    2130 }
    2131 
    2132 VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, bool fPosRelated, bool *pfChanged)
    2133 {
    2134     /* @todo: the fChanged sate calculation is really rough now, this is enough for now though */
    2135     bool fChanged = false, fPosChanged = false;
    2136     bool fWasInList = CrVrScrCompositorEntryIsInList(pEntry);
    2137     RTRECT *paTranslatedRects = NULL;
    2138     int rc = CrVrScrCompositorEntryRemove(pCompositor, pEntry);
    2139     if (!RT_SUCCESS(rc))
    2140     {
    2141         WARN(("RegionsSet: CrVrScrCompositorEntryRemove failed rc %d", rc));
    2142         return rc;
    2143     }
    2144 
    2145     if (pPos)
    2146     {
    2147         rc = crVrScrCompositorEntryPositionSet(pCompositor, pEntry, pPos, &fPosChanged);
    2148         if (!RT_SUCCESS(rc))
    2149         {
    2150             WARN(("RegionsSet: crVrScrCompositorEntryPositionSet failed rc %d", rc));
    2151             return rc;
    2152         }
    2153     }
    2154 
    2155     if (fPosRelated)
    2156     {
    2157         if (!pEntry)
    2158         {
    2159             WARN(("Entry is expected to be specified for pos-related regions"));
    2160             return VERR_INVALID_PARAMETER;
    2161         }
    2162 
    2163         if (cRegions && (pEntry->Pos.x || pEntry->Pos.y))
    2164         {
    2165             paTranslatedRects = (RTRECT*)RTMemAlloc(sizeof (RTRECT) * cRegions);
    2166             if (!paTranslatedRects)
    2167             {
    2168                 WARN(("RTMemAlloc failed"));
    2169                 return VERR_NO_MEMORY;
    2170             }
    2171             memcpy (paTranslatedRects, paRegions, sizeof (RTRECT) * cRegions);
    2172             for (uint32_t i = 0; i < cRegions; ++i)
    2173             {
    2174                 VBoxRectTranslate(&paTranslatedRects[i], pEntry->Pos.x, pEntry->Pos.y);
    2175                 paRegions = paTranslatedRects;
    2176             }
    2177         }
    2178     }
    2179 
    2180     rc = crVrScrCompositorEntryRegionsSet(pCompositor, pEntry, cRegions, paRegions, &fChanged);
    2181     if (!RT_SUCCESS(rc))
    2182     {
    2183         WARN(("crVrScrCompositorEntryRegionsSet failed, rc %d", rc));
    2184         return rc;
    2185     }
    2186 
    2187     if (fChanged && CrVrScrCompositorEntryIsUsed(pEntry))
    2188     {
    2189         rc = crVrScrCompositorEntryEnsureRegionsInTex(pCompositor, pEntry, NULL);
    2190         if (!RT_SUCCESS(rc))
    2191         {
    2192             WARN(("crVrScrCompositorEntryEnsureRegionsInTex failed, rc %d", rc));
    2193             return rc;
    2194         }
    2195     }
    2196 
    2197     if (pfChanged)
    2198         *pfChanged = fPosChanged || fChanged || fWasInList;
    2199 
    2200     return VINF_SUCCESS;
    2201 }
    2202 
    2203 VBOXVREGDECL(int) CrVrScrCompositorEntryListIntersect(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const VBOXVR_LIST *pList2, bool *pfChanged)
    2204 {
    2205     bool fChanged = false;
    2206     int rc = VBoxVrCompositorEntryListIntersect(&pCompositor->Compositor, &pEntry->Ce, pList2, &fChanged);
    2207     if (!RT_SUCCESS(rc))
    2208     {
    2209         WARN(("RegionsIntersect: VBoxVrCompositorEntryRegionsIntersect failed rc %d", rc));
    2210         return rc;
    2211     }
    2212 
    2213     if (fChanged)
    2214     {
    2215         CrVrScrCompositorEntrySetChanged(pEntry, true);
    2216         crVrScrCompositorRectsInvalidate(pCompositor);
    2217     }
    2218 
    2219     if (pfChanged)
    2220         *pfChanged = fChanged;
    2221 
    2222     return VINF_SUCCESS;
    2223 }
    2224 
    2225 VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsIntersect(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged)
    2226 {
    2227     bool fChanged = false;
    2228     int rc = VBoxVrCompositorEntryRegionsIntersect(&pCompositor->Compositor, &pEntry->Ce, cRegions, paRegions, &fChanged);
    2229     if (!RT_SUCCESS(rc))
    2230     {
    2231         WARN(("RegionsIntersect: VBoxVrCompositorEntryRegionsIntersect failed rc %d", rc));
    2232         return rc;
    2233     }
    2234 
    2235     if (fChanged)
    2236     {
    2237         CrVrScrCompositorEntrySetChanged(pEntry, true);
    2238         crVrScrCompositorRectsInvalidate(pCompositor);
    2239     }
    2240 
    2241     if (pfChanged)
    2242         *pfChanged = fChanged;
    2243 
    2244     return VINF_SUCCESS;
    2245 }
    2246 
    2247 VBOXVREGDECL(int) CrVrScrCompositorEntryListIntersectAll(PVBOXVR_SCR_COMPOSITOR pCompositor, const VBOXVR_LIST *pList2, bool *pfChanged)
    2248 {
    2249     VBOXVR_SCR_COMPOSITOR_ITERATOR Iter;
    2250     CrVrScrCompositorIterInit(pCompositor, &Iter);
    2251     PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry;
    2252     int rc = VINF_SUCCESS;
    2253     bool fChanged = false;
    2254 
    2255     while ((pEntry = CrVrScrCompositorIterNext(&Iter)) != NULL)
    2256     {
    2257         bool fTmpChanged = false;
    2258         int tmpRc = CrVrScrCompositorEntryListIntersect(pCompositor, pEntry, pList2, &fTmpChanged);
    2259         if (RT_SUCCESS(tmpRc))
    2260         {
    2261             fChanged |= fTmpChanged;
    2262         }
    2263         else
    2264         {
    2265             WARN(("CrVrScrCompositorEntryRegionsIntersect failed, rc %d", tmpRc));
    2266             rc = tmpRc;
    2267         }
    2268     }
    2269 
    2270     if (pfChanged)
    2271         *pfChanged = fChanged;
    2272 
    2273     return rc;
    2274 }
    2275 
    2276 VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsIntersectAll(PVBOXVR_SCR_COMPOSITOR pCompositor, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged)
    2277 {
    2278     VBOXVR_SCR_COMPOSITOR_ITERATOR Iter;
    2279     CrVrScrCompositorIterInit(pCompositor, &Iter);
    2280     PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry;
    2281     int rc = VINF_SUCCESS;
    2282     bool fChanged = false;
    2283 
    2284     while ((pEntry = CrVrScrCompositorIterNext(&Iter)) != NULL)
    2285     {
    2286         bool fTmpChanged = false;
    2287         int tmpRc = CrVrScrCompositorEntryRegionsIntersect(pCompositor, pEntry, cRegions, paRegions, &fTmpChanged);
    2288         if (RT_SUCCESS(tmpRc))
    2289         {
    2290             fChanged |= fTmpChanged;
    2291         }
    2292         else
    2293         {
    2294             WARN(("CrVrScrCompositorEntryRegionsIntersect failed, rc %d", tmpRc));
    2295             rc = tmpRc;
    2296         }
    2297     }
    2298 
    2299     if (pfChanged)
    2300         *pfChanged = fChanged;
    2301 
    2302     return rc;
    2303 }
    2304 
    2305 VBOXVREGDECL(int) CrVrScrCompositorEntryPosSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos)
    2306 {
    2307     int rc = crVrScrCompositorEntryPositionSet(pCompositor, pEntry, pPos, NULL);
    2308     if (!RT_SUCCESS(rc))
    2309     {
    2310         WARN(("RegionsSet: crVrScrCompositorEntryPositionSet failed rc %d", rc));
    2311         return rc;
    2312     }
    2313     return VINF_SUCCESS;
    2314 }
    2315 
    2316 /* regions are valid until the next CrVrScrCompositor call */
    2317 VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsGet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t *pcRegions, const RTRECT **ppaSrcRegions, const RTRECT **ppaDstRegions, const RTRECT **ppaDstUnstretchedRects)
    2318 {
    2319     int rc = crVrScrCompositorRectsCheckInit(pCompositor);
    2320     if (!RT_SUCCESS(rc))
    2321     {
    2322         WARN(("crVrScrCompositorRectsCheckInit failed, rc %d", rc));
    2323         return rc;
    2324     }
    2325 
    2326     Assert(pCompositor->cRects != VBOXVR_SCR_COMPOSITOR_RECTS_UNDEFINED);
    2327 
    2328     *pcRegions = pEntry->cRects;
    2329     if (ppaSrcRegions)
    2330         *ppaSrcRegions = pEntry->paSrcRects;
    2331     if (ppaDstRegions)
    2332         *ppaDstRegions = pEntry->paDstRects;
    2333     if (ppaDstUnstretchedRects)
    2334         *ppaDstUnstretchedRects = pEntry->paDstUnstretchedRects;
    2335 
    2336     return VINF_SUCCESS;
    2337 }
    2338 
    2339 VBOXVREGDECL(uint32_t) CrVrScrCompositorEntryFlagsCombinedGet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry)
    2340 {
    2341     return CRBLT_FOP_COMBINE(pCompositor->fFlags, pEntry->fFlags);
    2342 }
    2343 
    2344 VBOXVREGDECL(void) CrVrScrCompositorEntryFlagsSet(PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t fFlags)
    2345 {
    2346     if (pEntry->fFlags == fFlags)
    2347         return;
    2348 
    2349     pEntry->fFlags = fFlags;
    2350     CrVrScrCompositorEntrySetChanged(pEntry, true);
    2351 }
    2352 
    2353 static void crVrScrCompositorEntryDataCleanup(PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry)
    2354 {
    2355     pEntry->cRects = 0;
    2356     pEntry->paSrcRects = NULL;
    2357     pEntry->paDstRects = NULL;
    2358     pEntry->paDstUnstretchedRects = NULL;
    2359 }
    2360 
    2361 static void crVrScrCompositorEntryDataCopy(PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, PVBOXVR_SCR_COMPOSITOR_ENTRY pToEntry)
    2362 {
    2363     pToEntry->cRects = pEntry->cRects;
    2364     pToEntry->paSrcRects = pEntry->paSrcRects;
    2365     pToEntry->paDstRects = pEntry->paDstRects;
    2366     pToEntry->paDstUnstretchedRects = pEntry->paDstUnstretchedRects;
    2367     crVrScrCompositorEntryDataCleanup(pEntry);
    2368 }
    2369 
    2370 VBOXVREGDECL(int) CrVrScrCompositorEntryRemove(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry)
    2371 {
    2372     if (!VBoxVrCompositorEntryRemove(&pCompositor->Compositor, &pEntry->Ce))
    2373         return VINF_SUCCESS;
    2374 
    2375     CrVrScrCompositorEntrySetChanged(pEntry, true);
    2376     crVrScrCompositorEntryDataCleanup(pEntry);
    2377 
    2378     crVrScrCompositorRectsInvalidate(pCompositor);
    2379     return VINF_SUCCESS;
    2380 }
    2381 
    2382 VBOXVREGDECL(bool) CrVrScrCompositorEntryReplace(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, PVBOXVR_SCR_COMPOSITOR_ENTRY pNewEntry)
    2383 {
    2384     Assert(!CrVrScrCompositorEntryIsUsed(pNewEntry));
    2385 
    2386     if (!VBoxVrCompositorEntryReplace(&pCompositor->Compositor, &pEntry->Ce, &pNewEntry->Ce))
    2387         return false;
    2388 
    2389     CrVrScrCompositorEntrySetChanged(pEntry, true);
    2390     crVrScrCompositorEntryDataCopy(pEntry, pNewEntry);
    2391     CrVrScrCompositorEntrySetChanged(pNewEntry, true);
    2392 
    2393     return true;
    2394 }
    2395 
    2396 static DECLCALLBACK(void) crVrScrCompositorEntryReleasedCB(const struct VBOXVR_COMPOSITOR *pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, PVBOXVR_COMPOSITOR_ENTRY pReplacingEntry)
    2397 {
    2398     PVBOXVR_SCR_COMPOSITOR_ENTRY pCEntry = VBOXVR_SCR_COMPOSITOR_ENTRY_FROM_ENTRY(pEntry);
    2399     CrVrScrCompositorEntrySetChanged(pCEntry, true);
    2400 
    2401     if (pCEntry->pfnEntryReleased)
    2402     {
    2403         PVBOXVR_SCR_COMPOSITOR_ENTRY pCReplacingEntry = pReplacingEntry ? VBOXVR_SCR_COMPOSITOR_ENTRY_FROM_ENTRY(pReplacingEntry) : NULL;
    2404         PVBOXVR_SCR_COMPOSITOR pCConpositor = VBOXVR_SCR_COMPOSITOR_FROM_COMPOSITOR(pCompositor);
    2405         pCEntry->pfnEntryReleased(pCConpositor, pCEntry, pCReplacingEntry);
    2406     }
    2407 }
    2408 
    2409 VBOXVREGDECL(void) CrVrScrCompositorInit(PVBOXVR_SCR_COMPOSITOR pCompositor)
    2410 {
    2411     memset(pCompositor, 0, sizeof (*pCompositor));
    2412     VBoxVrCompositorInit(&pCompositor->Compositor, crVrScrCompositorEntryReleasedCB);
    2413     pCompositor->fFlags = CRBLT_F_LINEAR | CRBLT_F_INVERT_YCOORDS;
    2414 #ifndef IN_RING0
    2415     pCompositor->StretchX = 1.0;
    2416     pCompositor->StretchY = 1.0;
    2417 #endif
    2418 }
    2419 
    2420 VBOXVREGDECL(void) CrVrScrCompositorRegionsClear(PVBOXVR_SCR_COMPOSITOR pCompositor, bool *pfChanged)
    2421 {
    2422     /* set changed flag first, while entries are in the list and we have them */
    2423     CrVrScrCompositorEntrySetAllChanged(pCompositor, true);
    2424     VBoxVrCompositorRegionsClear(&pCompositor->Compositor, pfChanged);
    2425     crVrScrCompositorRectsInvalidate(pCompositor);
    2426 }
    2427 
    2428 VBOXVREGDECL(void) CrVrScrCompositorClear(PVBOXVR_SCR_COMPOSITOR pCompositor)
    2429 {
    2430     CrVrScrCompositorRegionsClear(pCompositor, NULL);
    2431     if (pCompositor->paDstRects)
    2432     {
    2433         RTMemFree(pCompositor->paDstRects);
    2434         pCompositor->paDstRects = NULL;
    2435     }
    2436     if (pCompositor->paSrcRects)
    2437     {
    2438         RTMemFree(pCompositor->paSrcRects);
    2439         pCompositor->paSrcRects = NULL;
    2440     }
    2441     if (pCompositor->paDstUnstretchedRects)
    2442     {
    2443         RTMemFree(pCompositor->paDstUnstretchedRects);
    2444         pCompositor->paDstUnstretchedRects = NULL;
    2445     }
    2446 
    2447     pCompositor->cRects = 0;
    2448     pCompositor->cRectsBuffer = 0;
    2449 }
    2450 
    2451 VBOXVREGDECL(void) CrVrScrCompositorEntrySetAllChanged(PVBOXVR_SCR_COMPOSITOR pCompositor, bool fChanged)
    2452 {
    2453     VBOXVR_SCR_COMPOSITOR_ITERATOR CIter;
    2454     PVBOXVR_SCR_COMPOSITOR_ENTRY pCurEntry;
    2455     CrVrScrCompositorIterInit(pCompositor, &CIter);
    2456 
    2457     while ((pCurEntry = CrVrScrCompositorIterNext(&CIter)) != NULL)
    2458     {
    2459         CrVrScrCompositorEntrySetChanged(pCurEntry, fChanged);
    2460     }
    2461 }
    2462 
    2463 #ifndef IN_RING0
    2464 VBOXVREGDECL(void) CrVrScrCompositorSetStretching(PVBOXVR_SCR_COMPOSITOR pCompositor, float StretchX, float StretchY)
    2465 {
    2466     if (pCompositor->StretchX == StretchX && pCompositor->StretchY == StretchY)
    2467         return;
    2468 
    2469     pCompositor->StretchX = StretchX;
    2470     pCompositor->StretchY = StretchY;
    2471     crVrScrCompositorRectsInvalidate(pCompositor);
    2472     CrVrScrCompositorEntrySetAllChanged(pCompositor, true);
    2473 }
    2474 #endif
    2475 
    2476 /* regions are valid until the next CrVrScrCompositor call */
    2477 VBOXVREGDECL(int) CrVrScrCompositorRegionsGet(PVBOXVR_SCR_COMPOSITOR pCompositor, uint32_t *pcRegions, const RTRECT **ppaSrcRegions, const RTRECT **ppaDstRegions, const RTRECT **ppaDstUnstretchedRects)
    2478 {
    2479     int rc = crVrScrCompositorRectsCheckInit(pCompositor);
    2480     if (!RT_SUCCESS(rc))
    2481     {
    2482         WARN(("crVrScrCompositorRectsCheckInit failed, rc %d", rc));
    2483         return rc;
    2484     }
    2485 
    2486     Assert(pCompositor->cRects != VBOXVR_SCR_COMPOSITOR_RECTS_UNDEFINED);
    2487 
    2488     *pcRegions = pCompositor->cRects;
    2489     if (ppaSrcRegions)
    2490         *ppaSrcRegions = pCompositor->paSrcRects;
    2491     if (ppaDstRegions)
    2492         *ppaDstRegions = pCompositor->paDstRects;
    2493     if (ppaDstUnstretchedRects)
    2494         *ppaDstUnstretchedRects = pCompositor->paDstUnstretchedRects;
    2495 
    2496     return VINF_SUCCESS;
    2497 }
    2498 
    2499 typedef struct VBOXVR_SCR_COMPOSITOR_VISITOR_CB
    2500 {
    2501     PFNVBOXVRSCRCOMPOSITOR_VISITOR pfnVisitor;
    2502     void *pvVisitor;
    2503 } VBOXVR_SCR_COMPOSITOR_VISITOR_CB, *PVBOXVR_SCR_COMPOSITOR_VISITOR_CB;
    2504 
    2505 static DECLCALLBACK(bool) crVrScrCompositorVisitCb(PVBOXVR_COMPOSITOR pCCompositor, PVBOXVR_COMPOSITOR_ENTRY pCEntry, void *pvVisitor)
    2506 {
    2507     PVBOXVR_SCR_COMPOSITOR_VISITOR_CB pData = (PVBOXVR_SCR_COMPOSITOR_VISITOR_CB)pvVisitor;
    2508     PVBOXVR_SCR_COMPOSITOR pCompositor = VBOXVR_SCR_COMPOSITOR_FROM_COMPOSITOR(pCCompositor);
    2509     PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry = VBOXVR_SCR_COMPOSITOR_ENTRY_FROM_ENTRY(pCEntry);
    2510     return pData->pfnVisitor(pCompositor, pEntry, pData->pvVisitor);
    2511 }
    2512 
    2513 VBOXVREGDECL(void) CrVrScrCompositorVisit(PVBOXVR_SCR_COMPOSITOR pCompositor, PFNVBOXVRSCRCOMPOSITOR_VISITOR pfnVisitor, void *pvVisitor)
    2514 {
    2515     VBOXVR_SCR_COMPOSITOR_VISITOR_CB Data;
    2516     Data.pfnVisitor = pfnVisitor;
    2517     Data.pvVisitor = pvVisitor;
    2518     VBoxVrCompositorVisit(&pCompositor->Compositor, crVrScrCompositorVisitCb, &Data);
    2519 }
    2520 
    2521 VBOXVREGDECL(int) CrVrScrCompositorClone(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR pDstCompositor, PFNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR pfnEntryFor, void* pvEntryFor)
    2522 {
    2523     /* for simplicity just copy from one to another */
    2524     CrVrScrCompositorInit(pDstCompositor);
    2525     VBOXVR_SCR_COMPOSITOR_ITERATOR CIter;
    2526     PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry;
    2527     CrVrScrCompositorIterInit(pCompositor, &CIter);
    2528     int rc = VINF_SUCCESS;
    2529     uint32_t cRects;
    2530     const RTRECT *pRects;
    2531 
    2532     while ((pEntry = CrVrScrCompositorIterNext(&CIter)) != NULL)
    2533     {
    2534         /* get source rects, that will be non-stretched and entry pos - pased */
    2535         rc = CrVrScrCompositorEntryRegionsGet(pCompositor, pEntry, &cRects, NULL, NULL, &pRects);
    2536         if (!RT_SUCCESS(rc))
    2537         {
    2538             WARN(("CrVrScrCompositorEntryRegionsGet failed, rc %d", rc));
    2539             return rc;
    2540         }
    2541 
    2542         PVBOXVR_SCR_COMPOSITOR_ENTRY pDstEntry = pfnEntryFor(pEntry, pvEntryFor);
    2543         if (!pDstEntry)
    2544         {
    2545             WARN(("pfnEntryFor failed"));
    2546             return VERR_INVALID_STATE;
    2547         }
    2548 
    2549         rc = CrVrScrCompositorEntryRegionsSet(pDstCompositor, pDstEntry, CrVrScrCompositorEntryPosGet(pEntry), cRects, pRects, false, NULL);
    2550         if (!RT_SUCCESS(rc))
    2551         {
    2552             crWarning("CrVrScrCompositorEntryRegionsSet failed, rc %d", rc);
    2553             return rc;
    2554         }
    2555     }
    2556 
    2557     return rc;
    2558 }
    2559 
    2560 VBOXVREGDECL(int) CrVrScrCompositorIntersectList(PVBOXVR_SCR_COMPOSITOR pCompositor, const VBOXVR_LIST *pVr, bool *pfChanged)
    2561 {
    2562     VBOXVR_SCR_COMPOSITOR_ITERATOR CIter;
    2563     PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry;
    2564     CrVrScrCompositorIterInit(pCompositor, &CIter);
    2565     int rc = VINF_SUCCESS;
    2566     bool fChanged = false;
    2567 
    2568     while ((pEntry = CrVrScrCompositorIterNext(&CIter)) != NULL)
    2569     {
    2570         bool fCurChanged = false;
    2571 
    2572         rc = CrVrScrCompositorEntryListIntersect(pCompositor, pEntry, pVr, &fCurChanged);
    2573         if (!RT_SUCCESS(rc))
    2574         {
    2575             crWarning("CrVrScrCompositorEntryRegionsSet failed, rc %d", rc);
    2576             break;
    2577         }
    2578 
    2579         fChanged |= fCurChanged;
    2580     }
    2581 
    2582     if (pfChanged)
    2583         *pfChanged = fChanged;
    2584 
    2585     return rc;
    2586 }
    2587 
    2588 VBOXVREGDECL(int) CrVrScrCompositorIntersectedList(PVBOXVR_SCR_COMPOSITOR pCompositor, const VBOXVR_LIST *pVr, PVBOXVR_SCR_COMPOSITOR pDstCompositor, PFNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR pfnEntryFor, void* pvEntryFor, bool *pfChanged)
    2589 {
    2590     int rc  = CrVrScrCompositorClone(pCompositor, pDstCompositor, pfnEntryFor, pvEntryFor);
    2591     if (!RT_SUCCESS(rc))
    2592     {
    2593         WARN(("CrVrScrCompositorClone failed, rc %d", rc));
    2594         return rc;
    2595     }
    2596 
    2597     rc = CrVrScrCompositorIntersectList(pDstCompositor, pVr, pfChanged);
    2598     if (!RT_SUCCESS(rc))
    2599     {
    2600         WARN(("CrVrScrCompositorIntersectList failed, rc %d", rc));
    2601         CrVrScrCompositorClear(pDstCompositor);
    2602         return rc;
    2603     }
    2604 
    2605     return VINF_SUCCESS;
    2606 }
  • trunk/src/VBox/HostServices/SharedOpenGL/Makefile.kmk

    r50041 r50095  
    132132        crserverlib/server_framebuffer.c \
    133133        crserverlib/server_glsl.c \
    134         crserverlib/server_muralfbo.c \
     134        crserverlib/server_muralfbo.cpp \
    135135        crserverlib/server_texture.c \
     136        crserverlib/server_vertattr.c \
    136137        crserverlib/server_presenter.cpp \
    137138        crserverlib/server_rpw.cpp \
  • trunk/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp

    r49474 r50095  
    11741174            break;
    11751175        }
     1176        case SHCRGL_HOST_FN_DEV_RESIZE:
     1177        {
     1178            Log(("svcCall: SHCRGL_HOST_FN_DEV_RESIZE\n"));
     1179
     1180            /* Verify parameter count and types. */
     1181            if (cParms != SHCRGL_CPARMS_DEV_RESIZE)
     1182            {
     1183                LogRel(("SHCRGL_HOST_FN_DEV_RESIZE: cParms invalid - %d", cParms));
     1184                rc = VERR_INVALID_PARAMETER;
     1185                break;
     1186            }
     1187
     1188            for (int i = 0; i < SHCRGL_CPARMS_DEV_RESIZE; ++i)
     1189            {
     1190                if (paParms[i].type != VBOX_HGCM_SVC_PARM_PTR
     1191                        || !paParms[i].u.pointer.addr)
     1192                {
     1193                    AssertMsgFailed(("invalid param\n"));
     1194                    return VERR_INVALID_PARAMETER;
     1195                }
     1196            }
     1197
     1198            rc = crVBoxServerNotifyResize((const VBVAINFOSCREEN *)paParms[0].u.pointer.addr, paParms[1].u.pointer.addr);
     1199            break;
     1200        }
    11761201        case SHCRGL_HOST_FN_VIEWPORT_CHANGED:
    11771202        {
     
    12521277                    if (pOutputRedirect->H3DORBegin != NULL)
    12531278                    {
    1254                         rc = crVBoxServerSetOffscreenRendering(GL_TRUE);
    1255 
     1279                        CROutputRedirect outputRedirect;
     1280                        outputRedirect.pvContext = pOutputRedirect->pvContext;
     1281                        outputRedirect.CRORBegin = pOutputRedirect->H3DORBegin;
     1282                        outputRedirect.CRORGeometry = pOutputRedirect->H3DORGeometry;
     1283                        outputRedirect.CRORVisibleRegion = pOutputRedirect->H3DORVisibleRegion;
     1284                        outputRedirect.CRORFrame = pOutputRedirect->H3DORFrame;
     1285                        outputRedirect.CROREnd = pOutputRedirect->H3DOREnd;
     1286                        outputRedirect.CRORContextProperty = pOutputRedirect->H3DORContextProperty;
     1287                        rc = crVBoxServerOutputRedirectSet(&outputRedirect);
    12561288                        if (RT_SUCCESS(rc))
    12571289                        {
    1258                             CROutputRedirect outputRedirect;
    1259                             outputRedirect.pvContext = pOutputRedirect->pvContext;
    1260                             outputRedirect.CRORBegin = pOutputRedirect->H3DORBegin;
    1261                             outputRedirect.CRORGeometry = pOutputRedirect->H3DORGeometry;
    1262                             outputRedirect.CRORVisibleRegion = pOutputRedirect->H3DORVisibleRegion;
    1263                             outputRedirect.CRORFrame = pOutputRedirect->H3DORFrame;
    1264                             outputRedirect.CROREnd = pOutputRedirect->H3DOREnd;
    1265                             outputRedirect.CRORContextProperty = pOutputRedirect->H3DORContextProperty;
    1266                             rc = crVBoxServerOutputRedirectSet(&outputRedirect);
     1290                            rc = crVBoxServerSetOffscreenRendering(GL_TRUE);
    12671291                        }
    12681292                    }
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h

    r50041 r50095  
    1515
    1616#include "cr_server.h"
     17#include <cr_htable.h>
     18#include <cr_compositor.h>
    1719
    1820#ifdef VBOX_WITH_CRHGSMI
     
    114116GLint crServerDispatchCreateContextEx(const char *dpyName, GLint visualBits, GLint shareCtx, GLint preloadCtxID, int32_t internalID);
    115117GLint crServerDispatchWindowCreateEx(const char *dpyName, GLint visBits, GLint preloadWinID);
    116 GLint crServerMuralInit(CRMuralInfo *mural, const char *dpyName, GLint visBits, GLint preloadWinID, GLboolean fUseDefaultDEntry);
     118GLint crServerMuralInit(CRMuralInfo *mural, const char *dpyName, GLint visBits, GLint preloadWinID);
    117119void crServerMuralTerm(CRMuralInfo *mural);
    118120GLboolean crServerMuralSize(CRMuralInfo *mural, GLint width, GLint height);
    119 void crServerMuralPosition(CRMuralInfo *mural, GLint x, GLint y, GLboolean fSkipCheckGeometry);
     121void crServerMuralPosition(CRMuralInfo *mural, GLint x, GLint y);
    120122void crServerMuralVisibleRegion( CRMuralInfo *mural, GLint cRects, const GLint *pRects );
    121123void crServerMuralShow( CRMuralInfo *mural, GLint state );
    122 int crServerMuralSynchRootVr(CRMuralInfo *mural, bool *pfChanged);
    123124
    124125GLint crServerGenerateID(GLint *pCounter);
     
    129130
    130131CRMuralInfo * crServerGetDummyMural(GLint visualBits);
    131 
    132 void crServerPresentOutputRedirect(CRMuralInfo *pMural);
    133 void crServerOutputRedirectCheckEnableDisable(CRMuralInfo *pMural);
    134132
    135133void crServerCheckMuralGeometry(CRMuralInfo *mural);
    136134GLboolean crServerSupportRedirMuralFBO(void);
    137135
     136void crVBoxServerMuralFbResizeBegin(HCR_FRAMEBUFFER hFb);
     137void crVBoxServerMuralFbResizeEnd(HCR_FRAMEBUFFER hFb);
     138
    138139void crVBoxServerNotifyEvent(int32_t idScreen, uint32_t uEvent, void*pvData);
    139140void crVBoxServerCheckVisibilityEvent(int32_t idScreen);
    140141
    141 void crServerDisplayTermAll();
    142 
    143 void crServerWindowSize(CRMuralInfo *pMural);
    144 void crServerWindowShow(CRMuralInfo *pMural);
    145 void crServerWindowVisibleRegion(CRMuralInfo *pMural);
     142void crServerRedirMuralFbClear(CRMuralInfo *mural);
     143
    146144void crServerWindowReparent(CRMuralInfo *pMural);
    147145
    148 void crServerWindowSetIsVisible(CRMuralInfo *pMural, GLboolean fIsVisible);
    149 void crServerWindowCheckIsVisible(CRMuralInfo *pMural);
    150 
    151 int crVBoxServerUpdateMuralRootVisibleRegion(CRMuralInfo *pMI);
    152 
    153 #define CR_SERVER_REDIR_F_NONE     0x00
    154 /* the data should be displayed on host (unset when is on or when CR_SERVER_REDIR_F_FBO_RAM_VMFB is set) */
    155 #define CR_SERVER_REDIR_F_DISPLAY       0x01
    156 /* guest window data get redirected to FBO on host */
    157 #define CR_SERVER_REDIR_F_FBO           0x02
    158 /* used with CR_SERVER_REDIR_F_FBO only
    159  * indicates that FBO data should be copied to RAM for further processing */
    160 #define CR_SERVER_REDIR_F_FBO_RAM       0x04
    161 /* used with CR_SERVER_REDIR_F_FBO_RAM only
    162  * indicates that FBO data should be passed to VRDP backend */
    163 #define CR_SERVER_REDIR_F_FBO_RAM_VRDP  0x08
    164 /* used with CR_SERVER_REDIR_F_FBO_RAM only
    165  * indicates that FBO data should be passed to VM Framebuffer */
    166 #define CR_SERVER_REDIR_F_FBO_RAM_VMFB  0x10
    167 /* used with CR_SERVER_REDIR_F_FBO_RAM only
    168  * makes the RPW (Read Pixels Worker) mechanism to be used for GPU memory aquisition */
    169 #define CR_SERVER_REDIR_F_FBO_RPW       0x20
    170 
    171 
    172 #define CR_SERVER_REDIR_F_ALL           0x3f
    173 
    174 #define CR_SERVER_REDIR_FGROUP_REQUIRE_FBO     (CR_SERVER_REDIR_F_ALL & ~CR_SERVER_REDIR_F_DISPLAY)
    175 #define CR_SERVER_REDIR_FGROUP_REQUIRE_FBO_RAM (CR_SERVER_REDIR_F_FBO_RAM_VRDP | CR_SERVER_REDIR_F_FBO_RAM_VMFB | CR_SERVER_REDIR_F_FBO_RPW)
    176 
    177 DECLINLINE(GLuint) crServerRedirModeAdjust(GLuint value)
    178 {
    179     /* sanitize values */
    180     value &= CR_SERVER_REDIR_F_ALL;
    181 
    182     if (value & CR_SERVER_REDIR_FGROUP_REQUIRE_FBO)
    183         value |=  CR_SERVER_REDIR_F_FBO;
    184     if (value & CR_SERVER_REDIR_FGROUP_REQUIRE_FBO_RAM)
    185         value |=  CR_SERVER_REDIR_F_FBO_RAM;
    186 
    187     return value;
    188 }
    189 
    190 int32_t crServerSetOffscreenRenderingMode(GLuint value);
    191 void crServerRedirMuralFBO(CRMuralInfo *mural, GLuint redir);
     146void crServerRedirMuralFBO(CRMuralInfo *mural, bool fEnabled);
    192147void crServerDeleteMuralFBO(CRMuralInfo *mural);
    193148void crServerPresentFBO(CRMuralInfo *mural);
     
    196151void crServerMuralFBOSwapBuffers(CRMuralInfo *mural);
    197152
    198 void crServerVBoxCompositionDisableEnter(CRMuralInfo *mural);
    199 void crServerVBoxCompositionDisableLeave(CRMuralInfo *mural, GLboolean fForcePresentOnEnabled);
    200 void crServerVBoxCompositionPresent(CRMuralInfo *mural);
    201 DECLINLINE(GLboolean) crServerVBoxCompositionPresentNeeded(CRMuralInfo *mural)
    202 {
    203     return mural->bVisible
    204                 && mural->width
    205                 && mural->height
    206                 && !mural->fRootVrOn ? !CrVrScrCompositorIsEmpty(&mural->Compositor) : !CrVrScrCompositorIsEmpty(&mural->RootVrCompositor);
    207 }
    208153
    209154#define CR_SERVER_FBO_BB_IDX(_mural) ((_mural)->iBbBuffer)
     
    219164int32_t crVBoxServerInternalClientRead(CRClient *pClient, uint8_t *pBuffer, uint32_t *pcbBuffer);
    220165
    221 PCR_DISPLAY crServerDisplayGetInitialized(uint32_t idScreen);
    222 
    223166void crServerPerformMakeCurrent( CRMuralInfo *mural, CRContextInfo *ctxInfo );
    224167
    225168PCR_BLITTER crServerVBoxBlitterGet();
     169PCR_BLITTER crServerVBoxBlitterGetInitialized();
    226170
    227171DECLINLINE(void) crServerVBoxBlitterWinInit(CR_BLITTER_WINDOW *win, CRMuralInfo *mural)
     
    420364int crServerVBoxParseNumerics(const char *pszStr, const int defaultVal);
    421365
    422 void CrDpRootUpdate(PCR_DISPLAY pDisplay);
    423 void CrDpEnter(PCR_DISPLAY pDisplay);
    424 void CrDpLeave(PCR_DISPLAY pDisplay);
    425 int CrDpInit(PCR_DISPLAY pDisplay);
    426 void CrDpTerm(PCR_DISPLAY pDisplay);
    427 
    428 DECLINLINE(bool) CrDpIsEmpty(PCR_DISPLAY pDisplay)
    429 {
    430     return CrVrScrCompositorIsEmpty(&pDisplay->Mural.Compositor);
    431 }
    432 
    433 int CrDpSaveState(PCR_DISPLAY pDisplay, PSSMHANDLE pSSM);
    434 int CrDpLoadState(PCR_DISPLAY pDisplay, PSSMHANDLE pSSM, uint32_t version);
    435 
    436 void CrDpReparent(PCR_DISPLAY pDisplay, CRScreenInfo *pScreen);
    437 
    438 void CrDpResize(PCR_DISPLAY pDisplay, int32_t xPos, int32_t yPos, uint32_t width, uint32_t height);
    439 void CrDpEntryInit(PCR_DISPLAY_ENTRY pEntry, const VBOXVR_TEXTURE *pTextureData, uint32_t fFlags, PFNVBOXVRSCRCOMPOSITOR_ENTRY_RELEASED pfnEntryReleased);
    440 void CrDpEntryCleanup(PCR_DISPLAY_ENTRY pEntry);
    441 int CrDpEntryRegionsSet(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions);
    442 int CrDpEntryRegionsAdd(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, CR_DISPLAY_ENTRY_MAP *pMap);
    443 void CrDpRegionsClear(PCR_DISPLAY pDisplay);
    444 DECLINLINE(bool) CrDpEntryIsUsed(PCR_DISPLAY_ENTRY pEntry)
    445 {
    446     return CrVrScrCompositorEntryIsInList(&pEntry->CEntry);
    447 }
    448 
    449 DECLINLINE(CRMuralInfo*) CrDpGetMural(PCR_DISPLAY pDisplay)
    450 {
    451     return &pDisplay->Mural;
    452 }
    453 
    454 int CrDemGlobalInit();
    455 void CrDemTeGlobalTerm();
    456 void CrDemEnter(PCR_DISPLAY_ENTRY_MAP pMap);
    457 void CrDemLeave(PCR_DISPLAY_ENTRY_MAP pMap, PCR_DISPLAY_ENTRY pNewEntry, PCR_DISPLAY_ENTRY pReplacedEntry);
    458 int CrDemInit(PCR_DISPLAY_ENTRY_MAP pMap);
    459 void CrDemTerm(PCR_DISPLAY_ENTRY_MAP pMap);
    460 PCR_DISPLAY_ENTRY CrDemEntryAcquire(PCR_DISPLAY_ENTRY_MAP pMap, GLuint idTexture, uint32_t fFlags);
    461 void CrDemEntryRelease(PCR_DISPLAY_ENTRY pEntry);
    462 int CrDemEntrySaveState(PCR_DISPLAY_ENTRY pEntry, PSSMHANDLE pSSM);
    463 int CrDemEntryLoadState(PCR_DISPLAY_ENTRY_MAP pMap, PCR_DISPLAY_ENTRY *ppEntry, PSSMHANDLE pSSM);
    464 
    465 int crServerDisplaySaveState(PSSMHANDLE pSSM);
    466 int crServerDisplayLoadState(PSSMHANDLE pSSM, uint32_t u32Version);
    467 
    468 
    469 void crServerDEntryResized(CRMuralInfo *pMural, CR_DISPLAY_ENTRY *pDEntry);
    470 void crServerDEntryMoved(CRMuralInfo *pMural, CR_DISPLAY_ENTRY *pDEntry);
    471 void crServerDEntryVibleRegions(CRMuralInfo *pMural, CR_DISPLAY_ENTRY *pDEntry);
    472 void crServerDEntryCheckFBO(CRMuralInfo *pMural, CR_DISPLAY_ENTRY *pDEntry, CRContext *ctx);
    473 
    474 void crServerDEntryAllResized(CRMuralInfo *pMural);
    475 void crServerDEntryAllMoved(CRMuralInfo *pMural);
    476 void crServerDEntryAllVibleRegions(CRMuralInfo *pMural);
     366/*helper function that calls CrFbUpdateBegin for all enabled framebuffers */
     367int CrPMgrHlpGlblUpdateBegin();
     368/*helper function that calls CrFbUpdateEnd for all framebuffers being updated */
     369void CrPMgrHlpGlblUpdateEnd();
     370HCR_FRAMEBUFFER CrPMgrFbGetFirstEnabled();
     371HCR_FRAMEBUFFER CrPMgrFbGetNextEnabled(HCR_FRAMEBUFFER hFb);
     372int CrPMgrModeVrdp(bool fEnable);
     373int CrPMgrModeRootVr(bool fEnable);
     374int CrPMgrRootVrUpdate();
     375int CrPMgrViewportUpdate(uint32_t idScreen);
     376int CrPMgrScreenChanged(uint32_t idScreen);
     377int CrPMgrNotifyResize(HCR_FRAMEBUFFER hFb);
     378int CrPMgrSaveState(PSSMHANDLE pSSM);
     379int CrPMgrLoadState(PSSMHANDLE pSSM, uint32_t version);
     380HCR_FRAMEBUFFER CrPMgrFbGet(uint32_t idScreen);
     381/*cleanup stuff*/
     382
     383int CrPMgrInit();
     384void CrPMgrTerm();
     385
     386int CrFbResize(HCR_FRAMEBUFFER hFb, const struct VBVAINFOSCREEN * pScreen, void *pvVRAM);
     387bool CrFbIsEnabled(HCR_FRAMEBUFFER hFb);
     388int CrFbEntryCreateForTexId(HCR_FRAMEBUFFER hFb, GLuint idTex, uint32_t fFlags, HCR_FRAMEBUFFER_ENTRY *phEntry);
     389int CrFbEntryCreateForTexData(HCR_FRAMEBUFFER hFb, struct CR_TEXDATA *pTex, uint32_t fFlags, HCR_FRAMEBUFFER_ENTRY *phEntry);
     390void CrFbEntryAddRef(HCR_FRAMEBUFFER hFb, HCR_FRAMEBUFFER_ENTRY hEntry);
     391void CrFbEntryRelease(HCR_FRAMEBUFFER hFb, HCR_FRAMEBUFFER_ENTRY hEntry);
     392const struct VBVAINFOSCREEN* CrFbGetScreenInfo(HCR_FRAMEBUFFER hFb);
     393const struct VBOXVR_SCR_COMPOSITOR* CrFbGetCompositor(HCR_FRAMEBUFFER hFb);
     394const struct VBOXVR_SCR_COMPOSITOR_ENTRY* CrFbEntryGetCompositorEntry(HCR_FRAMEBUFFER_ENTRY hEntry);
     395
     396/* start doing modifications to the framebuffer */
     397int CrFbUpdateBegin(HCR_FRAMEBUFFER hFb);
     398/*below commands can only be used in Framebuffer update mode, i.e. after the CrFbUpdateBegin succeeded */
     399int CrFbEntryRegions(HCR_FRAMEBUFFER hFb, HCR_FRAMEBUFFER_ENTRY hEntry);
     400
     401/* complete doing modifications to the framebuffer */
     402void CrFbUpdateEnd(HCR_FRAMEBUFFER hFb);
     403
     404int CrFbEntryRegionsAdd(HCR_FRAMEBUFFER hFb, HCR_FRAMEBUFFER_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, bool fPosRelated);
     405int CrFbEntryRegionsSet(HCR_FRAMEBUFFER hFb, HCR_FRAMEBUFFER_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, bool fPosRelated);
     406
     407int CrFbEntryTexDataUpdate(HCR_FRAMEBUFFER hFb, HCR_FRAMEBUFFER_ENTRY pEntry, struct CR_TEXDATA *pTex);
     408
     409CRHTABLE_HANDLE CrFbDDataAllocSlot(HCR_FRAMEBUFFER hFb);
     410void CrFbDDataReleaseSlot(HCR_FRAMEBUFFER hFb, CRHTABLE_HANDLE hSlot);
     411int CrFbDDataEntryPut(HCR_FRAMEBUFFER_ENTRY hEntry, CRHTABLE_HANDLE hSlot, void *pvData);
     412void* CrFbDDataEntryGet(HCR_FRAMEBUFFER_ENTRY hEntry, CRHTABLE_HANDLE hSlot);
     413
     414CR_TEXDATA* CrFbTexDataCreate(const VBOXVR_TEXTURE *pTex);
     415void CrFbTexDataInit(CR_TEXDATA* pFbTex, const VBOXVR_TEXTURE *pTex, PFNCRTEXDATA_RELEASED pfnTextureReleased);
    477416
    478417//#define VBOX_WITH_CRSERVER_DUMPER
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_clear.c

    r46368 r50095  
    444444    {
    445445        cr_server.head_spu->dispatch_table.SwapBuffers( mural->spuWindow, flags );
    446         if (crServerVBoxCompositionPresentNeeded(mural))
    447             mural->fDataPresented = GL_TRUE;
    448446    }
    449447
     
    464462            if (crServerIsRedirectedToFBO())
    465463                crServerPresentFBO(mural);
    466             else if (crServerVBoxCompositionPresentNeeded(mural))
    467                 mural->fDataPresented = GL_TRUE;
    468464        }
    469465
     
    488484            if (crServerIsRedirectedToFBO())
    489485                crServerPresentFBO(mural);
    490             else if (crServerVBoxCompositionPresentNeeded(mural))
    491                 mural->fDataPresented = GL_TRUE;
    492486        }
    493487
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_config.c

    r49591 r50095  
    5252
    5353    cr_server.screenCount = 0;
    54     cr_server.fPresentMode = CR_SERVER_REDIR_F_NONE;
    55     cr_server.fPresentModeDefault = cr_server.fPresentMode;
    56     cr_server.fVramPresentModeDefault = CR_SERVER_REDIR_F_FBO_RAM;
    5754    cr_server.bUsePBOForReadback = GL_FALSE;
    58     cr_server.bUseOutputRedirect = GL_FALSE;
    5955    cr_server.bWindowsInitiallyHidden = GL_FALSE;
    6056
     
    217213        crSPULoadChain(num_spus, spu_ids, spu_names, spu_dir, &cr_server);
    218214
    219     env = crGetenv( "CR_SERVER_DEFAULT_RENDER_TYPE" );
     215    env = crGetenv( "CR_SERVER_DEFAULT_VISUAL_BITS" );
    220216    if (env != NULL && env[0] != '\0')
    221217    {
    222         unsigned int redir = (unsigned int)crServerVBoxParseNumerics(env, CR_SERVER_REDIR_F_NONE);
    223         if (redir <= CR_SERVER_REDIR_F_ALL)
    224         {
    225             int rc = crServerSetOffscreenRenderingMode(redir);
    226             if (!RT_SUCCESS(rc))
    227                 crWarning("offscreen rendering unsupported, no offscreen rendering will be used..");
    228         }
     218        unsigned int bits = (unsigned int)crServerVBoxParseNumerics(env, 0);
     219        if (bits <= CR_ALL_BITS)
     220            cr_server.fVisualBitsDefault = bits;
    229221        else
    230             crWarning("invalid redir option %c", redir);
    231     }
    232 #if defined(RT_OS_DARWIN) || defined(RT_OS_WINDOWS) || defined(GLX)
    233     if (cr_server.fPresentMode == CR_SERVER_REDIR_F_NONE)
    234     {
    235         /* the CR_SERVER_REDIR_F_FBO_BLT is set only if parent window is received, which means we are not in headles */
    236         int rc = crServerSetOffscreenRenderingMode(CR_SERVER_REDIR_F_FBO | CR_SERVER_REDIR_F_DISPLAY);
    237         if (!RT_SUCCESS(rc))
    238             crWarning("offscreen rendering unsupported, no offscreen rendering will be used..");
    239 
    240     }
    241 #endif
    242     cr_server.fPresentModeDefault = cr_server.fPresentMode;
    243     cr_server.fVramPresentModeDefault = CR_SERVER_REDIR_F_FBO_RAM/* | CR_SERVER_REDIR_F_FBO_RPW*/;
     222            crWarning("invalid bits option %c", bits);
     223    }
     224    else
     225        cr_server.fVisualBitsDefault = CR_RGB_BIT | CR_ALPHA_BIT | CR_DOUBLE_BIT;
    244226
    245227    env = crGetenv("CR_SERVER_CAPS");
     
    258240    }
    259241
    260     if (!(cr_server.fPresentModeDefault & CR_SERVER_REDIR_F_FBO))
    261     {
    262         /* can not do tex present in case CR_SERVER_REDIR_F_FBO is disabled */
    263         cr_server.u32Caps &= ~CR_VBOX_CAP_TEX_PRESENT;
    264     }
    265 
    266     crInfo("Cfg: fPresentModeDefault(%#x), fVramPresentModeDefault(%#x), u32Caps(%#x)",
    267             cr_server.fPresentModeDefault, cr_server.fVramPresentModeDefault, cr_server.u32Caps);
     242    crInfo("Cfg: u32Caps(%#x), fVisualBitsDefault(%#x)",
     243            cr_server.u32Caps,
     244            cr_server.fVisualBitsDefault);
    268245
    269246    /* Need to do this as early as possible */
     
    385362        return;
    386363
    387     env = crGetenv( "CR_SERVER_DEFAULT_RENDER_TYPE" );
     364
     365    env = crGetenv( "CR_SERVER_DEFAULT_VISUAL_BITS" );
    388366    if (env != NULL && env[0] != '\0')
    389367    {
    390         unsigned int redir = (unsigned int)crServerVBoxParseNumerics(env, CR_SERVER_REDIR_F_NONE);
    391         if (redir <= CR_SERVER_REDIR_F_ALL)
    392         {
    393             int rc = crServerSetOffscreenRenderingMode(redir);
    394             if (!RT_SUCCESS(rc))
    395                 crWarning("offscreen rendering unsupported, no offscreen rendering will be used..");
    396         }
     368        unsigned int bits = (unsigned int)crServerVBoxParseNumerics(env, 0);
     369        if (bits <= CR_ALL_BITS)
     370            cr_server.fVisualBitsDefault = bits;
    397371        else
    398             crWarning("invalid redir option %c", redir);
    399     }
    400 #if defined(RT_OS_DARWIN) || defined(RT_OS_WINDOWS) || defined(GLX)
    401     if (cr_server.fPresentMode == CR_SERVER_REDIR_F_NONE)
    402     {
    403         /* the CR_SERVER_REDIR_F_FBO_BLT is set only if parent window is received, which means we are not in headles */
    404         int rc = crServerSetOffscreenRenderingMode(CR_SERVER_REDIR_F_FBO | CR_SERVER_REDIR_F_DISPLAY);
    405         if (!RT_SUCCESS(rc))
    406             crWarning("offscreen rendering unsupported, no offscreen rendering will be used..");
    407 
    408     }
    409 #endif
    410     cr_server.fPresentModeDefault = cr_server.fPresentMode;
    411     cr_server.fVramPresentModeDefault = CR_SERVER_REDIR_F_FBO_RAM/* | CR_SERVER_REDIR_F_FBO_RPW*/;
     372            crWarning("invalid bits option %c", bits);
     373    }
     374    else
     375        cr_server.fVisualBitsDefault = CR_RGB_BIT | CR_ALPHA_BIT | CR_DOUBLE_BIT;
    412376
    413377    env = crGetenv("CR_SERVER_CAPS");
     
    425389    }
    426390
    427     if (!(cr_server.fPresentModeDefault & CR_SERVER_REDIR_F_FBO))
    428     {
    429         /* can not do tex present in case CR_SERVER_REDIR_F_FBO is disabled */
    430         cr_server.u32Caps &= ~CR_VBOX_CAP_TEX_PRESENT;
    431     }
    432 
    433     crInfo("Cfg: fPresentModeDefault(%#x), fVramPresentModeDefault(%#x), u32Caps(%#x)",
    434             cr_server.fPresentModeDefault, cr_server.fVramPresentModeDefault, cr_server.u32Caps);
     391    crInfo("Cfg: u32Caps(%#x), fVisualBitsDefault(%#x)",
     392            cr_server.u32Caps,
     393            cr_server.fVisualBitsDefault);
    435394
    436395    cr_server.head_spu->dispatch_table.GetChromiumParametervCR(GL_WINDOW_POSITION_CR, 0, GL_INT, 2, &dims[0]);
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_context.c

    r48079 r50095  
    2929
    3030    dpyName = "";
     31    if (cr_server.fVisualBitsDefault)
     32        visualBits = cr_server.fVisualBitsDefault;
    3133
    3234    if (shareCtx > 0) {
     
    301303     * while crStateSwitchPostprocess restores it back to the original values */
    302304    oldCtx = crStateGetCurrent();
    303     if (oldMural && (oldMural->fPresentMode & CR_SERVER_REDIR_F_FBO) && crServerSupportRedirMuralFBO())
     305    if (oldMural && oldMural->fRedirected && crServerSupportRedirMuralFBO())
    304306    {
    305307        idDrawFBO = CR_SERVER_FBO_FOR_IDX(oldMural, oldMural->iCurDrawBuffer);
     
    383385    crStateMakeCurrent( ctx );
    384386
    385     if (mural && (mural->fPresentMode & CR_SERVER_REDIR_F_FBO) && crServerSupportRedirMuralFBO())
     387    if (mural && mural->fRedirected && crServerSupportRedirMuralFBO())
    386388    {
    387389        GLuint id = crServerMuralFBOIdxFromBufferName(mural, ctx->buffer.drawBuffer);
     
    414416        cr_server.curClient->currentMural->bFbDraw = GL_TRUE;
    415417
    416     if (!(mural->fPresentMode & CR_SERVER_REDIR_F_FBO))
     418    if (!mural->fRedirected)
    417419    {
    418420        ctx->buffer.width = mural->width;
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_lists.c

    r50041 r50095  
    6161crServerDispatchNewList( GLuint list, GLenum mode )
    6262{
     63    Assert(0);
    6364    if (mode == GL_COMPILE_AND_EXECUTE)
    6465        crWarning("using glNewList(GL_COMPILE_AND_EXECUTE) can confuse the crserver");
     
    7475    CRClient *client = cr_server.curClient;
    7576    CRMuralInfo *mural = client ? client->currentMural : NULL;
    76     if (mural && mural->fPresentMode & CR_SERVER_REDIR_F_FBO)
     77    if (mural && mural->fRedirected)
    7778    {
    7879        fbFbo = mural->aidFBOs[CR_SERVER_FBO_FB_IDX(mural)];
     
    292293    }
    293294
     295    for (i = 0; i < n; ++i)
     296    {
     297        crDebug("DeleteTexture: %d, pid %d, ctx %d", textures[i], (uint32_t)cr_server.curClient->pid, cr_server.currentCtxInfo->pContext->id);
     298    }
     299
     300
    294301    crStateDeleteTextures(n, textures);
    295302    cr_server.head_spu->dispatch_table.DeleteTextures(n, newTextures);
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c

    r50041 r50095  
    188188    crFreeHashtable(cr_server.muralTable, deleteMuralInfoCallback);
    189189
    190     crServerDisplayTermAll();
    191     CrDemTerm(&cr_server.PresentTexturepMap);
    192     CrDemTeGlobalTerm();
    193     memset(cr_server.DisplaysInitMap, 0, sizeof (cr_server.DisplaysInitMap));
    194     memset(cr_server.aDispplays, 0, sizeof (cr_server.aDispplays));
     190    CrPMgrTerm();
    195191
    196192    for (i = 0; i < cr_server.numClients; i++) {
     
    369365    cr_server.dummyMuralTable = crAllocHashtable();
    370366
    371     CrDemGlobalInit();
    372 
    373     CrDemInit(&cr_server.PresentTexturepMap);
    374     memset(cr_server.DisplaysInitMap, 0, sizeof (cr_server.DisplaysInitMap));
    375     memset(cr_server.aDispplays, 0, sizeof (cr_server.aDispplays));
     367    CrPMgrInit();
    376368
    377369    cr_server.fRootVrOn = GL_FALSE;
     
    486478    cr_server.dummyMuralTable = crAllocHashtable();
    487479
    488     CrDemGlobalInit();
    489 
    490     CrDemInit(&cr_server.PresentTexturepMap);
    491     memset(cr_server.DisplaysInitMap, 0, sizeof (cr_server.DisplaysInitMap));
    492     memset(cr_server.aDispplays, 0, sizeof (cr_server.aDispplays));
     480    CrPMgrInit();
    493481
    494482    cr_server.fRootVrOn = GL_FALSE;
     
    1005993            return NULL;
    1006994        }
    1007         id = crServerMuralInit(pMural, "", visualBits, 0, GL_TRUE);
     995        id = crServerMuralInit(pMural, "", visualBits, 0);
    1008996        if (id < 0)
    1009997        {
     
    11491137
    11501138    pEl = &pData->aElements[pData->cElements];
    1151     pEl->idFBO = pMural && (pMural->fPresentMode & CR_SERVER_REDIR_F_FBO) ? pMural->aidFBOs[CR_SERVER_FBO_FB_IDX(pMural)] : 0;
     1139    pEl->idFBO = pMural && pMural->fRedirected ? pMural->aidFBOs[CR_SERVER_FBO_FB_IDX(pMural)] : 0;
    11521140    pEl->enmBuffer = pData->aElements[1].idFBO ? GL_COLOR_ATTACHMENT0 : GL_FRONT;
    11531141    pEl->posX = 0;
     
    11761164    {
    11771165        pEl = &pData->aElements[pData->cElements];
    1178         pEl->idFBO = pMural && (pMural->fPresentMode & CR_SERVER_REDIR_F_FBO) ? pMural->aidFBOs[CR_SERVER_FBO_BB_IDX(pMural)] : 0;
     1166        pEl->idFBO = pMural && pMural->fRedirected ? pMural->aidFBOs[CR_SERVER_FBO_BB_IDX(pMural)] : 0;
    11791167        pEl->enmBuffer = pData->aElements[1].idFBO ? GL_COLOR_ATTACHMENT0 : GL_BACK;
    11801168        pEl->posX = 0;
     
    12061194            AssertCompile(sizeof (GLfloat) == 4);
    12071195            pEl = &pData->aElements[pData->cElements];
    1208             pEl->idFBO = pMural && (pMural->fPresentMode & CR_SERVER_REDIR_F_FBO) ? pMural->aidFBOs[CR_SERVER_FBO_FB_IDX(pMural)] : 0;
     1196            pEl->idFBO = pMural && pMural->fRedirected ? pMural->aidFBOs[CR_SERVER_FBO_FB_IDX(pMural)] : 0;
    12091197            pEl->enmBuffer = 0; /* we do not care */
    12101198            pEl->posX = 0;
     
    12371225            AssertCompile(sizeof (GLuint) == 4);
    12381226            pEl = &pData->aElements[pData->cElements];
    1239             pEl->idFBO = pMural && (pMural->fPresentMode & CR_SERVER_REDIR_F_FBO) ? pMural->aidFBOs[CR_SERVER_FBO_FB_IDX(pMural)] : 0;
     1227            pEl->idFBO = pMural && pMural->fRedirected ? pMural->aidFBOs[CR_SERVER_FBO_FB_IDX(pMural)] : 0;
    12401228            pEl->enmBuffer = 0; /* we do not care */
    12411229            pEl->posX = 0;
     
    12621250    {
    12631251        pEl = &pData->aElements[pData->cElements];
    1264         pEl->idFBO = pMural && (pMural->fPresentMode & CR_SERVER_REDIR_F_FBO) ? pMural->aidFBOs[CR_SERVER_FBO_FB_IDX(pMural)] : 0;
     1252        pEl->idFBO = pMural && pMural->fRedirected ? pMural->aidFBOs[CR_SERVER_FBO_FB_IDX(pMural)] : 0;
    12651253        pEl->enmBuffer = 0; /* we do not care */
    12661254        pEl->posX = 0;
     
    17191707    }
    17201708
    1721     rc = crServerDisplaySaveState(pSSM);
     1709    rc = CrPMgrSaveState(pSSM);
    17221710    AssertRCReturn(rc, rc);
    17231711
     
    21372125            crFree(muralInfo.pVisibleRects);
    21382126        }
    2139 
    2140         Assert(!pActualMural->fDataPresented);
    2141 
    2142         if (version >= SHCROGL_SSM_VERSION_WITH_PRESENT_STATE)
    2143             pActualMural->fDataPresented = muralInfo.fDataPresented;
    2144         else
    2145             pActualMural->fDataPresented = crServerVBoxCompositionPresentNeeded(pActualMural);
    21462127    }
    21472128
     
    22312212        crVBoxServerFBImageDataTerm(&Data.data);
    22322213
    2233         if ((pMural->fPresentMode & CR_SERVER_REDIR_F_FBO) && pMural->fDataPresented && crServerVBoxCompositionPresentNeeded(pMural))
    2234         {
    2235             crServerPresentFBO(pMural);
    2236         }
     2214        crServerPresentFBO(pMural);
    22372215
    22382216        CRASSERT(cr_server.currentMural);
     
    26102588    if (version >= SHCROGL_SSM_VERSION_WITH_SCREEN_INFO)
    26112589    {
    2612         rc = crServerDisplayLoadState(pSSM, version);
     2590        HCR_FRAMEBUFFER hFb;
     2591
     2592        rc = CrPMgrLoadState(pSSM, version);
    26132593        AssertRCReturn(rc, rc);
    26142594    }
     
    26822662}
    26832663
     2664void crServerWindowReparent(CRMuralInfo *pMural)
     2665{
     2666    pMural->fHasParentWindow = !!cr_server.screen[pMural->screenId].winID;
     2667
     2668    renderspuReparentWindow(pMural->spuWindow);
     2669}
     2670
    26842671static void crVBoxServerReparentMuralCB(unsigned long key, void *data1, void *data2)
    26852672{
     
    26872674    int *sIndex = (int*) data2;
    26882675
    2689     Assert(pMI->cDisabled);
    2690 
    26912676    if (pMI->screenId == *sIndex)
    26922677    {
    26932678        crServerWindowReparent(pMI);
    26942679    }
    2695 }
    2696 
    2697 static void crVBoxServerCheckMuralCB(unsigned long key, void *data1, void *data2)
    2698 {
    2699     CRMuralInfo *pMI = (CRMuralInfo*) data1;
    2700     (void) data2;
    2701 
    2702     crServerCheckMuralGeometry(pMI);
    27032680}
    27042681
     
    27372714    if (MAPPED(SCREEN(sIndex)))
    27382715    {
    2739         PCR_DISPLAY pDisplay = crServerDisplayGetInitialized(sIndex);
    2740 
    27412716        SCREEN(sIndex).winID = 0;
    27422717        renderspuSetWindowId(0);
     
    27462721        crHashtableWalk(cr_server.dummyMuralTable, crVBoxServerReparentMuralCB, &sIndex);
    27472722
    2748         if (pDisplay)
    2749             CrDpReparent(pDisplay, &SCREEN(sIndex));
     2723        CrPMgrScreenChanged((uint32_t)sIndex);
    27502724    }
    27512725
    27522726    renderspuSetWindowId(SCREEN(0).winID);
    2753 
    2754     crHashtableWalk(cr_server.muralTable, crVBoxServerCheckMuralCB, NULL);
    27552727
    27562728/*    crVBoxServerNotifyEvent(sIndex, VBOX3D_NOTIFY_EVENT_TYPE_VISIBLE_3DDATA, NULL); */
     
    27832755    crHashtableWalk(cr_server.dummyMuralTable, crVBoxServerReparentMuralCB, &sIndex);
    27842756    renderspuSetWindowId(SCREEN(0).winID);
    2785 
    2786     crHashtableWalk(cr_server.muralTable, crVBoxServerCheckMuralCB, NULL);
    27872757
    27882758#ifndef WINDOWS
     
    28192789#endif
    28202790
    2821     {
    2822         PCR_DISPLAY pDisplay = crServerDisplayGetInitialized(sIndex);
    2823         if (pDisplay)
    2824             CrDpReparent(pDisplay, &SCREEN(sIndex));
    2825     }
     2791    CrPMgrScreenChanged((uint32_t)sIndex);
    28262792
    28272793    crVBoxServerNotifyEvent(sIndex, VBOX3D_NOTIFY_EVENT_TYPE_VISIBLE_3DDATA,
     
    28312797}
    28322798
    2833 int crVBoxServerUpdateMuralRootVisibleRegion(CRMuralInfo *pMI)
    2834 {
    2835     GLboolean fForcePresent;
    2836 
    2837     int rc = VINF_SUCCESS;
    2838 
    2839     fForcePresent = crServerVBoxCompositionPresentNeeded(pMI);
    2840 
    2841     crServerVBoxCompositionDisableEnter(pMI);
    2842 
    2843     if (cr_server.fRootVrOn)
    2844     {
    2845         if (!pMI->fRootVrOn)
    2846         {
    2847             CrVrScrCompositorInit(&pMI->RootVrCompositor);
    2848         }
    2849 
    2850         rc = crServerMuralSynchRootVr(pMI, NULL);
    2851         if (!RT_SUCCESS(rc))
    2852         {
    2853             crWarning("crServerMuralSynchRootVr failed, rc %d", rc);
    2854             goto end;
    2855         }
    2856     }
    2857     else
    2858     {
    2859         CrVrScrCompositorClear(&pMI->RootVrCompositor);
    2860     }
    2861 
    2862     pMI->fRootVrOn = cr_server.fRootVrOn;
    2863 
    2864     crServerWindowVisibleRegion(pMI);
    2865 
    2866 end:
    2867     crServerVBoxCompositionDisableLeave(pMI, fForcePresent);
    2868 
    2869     return rc;
    2870 }
    2871 
    2872 static void crVBoxServerSetRootVisibleRegionCB(unsigned long key, void *data1, void *data2)
    2873 {
    2874     CRMuralInfo *pMI = (CRMuralInfo*) data1;
    2875 
    2876     if (!pMI->CreateInfo.externalID)
    2877         return;
    2878     (void) data2;
    2879 
    2880     crVBoxServerUpdateMuralRootVisibleRegion(pMI);
    2881 }
    2882 
    28832799DECLEXPORT(int32_t) crVBoxServerSetRootVisibleRegion(GLint cRects, const RTRECT *pRects)
    28842800{
    28852801    int32_t rc = VINF_SUCCESS;
    2886     int i;
     2802    GLboolean fOldRootVrOn = cr_server.fRootVrOn;
    28872803
    28882804    /* non-zero rects pointer indicate rects are present and switched on
     
    29112827    }
    29122828
    2913     crHashtableWalk(cr_server.muralTable, crVBoxServerSetRootVisibleRegionCB, NULL);
    2914 
    2915     for (i = 0; i < cr_server.screenCount; ++i)
    2916     {
    2917         PCR_DISPLAY pDisplay = crServerDisplayGetInitialized((uint32_t)i);
    2918         if (!pDisplay)
    2919             continue;
    2920 
    2921         CrDpRootUpdate(pDisplay);
     2829    if (!fOldRootVrOn != !cr_server.fRootVrOn)
     2830    {
     2831        rc = CrPMgrModeRootVr(cr_server.fRootVrOn);
     2832        if (!RT_SUCCESS(rc))
     2833        {
     2834            crWarning("CrPMgrModeRootVr failed rc %d", rc);
     2835            return rc;
     2836        }
     2837    }
     2838    else if (cr_server.fRootVrOn)
     2839    {
     2840        rc = CrPMgrRootVrUpdate();
     2841        if (!RT_SUCCESS(rc))
     2842        {
     2843            crWarning("CrPMgrRootVrUpdate failed rc %d", rc);
     2844            return rc;
     2845        }
    29222846    }
    29232847
     
    29302854}
    29312855
    2932 int32_t crServerSetOffscreenRenderingMode(GLuint value)
    2933 {
    2934     /* sanitize values */
    2935     value = crServerRedirModeAdjust(value);
    2936 
    2937     if (value == CR_SERVER_REDIR_F_NONE)
    2938     {
    2939         crWarning("crServerSetOffscreenRenderingMode: value undefined");
    2940     }
    2941 
    2942     if (cr_server.fPresentMode==value)
    2943     {
    2944         return VINF_SUCCESS;
    2945     }
    2946 
    2947     if ((value & CR_SERVER_REDIR_F_FBO) && !crServerSupportRedirMuralFBO())
    2948     {
    2949         crWarning("crServerSetOffscreenRenderingMode: FBO not supported");
    2950         return VERR_NOT_SUPPORTED;
    2951     }
    2952 
    2953     cr_server.fPresentMode=value;
    2954 
    2955     crHashtableWalk(cr_server.muralTable, crVBoxServerCheckMuralCB, NULL);
    2956 
    2957     return VINF_SUCCESS;
    2958 }
    2959 
    29602856DECLEXPORT(int32_t) crVBoxServerSetOffscreenRendering(GLboolean value)
    29612857{
    2962     return crServerSetOffscreenRenderingMode(value ?
    2963             cr_server.fPresentModeDefault | CR_SERVER_REDIR_F_FBO_RAM_VRDP | cr_server.fVramPresentModeDefault
    2964             : cr_server.fPresentModeDefault);
    2965 }
    2966 
    2967 static void crVBoxServerOutputRedirectCB(unsigned long key, void *data1, void *data2)
    2968 {
    2969     CRMuralInfo *mural = (CRMuralInfo*) data1;
    2970 
    2971     if (!mural->CreateInfo.externalID)
    2972         return;
    2973 
    2974     if (cr_server.bUseOutputRedirect)
    2975         crServerPresentOutputRedirect(mural);
    2976     else
    2977         crServerOutputRedirectCheckEnableDisable(mural);
     2858    return CrPMgrModeVrdp(value);
    29782859}
    29792860
     
    29842865    {
    29852866        cr_server.outputRedirect = *pCallbacks;
    2986         cr_server.bUseOutputRedirect = true;
    29872867    }
    29882868    else
    29892869    {
    2990         cr_server.bUseOutputRedirect = false;
    2991     }
    2992 
    2993     /* dynamically intercept already existing output */
    2994     crHashtableWalk(cr_server.muralTable, crVBoxServerOutputRedirectCB, NULL);
     2870        memset (&cr_server.outputRedirect, 0, sizeof (cr_server.outputRedirect));
     2871    }
    29952872
    29962873    return VINF_SUCCESS;
    29972874}
    29982875
    2999 static void crVBoxServerUpdateScreenViewportCB(unsigned long key, void *data1, void *data2)
    3000 {
    3001     CRMuralInfo *mural = (CRMuralInfo*) data1;
    3002     int *sIndex = (int*) data2;
    3003 
    3004     if (mural->screenId != *sIndex)
    3005         return;
    3006 
    3007     crServerCheckMuralGeometry(mural);
    3008 }
    3009 
    3010 
    30112876DECLEXPORT(int32_t) crVBoxServerSetScreenViewport(int sIndex, int32_t x, int32_t y, uint32_t w, uint32_t h)
    30122877{
    3013     CRScreenViewportInfo *pVieport;
    3014     GLboolean fPosChanged, fSizeChanged;
     2878    CRScreenViewportInfo *pViewport;
     2879    RTRECT NewRect;
     2880    GLboolean fChanged;
     2881    int rc;
    30152882
    30162883    crDebug("crVBoxServerSetScreenViewport(%i)", sIndex);
     
    30222889    }
    30232890
    3024     pVieport = &cr_server.screenVieport[sIndex];
    3025     fPosChanged = (pVieport->x != x || pVieport->y != y);
    3026     fSizeChanged = (pVieport->w != w || pVieport->h != h);
    3027 
    3028     if (!fPosChanged && !fSizeChanged)
     2891    NewRect.xLeft = x;
     2892    NewRect.yTop = y;
     2893    NewRect.xRight = x + w;
     2894    NewRect.yBottom = y + h;
     2895
     2896    pViewport = &cr_server.screenVieport[sIndex];
     2897
     2898    fChanged = !!memcmp(&NewRect, &pViewport->Rect, sizeof (NewRect));
     2899    if (!fChanged)
    30292900    {
    30302901        crDebug("crVBoxServerSetScreenViewport: no changes");
     
    30322903    }
    30332904
    3034     if (fPosChanged)
    3035     {
    3036         pVieport->x = x;
    3037         pVieport->y = y;
    3038 
    3039         crHashtableWalk(cr_server.muralTable, crVBoxServerUpdateScreenViewportCB, &sIndex);
    3040     }
    3041 
    3042     if (fSizeChanged)
    3043     {
    3044         pVieport->w = w;
    3045         pVieport->h = h;
    3046 
    3047         /* no need to do anything here actually */
    3048     }
    3049 
    3050     if (fPosChanged || fSizeChanged)
    3051     {
    3052         PCR_DISPLAY pDisplay = crServerDisplayGetInitialized(sIndex);
    3053         if (pDisplay)
    3054             CrDpResize(pDisplay, SCREEN(sIndex).x, SCREEN(sIndex).y, SCREEN(sIndex).w, SCREEN(sIndex).h);
    3055     }
     2905    pViewport->Rect = NewRect;
     2906    rc = CrPMgrViewportUpdate((uint32_t)sIndex);
     2907    if (!RT_SUCCESS(rc))
     2908    {
     2909        crWarning("CrPMgrViewportUpdate failed %d", rc);
     2910        return rc;
     2911    }
     2912
    30562913    return VINF_SUCCESS;
    30572914}
     
    33713228}
    33723229
    3373 
    33743230int32_t crVBoxServerCrHgsmiCmd(struct VBOXVDMACMD_CHROMIUM_CMD *pCmd, uint32_t cbCmd)
    33753231{
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_misc.c

    r50044 r50095  
    688688}
    689689
     690PCR_BLITTER crServerVBoxBlitterGetInitialized()
     691{
     692    if (CrBltIsInitialized(&cr_server.Blitter))
     693        return &cr_server.Blitter;
     694    return NULL;
     695}
     696
     697
    690698int crServerVBoxBlitterTexInit(CRContext *ctx, CRMuralInfo *mural, PVBOXVR_TEXTURE pTex, GLboolean fDraw)
    691699{
     
    702710        GLuint hwid;
    703711
    704         if (!(mural->fPresentMode & CR_SERVER_REDIR_F_FBO))
     712        if (!mural->fRedirected)
    705713            return VERR_NOT_IMPLEMENTED;
    706714
     
    847855    crServerVBoxBlitterCtxInit(&Ctx, cr_server.curClient->currentCtxInfo);
    848856
    849     CrBltMuralSetCurrent(pBlitter, &BltInfo);
     857    CrBltMuralSetCurrentInfo(pBlitter, &BltInfo);
    850858
    851859    idDrawFBO = CR_SERVER_FBO_FOR_IDX(mural, mural->iCurDrawBuffer);
     
    854862    crStateSwitchPrepare(NULL, ctx, idDrawFBO, idReadFBO);
    855863
    856     rc = CrBltEnter(pBlitter, &Ctx, &BltInfo);
     864    rc = CrBltEnter(pBlitter);
    857865    if (RT_SUCCESS(rc))
    858866    {
     
    14811489        }
    14821490
    1483         rc = CrBltMuralSetCurrent(&cr_server.RecorderBlitter, &BltWin);
     1491        rc = CrBltMuralSetCurrentInfo(&cr_server.RecorderBlitter, &BltWin);
    14841492        if (!RT_SUCCESS(rc))
    14851493        {
    1486             crWarning("CrBltMuralSetCurrent failed rc %d", rc);
     1494            crWarning("CrBltMuralSetCurrentInfo failed rc %d", rc);
    14871495            return rc;
    14881496        }
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.cpp

    r50078 r50095  
    2323#include "render/renderspu.h"
    2424
    25 static int crServerGetPointScreen(GLint x, GLint y)
    26 {
    27     int i;
    28 
    29     for (i=0; i<cr_server.screenCount; ++i)
    30     {
    31         if ((x>=cr_server.screen[i].x && x<cr_server.screen[i].x+(int)cr_server.screen[i].w)
    32            && (y>=cr_server.screen[i].y && y<cr_server.screen[i].y+(int)cr_server.screen[i].h))
    33         {
    34             return i;
    35         }
    36     }
    37 
    38     return -1;
    39 }
    40 
    41 static GLboolean crServerMuralCoverScreen(CRMuralInfo *mural, int sId)
    42 {
    43     return mural->gX < cr_server.screen[sId].x
    44            && mural->gX+(int)mural->width > cr_server.screen[sId].x+(int)cr_server.screen[sId].w
    45            && mural->gY < cr_server.screen[sId].y
    46            && mural->gY+(int)mural->height > cr_server.screen[sId].y+(int)cr_server.screen[sId].h;
    47 }
    48 
    49 void crServerDEntryResized(CRMuralInfo *pMural, CR_DISPLAY_ENTRY *pDEntry)
    50 {
    51     /*PBO*/
    52     if (pDEntry->idPBO)
    53     {
    54         CRASSERT(cr_server.bUsePBOForReadback);
    55         cr_server.head_spu->dispatch_table.DeleteBuffersARB(1, &pDEntry->idPBO);
    56         pDEntry->idPBO = 0;
    57     }
    58 
    59     if (pDEntry->idInvertTex)
    60     {
    61         cr_server.head_spu->dispatch_table.DeleteTextures(1, &pDEntry->idInvertTex);
    62         pDEntry->idInvertTex = 0;
    63     }
    64 
    65     if (pDEntry->pvORInstance)
    66     {
    67         cr_server.outputRedirect.CRORGeometry(pDEntry->pvORInstance,
    68                                                 pMural->hX + CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->x,
    69                                                 pMural->hY + CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->y,
    70                                                 CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->width,
    71                                                 CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->height);
    72 
    73         crServerDEntryVibleRegions(pMural, pDEntry);
    74     }
    75 }
    76 
    77 void crServerDEntryMoved(CRMuralInfo *pMural, CR_DISPLAY_ENTRY *pDEntry)
    78 {
    79     if (pDEntry->pvORInstance)
    80     {
    81         cr_server.outputRedirect.CRORGeometry(pDEntry->pvORInstance,
    82                                                 pMural->hX + CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->x,
    83                                                 pMural->hY + CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->y,
    84                                                 CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->width,
    85                                                 CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->height);
    86 
    87         crServerDEntryVibleRegions(pMural, pDEntry);
    88     }
    89 
    90 }
    91 
    92 void crServerDEntryVibleRegions(CRMuralInfo *pMural, CR_DISPLAY_ENTRY *pDEntry)
    93 {
    94     if (pDEntry->pvORInstance)
    95     {
    96         uint32_t cRects;
    97         const RTRECT *pRects;
    98 
    99         int rc = CrVrScrCompositorEntryRegionsGet(&pMural->Compositor, &pDEntry->CEntry, &cRects, NULL, &pRects, NULL);
    100         if (!RT_SUCCESS(rc))
    101         {
    102             crWarning("CrVrScrCompositorEntryRegionsGet failed, rc %d", rc);
    103             return;
    104         }
    105 
    106         cr_server.outputRedirect.CRORVisibleRegion(pDEntry->pvORInstance, cRects, pRects);
    107     }
    108 }
    109 
    110 /***/
    111 void crServerDEntryAllResized(CRMuralInfo *pMural)
    112 {
    113     VBOXVR_SCR_COMPOSITOR_ITERATOR Iter;
    114     PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry;
    115 
    116     CrVrScrCompositorIterInit(&pMural->Compositor, &Iter);
    117     while ((pEntry = CrVrScrCompositorIterNext(&Iter)) != NULL)
    118     {
    119         CR_DISPLAY_ENTRY *pDEntry = CR_DENTRY_FROM_CENTRY(pEntry);
    120         crServerDEntryResized(pMural, pDEntry);
    121     }
    122 }
    123 
    124 void crServerDEntryAllMoved(CRMuralInfo *pMural)
    125 {
    126     VBOXVR_SCR_COMPOSITOR_ITERATOR Iter;
    127     PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry;
    128 
    129     CrVrScrCompositorIterInit(&pMural->Compositor, &Iter);
    130 
    131     while ((pEntry = CrVrScrCompositorIterNext(&Iter)) != NULL)
    132     {
    133         CR_DISPLAY_ENTRY *pDEntry = CR_DENTRY_FROM_CENTRY(pEntry);
    134         crServerDEntryMoved(pMural, pDEntry);
    135     }
    136 }
    137 
    138 void crServerDEntryAllVibleRegions(CRMuralInfo *pMural)
    139 {
    140     VBOXVR_SCR_COMPOSITOR_ITERATOR Iter;
    141     PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry;
    142 
    143     CrVrScrCompositorIterInit(&pMural->Compositor, &Iter);
    144 
    145     while ((pEntry = CrVrScrCompositorIterNext(&Iter)) != NULL)
    146     {
    147         CR_DISPLAY_ENTRY *pDEntry = CR_DENTRY_FROM_CENTRY(pEntry);
    148         crServerDEntryVibleRegions(pMural, pDEntry);
    149     }
    150 }
    151 /**/
    152 
    153 void crServerDEntryCheckFBO(CRMuralInfo *pMural, CR_DISPLAY_ENTRY *pDEntry, CRContext *ctx)
    154 {
    155     if (!cr_server.bUsePBOForReadback == !pDEntry->idPBO)
    156         return;
    157 
    158     if (cr_server.bUsePBOForReadback)
    159     {
    160         Assert(!pDEntry->idPBO);
    161         cr_server.head_spu->dispatch_table.GenBuffersARB(1, &pDEntry->idPBO);
    162         cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pDEntry->idPBO);
    163         cr_server.head_spu->dispatch_table.BufferDataARB(GL_PIXEL_PACK_BUFFER_ARB,
    164                 CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->width*CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->height*4,
    165                 0, GL_STREAM_READ_ARB);
    166         cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, ctx->bufferobject.packBuffer->hwid);
    167 
    168         if (!pDEntry->idPBO)
    169         {
    170             crWarning("PBO create failed");
    171         }
    172     }
    173 }
    174 
    175 void crServerDEntryCheckInvertTex(CRMuralInfo *pMural, CR_DISPLAY_ENTRY *pDEntry, CRContext *ctx)
    176 {
    177     CRContextInfo *pMuralContextInfo;
    178 
    179     if (pDEntry->idInvertTex)
    180         return;
    181 
    182     pMuralContextInfo = cr_server.currentCtxInfo;
    183     if (!pMuralContextInfo)
    184     {
    185         /* happens on saved state load */
    186         CRASSERT(cr_server.MainContextInfo.SpuContext);
    187         pMuralContextInfo = &cr_server.MainContextInfo;
    188         cr_server.head_spu->dispatch_table.MakeCurrent(pMural->spuWindow, 0, cr_server.MainContextInfo.SpuContext);
    189     }
    190 
    191     if (pMuralContextInfo->CreateInfo.visualBits != pMural->CreateInfo.visualBits)
    192     {
    193         crWarning("mural visual bits do not match with current context visual bits!");
    194     }
    195 
    196     if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
    197     {
    198         cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
    199     }
    200 
    201     cr_server.head_spu->dispatch_table.GenTextures(1, &pDEntry->idInvertTex);
    202     CRASSERT(pDEntry->idInvertTex);
    203     cr_server.head_spu->dispatch_table.BindTexture(GL_TEXTURE_2D, pDEntry->idInvertTex);
    204     cr_server.head_spu->dispatch_table.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    205     cr_server.head_spu->dispatch_table.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    206     cr_server.head_spu->dispatch_table.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    207     cr_server.head_spu->dispatch_table.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    208     cr_server.head_spu->dispatch_table.TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,
    209             CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->width,
    210             CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->height,
    211             0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
    212 
    213 
    214     /*Restore gl state*/
    215     cr_server.head_spu->dispatch_table.BindTexture(GL_TEXTURE_2D,
    216             ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->hwid);
    217 
    218     if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
    219     {
    220         cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, ctx->bufferobject.unpackBuffer->hwid);
    221     }
    222 
    223     if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
    224     {
    225         cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, ctx->bufferobject.packBuffer->hwid);
    226     }
    227     else
    228     {
    229         cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
    230     }
    231 }
    232 
    233 void crServerDEntryImgRelease(CRMuralInfo *pMural, CR_DISPLAY_ENTRY *pDEntry, void*pvImg)
    234 {
    235     GLuint idPBO;
    236     CRContext *ctx = crStateGetCurrent();
    237 
    238     idPBO = cr_server.bUsePBOForReadback ? pDEntry->idPBO : 0;
    239 
    240     CrHlpFreeTexImage(ctx, idPBO, pvImg);
    241 }
    242 
    243 
    244 void* crServerDEntryImgAcquire(CRMuralInfo *pMural, CR_DISPLAY_ENTRY *pDEntry, GLenum enmFormat)
    245 {
    246     void* pvData;
    247     GLuint idPBO;
    248     VBOXVR_TEXTURE Tex;
    249     const VBOXVR_TEXTURE * pTex;
    250     CRContext *ctx = crStateGetCurrent();
    251 
    252     crServerDEntryCheckFBO(pMural, pDEntry, ctx);
    253 
    254     if (cr_server.bUsePBOForReadback && !pDEntry->idPBO)
    255     {
    256         crWarning("Mural doesn't have PBO even though bUsePBOForReadback is set!");
    257     }
    258 
    259     idPBO = cr_server.bUsePBOForReadback ? pDEntry->idPBO : 0;
    260 
    261     if (!(CrVrScrCompositorEntryFlagsGet(&pDEntry->CEntry) & CRBLT_F_INVERT_SRC_YCOORDS))
    262         pTex = CrVrScrCompositorEntryTexGet(&pDEntry->CEntry);
    263     else
    264     {
    265         CRMuralInfo *pCurrentMural = cr_server.currentMural;
    266         CRContextInfo *pCurCtxInfo = cr_server.currentCtxInfo;
    267         PCR_BLITTER pBlitter = crServerVBoxBlitterGet();
    268         CRMuralInfo *pBlitterMural;
    269         CR_SERVER_CTX_SWITCH CtxSwitch;
    270         RTRECT SrcRect, DstRect;
    271         CR_BLITTER_WINDOW BlitterBltInfo, CurrentBltInfo;
    272         CR_BLITTER_CONTEXT CtxBltInfo;
    273         int rc;
    274 
    275         crServerDEntryCheckInvertTex(pMural, pDEntry, ctx);
    276         if (!pDEntry->idInvertTex)
    277         {
    278             crWarning("crServerDEntryCheckInvertTex failed");
    279             return NULL;
    280         }
    281 
    282         Tex = *CrVrScrCompositorEntryTexGet(&pDEntry->CEntry);
    283         Tex.hwid = pDEntry->idInvertTex;
    284 
    285         SrcRect.xLeft = 0;
    286         SrcRect.yTop = Tex.height;
    287         SrcRect.xRight = Tex.width;
    288         SrcRect.yBottom = 0;
    289 
    290         DstRect.xLeft = 0;
    291         DstRect.yTop = 0;
    292         DstRect.xRight = Tex.width;
    293         DstRect.yBottom = Tex.height;
    294 
    295         if (pCurrentMural && pCurrentMural->CreateInfo.visualBits == CrBltGetVisBits(pBlitter))
    296         {
    297             pBlitterMural = pCurrentMural;
    298         }
    299         else
    300         {
    301             pBlitterMural = crServerGetDummyMural(pCurrentMural->CreateInfo.visualBits);
    302             if (!pBlitterMural)
    303             {
    304                 crWarning("crServerGetDummyMural failed for blitter mural");
    305                 return NULL;
    306             }
    307         }
    308 
    309         crServerCtxSwitchPrepare(&CtxSwitch, NULL);
    310 
    311         crServerVBoxBlitterWinInit(&CurrentBltInfo, pCurrentMural);
    312         crServerVBoxBlitterWinInit(&BlitterBltInfo, pBlitterMural);
    313         crServerVBoxBlitterCtxInit(&CtxBltInfo, pCurCtxInfo);
    314 
    315         CrBltMuralSetCurrent(pBlitter, &BlitterBltInfo);
    316 
    317         rc =  CrBltEnter(pBlitter, &CtxBltInfo, &CurrentBltInfo);
    318         if (RT_SUCCESS(rc))
    319         {
    320             CrBltBlitTexTex(pBlitter, CrVrScrCompositorEntryTexGet(&pDEntry->CEntry), &SrcRect, &Tex, &DstRect, 1, 0);
    321             CrBltLeave(pBlitter);
    322         }
    323         else
    324         {
    325             crWarning("CrBltEnter failed rc %d", rc);
    326         }
    327 
    328         crServerCtxSwitchPostprocess(&CtxSwitch);
    329 
    330         pTex = &Tex;
    331     }
    332 
    333     pvData = CrHlpGetTexImage(ctx, pTex, idPBO, enmFormat);
    334     if (!pvData)
    335         crWarning("CrHlpGetTexImage failed in crServerPresentFBO");
    336 
    337     return pvData;
    338 }
    339 
    340 
    341 /* Called when a new CRMuralInfo is created
    342  * or when OutputRedirect status is changed.
    343  */
    344 void crServerSetupOutputRedirectEntry(CRMuralInfo *mural, CR_DISPLAY_ENTRY *pDEntry)
    345 {
    346     /* Unset the previous redirect. */
    347     if (pDEntry->pvORInstance)
    348     {
    349         cr_server.outputRedirect.CROREnd(pDEntry->pvORInstance);
    350         pDEntry->pvORInstance = NULL;
    351     }
    352 
    353     /* Setup a new redirect. */
    354     if (cr_server.bUseOutputRedirect)
    355     {
    356         /* Query supported formats. */
    357         uint32_t cbFormats = 4096;
    358         char *pachFormats = (char *)crAlloc(cbFormats);
    359 
    360         if (pachFormats)
    361         {
    362             int rc = cr_server.outputRedirect.CRORContextProperty(cr_server.outputRedirect.pvContext,
    363                                                                   0 /* H3DOR_PROP_FORMATS */, // @todo from a header
    364                                                                   pachFormats, cbFormats, &cbFormats);
    365             if (RT_SUCCESS(rc))
    366             {
    367                 if (RTStrStr(pachFormats, "H3DOR_FMT_RGBA_TOPDOWN"))
    368                 {
    369                     cr_server.outputRedirect.CRORBegin(cr_server.outputRedirect.pvContext,
    370                                                        &pDEntry->pvORInstance,
    371                                                        "H3DOR_FMT_RGBA_TOPDOWN"); // @todo from a header
    372                 }
    373             }
    374 
    375             crFree(pachFormats);
    376         }
    377 
    378         /* If this is not NULL then there was a supported format. */
    379         if (pDEntry->pvORInstance)
    380         {
    381             uint32_t cRects;
    382             const RTRECT *pRects;
    383 
    384             int rc = CrVrScrCompositorEntryRegionsGet(&mural->Compositor, &pDEntry->CEntry, &cRects, NULL, &pRects, NULL);
    385             if (!RT_SUCCESS(rc))
    386             {
    387                 crWarning("CrVrScrCompositorEntryRegionsGet failed, rc %d", rc);
    388                 return;
    389             }
    390 
    391             cr_server.outputRedirect.CRORGeometry(pDEntry->pvORInstance,
    392                                                   mural->hX + CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->x,
    393                                                   mural->hY + CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->y,
    394                                                   CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->width,
    395                                                   CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->height);
    396 
    397             cr_server.outputRedirect.CRORVisibleRegion(pDEntry->pvORInstance, cRects, pRects);
    398 //!!
    399 //            crServerPresentFBO(mural);
    400         }
    401     }
    402 }
     25static void crServerRedirMuralFbSync(CRMuralInfo *mural);
    40326
    40427void crServerCheckMuralGeometry(CRMuralInfo *mural)
    40528{
    406     int tlS, brS, trS, blS;
    407     int overlappingScreenCount = 0, primaryS = -1 , i;
    408     uint64_t winID = 0;
    409     GLuint fPresentMode;
    410 
    41129    if (!mural->CreateInfo.externalID)
    41230        return;
     
    41533    CRASSERT(mural->spuWindow != CR_RENDER_DEFAULT_WINDOW_ID);
    41634
    417     crServerVBoxCompositionDisableEnter(mural);
     35    if (!mural->width || !mural->height
     36            || mural->fboWidth != mural->width
     37            || mural->fboHeight != mural->height)
     38    {
     39        crServerRedirMuralFbClear(mural);
     40        crServerRedirMuralFBO(mural, false);
     41        crServerDeleteMuralFBO(mural);
     42    }
    41843
    41944    if (!mural->width || !mural->height)
    420     {
    421         crServerRedirMuralFBO(mural, CR_SERVER_REDIR_F_NONE);
    422         crServerDeleteMuralFBO(mural);
    423         crServerVBoxCompositionDisableLeave(mural, GL_FALSE);
    42445        return;
    425     }
    426 
    427     tlS = crServerGetPointScreen(mural->gX, mural->gY);
    428     brS = crServerGetPointScreen(mural->gX+mural->width-1, mural->gY+mural->height-1);
    429 
    430     if ((tlS==brS && tlS>=0) || cr_server.screenCount <= 1)
    431     {
    432         if (cr_server.screenCount <= 1)
    433         {
    434             if (tlS != brS)
    435             {
    436                 if (tlS >= 0)
    437                     brS = tlS;
    438                 else
    439                     tlS = brS;
    440             }
    441 
    442             primaryS = 0;
    443         }
    444         else
    445         {
    446             Assert(brS == tlS);
    447 
    448             primaryS = brS;
    449         }
    450 
    451 
    452         Assert(brS == tlS);
    453 
    454         if (tlS>=0 && cr_server.screen[tlS].winID)
    455         {
    456             overlappingScreenCount = 1;
    457         }
    458     }
    459     else
    460     {
    461         bool fFoundWindIdScreen = false;
    462         trS = crServerGetPointScreen(mural->gX+mural->width-1, mural->gY);
    463         blS = crServerGetPointScreen(mural->gX, mural->gY+mural->height-1);
    464 
    465         primaryS = -1; overlappingScreenCount = 0;
    466         for (i=0; i<cr_server.screenCount; ++i)
    467         {
    468             if ((i==tlS) || (i==brS) || (i==trS) || (i==blS)
    469                 || crServerMuralCoverScreen(mural, i))
    470             {
    471                 if ((!fFoundWindIdScreen && cr_server.screen[i].winID) || primaryS<0)
    472                     primaryS = i;
    473 
    474                 if (cr_server.screen[i].winID)
    475                 {
    476                     overlappingScreenCount++;
    477                     fFoundWindIdScreen = true;
    478                 }
    479             }
    480         }
    481 
    482         if (primaryS<0)
    483         {
    484             primaryS = 0;
    485         }
    486     }
    487 
    488     CRASSERT(primaryS >= 0);
    489 
    490     winID = overlappingScreenCount ? cr_server.screen[primaryS].winID : 0;
    491 
    492     if (!winID != !mural->fHasParentWindow
    493             || (winID && primaryS!=mural->screenId))
    494     {
    495         mural->fHasParentWindow = !!winID;
    496 
    497         renderspuSetWindowId(winID);
    498         renderspuReparentWindow(mural->spuWindow);
    499         renderspuSetWindowId(cr_server.screen[0].winID);
    500     }
    501 
    502     if (primaryS != mural->screenId)
    503     {
    504         /* mark it invisible on the old screen */
    505         crServerWindowSetIsVisible(mural, GL_FALSE);
    506         mural->screenId = primaryS;
    507         /* check if mural is visivle on the new screen, and mark it as such */
    508         crServerWindowCheckIsVisible(mural);
    509     }
    510 
    511     mural->hX = mural->gX-cr_server.screen[primaryS].x;
    512     mural->hY = mural->gY-cr_server.screen[primaryS].y;
    513 
    514     fPresentMode = cr_server.fPresentMode;
    515 
    516     if (!mural->fHasParentWindow)
    517         fPresentMode &= ~CR_SERVER_REDIR_F_DISPLAY;
    518 
    519     if (!overlappingScreenCount)
    520         fPresentMode &= ~CR_SERVER_REDIR_F_DISPLAY;
    521     else if (overlappingScreenCount > 1)
    522         fPresentMode = (fPresentMode | CR_SERVER_REDIR_F_FBO_RAM_VMFB | cr_server.fVramPresentModeDefault) & ~CR_SERVER_REDIR_F_DISPLAY;
    523 
    524     if (!mural->fUseDefaultDEntry)
    525     {
    526         /* only display matters */
    527         fPresentMode &= CR_SERVER_REDIR_F_DISPLAY;
    528     }
    529 
    530     fPresentMode = crServerRedirModeAdjust(fPresentMode);
    531 
    532     if (!(fPresentMode & CR_SERVER_REDIR_F_FBO))
    533     {
    534         crServerRedirMuralFBO(mural, fPresentMode);
    535         crServerDeleteMuralFBO(mural);
    536     }
    537     else
    538     {
    539         if (mural->fPresentMode & CR_SERVER_REDIR_F_FBO)
    540         {
    541             if (mural->width!=mural->fboWidth
    542                 || mural->height!=mural->fboHeight)
    543             {
    544                 crServerRedirMuralFBO(mural, fPresentMode & CR_SERVER_REDIR_F_DISPLAY);
    545                 crServerDeleteMuralFBO(mural);
    546             }
    547         }
    548 
    549         crServerRedirMuralFBO(mural, fPresentMode);
    550     }
    551 
    552     if (mural->fPresentMode & CR_SERVER_REDIR_F_DISPLAY)
    553     {
    554         CRScreenViewportInfo *pVieport = &cr_server.screenVieport[mural->screenId];
    555 
    556         cr_server.head_spu->dispatch_table.WindowPosition(mural->spuWindow, mural->hX - pVieport->x, mural->hY - pVieport->y);
    557     }
    558 
    559     crServerVBoxCompositionDisableLeave(mural, GL_FALSE);
     46
     47    crServerRedirMuralFBO(mural, true);
     48    crServerRedirMuralFbSync(mural);
    56049}
    56150
     
    57665}
    57766
    578 static void crServerDentryPresentVRAM(CRMuralInfo *mural, CR_DISPLAY_ENTRY *pDEntry, char *pixels);
    579 
    580 #define CR_SERVER_MURAL_FROM_RPW_ENTRY(_pEntry) ((CRMuralInfo*)(((uint8_t*)(_pEntry)) - RT_OFFSETOF(CRMuralInfo, RpwEntry)))
    581 
    582 static DECLCALLBACK(void) crServerMuralRpwDataCB(const struct CR_SERVER_RPW_ENTRY* pEntry, void *pvEntryTexData)
    583 {
    584     CRMuralInfo *pMural = CR_SERVER_MURAL_FROM_RPW_ENTRY(pEntry);
    585 
    586     Assert(&pMural->RpwEntry == pEntry);
    587     crError("port me!");
    588     //    crServerPresentMuralVRAM(pMural, pvEntryTexData);
    589 }
    590 
    59167static void crServerCreateMuralFBO(CRMuralInfo *mural);
    59268
    593 static bool crServerEnableMuralRpw(CRMuralInfo *mural, GLboolean fEnable)
    594 {
     69void crServerRedirMuralFbClear(CRMuralInfo *mural)
     70{
     71    uint32_t i;
     72    for (i = 0; i < mural->cUsedFBDatas; ++i)
     73    {
     74        CR_FBDATA *pData = mural->apUsedFBDatas[i];
     75        int rc = CrFbUpdateBegin(pData->hFb);
     76        if (RT_SUCCESS(rc))
     77        {
     78            CrFbEntryRegionsSet(pData->hFb, pData->hFbEntry, NULL, 0, NULL, false);
     79            CrFbUpdateEnd(pData->hFb);
     80        }
     81        else
     82            WARN(("CrFbUpdateBegin failed rc %d", rc));
     83    }
     84    mural->cUsedFBDatas = 0;
     85
     86    for (i = 0; i < cr_server.screenCount; ++i)
     87    {
     88        GLuint j;
     89        CR_FBDATA *pData = &mural->aFBDatas[i];
     90        if (!pData->hFb)
     91            continue;
     92
     93        CrFbEntryRelease(pData->hFb, pData->hFbEntry);
     94        pData->hFbEntry = NULL;
     95
     96        for (j = 0; j < mural->cBuffers; ++j)
     97        {
     98            CrTdRelease(pData->apTexDatas[j]);
     99            pData->apTexDatas[j] = NULL;
     100        }
     101
     102        pData->hFb = NULL;
     103    }
     104}
     105
     106static int crServerRedirMuralDbSyncFb(CRMuralInfo *mural, HCR_FRAMEBUFFER hFb, CR_FBDATA **ppData)
     107{
     108    CR_FBDATA *pData;
     109    const struct VBVAINFOSCREEN* pScreenInfo = CrFbGetScreenInfo(hFb);
     110    const struct VBOXVR_SCR_COMPOSITOR* pCompositor = CrFbGetCompositor(hFb);
     111    RTRECT FbRect = *CrVrScrCompositorRectGet(pCompositor);
     112    RTRECT DefaultRegionsRect;
     113    const RTRECT * pRegions;
     114    uint32_t cRegions;
     115    RTPOINT Pos;
     116    RTRECT MuralRect;
     117    int rc;
     118
     119    CRASSERT(mural->fRedirected);
     120
     121    *ppData = NULL;
     122
     123    if (!mural->bVisible)
     124        return VINF_SUCCESS;
     125
     126    MuralRect.xLeft = mural->gX;
     127    MuralRect.yTop = mural->gY;
     128    MuralRect.xRight = MuralRect.xLeft + mural->width;
     129    MuralRect.yBottom = MuralRect.yTop + mural->height;
     130
     131    Pos.x = mural->gX - pScreenInfo->i32OriginX;
     132    Pos.y = mural->gY - pScreenInfo->i32OriginY;
     133
     134    VBoxRectTranslate(&FbRect, pScreenInfo->i32OriginX, pScreenInfo->i32OriginY);
     135
     136    VBoxRectIntersect(&FbRect, &MuralRect);
     137
     138    if (VBoxRectIsZero(&FbRect))
     139        return VINF_SUCCESS;
     140
     141    if (mural->bReceivedRects)
     142    {
     143        pRegions = (const RTRECT*)mural->pVisibleRects;
     144        cRegions = mural->cVisibleRects;
     145    }
     146    else
     147    {
     148        DefaultRegionsRect.xLeft = 0;
     149        DefaultRegionsRect.yTop = 0;
     150        DefaultRegionsRect.xRight = mural->width;
     151        DefaultRegionsRect.yBottom = mural->height;
     152        pRegions = &DefaultRegionsRect;
     153        cRegions = 1;
     154    }
     155
     156    if (!cRegions)
     157        return VINF_SUCCESS;
     158
     159    pData = &mural->aFBDatas[pScreenInfo->u32ViewIndex];
     160
     161    if (!pData->hFb)
     162    {
     163        pData->hFb = hFb;
     164
     165        for (uint32_t i = 0; i < mural->cBuffers; ++i)
     166        {
     167            VBOXVR_TEXTURE Tex;
     168            int rc;
     169            Tex.width = mural->width;
     170            Tex.height = mural->height;
     171            Tex.hwid = mural->aidColorTexs[i];
     172            Tex.target = GL_TEXTURE_2D;
     173
     174            pData->apTexDatas[i] = CrFbTexDataCreate(&Tex);
     175        }
     176
     177        rc = CrFbEntryCreateForTexData(hFb, pData->apTexDatas[CR_SERVER_FBO_FB_IDX(mural)], 0, &pData->hFbEntry);
     178        if (!RT_SUCCESS(rc))
     179        {
     180            WARN(("CrFbEntryCreateForTexData failed rc %d", rc));
     181        }
     182    }
     183    else
     184    {
     185        CRASSERT(pData->hFb == hFb);
     186    }
     187
     188    rc = CrFbUpdateBegin(hFb);
     189    if (!RT_SUCCESS(rc))
     190    {
     191        WARN(("CrFbUpdateBegin failed rc %d", rc));
     192        return rc;
     193    }
     194
     195    rc = CrFbEntryRegionsSet(hFb, pData->hFbEntry, &Pos, cRegions, pRegions, true);
     196    if (!RT_SUCCESS(rc))
     197    {
     198        WARN(("CrFbEntryRegionsSet failed rc %d", rc));
     199    }
     200
     201    CrFbUpdateEnd(hFb);
     202
     203    const struct VBOXVR_SCR_COMPOSITOR_ENTRY* pCEntry = CrFbEntryGetCompositorEntry(pData->hFbEntry);
     204    if (CrVrScrCompositorEntryIsUsed(pCEntry))
     205        *ppData = pData;
     206
     207    return rc;
     208}
     209
     210static void crServerRedirMuralFbSync(CRMuralInfo *mural)
     211{
     212    uint32_t i;
     213    uint32_t cUsedFBs = 0;
     214    HCR_FRAMEBUFFER ahUsedFbs[CR_MAX_GUEST_MONITORS];
     215    HCR_FRAMEBUFFER hFb;
     216
     217    for (i = 0; i < mural->cUsedFBDatas; ++i)
     218    {
     219        CR_FBDATA *pData = mural->apUsedFBDatas[i];
     220        int rc = CrFbUpdateBegin(pData->hFb);
     221        if (RT_SUCCESS(rc))
     222        {
     223            ahUsedFbs[cUsedFBs] = pData->hFb;
     224            CrFbEntryRegionsSet(pData->hFb, pData->hFbEntry, NULL, 0, NULL, false);
     225            ++cUsedFBs;
     226        }
     227        else
     228            WARN(("CrFbUpdateBegin failed rc %d", rc));
     229    }
     230    mural->cUsedFBDatas = 0;
     231
     232    if (!mural->width
     233            || !mural->height
     234            || !mural->bVisible
     235            )
     236        goto end;
     237
     238    CRASSERT(mural->fRedirected);
     239
     240    for (hFb = CrPMgrFbGetFirstEnabled();
     241            hFb;
     242            hFb = CrPMgrFbGetNextEnabled(hFb))
     243    {
     244        CR_FBDATA *pData = NULL;
     245        int rc = crServerRedirMuralDbSyncFb(mural, hFb, &pData);
     246        if (!RT_SUCCESS(rc))
     247        {
     248            WARN(("crServerRedirMuralDbSyncFb failed %d", rc));
     249            continue;
     250        }
     251
     252        if (!pData)
     253            continue;
     254
     255        mural->apUsedFBDatas[mural->cUsedFBDatas] = pData;
     256        ++mural->cUsedFBDatas;
     257    }
     258
     259end:
     260
     261    for (i = 0; i < cUsedFBs; ++i)
     262    {
     263        CrFbUpdateEnd(ahUsedFbs[i]);
     264    }
     265}
     266
     267static void crVBoxServerMuralFbCleanCB(unsigned long key, void *data1, void *data2)
     268{
     269    CRMuralInfo *pMI = (CRMuralInfo*) data1;
     270    HCR_FRAMEBUFFER hFb = (HCR_FRAMEBUFFER)data2;
     271    uint32_t i;
     272    for (i = 0; i < pMI->cUsedFBDatas; ++i)
     273    {
     274        CR_FBDATA *pData = pMI->apUsedFBDatas[i];
     275        if (hFb != pData->hFb)
     276            continue;
     277
     278        CrFbEntryRegionsSet(pData->hFb, pData->hFbEntry, NULL, 0, NULL, false);
     279        break;
     280    }
     281}
     282
     283static void crVBoxServerMuralFbSetCB(unsigned long key, void *data1, void *data2)
     284{
     285    CRMuralInfo *pMI = (CRMuralInfo*) data1;
     286    HCR_FRAMEBUFFER hFb = (HCR_FRAMEBUFFER)data2;
     287    uint32_t i;
     288    CR_FBDATA *pData = NULL;
     289    bool fFbWasUsed = false;
     290
     291    Assert(hFb);
     292
     293    if (!pMI->fRedirected)
     294    {
     295        Assert(!pMI->cUsedFBDatas);
     296        return;
     297    }
     298
     299    for (i = 0; i < pMI->cUsedFBDatas; ++i)
     300    {
     301        CR_FBDATA *pData = pMI->apUsedFBDatas[i];
     302        if (hFb != pData->hFb)
     303            continue;
     304
     305        fFbWasUsed = true;
     306        break;
     307    }
     308
     309    if (CrFbIsEnabled(hFb))
     310    {
     311        int rc = crServerRedirMuralDbSyncFb(pMI, hFb, &pData);
     312        if (!RT_SUCCESS(rc))
     313        {
     314            WARN(("crServerRedirMuralDbSyncFb failed %d", rc));
     315            pData = NULL;
     316        }
     317    }
     318
     319    if (pData)
     320    {
     321        if (!fFbWasUsed)
     322        {
     323            uint32_t idScreen = CrFbGetScreenInfo(hFb)->u32ViewIndex;
     324            for (i = 0; i < pMI->cUsedFBDatas; ++i)
     325            {
     326                CR_FBDATA *pData = pMI->apUsedFBDatas[i];
     327                uint32_t idCurScreen = CrFbGetScreenInfo(pData->hFb)->u32ViewIndex;
     328                if (idCurScreen > idScreen)
     329                    break;
     330
     331                Assert(idCurScreen != idScreen);
     332            }
     333
     334            for (int j = pMI->cUsedFBDatas; j > i; --j)
     335            {
     336                pMI->apUsedFBDatas[j] = pMI->apUsedFBDatas[j-1];
     337            }
     338
     339            pMI->apUsedFBDatas[i] = pData;
     340            ++pMI->cUsedFBDatas;
     341        }
     342        /* else - nothing to do */
     343    }
     344    else
     345    {
     346        if (fFbWasUsed)
     347        {
     348            for (int j = i; j < pMI->cUsedFBDatas - 1; ++j)
     349            {
     350                pMI->apUsedFBDatas[j] = pMI->apUsedFBDatas[j+1];
     351            }
     352            --pMI->cUsedFBDatas;
     353        }
     354        /* else - nothing to do */
     355    }
     356}
     357
     358void crVBoxServerMuralFbResizeEnd(HCR_FRAMEBUFFER hFb)
     359{
     360    crHashtableWalk(cr_server.muralTable, crVBoxServerMuralFbSetCB, hFb);
     361}
     362
     363void crVBoxServerMuralFbResizeBegin(HCR_FRAMEBUFFER hFb)
     364{
     365    crHashtableWalk(cr_server.muralTable, crVBoxServerMuralFbCleanCB, hFb);
     366}
     367
     368DECLEXPORT(int) crVBoxServerNotifyResize(const struct VBVAINFOSCREEN *pScreen, void *pvVRAM)
     369{
     370    int rc;
     371    HCR_FRAMEBUFFER hFb = CrPMgrFbGet(pScreen->u32ViewIndex);
     372    if (!hFb)
     373    {
     374        WARN(("CrPMgrFbGet failed"));
     375        return VERR_INVALID_PARAMETER;
     376    }
     377
     378    rc = CrFbUpdateBegin(hFb);
     379    if (!RT_SUCCESS(rc))
     380    {
     381        WARN(("CrFbUpdateBegin failed %d", rc));
     382        return rc;
     383    }
     384
     385    crVBoxServerMuralFbResizeBegin(hFb);
     386
     387    rc = CrFbResize(hFb, pScreen, pvVRAM);
     388    if (!RT_SUCCESS(rc))
     389    {
     390        WARN(("CrFbResize failed %d", rc));
     391    }
     392
     393    crVBoxServerMuralFbResizeEnd(hFb);
     394
     395    CrFbUpdateEnd(hFb);
     396
     397    CrPMgrNotifyResize(hFb);
     398
     399    return rc;
     400}
     401
     402void crServerRedirMuralFBO(CRMuralInfo *mural, bool fEnabled)
     403{
     404    if (!mural->fRedirected == !fEnabled)
     405    {
     406        return;
     407    }
     408
    595409    if (!mural->CreateInfo.externalID)
    596410    {
    597         crWarning("trying to change Rpw setting for internal mural %d", mural->spuWindow);
    598         return !fEnable;
    599     }
    600 
    601     if (fEnable)
    602     {
    603         if (!(mural->fPresentMode & CR_SERVER_REDIR_F_FBO_RPW))
    604         {
    605             int rc;
    606             if (!crServerRpwIsInitialized(&cr_server.RpwWorker))
    607             {
    608                 rc = crServerRpwInit(&cr_server.RpwWorker);
    609                 if (!RT_SUCCESS(rc))
    610                 {
    611                     crWarning("crServerRpwInit failed rc %d", rc);
    612                     return false;
    613                 }
    614             }
    615 
    616             CRASSERT(!mural->RpwEntry.Size.cx);
    617             CRASSERT(!mural->RpwEntry.Size.cy);
    618 
    619             if (!crServerRpwEntryIsInitialized(&mural->RpwEntry))
    620             {
    621                 rc = crServerRpwEntryInit(&cr_server.RpwWorker, &mural->RpwEntry, mural->width, mural->height, crServerMuralRpwDataCB);
    622                 if (!RT_SUCCESS(rc))
    623                 {
    624                     crWarning("crServerRpwEntryInit failed rc %d", rc);
    625                     return false;
    626                 }
    627             }
    628             else
    629             {
    630                 rc = crServerRpwEntryResize(&cr_server.RpwWorker, &mural->RpwEntry, mural->width, mural->height);
    631                 if (!RT_SUCCESS(rc))
    632                 {
    633                     crWarning("crServerRpwEntryResize failed rc %d", rc);
    634                     return false;
    635                 }
    636             }
    637 
    638             mural->fPresentMode |= CR_SERVER_REDIR_F_FBO_RPW;
    639         }
    640     }
    641     else
    642     {
    643         if ((mural->fPresentMode & CR_SERVER_REDIR_F_FBO_RPW))
    644         {
    645 //            crServerRpwEntryCleanup(&cr_server.RpwWorker, &mural->RpwEntry);
    646             mural->fPresentMode &= ~CR_SERVER_REDIR_F_FBO_RPW;
    647         }
    648     }
    649 
    650     return true;
    651 }
    652 
    653 static void crServerEnableDisplayMuralFBO(CRMuralInfo *mural, GLboolean fEnable)
    654 {
    655     if (!mural->CreateInfo.externalID)
    656     {
    657         crWarning("trying to change display setting for internal mural %d", mural->spuWindow);
     411        WARN(("trying to change redir setting for internal mural %d", mural->spuWindow));
    658412        return;
    659413    }
    660414
    661     if (fEnable)
    662     {
    663         if (!(mural->fPresentMode & CR_SERVER_REDIR_F_DISPLAY))
    664         {
    665             mural->fPresentMode |= CR_SERVER_REDIR_F_DISPLAY;
    666 
    667             if  (mural->bVisible)
    668                 crServerWindowShow(mural);
    669         }
    670     }
    671     else
    672     {
    673         if ((mural->fPresentMode & CR_SERVER_REDIR_F_DISPLAY))
    674         {
    675             mural->fPresentMode &= ~CR_SERVER_REDIR_F_DISPLAY;
    676 
    677             if (mural->bVisible)
    678                 crServerWindowShow(mural);
    679         }
    680     }
    681 }
    682 
    683 void crServerRedirMuralFBO(CRMuralInfo *mural, GLuint redir)
    684 {
    685     if (mural->fPresentMode == redir)
    686     {
    687 //        if (redir)
    688 //            crWarning("crServerRedirMuralFBO called with the same redir status %d", redir);
    689         return;
    690     }
    691 
    692     if (!mural->CreateInfo.externalID)
    693     {
    694         crWarning("trying to change redir setting for internal mural %d", mural->spuWindow);
    695         return;
    696     }
    697 
    698     crServerVBoxCompositionDisableEnter(mural);
    699 
    700     if (redir & CR_SERVER_REDIR_F_FBO)
     415    if (fEnabled)
    701416    {
    702417        if (!crServerSupportRedirMuralFBO())
    703418        {
    704             crWarning("FBO not supported, can't redirect window output");
    705             goto end;
    706         }
    707 
    708         if (mural->fUseDefaultDEntry && mural->aidFBOs[0]==0)
     419            WARN(("FBO not supported, can't redirect window output"));
     420            return;
     421        }
     422
     423        if (mural->aidFBOs[0]==0)
    709424        {
    710425            crServerCreateMuralFBO(mural);
     
    744459    }
    745460
    746     crServerEnableMuralRpw(mural, !!(redir & CR_SERVER_REDIR_F_FBO_RPW));
    747 
    748     crServerEnableDisplayMuralFBO(mural, !!(redir & CR_SERVER_REDIR_F_DISPLAY));
    749 
    750     mural->fPresentMode = redir;
    751 
    752 end:
    753     crServerVBoxCompositionDisableLeave(mural, GL_FALSE);
     461    mural->fRedirected = !!fEnabled;
    754462}
    755463
     
    764472    CRASSERT(mural->aidFBOs[0]==0);
    765473    CRASSERT(mural->aidFBOs[1]==0);
    766     CRASSERT(mural->fUseDefaultDEntry);
    767     CRASSERT(mural->width == mural->DefaultDEntry.CEntry.Tex.width);
    768     CRASSERT(mural->height == mural->DefaultDEntry.CEntry.Tex.height);
    769474
    770475    pMuralContextInfo = cr_server.currentCtxInfo;
     
    779484    if (pMuralContextInfo->CreateInfo.visualBits != mural->CreateInfo.visualBits)
    780485    {
    781         crWarning("mural visual bits do not match with current context visual bits!");
     486        WARN(("mural visual bits do not match with current context visual bits!"));
    782487    }
    783488
     
    825530        if (status!=GL_FRAMEBUFFER_COMPLETE_EXT)
    826531        {
    827             crWarning("FBO status(0x%x) isn't complete", status);
     532            WARN(("FBO status(0x%x) isn't complete", status));
    828533        }
    829534    }
     
    866571
    867572    CRASSERT(mural->aidColorTexs[CR_SERVER_FBO_FB_IDX(mural)]);
    868 
    869     CrVrScrCompositorEntryTexNameUpdate(&mural->DefaultDEntry.CEntry, mural->aidColorTexs[CR_SERVER_FBO_FB_IDX(mural)]);
    870 
    871 //    if (mural->fRootVrOn)
    872 //        CrVrScrCompositorEntryTexNameUpdate(&mural->DefaultDEntry.RootVrCEntry, mural->aidColorTexs[CR_SERVER_FBO_FB_IDX(mural)]);
    873573}
    874574
    875575void crServerDeleteMuralFBO(CRMuralInfo *mural)
    876576{
    877     CRASSERT(!(mural->fPresentMode & CR_SERVER_REDIR_F_FBO));
    878 
    879577    if (mural->aidFBOs[0]!=0)
    880578    {
     
    897595
    898596    mural->cBuffers = 0;
    899 
    900     if (crServerRpwEntryIsInitialized(&mural->RpwEntry))
    901         crServerRpwEntryCleanup(&cr_server.RpwWorker, &mural->RpwEntry);
    902597}
    903598
     
    917612}
    918613
    919 static GLboolean crServerIntersectScreen(CRMuralInfo *mural, CR_DISPLAY_ENTRY *pDEntry, int sId, CRrecti *rect)
    920 {
    921     rect->x1 = MAX(mural->gX + CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->x, cr_server.screen[sId].x);
    922     rect->x2 = MIN(mural->gX + CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->x
    923             + (int)CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->width,
    924             cr_server.screen[sId].x+(int)cr_server.screen[sId].w);
    925     rect->y1 = MAX(mural->gY + CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->y, cr_server.screen[sId].y);
    926     rect->y2 = MIN(mural->gY + CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->y
    927             + (int)CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->height,
    928             cr_server.screen[sId].y+(int)cr_server.screen[sId].h);
    929 
    930     return (rect->x2>rect->x1) && (rect->y2>rect->y1);
    931 }
    932 
    933614static void crServerCopySubImage(char *pDst, char* pSrc, CRrecti *pRect, int srcWidth, int srcHeight)
    934615{
     
    949630}
    950631
    951 static void crServerTransformRect(CRrecti *pDst, CRrecti *pSrc, int dx, int dy)
    952 {
    953     pDst->x1 = pSrc->x1+dx;
    954     pDst->x2 = pSrc->x2+dx;
    955     pDst->y1 = pSrc->y1+dy;
    956     pDst->y2 = pSrc->y2+dy;
    957 }
    958 
    959 static void crServerVBoxCompositionPresentPerform(CRMuralInfo *mural)
    960 {
    961     CRMuralInfo *currentMural = cr_server.currentMural;
    962     CRContextInfo *curCtxInfo = cr_server.currentCtxInfo;
    963     GLuint idDrawFBO, idReadFBO;
    964     CRContext *curCtx = curCtxInfo ? curCtxInfo->pContext : NULL;
    965 
    966     CRASSERT(curCtx == crStateGetCurrent());
    967 
    968     Assert((mural->fPresentMode & CR_SERVER_REDIR_F_FBO) || !mural->fUseDefaultDEntry);
    969     Assert(mural->fPresentMode & CR_SERVER_REDIR_F_DISPLAY);
    970 
    971     mural->fDataPresented = GL_TRUE;
    972 
    973     if (currentMural)
    974     {
    975         idDrawFBO = CR_SERVER_FBO_FOR_IDX(currentMural, currentMural->iCurDrawBuffer);
    976         idReadFBO = CR_SERVER_FBO_FOR_IDX(currentMural, currentMural->iCurReadBuffer);
    977     }
    978     else
    979     {
    980         idDrawFBO = 0;
    981         idReadFBO = 0;
    982     }
    983 
    984     crStateSwitchPrepare(NULL, curCtx, idDrawFBO, idReadFBO);
    985 
    986     if (!mural->fRootVrOn)
    987         cr_server.head_spu->dispatch_table.VBoxPresentComposition(mural->spuWindow, &mural->Compositor, NULL);
    988     else
    989         cr_server.head_spu->dispatch_table.VBoxPresentComposition(mural->spuWindow, &mural->RootVrCompositor, NULL);
    990 
    991     crStateSwitchPostprocess(curCtx, NULL, idDrawFBO, idReadFBO);
    992 }
    993 
    994 void crServerVBoxCompositionPresent(CRMuralInfo *mural)
    995 {
    996     if (!crServerVBoxCompositionPresentNeeded(mural))
    997         return;
    998     crServerVBoxCompositionPresentPerform(mural);
    999 }
    1000 
    1001 static void crServerVBoxCompositionReenable(CRMuralInfo *mural)
    1002 {
    1003     GLboolean fForcePresent = mural->fForcePresentState;
    1004     GLboolean fOrPresentOnReenable = mural->fOrPresentOnReenable;
    1005 
    1006     mural->fForcePresentState = GL_FALSE;
    1007     mural->fOrPresentOnReenable = GL_FALSE;
    1008 
    1009     if ((mural->fUseDefaultDEntry && !(mural->fPresentMode & CR_SERVER_REDIR_F_FBO))
    1010             || !mural->fDataPresented
    1011             || (!fForcePresent
    1012                     && !crServerVBoxCompositionPresentNeeded(mural)))
    1013         return;
    1014 
    1015     if (mural->fPresentMode & CR_SERVER_REDIR_F_DISPLAY)
    1016         crServerVBoxCompositionPresentPerform(mural);
    1017 
    1018     if (fOrPresentOnReenable
    1019             && cr_server.bUseOutputRedirect
    1020             && crServerVBoxCompositionPresentNeeded(mural))
    1021         crServerPresentOutputRedirect(mural);
    1022 }
    1023 
    1024 static void crServerVBoxCompositionDisable(CRMuralInfo *mural)
    1025 {
    1026     if (!(mural->fPresentMode & CR_SERVER_REDIR_F_DISPLAY)
    1027             || (mural->fUseDefaultDEntry && !(mural->fPresentMode & CR_SERVER_REDIR_F_FBO))
    1028             || !mural->fDataPresented)
    1029         return;
    1030     cr_server.head_spu->dispatch_table.VBoxPresentComposition(mural->spuWindow, NULL, NULL);
    1031 }
    1032 
    1033 void crServerVBoxCompositionDisableEnter(CRMuralInfo *mural)
    1034 {
    1035     ++cr_server.cDisableEvents;
    1036     Assert(cr_server.cDisableEvents);
    1037 
    1038     ++mural->cDisabled;
    1039     Assert(mural->cDisabled);
    1040     if (mural->cDisabled == 1)
    1041     {
    1042         crServerVBoxCompositionDisable(mural);
    1043     }
    1044 }
    1045 
    1046 void crServerVBoxCompositionDisableLeave(CRMuralInfo *mural, GLboolean fForcePresentOnEnabled)
    1047 {
    1048     mural->fForcePresentState |= fForcePresentOnEnabled;
    1049     --mural->cDisabled;
    1050     Assert(mural->cDisabled < UINT32_MAX/2);
    1051     if (!mural->cDisabled)
    1052     {
    1053         crServerVBoxCompositionReenable(mural);
    1054     }
    1055 
    1056     --cr_server.cDisableEvents;
    1057     Assert(cr_server.cDisableEvents < UINT32_MAX/2);
    1058     crVBoxServerCheckVisibilityEvent(-1);
    1059 }
    1060 
    1061 static void crServerVBoxCompositionSetEnableStateGlobalCB(unsigned long key, void *data1, void *data2)
    1062 {
    1063     CRMuralInfo *mural = (CRMuralInfo *)data1;
    1064 
    1065     if (data2)
    1066         crServerVBoxCompositionDisableLeave(mural, GL_FALSE);
    1067     else
    1068         crServerVBoxCompositionDisableEnter(mural);
    1069 }
    1070 
    1071632DECLEXPORT(void) crServerVBoxCompositionSetEnableStateGlobal(GLboolean fEnable)
    1072633{
    1073     int i;
    1074 
    1075     crHashtableWalk(cr_server.muralTable, crServerVBoxCompositionSetEnableStateGlobalCB, (void*)(uintptr_t)fEnable);
    1076 
    1077     crHashtableWalk(cr_server.dummyMuralTable, crServerVBoxCompositionSetEnableStateGlobalCB, (void*)(uintptr_t)fEnable);
    1078 
    1079     for (i = 0; i < cr_server.screenCount; ++i)
    1080     {
    1081         PCR_DISPLAY pDisplay = crServerDisplayGetInitialized((uint32_t)i);
    1082         if (!pDisplay)
    1083             continue;
    1084 
    1085         if (!fEnable)
    1086             CrDpEnter(pDisplay);
     634}
     635
     636void crServerPresentFBO(CRMuralInfo *mural)
     637{
     638    uint32_t i;
     639    for (i = 0; i < mural->cUsedFBDatas; ++i)
     640    {
     641        CR_FBDATA *pData = mural->apUsedFBDatas[i];
     642        int rc = CrFbUpdateBegin(pData->hFb);
     643        if (RT_SUCCESS(rc))
     644        {
     645            CrFbEntryTexDataUpdate(pData->hFb, pData->hFbEntry, pData->apTexDatas[CR_SERVER_FBO_FB_IDX(mural)]);
     646            CrFbUpdateEnd(pData->hFb);
     647        }
    1087648        else
    1088             CrDpLeave(pDisplay);
    1089     }
    1090 }
    1091 
    1092 static void crServerDentryPresentVRAM(CRMuralInfo *mural, CR_DISPLAY_ENTRY *pDEntry, char *pixels)
    1093 {
    1094     char *tmppixels;
    1095     CRrecti rect, rectwr, sectr;
    1096     int i, rc;
    1097     uint32_t j;
    1098 
    1099     if (mural->fPresentMode & CR_SERVER_REDIR_F_FBO_RAM_VMFB)
    1100     {
    1101         for (i=0; i<cr_server.screenCount; ++i)
    1102         {
    1103             if (crServerIntersectScreen(mural, pDEntry, i, &rect))
    1104             {
    1105                 uint32_t cRects;
    1106                 const RTRECT *pRects;
    1107 
    1108                 /* rect in window relative coords */
    1109                 crServerTransformRect(&rectwr, &rect, -mural->gX, -mural->gY);
    1110 
    1111                 rc = CrVrScrCompositorEntryRegionsGet(&mural->Compositor, &pDEntry->CEntry, &cRects, NULL, &pRects, NULL);
    1112                 if (RT_SUCCESS(rc))
    1113                 {
    1114                     /*we don't get any rects info for guest compiz windows, so we treat windows as visible unless explicitly received 0 visible rects*/
    1115                     for (j=0; j<cRects; ++j)
    1116                     {
    1117                         if (crServerIntersectRect(&rectwr, (CRrecti*)&pRects[j], &sectr))
    1118                         {
    1119                             tmppixels = crAlloc(4*(sectr.x2-sectr.x1)*(sectr.y2-sectr.y1));
    1120                             if (!tmppixels)
    1121                             {
    1122                                 crWarning("Out of memory in crServerPresentFBO");
    1123                                 crFree(pixels);
    1124                                 return;
    1125                             }
    1126 
    1127                             crServerCopySubImage(tmppixels, pixels, &sectr, CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->width, CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->height);
    1128                             /*Note: pfnPresentFBO would free tmppixels*/
    1129                             cr_server.pfnPresentFBO(tmppixels, i,
    1130                                                     sectr.x1+mural->gX+CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->x-cr_server.screen[i].x,
    1131                                                     sectr.y1+mural->gY+CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->y-cr_server.screen[i].y,
    1132                                                     sectr.x2-sectr.x1, sectr.y2-sectr.y1);
    1133                         }
    1134                     }
    1135                 }
    1136                 else
    1137                 {
    1138                     crWarning("CrVrScrCompositorEntryRegionsGet failed, rc %d", rc);
    1139                 }
    1140             }
    1141         }
    1142     }
    1143 
    1144     if (pDEntry->pvORInstance)
    1145     {
    1146         /* @todo find out why presentfbo is not called but crorframe is called. */
    1147         cr_server.outputRedirect.CRORFrame(pDEntry->pvORInstance,
    1148                                            pixels,
    1149                                            4 * CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->width * CrVrScrCompositorEntryTexGet(&pDEntry->CEntry)->height);
    1150     }
    1151 }
    1152 
    1153 void crServerPresentOutputRedirectEntry(CRMuralInfo *pMural, CR_DISPLAY_ENTRY *pDEntry)
    1154 {
    1155     char *pixels=NULL;
    1156 
    1157     if (!pDEntry->pvORInstance)
    1158     {
    1159         crServerSetupOutputRedirectEntry(pMural, pDEntry);
    1160         if (!pDEntry->pvORInstance)
    1161         {
    1162             crWarning("crServerSetupOutputRedirectEntry failed!");
    1163             return;
    1164         }
    1165     }
    1166 
    1167     if (pMural->fPresentMode & CR_SERVER_REDIR_F_FBO_RPW)
    1168     {
    1169         crError("port me!");
    1170 #if 0
    1171         /* 1. blit to RPW entry draw texture */
    1172         CRMuralInfo *pCurrentMural = cr_server.currentMural;
    1173         CRContextInfo *pCurCtxInfo = cr_server.currentCtxInfo;
    1174         PCR_BLITTER pBlitter = crServerVBoxBlitterGet();
    1175         CRMuralInfo *pBlitterMural;
    1176         CR_SERVER_CTX_SWITCH CtxSwitch;
    1177         RTRECT Rect;
    1178         VBOXVR_TEXTURE DstTex;
    1179         CR_BLITTER_WINDOW BlitterBltInfo, CurrentBltInfo;
    1180         CR_BLITTER_CONTEXT CtxBltInfo;
    1181         int rc;
    1182 
    1183         Rect.xLeft = 0;
    1184         Rect.yTop = 0;
    1185         Rect.xRight = Tex.width;
    1186         Rect.yBottom = Tex.height;
    1187 
    1188         if (pCurrentMural && pCurrentMural->CreateInfo.visualBits == CrBltGetVisBits(pBlitter))
    1189         {
    1190             pBlitterMural = pCurrentMural;
    1191         }
    1192         else
    1193         {
    1194             pBlitterMural = crServerGetDummyMural(pCurrentMural->CreateInfo.visualBits);
    1195             if (!pBlitterMural)
    1196             {
    1197                 crWarning("crServerGetDummyMural failed for blitter mural");
    1198                 return;
    1199             }
    1200         }
    1201 
    1202         crServerRpwEntryDrawSettingsToTex(&mural->RpwEntry, &DstTex);
    1203 
    1204         crServerCtxSwitchPrepare(&CtxSwitch, NULL);
    1205 
    1206         crServerVBoxBlitterWinInit(&CurrentBltInfo, pCurrentMural);
    1207         crServerVBoxBlitterWinInit(&BlitterBltInfo, pBlitterMural);
    1208         crServerVBoxBlitterCtxInit(&CtxBltInfo, pCurCtxInfo);
    1209 
    1210         CrBltMuralSetCurrent(pBlitter, &BlitterBltInfo);
    1211 
    1212         rc =  CrBltEnter(pBlitter, &CtxBltInfo, &CurrentBltInfo);
    1213         if (RT_SUCCESS(rc))
    1214         {
    1215             CrBltBlitTexTex(pBlitter, &Tex, &Rect, &DstTex, &Rect, 1, 0);
    1216             CrBltLeave(pBlitter);
    1217         }
    1218         else
    1219         {
    1220             crWarning("CrBltEnter failed rc %d", rc);
    1221         }
    1222 
    1223         crServerCtxSwitchPostprocess(&CtxSwitch);
    1224 
    1225 #if 1
    1226         if (RT_SUCCESS(rc))
    1227         {
    1228             /* 2. submit RPW entry */
    1229             rc =  crServerRpwEntrySubmit(&cr_server.RpwWorker, &mural->RpwEntry);
    1230             if (!RT_SUCCESS(rc))
    1231             {
    1232                 crWarning("crServerRpwEntrySubmit failed rc %d", rc);
    1233             }
    1234         }
    1235 #endif
    1236 #endif
    1237         return;
    1238     }
    1239 
    1240     pixels = crServerDEntryImgAcquire(pMural, pDEntry, GL_BGRA);
    1241     if (!pixels)
    1242     {
    1243         crWarning("CrHlpGetTexImage failed in crServerPresentFBO");
    1244         return;
    1245     }
    1246 
    1247     crServerDentryPresentVRAM(pMural, pDEntry, pixels);
    1248 
    1249     crServerDEntryImgRelease(pMural, pDEntry, pixels);
    1250 }
    1251 
    1252 void crServerPresentOutputRedirect(CRMuralInfo *pMural)
    1253 {
    1254     VBOXVR_SCR_COMPOSITOR_ITERATOR Iter;
    1255     PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry;
    1256 
    1257     CrVrScrCompositorIterInit(&pMural->Compositor, &Iter);
    1258 
    1259     while ((pEntry = CrVrScrCompositorIterNext(&Iter)) != NULL)
    1260     {
    1261         CR_DISPLAY_ENTRY *pDEntry = CR_DENTRY_FROM_CENTRY(pEntry);
    1262         crServerPresentOutputRedirectEntry(pMural, pDEntry);
    1263     }
    1264 }
    1265 
    1266 void crServerOutputRedirectCheckEnableDisable(CRMuralInfo *pMural)
    1267 {
    1268     VBOXVR_SCR_COMPOSITOR_ITERATOR Iter;
    1269     PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry;
    1270 
    1271     CrVrScrCompositorIterInit(&pMural->Compositor, &Iter);
    1272 
    1273     while ((pEntry = CrVrScrCompositorIterNext(&Iter)) != NULL)
    1274     {
    1275         CR_DISPLAY_ENTRY *pDEntry = CR_DENTRY_FROM_CENTRY(pEntry);
    1276         crServerSetupOutputRedirectEntry(pMural, pDEntry);
    1277     }
    1278 }
    1279 
    1280 void crServerPresentFBO(CRMuralInfo *mural)
    1281 {
    1282     CRASSERT(mural->fPresentMode & CR_SERVER_REDIR_F_FBO);
    1283     CRASSERT(cr_server.pfnPresentFBO || (mural->fPresentMode & CR_SERVER_REDIR_F_DISPLAY));
    1284 
    1285     if (!crServerVBoxCompositionPresentNeeded(mural))
    1286         return;
    1287 
    1288     mural->fDataPresented = GL_TRUE;
    1289 
    1290     if (mural->fPresentMode & CR_SERVER_REDIR_F_DISPLAY)
    1291         crServerVBoxCompositionPresentPerform(mural);
    1292 
    1293     if (mural->fPresentMode & CR_SERVER_REDIR_FGROUP_REQUIRE_FBO_RAM)
    1294         crServerPresentOutputRedirect(mural);
     649            WARN(("CrFbUpdateBegin failed rc %d", rc));
     650    }
    1295651}
    1296652
     
    1307663    return cr_server.curClient
    1308664           && cr_server.curClient->currentMural
    1309            && (cr_server.curClient->currentMural->fPresentMode & CR_SERVER_REDIR_F_FBO);
     665           && cr_server.curClient->currentMural->fRedirected;
    1310666}
    1311667
     
    1332688            return -1;
    1333689        default:
    1334             crWarning("crServerMuralFBOIdxFromBufferName: invalid buffer passed 0x%x", buffer);
     690            WARN(("crServerMuralFBOIdxFromBufferName: invalid buffer passed 0x%x", buffer));
    1335691            return -2;
    1336692    }
     
    1358714    }
    1359715    Assert(mural->aidColorTexs[CR_SERVER_FBO_FB_IDX(mural)]);
    1360     Assert(mural->fUseDefaultDEntry);
    1361     CrVrScrCompositorEntryTexNameUpdate(&mural->DefaultDEntry.CEntry, mural->aidColorTexs[CR_SERVER_FBO_FB_IDX(mural)]);
    1362     if (mural->fRootVrOn)
    1363         CrVrScrCompositorEntryTexNameUpdate(&mural->DefaultDEntry.RootVrCEntry, mural->aidColorTexs[CR_SERVER_FBO_FB_IDX(mural)]);
    1364 }
     716}
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp

    r49448 r50095  
    2626#include "cr_string.h"
    2727#include <cr_vreg.h>
     28#include <cr_htable.h>
    2829
    2930#include <iprt/cdefs.h>
     
    3233#include <iprt/mem.h>
    3334#include <iprt/list.h>
    34 #include <iprt/memcache.h>
     35
     36
     37#ifdef DEBUG_misha
     38# define VBOXVDBG_MEMCACHE_DISABLE
     39#endif
     40
     41#ifndef VBOXVDBG_MEMCACHE_DISABLE
     42# include <iprt/memcache.h>
     43#endif
    3544
    3645#include "render/renderspu.h"
    3746
    38 /* DISPLAY */
    39 
    40 int CrDpInit(PCR_DISPLAY pDisplay)
    41 {
    42     const GLint visBits = cr_server.MainContextInfo.CreateInfo.visualBits;
    43     if (crServerMuralInit(&pDisplay->Mural, "", visBits, -1, GL_FALSE) < 0)
    44     {
    45         crWarning("crServerMuralInit failed!");
    46         return VERR_GENERAL_FAILURE;
    47     }
    48 
    49     crServerWindowVisibleRegion(&pDisplay->Mural);
    50     crServerDEntryAllVibleRegions(&pDisplay->Mural);
    51 
    52     crServerMuralShow(&pDisplay->Mural, GL_TRUE);
    53 
    54     pDisplay->fForcePresent = GL_FALSE;
     47class ICrFbDisplay
     48{
     49public:
     50    virtual int UpdateBegin(struct CR_FRAMEBUFFER *pFb) = 0;
     51    virtual void UpdateEnd(struct CR_FRAMEBUFFER *pFb) = 0;
     52
     53    virtual int EntryCreated(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) = 0;
     54    virtual int EntryAdded(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) = 0;
     55    virtual int EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry) = 0;
     56    virtual int EntryTexChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) = 0;
     57    virtual int EntryRemoved(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) = 0;
     58    virtual int EntryDestroyed(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) = 0;
     59    virtual int EntryPosChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry) = 0;
     60
     61    virtual int RegionsChanged(struct CR_FRAMEBUFFER *pFb) = 0;
     62
     63    virtual int FramebufferChanged(struct CR_FRAMEBUFFER *pFb) = 0;
     64
     65    virtual ~ICrFbDisplay() {}
     66};
     67
     68class CrFbDisplayComposite;
     69class CrFbDisplayBase;
     70class CrFbDisplayWindow;
     71class CrFbDisplayWindowRootVr;
     72class CrFbDisplayVrdp;
     73
     74typedef struct CR_FRAMEBUFFER
     75{
     76    VBOXVR_SCR_COMPOSITOR Compositor;
     77    struct VBVAINFOSCREEN ScreenInfo;
     78    void *pvVram;
     79    ICrFbDisplay *pDisplay;
     80    CRHTABLE SlotTable;
     81    uint32_t cUpdating;
     82} CR_FRAMEBUFFER;
     83
     84typedef struct CR_FBDISPLAY_INFO
     85{
     86    uint32_t u32Mode;
     87    CrFbDisplayWindow *pDpWin;
     88    CrFbDisplayWindowRootVr *pDpWinRootVr;
     89    CrFbDisplayVrdp *pDpVrdp;
     90    CrFbDisplayComposite *pDpComposite;
     91} CR_FBDISPLAY_INFO;
     92
     93typedef struct CR_PRESENTER_GLOBALS
     94{
     95#ifndef VBOXVDBG_MEMCACHE_DISABLE
     96    RTMEMCACHE FbEntryLookasideList;
     97    RTMEMCACHE FbTexLookasideList;
     98    RTMEMCACHE CEntryLookasideList;
     99#endif
     100    uint32_t u32DisplayMode;
     101    CRHashTable *pFbTexMap;
     102    CR_FBDISPLAY_INFO aDisplayInfos[CR_MAX_GUEST_MONITORS];
     103    uint8_t aFramebufferInitMap[(CR_MAX_GUEST_MONITORS+7)/8];
     104    CR_FRAMEBUFFER aFramebuffers[CR_MAX_GUEST_MONITORS];
     105} CR_PRESENTER_GLOBALS;
     106
     107static CR_PRESENTER_GLOBALS g_CrPresenter;
     108
     109/* FRAMEBUFFER */
     110
     111void CrFbInit(CR_FRAMEBUFFER *pFb, uint32_t idScreen)
     112{
     113    RTRECT Rect;
     114    Rect.xLeft = 0;
     115    Rect.yTop = 0;
     116    Rect.xRight = 1;
     117    Rect.yBottom = 1;
     118    memset(pFb, 0, sizeof (*pFb));
     119    pFb->ScreenInfo.u16Flags = VBVA_SCREEN_F_DISABLED;
     120    pFb->ScreenInfo.u32ViewIndex = idScreen;
     121    CrVrScrCompositorInit(&pFb->Compositor, &Rect);
     122    CrHTableCreate(&pFb->SlotTable, 0);
     123}
     124
     125bool CrFbIsEnabled(CR_FRAMEBUFFER *pFb)
     126{
     127    return !(pFb->ScreenInfo.u16Flags & VBVA_SCREEN_F_DISABLED);
     128}
     129
     130HCR_FRAMEBUFFER_ENTRY CrFbEntryFromCompositorEntry(const struct VBOXVR_SCR_COMPOSITOR_ENTRY* pCEntry);
     131
     132const struct VBOXVR_SCR_COMPOSITOR* CrFbGetCompositor(CR_FRAMEBUFFER *pFb)
     133{
     134    return &pFb->Compositor;
     135}
     136
     137DECLINLINE(CR_FRAMEBUFFER*) CrFbFromCompositor(const struct VBOXVR_SCR_COMPOSITOR* pCompositor)
     138{
     139    return RT_FROM_MEMBER(pCompositor, CR_FRAMEBUFFER, Compositor);
     140}
     141
     142const struct VBVAINFOSCREEN* CrFbGetScreenInfo(HCR_FRAMEBUFFER hFb)
     143{
     144    return &hFb->ScreenInfo;
     145}
     146
     147
     148int CrFbUpdateBegin(CR_FRAMEBUFFER *pFb)
     149{
     150    ++pFb->cUpdating;
     151
     152    if (pFb->cUpdating == 1)
     153    {
     154        if (pFb->pDisplay)
     155            pFb->pDisplay->UpdateBegin(pFb);
     156    }
     157
    55158    return VINF_SUCCESS;
    56159}
    57160
    58 void CrDpTerm(PCR_DISPLAY pDisplay)
    59 {
    60     crServerMuralTerm(&pDisplay->Mural);
    61 }
    62 
    63 void CrDpResize(PCR_DISPLAY pDisplay, int32_t xPos, int32_t yPos, uint32_t width, uint32_t height)
    64 {
    65     if (xPos != pDisplay->Mural.gX
    66             || yPos != pDisplay->Mural.gY
    67             || width != pDisplay->Mural.width
    68             || height != pDisplay->Mural.height)
    69     {
    70         crServerMuralPosition(&pDisplay->Mural, xPos, yPos, GL_TRUE);
    71         if (!crServerMuralSize(&pDisplay->Mural, width, height))
    72             crServerCheckMuralGeometry(&pDisplay->Mural);
     161void CrFbUpdateEnd(CR_FRAMEBUFFER *pFb)
     162{
     163    if (!pFb->cUpdating)
     164    {
     165        WARN(("invalid UpdateEnd call!"));
     166        return;
     167    }
     168
     169    --pFb->cUpdating;
     170
     171    if (!pFb->cUpdating)
     172    {
     173        if (pFb->pDisplay)
     174            pFb->pDisplay->UpdateEnd(pFb);
     175    }
     176}
     177
     178bool CrFbIsUpdating(const CR_FRAMEBUFFER *pFb)
     179{
     180    return !!pFb->cUpdating;
     181}
     182
     183int CrFbResize(CR_FRAMEBUFFER *pFb, const struct VBVAINFOSCREEN * pScreen, void *pvVRAM)
     184{
     185    if (!pFb->cUpdating)
     186    {
     187        WARN(("no update in progress"));
     188        return VERR_INVALID_STATE;
     189    }
     190    RTRECT Rect;
     191    Rect.xLeft = 0;
     192    Rect.yTop = 0;
     193    Rect.xRight = pScreen->u32Width;
     194    Rect.yBottom = pScreen->u32Height;
     195    int rc = CrVrScrCompositorRectSet(&pFb->Compositor, &Rect, NULL);
     196    if (!RT_SUCCESS(rc))
     197    {
     198        WARN(("CrVrScrCompositorRectSet failed rc %d", rc));
     199        return rc;
     200    }
     201
     202    pFb->ScreenInfo = *pScreen;
     203    pFb->pvVram = pvVRAM;
     204
     205    if (pFb->pDisplay)
     206        pFb->pDisplay->FramebufferChanged(pFb);
     207    return VINF_SUCCESS;
     208}
     209
     210void CrFbTerm(CR_FRAMEBUFFER *pFb)
     211{
     212    if (pFb->cUpdating)
     213    {
     214        WARN(("update in progress"));
     215        return;
     216    }
     217    CrVrScrCompositorClear(&pFb->Compositor);
     218    CrHTableDestroy(&pFb->SlotTable);
     219    memset(pFb, 0, sizeof (*pFb));
     220}
     221
     222ICrFbDisplay* CrFbDisplayGet(CR_FRAMEBUFFER *pFb)
     223{
     224    return pFb->pDisplay;
     225}
     226
     227int CrFbDisplaySet(CR_FRAMEBUFFER *pFb, ICrFbDisplay *pDisplay)
     228{
     229    if (pFb->cUpdating)
     230    {
     231        WARN(("update in progress"));
     232        return VERR_INVALID_STATE;
     233    }
     234
     235    if (pFb->pDisplay == pDisplay)
     236        return VINF_SUCCESS;
     237
     238    CrHTableEmpty(&pFb->SlotTable);
     239
     240    pFb->pDisplay = pDisplay;
     241
     242    return VINF_SUCCESS;
     243}
     244
     245typedef union CR_FBENTRY_FLAGS
     246{
     247    struct {
     248        uint32_t fCreateNotified : 1;
     249        uint32_t Reserved : 31;
     250    };
     251    uint32_t Value;
     252} CR_FBENTRY_FLAGS;
     253
     254typedef struct CR_FRAMEBUFFER_ENTRY
     255{
     256    VBOXVR_SCR_COMPOSITOR_ENTRY Entry;
     257    uint32_t cRefs;
     258    CR_FBENTRY_FLAGS Flags;
     259    CRHTABLE HTable;
     260} CR_FRAMEBUFFER_ENTRY;
     261
     262typedef struct CR_FBTEX
     263{
     264    CR_TEXDATA Tex;
     265    CRTextureObj *pTobj;
     266} CR_FBTEX;
     267
     268#define PCR_FBTEX_FROM_TEX(_pTex) ((CR_FBTEX*)((uint8_t*)(_pTex) - RT_OFFSETOF(CR_FBTEX, Tex)))
     269#define PCR_FRAMEBUFFER_FROM_COMPOSITOR(_pCompositor) ((CR_FRAMEBUFFER*)((uint8_t*)(_pCompositor) - RT_OFFSETOF(CR_FRAMEBUFFER, Compositor)))
     270#define PCR_FBENTRY_FROM_ENTRY(_pEntry) ((CR_FRAMEBUFFER_ENTRY*)((uint8_t*)(_pEntry) - RT_OFFSETOF(CR_FRAMEBUFFER_ENTRY, Entry)))
     271
     272#define CR_PMGR_MODE_WINDOW 0x1
     273/* CR_PMGR_MODE_WINDOW gets automatically set with it */
     274#define CR_PMGR_MODE_ROOTVR 0x2
     275#define CR_PMGR_MODE_VRDP   0x4
     276#define CR_PMGR_MODE_ALL    0x7
     277
     278static int crPMgrModeModifyGlobal(uint32_t u32Mode, bool fEnable);
     279
     280int CrPMgrInit()
     281{
     282    int rc = VINF_SUCCESS;
     283    memset(&g_CrPresenter, 0, sizeof (g_CrPresenter));
     284    g_CrPresenter.pFbTexMap = crAllocHashtable();
     285    if (g_CrPresenter.pFbTexMap)
     286    {
     287#ifndef VBOXVDBG_MEMCACHE_DISABLE
     288        rc = RTMemCacheCreate(&g_CrPresenter.FbEntryLookasideList, sizeof (CR_FRAMEBUFFER_ENTRY),
     289                                0, /* size_t cbAlignment */
     290                                UINT32_MAX, /* uint32_t cMaxObjects */
     291                                NULL, /* PFNMEMCACHECTOR pfnCtor*/
     292                                NULL, /* PFNMEMCACHEDTOR pfnDtor*/
     293                                NULL, /* void *pvUser*/
     294                                0 /* uint32_t fFlags*/
     295                                );
     296        if (RT_SUCCESS(rc))
     297        {
     298            rc = RTMemCacheCreate(&g_CrPresenter.FbTexLookasideList, sizeof (CR_FBTEX),
     299                                        0, /* size_t cbAlignment */
     300                                        UINT32_MAX, /* uint32_t cMaxObjects */
     301                                        NULL, /* PFNMEMCACHECTOR pfnCtor*/
     302                                        NULL, /* PFNMEMCACHEDTOR pfnDtor*/
     303                                        NULL, /* void *pvUser*/
     304                                        0 /* uint32_t fFlags*/
     305                                        );
     306            if (RT_SUCCESS(rc))
     307            {
     308                rc = RTMemCacheCreate(&g_CrPresenter.CEntryLookasideList, sizeof (VBOXVR_SCR_COMPOSITOR_ENTRY),
     309                                            0, /* size_t cbAlignment */
     310                                            UINT32_MAX, /* uint32_t cMaxObjects */
     311                                            NULL, /* PFNMEMCACHECTOR pfnCtor*/
     312                                            NULL, /* PFNMEMCACHEDTOR pfnDtor*/
     313                                            NULL, /* void *pvUser*/
     314                                            0 /* uint32_t fFlags*/
     315                                            );
     316                if (RT_SUCCESS(rc))
     317                {
     318#endif
     319                    rc = crPMgrModeModifyGlobal(CR_PMGR_MODE_WINDOW, true);
     320                    if (RT_SUCCESS(rc))
     321                        return VINF_SUCCESS;
     322                    else
     323                        WARN(("crPMgrModeModifyGlobal failed rc %d", rc));
     324#ifndef VBOXVDBG_MEMCACHE_DISABLE
     325                    RTMemCacheDestroy(g_CrPresenter.CEntryLookasideList);
     326                }
     327                else
     328                    WARN(("RTMemCacheCreate failed rc %d", rc));
     329
     330                RTMemCacheDestroy(g_CrPresenter.FbTexLookasideList);
     331            }
     332            else
     333                WARN(("RTMemCacheCreate failed rc %d", rc));
     334
     335            RTMemCacheDestroy(g_CrPresenter.FbEntryLookasideList);
     336        }
     337        else
     338            WARN(("RTMemCacheCreate failed rc %d", rc));
     339#endif
    73340    }
    74341    else
    75         crServerCheckMuralGeometry(&pDisplay->Mural);
    76 }
    77 
    78 void CrDpReparent(PCR_DISPLAY pDisplay, CRScreenInfo *pScreen)
    79 {
    80     renderspuSetWindowId(pScreen->winID);
    81     crServerWindowReparent(&pDisplay->Mural);
    82     renderspuSetWindowId(cr_server.screen[0].winID);
    83 
    84     CrDpResize(pDisplay, pScreen->x, pScreen->y, pScreen->w, pScreen->h);
    85 
    86     if (pScreen->winID)
    87     {
    88         /* need to do this on win, since otherwise the window ends up being with empty visible regions for some reason */
    89         crServerWindowVisibleRegion(&pDisplay->Mural);
    90     }
    91 }
    92 
    93 
    94 int CrDpSaveState(PCR_DISPLAY pDisplay, PSSMHANDLE pSSM)
    95 {
    96     VBOXVR_SCR_COMPOSITOR_ITERATOR Iter;
    97     CrVrScrCompositorIterInit(&pDisplay->Mural.Compositor, &Iter);
    98     PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry;
     342    {
     343        WARN(("crAllocHashtable failed"));
     344        rc = VERR_NO_MEMORY;
     345    }
     346    return rc;
     347}
     348
     349void CrPMgrTerm()
     350{
     351#ifndef VBOXVDBG_MEMCACHE_DISABLE
     352    RTMemCacheDestroy(g_CrPresenter.FbEntryLookasideList);
     353    RTMemCacheDestroy(g_CrPresenter.FbTexLookasideList);
     354    RTMemCacheDestroy(g_CrPresenter.CEntryLookasideList);
     355#endif
     356    crFreeHashtable(g_CrPresenter.pFbTexMap, NULL);
     357}
     358
     359static 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
     368static 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
     377static 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
     386static 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
     396DECLCALLBACK(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
     427void 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
     434static 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
     450CR_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
     462static 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
     519static 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
     529static 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
     537DECLINLINE(uint32_t) crFbEntryAddRef(CR_FRAMEBUFFER_ENTRY* pEntry)
     538{
     539    return ++pEntry->cRefs;
     540}
     541
     542DECLINLINE(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
     550static 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
     580static 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
     597int 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
     615int 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
     636int 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
     657void CrFbEntryAddRef(CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry)
     658{
     659    ++hEntry->cRefs;
     660}
     661
     662void CrFbEntryRelease(CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry)
     663{
     664    crFbEntryRelease(pFb, hEntry);
     665}
     666
     667int 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
     686int 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
     752int 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
     809const struct VBOXVR_SCR_COMPOSITOR_ENTRY* CrFbEntryGetCompositorEntry(HCR_FRAMEBUFFER_ENTRY hEntry)
     810{
     811    return &hEntry->Entry;
     812}
     813
     814HCR_FRAMEBUFFER_ENTRY CrFbEntryFromCompositorEntry(const struct VBOXVR_SCR_COMPOSITOR_ENTRY* pCEntry)
     815{
     816    return RT_FROM_MEMBER(pCEntry, CR_FRAMEBUFFER_ENTRY, Entry);
     817}
     818
     819CRHTABLE_HANDLE CrFbDDataAllocSlot(CR_FRAMEBUFFER *pFb)
     820{
     821    return CrHTablePut(&pFb->SlotTable, (void*)1);
     822}
     823
     824void CrFbDDataReleaseSlot(CR_FRAMEBUFFER *pFb, CRHTABLE_HANDLE hSlot)
     825{
     826    CrHTableRemove(&pFb->SlotTable, hSlot);
     827}
     828
     829int CrFbDDataEntryPut(HCR_FRAMEBUFFER_ENTRY hEntry, CRHTABLE_HANDLE hSlot, void *pvData)
     830{
     831    return CrHTablePutToSlot(&hEntry->HTable, hSlot, pvData);
     832}
     833
     834void* CrFbDDataEntryGet(HCR_FRAMEBUFFER_ENTRY hEntry, CRHTABLE_HANDLE hSlot)
     835{
     836    return CrHTableGet(&hEntry->HTable, hSlot);
     837}
     838
     839class CrFbDisplayBase : public ICrFbDisplay
     840{
     841public:
     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;
     1022protected:
     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
     1115private:
     1116    struct CR_FRAMEBUFFER *mpFb;
     1117    uint32_t mcUpdates;
     1118    CRHTABLE_HANDLE mhSlot;
     1119};
     1120
     1121class CrFbDisplayComposite : public CrFbDisplayBase
     1122{
     1123public:
     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    }
     1422private:
     1423    RTLISTNODE mDisplays;
     1424    uint32_t mcDisplays;
     1425};
     1426
     1427typedef 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
     1439class CrFbWindow
     1440{
     1441public:
     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    }
     1669protected:
     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    }
     1716private:
     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
     1728class CrFbDisplayWindow : public CrFbDisplayBase
     1729{
     1730public:
     1731    CrFbDisplayWindow(CrFbWindow *pWindow, const RTRECT *pViewportRect) :
     1732        mpWindow(pWindow),
     1733        mViewportRect(*pViewportRect)
     1734    {
     1735        CRASSERT(pWindow);
     1736    }
     1737
     1738    virtual ~CrFbDisplayWindow()
     1739    {
     1740        if (mpWindow)
     1741            delete mpWindow;
     1742    }
     1743
     1744    virtual int UpdateBegin(struct CR_FRAMEBUFFER *pFb)
     1745    {
     1746        int rc = CrFbDisplayBase::UpdateBegin(pFb);
     1747        if (!RT_SUCCESS(rc))
     1748        {
     1749            WARN(("err"));
     1750            return rc;
     1751        }
     1752
     1753        return mpWindow->UpdateBegin();
     1754    }
     1755
     1756    virtual void UpdateEnd(struct CR_FRAMEBUFFER *pFb)
     1757    {
     1758        mpWindow->UpdateEnd();
     1759
     1760        CrFbDisplayBase::UpdateEnd(pFb);
     1761    }
     1762
     1763    virtual int EntryCreated(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry)
     1764    {
     1765        int rc = CrFbDisplayBase::EntryCreated(pFb, hEntry);
     1766        if (!RT_SUCCESS(rc))
     1767        {
     1768            WARN(("err"));
     1769            return rc;
     1770        }
     1771
     1772        if (mpWindow->GetParentId())
     1773        {
     1774            rc = mpWindow->Create();
     1775            if (!RT_SUCCESS(rc))
     1776            {
     1777                WARN(("err"));
     1778                return rc;
     1779            }
     1780        }
     1781
     1782        return VINF_SUCCESS;
     1783    }
     1784
     1785    virtual int EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry)
     1786    {
     1787        int rc = CrFbDisplayBase::EntryReplaced(pFb, hNewEntry, hReplacedEntry);
     1788        if (!RT_SUCCESS(rc))
     1789        {
     1790            WARN(("err"));
     1791            return rc;
     1792        }
     1793
     1794        if (mpWindow->GetParentId())
     1795        {
     1796            rc = mpWindow->Create();
     1797            if (!RT_SUCCESS(rc))
     1798            {
     1799                WARN(("err"));
     1800                return rc;
     1801            }
     1802        }
     1803
     1804        return VINF_SUCCESS;
     1805    }
     1806
     1807    virtual int EntryRemoved(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry)
     1808    {
     1809        int rc = CrFbDisplayBase::EntryRemoved(pFb, hEntry);
     1810        if (!RT_SUCCESS(rc))
     1811        {
     1812            WARN(("err"));
     1813            return rc;
     1814        }
     1815
     1816        return mpWindow->SetVisibleRegionsChanged();
     1817    }
     1818
     1819    virtual int EntryPosChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry)
     1820    {
     1821        int rc = CrFbDisplayBase::EntryPosChanged(pFb, hEntry);
     1822        if (!RT_SUCCESS(rc))
     1823        {
     1824            WARN(("err"));
     1825            return rc;
     1826        }
     1827
     1828        return mpWindow->SetVisibleRegionsChanged();
     1829    }
     1830
     1831    virtual int RegionsChanged(struct CR_FRAMEBUFFER *pFb)
     1832    {
     1833        int rc = CrFbDisplayBase::RegionsChanged(pFb);
     1834        if (!RT_SUCCESS(rc))
     1835        {
     1836            WARN(("err"));
     1837            return rc;
     1838        }
     1839
     1840        return mpWindow->SetVisibleRegionsChanged();
     1841    }
     1842
     1843    virtual int FramebufferChanged(struct CR_FRAMEBUFFER *pFb)
     1844    {
     1845        int rc = CrFbDisplayBase::FramebufferChanged(pFb);
     1846        if (!RT_SUCCESS(rc))
     1847        {
     1848            WARN(("err"));
     1849            return rc;
     1850        }
     1851
     1852        return screenChanged();
     1853    }
     1854
     1855    virtual int setViewportRect(const RTRECT *pViewportRect)
     1856    {
     1857        if (!isUpdating())
     1858        {
     1859            WARN(("not updating!"));
     1860            return VERR_INVALID_STATE;
     1861        }
     1862
     1863        if (pViewportRect->xLeft != mViewportRect.xLeft || pViewportRect->yTop != mViewportRect.yTop)
     1864        {
     1865            const RTRECT* pRect = CrVrScrCompositorRectGet(getCompositor());
     1866            int rc = mpWindow->SetPosition(pRect->xLeft - mViewportRect.xLeft, pRect->yTop - mViewportRect.yTop);
     1867            if (!RT_SUCCESS(rc))
     1868            {
     1869                WARN(("SetPosition failed"));
     1870                return rc;
     1871            }
     1872        }
     1873
     1874        mViewportRect = *pViewportRect;
     1875
     1876        return VINF_SUCCESS;
     1877    }
     1878
     1879    virtual CrFbWindow * windowDetach()
     1880    {
     1881        if (isUpdating())
     1882        {
     1883            WARN(("updating!"));
     1884            return NULL;
     1885        }
     1886
     1887        CrFbWindow * pWindow = mpWindow;
     1888        if (mpWindow)
     1889        {
     1890            windowCleanup();
     1891            mpWindow = NULL;
     1892        }
     1893        return pWindow;
     1894    }
     1895
     1896    virtual CrFbWindow * windowAttach(CrFbWindow * pNewWindow)
     1897    {
     1898        if (isUpdating())
     1899        {
     1900            WARN(("updating!"));
     1901            return NULL;
     1902        }
     1903
     1904        CrFbWindow * pOld = mpWindow;
     1905        if (mpWindow)
     1906            windowDetach();
     1907
     1908        mpWindow = pNewWindow;
     1909        if (pNewWindow)
     1910            windowSync();
     1911
     1912        return mpWindow;
     1913    }
     1914
     1915    virtual int reparent(uint64_t parentId)
     1916    {
     1917        if (!isUpdating())
     1918        {
     1919            WARN(("not updating!"));
     1920            return VERR_INVALID_STATE;
     1921        }
     1922
     1923        int rc = mpWindow->Reparent(parentId);
     1924        if (!RT_SUCCESS(rc))
     1925            WARN(("window reparent failed"));
     1926
     1927        return rc;
     1928    }
     1929
     1930protected:
     1931    virtual int screenChanged()
     1932    {
     1933        if (!isUpdating())
     1934        {
     1935            WARN(("not updating!"));
     1936            return VERR_INVALID_STATE;
     1937        }
     1938
     1939        const RTRECT* pRect = CrVrScrCompositorRectGet(getCompositor());
     1940        int rc = mpWindow->SetPosition(pRect->xLeft - mViewportRect.xLeft, pRect->yTop - mViewportRect.yTop);
     1941        if (!RT_SUCCESS(rc))
     1942        {
     1943            WARN(("SetComposition failed rc %d", rc));
     1944            return rc;
     1945        }
     1946
     1947        mpWindow->SetVisibleRegionsChanged();
     1948
     1949        return mpWindow->SetSize((uint32_t)(pRect->xRight - pRect->xLeft), (uint32_t)(pRect->yBottom - pRect->yTop));
     1950    }
     1951
     1952    virtual int windowCleanup()
     1953    {
     1954        int rc = mpWindow->UpdateBegin();
     1955        if (!RT_SUCCESS(rc))
     1956        {
     1957            WARN(("err"));
     1958            return rc;
     1959        }
     1960
     1961        rc = mpWindow->SetVisible(false);
     1962        if (!RT_SUCCESS(rc))
     1963        {
     1964            WARN(("err"));
     1965            mpWindow->UpdateEnd();
     1966            return rc;
     1967        }
     1968
     1969        rc = mpWindow->SetCompositor(NULL);
     1970        if (!RT_SUCCESS(rc))
     1971        {
     1972            WARN(("err"));
     1973            mpWindow->UpdateEnd();
     1974            return rc;
     1975        }
     1976
     1977        mpWindow->UpdateEnd();
     1978
     1979        return VINF_SUCCESS;
     1980    }
     1981
     1982    virtual int fbCleanup()
     1983    {
     1984        int rc = windowCleanup();
     1985        if (!RT_SUCCESS(rc))
     1986        {
     1987            WARN(("windowCleanup failed"));
     1988            return rc;
     1989        }
     1990        return CrFbDisplayBase::fbCleanup();
     1991    }
     1992
     1993    virtual int windowSync()
     1994    {
     1995        const struct VBOXVR_SCR_COMPOSITOR* pCompositor = getCompositor();
     1996        const RTRECT* pRect = CrVrScrCompositorRectGet(pCompositor);
     1997
     1998        int rc = mpWindow->UpdateBegin();
     1999        if (!RT_SUCCESS(rc))
     2000        {
     2001            WARN(("err"));
     2002            return rc;
     2003        }
     2004
     2005        rc = mpWindow->SetCompositor(pCompositor);
     2006        if (!RT_SUCCESS(rc))
     2007        {
     2008            WARN(("err"));
     2009            mpWindow->UpdateEnd();
     2010            return rc;
     2011        }
     2012
     2013        rc = mpWindow->SetPosition(pRect->xLeft - mViewportRect.xLeft, pRect->yTop - mViewportRect.yTop);
     2014        if (!RT_SUCCESS(rc))
     2015        {
     2016            WARN(("err"));
     2017            mpWindow->UpdateEnd();
     2018            return rc;
     2019        }
     2020
     2021        rc = mpWindow->SetSize((uint32_t)(pRect->xRight - pRect->xLeft), (uint32_t)(pRect->yBottom - pRect->yTop));
     2022        if (!RT_SUCCESS(rc))
     2023        {
     2024            WARN(("err"));
     2025            mpWindow->UpdateEnd();
     2026            return rc;
     2027        }
     2028
     2029        rc = mpWindow->SetVisible(true);
     2030        if (!RT_SUCCESS(rc))
     2031        {
     2032            WARN(("err"));
     2033            mpWindow->UpdateEnd();
     2034            return rc;
     2035        }
     2036
     2037        mpWindow->UpdateEnd();
     2038
     2039        return rc;
     2040    }
     2041
     2042    virtual int fbSync()
     2043    {
     2044        int rc = CrFbDisplayBase::fbSync();
     2045        if (!RT_SUCCESS(rc))
     2046        {
     2047            WARN(("err"));
     2048            return rc;
     2049        }
     2050
     2051        return windowSync();
     2052    }
     2053
     2054    virtual const struct VBOXVR_SCR_COMPOSITOR* getCompositor()
     2055    {
     2056        return CrFbGetCompositor(getFramebuffer());
     2057    }
     2058
     2059    CrFbWindow* getWindow() {return mpWindow;}
     2060private:
     2061    CrFbWindow *mpWindow;
     2062    RTRECT mViewportRect;
     2063};
     2064
     2065class CrFbDisplayWindowRootVr : public CrFbDisplayWindow
     2066{
     2067public:
     2068    CrFbDisplayWindowRootVr(CrFbWindow *pWindow, const RTRECT *pViewportRect) :
     2069        CrFbDisplayWindow(pWindow, pViewportRect)
     2070    {
     2071        CrVrScrCompositorInit(&mCompositor, NULL);
     2072        memset(&mPos, 0, sizeof (mPos));
     2073    }
     2074
     2075    virtual int EntryCreated(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry)
     2076    {
     2077        int rc = CrFbDisplayWindow::EntryCreated(pFb, hEntry);
     2078        if (!RT_SUCCESS(rc))
     2079        {
     2080            WARN(("err"));
     2081            return rc;
     2082        }
     2083
     2084        Assert(!CrFbDDataEntryGet(hEntry, slotGet()));
     2085
     2086        const VBOXVR_SCR_COMPOSITOR_ENTRY* pSrcEntry = CrFbEntryGetCompositorEntry(hEntry);
     2087        VBOXVR_SCR_COMPOSITOR_ENTRY *pMyEntry = entryAlloc();
     2088        CrVrScrCompositorEntryInit(pMyEntry, CrVrScrCompositorEntryRectGet(pSrcEntry), CrVrScrCompositorEntryTexGet(pSrcEntry), NULL);
     2089        CrVrScrCompositorEntryFlagsSet(pMyEntry, CrVrScrCompositorEntryFlagsGet(pSrcEntry));
     2090        rc = CrFbDDataEntryPut(hEntry, slotGet(), pMyEntry);
     2091        if (!RT_SUCCESS(rc))
     2092        {
     2093            WARN(("CrFbDDataEntryPut failed rc %d", rc));
     2094            entryFree(pMyEntry);
     2095            return rc;
     2096        }
     2097
     2098        return VINF_SUCCESS;
     2099    }
     2100
     2101    virtual int EntryAdded(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry)
     2102    {
     2103        int rc = CrFbDisplayWindow::EntryAdded(pFb, hEntry);
     2104        if (!RT_SUCCESS(rc))
     2105        {
     2106            WARN(("err"));
     2107            return rc;
     2108        }
     2109
     2110        const VBOXVR_SCR_COMPOSITOR_ENTRY* pSrcEntry = CrFbEntryGetCompositorEntry(hEntry);
     2111        VBOXVR_SCR_COMPOSITOR_ENTRY *pMyEntry = (VBOXVR_SCR_COMPOSITOR_ENTRY*)CrFbDDataEntryGet(hEntry, slotGet());
     2112        Assert(pMyEntry);
     2113        CrVrScrCompositorEntryTexSet(pMyEntry, CrVrScrCompositorEntryTexGet(pSrcEntry));
     2114
     2115        return VINF_SUCCESS;
     2116    }
     2117
     2118    virtual int EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry)
     2119    {
     2120        int rc = CrFbDisplayWindow::EntryReplaced(pFb, hNewEntry, hReplacedEntry);
     2121        if (!RT_SUCCESS(rc))
     2122        {
     2123            WARN(("err"));
     2124            return rc;
     2125        }
     2126
     2127        const VBOXVR_SCR_COMPOSITOR_ENTRY* pSrcNewEntry = CrFbEntryGetCompositorEntry(hNewEntry);
     2128        VBOXVR_SCR_COMPOSITOR_ENTRY *pMyEntry = (VBOXVR_SCR_COMPOSITOR_ENTRY*)CrFbDDataEntryGet(hNewEntry, slotGet());
     2129        CrVrScrCompositorEntryTexSet(pMyEntry, CrVrScrCompositorEntryTexGet(pSrcNewEntry));
     2130
     2131        return VINF_SUCCESS;
     2132    }
     2133
     2134    virtual int EntryTexChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry)
     2135    {
     2136        int rc = CrFbDisplayWindow::EntryTexChanged(pFb, hEntry);
     2137        if (!RT_SUCCESS(rc))
     2138        {
     2139            WARN(("err"));
     2140            return rc;
     2141        }
     2142
     2143        const VBOXVR_SCR_COMPOSITOR_ENTRY* pSrcEntry = CrFbEntryGetCompositorEntry(hEntry);
     2144        VBOXVR_SCR_COMPOSITOR_ENTRY *pMyEntry = (VBOXVR_SCR_COMPOSITOR_ENTRY*)CrFbDDataEntryGet(hEntry, slotGet());
     2145        CrVrScrCompositorEntryTexSet(pMyEntry, CrVrScrCompositorEntryTexGet(pSrcEntry));
     2146
     2147        return VINF_SUCCESS;
     2148    }
     2149
     2150    virtual int EntryRemoved(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry)
     2151    {
     2152        int rc = CrFbDisplayWindow::EntryRemoved(pFb, hEntry);
     2153        if (!RT_SUCCESS(rc))
     2154        {
     2155            WARN(("err"));
     2156            return rc;
     2157        }
     2158
     2159        return VINF_SUCCESS;
     2160    }
     2161
     2162    virtual int EntryDestroyed(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry)
     2163    {
     2164        int rc = CrFbDisplayWindow::EntryDestroyed(pFb, hEntry);
     2165        if (!RT_SUCCESS(rc))
     2166        {
     2167            WARN(("err"));
     2168            return rc;
     2169        }
     2170
     2171        const VBOXVR_SCR_COMPOSITOR_ENTRY* pSrcEntry = CrFbEntryGetCompositorEntry(hEntry);
     2172        VBOXVR_SCR_COMPOSITOR_ENTRY *pMyEntry = (VBOXVR_SCR_COMPOSITOR_ENTRY*)CrFbDDataEntryGet(hEntry, slotGet());
     2173        CrVrScrCompositorEntryCleanup(pMyEntry);
     2174        entryFree(pMyEntry);
     2175
     2176        return VINF_SUCCESS;
     2177    }
     2178
     2179    virtual int RegionsChanged(struct CR_FRAMEBUFFER *pFb)
     2180    {
     2181        int rc = CrFbDisplayWindow::RegionsChanged(pFb);
     2182        if (!RT_SUCCESS(rc))
     2183        {
     2184            WARN(("err"));
     2185            return rc;
     2186        }
     2187
     2188        rc = synchCompositorRegions();
     2189        if (!RT_SUCCESS(rc))
     2190        {
     2191            WARN(("err"));
     2192            return rc;
     2193        }
     2194
     2195        return VINF_SUCCESS;
     2196    }
     2197
     2198    virtual int setViewportRect(const RTRECT *pViewportRect)
     2199    {
     2200        int rc = CrFbDisplayWindow::setViewportRect(pViewportRect);
     2201        if (!RT_SUCCESS(rc))
     2202        {
     2203            WARN(("err"));
     2204            return rc;
     2205        }
     2206
     2207        rc = synchCompositorData();
     2208        if (!RT_SUCCESS(rc))
     2209        {
     2210            WARN(("err"));
     2211            return rc;
     2212        }
     2213
     2214        return VINF_SUCCESS;
     2215    }
     2216
     2217protected:
     2218    virtual int screenChanged()
     2219    {
     2220        int rc = CrFbDisplayWindow::screenChanged();
     2221        if (!RT_SUCCESS(rc))
     2222        {
     2223            WARN(("screenChanged failed %d", rc));
     2224            return rc;
     2225        }
     2226
     2227        rc = synchCompositorData();
     2228        if (!RT_SUCCESS(rc))
     2229        {
     2230            WARN(("err"));
     2231            return rc;
     2232        }
     2233
     2234        return VINF_SUCCESS;
     2235    }
     2236
     2237    virtual int fbCleanup()
     2238    {
     2239        int rc = clearCompositor();
     2240        if (!RT_SUCCESS(rc))
     2241        {
     2242            WARN(("err"));
     2243            return rc;
     2244        }
     2245
     2246        return CrFbDisplayWindow::fbCleanup();
     2247    }
     2248
     2249    virtual int fbSync()
     2250    {
     2251        int rc = synchCompositor();
     2252        if (!RT_SUCCESS(rc))
     2253        {
     2254            WARN(("err"));
     2255            return rc;
     2256        }
     2257
     2258        return CrFbDisplayWindow::fbSync();
     2259    }
     2260
     2261    VBOXVR_SCR_COMPOSITOR_ENTRY* entryAlloc()
     2262    {
     2263#ifndef VBOXVDBG_MEMCACHE_DISABLE
     2264        return (VBOXVR_SCR_COMPOSITOR_ENTRY*)RTMemCacheAlloc(g_CrPresenter.CEntryLookasideList);
     2265#else
     2266        return (VBOXVR_SCR_COMPOSITOR_ENTRY*)RTMemAlloc(sizeof (VBOXVR_SCR_COMPOSITOR_ENTRY));
     2267#endif
     2268    }
     2269
     2270    void entryFree(VBOXVR_SCR_COMPOSITOR_ENTRY* pEntry)
     2271    {
     2272        Assert(!CrVrScrCompositorEntryIsUsed(pEntry));
     2273#ifndef VBOXVDBG_MEMCACHE_DISABLE
     2274        RTMemCacheFree(g_CrPresenter.CEntryLookasideList, pEntry);
     2275#else
     2276        RTMemFree(pEntry);
     2277#endif
     2278    }
     2279
     2280    int synchCompositorRegions()
     2281    {
     2282        int rc;
     2283
     2284        rootVrTranslateForPos();
     2285
     2286        /* ensure the rootvr compositor does not hold any data,
     2287         * i.e. cleanup all rootvr entries data */
     2288        CrVrScrCompositorClear(&mCompositor);
     2289
     2290        rc = CrVrScrCompositorIntersectedList(CrFbGetCompositor(getFramebuffer()), &cr_server.RootVr, &mCompositor, rootVrGetCEntry, this, NULL);
     2291        if (!RT_SUCCESS(rc))
     2292        {
     2293            WARN(("CrVrScrCompositorIntersectedList failed, rc %d", rc));
     2294            return rc;
     2295        }
     2296
     2297        return getWindow()->SetVisibleRegionsChanged();
     2298    }
     2299
     2300    int synchCompositorData()
     2301    {
     2302        CrVrScrCompositorClear(&mCompositor);
     2303
     2304        const struct VBVAINFOSCREEN* pScreenInfo = CrFbGetScreenInfo(getFramebuffer());
     2305        mPos.x = pScreenInfo->i32OriginX;
     2306        mPos.y = pScreenInfo->i32OriginY;
     2307
     2308        int rc = CrVrScrCompositorRectSet(&mCompositor, CrVrScrCompositorRectGet(CrFbGetCompositor(getFramebuffer())), NULL);
     2309        if (!RT_SUCCESS(rc))
     2310        {
     2311            WARN(("CrVrScrCompositorRectSet failed, rc %d", rc));
     2312            return rc;
     2313        }
     2314        rc = synchCompositorRegions();
     2315        if (!RT_SUCCESS(rc))
     2316        {
     2317            WARN(("synchCompositorRegions failed, rc %d", rc));
     2318            return rc;
     2319        }
     2320
     2321        return rc;
     2322    }
     2323
     2324    virtual int synchCompositor()
     2325    {
     2326        int rc = CrVrScrCompositorRectSet(&mCompositor, CrVrScrCompositorRectGet(CrFbGetCompositor(getFramebuffer())), NULL);
     2327        if (!RT_SUCCESS(rc))
     2328        {
     2329            WARN(("CrVrScrCompositorRectSet failed, rc %d", rc));
     2330            return rc;
     2331        }
     2332
     2333        rc = fbSynchAddAllEntries();
     2334        if (!RT_SUCCESS(rc))
     2335        {
     2336            WARN(("fbSynchAddAllEntries failed, rc %d", rc));
     2337            return rc;
     2338        }
     2339
     2340        rc = synchCompositorRegions();
     2341        if (!RT_SUCCESS(rc))
     2342        {
     2343            WARN(("synchCompositorRegions failed, rc %d", rc));
     2344            return rc;
     2345        }
     2346
     2347        return rc;
     2348    }
     2349
     2350    virtual int clearCompositor()
     2351    {
     2352        return fbCleanupRemoveAllEntries(true);
     2353    }
     2354
     2355    void rootVrTranslateForPos()
     2356    {
     2357        int32_t dx = cr_server.RootVrCurPoint.x - mPos.x;
     2358        int32_t dy = cr_server.RootVrCurPoint.y - mPos.y;
     2359
     2360        cr_server.RootVrCurPoint.x = mPos.x;
     2361        cr_server.RootVrCurPoint.y = mPos.y;
     2362
     2363        VBoxVrListTranslate(&cr_server.RootVr, dx, dy);
     2364    }
     2365
     2366    static DECLCALLBACK(VBOXVR_SCR_COMPOSITOR_ENTRY*) rootVrGetCEntry(const VBOXVR_SCR_COMPOSITOR_ENTRY*pEntry, void *pvContext)
     2367    {
     2368        CrFbDisplayWindowRootVr *pThis = (CrFbDisplayWindowRootVr*)pvContext;
     2369        HCR_FRAMEBUFFER_ENTRY hEntry = CrFbEntryFromCompositorEntry(pEntry);
     2370        VBOXVR_SCR_COMPOSITOR_ENTRY *pMyEntry = (VBOXVR_SCR_COMPOSITOR_ENTRY*)CrFbDDataEntryGet(hEntry, pThis->slotGet());
     2371        Assert(!CrVrScrCompositorEntryIsUsed(pMyEntry));
     2372        CrVrScrCompositorEntryRectSet(&pThis->mCompositor, pMyEntry, CrVrScrCompositorEntryRectGet(pEntry));
     2373        return pMyEntry;
     2374    }
     2375private:
     2376    VBOXVR_SCR_COMPOSITOR mCompositor;
     2377    RTPOINT mPos;
     2378};
     2379
     2380class CrFbDisplayVrdp : public CrFbDisplayBase
     2381{
     2382public:
     2383    CrFbDisplayVrdp()
     2384    {
     2385        memset(&mPos, 0, sizeof (mPos));
     2386    }
     2387
     2388    virtual int EntryCreated(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry)
     2389    {
     2390        int rc = CrFbDisplayBase::EntryCreated(pFb, hEntry);
     2391        if (!RT_SUCCESS(rc))
     2392        {
     2393            WARN(("EntryAdded failed rc %d", rc));
     2394            return rc;
     2395        }
     2396
     2397        Assert(!CrFbDDataEntryGet(hEntry, slotGet()));
     2398        rc = vrdpCreate(pFb, hEntry);
     2399        if (!RT_SUCCESS(rc))
     2400        {
     2401            WARN(("vrdpCreate failed rc %d", rc));
     2402            return rc;
     2403        }
     2404
     2405        return VINF_SUCCESS;
     2406    }
     2407
     2408    virtual int EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry)
     2409    {
     2410        int rc = CrFbDisplayBase::EntryReplaced(pFb, hNewEntry, hReplacedEntry);
     2411        if (!RT_SUCCESS(rc))
     2412        {
     2413            WARN(("err"));
     2414            return rc;
     2415        }
     2416
     2417        return vrdpFrame(hNewEntry);
     2418    }
     2419
     2420    virtual int EntryTexChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry)
     2421    {
     2422        int rc = CrFbDisplayBase::EntryTexChanged(pFb, hEntry);
     2423        if (!RT_SUCCESS(rc))
     2424        {
     2425            WARN(("err"));
     2426            return rc;
     2427        }
     2428
     2429        return vrdpFrame(hEntry);
     2430    }
     2431
     2432    virtual int EntryRemoved(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry)
     2433    {
     2434        int rc = CrFbDisplayBase::EntryRemoved(pFb, hEntry);
     2435        if (!RT_SUCCESS(rc))
     2436        {
     2437            WARN(("err"));
     2438            return rc;
     2439        }
     2440
     2441        return vrdpRegions(pFb, hEntry);
     2442    }
     2443
     2444    virtual int EntryDestroyed(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry)
     2445    {
     2446        int rc = CrFbDisplayBase::EntryDestroyed(pFb, hEntry);
     2447        if (!RT_SUCCESS(rc))
     2448        {
     2449            WARN(("err"));
     2450            return rc;
     2451        }
     2452
     2453        vrdpDestroy(hEntry);
     2454        return VINF_SUCCESS;
     2455    }
     2456
     2457    virtual int EntryPosChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry)
     2458    {
     2459        int rc = CrFbDisplayBase::EntryPosChanged(pFb, hEntry);
     2460        if (!RT_SUCCESS(rc))
     2461        {
     2462            WARN(("err"));
     2463            return rc;
     2464        }
     2465
     2466        vrdpGeometry(hEntry);
     2467
     2468        return VINF_SUCCESS;
     2469    }
     2470
     2471    virtual int RegionsChanged(struct CR_FRAMEBUFFER *pFb)
     2472    {
     2473        int rc = CrFbDisplayBase::RegionsChanged(pFb);
     2474        if (!RT_SUCCESS(rc))
     2475        {
     2476            WARN(("err"));
     2477            return rc;
     2478        }
     2479
     2480        return vrdpRegionsAll(pFb);
     2481    }
     2482
     2483    virtual int FramebufferChanged(struct CR_FRAMEBUFFER *pFb)
     2484    {
     2485        int rc = CrFbDisplayBase::FramebufferChanged(pFb);
     2486        if (!RT_SUCCESS(rc))
     2487        {
     2488            WARN(("err"));
     2489            return rc;
     2490        }
     2491
     2492        syncPos();
     2493
     2494        rc = vrdpSyncEntryAll(pFb);
     2495        if (!RT_SUCCESS(rc))
     2496        {
     2497            WARN(("err"));
     2498            return rc;
     2499        }
     2500
     2501        return vrdpRegionsAll(pFb);
     2502    }
     2503
     2504protected:
     2505    void syncPos()
     2506    {
     2507        const struct VBVAINFOSCREEN* pScreenInfo = CrFbGetScreenInfo(getFramebuffer());
     2508        mPos.x = pScreenInfo->i32OriginX;
     2509        mPos.y = pScreenInfo->i32OriginY;
     2510    }
     2511
     2512    virtual int fbCleanup()
     2513    {
     2514        int rc = fbCleanupRemoveAllEntries(true);
     2515        if (!RT_SUCCESS(rc))
     2516        {
     2517            WARN(("err"));
     2518            return rc;
     2519        }
     2520
     2521        return CrFbDisplayBase::fbCleanup();
     2522    }
     2523
     2524    virtual int fbSync()
     2525    {
     2526        syncPos();
     2527
     2528        int rc = fbSynchAddAllEntries();
     2529        if (!RT_SUCCESS(rc))
     2530        {
     2531            WARN(("err"));
     2532            return rc;
     2533        }
     2534
     2535        return CrFbDisplayBase::fbSync();
     2536    }
     2537protected:
     2538    void vrdpDestroy(HCR_FRAMEBUFFER_ENTRY hEntry)
     2539    {
     2540        void *pVrdp = CrFbDDataEntryGet(hEntry, slotGet());
     2541        cr_server.outputRedirect.CROREnd(pVrdp);
     2542    }
     2543
     2544    void vrdpGeometry(HCR_FRAMEBUFFER_ENTRY hEntry)
     2545    {
     2546        void *pVrdp = CrFbDDataEntryGet(hEntry, slotGet());
     2547        const VBOXVR_SCR_COMPOSITOR_ENTRY* pEntry = CrFbEntryGetCompositorEntry(hEntry);
     2548
     2549        cr_server.outputRedirect.CRORGeometry(pVrdp,
     2550                                                                                        mPos.x + CrVrScrCompositorEntryRectGet(pEntry)->xLeft,
     2551                                                                                        mPos.y + CrVrScrCompositorEntryRectGet(pEntry)->yTop,
     2552                                                                                   CrVrScrCompositorEntryTexGet(pEntry)->Tex.width,
     2553                                               CrVrScrCompositorEntryTexGet(pEntry)->Tex.height);
     2554    }
     2555
     2556    int vrdpRegions(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry)
     2557    {
     2558        void *pVrdp = CrFbDDataEntryGet(hEntry, slotGet());
     2559        const struct VBOXVR_SCR_COMPOSITOR* pCompositor = CrFbGetCompositor(pFb);
     2560        const VBOXVR_SCR_COMPOSITOR_ENTRY* pEntry = CrFbEntryGetCompositorEntry(hEntry);
     2561        uint32_t cRects;
     2562        const RTRECT *pRects;
     2563
     2564        int rc = CrVrScrCompositorEntryRegionsGet(pCompositor, pEntry, &cRects, NULL, &pRects, NULL);
     2565        if (!RT_SUCCESS(rc))
     2566        {
     2567            WARN(("CrVrScrCompositorEntryRegionsGet failed, rc %d", rc));
     2568            return rc;
     2569        }
     2570
     2571        cr_server.outputRedirect.CRORVisibleRegion(pVrdp, cRects, pRects);
     2572        return VINF_SUCCESS;
     2573    }
     2574
     2575    int vrdpFrame(HCR_FRAMEBUFFER_ENTRY hEntry)
     2576    {
     2577        void *pVrdp = CrFbDDataEntryGet(hEntry, slotGet());
     2578        const VBOXVR_SCR_COMPOSITOR_ENTRY* pEntry = CrFbEntryGetCompositorEntry(hEntry);
     2579        CR_TEXDATA *pTex = CrVrScrCompositorEntryTexGet(pEntry);
     2580        const CR_BLITTER_IMG *pImg;
     2581        int rc = CrTdBltDataAcquire(pTex, GL_BGRA, !!(CrVrScrCompositorEntryFlagsGet(pEntry) & CRBLT_F_INVERT_SRC_YCOORDS), &pImg);
     2582        if (!RT_SUCCESS(rc))
     2583        {
     2584                WARN(("CrTdBltDataAcquire failed rc %d", rc));
     2585                return rc;
     2586        }
     2587
     2588        cr_server.outputRedirect.CRORFrame(pVrdp, pImg->pvData, pImg->cbData);
     2589        CrTdBltDataRelease(pTex);
     2590        return VINF_SUCCESS;
     2591    }
     2592
     2593    int vrdpRegionsAll(struct CR_FRAMEBUFFER *pFb)
     2594    {
     2595        const struct VBOXVR_SCR_COMPOSITOR* pCompositor = CrFbGetCompositor(pFb);
     2596        VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR Iter;
     2597        CrVrScrCompositorConstIterInit(pCompositor, &Iter);
     2598        const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry;
     2599        while ((pEntry = CrVrScrCompositorConstIterNext(&Iter)) != NULL)
     2600        {
     2601                HCR_FRAMEBUFFER_ENTRY hEntry = CrFbEntryFromCompositorEntry(pEntry);
     2602                vrdpRegions(pFb, hEntry);
     2603        }
     2604
     2605        return VINF_SUCCESS;
     2606    }
     2607
     2608    int vrdpSynchEntry(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry)
     2609    {
     2610        vrdpGeometry(hEntry);
     2611
     2612        return vrdpRegions(pFb, hEntry);;
     2613    }
     2614
     2615    int vrdpSyncEntryAll(struct CR_FRAMEBUFFER *pFb)
     2616    {
     2617        const struct VBOXVR_SCR_COMPOSITOR* pCompositor = CrFbGetCompositor(pFb);
     2618        VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR Iter;
     2619        CrVrScrCompositorConstIterInit(pCompositor, &Iter);
     2620        const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry;
     2621        while ((pEntry = CrVrScrCompositorConstIterNext(&Iter)) != NULL)
     2622        {
     2623            HCR_FRAMEBUFFER_ENTRY hEntry = CrFbEntryFromCompositorEntry(pEntry);
     2624            int rc = vrdpSynchEntry(pFb, hEntry);
     2625            if (!RT_SUCCESS(rc))
     2626            {
     2627                WARN(("vrdpSynchEntry failed rc %d", rc));
     2628                return rc;
     2629            }
     2630        }
     2631
     2632        return VINF_SUCCESS;
     2633    }
     2634
     2635    int vrdpCreate(HCR_FRAMEBUFFER hFb, HCR_FRAMEBUFFER_ENTRY hEntry)
     2636    {
     2637        void *pVrdp;
     2638
     2639        /* Query supported formats. */
     2640        uint32_t cbFormats = 4096;
     2641        char *pachFormats = (char *)crAlloc(cbFormats);
     2642
     2643        if (!pachFormats)
     2644        {
     2645            WARN(("crAlloc failed"));
     2646            return VERR_NO_MEMORY;
     2647        }
     2648
     2649        int rc = cr_server.outputRedirect.CRORContextProperty(cr_server.outputRedirect.pvContext,
     2650                                                                  0 /* H3DOR_PROP_FORMATS */, // @todo from a header
     2651                                                                  pachFormats, cbFormats, &cbFormats);
     2652        if (RT_SUCCESS(rc))
     2653        {
     2654            if (RTStrStr(pachFormats, "H3DOR_FMT_RGBA_TOPDOWN"))
     2655            {
     2656                cr_server.outputRedirect.CRORBegin(cr_server.outputRedirect.pvContext,
     2657                                        &pVrdp,
     2658                                "H3DOR_FMT_RGBA_TOPDOWN"); // @todo from a header
     2659
     2660                if (pVrdp)
     2661                {
     2662                    rc = CrFbDDataEntryPut(hEntry, slotGet(), pVrdp);
     2663                    if (RT_SUCCESS(rc))
     2664                    {
     2665                        vrdpGeometry(hEntry);
     2666                        vrdpRegions(hFb, hEntry);
     2667                        vrdpFrame(hEntry);
     2668                        return VINF_SUCCESS;
     2669                    }
     2670                    else
     2671                        WARN(("CrFbDDataEntryPut failed rc %d", rc));
     2672
     2673                    cr_server.outputRedirect.CROREnd(pVrdp);
     2674                }
     2675                else
     2676                {
     2677                    WARN(("CRORBegin failed"));
     2678                    rc = VERR_GENERAL_FAILURE;
     2679                }
     2680            }
     2681        }
     2682        else
     2683            WARN(("CRORContextProperty failed rc %d", rc));
     2684
     2685        crFree(pachFormats);
     2686
     2687        return rc;
     2688    }
     2689private:
     2690    RTPOINT mPos;
     2691};
     2692
     2693CrFbDisplayBase::~CrFbDisplayBase()
     2694{
     2695    Assert(!mcUpdates);
     2696
     2697    if (mpContainer)
     2698        mpContainer->remove(this);
     2699}
     2700
     2701
     2702#if 0
     2703
     2704
     2705
     2706
     2707
     2708void crDbgDumpRect(uint32_t i, const RTRECT *pRect)
     2709{
     2710    crDebug("%d: (%d;%d) X (%d;%d)", i, pRect->xLeft, pRect->yTop, pRect->xRight, pRect->yBottom);
     2711}
     2712
     2713void crDbgDumpRects(uint32_t cRects, const RTRECT *paRects)
     2714{
     2715    crDebug("Dumping rects (%d)", cRects);
     2716    for (uint32_t i = 0; i < cRects; ++i)
     2717    {
     2718        crDbgDumpRect(i, &paRects[i]);
     2719    }
     2720    crDebug("End Dumping rects (%d)", cRects);
     2721}
     2722
     2723int crServerDisplaySaveState(PSSMHANDLE pSSM)
     2724{
     2725    int rc;
     2726    int cDisplays = 0, i;
     2727    for (i = 0; i < cr_server.screenCount; ++i)
     2728    {
     2729        if (ASMBitTest(cr_server.DisplaysInitMap, i) && !CrDpIsEmpty(&cr_server.aDispplays[i]))
     2730            ++cDisplays;
     2731    }
     2732
     2733    rc = SSMR3PutS32(pSSM, cDisplays);
     2734    AssertRCReturn(rc, rc);
     2735
     2736    if (!cDisplays)
     2737        return VINF_SUCCESS;
     2738
     2739    rc = SSMR3PutS32(pSSM, cr_server.screenCount);
     2740    AssertRCReturn(rc, rc);
     2741
     2742    for (i = 0; i < cr_server.screenCount; ++i)
     2743    {
     2744        rc = SSMR3PutS32(pSSM, cr_server.screen[i].x);
     2745        AssertRCReturn(rc, rc);
     2746
     2747        rc = SSMR3PutS32(pSSM, cr_server.screen[i].y);
     2748        AssertRCReturn(rc, rc);
     2749
     2750        rc = SSMR3PutU32(pSSM, cr_server.screen[i].w);
     2751        AssertRCReturn(rc, rc);
     2752
     2753        rc = SSMR3PutU32(pSSM, cr_server.screen[i].h);
     2754        AssertRCReturn(rc, rc);
     2755    }
     2756
     2757    for (i = 0; i < cr_server.screenCount; ++i)
     2758    {
     2759        if (ASMBitTest(cr_server.DisplaysInitMap, i) && !CrDpIsEmpty(&cr_server.aDispplays[i]))
     2760        {
     2761            rc = SSMR3PutS32(pSSM, i);
     2762            AssertRCReturn(rc, rc);
     2763
     2764            rc = CrDpSaveState(&cr_server.aDispplays[i], pSSM);
     2765            AssertRCReturn(rc, rc);
     2766        }
     2767    }
     2768
     2769    return VINF_SUCCESS;
     2770}
     2771
     2772int crServerDisplayLoadState(PSSMHANDLE pSSM, uint32_t u32Version)
     2773{
     2774
     2775}
     2776#endif
     2777
     2778HCR_FRAMEBUFFER CrPMgrFbGet(uint32_t idScreen)
     2779{
     2780    if (idScreen >= CR_MAX_GUEST_MONITORS)
     2781    {
     2782        WARN(("invalid idScreen %d", idScreen));
     2783        return NULL;
     2784    }
     2785
     2786    if (!ASMBitTest(g_CrPresenter.aFramebufferInitMap, idScreen))
     2787    {
     2788        CrFbInit(&g_CrPresenter.aFramebuffers[idScreen], idScreen);
     2789        ASMBitSet(g_CrPresenter.aFramebufferInitMap, idScreen);
     2790    }
     2791    else
     2792        Assert(g_CrPresenter.aFramebuffers[idScreen].ScreenInfo.u32ViewIndex == idScreen);
     2793
     2794    return &g_CrPresenter.aFramebuffers[idScreen];
     2795}
     2796
     2797HCR_FRAMEBUFFER CrPMgrFbGetEnabled(uint32_t idScreen)
     2798{
     2799    if (idScreen >= CR_MAX_GUEST_MONITORS)
     2800    {
     2801        WARN(("invalid idScreen %d", idScreen));
     2802        return NULL;
     2803    }
     2804
     2805    if (!ASMBitTest(g_CrPresenter.aFramebufferInitMap, idScreen))
     2806    {
     2807        return NULL;
     2808    }
     2809    else
     2810        Assert(g_CrPresenter.aFramebuffers[idScreen].ScreenInfo.u32ViewIndex == idScreen);
     2811
     2812    HCR_FRAMEBUFFER hFb = &g_CrPresenter.aFramebuffers[idScreen];
     2813
     2814    if(CrFbIsEnabled(hFb))
     2815        return hFb;
     2816
     2817    return NULL;
     2818}
     2819
     2820static HCR_FRAMEBUFFER crPMgrFbGetNextEnabled(uint32_t i)
     2821{
     2822    for (;i < cr_server.screenCount; ++i)
     2823    {
     2824        HCR_FRAMEBUFFER hFb = CrPMgrFbGetEnabled(i);
     2825        if (hFb)
     2826            return hFb;
     2827    }
     2828
     2829    return NULL;
     2830}
     2831
     2832HCR_FRAMEBUFFER CrPMgrFbGetFirstEnabled()
     2833{
     2834    HCR_FRAMEBUFFER hFb = crPMgrFbGetNextEnabled(0);
     2835    if (!hFb)
     2836        WARN(("no enabled framebuffer found"));
     2837    return hFb;
     2838}
     2839
     2840HCR_FRAMEBUFFER CrPMgrFbGetNextEnabled(HCR_FRAMEBUFFER hFb)
     2841{
     2842    return crPMgrFbGetNextEnabled(hFb->ScreenInfo.u32ViewIndex+1);
     2843}
     2844
     2845static uint32_t crPMgrModeAdjustVal(uint32_t u32Mode)
     2846{
     2847    u32Mode = CR_PMGR_MODE_ALL & u32Mode;
     2848    if (CR_PMGR_MODE_ROOTVR & u32Mode)
     2849        u32Mode |= CR_PMGR_MODE_WINDOW;
     2850    return u32Mode;
     2851}
     2852
     2853int CrPMgrScreenChanged(uint32_t idScreen)
     2854{
     2855    if (idScreen >= CR_MAX_GUEST_MONITORS)
     2856    {
     2857        WARN(("invalid idScreen %d", idScreen));
     2858        return NULL;
     2859    }
     2860
     2861    CR_FBDISPLAY_INFO *pInfo = &g_CrPresenter.aDisplayInfos[idScreen];
     2862    if (pInfo->pDpWin)
     2863    {
     2864        HCR_FRAMEBUFFER hFb = CrPMgrFbGet(idScreen);
     2865        if (CrFbIsUpdating(hFb))
     2866        {
     2867            WARN(("trying to update viewport while framebuffer is being updated"));
     2868            return VERR_INVALID_STATE;
     2869        }
     2870
     2871        int rc = pInfo->pDpWin->UpdateBegin(hFb);
     2872        if (RT_SUCCESS(rc))
     2873        {
     2874            pInfo->pDpWin->reparent(cr_server.screen[idScreen].winID);
     2875
     2876            pInfo->pDpWin->UpdateEnd(hFb);
     2877        }
     2878        else
     2879            WARN(("UpdateBegin failed %d", rc));
     2880    }
     2881
     2882    return VINF_SUCCESS;
     2883}
     2884
     2885int CrPMgrViewportUpdate(uint32_t idScreen)
     2886{
     2887    if (idScreen >= CR_MAX_GUEST_MONITORS)
     2888    {
     2889        WARN(("invalid idScreen %d", idScreen));
     2890        return VERR_INVALID_PARAMETER;
     2891    }
     2892
     2893    CR_FBDISPLAY_INFO *pInfo = &g_CrPresenter.aDisplayInfos[idScreen];
     2894    if (pInfo->pDpWin)
     2895    {
     2896        HCR_FRAMEBUFFER hFb = CrPMgrFbGet(idScreen);
     2897        if (CrFbIsUpdating(hFb))
     2898        {
     2899            WARN(("trying to update viewport while framebuffer is being updated"));
     2900            return VERR_INVALID_STATE;
     2901        }
     2902
     2903        int rc = pInfo->pDpWin->UpdateBegin(hFb);
     2904        if (RT_SUCCESS(rc))
     2905        {
     2906            pInfo->pDpWin->setViewportRect(&cr_server.screenVieport[idScreen].Rect);
     2907            pInfo->pDpWin->UpdateEnd(hFb);
     2908        }
     2909        else
     2910            WARN(("UpdateBegin failed %d", rc));
     2911    }
     2912
     2913    return VINF_SUCCESS;
     2914}
     2915
     2916int CrPMgrModeModify(HCR_FRAMEBUFFER hFb, uint32_t u32ModeAdd, uint32_t u32ModeRemove)
     2917{
     2918    uint32_t idScreen = CrFbGetScreenInfo(hFb)->u32ViewIndex;
     2919
     2920    CR_FBDISPLAY_INFO *pInfo = &g_CrPresenter.aDisplayInfos[idScreen];
     2921    u32ModeRemove = crPMgrModeAdjustVal(u32ModeRemove);
     2922    u32ModeAdd = crPMgrModeAdjustVal(u32ModeAdd);
     2923    u32ModeRemove &= pInfo->u32Mode;
     2924    u32ModeAdd &= ~(u32ModeRemove | pInfo->u32Mode);
     2925    if (!u32ModeRemove && !u32ModeAdd)
     2926        return VINF_SUCCESS;
     2927
     2928    if (!pInfo->pDpComposite)
     2929    {
     2930        pInfo->pDpComposite = new CrFbDisplayComposite();
     2931        pInfo->pDpComposite->setFramebuffer(hFb);
     2932    }
     2933
     2934    CrFbWindow * pOldWin = NULL;
     2935
     2936    if (u32ModeRemove & CR_PMGR_MODE_ROOTVR)
     2937    {
     2938        CRASSERT(pInfo->pDpWinRootVr);
     2939        CRASSERT(pInfo->pDpWin == pInfo->pDpWinRootVr);
     2940        pInfo->pDpComposite->remove(pInfo->pDpWinRootVr);
     2941        pOldWin = pInfo->pDpWinRootVr->windowDetach();
     2942        CRASSERT(pOldWin);
     2943        delete pInfo->pDpWinRootVr;
     2944        pInfo->pDpWinRootVr = NULL;
     2945        pInfo->pDpWin = NULL;
     2946
     2947        if (!(u32ModeRemove & CR_PMGR_MODE_WINDOW))
     2948        {
     2949            /* ensure the window is re-created */
     2950            u32ModeAdd |= CR_PMGR_MODE_WINDOW;
     2951        }
     2952    }
     2953    else if (u32ModeRemove & CR_PMGR_MODE_WINDOW)
     2954    {
     2955        CRASSERT(!pInfo->pDpWinRootVr);
     2956        CRASSERT(pInfo->pDpWin);
     2957        pInfo->pDpComposite->remove(pInfo->pDpWin);
     2958        pOldWin = pInfo->pDpWin->windowDetach();
     2959        CRASSERT(pOldWin);
     2960        delete pInfo->pDpWin;
     2961        pInfo->pDpWin = NULL;
     2962    }
     2963
     2964    if (u32ModeRemove & CR_PMGR_MODE_VRDP)
     2965    {
     2966        CRASSERT(pInfo->pDpVrdp);
     2967        if (pInfo->pDpComposite)
     2968            pInfo->pDpComposite->remove(pInfo->pDpVrdp);
     2969        else
     2970            CrFbDisplaySet(hFb, NULL);
     2971
     2972        delete pInfo->pDpVrdp;
     2973        pInfo->pDpVrdp = NULL;
     2974    }
     2975
     2976    CrFbDisplayBase *pDpToSet = NULL;
     2977
     2978    if (u32ModeAdd & CR_PMGR_MODE_ROOTVR)
     2979    {
     2980        CRASSERT(!pInfo->pDpWin);
     2981        CRASSERT(!pInfo->pDpWinRootVr);
     2982
     2983        if (!pOldWin)
     2984            pOldWin = new CrFbWindow(cr_server.screen[idScreen].winID);
     2985
     2986        pInfo->pDpWinRootVr = new CrFbDisplayWindowRootVr(pOldWin, &cr_server.screenVieport[idScreen].Rect);
     2987        pOldWin = NULL;
     2988        pInfo->pDpWin = pInfo->pDpWinRootVr;
     2989        pInfo->pDpComposite->add(pInfo->pDpWinRootVr);
     2990    }
     2991    else if (u32ModeAdd & CR_PMGR_MODE_WINDOW)
     2992    {
     2993        CRASSERT(!pInfo->pDpWin);
     2994        CRASSERT(!pInfo->pDpWinRootVr);
     2995
     2996        if (!pOldWin)
     2997            pOldWin = new CrFbWindow(cr_server.screen[idScreen].winID);
     2998
     2999        pInfo->pDpWin = new CrFbDisplayWindow(pOldWin, &cr_server.screenVieport[idScreen].Rect);
     3000        pOldWin = NULL;
     3001        pInfo->pDpComposite->add(pInfo->pDpWin);
     3002    }
     3003
     3004    if (u32ModeAdd & CR_PMGR_MODE_VRDP)
     3005    {
     3006        CRASSERT(!pInfo->pDpVrdp);
     3007        pInfo->pDpVrdp = new CrFbDisplayVrdp();
     3008        pInfo->pDpComposite->add(pInfo->pDpVrdp);
     3009    }
     3010
     3011    if (pInfo->pDpComposite->getDisplayCount() > 1)
     3012    {
     3013        ICrFbDisplay* pCur = CrFbDisplayGet(hFb);
     3014        if (pCur != (ICrFbDisplay*)pInfo->pDpComposite)
     3015            CrFbDisplaySet(hFb, pInfo->pDpComposite);
     3016    }
     3017    else
     3018    {
     3019        ICrFbDisplay* pCur = CrFbDisplayGet(hFb);
     3020        ICrFbDisplay* pFirst = pInfo->pDpComposite->first();
     3021        if (pCur != pFirst)
     3022            CrFbDisplaySet(hFb, pFirst);
     3023    }
     3024
     3025    if (pOldWin)
     3026        delete pOldWin;
     3027
     3028    pInfo->u32Mode = ((pInfo->u32Mode | u32ModeAdd) & ~u32ModeRemove);
     3029
     3030    return VINF_SUCCESS;
     3031}
     3032
     3033static int crPMgrModeModifyGlobal(uint32_t u32Mode, bool fEnable)
     3034{
     3035    uint32_t u32ModeAdd, u32ModeRemove;
     3036    if (fEnable)
     3037    {
     3038        u32ModeAdd = u32Mode;
     3039        u32ModeRemove = 0;
     3040    }
     3041    else
     3042    {
     3043        u32ModeAdd = 0;
     3044        u32ModeRemove = u32Mode;
     3045    }
     3046
     3047    g_CrPresenter.u32DisplayMode = (g_CrPresenter.u32DisplayMode | u32ModeAdd) & ~u32ModeRemove;
     3048
     3049    for (HCR_FRAMEBUFFER hFb = CrPMgrFbGetFirstEnabled();
     3050            hFb;
     3051            hFb = CrPMgrFbGetNextEnabled(hFb))
     3052    {
     3053        CrPMgrModeModify(hFb, u32ModeAdd, u32ModeRemove);
     3054    }
     3055
     3056    return VINF_SUCCESS;
     3057}
     3058
     3059int CrPMgrModeVrdp(bool fEnable)
     3060{
     3061    return crPMgrModeModifyGlobal(CR_PMGR_MODE_VRDP, fEnable);
     3062}
     3063
     3064int CrPMgrModeRootVr(bool fEnable)
     3065{
     3066    return crPMgrModeModifyGlobal(CR_PMGR_MODE_ROOTVR, fEnable);
     3067}
     3068
     3069int CrPMgrRootVrUpdate()
     3070{
     3071    for (HCR_FRAMEBUFFER hFb = CrPMgrFbGetFirstEnabled();
     3072            hFb;
     3073            hFb = CrPMgrFbGetNextEnabled(hFb))
     3074    {
     3075        uint32_t idScreen = CrFbGetScreenInfo(hFb)->u32ViewIndex;
     3076        CR_FBDISPLAY_INFO *pInfo = &g_CrPresenter.aDisplayInfos[idScreen];
     3077        int rc = CrFbUpdateBegin(hFb);
     3078        if (RT_SUCCESS(rc))
     3079        {
     3080            pInfo->pDpWinRootVr->RegionsChanged(hFb);
     3081            CrFbUpdateEnd(hFb);
     3082        }
     3083        else
     3084            WARN(("CrFbUpdateBegin failed %d", rc));
     3085    }
     3086
     3087    return VINF_SUCCESS;
     3088}
     3089
     3090/*helper function that calls CrFbUpdateBegin for all enabled framebuffers */
     3091int CrPMgrHlpGlblUpdateBegin()
     3092{
     3093    for (HCR_FRAMEBUFFER hFb = CrPMgrFbGetFirstEnabled();
     3094            hFb;
     3095            hFb = CrPMgrFbGetNextEnabled(hFb))
     3096    {
     3097        int rc = CrFbUpdateBegin(hFb);
     3098        if (!RT_SUCCESS(rc))
     3099        {
     3100            WARN(("UpdateBegin failed, rc %d", rc));
     3101            for (HCR_FRAMEBUFFER hTmpFb = CrPMgrFbGetFirstEnabled();
     3102                        hFb != hTmpFb;
     3103                        hTmpFb = CrPMgrFbGetNextEnabled(hTmpFb))
     3104            {
     3105                CrFbUpdateEnd(hTmpFb);
     3106            }
     3107            return rc;
     3108        }
     3109    }
     3110
     3111    return VINF_SUCCESS;
     3112}
     3113
     3114/*helper function that calls CrFbUpdateEnd for all framebuffers being updated */
     3115void CrPMgrHlpGlblUpdateEnd()
     3116{
     3117    for (uint32_t i = 0; i < cr_server.screenCount; ++i)
     3118    {
     3119        HCR_FRAMEBUFFER hFb = CrPMgrFbGet(i);
     3120        Assert(hFb);
     3121        if (CrFbIsUpdating(hFb))
     3122            CrFbUpdateEnd(hFb);
     3123    }
     3124}
     3125
     3126/*client should notify the manager about the framebuffer resize via this function */
     3127int CrPMgrNotifyResize(HCR_FRAMEBUFFER hFb)
     3128{
     3129    int rc = VINF_SUCCESS;
     3130    if (CrFbIsEnabled(hFb))
     3131    {
     3132        rc = CrPMgrModeModify(hFb, g_CrPresenter.u32DisplayMode, 0);
     3133        if (!RT_SUCCESS(rc))
     3134        {
     3135            WARN(("CrPMgrModeModify failed rc %d", rc));
     3136            return rc;
     3137        }
     3138    }
     3139    else
     3140    {
     3141        rc = CrPMgrModeModify(hFb, 0, CR_PMGR_MODE_ALL);
     3142        if (!RT_SUCCESS(rc))
     3143        {
     3144            WARN(("CrPMgrModeModify failed rc %d", rc));
     3145            return rc;
     3146        }
     3147    }
     3148
     3149    return VINF_SUCCESS;
     3150}
     3151
     3152int CrFbEntrySaveState(CR_FRAMEBUFFER *pFb, CR_FRAMEBUFFER_ENTRY *hEntry, PSSMHANDLE pSSM)
     3153{
     3154    const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry = CrFbEntryGetCompositorEntry(hEntry);
     3155    CR_TEXDATA *pTexData = CrVrScrCompositorEntryTexGet(pEntry);
     3156    CR_FBTEX *pFbTex = PCR_FBTEX_FROM_TEX(pTexData);
     3157    int rc = SSMR3PutU32(pSSM, pFbTex->pTobj->id);
     3158    AssertRCReturn(rc, rc);
    993159    uint32_t u32 = 0;
    100     while ((pEntry = CrVrScrCompositorIterNext(&Iter)) != NULL)
    101     {
    102         ++u32;
     3160
     3161    u32 = CrVrScrCompositorEntryFlagsGet(pEntry);
     3162    rc = SSMR3PutU32(pSSM, u32);
     3163    AssertRCReturn(rc, rc);
     3164
     3165    const RTRECT *pRect = CrVrScrCompositorEntryRectGet(pEntry);
     3166
     3167    rc = SSMR3PutS32(pSSM, pRect->xLeft);
     3168    AssertRCReturn(rc, rc);
     3169    rc = SSMR3PutS32(pSSM, pRect->yTop);
     3170    AssertRCReturn(rc, rc);
     3171#if 0
     3172    rc = SSMR3PutS32(pSSM, pRect->xRight);
     3173    AssertRCReturn(rc, rc);
     3174    rc = SSMR3PutS32(pSSM, pRect->yBottom);
     3175    AssertRCReturn(rc, rc);
     3176#endif
     3177
     3178    rc = CrVrScrCompositorEntryRegionsGet(&pFb->Compositor, pEntry, &u32, NULL, NULL, &pRect);
     3179    AssertRCReturn(rc, rc);
     3180
     3181    rc = SSMR3PutU32(pSSM, u32);
     3182    AssertRCReturn(rc, rc);
     3183
     3184    if (u32)
     3185    {
     3186        rc = SSMR3PutMem(pSSM, pRect, u32 * sizeof (*pRect));
     3187        AssertRCReturn(rc, rc);
     3188    }
     3189    return rc;
     3190}
     3191
     3192int CrFbSaveState(CR_FRAMEBUFFER *pFb, PSSMHANDLE pSSM)
     3193{
     3194    VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR Iter;
     3195    CrVrScrCompositorConstIterInit(&pFb->Compositor, &Iter);
     3196    const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry;
     3197    uint32_t u32 = 0;
     3198    while ((pEntry = CrVrScrCompositorConstIterNext(&Iter)) != NULL)
     3199    {
     3200        CR_TEXDATA *pTexData = CrVrScrCompositorEntryTexGet(pEntry);
     3201        CRASSERT(pTexData);
     3202        CR_FBTEX *pFbTex = PCR_FBTEX_FROM_TEX(pTexData);
     3203        if (pFbTex->pTobj)
     3204            ++u32;
    1033205    }
    1043206
     
    1063208    AssertRCReturn(rc, rc);
    1073209
    108     CrVrScrCompositorIterInit(&pDisplay->Mural.Compositor, &Iter);
    109 
    110     while ((pEntry = CrVrScrCompositorIterNext(&Iter)) != NULL)
    111     {
    112         CR_DISPLAY_ENTRY *pDEntry = CR_DENTRY_FROM_CENTRY(pEntry);
    113         rc = CrDemEntrySaveState(pDEntry, pSSM);
     3210    CrVrScrCompositorConstIterInit(&pFb->Compositor, &Iter);
     3211
     3212    while ((pEntry = CrVrScrCompositorConstIterNext(&Iter)) != NULL)
     3213    {
     3214        HCR_FRAMEBUFFER_ENTRY hEntry = CrFbEntryFromCompositorEntry(pEntry);
     3215        rc = CrFbEntrySaveState(pFb, hEntry, pSSM);
    1143216        AssertRCReturn(rc, rc);
    115 
    116         u32 = CrVrScrCompositorEntryFlagsGet(&pDEntry->CEntry);
    117         rc = SSMR3PutU32(pSSM, u32);
     3217    }
     3218
     3219    return VINF_SUCCESS;
     3220}
     3221
     3222int CrPMgrSaveState(PSSMHANDLE pSSM)
     3223{
     3224    int rc;
     3225    int cDisplays = 0, i;
     3226    for (i = 0; i < cr_server.screenCount; ++i)
     3227    {
     3228        if (CrPMgrFbGetEnabled(i))
     3229            ++cDisplays;
     3230    }
     3231
     3232    rc = SSMR3PutS32(pSSM, cDisplays);
     3233    AssertRCReturn(rc, rc);
     3234
     3235    if (!cDisplays)
     3236        return VINF_SUCCESS;
     3237
     3238    rc = SSMR3PutS32(pSSM, cr_server.screenCount);
     3239    AssertRCReturn(rc, rc);
     3240
     3241    for (i = 0; i < cr_server.screenCount; ++i)
     3242    {
     3243        CR_FRAMEBUFFER *hFb = CrPMgrFbGetEnabled(i);
     3244        if (hFb)
     3245        {
     3246            Assert(hFb->ScreenInfo.u32ViewIndex == i);
     3247            rc = SSMR3PutU32(pSSM, hFb->ScreenInfo.u32ViewIndex);
     3248            AssertRCReturn(rc, rc);
     3249
     3250            rc = SSMR3PutS32(pSSM, hFb->ScreenInfo.i32OriginX);
     3251            AssertRCReturn(rc, rc);
     3252
     3253            rc = SSMR3PutS32(pSSM, hFb->ScreenInfo.i32OriginY);
     3254            AssertRCReturn(rc, rc);
     3255
     3256            rc = SSMR3PutU32(pSSM, hFb->ScreenInfo.u32StartOffset);
     3257            AssertRCReturn(rc, rc);
     3258
     3259            rc = SSMR3PutU32(pSSM, hFb->ScreenInfo.u32LineSize);
     3260            AssertRCReturn(rc, rc);
     3261
     3262            rc = SSMR3PutU32(pSSM, hFb->ScreenInfo.u32Width);
     3263            AssertRCReturn(rc, rc);
     3264
     3265            rc = SSMR3PutU32(pSSM, hFb->ScreenInfo.u32Height);
     3266            AssertRCReturn(rc, rc);
     3267
     3268            rc = SSMR3PutU16(pSSM, hFb->ScreenInfo.u16BitsPerPixel);
     3269            AssertRCReturn(rc, rc);
     3270
     3271            rc = SSMR3PutU16(pSSM, hFb->ScreenInfo.u16Flags);
     3272            AssertRCReturn(rc, rc);
     3273
     3274            rc = SSMR3PutU32(pSSM, (uint32_t)(((uintptr_t)hFb->pvVram) - ((uintptr_t)g_pvVRamBase)));
     3275            AssertRCReturn(rc, rc);
     3276
     3277            rc = CrFbSaveState(hFb, pSSM);
     3278            AssertRCReturn(rc, rc);
     3279        }
     3280    }
     3281
     3282    return VINF_SUCCESS;
     3283}
     3284
     3285int CrFbEntryLoadState(CR_FRAMEBUFFER *pFb, PSSMHANDLE pSSM, uint32_t version)
     3286{
     3287    uint32_t texture;
     3288    int  rc = SSMR3GetU32(pSSM, &texture);
     3289    AssertRCReturn(rc, rc);
     3290
     3291    uint32_t fFlags;
     3292    rc = SSMR3GetU32(pSSM, &fFlags);
     3293    AssertRCReturn(rc, rc);
     3294
     3295
     3296    HCR_FRAMEBUFFER_ENTRY hEntry;
     3297
     3298    rc = CrFbEntryCreateForTexId(pFb, texture, fFlags, &hEntry);
     3299    if (!RT_SUCCESS(rc))
     3300    {
     3301        WARN(("CrFbEntryCreateForTexId Failed"));
     3302        return rc;
     3303    }
     3304
     3305    Assert(hEntry);
     3306
     3307    const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry = CrFbEntryGetCompositorEntry(hEntry);
     3308    CR_TEXDATA *pTexData = CrVrScrCompositorEntryTexGet(pEntry);
     3309    CR_FBTEX *pFbTex = PCR_FBTEX_FROM_TEX(pTexData);
     3310
     3311    RTPOINT Point;
     3312    rc = SSMR3GetS32(pSSM, &Point.x);
     3313    AssertRCReturn(rc, rc);
     3314
     3315    rc = SSMR3GetS32(pSSM, &Point.y);
     3316    AssertRCReturn(rc, rc);
     3317
     3318    uint32_t cRects;
     3319    rc = SSMR3GetU32(pSSM, &cRects);
     3320    AssertRCReturn(rc, rc);
     3321
     3322    RTRECT * pRects = NULL;
     3323    if (cRects)
     3324    {
     3325        pRects = (RTRECT *)crAlloc(cRects * sizeof (*pRects));
     3326        AssertReturn(pRects, VERR_NO_MEMORY);
     3327
     3328        rc = SSMR3GetMem(pSSM, pRects, cRects * sizeof (*pRects));
    1183329        AssertRCReturn(rc, rc);
    119 
    120         rc = SSMR3PutS32(pSSM, CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->x);
    121         AssertRCReturn(rc, rc);
    122 
    123         rc = SSMR3PutS32(pSSM, CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->y);
    124         AssertRCReturn(rc, rc);
    125 
    126         const RTRECT * pRects;
    127         rc = CrVrScrCompositorEntryRegionsGet(&pDisplay->Mural.Compositor, &pDEntry->CEntry, &u32, NULL, NULL, &pRects);
    128         AssertRCReturn(rc, rc);
    129 
    130         rc = SSMR3PutU32(pSSM, u32);
    131         AssertRCReturn(rc, rc);
    132 
    133         if (u32)
    134         {
    135             rc = SSMR3PutMem(pSSM, pRects, u32 * sizeof (*pRects));
    136             AssertRCReturn(rc, rc);
    137         }
    138     }
     3330    }
     3331
     3332    rc = CrFbEntryRegionsSet(pFb, hEntry, &Point, cRects, pRects, false);
     3333    AssertRCReturn(rc, rc);
     3334
     3335    if (pRects)
     3336        crFree(pRects);
    1393337
    1403338    return VINF_SUCCESS;
    1413339}
    1423340
    143 int CrDpLoadState(PCR_DISPLAY pDisplay, PSSMHANDLE pSSM, uint32_t version)
     3341int CrFbLoadState(CR_FRAMEBUFFER *pFb, PSSMHANDLE pSSM, uint32_t version)
    1443342{
    1453343    uint32_t u32 = 0;
     
    1503348        return VINF_SUCCESS;
    1513349
    152     CrDpEnter(pDisplay);
     3350    rc = CrFbUpdateBegin(pFb);
     3351    AssertRCReturn(rc, rc);
    1533352
    1543353    for (uint32_t i = 0; i < u32; ++i)
    1553354    {
    156         CR_DISPLAY_ENTRY *pDEntry;
    157         rc = CrDemEntryLoadState(&cr_server.PresentTexturepMap, &pDEntry, pSSM);
     3355        rc = CrFbEntryLoadState(pFb, pSSM, version);
    1583356        AssertRCReturn(rc, rc);
    1593357
    160         uint32_t fFlags;
    161         rc = SSMR3GetU32(pSSM, &fFlags);
    162         AssertRCReturn(rc, rc);
    163 
    164         CrVrScrCompositorEntryFlagsSet(&pDEntry->CEntry, fFlags);
    165 
    166         RTPOINT Pos;
    167         rc = SSMR3GetS32(pSSM, &Pos.x);
    168         AssertRCReturn(rc, rc);
    169 
    170         rc = SSMR3GetS32(pSSM, &Pos.y);
    171         AssertRCReturn(rc, rc);
    172 
    173         uint32_t cRects;
    174         rc = SSMR3GetU32(pSSM, &cRects);
    175         AssertRCReturn(rc, rc);
    176 
    177         RTRECT * pRects = NULL;
    178         if (cRects)
    179         {
    180             pRects = (RTRECT *)crAlloc(cRects * sizeof (*pRects));
    181             AssertReturn(pRects, VERR_NO_MEMORY);
    182 
    183             rc = SSMR3GetMem(pSSM, pRects, cRects * sizeof (*pRects));
    184             AssertRCReturn(rc, rc);
    185         }
    186 
    187         rc = CrDpEntryRegionsAdd(pDisplay, pDEntry, &Pos, (uint32_t)cRects, (const RTRECT*)pRects, NULL);
    188         AssertRCReturn(rc, rc);
    189 
    190         if (pRects)
    191             crFree(pRects);
    192     }
    193 
    194     CrDpLeave(pDisplay);
     3358    }
     3359
     3360    CrFbUpdateEnd(pFb);
    1953361
    1963362    return VINF_SUCCESS;
    1973363}
    1983364
    199 
    200 int CrDpEntryRegionsSet(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions)
    201 {
    202     int rc = CrVrScrCompositorEntryRegionsSet(&pDisplay->Mural.Compositor, pEntry ? &pEntry->CEntry : NULL, pPos, cRegions, paRegions, false, NULL);
    203     return rc;
    204 }
    205 
    206 void crDbgDumpRect(uint32_t i, const RTRECT *pRect)
    207 {
    208     crDebug("%d: (%d;%d) X (%d;%d)", i, pRect->xLeft, pRect->yTop, pRect->xRight, pRect->yBottom);
    209 }
    210 
    211 void crDbgDumpRects(uint32_t cRects, const RTRECT *paRects)
    212 {
    213     crDebug("Dumping rects (%d)", cRects);
    214     for (uint32_t i = 0; i < cRects; ++i)
    215     {
    216         crDbgDumpRect(i, &paRects[i]);
    217     }
    218     crDebug("End Dumping rects (%d)", cRects);
    219 }
    220 
    221 int CrDpEntryRegionsAdd(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, CR_DISPLAY_ENTRY_MAP *pMap)
    222 {
    223     uint32_t fChangeFlags = 0;
    224     VBOXVR_SCR_COMPOSITOR_ENTRY *pReplacedScrEntry = NULL;
    225 
    226     if (pMap)
    227         CrDemEnter(pMap);
    228 
    229     int rc = CrVrScrCompositorEntryRegionsAdd(&pDisplay->Mural.Compositor, pEntry ? &pEntry->CEntry : NULL, pPos, cRegions, paRegions, false, &pReplacedScrEntry, &fChangeFlags);
    230     if (RT_SUCCESS(rc))
    231     {
    232         if (fChangeFlags & VBOXVR_COMPOSITOR_CF_REGIONS_CHANGED)
    233         {
    234             bool fChanged = true;
    235             if (pDisplay->Mural.fRootVrOn)
    236             {
    237                 int rc = crServerMuralSynchRootVr(&pDisplay->Mural, &fChanged);
    238                 if (!RT_SUCCESS(rc))
    239                 {
    240                     crWarning("crServerMuralSynchRootVr failed, rc %d", rc);
    241                     fChanged = false;
    242                 }
    243             }
    244 
    245             if (fChanged)
    246                 crServerWindowVisibleRegion(&pDisplay->Mural);
    247 
    248             crServerDEntryAllVibleRegions(&pDisplay->Mural);
    249 
    250             Assert(!pReplacedScrEntry);
    251         }
    252         else if (fChangeFlags & VBOXVR_COMPOSITOR_CF_ENTRY_REGIONS_CHANGED)
    253         {
    254             if (fChangeFlags & VBOXVR_COMPOSITOR_CF_ENTRY_REPLACED)
    255             {
    256                 Assert(pReplacedScrEntry);
    257                 Assert(pEntry);
    258                 if (pDisplay->Mural.fRootVrOn)
    259                 {
    260                     CR_DISPLAY_ENTRY *pReplacedDEntry = CR_DENTRY_FROM_CENTRY(pReplacedScrEntry);
    261                     Assert(CrVrScrCompositorEntryIsUsed(&pReplacedDEntry->RootVrCEntry));
    262                     Assert(!CrVrScrCompositorEntryIsUsed(&pEntry->RootVrCEntry));
    263                     CrVrScrCompositorEntryInit(&pEntry->RootVrCEntry, CrVrScrCompositorEntryTexGet(&pEntry->CEntry), NULL);
    264                     CrVrScrCompositorEntryFlagsSet(&pEntry->RootVrCEntry, CrVrScrCompositorEntryFlagsGet(&pEntry->CEntry));
    265                     CrVrScrCompositorEntryReplace(&pDisplay->Mural.RootVrCompositor, &pReplacedDEntry->RootVrCEntry, &pEntry->RootVrCEntry);
    266                 }
    267             }
    268             else
    269             {
    270                 Assert(!pReplacedScrEntry);
    271                 if (pDisplay->Mural.fRootVrOn)
    272                 {
    273                     bool fChanged = false;
    274                     int rc = crServerMuralSynchRootVr(&pDisplay->Mural, &fChanged);
    275                     if (RT_SUCCESS(rc))
    276                     {
    277                         if (fChanged)
    278                             crServerWindowVisibleRegion(&pDisplay->Mural);
    279                     }
    280                     else
    281                         crWarning("crServerMuralSynchRootVr failed, rc %d", rc);
    282                 }
    283             }
    284         }
    285         else
    286         {
    287             Assert(!(fChangeFlags & VBOXVR_COMPOSITOR_CF_ENTRY_REPLACED));
    288             Assert(!pReplacedScrEntry);
    289         }
    290     }
    291     else
    292         crWarning("CrVrScrCompositorEntryRegionsAdd failed, rc %d", rc);
    293 
    294     if (pMap)
    295         CrDemLeave(pMap, CR_DENTRY_FROM_CENTRY(pEntry), CR_DENTRY_FROM_CENTRY(pReplacedScrEntry));
    296 
    297     return rc;
    298 }
    299 
    300 void CrDpRegionsClear(PCR_DISPLAY pDisplay)
    301 {
    302     bool fChanged = false;
    303     CrVrScrCompositorRegionsClear(&pDisplay->Mural.Compositor, &fChanged);
    304     if (fChanged)
    305     {
    306         crServerMuralVisibleRegion(&pDisplay->Mural, 0, NULL);
    307     }
    308 }
    309 
    310 #define PCR_DISPLAY_ENTRY_FROM_CENTRY(_pe) ((PCR_DISPLAY_ENTRY)((uint8_t*)(_pe) - RT_OFFSETOF(CR_DISPLAY_ENTRY, CEntry)))
    311 static DECLCALLBACK(void) crDpEntryCEntryReleaseCB(const struct VBOXVR_SCR_COMPOSITOR *pCompositor, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pReplacingEntry)
    312 {
    313     PCR_DISPLAY_ENTRY pCEntry = PCR_DISPLAY_ENTRY_FROM_CENTRY(pEntry);
    314     CrDemEntryRelease(pCEntry);
    315 }
    316 
    317 void CrDpEntryInit(PCR_DISPLAY_ENTRY pEntry, const VBOXVR_TEXTURE *pTextureData, uint32_t fFlags, PFNVBOXVRSCRCOMPOSITOR_ENTRY_RELEASED pfnEntryReleased)
    318 {
    319     CrVrScrCompositorEntryInit(&pEntry->CEntry, pTextureData, pfnEntryReleased);
    320     CrVrScrCompositorEntryFlagsSet(&pEntry->CEntry, fFlags);
    321     CrVrScrCompositorEntryInit(&pEntry->RootVrCEntry, pTextureData, NULL);
    322     CrVrScrCompositorEntryFlagsSet(&pEntry->RootVrCEntry, fFlags);
    323     pEntry->pvORInstance = NULL;
    324     pEntry->idPBO = 0;
    325     pEntry->idInvertTex = 0;
    326 }
    327 
    328 void CrDpEntryCleanup(PCR_DISPLAY_ENTRY pDEntry)
    329 {
    330     if (pDEntry->idPBO)
    331     {
    332         CRASSERT(cr_server.bUsePBOForReadback);
    333         cr_server.head_spu->dispatch_table.DeleteBuffersARB(1, &pDEntry->idPBO);
    334         pDEntry->idPBO = 0;
    335     }
    336 
    337     if (pDEntry->idInvertTex)
    338     {
    339         cr_server.head_spu->dispatch_table.DeleteTextures(1, &pDEntry->idInvertTex);
    340         pDEntry->idInvertTex = 0;
    341     }
    342 
    343     if (pDEntry->pvORInstance)
    344     {
    345         cr_server.outputRedirect.CROREnd(pDEntry->pvORInstance);
    346         pDEntry->pvORInstance = NULL;
    347     }
    348 }
    349 
    350 void CrDpEnter(PCR_DISPLAY pDisplay)
    351 {
    352     pDisplay->fForcePresent |= crServerVBoxCompositionPresentNeeded(&pDisplay->Mural);
    353     crServerVBoxCompositionDisableEnter(&pDisplay->Mural);
    354 }
    355 
    356 void CrDpLeave(PCR_DISPLAY pDisplay)
    357 {
    358     pDisplay->Mural.fDataPresented = GL_TRUE;
    359     pDisplay->Mural.fOrPresentOnReenable = GL_TRUE;
    360     crServerVBoxCompositionDisableLeave(&pDisplay->Mural, pDisplay->fForcePresent);
    361     pDisplay->fForcePresent = GL_FALSE;
    362 }
    363 
    364 void CrDpRootUpdate(PCR_DISPLAY pDisplay)
    365 {
    366     crVBoxServerUpdateMuralRootVisibleRegion(&pDisplay->Mural);
    367 }
    368 
    369 
    370 typedef struct CR_DEM_ENTRY_INFO
    371 {
    372     CRTextureObj *pTobj;
    373     uint32_t cEntries;
    374 } CR_DEM_ENTRY_INFO;
    375 
    376 typedef struct CR_DEM_ENTRY
    377 {
    378     CR_DISPLAY_ENTRY Entry;
    379     CR_DEM_ENTRY_INFO *pInfo;
    380     CR_DISPLAY_ENTRY_MAP *pMap;
    381     RTLISTNODE Node;
    382 } CR_DEM_ENTRY;
    383 
    384 #define PCR_DEM_ENTRY_FROM_ENTRY(_pEntry) ((CR_DEM_ENTRY*)((uint8_t*)(_pEntry) - RT_OFFSETOF(CR_DEM_ENTRY, Entry)))
    385 
    386 static RTMEMCACHE g_VBoxCrDemLookasideList;
    387 static RTMEMCACHE g_VBoxCrDemInfoLookasideList;
    388 
    389 int CrDemGlobalInit()
    390 {
    391     int rc = RTMemCacheCreate(&g_VBoxCrDemLookasideList, sizeof (CR_DEM_ENTRY),
    392                             0, /* size_t cbAlignment */
    393                             UINT32_MAX, /* uint32_t cMaxObjects */
    394                             NULL, /* PFNMEMCACHECTOR pfnCtor*/
    395                             NULL, /* PFNMEMCACHEDTOR pfnDtor*/
    396                             NULL, /* void *pvUser*/
    397                             0 /* uint32_t fFlags*/
    398                             );
    399     if (RT_SUCCESS(rc))
    400     {
    401         rc = RTMemCacheCreate(&g_VBoxCrDemInfoLookasideList, sizeof (CR_DEM_ENTRY_INFO),
    402                                     0, /* size_t cbAlignment */
    403                                     UINT32_MAX, /* uint32_t cMaxObjects */
    404                                     NULL, /* PFNMEMCACHECTOR pfnCtor*/
    405                                     NULL, /* PFNMEMCACHEDTOR pfnDtor*/
    406                                     NULL, /* void *pvUser*/
    407                                     0 /* uint32_t fFlags*/
    408                                     );
    409         if (RT_SUCCESS(rc))
    410             return VINF_SUCCESS;
    411         else
    412             crWarning("RTMemCacheCreate failed rc %d", rc);
    413 
    414         RTMemCacheDestroy(g_VBoxCrDemLookasideList);
    415     }
    416     else
    417         crWarning("RTMemCacheCreate failed rc %d", rc);
    418     return VINF_SUCCESS;
    419 }
    420 
    421 void CrDemTeGlobalTerm()
    422 {
    423     RTMemCacheDestroy(g_VBoxCrDemLookasideList);
    424     RTMemCacheDestroy(g_VBoxCrDemInfoLookasideList);
    425 }
    426 
    427 static CR_DEM_ENTRY* crDemEntryAlloc()
    428 {
    429     return (CR_DEM_ENTRY*)RTMemCacheAlloc(g_VBoxCrDemLookasideList);
    430 }
    431 
    432 static CR_DEM_ENTRY_INFO* crDemEntryInfoAlloc()
    433 {
    434     return (CR_DEM_ENTRY_INFO*)RTMemCacheAlloc(g_VBoxCrDemInfoLookasideList);
    435 }
    436 
    437 static void crDemEntryFree(CR_DEM_ENTRY* pDemEntry)
    438 {
    439     CrDpEntryCleanup(&pDemEntry->Entry);
    440     RTMemCacheFree(g_VBoxCrDemLookasideList, pDemEntry);
    441 }
    442 
    443 static void crDemEntryInfoFree(CR_DEM_ENTRY_INFO* pDemEntryInfo)
    444 {
    445     RTMemCacheFree(g_VBoxCrDemInfoLookasideList, pDemEntryInfo);
    446 }
    447 
    448 void crDemEntryRelease(PCR_DISPLAY_ENTRY_MAP pMap, CR_DEM_ENTRY *pDemEntry)
    449 {
    450     CR_DEM_ENTRY_INFO *pInfo = pDemEntry->pInfo;
    451     CRTextureObj *pTobj = pInfo->pTobj;
    452 
    453     --pInfo->cEntries;
    454 
    455     if (!pInfo->cEntries)
    456     {
    457         CR_STATE_SHAREDOBJ_USAGE_CLEAR(pInfo->pTobj, cr_server.MainContextInfo.pContext);
    458 
    459         crHashtableDelete(pMap->pTexIdToDemInfoMap, pTobj->id, NULL);
    460 
    461         crDemEntryInfoFree(pInfo);
    462     }
    463 
    464     if (!CR_STATE_SHAREDOBJ_USAGE_IS_USED(pTobj))
    465     {
    466         CRSharedState *pShared = crStateGlobalSharedAcquire();
    467 
    468         CRASSERT(pShared);
    469         /* on the host side, we need to delete an ogl texture object here as well, which crStateDeleteTextureCallback will do
    470          * in addition to calling crStateDeleteTextureObject to delete a state object */
    471         crHashtableDelete(pShared->textureTable, pTobj->id, crStateDeleteTextureCallback);
    472 
    473         crStateGlobalSharedRelease();
    474     }
    475 
    476     crStateGlobalSharedRelease();
    477 
    478     if (!pMap->cEntered)
    479         crDemEntryFree(pDemEntry);
    480     else
    481         RTListNodeInsertAfter(&pMap->ReleasedList, &pDemEntry->Node);
    482 }
    483 
    484 int CrDemInit(PCR_DISPLAY_ENTRY_MAP pMap)
    485 {
    486     pMap->pTexIdToDemInfoMap = crAllocHashtable();
    487     if (pMap->pTexIdToDemInfoMap)
    488     {
    489         RTListInit(&pMap->ReleasedList);
    490         return VINF_SUCCESS;
    491     }
    492 
    493     crWarning("crAllocHashtable failed");
    494     return VERR_NO_MEMORY;
    495 }
    496 
    497 void CrDemTerm(PCR_DISPLAY_ENTRY_MAP pMap)
    498 {
    499     CRASSERT(RTListIsEmpty(&pMap->ReleasedList));
    500     CRASSERT(!pMap->cEntered);
    501     crFreeHashtable(pMap->pTexIdToDemInfoMap, NULL);
    502     pMap->pTexIdToDemInfoMap = NULL;
    503 }
    504 
    505 void CrDemEnter(PCR_DISPLAY_ENTRY_MAP pMap)
    506 {
    507     ++pMap->cEntered;
    508     Assert(pMap->cEntered);
    509 }
    510 
    511 void CrDemLeave(PCR_DISPLAY_ENTRY_MAP pMap, PCR_DISPLAY_ENTRY pNewEntry, PCR_DISPLAY_ENTRY pReplacedEntry)
    512 {
    513     Assert(pMap->cEntered);
    514     --pMap->cEntered;
    515     Assert(!pReplacedEntry || pNewEntry);
    516     if (pNewEntry && pReplacedEntry)
    517     {
    518         CR_DEM_ENTRY *pNewDemEntry = PCR_DEM_ENTRY_FROM_ENTRY(pNewEntry);
    519         CR_DEM_ENTRY *pReplacedDemEntry = PCR_DEM_ENTRY_FROM_ENTRY(pReplacedEntry);
    520         Assert(!RTListIsEmpty(&pMap->ReleasedList));
    521         Assert(!RTListIsEmpty(&pReplacedDemEntry->Node));
    522         Assert(RTListIsEmpty(&pNewDemEntry->Node));
    523         Assert(!pNewDemEntry->Entry.pvORInstance);
    524         if (!pNewDemEntry->Entry.pvORInstance)
    525         {
    526             pNewDemEntry->Entry.pvORInstance = pReplacedDemEntry->Entry.pvORInstance;
    527             pReplacedDemEntry->Entry.pvORInstance = NULL;
    528         }
    529         RTListNodeRemove(&pReplacedDemEntry->Node);
    530         crDemEntryFree(pReplacedDemEntry);
    531     }
    532 
    533     if (!pMap->cEntered)
    534     {
    535         CR_DEM_ENTRY *pCurEntry, *pNextEntry;
    536         RTListForEachSafe(&pMap->ReleasedList, pCurEntry, pNextEntry, CR_DEM_ENTRY, Node)
    537         {
    538             RTListNodeRemove(&pCurEntry->Node);
    539             crDemEntryFree(pCurEntry);
    540         }
    541     }
    542 }
    543 
    544 void CrDemEntryRelease(PCR_DISPLAY_ENTRY pEntry)
    545 {
    546     CR_DEM_ENTRY *pDemEntry = PCR_DEM_ENTRY_FROM_ENTRY(pEntry);
    547     crDemEntryRelease(pDemEntry->pMap, pDemEntry);
    548 }
    549 
    550 int CrDemEntrySaveState(PCR_DISPLAY_ENTRY pEntry, PSSMHANDLE pSSM)
    551 {
    552     CR_DEM_ENTRY *pDemEntry = PCR_DEM_ENTRY_FROM_ENTRY(pEntry);
    553     int  rc = SSMR3PutU32(pSSM, pDemEntry->pInfo->pTobj->id);
    554     AssertRCReturn(rc, rc);
    555     return rc;
    556 }
    557 
    558 int CrDemEntryLoadState(PCR_DISPLAY_ENTRY_MAP pMap, PCR_DISPLAY_ENTRY *ppEntry, PSSMHANDLE pSSM)
    559 {
    560     uint32_t u32;
    561     int  rc = SSMR3GetU32(pSSM, &u32);
    562     AssertRCReturn(rc, rc);
    563 
    564     PCR_DISPLAY_ENTRY pEntry = CrDemEntryAcquire(pMap, u32, CRBLT_F_INVERT_SRC_YCOORDS);
    565     if (!pEntry)
    566     {
    567         crWarning("CrDemEntryAcquire failed");
    568         return VERR_NO_MEMORY;
    569     }
    570 
    571     *ppEntry = pEntry;
    572     return VINF_SUCCESS;
    573 }
    574 
    575 PCR_DISPLAY_ENTRY CrDemEntryAcquire(PCR_DISPLAY_ENTRY_MAP pMap, GLuint idTexture, uint32_t fFlags)
    576 {
    577     CR_DEM_ENTRY *pDemEntry = NULL;
    578 
    579     CRSharedState *pShared = crStateGlobalSharedAcquire();
    580     if (!pShared)
    581     {
    582         crWarning("pShared is null!");
    583         return NULL;
    584     }
    585 
    586     CRTextureObj *pTobj = (CRTextureObj*)crHashtableSearch(pShared->textureTable, idTexture);
    587     if (!pTobj)
    588     {
    589         crWarning("pTobj is null!");
    590         crStateGlobalSharedRelease();
    591         return NULL;
    592     }
    593 
    594     Assert(pTobj->id == idTexture);
    595 
    596     GLuint hwId = crStateGetTextureObjHWID(pTobj);
    597     if (!hwId)
    598     {
    599         crWarning("hwId is null!");
    600         crStateGlobalSharedRelease();
    601         return NULL;
    602     }
    603 
    604     VBOXVR_TEXTURE TextureData;
    605     TextureData.width = pTobj->level[0]->width;
    606     TextureData.height = pTobj->level[0]->height;
    607     TextureData.target = pTobj->target;
    608     TextureData.hwid = hwId;
    609 
    610     pDemEntry = crDemEntryAlloc();
    611     if (!pDemEntry)
    612     {
    613         crWarning("crDemEntryAlloc failed allocating CR_DEM_ENTRY");
    614         crStateGlobalSharedRelease();
    615         return NULL;
    616     }
    617 
    618     CrDpEntryInit(&pDemEntry->Entry, &TextureData, fFlags, crDpEntryCEntryReleaseCB);
    619 
    620     CR_DEM_ENTRY_INFO *pInfo = (CR_DEM_ENTRY_INFO*)crHashtableSearch(pMap->pTexIdToDemInfoMap, pTobj->id);
    621     if (!pInfo)
    622     {
    623         pInfo = crDemEntryInfoAlloc();
    624         CRASSERT(pInfo);
    625         crHashtableAdd(pMap->pTexIdToDemInfoMap, pTobj->id, pInfo);
    626         pInfo->cEntries = 0;
    627         pInfo->pTobj = pTobj;
    628     }
    629 
    630     ++pInfo->cEntries;
    631     pDemEntry->pInfo = pInfo;
    632     pDemEntry->pMap = pMap;
    633     RTListInit(&pDemEntry->Node);
    634 
    635     /* just use main context info's context to hold the texture reference */
    636     CR_STATE_SHAREDOBJ_USAGE_SET(pTobj, cr_server.MainContextInfo.pContext);
    637 
    638     return &pDemEntry->Entry;
    639 }
    640 
    641 PCR_DISPLAY crServerDisplayGetInitialized(uint32_t idScreen)
    642 {
    643     if (idScreen >= CR_MAX_GUEST_MONITORS)
    644     {
    645         crWarning("invalid idScreen %d", idScreen);
    646         return NULL;
    647     }
    648 
    649     if (ASMBitTest(cr_server.DisplaysInitMap, idScreen))
    650     {
    651         Assert(cr_server.aDispplays[idScreen].Mural.screenId == idScreen);
    652         return &cr_server.aDispplays[idScreen];
    653     }
    654     return NULL;
    655 }
    656 
    657 static PCR_DISPLAY crServerDisplayGet(uint32_t idScreen)
    658 {
    659     if (idScreen >= CR_MAX_GUEST_MONITORS)
    660     {
    661         crWarning("invalid idScreen %d", idScreen);
    662         return NULL;
    663     }
    664 
    665     if (ASMBitTest(cr_server.DisplaysInitMap, idScreen))
    666     {
    667         Assert(cr_server.aDispplays[idScreen].Mural.screenId == idScreen);
    668         return &cr_server.aDispplays[idScreen];
    669     }
    670 
    671      int rc = CrDpInit(&cr_server.aDispplays[idScreen]);
    672      if (RT_SUCCESS(rc))
    673      {
    674          CrDpResize(&cr_server.aDispplays[idScreen],
    675                  cr_server.screen[idScreen].x, cr_server.screen[idScreen].y,
    676                  cr_server.screen[idScreen].w, cr_server.screen[idScreen].h);
    677          ASMBitSet(cr_server.DisplaysInitMap, idScreen);
    678          return &cr_server.aDispplays[idScreen];
    679      }
    680      else
    681      {
    682          crWarning("CrDpInit failed for screen %d", idScreen);
    683      }
    684 
    685     return NULL;
    686 }
    687 
    688 int crServerDisplaySaveState(PSSMHANDLE pSSM)
    689 {
    690     int rc;
    691     int cDisplays = 0, i;
    692     for (i = 0; i < cr_server.screenCount; ++i)
    693     {
    694         if (ASMBitTest(cr_server.DisplaysInitMap, i) && !CrDpIsEmpty(&cr_server.aDispplays[i]))
    695             ++cDisplays;
    696     }
    697 
    698     rc = SSMR3PutS32(pSSM, cDisplays);
    699     AssertRCReturn(rc, rc);
    700 
    701     if (!cDisplays)
    702         return VINF_SUCCESS;
    703 
    704     rc = SSMR3PutS32(pSSM, cr_server.screenCount);
    705     AssertRCReturn(rc, rc);
    706 
    707     for (i = 0; i < cr_server.screenCount; ++i)
    708     {
    709         rc = SSMR3PutS32(pSSM, cr_server.screen[i].x);
    710         AssertRCReturn(rc, rc);
    711 
    712         rc = SSMR3PutS32(pSSM, cr_server.screen[i].y);
    713         AssertRCReturn(rc, rc);
    714 
    715         rc = SSMR3PutU32(pSSM, cr_server.screen[i].w);
    716         AssertRCReturn(rc, rc);
    717 
    718         rc = SSMR3PutU32(pSSM, cr_server.screen[i].h);
    719         AssertRCReturn(rc, rc);
    720     }
    721 
    722     for (i = 0; i < cr_server.screenCount; ++i)
    723     {
    724         if (ASMBitTest(cr_server.DisplaysInitMap, i) && !CrDpIsEmpty(&cr_server.aDispplays[i]))
    725         {
    726             rc = SSMR3PutS32(pSSM, i);
    727             AssertRCReturn(rc, rc);
    728 
    729             rc = CrDpSaveState(&cr_server.aDispplays[i], pSSM);
    730             AssertRCReturn(rc, rc);
    731         }
    732     }
    733 
    734     return VINF_SUCCESS;
    735 }
    736 
    737 int crServerDisplayLoadState(PSSMHANDLE pSSM, uint32_t u32Version)
     3365int CrPMgrLoadState(PSSMHANDLE pSSM, uint32_t version)
    7383366{
    7393367    int rc;
     
    7513379    CRASSERT(screenCount == cr_server.screenCount);
    7523380
    753     crServerVBoxCompositionSetEnableStateGlobal(GL_FALSE);
    754 
    755     for (i = 0; i < cr_server.screenCount; ++i)
    756     {
    757         int32_t    x, y;
    758         uint32_t   w, h;
    759         rc = SSMR3GetS32(pSSM, &x);
    760         AssertRCReturn(rc, rc);
    761 
    762         rc = SSMR3GetS32(pSSM, &y);
    763         AssertRCReturn(rc, rc);
    764 
    765         rc = SSMR3GetU32(pSSM, &w);
    766         AssertRCReturn(rc, rc);
    767 
    768         rc = SSMR3GetU32(pSSM, &h);
    769         AssertRCReturn(rc, rc);
    770 
    771         rc = crVBoxServerMapScreen(i, x, y, w, h, cr_server.screen[i].winID);
    772         AssertRCReturn(rc, rc);
    773     }
    774 
    775     crServerVBoxCompositionSetEnableStateGlobal(GL_TRUE);
     3381    CRScreenInfo screen[CR_MAX_GUEST_MONITORS];
     3382
     3383    if (version < SHCROGL_SSM_VERSION_WITH_FB_INFO)
     3384    {
     3385        for (i = 0; i < cr_server.screenCount; ++i)
     3386        {
     3387            rc = SSMR3GetS32(pSSM, &screen[i].x);
     3388            AssertRCReturn(rc, rc);
     3389
     3390            rc = SSMR3GetS32(pSSM, &screen[i].y);
     3391            AssertRCReturn(rc, rc);
     3392
     3393            rc = SSMR3GetU32(pSSM, &screen[i].w);
     3394            AssertRCReturn(rc, rc);
     3395
     3396            rc = SSMR3GetU32(pSSM, &screen[i].h);
     3397            AssertRCReturn(rc, rc);
     3398        }
     3399    }
    7763400
    7773401    for (i = 0; i < cDisplays; ++i)
     
    7823406        AssertRCReturn(rc, rc);
    7833407
    784         PCR_DISPLAY pDisplay = crServerDisplayGet((uint32_t)iScreen);
    785         if (!pDisplay)
    786         {
    787             crWarning("crServerDisplayGet failed");
    788             return VERR_GENERAL_FAILURE;
    789         }
    790 
    791         rc = CrDpLoadState(pDisplay, pSSM, u32Version);
     3408        CR_FRAMEBUFFER *pFb = CrPMgrFbGet(iScreen);
     3409        Assert(pFb);
     3410
     3411        rc = CrFbUpdateBegin(pFb);
     3412        if (!RT_SUCCESS(rc))
     3413        {
     3414            WARN(("CrFbUpdateBegin failed %d", rc));
     3415            return rc;
     3416        }
     3417
     3418        VBVAINFOSCREEN Screen;
     3419        void *pvVRAM;
     3420
     3421        Screen.u32ViewIndex = iScreen;
     3422
     3423        if (version < SHCROGL_SSM_VERSION_WITH_FB_INFO)
     3424        {
     3425            memset(&Screen, 0, sizeof (Screen));
     3426            Screen.u32LineSize = 4 * screen[iScreen].w;
     3427            Screen.u32Width = screen[iScreen].w;
     3428            Screen.u32Height = screen[iScreen].h;
     3429            Screen.u16BitsPerPixel = 4;
     3430            Screen.u16Flags = VBVA_SCREEN_F_ACTIVE;
     3431
     3432            pvVRAM = g_pvVRamBase;
     3433        }
     3434        else
     3435        {
     3436            rc = SSMR3GetS32(pSSM, &Screen.i32OriginX);
     3437            AssertRCReturn(rc, rc);
     3438
     3439            rc = SSMR3GetS32(pSSM, &Screen.i32OriginY);
     3440            AssertRCReturn(rc, rc);
     3441
     3442            rc = SSMR3GetU32(pSSM, &Screen.u32StartOffset);
     3443            AssertRCReturn(rc, rc);
     3444
     3445            rc = SSMR3GetU32(pSSM, &Screen.u32LineSize);
     3446            AssertRCReturn(rc, rc);
     3447
     3448            rc = SSMR3GetU32(pSSM, &Screen.u32Width);
     3449            AssertRCReturn(rc, rc);
     3450
     3451            rc = SSMR3GetU32(pSSM, &Screen.u32Height);
     3452            AssertRCReturn(rc, rc);
     3453
     3454            rc = SSMR3GetU16(pSSM, &Screen.u16BitsPerPixel);
     3455            AssertRCReturn(rc, rc);
     3456
     3457            rc = SSMR3GetU16(pSSM, &Screen.u16Flags);
     3458            AssertRCReturn(rc, rc);
     3459
     3460            uint32_t offVram = 0;
     3461            rc = SSMR3GetU32(pSSM, &offVram);
     3462            AssertRCReturn(rc, rc);
     3463
     3464            pvVRAM = (void*)(((uintptr_t)g_pvVRamBase) + offVram);
     3465        }
     3466
     3467        crVBoxServerMuralFbResizeBegin(pFb);
     3468
     3469        rc = CrFbResize(pFb, &Screen, pvVRAM);
     3470        if (!RT_SUCCESS(rc))
     3471        {
     3472            WARN(("CrFbResize failed %d", rc));
     3473            return rc;
     3474        }
     3475
     3476        rc = CrFbLoadState(pFb, pSSM, version);
    7923477        AssertRCReturn(rc, rc);
     3478
     3479        crVBoxServerMuralFbResizeEnd(pFb);
     3480
     3481        CrFbUpdateEnd(pFb);
     3482
     3483        CrPMgrNotifyResize(pFb);
    7933484    }
    7943485
     
    7963487}
    7973488
    798 void crServerDisplayTermAll()
    799 {
    800     int i;
    801     for (i = 0; i < cr_server.screenCount; ++i)
    802     {
    803         if (ASMBitTest(cr_server.DisplaysInitMap, i))
    804         {
    805             CrDpTerm(&cr_server.aDispplays[i]);
    806             ASMBitClear(cr_server.DisplaysInitMap, i);
    807         }
    808     }
    809 }
    810 
    811 void CrHlpFreeTexImage(CRContext *pCurCtx, GLuint idPBO, void *pvData)
    812 {
    813     if (idPBO)
    814     {
    815         cr_server.head_spu->dispatch_table.UnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
    816         if (pCurCtx)
    817             cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pCurCtx->bufferobject.packBuffer->hwid);
    818         else
    819             cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
    820     }
    821     else
    822     {
    823         crFree(pvData);
    824         if (pCurCtx && crStateIsBufferBoundForCtx(pCurCtx, GL_PIXEL_PACK_BUFFER_ARB))
    825             cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pCurCtx->bufferobject.packBuffer->hwid);
    826     }
    827 }
    828 
    829 void CrHlpPutTexImage(CRContext *pCurCtx, const VBOXVR_TEXTURE *pTexture, GLenum enmFormat, void *pvData)
    830 {
    831     CRASSERT(pTexture->hwid);
    832     cr_server.head_spu->dispatch_table.BindTexture(pTexture->target, pTexture->hwid);
    833 
    834     if (!pCurCtx || crStateIsBufferBoundForCtx(pCurCtx, GL_PIXEL_UNPACK_BUFFER_ARB))
    835     {
    836         cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
    837     }
    838 
    839     /*read the texture, note pixels are NULL for PBO case as it's offset in the buffer*/
    840     cr_server.head_spu->dispatch_table.TexSubImage2D(GL_TEXTURE_2D,  0 /* level*/,  0 /*xoffset*/,  0 /*yoffset*/,  pTexture->width, pTexture->height, enmFormat, GL_UNSIGNED_BYTE, pvData);
    841 
    842     /*restore gl state*/
    843     if (pCurCtx)
    844     {
    845         CRTextureObj *pTObj;
    846         CRTextureLevel *pTImg;
    847         crStateGetTextureObjectAndImage(pCurCtx, pTexture->target, 0, &pTObj, &pTImg);
    848 
    849         GLuint uid = pTObj->hwid;
    850         cr_server.head_spu->dispatch_table.BindTexture(pTexture->target, uid);
    851     }
    852     else
    853     {
    854         cr_server.head_spu->dispatch_table.BindTexture(pTexture->target, 0);
    855     }
    856 
    857     if (pCurCtx && crStateIsBufferBoundForCtx(pCurCtx, GL_PIXEL_UNPACK_BUFFER_ARB))
    858         cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pCurCtx->bufferobject.unpackBuffer->hwid);
    859 }
    860 
    861 void* CrHlpGetTexImage(CRContext *pCurCtx, const VBOXVR_TEXTURE *pTexture, GLuint idPBO, GLenum enmFormat)
    862 {
    863     void *pvData = NULL;
    864     cr_server.head_spu->dispatch_table.BindTexture(pTexture->target, pTexture->hwid);
    865 
    866     if (idPBO)
    867     {
    868         cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, idPBO);
    869     }
    870     else
    871     {
    872         if (!pCurCtx || crStateIsBufferBoundForCtx(pCurCtx, GL_PIXEL_PACK_BUFFER_ARB))
    873         {
    874             cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
    875         }
    876 
    877         pvData = crAlloc(4*pTexture->width*pTexture->height);
    878         if (!pvData)
    879         {
    880             crWarning("Out of memory in CrHlpGetTexImage");
    881             return NULL;
    882         }
    883     }
    884 
    885     /*read the texture, note pixels are NULL for PBO case as it's offset in the buffer*/
    886     cr_server.head_spu->dispatch_table.GetTexImage(GL_TEXTURE_2D, 0, enmFormat, GL_UNSIGNED_BYTE, pvData);
    887 
    888     /*restore gl state*/
    889     if (pCurCtx)
    890     {
    891         CRTextureObj *pTObj;
    892         CRTextureLevel *pTImg;
    893         crStateGetTextureObjectAndImage(pCurCtx, pTexture->target, 0, &pTObj, &pTImg);
    894 
    895         GLuint uid = pTObj->hwid;
    896         cr_server.head_spu->dispatch_table.BindTexture(pTexture->target, uid);
    897     }
    898     else
    899     {
    900         cr_server.head_spu->dispatch_table.BindTexture(pTexture->target, 0);
    901     }
    902 
    903     if (idPBO)
    904     {
    905         pvData = cr_server.head_spu->dispatch_table.MapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
    906         if (!pvData)
    907         {
    908             crWarning("Failed to MapBuffer in CrHlpGetTexImage");
    909             return NULL;
    910         }
    911     }
    912 
    913     CRASSERT(pvData);
    914     return pvData;
    915 }
    9163489
    9173490void SERVER_DISPATCH_APIENTRY
     
    9213494    if (idScreen >= CR_MAX_GUEST_MONITORS)
    9223495    {
    923         crWarning("Invalid guest screen");
     3496        WARN(("Invalid guest screen"));
    9243497        return;
    9253498    }
    9263499
    927     PCR_DISPLAY pDisplay;
    928     PCR_DISPLAY_ENTRY pEntry = NULL;
    929 
     3500    HCR_FRAMEBUFFER hFb = CrPMgrFbGetEnabled(idScreen);
     3501    if (!hFb)
     3502    {
     3503        WARN(("request to present on disabled framebuffer, ignore"));
     3504        return;
     3505    }
     3506
     3507    HCR_FRAMEBUFFER_ENTRY hEntry;
     3508    int rc;
    9303509    if (texture)
    9313510    {
    932         pEntry = CrDemEntryAcquire(&cr_server.PresentTexturepMap, texture, (cfg & CR_PRESENT_FLAG_TEX_NONINVERT_YCOORD) ? 0 : CRBLT_F_INVERT_SRC_YCOORDS);
    933         if (!pEntry)
    934         {
    935             crWarning("CrDemEntryAcquire Failed");
     3511        rc = CrFbEntryCreateForTexId(hFb, texture, (cfg & CR_PRESENT_FLAG_TEX_NONINVERT_YCOORD) ? 0 : CRBLT_F_INVERT_SRC_YCOORDS, &hEntry);
     3512        if (!RT_SUCCESS(rc))
     3513        {
     3514            WARN(("CrFbEntryCreateForTexId Failed"));
    9363515            return;
    9373516        }
    9383517
    939         pDisplay = crServerDisplayGet(idScreen);
    940         if (!pDisplay)
    941         {
    942             crWarning("crServerDisplayGet Failed");
    943             CrDemEntryRelease(pEntry);
    944             return;
    945         }
     3518        Assert(hEntry);
     3519
     3520#if 0
     3521        if (!(cfg & CR_PRESENT_FLAG_CLEAR_RECTS))
     3522        {
     3523            CR_SERVER_DUMP_TEXPRESENT(&pEntry->CEntry.Tex);
     3524        }
     3525#endif
    9463526    }
    9473527    else
    948     {
    949         pDisplay = crServerDisplayGetInitialized(idScreen);
    950         if (!pDisplay)
    951         {
    952             /* no display initialized, and nothing to present */
    953             return;
    954         }
    955     }
    956 
    957     if (!(cfg & CR_PRESENT_FLAG_CLEAR_RECTS))
    958     {
    959         CR_SERVER_DUMP_TEXPRESENT(&pEntry->CEntry.Tex);
    960     }
    961 
    962     CrDpEnter(pDisplay);
    963 
    964     if (!(cfg & CR_PRESENT_FLAG_CLEAR_RECTS))
    965     {
    966         RTPOINT Point = {xPos, yPos};
    967         int rc = CrDpEntryRegionsAdd(pDisplay, pEntry, &Point, (uint32_t)cRects, (const RTRECT*)pRects, &cr_server.PresentTexturepMap);
    968         if (!RT_SUCCESS(rc))
    969         {
    970             crWarning("CrDpEntryRegionsAdd Failed rc %d", rc);
    971             /* no need to release anything, as CrDpEntryRegionsAdd would do everything for us as needed */
    972 //            if (pEntry)
    973 //                CrDemEntryRelease(pEntry);
    974         }
     3528        hEntry = NULL;
     3529
     3530    rc = CrFbUpdateBegin(hFb);
     3531    if (RT_SUCCESS(rc))
     3532    {
     3533        if (!(cfg & CR_PRESENT_FLAG_CLEAR_RECTS))
     3534        {
     3535            RTPOINT Point = {xPos, yPos};
     3536            rc = CrFbEntryRegionsAdd(hFb, hEntry, &Point, (uint32_t)cRects, (const RTRECT*)pRects, false);
     3537        }
     3538        else
     3539        {
     3540            CrFbRegionsClear(hFb);
     3541        }
     3542
     3543        CrFbUpdateEnd(hFb);
    9753544    }
    9763545    else
    9773546    {
    978         if (pEntry)
    979             CrDemEntryRelease(pEntry);
    980         CrDpRegionsClear(pDisplay);
    981     }
    982 
    983     CrDpLeave(pDisplay);
    984 }
     3547        WARN(("CrFbUpdateBegin Failed"));
     3548    }
     3549
     3550    if (hEntry)
     3551        CrFbEntryRelease(hFb, hEntry);
     3552}
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_stream.c

    r44290 r50095  
    442442            uint32_t cbWriteback = pCmdData->cbWriteback;
    443443            rc = crVBoxServerInternalClientRead(conn->pClient, (uint8_t*)pCmdData->pWriteback, &cbWriteback);
    444             CRASSERT(rc == VINF_SUCCESS || rc == VERR_BUFFER_OVERFLOW);
     444            Assert(rc == VINF_SUCCESS || rc == VERR_BUFFER_OVERFLOW);
    445445            *pCmdData->pcbWriteback = cbWriteback;
    446446        }
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c

    r49474 r50095  
    1313#include "render/renderspu.h"
    1414
    15 static GLboolean crServerWindowCalcIsVisible(CRMuralInfo *pMural)
    16 {
    17     uint32_t cRegions;
    18     int rc;
    19     if (!pMural->width || !pMural->height)
    20         return GL_FALSE;
    21 
    22     if (!pMural->bVisible || !(pMural->fPresentMode & CR_SERVER_REDIR_F_DISPLAY))
    23         return GL_FALSE;
    24 
    25     rc = CrVrScrCompositorRegionsGet(pMural->fRootVrOn ? &pMural->RootVrCompositor : &pMural->Compositor, &cRegions, NULL, NULL, NULL);
    26     if (RT_FAILURE(rc))
    27     {
    28         crWarning("CrVrScrCompositorRegionsGet failed, rc %d", rc);
    29         return GL_FALSE;
    30     }
    31 
    32     if (!cRegions)
    33         return GL_FALSE;
    34 
    35     return GL_TRUE;
    36 }
    37 
    38 void crServerWindowSetIsVisible(CRMuralInfo *pMural, GLboolean fIsVisible)
    39 {
    40     if (!fIsVisible == !pMural->fIsVisible)
    41         return;
    42 
    43     pMural->fIsVisible = fIsVisible;
    44 
    45     CRASSERT(pMural->screenId < cr_server.screenCount);
    46 
    47     if (fIsVisible)
    48     {
    49         ++cr_server.aWinVisibilityInfos[pMural->screenId].cVisibleWindows;
    50         cr_server.aWinVisibilityInfos[pMural->screenId].fVisibleChanged = 1;
    51     }
    52     else
    53     {
    54         --cr_server.aWinVisibilityInfos[pMural->screenId].cVisibleWindows;
    55         CRASSERT(cr_server.aWinVisibilityInfos[pMural->screenId].cVisibleWindows < UINT32_MAX/2);
    56         if (!cr_server.aWinVisibilityInfos[pMural->screenId].cVisibleWindows)
    57             cr_server.aWinVisibilityInfos[pMural->screenId].fVisibleChanged = 0;
    58     }
    59 
    60     crVBoxServerCheckVisibilityEvent(pMural->screenId);
    61 }
    62 
    63 void crServerWindowCheckIsVisible(CRMuralInfo *pMural)
    64 {
    65     GLboolean fIsVisible = crServerWindowCalcIsVisible(pMural);
    66 
    67     crServerWindowSetIsVisible(pMural, fIsVisible);
    68 }
    69 
    70 void crServerWindowSize(CRMuralInfo *pMural)
    71 {
    72     cr_server.head_spu->dispatch_table.WindowSize(pMural->spuWindow, pMural->width, pMural->height);
    73 
    74     crServerWindowCheckIsVisible(pMural);
    75 }
    76 
    77 void crServerWindowShow(CRMuralInfo *pMural)
    78 {
    79     cr_server.head_spu->dispatch_table.WindowShow(pMural->spuWindow,
    80             !!(pMural->fPresentMode & CR_SERVER_REDIR_F_DISPLAY) && pMural->bVisible);
    81 
    82     crServerWindowCheckIsVisible(pMural);
    83 }
    84 
    85 void crServerWindowVisibleRegion(CRMuralInfo *pMural)
    86 {
    87     uint32_t cRects;
    88     const RTRECT *pRects;
    89     int rc = CrVrScrCompositorRegionsGet(pMural->fRootVrOn ? &pMural->RootVrCompositor : &pMural->Compositor, &cRects, NULL, &pRects, NULL);
    90     if (RT_SUCCESS(rc))
    91     {
    92         cr_server.head_spu->dispatch_table.WindowVisibleRegion(pMural->spuWindow, cRects, (const GLint*)pRects);
    93 
    94         crServerWindowCheckIsVisible(pMural);
    95     }
    96     else
    97         crWarning("CrVrScrCompositorRegionsGet failed rc %d", rc);
    98 
    99 }
    100 
    101 void crServerWindowReparent(CRMuralInfo *pMural)
    102 {
    103     crServerVBoxCompositionDisableEnter(pMural);
    104 
    105     pMural->fHasParentWindow = !!cr_server.screen[pMural->screenId].winID;
    106 
    107     renderspuReparentWindow(pMural->spuWindow);
    108 
    109     crServerVBoxCompositionDisableLeave(pMural, GL_FALSE);
    110 }
    111 
    11215GLint SERVER_DISPATCH_APIENTRY
    11316crServerDispatchWindowCreate(const char *dpyName, GLint visBits)
     
    11619}
    11720
    118 static DECLCALLBACK(void) crServerMuralDefaultEntryReleasedCB(const struct VBOXVR_SCR_COMPOSITOR *pCompositor, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pReplacingEntry)
    119 {
    120     CR_DISPLAY_ENTRY *pDEntry = CR_DENTRY_FROM_CENTRY(pEntry);
    121     CrDpEntryCleanup(pDEntry);
    122 }
    123 
    124 GLint crServerMuralInit(CRMuralInfo *mural, const char *dpyName, GLint visBits, GLint preloadWinID, GLboolean fUseDefaultDEntry)
     21GLint crServerMuralInit(CRMuralInfo *mural, const char *dpyName, GLint visBits, GLint preloadWinID)
    12522{
    12623    CRMuralInfo *defaultMural;
     
    13229    crMemset(mural, 0, sizeof (*mural));
    13330
    134     CrVrScrCompositorInit(&mural->Compositor);
    135 
    136     if (cr_server.fRootVrOn)
    137     {
    138         CrVrScrCompositorInit(&mural->RootVrCompositor);
    139     }
    140 
    14131    /*
    14232     * Have first SPU make a new window.
     
    14434    spuWindow = cr_server.head_spu->dispatch_table.WindowCreate( dpyName, visBits );
    14535    if (spuWindow < 0) {
    146         CrVrScrCompositorClear(&mural->Compositor);
    147         if (cr_server.fRootVrOn)
    148             CrVrScrCompositorClear(&mural->RootVrCompositor);
    14936        return spuWindow;
    15037    }
     
    15239    /* get initial window size */
    15340    cr_server.head_spu->dispatch_table.GetChromiumParametervCR(GL_WINDOW_SIZE_CR, spuWindow, GL_INT, 2, dims);
    154 
    155     mural->fUseDefaultDEntry = fUseDefaultDEntry;
    156 
    157     if (fUseDefaultDEntry)
    158     {
    159         VBOXVR_TEXTURE Tex = {0};
    160         Tex.width = dims[0];
    161         Tex.height = dims[1];
    162         Tex.target = GL_TEXTURE_2D;
    163         Tex.hwid = 0;
    164 
    165         CrDpEntryInit(&mural->DefaultDEntry, &Tex, 0, crServerMuralDefaultEntryReleasedCB);
    166 
    167         mural->fRootVrOn = cr_server.fRootVrOn;
    168     }
    16941
    17042    defaultMural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, 0);
     
    17446    mural->width = dims[0];
    17547    mural->height = dims[1];
    176    
     48
    17749    mural->spuWindow = spuWindow;
    17850    mural->screenId = 0;
    17951    mural->fHasParentWindow = !!cr_server.screen[0].winID;
    18052    mural->bVisible = !cr_server.bWindowsInitiallyHidden;
    181     mural->fPresentMode = CR_SERVER_REDIR_F_NONE;
    18253
    18354    mural->cVisibleRects = 0;
     
    19768    CR_STATE_SHAREDOBJ_USAGE_INIT(mural);
    19869
    199     if (fUseDefaultDEntry)
    200     {
    201         RTRECT Rect;
    202         Rect.xLeft = 0;
    203         Rect.xRight = mural->width;
    204         Rect.yTop = 0;
    205         Rect.yBottom = mural->height;
    206         rc = CrVrScrCompositorEntryRegionsSet(&mural->Compositor, &mural->DefaultDEntry.CEntry, NULL, 1, &Rect, false, NULL);
    207         if (!RT_SUCCESS(rc))
    208         {
    209             crWarning("CrVrScrCompositorEntryRegionsSet failed, rc %d", rc);
    210             return -1;
    211         }
    212     }
    213 
    214     if (mural->fRootVrOn)
    215     {
    216         uint32_t cRects;
    217         const RTRECT *pRects;
    218         int rc = crServerMuralSynchRootVr(mural, NULL);
    219         if (RT_SUCCESS(rc))
    220         {
    221             rc = CrVrScrCompositorRegionsGet(&mural->RootVrCompositor, &cRects, NULL, &pRects, NULL);
    222             if (RT_SUCCESS(rc))
    223             {
    224                 if (cRects != 1
    225                         || pRects[0].xLeft != 0 || pRects[0].yTop != 0
    226                         || pRects[0].xRight != mural->width || pRects[0].yBottom != mural->height)
    227                 {
    228                     /* do visible rects only if they differ from the default */
    229                     crServerWindowVisibleRegion(mural);
    230                 }
    231             }
    232             else
    233             {
    234                 crWarning("CrVrScrCompositorRegionsGet failed, rc %d", rc);
    235             }
    236         }
    237     }
    238 
    23970    return windowID;
    24071}
    24172
    242 GLint
    243 crServerDispatchWindowCreateEx(const char *dpyName, GLint visBits, GLint preloadWinID)
     73GLint crServerDispatchWindowCreateEx(const char *dpyName, GLint visBits, GLint preloadWinID)
    24474{
    24575    CRMuralInfo *mural;
     
    24777
    24878    dpyName = "";
     79
     80    if (cr_server.fVisualBitsDefault)
     81        visBits = cr_server.fVisualBitsDefault;
    24982
    25083    if (cr_server.sharedWindows) {
     
    287120    }
    288121
    289     windowID = crServerMuralInit(mural, dpyName, visBits, preloadWinID, GL_TRUE);
     122    windowID = crServerMuralInit(mural, dpyName, visBits, preloadWinID);
    290123    if (windowID < 0)
    291124    {
     
    318151}
    319152
    320 static void crServerVBoxRootVrTranslateForMural(CRMuralInfo *mural)
    321 {
    322     int32_t dx = cr_server.RootVrCurPoint.x - mural->gX;
    323     int32_t dy = cr_server.RootVrCurPoint.y - mural->gY;
    324 
    325     cr_server.RootVrCurPoint.x = mural->gX;
    326     cr_server.RootVrCurPoint.y = mural->gY;
    327 
    328     VBoxVrListTranslate(&cr_server.RootVr, dx, dy);
    329 }
    330 
    331153static int crServerRemoveClientWindow(CRClient *pClient, GLint window)
    332154{
     
    347169void crServerMuralTerm(CRMuralInfo *mural)
    348170{
    349     crServerRedirMuralFBO(mural, CR_SERVER_REDIR_F_NONE);
     171        PCR_BLITTER pBlitter;
     172    crServerRedirMuralFBO(mural, false);
    350173    crServerDeleteMuralFBO(mural);
    351174
     
    364187    }
    365188
     189    pBlitter = crServerVBoxBlitterGetInitialized();
     190    if (pBlitter)
     191    {
     192        const CR_BLITTER_WINDOW * pWindow = CrBltMuralGetCurrentInfo(pBlitter);
     193        if (pWindow && pWindow->Base.id == mural->spuWindow)
     194        {
     195                CRMuralInfo *dummy = crServerGetDummyMural(mural->CreateInfo.visualBits);
     196                CR_BLITTER_WINDOW DummyInfo;
     197                CRASSERT(dummy);
     198                CrBltMuralSetCurrentInfo(pBlitter, &DummyInfo);
     199        }
     200    }
    366201
    367202    cr_server.head_spu->dispatch_table.WindowDestroy( mural->spuWindow );
     
    375210        crFree(mural->CreateInfo.pszDpyName);
    376211
    377     CrVrScrCompositorClear(&mural->Compositor);
    378 
    379     if (mural->fRootVrOn)
    380         CrVrScrCompositorClear(&mural->RootVrCompositor);
     212    crServerRedirMuralFbClear(mural);
    381213}
    382214
     
    480312}
    481313
    482 static DECLCALLBACK(VBOXVR_SCR_COMPOSITOR_ENTRY*) crServerMuralGetRootVrCEntry(VBOXVR_SCR_COMPOSITOR_ENTRY*pEntry, void *pvContext)
    483 {
    484     CR_DISPLAY_ENTRY *pDEntry = CR_DENTRY_FROM_CENTRY(pEntry);
    485     Assert(!CrVrScrCompositorEntryIsUsed(&pDEntry->RootVrCEntry));
    486     CrVrScrCompositorEntryInit(&pDEntry->RootVrCEntry, CrVrScrCompositorEntryTexGet(pEntry), NULL);
    487     CrVrScrCompositorEntryFlagsSet(&pDEntry->RootVrCEntry, CrVrScrCompositorEntryFlagsGet(pEntry));
    488     return &pDEntry->RootVrCEntry;
    489 }
    490 
    491 int crServerMuralSynchRootVr(CRMuralInfo *mural, bool *pfChanged)
    492 {
    493     int rc;
    494 
    495     crServerVBoxRootVrTranslateForMural(mural);
    496 
    497     /* ensure the rootvr compositor does not hold any data,
    498      * i.e. cleanup all rootvr entries data */
    499     CrVrScrCompositorClear(&mural->RootVrCompositor);
    500 
    501     rc = CrVrScrCompositorIntersectedList(&mural->Compositor, &cr_server.RootVr, &mural->RootVrCompositor, crServerMuralGetRootVrCEntry, NULL, pfChanged);
    502     if (!RT_SUCCESS(rc))
    503     {
    504         crWarning("CrVrScrCompositorIntersectedList failed, rc %d", rc);
    505         return rc;
    506     }
    507 
    508     return VINF_SUCCESS;
    509 }
    510 
    511314GLboolean crServerMuralSize(CRMuralInfo *mural, GLint width, GLint height)
    512315{
    513     RTRECT Rect;
    514     VBOXVR_TEXTURE Tex;
    515     int rc = VINF_SUCCESS;
    516     Tex.width = width;
    517     Tex.height = height;
    518     Tex.target = GL_TEXTURE_2D;
    519     Tex.hwid = 0;
    520 
    521316    if (mural->width == width && mural->height == height)
    522317        return GL_FALSE;
    523318
    524 
    525     /* since we're going to change the current compositor & the window we need to avoid
    526      * renderspu fron dealing with inconsistent data, i.e. modified compositor and
    527      * still unmodified window.
    528      * So what we do is:
    529      * 1. tell renderspu to stop using the current compositor -> renderspu would do necessary synchronization with its redraw thread to ensure compositor is no longer used
    530      * 2. do necessary modifications
    531      * 3. (so far not needed for resize, but in case it is in the future) re-set the compositor */
    532 
    533     /* 1. tell renderspu to stop using the current compositor (see above comment) */
    534     crServerVBoxCompositionDisableEnter(mural);
    535 
    536     /* 2. do necessary modifications (see above comment) */
    537     /* NOTE: we can do it even if mural->fPresentMode == CR_SERVER_REDIR_F_NONE to make sure the compositor data is always up to date */
    538     /* the compositor lock is not needed actually since we have prevented renderspu from using the compositor */
    539     /* CrVrScrCompositorLock(&mural->Compositor); */
    540     if (mural->fUseDefaultDEntry)
    541     {
    542         if (!mural->bReceivedRects)
    543         {
    544             rc = CrVrScrCompositorEntryRemove(&mural->Compositor, &mural->DefaultDEntry.CEntry);
    545             if (!RT_SUCCESS(rc))
    546             {
    547                 crWarning("CrVrScrCompositorEntryRemove failed, rc %d", rc);
    548                 goto end;
    549             }
    550             CrVrScrCompositorEntryInit(&mural->DefaultDEntry.CEntry, &Tex, NULL);
    551             /* initially set regions to all visible since this is what some guest assume
    552              * and will not post any more visible regions command */
    553             Rect.xLeft = 0;
    554             Rect.xRight = width;
    555             Rect.yTop = 0;
    556             Rect.yBottom = height;
    557             rc = CrVrScrCompositorEntryRegionsSet(&mural->Compositor, &mural->DefaultDEntry.CEntry, NULL, 1, &Rect, false, NULL);
    558             if (!RT_SUCCESS(rc))
    559             {
    560                 crWarning("CrVrScrCompositorEntryRegionsSet failed, rc %d", rc);
    561                 goto end;
    562             }
    563         }
    564         else
    565         {
    566             rc = CrVrScrCompositorEntryTexUpdate(&mural->Compositor, &mural->DefaultDEntry.CEntry, &Tex);
    567             if (!RT_SUCCESS(rc))
    568             {
    569                 crWarning("CrVrScrCompositorEntryTexUpdate failed, rc %d", rc);
    570                 goto end;
    571             }
    572         }
    573     }
    574     else
    575     {
    576         CrVrScrCompositorClear(&mural->Compositor);
    577     }
    578 
    579     /* CrVrScrCompositorUnlock(&mural->Compositor); */
    580319    mural->width = width;
    581320    mural->height = height;
    582321
    583     mural->fDataPresented = GL_FALSE;
    584 
    585     if (cr_server.curClient && cr_server.curClient->currentMural == mural)
     322    cr_server.head_spu->dispatch_table.WindowSize(mural->spuWindow, mural->width, mural->height);
     323
     324    if (cr_server.curClient && cr_server.curClient->currentMural == mural
     325            && !mural->fRedirected)
    586326    {
    587327        crStateGetCurrent()->buffer.width = mural->width;
     
    589329    }
    590330
    591     if (mural->fRootVrOn)
    592     {
    593         rc = crServerMuralSynchRootVr(mural, NULL);
    594         if (!RT_SUCCESS(rc))
    595         {
    596             crWarning("crServerMuralSynchRootVr failed, rc %d", rc);
    597             goto end;
    598         }
    599     }
    600 
    601331    crServerCheckMuralGeometry(mural);
    602 
    603     crServerWindowSize(mural);
    604 
    605     crServerWindowVisibleRegion(mural);
    606 
    607     crServerDEntryAllResized(mural);
    608 end:
    609     /* 3. (so far not needed for resize, but in case it is in the future) re-set the compositor (see above comment) */
    610     /* uncomment when needed */
    611     /* NOTE: !!! we have mural->fHasPresentationData set to GL_FALSE above, so crServerVBoxCompositionReenable will have no effect in any way
    612 
    613     */
    614     crServerVBoxCompositionDisableLeave(mural, GL_FALSE);
    615332
    616333    return GL_TRUE;
     
    639356}
    640357
    641 void crServerMuralPosition(CRMuralInfo *mural, GLint x, GLint y, GLboolean fSkipCheckGeometry)
    642 {
    643     GLboolean fForcePresent = GL_FALSE;
    644     /*  crDebug("CRServer: Window %d pos %d, %d", window, x, y);*/
    645 
    646 //    if (mural->gX != x || mural->gY != y)
    647     {
    648         /* since we're going to change the current compositor & the window we need to avoid
    649          * renderspu fron dealing with inconsistent data, i.e. modified compositor and
    650          * still unmodified window.
    651          * So what we do is:
    652          * 1. tell renderspu to stop using the current compositor -> renderspu would do necessary synchronization with its redraw thread to ensure compositor is no longer used
    653          * 2. do necessary modifications
    654          * 3. re-set the compositor */
    655 
    656         /* 1. tell renderspu to stop using the current compositor (see above comment) */
    657         crServerVBoxCompositionDisableEnter(mural);
    658 
    659         /* 2. do necessary modifications (see above comment) */
    660         /* NOTE: we can do it even if !(mural->fPresentMode & CR_SERVER_REDIR_F_DISPLAY) to make sure the compositor data is always up to date */
    661 
    662         if (mural->gX != x || mural->gY != y)
    663         {
    664             if (mural->fRootVrOn)
    665             {
    666                 fForcePresent = crServerVBoxCompositionPresentNeeded(mural);
    667             }
    668 
    669             mural->gX = x;
    670             mural->gY = y;
    671 
    672             /* no need to set position because the position is relative to window */
    673             /*CrVrScrCompositorEntryPosSet(&mural->Compositor, &mural->CEntry, &Pos);*/
    674 
    675             if (mural->fRootVrOn)
    676             {
    677                 int rc = crServerMuralSynchRootVr(mural, NULL);
    678                 if (RT_SUCCESS(rc))
    679                 {
    680                     crServerWindowVisibleRegion(mural);
    681                 }
    682                 else
    683                 {
    684                     crWarning("crServerMuralSynchRootVr failed, rc %d", rc);
    685                 }
    686             }
    687         }
    688 
    689         if (!fSkipCheckGeometry)
    690             crServerCheckMuralGeometry(mural);
    691 
    692         crServerDEntryAllMoved(mural);
    693 
    694         /* 3. re-set the compositor (see above comment) */
    695         crServerVBoxCompositionDisableLeave(mural, fForcePresent);
    696     }
     358void crServerMuralPosition(CRMuralInfo *mural, GLint x, GLint y)
     359{
     360    if (mural->gX == x && mural->gY == y)
     361        return;
     362
     363    mural->gX = x;
     364    mural->gY = y;
     365
     366    crServerCheckMuralGeometry(mural);
    697367}
    698368
     
    707377         return;
    708378    }
    709     crServerMuralPosition(mural, x, y, GL_FALSE);
     379    crServerMuralPosition(mural, x, y);
    710380}
    711381
    712382void crServerMuralVisibleRegion( CRMuralInfo *mural, GLint cRects, const GLint *pRects )
    713383{
    714     GLboolean fForcePresent = crServerVBoxCompositionPresentNeeded(mural);
    715     bool fRegionsChanged = false;
    716     int rc = VINF_SUCCESS;
    717 
    718     /* since we're going to change the current compositor & the window we need to avoid
    719      * renderspu fron dealing with inconsistent data, i.e. modified compositor and
    720      * still unmodified window.
    721      * So what we do is:
    722      * 1. tell renderspu to stop using the current compositor -> renderspu would do necessary synchronization with its redraw thread to ensure compositor is no longer used
    723      * 2. do necessary modifications
    724      * 3. re-set the compositor */
    725 
    726     /* 1. tell renderspu to stop using the current compositor (see above comment) */
    727     crServerVBoxCompositionDisableEnter(mural);
    728 
    729     /* 2. do necessary modifications (see above comment) */
    730384    if (mural->pVisibleRects)
    731385    {
     
    746400    }
    747401
    748     Assert(mural->fUseDefaultDEntry);
    749     /* NOTE: we can do it even if !(mural->fPresentMode & CR_SERVER_REDIR_F_DISPLAY) to make sure the compositor data is always up to date */
    750     /* the compositor lock is not needed actually since we have prevented renderspu from using the compositor */
    751     /* CrVrScrCompositorLock(&mural->Compositor); */
    752     rc = CrVrScrCompositorEntryRegionsSet(&mural->Compositor, &mural->DefaultDEntry.CEntry, NULL, cRects, (const RTRECT *)pRects, false, &fRegionsChanged);
    753     /*CrVrScrCompositorUnlock(&mural->Compositor);*/
    754     if (!RT_SUCCESS(rc))
    755     {
    756         crWarning("CrVrScrCompositorEntryRegionsSet failed, rc %d", rc);
    757         goto end;
    758     }
    759 
    760     if (fRegionsChanged)
    761     {
    762         if (mural->fRootVrOn)
    763         {
    764             rc = crServerMuralSynchRootVr(mural, NULL);
    765             if (!RT_SUCCESS(rc))
    766             {
    767                 crWarning("crServerMuralSynchRootVr failed, rc %d", rc);
    768                 goto end;
    769             }
    770         }
    771 
    772         crServerWindowVisibleRegion(mural);
    773 
    774         crServerDEntryAllVibleRegions(mural);
    775     }
    776 end:
    777     /* 3. re-set the compositor (see above comment) */
    778     crServerVBoxCompositionDisableLeave(mural, fForcePresent);
     402    crServerCheckMuralGeometry(mural);
    779403}
    780404
     
    795419void crServerMuralShow( CRMuralInfo *mural, GLint state )
    796420{
    797     mural->bVisible = !!state;
    798 
    799     if (mural->fPresentMode & CR_SERVER_REDIR_F_DISPLAY)
    800         crServerWindowShow(mural);
     421    if (!mural->bVisible == !state)
     422        return;
     423
     424    crServerCheckMuralGeometry(mural);
    801425}
    802426
  • trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu.c

    r50041 r50095  
    766766
    767767static void RENDER_APIENTRY
    768 renderspuVBoxPresentComposition( GLint win, struct VBOXVR_SCR_COMPOSITOR * pCompositor, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry )
     768renderspuVBoxPresentComposition( GLint win, const struct VBOXVR_SCR_COMPOSITOR * pCompositor, const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry )
    769769{
    770770    WindowInfo *window;
     
    789789}
    790790
    791 void renderspuVBoxCompositorBlitStretched ( struct VBOXVR_SCR_COMPOSITOR * pCompositor, PCR_BLITTER pBlitter, GLfloat scaleX, GLfloat scaleY)
    792 {
    793     VBOXVR_SCR_COMPOSITOR_ITERATOR CIter;
    794     PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry;
    795     CrVrScrCompositorIterInit(pCompositor, &CIter);
    796     while ((pEntry = CrVrScrCompositorIterNext(&CIter)) != NULL)
     791void renderspuVBoxCompositorBlitStretched ( const struct VBOXVR_SCR_COMPOSITOR * pCompositor, PCR_BLITTER pBlitter, GLfloat scaleX, GLfloat scaleY)
     792{
     793    VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR CIter;
     794    const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry;
     795    CrVrScrCompositorConstIterInit(pCompositor, &CIter);
     796    while ((pEntry = CrVrScrCompositorConstIterNext(&CIter)) != NULL)
    797797    {
    798798        uint32_t cRegions;
     
    806806            {
    807807                RTRECT DstRect;
     808                const CR_TEXDATA *pTexData = CrVrScrCompositorEntryTexGet(pEntry);
    808809                DstRect.xLeft = paDstRegions[i].xLeft * scaleX;
    809810                DstRect.yTop = paDstRegions[i].yTop * scaleY;
    810811                DstRect.xRight = paDstRegions[i].xRight * scaleX;
    811812                DstRect.yBottom = paDstRegions[i].yBottom * scaleY;
    812                 CrBltBlitTexMural(pBlitter, true, &pEntry->Tex, &paSrcRegions[i], &DstRect, 1, fFlags);
     813                CrBltBlitTexMural(pBlitter, true, CrTdTexGet(pTexData), &paSrcRegions[i], &DstRect, 1, fFlags);
    813814            }
    814815        }
     
    820821}
    821822
    822 void renderspuVBoxCompositorBlit ( struct VBOXVR_SCR_COMPOSITOR * pCompositor, PCR_BLITTER pBlitter)
    823 {
    824     VBOXVR_SCR_COMPOSITOR_ITERATOR CIter;
    825     PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry;
    826     CrVrScrCompositorIterInit(pCompositor, &CIter);
    827     while ((pEntry = CrVrScrCompositorIterNext(&CIter)) != NULL)
     823void renderspuVBoxCompositorBlit ( const struct VBOXVR_SCR_COMPOSITOR * pCompositor, PCR_BLITTER pBlitter)
     824{
     825    VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR CIter;
     826    const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry;
     827    CrVrScrCompositorConstIterInit(pCompositor, &CIter);
     828    while ((pEntry = CrVrScrCompositorConstIterNext(&CIter)) != NULL)
    828829    {
    829830        uint32_t cRegions;
     
    833834        if (RT_SUCCESS(rc))
    834835        {
    835             CrBltBlitTexMural(pBlitter, true, &pEntry->Tex, paSrcRegions, paDstRegions, cRegions, fFlags);
     836            const CR_TEXDATA *pTexData = CrVrScrCompositorEntryTexGet(pEntry);
     837            CrBltBlitTexMural(pBlitter, true, CrTdTexGet(pTexData), paSrcRegions, paDstRegions, cRegions, fFlags);
    836838        }
    837839        else
     
    850852    {
    851853        const CR_BLITTER_WINDOW * pBltInfo = CrBltMuralGetCurrentInfo(window->pBlitter);
    852         if (pBltInfo->Base.id == window->BltInfo.Base.id)
    853         {
    854             CrBltMuralSetCurrent(window->pBlitter, NULL);
     854        if (pBltInfo && pBltInfo->Base.id == window->BltInfo.Base.id)
     855        {
     856            CrBltMuralSetCurrentInfo(window->pBlitter, NULL);
    855857        }
    856858    }
     
    858860    {
    859861        CRASSERT(CrBltMuralGetCurrentInfo(window->pBlitter)->Base.id == window->BltInfo.Base.id);
    860         CrBltMuralSetCurrent(window->pBlitter, NULL);
     862        CrBltMuralSetCurrentInfo(window->pBlitter, NULL);
    861863        CrBltTerm(window->pBlitter);
    862864    }
     
    895897            }
    896898
    897             rc = CrBltInit(pBlitter, &pDefaultCtxInfo->BltInfo, true, true, NULL, render_spu.blitterDispatch);
     899            rc = CrBltInit(pBlitter, &pDefaultCtxInfo->BltInfo, true, true, NULL, &render_spu.blitterDispatch);
    898900
    899901            /* we can release it either way, since it will be retained when used as a shared context */
     
    920922    }
    921923
    922     CrBltMuralSetCurrent(pBlitter, &window->BltInfo);
     924    CrBltMuralSetCurrentInfo(pBlitter, &window->BltInfo);
    923925    return pBlitter;
    924926}
     
    927929{
    928930    int rc;
    929     PCR_BLITTER_CONTEXT pCtxInfo = NULL;
    930     PCR_BLITTER_WINDOW pWindowInfo = NULL;
    931     GET_CONTEXT(pCtx);
    932 
    933     if (pCtx)
    934     {
    935         if (pCtx->currentWindow)
    936         {
    937             pCtxInfo = &pCtx->BltInfo;
    938             pWindowInfo =  &pCtx->currentWindow->BltInfo;
    939         }
    940     }
    941931
    942932    CrBltSetMakeCurrentUserData(pBlitter, i32MakeCurrentUserData);
    943933
    944     rc = CrBltEnter(pBlitter, pCtxInfo, pWindowInfo);
     934    rc = CrBltEnter(pBlitter);
    945935    if (!RT_SUCCESS(rc))
    946936    {
     
    969959    if (!window->pBlitter)
    970960    {
    971         struct VBOXVR_SCR_COMPOSITOR * pTmpCompositor;
     961        const struct VBOXVR_SCR_COMPOSITOR * pTmpCompositor;
    972962        /* just use compositor lock to synchronize */
    973963        pTmpCompositor = renderspuVBoxCompositorAcquire(window);
     
    1006996}
    1007997
    1008 void renderspuVBoxPresentCompositionGeneric( WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR * pCompositor, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry, int32_t i32MakeCurrentUserData )
     998void renderspuVBoxPresentCompositionGeneric( WindowInfo *window, const struct VBOXVR_SCR_COMPOSITOR * pCompositor, const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry, int32_t i32MakeCurrentUserData )
    1009999{
    10101000    PCR_BLITTER pBlitter = renderspuVBoxPresentBlitterGetAndEnter(window, i32MakeCurrentUserData);
     
    10191009}
    10201010
    1021 void renderspuVBoxCompositorSet( WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR * pCompositor)
     1011void renderspuVBoxCompositorSet( WindowInfo *window, const struct VBOXVR_SCR_COMPOSITOR * pCompositor)
    10221012{
    10231013    int rc;
     
    10561046}
    10571047
    1058 struct VBOXVR_SCR_COMPOSITOR * renderspuVBoxCompositorAcquire( WindowInfo *window)
     1048const struct VBOXVR_SCR_COMPOSITOR * renderspuVBoxCompositorAcquire( WindowInfo *window)
    10591049{
    10601050    int rc = RTCritSectEnter(&window->CompositorLock);
    10611051    if (RT_SUCCESS(rc))
    10621052    {
    1063         VBOXVR_SCR_COMPOSITOR * pCompositor = window->pCompositor;
     1053        const VBOXVR_SCR_COMPOSITOR * pCompositor = window->pCompositor;
    10641054        if (pCompositor)
    10651055            return pCompositor;
     
    10891079}
    10901080
    1091 int renderspuVBoxCompositorTryAcquire(WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR **ppCompositor)
     1081int renderspuVBoxCompositorTryAcquire(WindowInfo *window, const struct VBOXVR_SCR_COMPOSITOR **ppCompositor)
    10921082{
    10931083    int rc = RTCritSectTryEnter(&window->CompositorLock);
     
    15511541        break;
    15521542
     1543    case GL_HH_SET_TMPCTX_MAKE_CURRENT:
     1544        if (type == GL_BYTE && count == sizeof (void*))
     1545                memcpy(&render_spu.blitterDispatch.MakeCurrent, values, count);
     1546        else
     1547                crWarning("unexpected type(%#x) - count(%d) pair", type, count);
     1548        break;
     1549
    15531550    default:
    15541551#if 0
  • trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu.h

    r50041 r50095  
    2929#include "cr_server.h"
    3030#include "cr_blitter.h"
     31#include "cr_compositor.h"
    3132
    3233#include <iprt/cdefs.h>
     
    103104    char *title;
    104105
    105     PVBOXVR_SCR_COMPOSITOR pCompositor;
     106    const VBOXVR_SCR_COMPOSITOR *pCompositor;
    106107    /* the composotor lock is used to synchronize the current compositor access,
    107108     * i.e. the compositor can be accessed by a gui refraw thread,
     
    285286    CRConnection **swap_conns;
    286287
    287     SPUDispatchTable *blitterDispatch;
     288    SPUDispatchTable blitterDispatch;
    288289    CRHashTable *blitterTable;
    289290
     
    406407extern void renderspu_SystemSwapBuffers( WindowInfo *window, GLint flags );
    407408extern void renderspu_SystemReparentWindow(WindowInfo *window);
    408 extern void renderspu_SystemVBoxPresentComposition( WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry );
     409extern void renderspu_SystemVBoxPresentComposition( WindowInfo *window, const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry );
    409410uint32_t renderspu_SystemPostprocessFunctions(SPUNamedFunctionTable *aFunctions, uint32_t cFunctions, uint32_t cTable);
    410411extern void renderspu_GCWindow(void);
    411412extern int renderspuCreateFunctions( SPUNamedFunctionTable table[] );
    412 extern void renderspuVBoxCompositorSet( WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR * pCompositor);
     413extern void renderspuVBoxCompositorSet( WindowInfo *window, const struct VBOXVR_SCR_COMPOSITOR * pCompositor);
    413414extern void renderspuVBoxCompositorClearAll();
    414415extern int renderspuVBoxCompositorLock(WindowInfo *window);
    415416extern int renderspuVBoxCompositorUnlock(WindowInfo *window);
    416 extern struct VBOXVR_SCR_COMPOSITOR * renderspuVBoxCompositorAcquire( WindowInfo *window);
    417 extern int renderspuVBoxCompositorTryAcquire(WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR **ppCompositor);
     417extern const struct VBOXVR_SCR_COMPOSITOR * renderspuVBoxCompositorAcquire( WindowInfo *window);
     418extern int renderspuVBoxCompositorTryAcquire(WindowInfo *window, const struct VBOXVR_SCR_COMPOSITOR **ppCompositor);
    418419extern void renderspuVBoxCompositorRelease( WindowInfo *window);
    419 extern void renderspuVBoxPresentCompositionGeneric( WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR * pCompositor, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry, int32_t i32MakeCurrentUserData );
     420extern void renderspuVBoxPresentCompositionGeneric( WindowInfo *window, const struct VBOXVR_SCR_COMPOSITOR * pCompositor, const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry, int32_t i32MakeCurrentUserData );
    420421extern PCR_BLITTER renderspuVBoxPresentBlitterGet( WindowInfo *window );
    421422void renderspuVBoxPresentBlitterCleanup( WindowInfo *window );
     
    429430extern GLboolean renderspuWindowInitWithVisual( WindowInfo *window, VisualInfo *visual, GLboolean showIt, GLint id );
    430431extern GLboolean renderspuInitVisual(VisualInfo *pVisInfo, const char *displayName, GLbitfield visAttribs);
    431 extern void renderspuVBoxCompositorBlit ( struct VBOXVR_SCR_COMPOSITOR * pCompositor, PCR_BLITTER pBlitter);
    432 extern void renderspuVBoxCompositorBlitStretched ( struct VBOXVR_SCR_COMPOSITOR * pCompositor, PCR_BLITTER pBlitter, GLfloat scaleX, GLfloat scaleY);
     432extern void renderspuVBoxCompositorBlit ( const struct VBOXVR_SCR_COMPOSITOR * pCompositor, PCR_BLITTER pBlitter);
     433extern void renderspuVBoxCompositorBlitStretched ( const struct VBOXVR_SCR_COMPOSITOR * pCompositor, PCR_BLITTER pBlitter, GLfloat scaleX, GLfloat scaleY);
    433434extern GLint renderspuCreateContextEx(const char *dpyName, GLint visBits, GLint id, GLint shareCtx);
    434435extern GLint renderspuWindowCreateEx( const char *dpyName, GLint visBits, GLint id );
  • trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_agl.c

    r48291 r50095  
    608608}
    609609
    610 void renderspu_SystemVBoxPresentComposition( WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR * pCompositor, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry )
     610void renderspu_SystemVBoxPresentComposition( WindowInfo *window, const struct VBOXVR_SCR_COMPOSITOR * pCompositor, const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry )
    611611{
    612612    renderspuVBoxPresentCompositionGeneric(window, pCompositor, pChangedEntry, 0);
  • trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa.c

    r50041 r50095  
    155155}
    156156
    157 void renderspu_SystemVBoxPresentComposition( WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry )
     157void renderspu_SystemVBoxPresentComposition( WindowInfo *window, const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry )
    158158{
    159159    cocoaViewPresentComposition(window->window, pChangedEntry);
     
    271271    if (!CrGlslIsInited(&render_spu.GlobalShaders))
    272272    {
    273         CrGlslInit(&render_spu.GlobalShaders, render_spu.blitterDispatch);
     273        CrGlslInit(&render_spu.GlobalShaders, &render_spu.blitterDispatch);
    274274    }
    275275
  • trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.h

    r45132 r50095  
    2323#include <OpenGL/OpenGL.h>
    2424#include <cr_vreg.h>
     25#include <cr_compositor.h>
     26
    2527
    2628RT_C_DECLS_BEGIN
     
    4749void cocoaViewMakeCurrentContext(NativeNSViewRef pView, NativeNSOpenGLContextRef pCtx);
    4850void cocoaViewSetVisibleRegion(NativeNSViewRef pView, GLint cRects, const GLint* paRects);
    49 void cocoaViewPresentComposition(NativeNSViewRef pView, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry);
     51void cocoaViewPresentComposition(NativeNSViewRef pView, const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry);
    5052
    5153RT_C_DECLS_END
  • trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.m

    r49868 r50095  
    373373- (void)vboxTryDraw;
    374374- (void)vboxTryDrawUI;
    375 - (void)vboxPresent:(PVBOXVR_SCR_COMPOSITOR)pCompositor;
    376 - (void)vboxPresentCS:(PVBOXVR_SCR_COMPOSITOR)pCompositor;
    377 - (void)vboxPresentToDockTileCS:(PVBOXVR_SCR_COMPOSITOR)pCompositor;
    378 - (void)vboxPresentToViewCS:(PVBOXVR_SCR_COMPOSITOR)pCompositor;
    379 - (void)presentComposition:(PVBOXVR_SCR_COMPOSITOR_ENTRY)pChangedEntry;
     375- (void)vboxPresent:(const VBOXVR_SCR_COMPOSITOR*)pCompositor;
     376- (void)vboxPresentCS:(const VBOXVR_SCR_COMPOSITOR*)pCompositor;
     377- (void)vboxPresentToDockTileCS:(const VBOXVR_SCR_COMPOSITOR*)pCompositor;
     378- (void)vboxPresentToViewCS:(const VBOXVR_SCR_COMPOSITOR*)pCompositor;
     379- (void)presentComposition:(const VBOXVR_SCR_COMPOSITOR_ENTRY*)pChangedEntry;
    380380- (void)vboxBlitterSyncWindow;
    381381
     
    790790    [self deleteDockTile];
    791791   
    792     if (m_pGLCtx)
    793     {
    794         if ([m_pGLCtx view] == self)
    795             [m_pGLCtx clearDrawable];
    796 
    797         m_pGLCtx = nil;
    798     }
     792    [self setGLCtx:nil];
     793   
    799794    if (m_pSharedGLCtx)
    800795    {
     
    808803        CrBltTerm(m_pBlitter);
    809804       
     805        RTMemFree(m_pBlitter);
     806       
    810807        m_pBlitter = nil;
    811808    }
     
    836833    /* ensure the context drawable is cleared to avoid holding a reference to inexistent view */
    837834    if (m_pGLCtx)
     835    {
    838836        [m_pGLCtx clearDrawable];
     837        [m_pGLCtx release];
     838        /*[m_pGLCtx performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:NO];*/
     839    }
    839840
    840841    m_pGLCtx = pCtx;
     842    if (pCtx)
     843        [pCtx retain];
    841844}
    842845
     
    11131116    if ([self lockFocusIfCanDraw])
    11141117    {
    1115         VBOXVR_SCR_COMPOSITOR *pCompositor = NULL;
     1118        const const VBOXVR_SCR_COMPOSITOR *pCompositor = NULL;
    11161119        if (!m_pSharedGLCtx)
    11171120            {
     
    11231126                if (m_pBlitter)
    11241127                {
    1125                     int rc = CrBltInit(m_pBlitter, NULL, false, false, &render_spu.GlobalShaders, render_spu.blitterDispatch);
     1128                    int rc = CrBltInit(m_pBlitter, NULL, false, false, &render_spu.GlobalShaders, &render_spu.blitterDispatch);
    11261129                    if (RT_SUCCESS(rc))
    11271130                    {
     
    12181221             * while here we do a reverse order: acquire compositor lock being in gui thread.
    12191222             * this is why we do only try acquire and re-submit repaint event if compositor lock is busy */
    1220             VBOXVR_SCR_COMPOSITOR *pCompositor = NULL;
     1223            const VBOXVR_SCR_COMPOSITOR *pCompositor = NULL;
    12211224            int rc = renderspuVBoxCompositorTryAcquire(m_pWinInfo, &pCompositor);
    12221225            if (RT_SUCCESS(rc))
     
    12281231            else if (rc == VERR_SEM_BUSY)
    12291232            {
     1233                Assert(!pCompositor);
    12301234                /* re-issue to the gui thread */
    12311235# ifdef DEBUG_misha
     
    12341238                [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(vboxTryDrawUI) userInfo:nil repeats:NO];
    12351239            }
    1236             else
     1240            else if (rc != VERR_INVALID_STATE) /* VERR_INVALID_STATE means no compositor, which is ok */
    12371241            {
     1242                Assert(!pCompositor);
    12381243                /* this is somewhat we do not expect */
    12391244                DEBUG_WARN(("renderspuVBoxCompositorTryAcquire failed rc %d", rc));
    12401245            }
    12411246#else
    1242                 VBOXVR_SCR_COMPOSITOR *pCompositor = renderspuVBoxCompositorAcquire(m_pWinInfo);
     1247                const VBOXVR_SCR_COMPOSITOR *pCompositor = renderspuVBoxCompositorAcquire(m_pWinInfo);
    12431248                if (pCompositor)
    12441249                {
     
    12611266}
    12621267
    1263 - (void)vboxPresent:(PVBOXVR_SCR_COMPOSITOR)pCompositor
     1268- (void)vboxPresent:(const VBOXVR_SCR_COMPOSITOR*)pCompositor
    12641269{
    12651270    VBOX_CR_RENDER_CTX_INFO CtxInfo;   
     
    12851290}
    12861291
    1287 - (void)vboxPresentCS:(PVBOXVR_SCR_COMPOSITOR)pCompositor
     1292- (void)vboxPresentCS:(const VBOXVR_SCR_COMPOSITOR*)pCompositor
    12881293{
    12891294        {
     
    13381343}
    13391344
    1340 - (void)vboxPresentToViewCS:(PVBOXVR_SCR_COMPOSITOR)pCompositor
     1345- (void)vboxPresentToViewCS:(const VBOXVR_SCR_COMPOSITOR*)pCompositor
    13411346{
    13421347    NSRect r = [self frame];
     
    13451350
    13461351#if 1 /* Set to 0 to see the docktile instead of the real output */
    1347     VBOXVR_SCR_COMPOSITOR_ITERATOR CIter;
    1348     PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry;
     1352    VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR CIter;
     1353    const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry;
    13491354       
    1350     CrVrScrCompositorIterInit(pCompositor, &CIter);
     1355    CrVrScrCompositorConstIterInit(pCompositor, &CIter);
    13511356       
    13521357    glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
     
    13581363    CrVrScrCompositorGetStretching(pCompositor, &xStretch, &yStretch);
    13591364       
    1360     while ((pEntry = CrVrScrCompositorIterNext(&CIter)) != NULL)
     1365    while ((pEntry = CrVrScrCompositorConstIterNext(&CIter)) != NULL)
    13611366    {
    13621367        uint32_t cRegions;
     
    13671372        {
    13681373            uint32_t i;
    1369             int rc = CrBltEnter(m_pBlitter, NULL, NULL);
     1374            int rc = CrBltEnter(m_pBlitter);
    13701375            if (RT_SUCCESS(rc))
    13711376            {                   
     
    13741379                    const RTRECT * pSrcRect = &paSrcRegions[i];
    13751380                    const RTRECT * pDstRect = &paDstRegions[i];
    1376                     RTRECT SrcRect, DstRect, RestrictSrcRect, RestrictDstRect;
    1377                    
     1381                    RTRECT DstRect, RestrictDstRect;
     1382                    RTRECT SrcRect, RestrictSrcRect;
     1383
    13781384                    vboxNSRectToRect(&m_RootRect, &RestrictDstRect);
    13791385                    VBoxRectIntersected(&RestrictDstRect, pDstRect, &DstRect);
     
    13831389
    13841390                    VBoxRectTranslate(&DstRect, -RestrictDstRect.xLeft, -RestrictDstRect.yTop);
    1385                        
     1391
    13861392                    vboxNSRectToRectUnstretched(&m_RootRect, &RestrictSrcRect, xStretch, yStretch);
     1393                    VBoxRectTranslate(&RestrictSrcRect, -CrVrScrCompositorEntryRectGet(pEntry)->xLeft, -CrVrScrCompositorEntryRectGet(pEntry)->yTop);
    13871394                    VBoxRectIntersected(&RestrictSrcRect, pSrcRect, &SrcRect);
    13881395                   
     
    13931400                    pDstRect = &DstRect;
    13941401                   
    1395                     CrBltBlitTexMural(m_pBlitter, true, &pEntry->Tex, pSrcRect, pDstRect, 1, fFlags | CRBLT_F_NOALPHA);
     1402                    const CR_TEXDATA *pTexData = CrVrScrCompositorEntryTexGet(pEntry);
     1403                   
     1404                    CrBltBlitTexMural(m_pBlitter, true, CrTdTexGet(pTexData), pSrcRect, pDstRect, 1, fFlags | CRBLT_F_NOALPHA);
    13961405                }
    13971406                CrBltLeave(m_pBlitter);
     
    14161425}
    14171426
    1418 - (void)presentComposition:(PVBOXVR_SCR_COMPOSITOR_ENTRY)pChangedEntry
     1427- (void)presentComposition:(const VBOXVR_SCR_COMPOSITOR_ENTRY*)pChangedEntry
    14191428{
    14201429    [self vboxTryDraw];
     
    14381447    Assert(WinInfo.height = m_RootRect.size.height);
    14391448
    1440     /*CrBltMuralSetCurrent(m_pBlitter, NULL);*/
    1441    
    1442     CrBltMuralSetCurrent(m_pBlitter, &WinInfo);
     1449    /*CrBltMuralSetCurrentInfo(m_pBlitter, NULL);*/
     1450   
     1451    CrBltMuralSetCurrentInfo(m_pBlitter, &WinInfo);
    14431452    CrBltCheckUpdateViewport(m_pBlitter);
    14441453}
     
    14471456static int g_cVBoxTgaCtr = 0;
    14481457#endif
    1449 - (void)vboxPresentToDockTileCS:(PVBOXVR_SCR_COMPOSITOR)pCompositor
     1458- (void)vboxPresentToDockTileCS:(const VBOXVR_SCR_COMPOSITOR*)pCompositor
    14501459{
    14511460    NSRect r        = [self frame];
     
    14601469         * heavy performance wise. */
    14611470        uint64_t uiNewTime = RTTimeMilliTS();
    1462         VBOXVR_SCR_COMPOSITOR_ITERATOR CIter;
    1463         PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry;
     1471        VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR CIter;
     1472        const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry;
    14641473       
    14651474        if (uiNewTime - m_uiDockUpdateTime > 200)
     
    14921501            CrVrScrCompositorGetStretching(pCompositor, &xStretch, &yStretch);
    14931502           
    1494             CrVrScrCompositorIterInit(pCompositor, &CIter);
    1495             while ((pEntry = CrVrScrCompositorIterNext(&CIter)) != NULL)
     1503            CrVrScrCompositorConstIterInit(pCompositor, &CIter);
     1504            while ((pEntry = CrVrScrCompositorConstIterNext(&CIter)) != NULL)
    14961505            {
    14971506                uint32_t cRegions;
     
    15021511                {
    15031512                    uint32_t i;
    1504                     int rc = CrBltEnter(m_pBlitter, NULL, NULL);
     1513                    int rc = CrBltEnter(m_pBlitter);
    15051514                    if (RT_SUCCESS(rc))
    15061515                    {                   
     
    15221531                       
    15231532                            vboxNSRectToRectUnstretched(&m_RootRect, &RestrictSrcRect, xStretch, yStretch);
     1533                            VBoxRectTranslate(&RestrictSrcRect, -CrVrScrCompositorEntryRectGet(pEntry)->xLeft, -CrVrScrCompositorEntryRectGet(pEntry)->yTop);
    15241534                            VBoxRectIntersected(&RestrictSrcRect, pSrcRect, &SrcRect);
    15251535                   
     
    15301540                            pDstRect = &DstRect;
    15311541                           
    1532                             CrBltBlitTexMural(m_pBlitter, true, &pEntry->Tex, pSrcRect, pDstRect, 1, fFlags);
     1542                            const CR_TEXDATA *pTexData = CrVrScrCompositorEntryTexGet(pEntry);
     1543                           
     1544                            CrBltBlitTexMural(m_pBlitter, true, CrTdTexGet(pTexData), pSrcRect, pDstRect, 1, fFlags);
    15331545                        }
    15341546                        CrBltLeave(m_pBlitter);
     
    17471759    NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
    17481760
    1749     /*
    17501761    [pCtx release];
    1751     */
     1762    /*[pCtx performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:NO];*/
    17521763
    17531764    [pPool release];
     
    19061917}
    19071918
    1908 void cocoaViewPresentComposition(NativeNSViewRef pView, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry)
     1919void cocoaViewPresentComposition(NativeNSViewRef pView, const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry)
    19091920{
    19101921    NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
  • trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_glx.c

    r50041 r50095  
    579579                    if (pWindow)
    580580                    {
    581                         struct VBOXVR_SCR_COMPOSITOR * pCompositor;
     581                        const struct VBOXVR_SCR_COMPOSITOR * pCompositor;
    582582
    583583                        pCompositor = renderspuVBoxCompositorAcquire(pWindow);
     
    19691969}
    19701970
    1971 void renderspu_SystemVBoxPresentComposition( WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry )
     1971void renderspu_SystemVBoxPresentComposition( WindowInfo *window, const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry )
    19721972{
    19731973    /* the CR_RENDER_FORCE_PRESENT_MAIN_THREAD is actually inherited from cocoa backend impl,
     
    19761976     * @todo: change to some more generic macro name */
    19771977#ifndef CR_RENDER_FORCE_PRESENT_MAIN_THREAD
    1978     struct VBOXVR_SCR_COMPOSITOR *pCompositor;
     1978    const struct VBOXVR_SCR_COMPOSITOR *pCompositor;
    19791979    /* we do not want to be blocked with the GUI thread here, so only draw her eif we are really able to do that w/o bllocking */
    19801980    int rc = renderspuVBoxCompositorTryAcquire(window, &pCompositor);
  • trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_init.c

    r50041 r50095  
    386386    crSPUCopyDispatchTable( &(render_spu.self), self );
    387387
    388     render_spu.blitterDispatch = &(render_spu.self);
     388    crSPUInitDispatchTable( &(render_spu.blitterDispatch) );
     389    crSPUCopyDispatchTable( &(render_spu.blitterDispatch), self );
    389390
    390391    render_spu.server = (CRServer *)(self->server);
  • trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c

    r50041 r50095  
    431431            if (pWindow)
    432432            {
    433                 struct VBOXVR_SCR_COMPOSITOR * pCompositor;
     433                const struct VBOXVR_SCR_COMPOSITOR * pCompositor;
    434434
    435435                pCompositor = renderspuVBoxCompositorAcquire(pWindow);
     
    12521252}
    12531253
    1254 void renderspu_SystemVBoxPresentComposition( WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry )
     1254void renderspu_SystemVBoxPresentComposition( WindowInfo *window, const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry )
    12551255{
    12561256    /* the CR_RENDER_FORCE_PRESENT_MAIN_THREAD is actually inherited from cocoa backend impl,
     
    12591259     * @todo: change to some more generic macro name */
    12601260#ifndef CR_RENDER_FORCE_PRESENT_MAIN_THREAD
    1261     struct VBOXVR_SCR_COMPOSITOR *pCompositor;
     1261    const struct VBOXVR_SCR_COMPOSITOR *pCompositor;
    12621262    /* we do not want to be blocked with the GUI thread here, so only draw her eif we are really able to do that w/o bllocking */
    12631263    int rc = renderspuVBoxCompositorTryAcquire(window, &pCompositor);
  • trunk/src/VBox/Main/include/DisplayImpl.h

    r49790 r50095  
    102102    PVBVAHOSTFLAGS pVBVAHostFlags;
    103103#endif /* VBOX_WITH_HGSMI */
     104
     105#ifdef VBOX_WITH_CROGL
     106    struct
     107    {
     108        bool fPending;
     109        ULONG x;
     110        ULONG y;
     111        ULONG width;
     112        ULONG height;
     113    } pendingViewportInfo;
     114#endif /* VBOX_WITH_CROGL */
    104115} DISPLAYFBINFO;
    105116
     
    113124};
    114125
     126class VMMDev;
     127
    115128class ATL_NO_VTABLE Display :
    116129    public VirtualBoxBase,
     
    157170    void handleCrHgsmiControlCompletion(int32_t result, uint32_t u32Function, PVBOXHGCMSVCPARM pParam);
    158171#endif
     172    int notifyCroglResize(const PVBVAINFOVIEW pView, const PVBVAINFOSCREEN pScreen, void *pvVRAM);
     173
    159174    IFramebuffer *getFramebuffer()
    160175    {
     
    211226#endif
    212227
     228#ifdef VBOX_WITH_CROGL
     229    void crViewportNotify(class VMMDev *pVMMDev, ULONG aScreenId, ULONG x, ULONG y, ULONG width, ULONG height);
     230#endif
     231
    213232    static DECLCALLBACK(int)   changeFramebuffer(Display *that, IFramebuffer *aFB, unsigned uScreenId);
    214233
  • trunk/src/VBox/Main/src-client/DisplayImpl.cpp

    r50080 r50095  
    497497        maFramebuffers[ul].pVBVAHostFlags = NULL;
    498498#endif /* VBOX_WITH_HGSMI */
     499#ifdef VBOX_WITH_CROGL
     500        RT_ZERO(maFramebuffers[ul].pendingViewportInfo);
     501#endif
    499502    }
    500503
     
    650653    }
    651654
     655    return VINF_SUCCESS;
     656}
     657
     658int Display::notifyCroglResize(const PVBVAINFOVIEW pView, const PVBVAINFOSCREEN pScreen, void *pvVRAM)
     659{
     660#if defined(VBOX_WITH_HGCM) && defined(VBOX_WITH_CROGL)
     661    BOOL is3denabled;
     662    mParent->machine()->COMGETTER(Accelerate3DEnabled)(&is3denabled);
     663
     664    if (is3denabled)
     665    {
     666        VBOXHGCMSVCPARM parm[SHCRGL_CPARMS_DEV_RESIZE];
     667
     668        parm[0].type = VBOX_HGCM_SVC_PARM_PTR;
     669        parm[0].u.pointer.addr = (void*)pScreen;
     670        parm[0].u.pointer.size = sizeof (*pScreen);
     671        parm[1].type = VBOX_HGCM_SVC_PARM_PTR;
     672        parm[1].u.pointer.addr = (void*)pvVRAM;
     673        parm[1].u.pointer.size = 0;
     674
     675        VMMDev *pVMMDev = mParent->getVMMDev();
     676
     677        if (pVMMDev)
     678            return pVMMDev->hgcmHostCall("VBoxSharedCrOpenGL", SHCRGL_HOST_FN_DEV_RESIZE, SHCRGL_CPARMS_DEV_RESIZE, parm);
     679        return VERR_INVALID_STATE;
     680    }
     681#endif /* #if defined(VBOX_WITH_HGCM) && defined(VBOX_WITH_CROGL) */
    652682    return VINF_SUCCESS;
    653683}
     
    31523182{
    31533183#if defined(VBOX_WITH_HGCM) && defined(VBOX_WITH_CROGL)
     3184
     3185    if (mcMonitors <= aScreenId)
     3186    {
     3187        AssertMsgFailed(("invalid screen id\n"));
     3188        return E_INVALIDARG;
     3189    }
     3190
    31543191    BOOL is3denabled;
    31553192    mParent->machine()->COMGETTER(Accelerate3DEnabled)(&is3denabled);
     
    31573194    if (is3denabled)
    31583195    {
    3159         VBOXHGCMSVCPARM aParms[5];
    3160 
    3161         aParms[0].type = VBOX_HGCM_SVC_PARM_32BIT;
    3162         aParms[0].u.uint32 = aScreenId;
    3163 
    3164         aParms[1].type = VBOX_HGCM_SVC_PARM_32BIT;
    3165         aParms[1].u.uint32 = x;
    3166 
    3167         aParms[2].type = VBOX_HGCM_SVC_PARM_32BIT;
    3168         aParms[2].u.uint32 = y;
    3169 
    3170 
    3171         aParms[3].type = VBOX_HGCM_SVC_PARM_32BIT;
    3172         aParms[3].u.uint32 = width;
    3173 
    3174         aParms[4].type = VBOX_HGCM_SVC_PARM_32BIT;
    3175         aParms[4].u.uint32 = height;
    3176 
    31773196        VMMDev *pVMMDev = mParent->getVMMDev();
    31783197
    31793198        if (pVMMDev)
    3180             pVMMDev->hgcmHostCall("VBoxSharedCrOpenGL", SHCRGL_HOST_FN_VIEWPORT_CHANGED, SHCRGL_CPARMS_VIEWPORT_CHANGED, aParms);
     3199        {
     3200            crViewportNotify(pVMMDev, aScreenId, x, y, width, height);
     3201        }
     3202        else
     3203        {
     3204            DISPLAYFBINFO *pFb = &maFramebuffers[aScreenId];
     3205            pFb->pendingViewportInfo.fPending = true;
     3206            pFb->pendingViewportInfo.x = x;
     3207            pFb->pendingViewportInfo.y = y;
     3208            pFb->pendingViewportInfo.width = width;
     3209            pFb->pendingViewportInfo.height = height;
     3210        }
    31813211    }
    31823212#endif /* VBOX_WITH_CROGL && VBOX_WITH_HGCM */
     
    32663296}
    32673297
     3298#ifdef VBOX_WITH_CROGL
     3299void Display::crViewportNotify(VMMDev *pVMMDev, ULONG aScreenId, ULONG x, ULONG y, ULONG width, ULONG height)
     3300{
     3301    VBOXHGCMSVCPARM aParms[5];
     3302
     3303    aParms[0].type = VBOX_HGCM_SVC_PARM_32BIT;
     3304    aParms[0].u.uint32 = aScreenId;
     3305
     3306    aParms[1].type = VBOX_HGCM_SVC_PARM_32BIT;
     3307    aParms[1].u.uint32 = x;
     3308
     3309    aParms[2].type = VBOX_HGCM_SVC_PARM_32BIT;
     3310    aParms[2].u.uint32 = y;
     3311
     3312
     3313    aParms[3].type = VBOX_HGCM_SVC_PARM_32BIT;
     3314    aParms[3].u.uint32 = width;
     3315
     3316    aParms[4].type = VBOX_HGCM_SVC_PARM_32BIT;
     3317    aParms[4].u.uint32 = height;
     3318
     3319    pVMMDev->hgcmHostCall("VBoxSharedCrOpenGL", SHCRGL_HOST_FN_VIEWPORT_CHANGED, SHCRGL_CPARMS_VIEWPORT_CHANGED, aParms);
     3320
     3321}
     3322#endif
     3323
    32683324#ifdef VBOX_WITH_CRHGSMI
    32693325void Display::setupCrHgsmiData(void)
     
    32923348        rc = pVMMDev->hgcmHostCall("VBoxSharedCrOpenGL", SHCRGL_HOST_FN_CRHGSMI_CTL, 1, &parm);
    32933349        if (RT_SUCCESS(rc))
     3350        {
     3351            ULONG ul;
     3352
     3353            for (ul = 0; ul < mcMonitors; ul++)
     3354            {
     3355                DISPLAYFBINFO *pFb = &maFramebuffers[ul];
     3356                if (!pFb->pendingViewportInfo.fPending)
     3357                    continue;
     3358
     3359                crViewportNotify(pVMMDev, ul, pFb->pendingViewportInfo.x, pFb->pendingViewportInfo.y, pFb->pendingViewportInfo.width, pFb->pendingViewportInfo.height);
     3360                pFb->pendingViewportInfo.fPending = false;
     3361            }
     3362
    32943363            return;
     3364        }
    32953365
    32963366        AssertMsgFailed(("VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRHGSMI_SETUP_COMPLETION failed rc %d", rc));
     
    43034373    if (pScreen->u16Flags & VBVA_SCREEN_F_DISABLED)
    43044374    {
     4375        pThis->notifyCroglResize(pView, pScreen, pvVRAM);
     4376
    43054377        pFBInfo->fDisabled = true;
    43064378        pFBInfo->flags = pScreen->u16Flags;
     
    43254397     */
    43264398    bool fResize = pFBInfo->fDisabled || pFBInfo->pFramebuffer.isNull();
    4327 
    4328     if (pFBInfo->fDisabled)
    4329     {
    4330         pFBInfo->fDisabled = false;
    4331         fireGuestMonitorChangedEvent(pThis->mParent->getEventSource(),
    4332                                      GuestMonitorChangedEventType_Enabled,
    4333                                      pScreen->u32ViewIndex,
    4334                                      pScreen->i32OriginX, pScreen->i32OriginY,
    4335                                      pScreen->u32Width, pScreen->u32Height);
    4336         /* Continue to update pFBInfo. */
    4337     }
    43384399
    43394400    /* Check if this is a real resize or a notification about the screen origin.
     
    43504411                      || pFBInfo->yOrigin != pScreen->i32OriginY;
    43514412
     4413    if (fNewOrigin || fResize)
     4414        pThis->notifyCroglResize(pView, pScreen, pvVRAM);
     4415
     4416    if (pFBInfo->fDisabled)
     4417    {
     4418        pFBInfo->fDisabled = false;
     4419        fireGuestMonitorChangedEvent(pThis->mParent->getEventSource(),
     4420                                     GuestMonitorChangedEventType_Enabled,
     4421                                     pScreen->u32ViewIndex,
     4422                                     pScreen->i32OriginX, pScreen->i32OriginY,
     4423                                     pScreen->u32Width, pScreen->u32Height);
     4424        /* Continue to update pFBInfo. */
     4425    }
     4426
    43524427    pFBInfo->u32Offset = pView->u32ViewOffset; /* Not used in HGSMI. */
    43534428    pFBInfo->u32MaxFramebufferSize = pView->u32MaxScreenSize; /* Not used in HGSMI. */
     
    43744449                                     0, 0);
    43754450    }
    4376 
    4377 #if defined(VBOX_WITH_HGCM) && defined(VBOX_WITH_CROGL)
    4378     if (fNewOrigin && !fResize)
    4379     {
    4380         BOOL is3denabled;
    4381         pThis->mParent->machine()->COMGETTER(Accelerate3DEnabled)(&is3denabled);
    4382 
    4383         if (is3denabled)
    4384         {
    4385             VBOXHGCMSVCPARM parm;
    4386 
    4387             parm.type = VBOX_HGCM_SVC_PARM_32BIT;
    4388             parm.u.uint32 = pScreen->u32ViewIndex;
    4389 
    4390             VMMDev *pVMMDev = pThis->mParent->getVMMDev();
    4391 
    4392             if (pVMMDev)
    4393                 pVMMDev->hgcmHostCall("VBoxSharedCrOpenGL", SHCRGL_HOST_FN_SCREEN_CHANGED, SHCRGL_CPARMS_SCREEN_CHANGED, &parm);
    4394         }
    4395     }
    4396 #endif /* VBOX_WITH_CROGL */
    43974451
    43984452    if (!fResize)
Note: See TracChangeset for help on using the changeset viewer.

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