VirtualBox

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/src/VBox/HostServices/SharedOpenGL
Files:
21 edited
1 moved

Legend:

Unmodified
Added
Removed
  • 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);
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