VirtualBox

Changeset 50364 in vbox for trunk


Ignore:
Timestamp:
Feb 7, 2014 2:11:50 PM (11 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
92115
Message:

crOpenGL: screenshot support; a bit of performance for video recording

Location:
trunk
Files:
11 edited

Legend:

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

    r50319 r50364  
    396396    /* screen id or CRSCREEN_ALL to specify all enabled */
    397397    uint32_t u32Screen;
     398    uint32_t u32Width;
     399    uint32_t u32Height;
     400    uint32_t u32Pitch;
     401    void *pvBuffer;
    398402    void *pvContext;
    399403    PFNCRSCREENSHOTBEGIN pfnScreenshotBegin;
  • trunk/src/VBox/GuestHost/OpenGL/Makefile.kmk

    r50095 r50364  
    8787        util/compositor.cpp \
    8888        util/htable.cpp \
     89        util/bmpscale.cpp \
    8990        util/vboxhgcm.c \
    9091        $(VBOX_PATH_CROGL_GENFILES)/debug_opcodes.c
  • trunk/src/VBox/GuestHost/OpenGL/include/cr_blitter.h

    r50313 r50364  
    8080        uint32_t ForceDrawBlit       : 1;
    8181        uint32_t ShadersGloal        : 1;
    82         uint32_t Entered             : 1;
    83         uint32_t Reserved            : 23;
     82        uint32_t Reserved            : 24;
    8483    };
    8584    uint32_t Value;
     
    122121    GLuint idFBO;
    123122    CR_BLITTER_FLAGS Flags;
     123    uint32_t cEnters;
    124124    PFNCRBLT_BLITTER pfnBlt;
    125125    CR_BLITTER_BUFFER Verticies;
     
    152152DECLINLINE(GLboolean) CrBltIsEntered(PCR_BLITTER pBlitter)
    153153{
    154     return pBlitter->Flags.Entered;
     154    return !!pBlitter->cEnters;
    155155}
    156156
     
    198198    struct
    199199    {
     200        uint32_t DataValid           : 1;
     201        uint32_t DataAcquired        : 1;
    200202        uint32_t DataInverted        : 1;
    201203        uint32_t Entered             : 1;
    202         uint32_t BltEntered          : 1;
    203         uint32_t Reserved            : 29;
     204        uint32_t Reserved            : 28;
    204205    };
    205206    uint32_t Value;
     
    219220    /*dtor*/
    220221    PFNCRTEXDATA_RELEASED pfnTextureReleased;
     222    struct CR_TEXDATA *pStretchedCache;
    221223} CR_TEXDATA, *PCR_TEXDATA;
    222224
     
    235237}
    236238
     239DECLINLINE(PCR_BLITTER) CrTdBlitterGet(CR_TEXDATA *pTex)
     240{
     241    return pTex->pBlitter;
     242}
     243
    237244DECLINLINE(int) CrTdBltEnter(PCR_TEXDATA pTex)
    238245{
     246    int rc;
    239247        if (pTex->Flags.Entered)
    240248                return VERR_INVALID_STATE;
    241         if (!CrBltIsEntered(pTex->pBlitter))
    242         {
    243                 int rc = CrBltEnter(pTex->pBlitter);
    244                 if (!RT_SUCCESS(rc))
    245                 {
    246                         WARN(("CrBltEnter failed rc %d", rc));
    247                         return rc;
    248                 }
    249                 pTex->Flags.BltEntered = 1;
    250         }
     249        rc = CrBltEnter(pTex->pBlitter);
     250    if (!RT_SUCCESS(rc))
     251    {
     252        WARN(("CrBltEnter failed rc %d", rc));
     253        return rc;
     254    }
    251255        pTex->Flags.Entered = 1;
    252256        return VINF_SUCCESS;
     
    266270        }
    267271
    268         if (pTex->Flags.BltEntered)
    269         {
    270                 CrBltLeave(pTex->pBlitter);
    271                 pTex->Flags.BltEntered = 0;
    272         }
     272        CrBltLeave(pTex->pBlitter);
    273273
    274274        pTex->Flags.Entered = 0;
     
    277277/* the CrTdBltXxx calls are done with the entered blitter */
    278278/* acquire the texture data, returns the cached data in case it is cached.
    279  * the data remains cached in the CR_TEXDATA object until it is discarded with CrTdBltDataDiscard or CrTdBltDataCleanup.
     279 * the data remains cached in the CR_TEXDATA object until it is discarded with CrTdBltDataFree or CrTdBltDataCleanup.
    280280 * */
    281281VBOXBLITTERDECL(int) CrTdBltDataAcquire(PCR_TEXDATA pTex, GLenum enmFormat, bool fInverted, const CR_BLITTER_IMG**ppImg);
    282 /* release the texture data, the data remains cached in the CR_TEXDATA object until it is discarded with CrTdBltDataDiscard or CrTdBltDataCleanup */
     282
     283VBOXBLITTERDECL(int) CrTdBltDataAcquireStretched(PCR_TEXDATA pTex, GLenum enmFormat, bool fInverted, uint32_t width, uint32_t height, const CR_BLITTER_IMG**ppImg);
     284
     285VBOXBLITTERDECL(int) CrTdBltDataReleaseStretched(PCR_TEXDATA pTex, const CR_BLITTER_IMG *pImg);
     286
     287VBOXBLITTERDECL(void) CrTdBltStretchCacheMoveTo(PCR_TEXDATA pTex, PCR_TEXDATA pDstTex);
     288
     289/* release the texture data, the data remains cached in the CR_TEXDATA object until it is discarded with CrTdBltDataFree or CrTdBltDataCleanup */
    283290VBOXBLITTERDECL(int) CrTdBltDataRelease(PCR_TEXDATA pTex);
    284291/* discard the texture data cached with previous CrTdBltDataAcquire.
    285292 * Must be called wit data released (CrTdBltDataRelease) */
    286 VBOXBLITTERDECL(int) CrTdBltDataDiscard(PCR_TEXDATA pTex);
    287 VBOXBLITTERDECL(int) CrTdBltDataDiscardNe(PCR_TEXDATA pTex);
    288 /* does same as CrTdBltDataDiscard, and in addition cleans up.
     293VBOXBLITTERDECL(int) CrTdBltDataFree(PCR_TEXDATA pTex);
     294VBOXBLITTERDECL(int) CrTdBltDataFreeNe(PCR_TEXDATA pTex);
     295VBOXBLITTERDECL(void) CrTdBltDataInvalidateNe(PCR_TEXDATA pTex);
     296/* does same as CrTdBltDataFree, and in addition cleans up.
    289297 * this is kind of a texture destructor, which clients should call on texture object destruction, e.g. from the PFNCRTEXDATA_RELEASED callback */
    290298VBOXBLITTERDECL(int) CrTdBltDataCleanup(PCR_TEXDATA pTex);
  • trunk/src/VBox/GuestHost/OpenGL/include/cr_server.h

    r50313 r50364  
    523523    CR_BLITTER_IMG Img;
    524524    uint32_t u32Screen;
    525     uint32_t fDataIsFbDirect;
     525    uint32_t fDataAllocated;
    526526} CR_SCREENSHOT;
    527527
    528 extern DECLEXPORT(int) crServerVBoxScreenshotGet(uint32_t u32Screen, CR_SCREENSHOT *pScreenshot);
     528extern DECLEXPORT(int) crServerVBoxScreenshotGet(uint32_t u32Screen, uint32_t width, uint32_t height, uint32_t pitch, void *pvBuffer, CR_SCREENSHOT *pScreenshot);
    529529extern DECLEXPORT(void) crServerVBoxScreenshotRelease(CR_SCREENSHOT *pScreenshot);
    530530
  • trunk/src/VBox/GuestHost/OpenGL/util/blitter.cpp

    r50313 r50364  
    9898    if (CrBltIsEntered(pBlitter))
    9999    {
    100         crWarning("CrBltBlitTexTex: blitter is entered");
     100        WARN(("CrBltBlitTexTex: blitter is entered"));
    101101        return VERR_INVALID_STATE;
    102102    }
     
    108108    if (!RT_SUCCESS(rc))
    109109    {
    110         crWarning("CrBltEnter failed, rc %d", rc);
     110        WARN(("CrBltEnter failed, rc %d", rc));
    111111        return rc;
    112112    }
     
    138138        if (CrBltIsEntered(pBlitter))
    139139        {
    140             crWarning("can not set null mural for entered bleater");
     140            WARN(("can not set null mural for entered bleater"));
    141141            return VERR_INVALID_STATE;
    142142        }
     
    152152    else if (!pBlitter->CtxInfo.Base.id)
    153153    {
    154         crWarning("setting current mural for entered no-context blitter");
     154        WARN(("setting current mural for entered no-context blitter"));
    155155        return VERR_INVALID_STATE;
    156156    }
    157157
    158     crWarning("changing mural for entered blitter, is is somewhat expected?");
     158    WARN(("changing mural for entered blitter, is is somewhat expected?"));
    159159
    160160    pBlitter->pDispatch->Flush();
     
    548548void CrBltLeave(PCR_BLITTER pBlitter)
    549549{
    550     if (!CrBltIsEntered(pBlitter))
    551     {
    552         WARN(("CrBltLeave: blitter not entered"));
     550    if (!pBlitter->cEnters)
     551    {
     552        WARN(("blitter not entered!"));
    553553        return;
    554554    }
     555
     556    if (--pBlitter->cEnters)
     557        return;
    555558
    556559    if (pBlitter->Flags.SupportsFBO)
     
    565568    if (pBlitter->CtxInfo.Base.id)
    566569        pBlitter->pDispatch->MakeCurrent(0, 0, 0);
    567 
    568     pBlitter->Flags.Entered = 0;
    569570}
    570571
     
    577578    }
    578579
    579     if (CrBltIsEntered(pBlitter))
    580     {
    581         WARN(("blitter is entered already!"));
    582         return VERR_INVALID_STATE;
    583     }
     580    if (pBlitter->cEnters++)
     581        return VINF_SUCCESS;
    584582
    585583    if (pBlitter->CurrentMural.Base.id) /* <- pBlitter->CurrentMural.Base.id can be null if the blitter is in a "no-context" mode (see comments to BltInit for detail)*/
     
    587585        pBlitter->pDispatch->MakeCurrent(pBlitter->CurrentMural.Base.id, pBlitter->i32MakeCurrentUserData, pBlitter->CtxInfo.Base.id);
    588586    }
    589 
    590     pBlitter->Flags.Entered = 1;
    591587
    592588    if (pBlitter->Flags.Initialized)
     
    647643    if (!CrBltIsEntered(pBlitter))
    648644    {
    649         crWarning("CrBltBlitTexMural: blitter not entered");
     645        WARN(("CrBltBlitTexMural: blitter not entered"));
    650646        return;
    651647    }
     
    662658    if (!CrBltIsEntered(pBlitter))
    663659    {
    664         crWarning("CrBltBlitTexTex: blitter not entered");
     660        WARN(("CrBltBlitTexTex: blitter not entered"));
    665661        return;
    666662    }
     
    686682    if (!CrBltIsEntered(pBlitter))
    687683    {
    688         crWarning("CrBltPresent: blitter not entered");
     684        WARN(("CrBltPresent: blitter not entered"));
    689685        return;
    690686    }
     
    702698            && enmFormat != GL_BGRA)
    703699    {
    704         crWarning("unsupported format 0x%x", enmFormat);
     700        WARN(("unsupported format 0x%x", enmFormat));
    705701        return VERR_NOT_IMPLEMENTED;
    706702    }
     
    752748    if (!CrBltIsEntered(pBlitter))
    753749    {
    754         crWarning("CrBltImgGetTex: blitter not entered");
     750        WARN(("CrBltImgGetTex: blitter not entered"));
    755751        return VERR_INVALID_STATE;
    756752    }
     
    787783    if (!CrBltIsEntered(pBlitter))
    788784    {
    789         crWarning("CrBltImgGetMural: blitter not entered");
     785        WARN(("CrBltImgGetMural: blitter not entered"));
    790786        return VERR_INVALID_STATE;
    791787    }
     
    799795    if (!CrBltIsEntered(pBlitter))
    800796    {
    801         crWarning("CrBltImgFree: blitter not entered");
     797        WARN(("CrBltImgFree: blitter not entered"));
    802798        return;
    803799    }
     
    11271123
    11281124/*TdBlt*/
    1129 
    11301125static void crTdBltCheckPBO(PCR_TEXDATA pTex)
    11311126{
     
    11521147}
    11531148
    1154 static uint32_t crTdBltTexCreate(PCR_TEXDATA pTex)
    1155 {
    1156         PCR_BLITTER pBlitter = pTex->pBlitter;
     1149static uint32_t crTdBltTexCreate(PCR_BLITTER pBlitter, uint32_t width, uint32_t height, GLenum enmTarget)
     1150{
    11571151    uint32_t tex = 0;
    11581152    pBlitter->pDispatch->GenTextures(1, &tex);
     
    11631157    }
    11641158
    1165     pBlitter->pDispatch->BindTexture(GL_TEXTURE_2D, tex);
    1166     pBlitter->pDispatch->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    1167     pBlitter->pDispatch->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    1168     pBlitter->pDispatch->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    1169     pBlitter->pDispatch->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    1170     pBlitter->pDispatch->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,
    1171             pTex->Tex.width,
    1172             pTex->Tex.height,
     1159    pBlitter->pDispatch->BindTexture(enmTarget, tex);
     1160    pBlitter->pDispatch->TexParameteri(enmTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     1161    pBlitter->pDispatch->TexParameteri(enmTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     1162    pBlitter->pDispatch->TexParameteri(enmTarget, GL_TEXTURE_WRAP_S, GL_CLAMP);
     1163    pBlitter->pDispatch->TexParameteri(enmTarget, GL_TEXTURE_WRAP_T, GL_CLAMP);
     1164    pBlitter->pDispatch->TexImage2D(enmTarget, 0, GL_RGBA8,
     1165            width, height,
    11731166            0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
    11741167
    11751168
    11761169    /*Restore gl state*/
    1177     pBlitter->pDispatch->BindTexture(GL_TEXTURE_2D, 0);
     1170    pBlitter->pDispatch->BindTexture(enmTarget, 0);
    11781171
    11791172    return tex;
     
    11851178        return VINF_SUCCESS;
    11861179
    1187     pTex->idInvertTex = crTdBltTexCreate(pTex);
     1180    pTex->idInvertTex = crTdBltTexCreate(pTex->pBlitter, pTex->Tex.width, pTex->Tex.height, pTex->Tex.target);
    11881181    if (!pTex->idInvertTex)
    11891182    {
     
    11941187}
    11951188
     1189void crTdBltImgRelease(PCR_TEXDATA pTex)
     1190{
     1191    pTex->Flags.DataValid = 0;
     1192}
     1193
    11961194void crTdBltImgFree(PCR_TEXDATA pTex)
    11971195{
    11981196    if (!pTex->Img.pvData)
     1197    {
     1198        Assert(!pTex->Flags.DataValid);
    11991199        return;
    1200 
    1201     PCR_BLITTER pBlitter = pTex->pBlitter;
     1200    }
     1201
     1202    crTdBltImgRelease(pTex);
     1203
     1204    Assert(!pTex->Flags.DataValid);
     1205
    12021206
    12031207    if (pTex->idPBO)
    12041208    {
     1209        PCR_BLITTER pBlitter = pTex->pBlitter;
     1210
    12051211        Assert(CrBltIsEntered(pBlitter));
    12061212        pBlitter->pDispatch->BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pTex->idPBO);
     
    12091215    }
    12101216    else
     1217    {
     1218        Assert(pTex->Img.pvData);
    12111219        RTMemFree(pTex->Img.pvData);
     1220    }
    12121221
    12131222    pTex->Img.pvData = NULL;
     
    12161225int crTdBltImgAcquire(PCR_TEXDATA pTex, GLenum enmFormat, bool fInverted)
    12171226{
     1227    void *pvData = pTex->Img.pvData;
     1228    Assert(!pTex->Flags.DataValid);
    12181229    int rc = crBltImgInitBaseForTex(&pTex->Tex, &pTex->Img, enmFormat);
    12191230    if (!RT_SUCCESS(rc))
    12201231    {
    1221         crWarning("crBltImgInitBaseForTex failed rc %d", rc);
     1232        WARN(("crBltImgInitBaseForTex failed rc %d", rc));
    12221233        return rc;
    12231234    }
    12241235
    12251236    PCR_BLITTER pBlitter = pTex->pBlitter;
    1226     void *pvData = NULL;
     1237    Assert(CrBltIsEntered(pBlitter));
    12271238    pBlitter->pDispatch->BindTexture(pTex->Tex.target, fInverted ? pTex->idInvertTex : pTex->Tex.hwid);
    12281239
    12291240    pBlitter->pDispatch->BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pTex->idPBO);
    12301241
    1231     if (!pTex->idPBO)
    1232     {
    1233         pvData = RTMemAlloc(4*pTex->Tex.width*pTex->Tex.height);
    1234         if (!pvData)
    1235         {
    1236             crWarning("Out of memory in crTdBltImgAcquire");
    1237             return VERR_NO_MEMORY;
    1238         }
    1239     }
     1242    if (pvData)
     1243    {
     1244        if (pTex->idPBO)
     1245        {
     1246            pBlitter->pDispatch->UnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
     1247            pvData = NULL;
     1248
     1249        }
     1250    }
     1251    else
     1252    {
     1253        if (!pTex->idPBO)
     1254        {
     1255            pvData = RTMemAlloc(4*pTex->Tex.width*pTex->Tex.height);
     1256            if (!pvData)
     1257            {
     1258                WARN(("Out of memory in crTdBltImgAcquire"));
     1259                pBlitter->pDispatch->BindTexture(pTex->Tex.target, 0);
     1260                return VERR_NO_MEMORY;
     1261            }
     1262        }
     1263    }
     1264
     1265    Assert(!pvData == !!pTex->idPBO);
    12401266
    12411267    /*read the texture, note pixels are NULL for PBO case as it's offset in the buffer*/
     
    12501276        if (!pvData)
    12511277        {
    1252             crWarning("Failed to MapBuffer in CrHlpGetTexImage");
     1278            WARN(("Failed to MapBuffer in CrHlpGetTexImage"));
    12531279            return VERR_GENERAL_FAILURE;
    12541280        }
     
    12571283    }
    12581284
    1259     CRASSERT(pvData);
     1285    Assert(pvData);
    12601286    pTex->Img.pvData = pvData;
     1287    pTex->Flags.DataValid = 1;
    12611288    pTex->Flags.DataInverted = fInverted;
    12621289    return VINF_SUCCESS;
    12631290}
    12641291
    1265 /* release the texture data, the data remains cached in the CR_TEXDATA object until it is discarded with CrTdBltDataDiscard or CrTdBltDataCleanup */
     1292/* release the texture data, the data remains cached in the CR_TEXDATA object until it is discarded with CrTdBltDataInvalidateNe or CrTdBltDataCleanup */
    12661293VBOXBLITTERDECL(int) CrTdBltDataRelease(PCR_TEXDATA pTex)
    12671294{
     
    12711298        return VERR_INVALID_STATE;
    12721299    }
     1300
     1301    if (!pTex->Flags.DataAcquired)
     1302    {
     1303        WARN(("Data NOT acquired"));
     1304        return VERR_INVALID_STATE;
     1305    }
     1306
    12731307    Assert(pTex->Img.pvData);
    1274     return VINF_SUCCESS;
     1308    Assert(pTex->Flags.DataValid);
     1309
     1310    pTex->Flags.DataAcquired = 0;
     1311
     1312    return VINF_SUCCESS;
     1313}
     1314
     1315static void crTdBltDataFree(PCR_TEXDATA pTex)
     1316{
     1317    crTdBltImgFree(pTex);
     1318
     1319    if (pTex->pStretchedCache)
     1320        CrTdBltDataFreeNe(pTex->pStretchedCache);
    12751321}
    12761322
    12771323/* discard the texture data cached with previous CrTdBltDataAcquire.
    12781324 * Must be called wit data released (CrTdBltDataRelease) */
    1279 VBOXBLITTERDECL(int) CrTdBltDataDiscard(PCR_TEXDATA pTex)
     1325VBOXBLITTERDECL(int) CrTdBltDataFree(PCR_TEXDATA pTex)
    12801326{
    12811327    if (!pTex->Flags.Entered)
     
    12851331    }
    12861332
    1287     crTdBltImgFree(pTex);
    1288 
    1289     return VINF_SUCCESS;
    1290 }
    1291 
    1292 VBOXBLITTERDECL(int) CrTdBltDataDiscardNe(PCR_TEXDATA pTex)
     1333    crTdBltDataFree(pTex);
     1334
     1335    return VINF_SUCCESS;
     1336}
     1337
     1338VBOXBLITTERDECL(void) CrTdBltDataInvalidateNe(PCR_TEXDATA pTex)
     1339{
     1340    crTdBltImgRelease(pTex);
     1341
     1342    if (pTex->pStretchedCache)
     1343        CrTdBltDataInvalidateNe(pTex->pStretchedCache);
     1344}
     1345
     1346VBOXBLITTERDECL(int) CrTdBltDataFreeNe(PCR_TEXDATA pTex)
    12931347{
    12941348    if (!pTex->Img.pvData)
     
    13081362    }
    13091363
    1310     crTdBltImgFree(pTex);
     1364    crTdBltDataFree(pTex);
    13111365
    13121366    if (fEntered)
     
    13141368
    13151369    return VINF_SUCCESS;
     1370}
     1371
     1372static void crTdBltSdCleanupCacheNe(PCR_TEXDATA pTex)
     1373{
     1374    if (pTex->pStretchedCache)
     1375    {
     1376        CrTdBltDataCleanupNe(pTex->pStretchedCache);
     1377        CrTdRelease(pTex->pStretchedCache);
     1378        pTex->pStretchedCache = NULL;
     1379    }
    13161380}
    13171381
     
    13351399        pTex->idInvertTex = 0;
    13361400    }
    1337 }
    1338 
    1339 /* does same as CrTdBltDataDiscard, and in addition cleans up */
     1401
     1402    crTdBltSdCleanupCacheNe(pTex);
     1403}
     1404
     1405/* does same as CrTdBltDataFree, and in addition cleans up */
    13401406VBOXBLITTERDECL(int) CrTdBltDataCleanup(PCR_TEXDATA pTex)
    13411407{
     
    13751441
    13761442/* acquire the texture data, returns the cached data in case it is cached.
    1377  * the data remains cached in the CR_TEXDATA object until it is discarded with CrTdBltDataDiscard or CrTdBltDataCleanup.
     1443 * the data remains cached in the CR_TEXDATA object until it is discarded with CrTdBltDataFree or CrTdBltDataCleanup.
    13781444 * */
    13791445VBOXBLITTERDECL(int) CrTdBltDataAcquire(PCR_TEXDATA pTex, GLenum enmFormat, bool fInverted, const CR_BLITTER_IMG**ppImg)
     
    13851451    }
    13861452
    1387     if (pTex->Img.pvData && pTex->Img.enmFormat == enmFormat && !pTex->Flags.DataInverted == !fInverted)
    1388     {
     1453    if (pTex->Flags.DataAcquired)
     1454    {
     1455        WARN(("Data acquired already"));
     1456        return VERR_INVALID_STATE;
     1457    }
     1458
     1459    if (pTex->Flags.DataValid && pTex->Img.enmFormat == enmFormat && !pTex->Flags.DataInverted == !fInverted)
     1460    {
     1461        Assert(pTex->Img.pvData);
    13891462        *ppImg = &pTex->Img;
     1463        pTex->Flags.DataAcquired = 1;
    13901464        return VINF_SUCCESS;
    13911465    }
    13921466
    1393     crTdBltImgFree(pTex);
     1467    crTdBltImgRelease(pTex);
    13941468
    13951469    crTdBltCheckPBO(pTex);
     
    14321506    }
    14331507
     1508    Assert(pTex->Img.pvData);
    14341509    *ppImg = &pTex->Img;
    1435 
    1436     return VINF_SUCCESS;
    1437 }
     1510    pTex->Flags.DataAcquired = 1;
     1511
     1512    return VINF_SUCCESS;
     1513}
     1514
     1515DECLINLINE(void) crTdResize(PCR_TEXDATA pTex, const VBOXVR_TEXTURE *pVrTex)
     1516{
     1517    crTdBltDataCleanup(pTex);
     1518
     1519    pTex->Tex = *pVrTex;
     1520}
     1521
     1522static DECLCALLBACK(void) ctTdBltSdReleased(struct CR_TEXDATA *pTexture)
     1523{
     1524    PCR_BLITTER pBlitter = pTexture->pBlitter;
     1525
     1526    int rc = CrBltEnter(pBlitter);
     1527    if (!RT_SUCCESS(rc))
     1528    {
     1529        WARN(("CrBltEnter failed, rc %d", rc));
     1530        return;
     1531    }
     1532
     1533    CrTdBltDataCleanupNe(pTexture);
     1534
     1535    pBlitter->pDispatch->DeleteTextures(1, &pTexture->Tex.hwid);
     1536
     1537    CrBltLeave(pBlitter);
     1538
     1539    RTMemFree(pTexture);
     1540}
     1541
     1542static int ctTdBltSdCreate(PCR_BLITTER pBlitter, uint32_t width, uint32_t height, GLenum enmTarget, PCR_TEXDATA *ppStretchedCache)
     1543{
     1544    PCR_TEXDATA pStretchedCache;
     1545
     1546    Assert(CrBltIsEntered(pBlitter));
     1547
     1548    *ppStretchedCache = NULL;
     1549
     1550    pStretchedCache = (PCR_TEXDATA)RTMemAlloc(sizeof (*pStretchedCache));
     1551    if (!pStretchedCache)
     1552    {
     1553        WARN(("RTMemAlloc failed"));
     1554        return VERR_NO_MEMORY;
     1555    }
     1556
     1557    VBOXVR_TEXTURE Tex;
     1558    Tex.width = width;
     1559    Tex.height = height;
     1560    Tex.target = enmTarget;
     1561    Tex.hwid = crTdBltTexCreate(pBlitter, width, height, enmTarget);
     1562    if (!Tex.hwid)
     1563    {
     1564        WARN(("Tex create failed"));
     1565        RTMemFree(pStretchedCache);
     1566        return VERR_GENERAL_FAILURE;
     1567    }
     1568
     1569    CrTdInit(pStretchedCache, &Tex, pBlitter, ctTdBltSdReleased);
     1570
     1571    *ppStretchedCache = pStretchedCache;
     1572
     1573    return VINF_SUCCESS;
     1574}
     1575
     1576static int ctTdBltSdGet(PCR_TEXDATA pTex, uint32_t width, uint32_t height, PCR_TEXDATA *ppStretchedCache)
     1577{
     1578    Assert(pTex->Flags.Entered);
     1579
     1580    PCR_TEXDATA pStretchedCache;
     1581
     1582    *ppStretchedCache = NULL;
     1583
     1584    if (!pTex->pStretchedCache)
     1585    {
     1586        int rc = ctTdBltSdCreate(pTex->pBlitter, width, height, pTex->Tex.target, &pStretchedCache);
     1587        if (!RT_SUCCESS(rc))
     1588        {
     1589            WARN(("ctTdBltSdCreate failed %d", rc));
     1590            return rc;
     1591        }
     1592
     1593        pTex->pStretchedCache = pStretchedCache;
     1594    }
     1595    else
     1596    {
     1597        int cmp = pTex->pStretchedCache->Tex.width - width;
     1598        if (cmp <= 0)
     1599            cmp = pTex->pStretchedCache->Tex.height - height;
     1600
     1601        if (!cmp)
     1602            pStretchedCache = pTex->pStretchedCache;
     1603        else if (cmp < 0) /* current cache is "less" than the requested */
     1604        {
     1605            int rc = ctTdBltSdCreate(pTex->pBlitter, width, height, pTex->Tex.target, &pStretchedCache);
     1606            if (!RT_SUCCESS(rc))
     1607            {
     1608                WARN(("ctTdBltSdCreate failed %d", rc));
     1609                return rc;
     1610            }
     1611
     1612            pStretchedCache->pStretchedCache = pTex->pStretchedCache;
     1613            pTex->pStretchedCache = pStretchedCache;
     1614        }
     1615        else /* cmp > 0 */
     1616        {
     1617            int rc = ctTdBltSdGet(pTex->pStretchedCache, width, height, &pStretchedCache);
     1618            if (!RT_SUCCESS(rc))
     1619            {
     1620                WARN(("ctTdBltSdGet failed %d", rc));
     1621                return rc;
     1622            }
     1623        }
     1624    }
     1625
     1626    Assert(pStretchedCache);
     1627
     1628#if 0
     1629    {
     1630        VBOXVR_TEXTURE Tex;
     1631        Tex.width = width;
     1632        Tex.height = height;
     1633        Tex.target = pTex->Tex.target;
     1634        Tex.hwid = crTdBltTexCreate(pTex, width, height);
     1635        if (!Tex.hwid)
     1636        {
     1637            WARN(("Tex create failed"));
     1638            return VERR_GENERAL_FAILURE;
     1639        }
     1640
     1641        pTex->pBlitter->pDispatch->DeleteTextures(1, &pTex->pStretchedCache->Tex.hwid);
     1642
     1643        crTdResize(pTex->pStretchedCache, &Tex);
     1644    }
     1645#endif
     1646
     1647    *ppStretchedCache = pStretchedCache;
     1648    return VINF_SUCCESS;
     1649}
     1650
     1651static int ctTdBltSdGetUpdated(PCR_TEXDATA pTex, uint32_t width, uint32_t height, PCR_TEXDATA *ppStretchedCache)
     1652{
     1653    PCR_TEXDATA pStretchedCache;
     1654
     1655    *ppStretchedCache = NULL;
     1656    int rc = ctTdBltSdGet(pTex, width, height, &pStretchedCache);
     1657    if (!RT_SUCCESS(rc))
     1658    {
     1659        WARN(("ctTdBltSdGet failed %d", rc));
     1660        return rc;
     1661    }
     1662
     1663    Assert(width == pStretchedCache->Tex.width);
     1664    Assert(height == pStretchedCache->Tex.height);
     1665
     1666    if (!pStretchedCache->Flags.DataValid)
     1667    {
     1668        RTRECT SrcRect, DstRect;
     1669
     1670        SrcRect.xLeft = 0;
     1671        SrcRect.yTop = 0;
     1672        SrcRect.xRight = pTex->Tex.width;
     1673        SrcRect.yBottom = pTex->Tex.height;
     1674
     1675        DstRect.xLeft = 0;
     1676        DstRect.yTop = 0;
     1677        DstRect.xRight = width;
     1678        DstRect.yBottom = height;
     1679
     1680        CrBltBlitTexTex(pTex->pBlitter, &pTex->Tex, &SrcRect, &pStretchedCache->Tex, &DstRect, 1, 0);
     1681    }
     1682
     1683    *ppStretchedCache = pStretchedCache;
     1684
     1685    return VINF_SUCCESS;
     1686}
     1687
     1688VBOXBLITTERDECL(int) CrTdBltDataAcquireStretched(PCR_TEXDATA pTex, GLenum enmFormat, bool fInverted, uint32_t width, uint32_t height, const CR_BLITTER_IMG**ppImg)
     1689{
     1690    if (pTex->Tex.width == width && pTex->Tex.height == height)
     1691        return CrTdBltDataAcquire(pTex, enmFormat, fInverted, ppImg);
     1692
     1693    if (!pTex->Flags.Entered)
     1694    {
     1695        WARN(("tex not entered"));
     1696        return VERR_INVALID_STATE;
     1697    }
     1698
     1699    PCR_TEXDATA pStretchedCache;
     1700
     1701    int rc = ctTdBltSdGetUpdated(pTex, width, height, &pStretchedCache);
     1702    if (!RT_SUCCESS(rc))
     1703    {
     1704        WARN(("ctTdBltSdGetUpdated failed rc %d", rc));
     1705        return rc;
     1706    }
     1707
     1708    rc = CrTdBltEnter(pStretchedCache);
     1709    if (!RT_SUCCESS(rc))
     1710    {
     1711        WARN(("CrTdBltEnter failed rc %d", rc));
     1712        return rc;
     1713    }
     1714
     1715    rc = CrTdBltDataAcquire(pStretchedCache, enmFormat, fInverted, ppImg);
     1716    if (!RT_SUCCESS(rc))
     1717    {
     1718        WARN(("CrTdBltDataAcquire failed rc %d", rc));
     1719        CrTdBltLeave(pTex->pStretchedCache);
     1720        return rc;
     1721    }
     1722
     1723    return VINF_SUCCESS;
     1724}
     1725
     1726VBOXBLITTERDECL(int) CrTdBltDataReleaseStretched(PCR_TEXDATA pTex, const CR_BLITTER_IMG *pImg)
     1727{
     1728    PCR_TEXDATA pStretchedCache = RT_FROM_MEMBER(pImg, CR_TEXDATA, Img);
     1729    int rc = CrTdBltDataRelease(pStretchedCache);
     1730    if (!RT_SUCCESS(rc))
     1731    {
     1732        WARN(("CrTdBltDataRelease failed rc %d", rc));
     1733        return rc;
     1734    }
     1735
     1736    if (pStretchedCache != pTex)
     1737        CrTdBltLeave(pStretchedCache);
     1738
     1739    return VINF_SUCCESS;
     1740}
     1741
     1742VBOXBLITTERDECL(void) CrTdBltStretchCacheMoveTo(PCR_TEXDATA pTex, PCR_TEXDATA pDstTex)
     1743{
     1744    if (!pTex->pStretchedCache)
     1745        return;
     1746
     1747    crTdBltSdCleanupCacheNe(pDstTex);
     1748
     1749    pDstTex->pStretchedCache = pTex->pStretchedCache;
     1750    pTex->pStretchedCache = NULL;
     1751}
  • trunk/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp

    r50341 r50364  
    939939        CR_SCREENSHOT Screenshot;
    940940
    941         int rc = crServerVBoxScreenshotGet(idScreen, &Screenshot);
     941        int rc = crServerVBoxScreenshotGet(idScreen, pScreenshot->u32Width, pScreenshot->u32Height, pScreenshot->u32Pitch, pScreenshot->pvBuffer, &Screenshot);
    942942        if (RT_SUCCESS(rc))
    943943        {
    944             pScreenshot->pfnScreenshotPerform(pScreenshot->pvContext, idScreen,
    945                     0, 0, 32,
    946                     Screenshot.Img.pitch, Screenshot.Img.width, Screenshot.Img.height,
    947                     (uint8_t*)Screenshot.Img.pvData, u64Now);
     944            if (pScreenshot->pfnScreenshotPerform)
     945                pScreenshot->pfnScreenshotPerform(pScreenshot->pvContext, idScreen,
     946                        0, 0, 32,
     947                        Screenshot.Img.pitch, Screenshot.Img.width, Screenshot.Img.height,
     948                        (uint8_t*)Screenshot.Img.pvData, u64Now);
    948949            crServerVBoxScreenshotRelease(&Screenshot);
    949950        }
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h

    r50318 r50364  
    425425void CrFbVisitCreatedEntries(HCR_FRAMEBUFFER hFb, PFNCR_FRAMEBUFFER_ENTRIES_VISITOR_CB pfnVisitorCb, void *pvContext);
    426426int CrFbResize(HCR_FRAMEBUFFER hFb, const struct VBVAINFOSCREEN * pScreen, void *pvVRAM);
    427 int CrFbBltGetContents(HCR_FRAMEBUFFER hFb, const RTPOINT *pPoint, uint32_t cRects, const RTRECT *pPrects, CR_BLITTER_IMG *pImg);
     427int CrFbBltGetContents(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, uint32_t cRects, const RTRECT *pPrects, CR_BLITTER_IMG *pImg);
    428428bool CrFbIsEnabled(HCR_FRAMEBUFFER hFb);
    429429int CrFbEntryCreateForTexId(HCR_FRAMEBUFFER hFb, GLuint idTex, uint32_t fFlags, HCR_FRAMEBUFFER_ENTRY *phEntry);
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.cpp

    r50313 r50364  
    658658}
    659659
    660 DECLEXPORT(int) crServerVBoxScreenshotGet(uint32_t u32Screen, CR_SCREENSHOT *pScreenshot)
     660DECLEXPORT(void) crServerVBoxScreenshotRelease(CR_SCREENSHOT *pScreenshot)
     661{
     662    if (pScreenshot->fDataAllocated)
     663    {
     664        RTMemFree(pScreenshot->Img.pvData);
     665        pScreenshot->fDataAllocated = 0;
     666    }
     667}
     668
     669DECLEXPORT(int) crServerVBoxScreenshotGet(uint32_t u32Screen, uint32_t width, uint32_t height, uint32_t pitch, void *pvBuffer, CR_SCREENSHOT *pScreenshot)
    661670{
    662671    HCR_FRAMEBUFFER hFb = CrPMgrFbGetEnabled(u32Screen);
     
    666675    const VBVAINFOSCREEN *pScreen = CrFbGetScreenInfo(hFb);
    667676
    668     if (CrFbHas3DData(hFb))
    669     {
    670         RTPOINT Pos = {0, 0};
     677    if (!width)
     678        width = pScreen->u32Width;
     679    if (!height)
     680        height = pScreen->u32Height;
     681    if (!pitch)
     682        pitch = pScreen->u32LineSize;
     683
     684    if (CrFbHas3DData(hFb)
     685            || pScreen->u32Width != width
     686            || pScreen->u32Height != height
     687            || pScreen->u32LineSize != pitch
     688            || pScreen->u16BitsPerPixel != 32)
     689    {
    671690        RTRECT Rect;
    672691
    673692        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;
     693        if (!pvBuffer)
     694        {
     695            pScreenshot->Img.pvData = RTMemAlloc(pScreenshot->Img.cbData);
     696            if (!pScreenshot->Img.pvData)
     697            {
     698                WARN(("RTMemAlloc failed"));
     699                return VERR_NO_MEMORY;
     700            }
     701            pScreenshot->fDataAllocated = 1;
     702        }
     703        else
     704        {
     705            pScreenshot->Img.pvData = pvBuffer;
     706            pScreenshot->fDataAllocated = 0;
     707        }
     708
     709        pScreenshot->Img.enmFormat = GL_BGRA;
     710        pScreenshot->Img.width = width;
     711        pScreenshot->Img.height = height;
     712        pScreenshot->Img.bpp = 32;
     713        pScreenshot->Img.pitch = pitch;
     714        Rect.xLeft = 0;
     715        Rect.yTop = 0;
     716        Rect.xRight = pScreen->u32Width;
     717        Rect.yBottom = pScreen->u32Height;
     718        int rc = CrFbBltGetContents(hFb, &Rect, 1, &Rect, &pScreenshot->Img);
     719        if (!RT_SUCCESS(rc))
     720        {
     721            WARN(("CrFbBltGetContents failed %d", rc));
     722            crServerVBoxScreenshotRelease(pScreenshot);
     723            return rc;
     724        }
     725    }
     726    else
     727    {
     728        pScreenshot->Img.cbData = pScreen->u32LineSize * pScreen->u32Height;
     729        if (!pvBuffer)
     730            pScreenshot->Img.pvData = CrFbGetVRAM(hFb);
     731        else
     732        {
     733            pScreenshot->Img.pvData = pvBuffer;
     734            memcpy(pvBuffer, CrFbGetVRAM(hFb), pScreenshot->Img.cbData);
    679735        }
    680736        pScreenshot->Img.enmFormat = GL_BGRA;
     
    683739        pScreenshot->Img.bpp = pScreen->u16BitsPerPixel;
    684740        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;
     741
     742        pScreenshot->fDataAllocated = 0;
    709743    }
    710744
     
    712746
    713747    return VINF_SUCCESS;
    714 }
    715 
    716 DECLEXPORT(void) crServerVBoxScreenshotRelease(CR_SCREENSHOT *pScreenshot)
    717 {
    718     if (!pScreenshot->fDataIsFbDirect)
    719     {
    720         RTMemFree(pScreenshot->Img.pvData);
    721         pScreenshot->fDataIsFbDirect = 1;
    722     }
    723748}
    724749
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp

    r50313 r50364  
    2727#include <cr_vreg.h>
    2828#include <cr_htable.h>
     29#include <cr_bmpscale.h>
    2930
    3031#include <iprt/cdefs.h>
     
    8384    CRHTABLE SlotTable;
    8485} CR_FRAMEBUFFER;
     86
     87typedef union CR_FBENTRY_FLAGS
     88{
     89    struct {
     90        uint32_t fCreateNotified : 1;
     91        uint32_t fInList         : 1;
     92        uint32_t Reserved        : 30;
     93    };
     94    uint32_t Value;
     95} CR_FBENTRY_FLAGS;
     96
     97typedef struct CR_FRAMEBUFFER_ENTRY
     98{
     99    VBOXVR_SCR_COMPOSITOR_ENTRY Entry;
     100    RTLISTNODE Node;
     101    uint32_t cRefs;
     102    CR_FBENTRY_FLAGS Flags;
     103    CRHTABLE HTable;
     104} CR_FRAMEBUFFER_ENTRY;
     105
     106typedef struct CR_FBTEX
     107{
     108    CR_TEXDATA Tex;
     109    CRTextureObj *pTobj;
     110} CR_FBTEX;
     111
     112#define PCR_FBTEX_FROM_TEX(_pTex) ((CR_FBTEX*)((uint8_t*)(_pTex) - RT_OFFSETOF(CR_FBTEX, Tex)))
     113#define PCR_FRAMEBUFFER_FROM_COMPOSITOR(_pCompositor) ((CR_FRAMEBUFFER*)((uint8_t*)(_pCompositor) - RT_OFFSETOF(CR_FRAMEBUFFER, Compositor)))
     114#define PCR_FBENTRY_FROM_ENTRY(_pEntry) ((CR_FRAMEBUFFER_ENTRY*)((uint8_t*)(_pEntry) - RT_OFFSETOF(CR_FRAMEBUFFER_ENTRY, Entry)))
     115
    85116
    86117typedef struct CR_FBDISPLAY_INFO
     
    234265}
    235266
    236 int CrFbBltGetContents(HCR_FRAMEBUFFER hFb, const RTPOINT *pPoint, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg)
     267static void crFbBltImgStretched(void *pvSrc, const RTRECT *pSrcDataRect, bool fSrcInvert, const RTRECT *pCopyRect, const RTPOINT *pDstDataPoint, float strX, float strY, CR_BLITTER_IMG *pDst)
     268{
     269    int32_t cbSrcPitch = (pSrcDataRect->xRight - pSrcDataRect->xLeft) * 4;
     270    int32_t srcX = pCopyRect->xLeft - pSrcDataRect->xLeft;
     271    int32_t srcY = pCopyRect->yTop - pSrcDataRect->yTop;
     272    Assert(srcX >= 0);
     273    Assert(srcY >= 0);
     274    Assert(srcX < pSrcDataRect->xRight - pSrcDataRect->xLeft);
     275    Assert(srcY < pSrcDataRect->yBottom - pSrcDataRect->yTop);
     276
     277    int32_t cbDstPitch = (int32_t)pDst->pitch;
     278    int32_t dstX = static_cast<uint32_t>(strX * pCopyRect->xLeft - pDstDataPoint->x);
     279    int32_t dstY = static_cast<uint32_t>(strY * pCopyRect->yTop - pDstDataPoint->y);
     280    Assert(dstX >= 0);
     281    Assert(dstY >= 0);
     282
     283    uint8_t *pu8Src = ((uint8_t*)pvSrc) + cbSrcPitch * (!fSrcInvert ? srcY : pSrcDataRect->yBottom - pSrcDataRect->yTop - srcY - 1) + srcX * 4;
     284    uint8_t *pu8Dst = ((uint8_t*)pDst->pvData) + cbDstPitch * dstY + dstX * 4;
     285    if (fSrcInvert)
     286        cbSrcPitch = -cbSrcPitch;
     287
     288    int srcW = pCopyRect->xRight - pCopyRect->xLeft;
     289    int srcH = pCopyRect->yBottom - pCopyRect->yTop;
     290    int dstW = static_cast<uint32_t>(strX * srcW);
     291    int dstH = static_cast<uint32_t>(strY * srcH);
     292
     293    CrBmpScale32(pu8Dst, cbDstPitch,
     294                            dstW, dstH,
     295                            pu8Src,
     296                            cbSrcPitch,
     297                            srcW, srcH);
     298}
     299
     300
     301static int crFbBltGetContentsDirect(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg)
    237302{
    238303    VBOXVR_LIST List;
    239304    uint32_t c2DRects = 0;
    240305    CR_TEXDATA *pEnteredTex = NULL;
     306    PCR_BLITTER pEnteredBlitter = NULL;
     307
     308    VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR Iter;
     309    RTPOINT SrcPoint = {pSrcRect->xLeft, pSrcRect->yTop};
     310    float strX = ((float)pImg->width) / (pSrcRect->xRight - pSrcRect->xLeft);
     311    float strY = ((float)pImg->height) / (pSrcRect->yBottom - pSrcRect->yTop);
     312
    241313    VBoxVrListInit(&List);
    242314    int rc = VBoxVrListRectsAdd(&List, 1, CrVrScrCompositorRectGet(&hFb->Compositor), NULL);
     
    247319    }
    248320
    249     VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR Iter;
    250 
    251321    CrVrScrCompositorConstIterInit(&hFb->Compositor, &Iter);
    252322
     
    271341        }
    272342
    273         Assert(!pEnteredTex);
     343        uint32_t width, height;
     344        RTRECT SrcRect;
    274345
    275346        for (uint32_t i = 0; i < cRects; ++i)
     
    284355                    continue;
    285356
     357                VBoxRectStretch(&Intersection, strX, strY);
     358                if (VBoxRectIsZero(&Intersection))
     359                    continue;
     360
    286361                CR_TEXDATA *pTex = CrVrScrCompositorEntryTexGet(pEntry);
    287362                const CR_BLITTER_IMG *pSrcImg;
    288363
    289                 if (!pEnteredTex)
     364                if (pEnteredTex != pTex)
    290365                {
     366                    if (!pEnteredBlitter)
     367                    {
     368                        pEnteredBlitter = CrTdBlitterGet(pTex);
     369                        rc = CrBltEnter(pEnteredBlitter);
     370                        if (!RT_SUCCESS(rc))
     371                        {
     372                            WARN(("CrBltEnter failed %d", rc));
     373                            pEnteredBlitter = NULL;
     374                            goto end;
     375                        }
     376                    }
     377
     378                    if (pEnteredTex)
     379                    {
     380                        CrTdBltLeave(pEnteredTex);
     381
     382                        pEnteredTex = NULL;
     383
     384                        if (pEnteredBlitter != CrTdBlitterGet(pTex))
     385                        {
     386                            WARN(("blitters not equal!"));
     387                            CrBltLeave(pEnteredBlitter);
     388
     389                            pEnteredBlitter = CrTdBlitterGet(pTex);
     390                            rc = CrBltEnter(pEnteredBlitter);
     391                             if (!RT_SUCCESS(rc))
     392                             {
     393                                 WARN(("CrBltEnter failed %d", rc));
     394                                 pEnteredBlitter = NULL;
     395                                 goto end;
     396                             }
     397                        }
     398                    }
     399
    291400                    rc = CrTdBltEnter(pTex);
    292401                    if (!RT_SUCCESS(rc))
     
    297406
    298407                    pEnteredTex = pTex;
     408
     409                    const VBOXVR_TEXTURE *pVrTex = CrTdTexGet(pTex);
     410
     411                    width = static_cast<uint32_t>(strX * pVrTex->width);
     412                    height = static_cast<uint32_t>(strY * pVrTex->height);
     413                    VBoxRectStretched(CrVrScrCompositorEntryRectGet(pEntry), strX, strY, &SrcRect);
    299414                }
    300415
    301                 rc = CrTdBltDataAcquire(pTex, GL_BGRA, false, &pSrcImg);
     416                rc = CrTdBltDataAcquireStretched(pTex, GL_BGRA, false, width, height, &pSrcImg);
    302417                if (!RT_SUCCESS(rc))
    303418                {
     
    306421                }
    307422
    308                 const RTRECT *pEntryRect = CrVrScrCompositorEntryRectGet(pEntry);
    309423                bool fInvert = !(CrVrScrCompositorEntryFlagsGet(pEntry) & CRBLT_F_INVERT_SRC_YCOORDS);
    310424
    311                 crFbBltImg(pSrcImg->pvData, pEntryRect, fInvert, &Intersection, pPoint, pImg);
    312 
    313                 CrTdBltDataRelease(pTex);
     425                crFbBltImg(pSrcImg->pvData, &SrcRect, fInvert, &Intersection, &SrcPoint, pImg);
     426
     427                CrTdBltDataReleaseStretched(pTex, pSrcImg);
    314428            }
    315         }
    316 
    317         if (pEnteredTex)
    318         {
    319             CrTdBltLeave(pEnteredTex);
    320             pEnteredTex = NULL;
    321429        }
    322430    }
     
    351459
    352460        RTPOINT Pos = {0};
     461        const RTRECT *pCompRect = CrVrScrCompositorRectGet(&hFb->Compositor);
     462        uint32_t fbPitch = (pCompRect->xRight - pCompRect->xLeft) * 4;
     463        uint32_t fbHeight = pCompRect->yBottom - pCompRect->yTop;
     464
     465        uint32_t dstPitch = static_cast<uint32_t>(strX * fbPitch);
     466        uint32_t dstHeight = static_cast<uint32_t>(strY * fbHeight);
     467
     468        bool fStretch = fbPitch != dstPitch || fbHeight != dstHeight;
    353469
    354470        for (uint32_t i = 0; i < cRects; ++i)
     
    363479                    continue;
    364480
    365                 crFbBltImg(hFb->pvVram, CrVrScrCompositorRectGet(&hFb->Compositor), false, &Intersection, pPoint, pImg);
     481                if (!fStretch)
     482                    crFbBltImg(hFb->pvVram, pCompRect, false, &Intersection, &SrcPoint, pImg);
     483                else
     484                    crFbBltImgStretched(hFb->pvVram, pCompRect, false, &Intersection, &SrcPoint, strX, strY, pImg);
    366485            }
    367486        }
     
    373492        CrTdBltLeave(pEnteredTex);
    374493
     494    if (pEnteredBlitter)
     495        CrBltLeave(pEnteredBlitter);
     496
    375497    VBoxVrListClear(&List);
    376498
    377499    return rc;
    378500}
     501
     502static int crFbBltGetContentsStretchCPU(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg)
     503{
     504    uint32_t srcWidth = pSrcRect->xRight - pSrcRect->xLeft;
     505    uint32_t srcHeight = pSrcRect->yBottom - pSrcRect->yTop;
     506
     507    /* destination is bigger than the source, do 3D data stretching with CPU */
     508    CR_BLITTER_IMG Img;
     509    Img.cbData = srcWidth * srcHeight * 4;
     510    Img.pvData = RTMemAlloc(Img.cbData);
     511    if (!Img.pvData)
     512    {
     513        WARN(("RTMemAlloc Failed"));
     514        return VERR_NO_MEMORY;
     515    }
     516    Img.enmFormat = pImg->enmFormat;
     517    Img.width = srcWidth;
     518    Img.height = srcHeight;
     519    Img.bpp = pImg->bpp;
     520    Img.pitch = Img.width * 4;
     521
     522    int rc = CrFbBltGetContents(hFb, pSrcRect, cRects, pRects, &Img);
     523    if (RT_SUCCESS(rc))
     524    {
     525        CrBmpScale32((uint8_t *)pImg->pvData,
     526                            pImg->pitch,
     527                            pImg->width, pImg->height,
     528                            (const uint8_t *)Img.pvData,
     529                            Img.pitch,
     530                            Img.width, Img.height);
     531    }
     532    else
     533        WARN(("CrFbBltGetContents failed %d", rc));
     534
     535    RTMemFree(Img.pvData);
     536
     537    return rc;
     538
     539}
     540
     541int CrFbBltGetContents(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg)
     542{
     543    uint32_t srcWidth = pSrcRect->xRight - pSrcRect->xLeft;
     544    uint32_t srcHeight = pSrcRect->yBottom - pSrcRect->yTop;
     545    if ((srcWidth == pImg->width
     546            && srcHeight == pImg->height)
     547            || !CrFbHas3DData(hFb)
     548            || (srcWidth * srcHeight > pImg->width * pImg->height))
     549    {
     550        return crFbBltGetContentsDirect(hFb, pSrcRect, cRects, pRects, pImg);
     551    }
     552
     553    return crFbBltGetContentsStretchCPU(hFb, pSrcRect, cRects, pRects, pImg);
     554}
     555
    379556
    380557int CrFbResize(CR_FRAMEBUFFER *pFb, const struct VBVAINFOSCREEN * pScreen, void *pvVRAM)
     
    454631}
    455632
    456 typedef union CR_FBENTRY_FLAGS
    457 {
    458     struct {
    459         uint32_t fCreateNotified : 1;
    460         uint32_t fInList         : 1;
    461         uint32_t Reserved        : 30;
    462     };
    463     uint32_t Value;
    464 } CR_FBENTRY_FLAGS;
    465 
    466 typedef struct CR_FRAMEBUFFER_ENTRY
    467 {
    468     VBOXVR_SCR_COMPOSITOR_ENTRY Entry;
    469     RTLISTNODE Node;
    470     uint32_t cRefs;
    471     CR_FBENTRY_FLAGS Flags;
    472     CRHTABLE HTable;
    473 } CR_FRAMEBUFFER_ENTRY;
    474 
    475 typedef struct CR_FBTEX
    476 {
    477     CR_TEXDATA Tex;
    478     CRTextureObj *pTobj;
    479 } CR_FBTEX;
    480 
    481 #define PCR_FBTEX_FROM_TEX(_pTex) ((CR_FBTEX*)((uint8_t*)(_pTex) - RT_OFFSETOF(CR_FBTEX, Tex)))
    482 #define PCR_FRAMEBUFFER_FROM_COMPOSITOR(_pCompositor) ((CR_FRAMEBUFFER*)((uint8_t*)(_pCompositor) - RT_OFFSETOF(CR_FRAMEBUFFER, Compositor)))
    483 #define PCR_FBENTRY_FROM_ENTRY(_pEntry) ((CR_FRAMEBUFFER_ENTRY*)((uint8_t*)(_pEntry) - RT_OFFSETOF(CR_FRAMEBUFFER_ENTRY, Entry)))
    484 
    485633#define CR_PMGR_MODE_WINDOW 0x1
    486634/* mutually exclusive with CR_PMGR_MODE_WINDOW */
     
    661809        CR_TEXDATA *pTex = CrVrScrCompositorEntryTexGet(&pEntry->Entry);
    662810        if (pTex)
    663             CrTdBltDataDiscardNe(pTex);
     811            CrTdBltDataInvalidateNe(pTex);
    664812    }
    665813}
     
    702850
    703851        CrHTableMoveTo(&pFbEntry->HTable, &pFbReplacingEntry->HTable);
     852
     853        CR_TEXDATA *pTex = CrVrScrCompositorEntryTexGet(&pFbEntry->Entry);
     854        CR_TEXDATA *pReplacingTex = CrVrScrCompositorEntryTexGet(&pFbReplacingEntry->Entry);
     855
     856        CrTdBltStretchCacheMoveTo(pTex, pReplacingTex);
     857
    704858        if (pFb->pDisplay)
    705859            pFb->pDisplay->EntryReplaced(pFb, pFbReplacingEntry, pFbEntry);
    706860
    707         CR_TEXDATA *pTex = CrVrScrCompositorEntryTexGet(&pFbEntry->Entry);
    708         if (pTex)
    709             CrTdBltDataDiscardNe(pTex);
     861        CrTdBltDataInvalidateNe(pTex);
    710862
    711863        /* 2. mark the replaced entry is destroyed */
     
    727879            CR_TEXDATA *pTex = CrVrScrCompositorEntryTexGet(&pFbEntry->Entry);
    728880            if (pTex)
    729                 CrTdBltDataDiscardNe(pTex);
     881                CrTdBltDataInvalidateNe(pTex);
    730882        }
    731883    }
     
    791943        CR_TEXDATA *pTex = CrVrScrCompositorEntryTexGet(&pEntry->Entry);
    792944        if (pTex)
    793             CrTdBltDataDiscardNe(pTex);
     945            CrTdBltDataInvalidateNe(pTex);
    794946    }
    795947
     
    9311083                CR_TEXDATA *pTex = CrVrScrCompositorEntryTexGet(&hEntry->Entry);
    9321084                if (pTex)
    933                     CrTdBltDataDiscardNe(pTex);
     1085                    CrTdBltDataInvalidateNe(pTex);
    9341086            }
    9351087        }
     
    10051157                CR_TEXDATA *pTex = CrVrScrCompositorEntryTexGet(&hEntry->Entry);
    10061158                if (pTex)
    1007                     CrTdBltDataDiscardNe(pTex);
     1159                    CrTdBltDataInvalidateNe(pTex);
    10081160            }
    10091161        }
     
    27912943        CR_TEXDATA *pNewTex = CrVrScrCompositorEntryTexGet(pNewEntry);
    27922944
    2793         rc = CrTdBltEnter(pReplacedTex);
     2945        CrTdBltDataInvalidateNe(pReplacedTex);
     2946
     2947        rc = CrTdBltEnter(pNewTex);
    27942948        if (RT_SUCCESS(rc))
    27952949        {
    2796             if (pNewTex != pReplacedTex)
    2797             {
    2798                 CrTdBltDataDiscard(pReplacedTex);
    2799                 rc = CrTdBltEnter(pNewTex);
    2800                 if (RT_SUCCESS(rc))
    2801                 {
    2802                     rc = vrdpFrame(hNewEntry);
    2803                     CrTdBltLeave(pNewTex);
    2804                 }
    2805                 else
    2806                     WARN(("CrTdBltEnter failed %d", rc));
    2807             }
    2808             else
    2809                 rc = vrdpFrame(hNewEntry);
    2810 
    2811             CrTdBltLeave(pReplacedTex);
     2950            rc = vrdpFrame(hNewEntry);
     2951            CrTdBltLeave(pNewTex);
    28122952        }
    28132953        else
    28142954            WARN(("CrTdBltEnter failed %d", rc));
    28152955
    2816         return rc;
     2956        return rc;
    28172957    }
    28182958
     
    28492989            return rc;
    28502990        }
     2991
     2992        const VBOXVR_SCR_COMPOSITOR_ENTRY* pEntry = CrFbEntryGetCompositorEntry(hEntry);
     2993        CR_TEXDATA *pTex = CrVrScrCompositorEntryTexGet(pEntry);
     2994        CrTdBltDataInvalidateNe(pTex);
    28512995
    28522996        return vrdpRegions(pFb, hEntry);
     
    29903134        CR_TEXDATA *pTex = CrVrScrCompositorEntryTexGet(pEntry);
    29913135        const CR_BLITTER_IMG *pImg;
    2992         CrTdBltDataDiscard(pTex);
     3136        CrTdBltDataInvalidateNe(pTex);
    29933137        int rc = CrTdBltDataAcquire(pTex, GL_BGRA, !!(CrVrScrCompositorEntryFlagsGet(pEntry) & CRBLT_F_INVERT_SRC_YCOORDS), &pImg);
    29943138        if (!RT_SUCCESS(rc))
     
    31873331}
    31883332#endif
     3333
     3334class CrFbDisplayEntryDataMonitor : public CrFbDisplayBase
     3335{
     3336public:
     3337    virtual int EntryReplaced(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hNewEntry, HCR_FRAMEBUFFER_ENTRY hReplacedEntry)
     3338    {
     3339        entryDataChanged(pFb, hReplacedEntry);
     3340        return VINF_SUCCESS;
     3341    }
     3342
     3343    virtual int EntryTexChanged(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry)
     3344    {
     3345        entryDataChanged(pFb, hEntry);
     3346        return VINF_SUCCESS;
     3347    }
     3348
     3349    virtual int EntryRemoved(struct CR_FRAMEBUFFER *pFb, HCR_FRAMEBUFFER_ENTRY hEntry)
     3350    {
     3351        entryDataChanged(pFb, hEntry);
     3352        return VINF_SUCCESS;
     3353    }
     3354protected:
     3355    virtual void entryDataChanged(HCR_FRAMEBUFFER hFb, HCR_FRAMEBUFFER_ENTRY hEntry)
     3356    {
     3357
     3358    }
     3359};
    31893360
    31903361int CrPMgrInit()
     
    42504421                uint8_t *pu8Buf = g_pvVRamBase + offVRAM;
    42514422
    4252                 RTPOINT Pos = {pBlt->Pos.x, pBlt->Pos.y};
     4423                RTRECT Rect;
     4424                Rect.xLeft = pBlt->Pos.x;
     4425                Rect.yTop = pBlt->Pos.y;
     4426                Rect.xRight = Rect.xLeft + pScreen->u32Width;
     4427                Rect.yBottom = Rect.yTop + pScreen->u32Height;
    42534428                CR_BLITTER_IMG Img;
    42544429                Img.pvData = pu8Buf;
     
    42594434                Img.bpp = pScreen->u16BitsPerPixel;
    42604435                Img.pitch = pScreen->u32LineSize;
    4261                 int rc = CrFbBltGetContents(hFb, &Pos, cRects, pRects, &Img);
     4436                int rc = CrFbBltGetContents(hFb, &Rect, cRects, pRects, &Img);
    42624437                if (!RT_SUCCESS(rc))
    42634438                {
  • trunk/src/VBox/Main/include/DisplayImpl.h

    r50315 r50364  
    363363    static int  displayTakeScreenshotEMT(Display *pDisplay, ULONG aScreenId, uint8_t **ppu8Data, size_t *pcbData, uint32_t *pu32Width, uint32_t *pu32Height);
    364364
     365#ifdef VBOX_WITH_CROGL
     366    static BOOL  displayCheckTakeScreenshotCrOgl(Display *pDisplay, ULONG aScreenId, uint8_t *pu8Data, uint32_t u32Width, uint32_t u32Height);
     367#endif
     368
    365369private:
    366370    static void InvalidateAndUpdateEMT(Display *pDisplay, unsigned uId, bool fUpdateAll);
  • trunk/src/VBox/Main/src-client/DisplayImpl.cpp

    r50315 r50364  
    152152#ifdef VBOX_WITH_CROGL
    153153    RT_ZERO(mCrOglCallbacks);
     154    RT_ZERO(mCrOglScreenshotData);
    154155    mfCrOglVideoRecState = CRVREC_STATE_IDLE;
    155156    mCrOglScreenshotData.u32Screen = CRSCREEN_ALL;
     
    24152416}
    24162417
     2418#ifdef VBOX_WITH_CROGL
     2419BOOL Display::displayCheckTakeScreenshotCrOgl(Display *pDisplay, ULONG aScreenId, uint8_t *pu8Data, uint32_t u32Width, uint32_t u32Height)
     2420{
     2421    BOOL is3denabled;
     2422    pDisplay->mParent->machine()->COMGETTER(Accelerate3DEnabled)(&is3denabled);
     2423    if (is3denabled && pDisplay->mCrOglCallbacks.pfnHasData())
     2424    {
     2425        VMMDev *pVMMDev = pDisplay->mParent->getVMMDev();
     2426        if (pVMMDev)
     2427        {
     2428            CRVBOXHGCMTAKESCREENSHOT *pScreenshot = (CRVBOXHGCMTAKESCREENSHOT*)RTMemAlloc(sizeof (*pScreenshot));
     2429            if (pScreenshot)
     2430            {
     2431                /* screen id or CRSCREEN_ALL to specify all enabled */
     2432                pScreenshot->u32Screen = aScreenId;
     2433                pScreenshot->u32Width = u32Width;
     2434                pScreenshot->u32Height = u32Height;
     2435                pScreenshot->u32Pitch = u32Width * 4;
     2436                pScreenshot->pvBuffer = pu8Data;
     2437                pScreenshot->pvContext = NULL;
     2438                pScreenshot->pfnScreenshotBegin = NULL;
     2439                pScreenshot->pfnScreenshotPerform = NULL;
     2440                pScreenshot->pfnScreenshotEnd = NULL;
     2441
     2442                VBOXHGCMSVCPARM parm;
     2443
     2444                parm.type = VBOX_HGCM_SVC_PARM_PTR;
     2445                parm.u.pointer.addr = pScreenshot;
     2446                parm.u.pointer.size = sizeof (*pScreenshot);
     2447
     2448                int rc = pVMMDev->hgcmHostCall("VBoxSharedCrOpenGL", SHCRGL_HOST_FN_TAKE_SCREENSHOT, 1, &parm);
     2449
     2450                RTMemFree(pScreenshot);
     2451
     2452                if (RT_SUCCESS(rc))
     2453                    return TRUE;
     2454                else
     2455                {
     2456                    AssertMsgFailed(("failed to get screenshot data from crOgl %d\n", rc));
     2457                    /* fall back to the non-3d mechanism */
     2458                }
     2459            }
     2460        }
     2461    }
     2462    return FALSE;
     2463}
     2464#endif
     2465
    24172466int Display::displayTakeScreenshotEMT(Display *pDisplay, ULONG aScreenId, uint8_t **ppu8Data, size_t *pcbData, uint32_t *pu32Width, uint32_t *pu32Height)
    24182467{
     
    25102559    uint32_t cy = 0;
    25112560    int vrc = VINF_SUCCESS;
     2561
     2562# if defined(VBOX_WITH_HGCM) && defined(VBOX_WITH_CROGL)
     2563    if (Display::displayCheckTakeScreenshotCrOgl(pDisplay, aScreenId, (uint8_t*)address, width, height))
     2564        return VINF_SUCCESS;
     2565#endif
    25122566
    25132567    int cRetries = 5;
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