VirtualBox

Changeset 50313 in vbox for trunk


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
Files:
16 edited

Legend:

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

    r50251 r50313  
    4848#define SHCRGL_HOST_FN_DEV_RESIZE          (22)
    4949#define SHCRGL_HOST_FN_VIEWPORT_CHANGED2 (23)
     50#define SHCRGL_HOST_FN_TAKE_SCREENSHOT (24)
    5051/* crOpenGL guest functions */
    5152#define SHCRGL_GUEST_FN_WRITE       (2)
     
    380381} CRVBOXHGCMVIEWPORT;
    381382
     383typedef DECLCALLBACKPTR(void, PFNCRSCREENSHOTREPORT)(void *pvCtx, uint32_t uScreen,
     384                uint32_t x, uint32_t y, uint32_t uBitsPerPixel,
     385                uint32_t uBytesPerLine, uint32_t uGuestWidth, uint32_t uGuestHeight,
     386                uint8_t *pu8BufferAddress, uint64_t u64TimeStamp);
     387
     388#define CRSCREEN_ALL (0xffffffff)
     389
     390typedef struct
     391{
     392    /* screen id or CRSCREEN_ALL to specify all enabled */
     393    uint32_t u32Screen;
     394    void *pvContext;
     395    PFNCRSCREENSHOTREPORT pfnScreenshot;
     396} CRVBOXHGCMTAKESCREENSHOT;
     397
    382398#endif
  • trunk/include/VBox/VBoxVideo.h

    r49591 r50313  
    14381438    VBOXVDMACMD_CHROMIUM_CTL_TYPE_SAVESTATE_BEGIN,
    14391439    VBOXVDMACMD_CHROMIUM_CTL_TYPE_SAVESTATE_END,
    1440     VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRHGSMI_SETUP_COMPLETION,
     1440    VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRHGSMI_SETUP_MAINCB,
    14411441    VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRCONNECT,
    14421442    VBOXVDMACMD_CHROMIUM_CTL_TYPE_SIZEHACK = 0xfffffffe
     
    14661466typedef FNCRHGSMICMDCOMPLETION *PFNCRHGSMICMDCOMPLETION;
    14671467
    1468 typedef struct VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_COMPLETION
     1468typedef DECLCALLBACK(bool) FNCROGLHASDATA();
     1469typedef FNCROGLHASDATA *PFNCROGLHASDATA;
     1470
     1471/* callbacks chrogl gives to main */
     1472typedef struct CR_MAIN_INTERFACE
     1473{
     1474    PFNCROGLHASDATA pfnHasData;
     1475} CR_MAIN_INTERFACE;
     1476
     1477typedef struct VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_MAINCB
    14691478{
    14701479    VBOXVDMACMD_CHROMIUM_CTL Hdr;
     1480    /*in*/
    14711481    HCRHGSMICMDCOMPLETION hCompletion;
    14721482    PFNCRHGSMICMDCOMPLETION pfnCompletion;
    1473 } VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_COMPLETION, *PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_COMPLETION;
     1483    /*out*/
     1484    CR_MAIN_INTERFACE MainInterface;
     1485} VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_MAINCB, *PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_MAINCB;
    14741486
    14751487typedef struct VBOXCRCON_SERVER *HVBOXCRCON_SERVER;
     
    16691681} VBOXCMDVBVA_RECT;
    16701682
     1683typedef struct VBOXCMDVBVA_POINT
     1684{
     1685   int16_t x;
     1686   int16_t y;
     1687} VBOXCMDVBVA_POINT;
     1688
    16711689typedef struct VBOXCMDVBVA_BLT_PRIMARY
    16721690{
    16731691    VBOXCMDVBVA_HDR Hdr;
    16741692    VBOXCMDVBVA_ALLOCINFO alloc;
     1693    VBOXCMDVBVA_POINT Pos;
    16751694    /* the rects count is determined from the command size */
    16761695    VBOXCMDVBVA_RECT aRects[1];
     
    16821701    VBOXCMDVBVA_ALLOCINFO src;
    16831702    VBOXCMDVBVA_ALLOCINFO dst;
     1703    VBOXCMDVBVA_POINT Pos;
    16841704    /* the rects count is determined from the command size */
    16851705    VBOXCMDVBVA_RECT aRects[1];
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp

    r49591 r50313  
    59205920            }
    59215921
     5922            pBlt->Pos.x = pPresent->DstRect.left - pPresent->SrcRect.left;
     5923            pBlt->Pos.y = pPresent->DstRect.top - pPresent->SrcRect.top;
     5924
    59225925            paRects = pBlt->aRects;
    59235926            cbMaxRects = pPresent->DmaBufferPrivateDataSize - RT_OFFSETOF(VBOXCMDVBVA_BLT_PRIMARY, aRects);
     
    59395942            if (VBoxCVDdiFillAllocInfo(pHdr, &pBlt->dst, pDstAlloc, pDst, true))
    59405943                u32DstPatch = RT_OFFSETOF(VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID, dst.offVRAM);
     5944
     5945            pBlt->Pos.x = pPresent->DstRect.left - pPresent->SrcRect.left;
     5946            pBlt->Pos.y = pPresent->DstRect.top - pPresent->SrcRect.top;
    59415947
    59425948            paRects = pBlt->aRects;
  • trunk/src/VBox/GuestHost/OpenGL/include/cr_blitter.h

    r50184 r50313  
    285285 * Must be called wit data released (CrTdBltDataRelease) */
    286286VBOXBLITTERDECL(int) CrTdBltDataDiscard(PCR_TEXDATA pTex);
     287VBOXBLITTERDECL(int) CrTdBltDataDiscardNe(PCR_TEXDATA pTex);
    287288/* does same as CrTdBltDataDiscard, and in addition cleans up.
    288289 * this is kind of a texture destructor, which clients should call on texture object destruction, e.g. from the PFNCRTEXDATA_RELEASED callback */
  • trunk/src/VBox/GuestHost/OpenGL/include/cr_server.h

    r50277 r50313  
    3434#include <VBox/Hardware/VBoxVideoVBE.h>
    3535#include <VBox/VBoxVideo3D.h>
    36 
    37 #include "cr_vreg.h"
    3836
    3937#ifdef __cplusplus
     
    521519extern DECLEXPORT(int32_t) crVBoxServerLoadState(PSSMHANDLE pSSM, uint32_t version);
    522520
     521typedef struct
     522{
     523    CR_BLITTER_IMG Img;
     524    uint32_t u32Screen;
     525    uint32_t fDataIsFbDirect;
     526} CR_SCREENSHOT;
     527
     528extern DECLEXPORT(int) crServerVBoxScreenshotGet(uint32_t u32Screen, CR_SCREENSHOT *pScreenshot);
     529extern DECLEXPORT(void) crServerVBoxScreenshotRelease(CR_SCREENSHOT *pScreenshot);
     530
    523531extern DECLEXPORT(void) crServerVBoxCompositionSetEnableStateGlobal(GLboolean fEnable);
    524532extern DECLEXPORT(int32_t) crVBoxServerSetScreenCount(int sCount);
  • trunk/src/VBox/GuestHost/OpenGL/include/cr_vreg.h

    r50246 r50313  
    9595}
    9696
     97DECLINLINE(void) VBoxRectInvertY(RTRECT * pRect)
     98{
     99    int32_t y = pRect->yTop;
     100    pRect->yTop = pRect->yBottom;
     101    pRect->yBottom = y;
     102}
     103
     104DECLINLINE(void) VBoxRectInvertedY(const RTRECT * pRect, RTRECT * pResult)
     105{
     106    *pResult = *pRect;
     107    VBoxRectInvertY(pResult);
     108}
     109
    97110DECLINLINE(void) VBoxRectMove(RTRECT * pRect, int32_t x, int32_t y)
    98111{
  • trunk/src/VBox/GuestHost/OpenGL/util/blitter.cpp

    r50184 r50313  
    12901290}
    12911291
     1292VBOXBLITTERDECL(int) CrTdBltDataDiscardNe(PCR_TEXDATA pTex)
     1293{
     1294    if (!pTex->Img.pvData)
     1295        return VINF_SUCCESS;
     1296
     1297    bool fEntered = false;
     1298    if (pTex->idPBO)
     1299    {
     1300        int rc = CrTdBltEnter(pTex);
     1301        if (!RT_SUCCESS(rc))
     1302        {
     1303            WARN(("err"));
     1304            return rc;
     1305        }
     1306
     1307        fEntered = true;
     1308    }
     1309
     1310    crTdBltImgFree(pTex);
     1311
     1312    if (fEntered)
     1313        CrTdBltLeave(pTex);
     1314
     1315    return VINF_SUCCESS;
     1316}
     1317
    12921318static void crTdBltDataCleanup(PCR_TEXDATA pTex)
    12931319{
  • trunk/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp

    r50251 r50313  
    4343PVBOXHGCMSVCHELPERS g_pHelpers;
    4444static IConsole* g_pConsole = NULL;
     45static uint32_t g_u32ScreenCount = 0;
    4546static PVM g_pVM = NULL;
    4647
     
    10251026
    10261027                    g_pConsole = pConsole;
     1028                    g_u32ScreenCount = monitorCount;
    10271029
    10281030                    rc = crVBoxServerSetScreenCount(monitorCount);
     
    11831185
    11841186                rc = VINF_SUCCESS;
     1187            }
     1188            break;
     1189        }
     1190        case SHCRGL_HOST_FN_TAKE_SCREENSHOT:
     1191        {
     1192            if (cParms != 1)
     1193            {
     1194                LogRel(("SHCRGL_HOST_FN_TAKE_SCREENSHOT: cParms invalid - %d", cParms));
     1195                rc = VERR_INVALID_PARAMETER;
     1196                break;
     1197            }
     1198
     1199            if (paParms->type != VBOX_HGCM_SVC_PARM_PTR)
     1200            {
     1201                AssertMsgFailed(("invalid param\n"));
     1202                rc = VERR_INVALID_PARAMETER;
     1203                break;
     1204            }
     1205
     1206            if (!paParms->u.pointer.addr)
     1207            {
     1208                AssertMsgFailed(("invalid param\n"));
     1209                rc = VERR_INVALID_PARAMETER;
     1210                break;
     1211            }
     1212
     1213            if (paParms->u.pointer.size != sizeof (CRVBOXHGCMTAKESCREENSHOT))
     1214            {
     1215                AssertMsgFailed(("invalid param\n"));
     1216                rc = VERR_INVALID_PARAMETER;
     1217                break;
     1218            }
     1219
     1220            CRVBOXHGCMTAKESCREENSHOT *pScreenshot = (CRVBOXHGCMTAKESCREENSHOT*)paParms->u.pointer.addr;
     1221            uint64_t u64Now = RTTimeProgramMilliTS();
     1222
     1223            if (pScreenshot->u32Screen == CRSCREEN_ALL)
     1224            {
     1225                for (uint32_t i = 0; i < g_u32ScreenCount; ++i)
     1226                {
     1227                    CR_SCREENSHOT Screenshot;
     1228
     1229                    int rc = crServerVBoxScreenshotGet(i, &Screenshot);
     1230                    if (RT_SUCCESS(rc))
     1231                    {
     1232                        pScreenshot->pfnScreenshot(pScreenshot->pvContext, i,
     1233                                0, 0, 32,
     1234                                Screenshot.Img.pitch, Screenshot.Img.width, Screenshot.Img.height,
     1235                                (uint8_t*)Screenshot.Img.pvData, u64Now);
     1236                        crServerVBoxScreenshotRelease(&Screenshot);
     1237                    }
     1238                    else
     1239                    {
     1240                        Assert(rc == VERR_INVALID_STATE);
     1241                    }
     1242                }
     1243            }
     1244            else if (pScreenshot->u32Screen < g_u32ScreenCount)
     1245            {
     1246                CR_SCREENSHOT Screenshot;
     1247
     1248                int rc = crServerVBoxScreenshotGet(pScreenshot->u32Screen, &Screenshot);
     1249                if (RT_SUCCESS(rc))
     1250                {
     1251                    pScreenshot->pfnScreenshot(pScreenshot->pvContext, pScreenshot->u32Screen,
     1252                            0, 0, 32,
     1253                            Screenshot.Img.pitch, Screenshot.Img.width, Screenshot.Img.height,
     1254                            (uint8_t*)Screenshot.Img.pvData, u64Now);
     1255                    crServerVBoxScreenshotRelease(&Screenshot);
     1256                }
     1257                else
     1258                {
     1259                    Assert(rc == VERR_INVALID_STATE);
     1260                }
     1261            }
     1262            else
     1263            {
     1264                AssertMsgFailed(("invalid screen id\n"));
     1265                rc = VERR_INVALID_PARAMETER;
     1266                break;
    11851267            }
    11861268            break;
  • 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}
  • trunk/src/VBox/Main/Makefile.kmk

    r50263 r50313  
    6969        $(if $(VBOX_WITH_DRAG_AND_DROP_GH),VBOX_WITH_DRAG_AND_DROP_GH,) \
    7070        $(if $(VBOX_WITH_CROGL),VBOX_WITH_CROGL,) \
     71        $(if $(VBOX_WITH_CRHGSMI),VBOX_WITH_CRHGSMI,) \
    7172        $(if $(VBOX_WITH_GUEST_PROPS),VBOX_WITH_GUEST_PROPS,) \
    7273        $(if $(VBOX_WITH_GUEST_PROPS_RDONLY_GUEST),VBOX_WITH_GUEST_PROPS_RDONLY_GUEST,) \
     
    281282        $(if $(VBOX_WITH_S3),VBOX_WITH_S3,) \
    282283        $(if $(VBOX_WITH_PCI_PASSTHROUGH),VBOX_WITH_PCI_PASSTHROUGH,) \
    283         $(if $(VBOX_WITH_NAT_SERVICE),VBOX_WITH_NAT_SERVICE,)
     284        $(if $(VBOX_WITH_NAT_SERVICE),VBOX_WITH_NAT_SERVICE,) \
     285        $(if $(VBOX_WITH_HGCM),VBOX_WITH_CROGL,) \
     286        $(if $(VBOX_WITH_CRHGSMI),VBOX_WITH_CRHGSMI,)
    284287ifdef VBOX_WITH_USB
    285288 VBoxSVC_DEFS += \
  • trunk/src/VBox/Main/include/DisplayImpl.h

    r50260 r50313  
    2727#include <VBox/VBoxVideo.h>
    2828
     29#ifdef VBOX_WITH_CROGL
     30# include <VBox/HostServices/VBoxCrOpenGLSvc.h>
     31#endif
     32
    2933class Console;
    3034struct VIDEORECCONTEXT;
     
    174178#if defined(VBOX_WITH_HGCM) && defined(VBOX_WITH_CROGL)
    175179    void  handleCrAsyncCmdCompletion(int32_t result, uint32_t u32Function, PVBOXHGCMSVCPARM pParam);
     180    void  handleCrVRecScreenshot(uint32_t uScreen,
     181                    uint32_t x, uint32_t y, uint32_t uPixelFormat, uint32_t uBitsPerPixel,
     182                    uint32_t uBytesPerLine, uint32_t uGuestWidth, uint32_t uGuestHeight,
     183                    uint8_t *pu8BufferAddress, uint64_t u64TimeStamp);
     184    void  handleVRecCompletion(int32_t result, uint32_t u32Function, PVBOXHGCMSVCPARM pParam, void *pvContext);
    176185#endif
    177186
     
    274283
    275284#if defined(VBOX_WITH_HGCM) && defined(VBOX_WITH_CROGL)
     285    static DECLCALLBACK(void) displayCrVRecScreenshot(void *pvCtx, uint32_t uScreen,
     286                    uint32_t x, uint32_t y, uint32_t uBitsPerPixel,
     287                    uint32_t uBytesPerLine, uint32_t uGuestWidth, uint32_t uGuestHeight,
     288                    uint8_t *pu8BufferAddress, uint64_t u64TimeStamp);
     289    static DECLCALLBACK(void)  displayVRecCompletion(int32_t result, uint32_t u32Function, PVBOXHGCMSVCPARM pParam, void *pvContext);
    276290    static DECLCALLBACK(void)  displayCrAsyncCmdCompletion(int32_t result, uint32_t u32Function, PVBOXHGCMSVCPARM pParam, void *pvContext);
    277291#endif
     
    319333    HGCMCVSHANDLE mhCrOglSvc;
    320334#endif
     335#ifdef VBOX_WITH_CROGL
     336    CR_MAIN_INTERFACE mCrOglCallbacks;
     337    volatile uint32_t mfCrOglVideoRecState;
     338    CRVBOXHGCMTAKESCREENSHOT mCrOglScreenshotData;
     339#endif
    321340
    322341    bool vbvaFetchCmd(VBVACMDHDR **ppHdr, uint32_t *pcbCmd);
  • trunk/src/VBox/Main/src-client/DisplayImpl.cpp

    r50260 r50313  
    5252# include <iprt/path.h>
    5353# include "VideoRec.h"
     54#endif
     55
     56#ifdef VBOX_WITH_CROGL
     57typedef enum
     58{
     59    CRVREC_STATE_IDLE,
     60    CRVREC_STATE_SUBMITTED
     61} CRVREC_STATE;
    5462#endif
    5563
     
    137145    for (unsigned i = 0; i < RT_ELEMENTS(maVideoRecEnabled); i++)
    138146        maVideoRecEnabled[i] = true;
     147#endif
     148
     149#ifdef VBOX_WITH_CRHGSMI
     150    mhCrOglSvc = NULL;
     151#endif
     152#ifdef VBOX_WITH_CROGL
     153    RT_ZERO(mCrOglCallbacks);
     154    mfCrOglVideoRecState = CRVREC_STATE_IDLE;
     155    mCrOglScreenshotData.u32Screen = CRSCREEN_ALL;
     156    mCrOglScreenshotData.pvContext = this;
     157    mCrOglScreenshotData.pfnScreenshot = displayCrVRecScreenshot;
    139158#endif
    140159
     
    34033422        Assert(mhCrOglSvc);
    34043423        /* setup command completion callback */
    3405         VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_COMPLETION Completion;
    3406         Completion.Hdr.enmType = VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRHGSMI_SETUP_COMPLETION;
     3424        VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_MAINCB Completion;
     3425        Completion.Hdr.enmType = VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRHGSMI_SETUP_MAINCB;
    34073426        Completion.Hdr.cbCmd = sizeof (Completion);
    34083427        Completion.hCompletion = mpDrv->pVBVACallbacks;
     
    34283447                pFb->pendingViewportInfo.fPending = false;
    34293448            }
     3449
     3450            mCrOglCallbacks = Completion.MainInterface;
    34303451
    34313452            return;
     
    36543675    if (VideoRecIsEnabled(pDisplay->mpVideoRecCtx))
    36553676    {
    3656         uint64_t u64Now = RTTimeProgramMilliTS();
    3657         for (uScreenId = 0; uScreenId < pDisplay->mcMonitors; uScreenId++)
    3658         {
    3659             if (!pDisplay->maVideoRecEnabled[uScreenId])
    3660                 continue;
    3661 
    3662             DISPLAYFBINFO *pFBInfo = &pDisplay->maFramebuffers[uScreenId];
    3663 
    3664             if (   !pFBInfo->pFramebuffer.isNull()
    3665                 && !pFBInfo->fDisabled
    3666                 && pFBInfo->u32ResizeStatus == ResizeStatus_Void)
     3677        do {
     3678#if defined(VBOX_WITH_HGCM) && defined(VBOX_WITH_CROGL)
     3679            BOOL is3denabled;
     3680            pDisplay->mParent->machine()->COMGETTER(Accelerate3DEnabled)(&is3denabled);
     3681            if (is3denabled)
    36673682            {
    3668                 int rc;
    3669                 if (   pFBInfo->fVBVAEnabled
    3670                     && pFBInfo->pu8FramebufferVRAM)
     3683                if (ASMAtomicCmpXchgU32(&pDisplay->mfCrOglVideoRecState, CRVREC_STATE_SUBMITTED, CRVREC_STATE_IDLE))
    36713684                {
    3672                     rc = VideoRecCopyToIntBuf(pDisplay->mpVideoRecCtx, uScreenId, 0, 0,
    3673                                               FramebufferPixelFormat_FOURCC_RGB,
    3674                                               pFBInfo->u16BitsPerPixel,
    3675                                               pFBInfo->u32LineSize, pFBInfo->w, pFBInfo->h,
    3676                                               pFBInfo->pu8FramebufferVRAM, u64Now);
     3685                    if (pDisplay->mCrOglCallbacks.pfnHasData())
     3686                    {
     3687                        /* submit */
     3688
     3689                        VBOXHGCMSVCPARM parm;
     3690
     3691                        parm.type = VBOX_HGCM_SVC_PARM_PTR;
     3692                        parm.u.pointer.addr = &pDisplay->mCrOglScreenshotData;
     3693                        parm.u.pointer.size = sizeof (pDisplay->mCrOglScreenshotData);
     3694
     3695                        VMMDev *pVMMDev = pDisplay->mParent->getVMMDev();
     3696                        if (pVMMDev)
     3697                        {
     3698                            int rc = pVMMDev->hgcmHostFastCallAsync(pDisplay->mhCrOglSvc, SHCRGL_HOST_FN_TAKE_SCREENSHOT, &parm, displayVRecCompletion, pDisplay);
     3699                            if (RT_SUCCESS(rc))
     3700                                break;
     3701                            else
     3702                                AssertMsgFailed(("hgcmHostFastCallAsync failed %f\n", rc));
     3703                        }
     3704                        else
     3705                            AssertMsgFailed(("no VMMDev\n"));
     3706                    }
     3707
     3708                    /* no 3D data available, or error has occured,
     3709                     * go the straight way */
     3710                    ASMAtomicWriteU32(&pDisplay->mfCrOglVideoRecState, CRVREC_STATE_IDLE);
    36773711                }
    36783712                else
    36793713                {
    3680                     rc = VideoRecCopyToIntBuf(pDisplay->mpVideoRecCtx, uScreenId, 0, 0,
    3681                                               FramebufferPixelFormat_FOURCC_RGB,
    3682                                               pDrv->IConnector.cBits,
    3683                                               pDrv->IConnector.cbScanline, pDrv->IConnector.cx,
    3684                                               pDrv->IConnector.cy, pDrv->IConnector.pu8Data, u64Now);
     3714                    /* record request is still in progress, don't do anything */
     3715                    break;
    36853716                }
    3686                 if (rc == VINF_TRY_AGAIN)
    3687                     break;
    36883717            }
    3689         }
     3718#endif
     3719            uint64_t u64Now = RTTimeProgramMilliTS();
     3720            for (uScreenId = 0; uScreenId < pDisplay->mcMonitors; uScreenId++)
     3721            {
     3722                if (!pDisplay->maVideoRecEnabled[uScreenId])
     3723                    continue;
     3724
     3725                DISPLAYFBINFO *pFBInfo = &pDisplay->maFramebuffers[uScreenId];
     3726
     3727                if (   !pFBInfo->pFramebuffer.isNull()
     3728                    && !pFBInfo->fDisabled
     3729                    && pFBInfo->u32ResizeStatus == ResizeStatus_Void)
     3730                {
     3731                    int rc;
     3732                    if (   pFBInfo->fVBVAEnabled
     3733                        && pFBInfo->pu8FramebufferVRAM)
     3734                    {
     3735                        rc = VideoRecCopyToIntBuf(pDisplay->mpVideoRecCtx, uScreenId, 0, 0,
     3736                                                  FramebufferPixelFormat_FOURCC_RGB,
     3737                                                  pFBInfo->u16BitsPerPixel,
     3738                                                  pFBInfo->u32LineSize, pFBInfo->w, pFBInfo->h,
     3739                                                  pFBInfo->pu8FramebufferVRAM, u64Now);
     3740                    }
     3741                    else
     3742                    {
     3743                        rc = VideoRecCopyToIntBuf(pDisplay->mpVideoRecCtx, uScreenId, 0, 0,
     3744                                                  FramebufferPixelFormat_FOURCC_RGB,
     3745                                                  pDrv->IConnector.cBits,
     3746                                                  pDrv->IConnector.cbScanline, pDrv->IConnector.cx,
     3747                                                  pDrv->IConnector.cy, pDrv->IConnector.pu8Data, u64Now);
     3748                    }
     3749                    if (rc == VINF_TRY_AGAIN)
     3750                        break;
     3751                }
     3752            }
     3753        } while (0);
    36903754    }
    36913755#endif
     
    41394203    if (pParam->type == VBOX_HGCM_SVC_PARM_PTR && pParam->u.pointer.addr)
    41404204        RTMemFree(pParam->u.pointer.addr);
     4205}
     4206
     4207
     4208void  Display::handleCrVRecScreenshot(uint32_t uScreen,
     4209                uint32_t x, uint32_t y, uint32_t uPixelFormat, uint32_t uBitsPerPixel,
     4210                uint32_t uBytesPerLine, uint32_t uGuestWidth, uint32_t uGuestHeight,
     4211                uint8_t *pu8BufferAddress, uint64_t u64TimeStamp)
     4212{
     4213    Assert(mfCrOglVideoRecState == CRVREC_STATE_SUBMITTED);
     4214    int rc = VideoRecCopyToIntBuf(mpVideoRecCtx, uScreen, x, y,
     4215                              uPixelFormat,
     4216                              uBitsPerPixel, uBytesPerLine,
     4217                              uGuestWidth, uGuestHeight,
     4218                              pu8BufferAddress, u64TimeStamp);
     4219    Assert(rc == VINF_SUCCESS || rc == VERR_TRY_AGAIN || rc == VINF_TRY_AGAIN);
     4220}
     4221
     4222void  Display::handleVRecCompletion(int32_t result, uint32_t u32Function, PVBOXHGCMSVCPARM pParam, void *pvContext)
     4223{
     4224    Assert(mfCrOglVideoRecState == CRVREC_STATE_SUBMITTED);
     4225    ASMAtomicWriteU32(&mfCrOglVideoRecState, CRVREC_STATE_IDLE);
     4226}
     4227
     4228DECLCALLBACK(void) Display::displayCrVRecScreenshot(void *pvCtx, uint32_t uScreen,
     4229                uint32_t x, uint32_t y, uint32_t uBitsPerPixel,
     4230                uint32_t uBytesPerLine, uint32_t uGuestWidth, uint32_t uGuestHeight,
     4231                uint8_t *pu8BufferAddress, uint64_t u64TimeStamp)
     4232{
     4233    Display *pDisplay = (Display *)pvCtx;
     4234    pDisplay->handleCrVRecScreenshot(uScreen,
     4235            x, y, FramebufferPixelFormat_FOURCC_RGB, uBitsPerPixel,
     4236            uBytesPerLine, uGuestWidth, uGuestHeight,
     4237            pu8BufferAddress, u64TimeStamp);
     4238}
     4239
     4240DECLCALLBACK(void)  Display::displayVRecCompletion(int32_t result, uint32_t u32Function, PVBOXHGCMSVCPARM pParam, void *pvContext)
     4241{
     4242    Display *pDisplay = (Display *)pvContext;
     4243    pDisplay->handleVRecCompletion(result, u32Function, pParam, pvContext);
    41414244}
    41424245
  • trunk/src/VBox/Main/src-client/VideoRec.h

    r50041 r50313  
    3232int  VideoRecCopyToIntBuf(PVIDEORECCONTEXT pCtx, uint32_t uScreen,
    3333                          uint32_t x, uint32_t y, uint32_t uPixelFormat, uint32_t uBitsPerPixel,
    34                           uint32_t uBytesPerLine, uint32_t uGuestHeight, uint32_t uGuestWidth,
     34                          uint32_t uBytesPerLine, uint32_t uGuestWidth, uint32_t uGuestHeight,
    3535                          uint8_t *pu8BufferAddress, uint64_t u64TimeStamp);
    3636
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