VirtualBox

Ignore:
Timestamp:
Feb 3, 2014 6:46:27 PM (11 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
92022
Message:

crOpenGL: video recording working

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

Legend:

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

    r50280 r50313  
    389389}
    390390
     391DECLINLINE(void) CrFBmSetAtomic(CR_FBMAP *pMap, uint32_t i)
     392{
     393    return ASMAtomicBitSet(&pMap->Map, i);
     394}
     395
    391396DECLINLINE(void) CrFBmClear(CR_FBMAP *pMap, uint32_t i)
    392397{
     
    400405HCR_FRAMEBUFFER CrPMgrFbGetFirstEnabled();
    401406HCR_FRAMEBUFFER CrPMgrFbGetNextEnabled(HCR_FRAMEBUFFER hFb);
     407HCR_FRAMEBUFFER CrPMgrFbGetEnabled(uint32_t idScreen);
    402408int CrPMgrModeVrdp(bool fEnable);
    403409int CrPMgrModeRootVr(bool fEnable);
     
    416422typedef DECLCALLBACKPTR(bool, PFNCR_FRAMEBUFFER_ENTRIES_VISITOR_CB)(HCR_FRAMEBUFFER hFb, HCR_FRAMEBUFFER_ENTRY hEntry, void *pvContext);
    417423
     424bool CrFbHas3DData(HCR_FRAMEBUFFER hFb);
    418425void CrFbVisitCreatedEntries(HCR_FRAMEBUFFER hFb, PFNCR_FRAMEBUFFER_ENTRIES_VISITOR_CB pfnVisitorCb, void *pvContext);
    419426int CrFbResize(HCR_FRAMEBUFFER hFb, const struct VBVAINFOSCREEN * pScreen, void *pvVRAM);
     427int CrFbBltGetContents(HCR_FRAMEBUFFER hFb, const RTPOINT *pPoint, uint32_t cRects, const RTRECT *pPrects, CR_BLITTER_IMG *pImg);
    420428bool CrFbIsEnabled(HCR_FRAMEBUFFER hFb);
    421429int CrFbEntryCreateForTexId(HCR_FRAMEBUFFER hFb, GLuint idTex, uint32_t fFlags, HCR_FRAMEBUFFER_ENTRY *phEntry);
     
    424432void CrFbEntryRelease(HCR_FRAMEBUFFER hFb, HCR_FRAMEBUFFER_ENTRY hEntry);
    425433const struct VBVAINFOSCREEN* CrFbGetScreenInfo(HCR_FRAMEBUFFER hFb);
     434void* CrFbGetVRAM(HCR_FRAMEBUFFER hFb);
    426435const struct VBOXVR_SCR_COMPOSITOR* CrFbGetCompositor(HCR_FRAMEBUFFER hFb);
    427436const struct VBOXVR_SCR_COMPOSITOR_ENTRY* CrFbEntryGetCompositorEntry(HCR_FRAMEBUFFER_ENTRY hEntry);
     
    451460CR_TEXDATA* CrFbTexDataCreate(const VBOXVR_TEXTURE *pTex);
    452461void CrFbTexDataInit(CR_TEXDATA* pFbTex, const VBOXVR_TEXTURE *pTex, PFNCRTEXDATA_RELEASED pfnTextureReleased);
     462
     463int32_t crVBoxServerCrCmdBltProcess(PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd);
    453464
    454465//#define VBOX_WITH_CRSERVER_DUMPER
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c

    r50277 r50313  
    28812881
    28822882#ifdef VBOX_WITH_CRHGSMI
    2883 /* We moved all CrHgsmi command processing to crserverlib to keep the logic of dealing with CrHgsmi commands in one place.
    2884  *
    2885  * For now we need the notion of CrHgdmi commands in the crserver_lib to be able to complete it asynchronously once it is really processed.
    2886  * This help avoiding the "blocked-client" issues. The client is blocked if another client is doing begin-end stuff.
    2887  * For now we eliminated polling that could occur on block, which caused a higher-priority thread (in guest) polling for the blocked command complition
    2888  * to block the lower-priority thread trying to complete the blocking command.
    2889  * And removed extra memcpy done on blocked command arrival.
    2890  *
    2891  * In the future we will extend CrHgsmi functionality to maintain texture data directly in CrHgsmi allocation to avoid extra memcpy-ing with PBO,
    2892  * implement command completion and stuff necessary for GPU scheduling to work properly for WDDM Windows guests, etc.
    2893  *
    2894  * NOTE: it is ALWAYS responsibility of the crVBoxServerCrHgsmiCmd to complete the command!
    2895  * */
     2883
    28962884static int32_t crVBoxServerCmdVbvaCrCmdProcess(struct VBOXCMDVBVA_CRCMD_CMD *pCmd)
    28972885{
     
    31933181}
    31943182
     3183static int32_t crVBoxServerCrCmdProcess(PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd)
     3184{
     3185    switch (pCmd->u8OpCode)
     3186    {
     3187        case VBOXCMDVBVA_OPTYPE_CRCMD:
     3188        {
     3189            VBOXCMDVBVA_CRCMD *pCrCmdDr = (VBOXCMDVBVA_CRCMD*)pCmd;
     3190            VBOXCMDVBVA_CRCMD_CMD *pCrCmd = &pCrCmdDr->Cmd;
     3191            int rc = crVBoxServerCmdVbvaCrCmdProcess(pCrCmd);
     3192            if (RT_SUCCESS(rc))
     3193            {
     3194            /* success */
     3195                pCmd->i8Result = 0;
     3196            }
     3197            else
     3198            {
     3199                crWarning("crVBoxServerCmdVbvaCrCmdProcess failed, rc %d", rc);
     3200                pCmd->i8Result = -1;
     3201            }
     3202            break;
     3203        }
     3204        case VBOXCMDVBVA_OPTYPE_BLT_OFFPRIMSZFMT_OR_ID:
     3205        {
     3206            crVBoxServerCrCmdBltProcess(pCmd, cbCmd);
     3207            break;
     3208        }
     3209        default:
     3210            WARN(("unsupported command"));
     3211            pCmd->i8Result = -1;
     3212    }
     3213    return VINF_SUCCESS;
     3214}
     3215
     3216int32_t crVBoxServerCrCmdNotifyCmds()
     3217{
     3218    PVBOXCMDVBVA_HDR pCmd = NULL;
     3219    uint32_t cbCmd;
     3220
     3221    for (;;)
     3222    {
     3223        int rc = cr_server.CltInfo.pfnCmdGet(cr_server.CltInfo.hClient, &pCmd, &cbCmd);
     3224        if (rc == VINF_EOF)
     3225            return VINF_SUCCESS;
     3226        if (!RT_SUCCESS(rc))
     3227            return rc;
     3228
     3229        rc = crVBoxServerCrCmdProcess(pCmd, cbCmd);
     3230        if (!RT_SUCCESS(rc))
     3231            return rc;
     3232    }
     3233
     3234    /* should not be here! */
     3235    AssertFailed();
     3236    return VERR_INTERNAL_ERROR;
     3237}
     3238
     3239/* We moved all CrHgsmi command processing to crserverlib to keep the logic of dealing with CrHgsmi commands in one place.
     3240 *
     3241 * For now we need the notion of CrHgdmi commands in the crserver_lib to be able to complete it asynchronously once it is really processed.
     3242 * This help avoiding the "blocked-client" issues. The client is blocked if another client is doing begin-end stuff.
     3243 * For now we eliminated polling that could occur on block, which caused a higher-priority thread (in guest) polling for the blocked command complition
     3244 * to block the lower-priority thread trying to complete the blocking command.
     3245 * And removed extra memcpy done on blocked command arrival.
     3246 *
     3247 * In the future we will extend CrHgsmi functionality to maintain texture data directly in CrHgsmi allocation to avoid extra memcpy-ing with PBO,
     3248 * implement command completion and stuff necessary for GPU scheduling to work properly for WDDM Windows guests, etc.
     3249 *
     3250 * NOTE: it is ALWAYS responsibility of the crVBoxServerCrHgsmiCmd to complete the command!
     3251 * */
     3252
     3253
    31953254int32_t crVBoxServerCrHgsmiCmd(struct VBOXVDMACMD_CHROMIUM_CMD *pCmd, uint32_t cbCmd)
    31963255{
     
    35053564}
    35063565
     3566static DECLCALLBACK(bool) crVBoxServerHasData()
     3567{
     3568    HCR_FRAMEBUFFER hFb = CrPMgrFbGetFirstEnabled();
     3569    for (;
     3570            hFb;
     3571            hFb = CrPMgrFbGetNextEnabled(hFb))
     3572    {
     3573        if (CrFbHas3DData(hFb))
     3574            return true;
     3575    }
     3576
     3577    return false;
     3578}
     3579
    35073580int32_t crVBoxServerCrHgsmiCtl(struct VBOXVDMACMD_CHROMIUM_CTL *pCtl, uint32_t cbCtl)
    35083581{
     
    35243597            rc = VINF_SUCCESS;
    35253598            break;
    3526         case VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRHGSMI_SETUP_COMPLETION:
    3527         {
    3528             PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_COMPLETION pSetup = (PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_COMPLETION)pCtl;
     3599        case VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRHGSMI_SETUP_MAINCB:
     3600        {
     3601            PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_MAINCB pSetup = (PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_MAINCB)pCtl;
    35293602            g_hCrHgsmiCompletion = pSetup->hCompletion;
    35303603            g_pfnCrHgsmiCompletion = pSetup->pfnCompletion;
     3604
     3605            pSetup->MainInterface.pfnHasData = crVBoxServerHasData;
     3606
    35313607            rc = VINF_SUCCESS;
    35323608            break;
     
    35463622}
    35473623
    3548 static int32_t crVBoxServerCrCmdProcess(PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd)
    3549 {
    3550     switch (pCmd->u8OpCode)
    3551     {
    3552         case VBOXCMDVBVA_OPTYPE_CRCMD:
    3553         {
    3554             VBOXCMDVBVA_CRCMD *pCrCmdDr = (VBOXCMDVBVA_CRCMD*)pCmd;
    3555             VBOXCMDVBVA_CRCMD_CMD *pCrCmd = &pCrCmdDr->Cmd;
    3556             int rc = crVBoxServerCmdVbvaCrCmdProcess(pCrCmd);
    3557             if (RT_SUCCESS(rc))
    3558             {
    3559             /* success */
    3560                 pCmd->i8Result = 0;
    3561             }
    3562             else
    3563             {
    3564                 crWarning("crVBoxServerCmdVbvaCrCmdProcess failed, rc %d", rc);
    3565                 pCmd->i8Result = -1;
    3566             }
    3567             break;
    3568         }
    3569         default:
    3570             crWarning("unsupported command");
    3571             pCmd->i8Result = -1;
    3572     }
    3573     return VINF_SUCCESS;
    3574 }
    3575 
    3576 int32_t crVBoxServerCrCmdNotifyCmds()
    3577 {
    3578     PVBOXCMDVBVA_HDR pCmd = NULL;
    3579     uint32_t cbCmd;
    3580 
    3581     for (;;)
    3582     {
    3583         int rc = cr_server.CltInfo.pfnCmdGet(cr_server.CltInfo.hClient, &pCmd, &cbCmd);
    3584         if (rc == VINF_EOF)
    3585             return VINF_SUCCESS;
    3586         if (!RT_SUCCESS(rc))
    3587             return rc;
    3588 
    3589         rc = crVBoxServerCrCmdProcess(pCmd, cbCmd);
    3590         if (!RT_SUCCESS(rc))
    3591             return rc;
    3592     }
    3593 
    3594     /* should not be here! */
    3595     AssertFailed();
    3596     return VERR_INTERNAL_ERROR;
    3597 }
    3598 #endif
     3624#endif
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.cpp

    r50277 r50313  
    654654}
    655655
    656 static void crServerCopySubImage(char *pDst, char* pSrc, CRrecti *pRect, int srcWidth, int srcHeight)
    657 {
    658     int i;
    659     int dstrowsize = 4*(pRect->x2-pRect->x1);
    660     int srcrowsize = 4*srcWidth;
    661     int height = pRect->y2-pRect->y1;
    662 
    663     pSrc += 4*pRect->x1 + srcrowsize*(srcHeight-1-pRect->y1);
    664 
    665     for (i=0; i<height; ++i)
    666     {
    667         crMemcpy(pDst, pSrc, dstrowsize);
    668 
    669         pSrc -= srcrowsize;
    670         pDst += dstrowsize;
    671     }
    672 }
    673 
    674656DECLEXPORT(void) crServerVBoxCompositionSetEnableStateGlobal(GLboolean fEnable)
    675657{
     658}
     659
     660DECLEXPORT(int) crServerVBoxScreenshotGet(uint32_t u32Screen, CR_SCREENSHOT *pScreenshot)
     661{
     662    HCR_FRAMEBUFFER hFb = CrPMgrFbGetEnabled(u32Screen);
     663    if (!hFb)
     664        return VERR_INVALID_STATE;
     665
     666    const VBVAINFOSCREEN *pScreen = CrFbGetScreenInfo(hFb);
     667
     668    if (CrFbHas3DData(hFb))
     669    {
     670        RTPOINT Pos = {0, 0};
     671        RTRECT Rect;
     672
     673        pScreenshot->Img.cbData = pScreen->u32LineSize * pScreen->u32Height;
     674        pScreenshot->Img.pvData = RTMemAlloc(pScreenshot->Img.cbData);
     675        if (!pScreenshot->Img.pvData)
     676        {
     677            WARN(("RTMemAlloc failed"));
     678            return VERR_NO_MEMORY;
     679        }
     680        pScreenshot->Img.enmFormat = GL_BGRA;
     681        pScreenshot->Img.width = pScreen->u32Width;
     682        pScreenshot->Img.height = pScreen->u32Height;
     683        pScreenshot->Img.bpp = pScreen->u16BitsPerPixel;
     684        pScreenshot->Img.pitch = pScreen->u32LineSize;
     685        Rect.xLeft = 0;
     686        Rect.yTop = 0;
     687        Rect.xRight = pScreenshot->Img.width;
     688        Rect.yBottom = pScreenshot->Img.height;
     689        int rc = CrFbBltGetContents(hFb, &Pos, 1, &Rect, &pScreenshot->Img);
     690        if (!RT_SUCCESS(rc))
     691        {
     692            WARN(("CrFbBltGetContents failed %d", rc));
     693            RTMemFree(pScreenshot->Img.pvData);
     694            return rc;
     695        }
     696        pScreenshot->fDataIsFbDirect = 0;
     697    }
     698    else
     699    {
     700        pScreenshot->Img.pvData = CrFbGetVRAM(hFb);
     701        pScreenshot->Img.cbData = pScreen->u32LineSize * pScreen->u32Height;
     702        pScreenshot->Img.enmFormat = GL_BGRA;
     703        pScreenshot->Img.width = pScreen->u32Width;
     704        pScreenshot->Img.height = pScreen->u32Height;
     705        pScreenshot->Img.bpp = pScreen->u16BitsPerPixel;
     706        pScreenshot->Img.pitch = pScreen->u32LineSize;
     707
     708        pScreenshot->fDataIsFbDirect = 1;
     709    }
     710
     711    pScreenshot->u32Screen = u32Screen;
     712
     713    return VINF_SUCCESS;
     714}
     715
     716DECLEXPORT(void) crServerVBoxScreenshotRelease(CR_SCREENSHOT *pScreenshot)
     717{
     718    if (!pScreenshot->fDataIsFbDirect)
     719    {
     720        RTMemFree(pScreenshot->Img.pvData);
     721        pScreenshot->fDataIsFbDirect = 1;
     722    }
    676723}
    677724
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp

    r50280 r50313  
    105105    CR_FBMAP FramebufferInitMap;
    106106    CR_FRAMEBUFFER aFramebuffers[CR_MAX_GUEST_MONITORS];
     107    uint32_t cbTmpBuf;
     108    void *pvTmpBuf;
     109    uint32_t cbTmpBuf2;
     110    void *pvTmpBuf2;
    107111} CR_PRESENTER_GLOBALS;
    108112
     
    148152}
    149153
     154void* CrFbGetVRAM(HCR_FRAMEBUFFER hFb)
     155{
     156    return hFb->pvVram;
     157}
    150158
    151159int CrFbUpdateBegin(CR_FRAMEBUFFER *pFb)
     
    182190{
    183191    return !!pFb->cUpdating;
     192}
     193
     194bool CrFbHas3DData(HCR_FRAMEBUFFER hFb)
     195{
     196    return !CrVrScrCompositorIsEmpty(&hFb->Compositor);
     197}
     198
     199static void crFbBltMem(uint8_t *pu8Src, int32_t cbSrcPitch, uint8_t *pu8Dst, int32_t cbDstPitch, uint32_t width, uint32_t height)
     200{
     201    uint32_t cbCopyRow = width * 4;
     202
     203    for (uint32_t i = 0; i < height; ++i)
     204    {
     205        memcpy(pu8Dst, pu8Src, cbCopyRow);
     206
     207        pu8Src += cbSrcPitch;
     208        pu8Dst += cbDstPitch;
     209    }
     210}
     211
     212static void crFbBltImg(void *pvSrc, const RTRECT *pSrcDataRect, bool fSrcInvert, const RTRECT *pCopyRect, const RTPOINT *pDstDataPoint, CR_BLITTER_IMG *pDst)
     213{
     214    int32_t cbSrcPitch = (pSrcDataRect->xRight - pSrcDataRect->xLeft) * 4;
     215    int32_t srcX = pCopyRect->xLeft - pSrcDataRect->xLeft;
     216    int32_t srcY = pCopyRect->yTop - pSrcDataRect->yTop;
     217    Assert(srcX >= 0);
     218    Assert(srcY >= 0);
     219    Assert(srcX < pSrcDataRect->xRight - pSrcDataRect->xLeft);
     220    Assert(srcY < pSrcDataRect->yBottom - pSrcDataRect->yTop);
     221
     222    uint32_t cbDstPitch = pDst->pitch;
     223    int32_t dstX = pCopyRect->xLeft - pDstDataPoint->x;
     224    int32_t dstY = pCopyRect->yTop - pDstDataPoint->y;
     225    Assert(dstX >= 0);
     226    Assert(dstY >= 0);
     227
     228    uint8_t *pu8Src = ((uint8_t*)pvSrc) + cbSrcPitch * (!fSrcInvert ? srcY : pSrcDataRect->yBottom - pSrcDataRect->yTop - srcY - 1) + srcX * 4;
     229    uint8_t *pu8Dst = ((uint8_t*)pDst->pvData) + cbDstPitch * dstY + dstX * 4;
     230    if (fSrcInvert)
     231        cbSrcPitch = -cbSrcPitch;
     232
     233    crFbBltMem(pu8Src, cbSrcPitch, pu8Dst, cbDstPitch, pCopyRect->xRight - pCopyRect->xLeft, pCopyRect->yBottom - pCopyRect->yTop);
     234}
     235
     236int CrFbBltGetContents(HCR_FRAMEBUFFER hFb, const RTPOINT *pPoint, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg)
     237{
     238    VBOXVR_LIST List;
     239    uint32_t c2DRects = 0;
     240    CR_TEXDATA *pEnteredTex = NULL;
     241    VBoxVrListInit(&List);
     242    int rc = VBoxVrListRectsAdd(&List, 1, CrVrScrCompositorRectGet(&hFb->Compositor), NULL);
     243    if (!RT_SUCCESS(rc))
     244    {
     245        WARN(("VBoxVrListRectsAdd failed rc %d", rc));
     246        goto end;
     247    }
     248
     249    VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR Iter;
     250
     251    CrVrScrCompositorConstIterInit(&hFb->Compositor, &Iter);
     252
     253    for(const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry = CrVrScrCompositorConstIterNext(&Iter);
     254            pEntry;
     255            pEntry = CrVrScrCompositorConstIterNext(&Iter))
     256    {
     257        uint32_t cRegions;
     258        const RTRECT *pRegions;
     259        rc = CrVrScrCompositorEntryRegionsGet(&hFb->Compositor, pEntry, &cRegions, NULL, NULL, &pRegions);
     260        if (!RT_SUCCESS(rc))
     261        {
     262            WARN(("CrVrScrCompositorEntryRegionsGet failed rc %d", rc));
     263            goto end;
     264        }
     265
     266        rc = VBoxVrListRectsSubst(&List, cRegions, pRegions, NULL);
     267        if (!RT_SUCCESS(rc))
     268        {
     269            WARN(("VBoxVrListRectsSubst failed rc %d", rc));
     270            goto end;
     271        }
     272
     273        Assert(!pEnteredTex);
     274
     275        for (uint32_t i = 0; i < cRects; ++i)
     276        {
     277            const RTRECT * pRect = &pRects[i];
     278            for (uint32_t j = 0; j < cRegions; ++j)
     279            {
     280                const RTRECT * pReg = &pRegions[j];
     281                RTRECT Intersection;
     282                VBoxRectIntersected(pRect, pReg, &Intersection);
     283                if (VBoxRectIsZero(&Intersection))
     284                    continue;
     285
     286                CR_TEXDATA *pTex = CrVrScrCompositorEntryTexGet(pEntry);
     287                const CR_BLITTER_IMG *pSrcImg;
     288
     289                if (!pEnteredTex)
     290                {
     291                    rc = CrTdBltEnter(pTex);
     292                    if (!RT_SUCCESS(rc))
     293                    {
     294                        WARN(("CrTdBltEnter failed %d", rc));
     295                        goto end;
     296                    }
     297
     298                    pEnteredTex = pTex;
     299                }
     300
     301                rc = CrTdBltDataAcquire(pTex, GL_BGRA, false, &pSrcImg);
     302                if (!RT_SUCCESS(rc))
     303                {
     304                    WARN(("CrTdBltDataAcquire failed rc %d", rc));
     305                    goto end;
     306                }
     307
     308                const RTRECT *pEntryRect = CrVrScrCompositorEntryRectGet(pEntry);
     309                bool fInvert = !(CrVrScrCompositorEntryFlagsGet(pEntry) & CRBLT_F_INVERT_SRC_YCOORDS);
     310
     311                crFbBltImg(pSrcImg->pvData, pEntryRect, fInvert, &Intersection, pPoint, pImg);
     312
     313                CrTdBltDataRelease(pTex);
     314            }
     315        }
     316
     317        if (pEnteredTex)
     318        {
     319            CrTdBltLeave(pEnteredTex);
     320            pEnteredTex = NULL;
     321        }
     322    }
     323
     324    c2DRects = VBoxVrListRectsCount(&List);
     325    if (c2DRects)
     326    {
     327        if (g_CrPresenter.cbTmpBuf2 < c2DRects * sizeof (RTRECT))
     328        {
     329            if (g_CrPresenter.pvTmpBuf2)
     330                RTMemFree(g_CrPresenter.pvTmpBuf2);
     331
     332            g_CrPresenter.cbTmpBuf2 = (c2DRects + 10) * sizeof (RTRECT);
     333            g_CrPresenter.pvTmpBuf2 = RTMemAlloc(g_CrPresenter.cbTmpBuf2);
     334            if (!g_CrPresenter.pvTmpBuf2)
     335            {
     336                WARN(("RTMemAlloc failed!"));
     337                g_CrPresenter.cbTmpBuf2 = 0;
     338                rc = VERR_NO_MEMORY;
     339                goto end;
     340            }
     341        }
     342
     343        RTRECT *p2DRects  = (RTRECT *)g_CrPresenter.pvTmpBuf2;
     344
     345        rc = VBoxVrListRectsGet(&List, c2DRects, p2DRects);
     346        if (!RT_SUCCESS(rc))
     347        {
     348            WARN(("VBoxVrListRectsGet failed, rc %d", rc));
     349            goto end;
     350        }
     351
     352        RTPOINT Pos = {0};
     353
     354        for (uint32_t i = 0; i < cRects; ++i)
     355        {
     356            const RTRECT * pRect = &pRects[i];
     357            for (uint32_t j = 0; j < c2DRects; ++j)
     358            {
     359                const RTRECT * p2DRect = &p2DRects[j];
     360                RTRECT Intersection;
     361                VBoxRectIntersected(pRect, p2DRect, &Intersection);
     362                if (VBoxRectIsZero(&Intersection))
     363                    continue;
     364
     365                crFbBltImg(hFb->pvVram, CrVrScrCompositorRectGet(&hFb->Compositor), false, &Intersection, pPoint, pImg);
     366            }
     367        }
     368    }
     369
     370end:
     371
     372    if (pEnteredTex)
     373        CrTdBltLeave(pEnteredTex);
     374
     375    VBoxVrListClear(&List);
     376
     377    return rc;
    184378}
    185379
     
    464658        if (pFb->pDisplay)
    465659            pFb->pDisplay->EntryDestroyed(pFb, pEntry);
     660
     661        CR_TEXDATA *pTex = CrVrScrCompositorEntryTexGet(&pEntry->Entry);
     662        if (pTex)
     663            CrTdBltDataDiscardNe(pTex);
    466664    }
    467665}
     
    507705            pFb->pDisplay->EntryReplaced(pFb, pFbReplacingEntry, pFbEntry);
    508706
     707        CR_TEXDATA *pTex = CrVrScrCompositorEntryTexGet(&pFbEntry->Entry);
     708        if (pTex)
     709            CrTdBltDataDiscardNe(pTex);
     710
    509711        /* 2. mark the replaced entry is destroyed */
    510712        Assert(pFbEntry->Flags.fCreateNotified);
     
    522724            if (pFb->pDisplay)
    523725                pFb->pDisplay->EntryRemoved(pFb, pFbEntry);
     726
     727            CR_TEXDATA *pTex = CrVrScrCompositorEntryTexGet(&pFbEntry->Entry);
     728            if (pTex)
     729                CrTdBltDataDiscardNe(pTex);
    524730        }
    525731    }
     
    582788        if (pFb->pDisplay)
    583789            pFb->pDisplay->EntryTexChanged(pFb, pEntry);
     790
     791        CR_TEXDATA *pTex = CrVrScrCompositorEntryTexGet(&pEntry->Entry);
     792        if (pTex)
     793            CrTdBltDataDiscardNe(pTex);
    584794    }
    585795
     
    718928                if (pFb->pDisplay)
    719929                    pFb->pDisplay->EntryTexChanged(pFb, hEntry);
     930
     931                CR_TEXDATA *pTex = CrVrScrCompositorEntryTexGet(&hEntry->Entry);
     932                if (pTex)
     933                    CrTdBltDataDiscardNe(pTex);
    720934            }
    721935        }
     
    7881002                if (pFb->pDisplay)
    7891003                    pFb->pDisplay->EntryTexChanged(pFb, hEntry);
     1004
     1005                CR_TEXDATA *pTex = CrVrScrCompositorEntryTexGet(&hEntry->Entry);
     1006                if (pTex)
     1007                    CrTdBltDataDiscardNe(pTex);
    7901008            }
    7911009        }
     
    30703288    crFreeHashtable(g_CrPresenter.pFbTexMap, NULL);
    30713289
     3290    if (g_CrPresenter.pvTmpBuf)
     3291        RTMemFree(g_CrPresenter.pvTmpBuf);
     3292
     3293    if (g_CrPresenter.pvTmpBuf2)
     3294        RTMemFree(g_CrPresenter.pvTmpBuf2);
     3295
    30723296    memset(&g_CrPresenter, 0, sizeof (g_CrPresenter));
    30733297}
     
    30843308    {
    30853309        CrFbInit(&g_CrPresenter.aFramebuffers[idScreen], idScreen);
    3086         CrFBmSet(&g_CrPresenter.FramebufferInitMap, idScreen);
     3310        CrFBmSetAtomic(&g_CrPresenter.FramebufferInitMap, idScreen);
    30873311    }
    30883312    else
     
    39034127        CrFbEntryRelease(hFb, hEntry);
    39044128}
     4129
     4130DECLINLINE(void) crVBoxPRectUnpack(const VBOXCMDVBVA_RECT *pVbvaRect, RTRECT *pRect)
     4131{
     4132    pRect->xLeft = pVbvaRect->xLeft;
     4133    pRect->yTop = pVbvaRect->yTop;
     4134    pRect->xRight = pVbvaRect->xRight;
     4135    pRect->yBottom = pVbvaRect->yBottom;
     4136}
     4137
     4138DECLINLINE(void) crVBoxPRectUnpacks(const VBOXCMDVBVA_RECT *paVbvaRects, RTRECT *paRects, uint32_t cRects)
     4139{
     4140    uint32_t i = 0;
     4141    for (; i < cRects; ++i)
     4142    {
     4143        crVBoxPRectUnpack(&paVbvaRects[i], &paRects[i]);
     4144    }
     4145}
     4146
     4147int32_t crVBoxServerCrCmdBltProcess(PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd)
     4148{
     4149    uint8_t u8Flags = pCmd->u8Flags;
     4150    if (u8Flags & (VBOXCMDVBVA_OPF_ALLOC_DSTPRIMARY | VBOXCMDVBVA_OPF_ALLOC_SRCPRIMARY))
     4151    {
     4152        VBOXCMDVBVA_BLT_PRIMARY *pBlt = (VBOXCMDVBVA_BLT_PRIMARY*)pCmd;
     4153        uint8_t u8PrimaryID = pBlt->Hdr.u8PrimaryID;
     4154        HCR_FRAMEBUFFER hFb = CrPMgrFbGetEnabled(u8PrimaryID);
     4155        if (!hFb)
     4156        {
     4157            WARN(("request to present on disabled framebuffer, ignore"));
     4158            pCmd->i8Result = -1;
     4159            return VINF_SUCCESS;
     4160        }
     4161
     4162        const VBOXCMDVBVA_RECT *pPRects = pBlt->aRects;
     4163        uint32_t cRects = (cbCmd - RT_OFFSETOF(VBOXCMDVBVA_BLT_PRIMARY, aRects)) / sizeof (VBOXCMDVBVA_RECT);
     4164        RTRECT *pRects;
     4165        if (g_CrPresenter.cbTmpBuf < cRects * sizeof (RTRECT))
     4166        {
     4167            if (g_CrPresenter.pvTmpBuf)
     4168                RTMemFree(g_CrPresenter.pvTmpBuf);
     4169
     4170            g_CrPresenter.cbTmpBuf = (cRects + 10) * sizeof (RTRECT);
     4171            g_CrPresenter.pvTmpBuf = RTMemAlloc(g_CrPresenter.cbTmpBuf);
     4172            if (!g_CrPresenter.pvTmpBuf)
     4173            {
     4174                WARN(("RTMemAlloc failed!"));
     4175                g_CrPresenter.cbTmpBuf = 0;
     4176                pCmd->i8Result = -1;
     4177                return VINF_SUCCESS;
     4178            }
     4179        }
     4180
     4181        pRects = (RTRECT *)g_CrPresenter.pvTmpBuf;
     4182
     4183        crVBoxPRectUnpacks(pPRects, pRects, cRects);
     4184
     4185        Assert(!((cbCmd - RT_OFFSETOF(VBOXCMDVBVA_BLT_PRIMARY, aRects)) % sizeof (VBOXCMDVBVA_RECT)));
     4186
     4187        if (u8Flags & VBOXCMDVBVA_OPF_ALLOC_DSTPRIMARY)
     4188        {
     4189            if (!(u8Flags & VBOXCMDVBVA_OPF_ALLOC_SRCPRIMARY))
     4190            {
     4191                /* blit to primary from non-primary */
     4192                uint32_t texId;
     4193                if (u8Flags & VBOXCMDVBVA_OPF_ALLOC_DSTID)
     4194                {
     4195                    /* TexPresent */
     4196                    texId = pBlt->alloc.id;
     4197                }
     4198                else
     4199                {
     4200                    VBOXCMDVBVAOFFSET offVRAM = pBlt->alloc.offVRAM;
     4201                    const VBVAINFOSCREEN *pScreen = CrFbGetScreenInfo(hFb);
     4202                    uint32_t cbScreen = pScreen->u32LineSize * pScreen->u32Height;
     4203                    if (offVRAM >= g_cbVRam
     4204                            || offVRAM + cbScreen >= g_cbVRam)
     4205                    {
     4206                        WARN(("invalid param"));
     4207                        pCmd->i8Result = -1;
     4208                        return VINF_SUCCESS;
     4209                    }
     4210
     4211                    uint8_t *pu8Buf = g_pvVRamBase + offVRAM;
     4212                    texId = 0;
     4213                    /*todo: notify VGA device to perform updates */
     4214                }
     4215
     4216                crServerDispatchVBoxTexPresent(texId, u8PrimaryID, pBlt->Pos.x, pBlt->Pos.y, cRects, (const GLint*)pRects);
     4217            }
     4218            else
     4219            {
     4220                /* blit from one primary to another primary, wow */
     4221                WARN(("not implemented"));
     4222                pCmd->i8Result = -1;
     4223                return VINF_SUCCESS;
     4224            }
     4225        }
     4226        else
     4227        {
     4228            Assert(u8Flags & VBOXCMDVBVA_OPF_ALLOC_SRCPRIMARY);
     4229            /* blit from primary to non-primary */
     4230            if (u8Flags & VBOXCMDVBVA_OPF_ALLOC_DSTID)
     4231            {
     4232                uint32_t texId = pBlt->alloc.id;
     4233                WARN(("not implemented"));
     4234                pCmd->i8Result = -1;
     4235                return VINF_SUCCESS;
     4236            }
     4237            else
     4238            {
     4239                VBOXCMDVBVAOFFSET offVRAM = pBlt->alloc.offVRAM;
     4240                const VBVAINFOSCREEN *pScreen = CrFbGetScreenInfo(hFb);
     4241                uint32_t cbScreen = pScreen->u32LineSize * pScreen->u32Height;
     4242                if (offVRAM >= g_cbVRam
     4243                        || offVRAM + cbScreen >= g_cbVRam)
     4244                {
     4245                    WARN(("invalid param"));
     4246                    pCmd->i8Result = -1;
     4247                    return VINF_SUCCESS;
     4248                }
     4249
     4250                uint8_t *pu8Buf = g_pvVRamBase + offVRAM;
     4251
     4252                RTPOINT Pos = {pBlt->Pos.x, pBlt->Pos.y};
     4253                CR_BLITTER_IMG Img;
     4254                Img.pvData = pu8Buf;
     4255                Img.cbData = pScreen->u32LineSize * pScreen->u32Height;
     4256                Img.enmFormat = GL_BGRA;
     4257                Img.width = pScreen->u32Width;
     4258                Img.height = pScreen->u32Height;
     4259                Img.bpp = pScreen->u16BitsPerPixel;
     4260                Img.pitch = pScreen->u32LineSize;
     4261                int rc = CrFbBltGetContents(hFb, &Pos, cRects, pRects, &Img);
     4262                if (!RT_SUCCESS(rc))
     4263                {
     4264                    WARN(("CrFbBltGetContents failed %d", rc));
     4265                    pCmd->i8Result = -1;
     4266                    return VINF_SUCCESS;
     4267                }
     4268            }
     4269        }
     4270    }
     4271    else
     4272    {
     4273        WARN(("not implemented"));
     4274        pCmd->i8Result = -1;
     4275        return VINF_SUCCESS;
     4276    }
     4277
     4278    pCmd->i8Result = 0;
     4279    return VINF_SUCCESS;
     4280}
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