VirtualBox

Changeset 39847 in vbox for trunk


Ignore:
Timestamp:
Jan 24, 2012 9:39:23 AM (13 years ago)
Author:
vboxsync
Message:

crOpenGL: fix saved state issues

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/VBoxVideo3D.h

    r39602 r39847  
    6060#define VBOXTLSREFDATA \
    6161    volatile int32_t cTlsRefs; \
    62     uint32_t enmTlsRefState; \
     62    VBOXTLSREFDATA_STATE enmTlsRefState; \
    6363    PFNVBOXTLSREFDTOR pfnTlsRefDtor; \
     64
     65struct VBOXTLSREFDATA_DUMMY
     66{
     67    VBOXTLSREFDATA
     68};
     69
     70#define VBOXTLSREFDATA_OFFSET(_t) RT_OFFSETOF(_t, cTlsRefs)
     71#define VBOXTLSREFDATA_SIZE() (sizeof (struct VBOXTLSREFDATA_DUMMY))
     72#define VBOXTLSREFDATA_COPY(_pDst, _pSrc) do { \
     73        (_pDst)->cTlsRefs = (_pSrc)->cTlsRefs; \
     74        (_pDst)->enmTlsRefState = (_pSrc)->enmTlsRefState; \
     75        (_pDst)->pfnTlsRefDtor = (_pSrc)->pfnTlsRefDtor; \
     76    } while (0)
     77
     78#define VBOXTLSREFDATA_EQUAL(_pDst, _pSrc) ( \
     79           (_pDst)->cTlsRefs == (_pSrc)->cTlsRefs \
     80        && (_pDst)->enmTlsRefState == (_pSrc)->enmTlsRefState \
     81        && (_pDst)->pfnTlsRefDtor == (_pSrc)->pfnTlsRefDtor \
     82    )
     83
    6484
    6585#define VBoxTlsRefInit(_p, _pfnDtor) do { \
     
    85105    } while (0)
    86106
    87 #define VBoxTlsRefReleaseMarkDestroy(_p) do { \
     107#define VBoxTlsRefMarkDestroy(_p) do { \
    88108        (_p)->enmTlsRefState = VBOXTLSREFDATA_STATE_TOBE_DESTROYED; \
    89109    } while (0)
  • trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_snapshot.c

    r38394 r39847  
    10191019    pContext->buffer.storedHeight = pContext->buffer.height;
    10201020
    1021     rc = SSMR3PutMem(pSSM, pContext, sizeof(*pContext));
     1021    CRASSERT(VBoxTlsRefIsFunctional(pContext));
     1022
     1023    /* do not increment the saved state version due to VBOXTLSREFDATA addition to CRContext */
     1024    rc = SSMR3PutMem(pSSM, pContext, VBOXTLSREFDATA_OFFSET(CRContext));
     1025    AssertRCReturn(rc, rc);
     1026
     1027    /* now store bitid & neg_bitid */
     1028    rc = SSMR3PutMem(pSSM, pContext->bitid, sizeof (pContext->bitid) + sizeof (pContext->neg_bitid));
     1029    AssertRCReturn(rc, rc);
     1030
     1031    /* the pre-VBOXTLSREFDATA CRContext structure might have additional allignment bits before the CRContext::shared */
     1032    ui32 = VBOXTLSREFDATA_OFFSET(CRContext) + sizeof (pContext->bitid) + sizeof (pContext->neg_bitid);
     1033    ui32 &= (sizeof (void*) - 1);
     1034    if (ui32)
     1035    {
     1036        void* pTmp = NULL;
     1037        rc = SSMR3PutMem(pSSM, &pTmp, ui32);
     1038        AssertRCReturn(rc, rc);
     1039    }
     1040
     1041    rc = SSMR3PutMem(pSSM, &pContext->shared, sizeof (CRContext) - RT_OFFSETOF(CRContext, shared));
    10221042    AssertRCReturn(rc, rc);
    10231043
     
    13791399#define SLC_ASSSERT_NULL_PTR(ptr) CRASSERT(!pContext->ptr)
    13801400
     1401AssertCompile(VBOXTLSREFDATA_SIZE() <= CR_MAX_BITARRAY);
     1402AssertCompile(VBOXTLSREFDATA_STATE_INITIALIZED != 0);
     1403AssertCompile(RT_OFFSETOF(CRContext, shared) >= VBOXTLSREFDATA_OFFSET(CRContext) + VBOXTLSREFDATA_SIZE() + RT_SIZEOFMEMB(CRContext, bitid) + RT_SIZEOFMEMB(CRContext, neg_bitid));
     1404
    13811405int32_t crStateLoadContext(CRContext *pContext, CRHashTable * pCtxTable, PSSMHANDLE pSSM)
    13821406{
     
    13861410    unsigned long key;
    13871411    GLboolean bLoadShared = GL_TRUE;
     1412    union {
     1413        CRbitvalue bitid[CR_MAX_BITARRAY];
     1414        struct {
     1415            VBOXTLSREFDATA
     1416        } tlsRef;
     1417    } bitid;
    13881418
    13891419    CRASSERT(pContext && pSSM);
     
    13941424        return VERR_NO_MEMORY;
    13951425
    1396     rc = SSMR3GetMem(pSSM, pTmpContext, sizeof(*pTmpContext));
     1426    CRASSERT(VBoxTlsRefIsFunctional(pContext));
     1427
     1428    /* do not increment the saved state version due to VBOXTLSREFDATA addition to CRContext */
     1429    rc = SSMR3GetMem(pSSM, pTmpContext, VBOXTLSREFDATA_OFFSET(CRContext));
     1430    AssertRCReturn(rc, rc);
     1431
     1432    /* VBox 4.1.8 had a bug that VBOXTLSREFDATA was also stored in the snapshot,
     1433     * thus the saved state data format was changed w/o changing the saved state version.
     1434     * here we determine whether the saved state contains VBOXTLSREFDATA, and if so, treat it accordingly */
     1435    rc = SSMR3GetMem(pSSM, &bitid, sizeof (bitid));
     1436    AssertRCReturn(rc, rc);
     1437
     1438    /* the bitid array has one bit set only. this is why if bitid.tlsRef has both cTlsRefs
     1439     * and enmTlsRefState non-zero - this is definitely NOT a bit id and is a VBOXTLSREFDATA */
     1440    if (bitid.tlsRef.enmTlsRefState == VBOXTLSREFDATA_STATE_INITIALIZED
     1441            && bitid.tlsRef.cTlsRefs)
     1442    {
     1443        /* VBOXTLSREFDATA is stored, skip it */
     1444        crMemcpy(&pTmpContext->bitid, ((uint8_t*)&bitid) + VBOXTLSREFDATA_SIZE(), sizeof (bitid) - VBOXTLSREFDATA_SIZE());
     1445        rc = SSMR3GetMem(pSSM, ((uint8_t*)&pTmpContext->bitid) + VBOXTLSREFDATA_SIZE(), sizeof (pTmpContext->bitid) + sizeof (pTmpContext->neg_bitid) - VBOXTLSREFDATA_SIZE());
     1446        AssertRCReturn(rc, rc);
     1447
     1448        ui = VBOXTLSREFDATA_OFFSET(CRContext) + VBOXTLSREFDATA_SIZE() + sizeof (pTmpContext->bitid) + sizeof (pTmpContext->neg_bitid);
     1449        ui = RT_OFFSETOF(CRContext, shared) - ui;
     1450    }
     1451    else
     1452    {
     1453        /* VBOXTLSREFDATA is NOT stored */
     1454        crMemcpy(&pTmpContext->bitid, &bitid, sizeof (bitid));
     1455        rc = SSMR3GetMem(pSSM, &pTmpContext->neg_bitid, sizeof (pTmpContext->neg_bitid));
     1456        AssertRCReturn(rc, rc);
     1457
     1458        /* the pre-VBOXTLSREFDATA CRContext structure might have additional allignment bits before the CRContext::shared */
     1459        ui = VBOXTLSREFDATA_OFFSET(CRContext) + sizeof (pTmpContext->bitid) + sizeof (pTmpContext->neg_bitid);
     1460
     1461        ui &= (sizeof (void*) - 1);
     1462    }
     1463
     1464    if (ui)
     1465    {
     1466        void* pTmp = NULL;
     1467        rc = SSMR3GetMem(pSSM, &pTmp, ui);
     1468        AssertRCReturn(rc, rc);
     1469    }
     1470
     1471    /* we will later do crMemcpy from entire pTmpContext to pContext,
     1472     * for simplicity store the VBOXTLSREFDATA from the pContext to pTmpContext */
     1473    VBOXTLSREFDATA_COPY(pTmpContext, pContext);
     1474
     1475    rc = SSMR3GetMem(pSSM, &pTmpContext->shared, sizeof (CRContext) - RT_OFFSETOF(CRContext, shared));
    13971476    AssertRCReturn(rc, rc);
    13981477
     
    15671646    /* Have to preserve original context id */
    15681647    CRASSERT(pTmpContext->id == pContext->id);
     1648    CRASSERT(VBOXTLSREFDATA_EQUAL(pContext, pTmpContext));
    15691649    /* Copy ordinary state to real context */
    15701650    crMemcpy(pContext, pTmpContext, sizeof(*pTmpContext));
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette