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)

File:
1 moved

Legend:

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