VirtualBox

Ignore:
Timestamp:
Feb 22, 2013 2:34:46 PM (12 years ago)
Author:
vboxsync
Message:

crOpenGL: saved state: save depth and stencil buffer data (still needs more testing)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c

    r44748 r44802  
    996996}
    997997
     998static void crVBoxServerFBImageDataTerm(CRFBData *pData)
     999{
     1000    GLuint i;
     1001    for (i = 0; i < pData->cElements; ++i)
     1002    {
     1003        CRFBDataElement * pEl = &pData->aElements[i];
     1004        if (pEl->pvData)
     1005        {
     1006            crFree(pEl->pvData);
     1007            /* sanity */
     1008            pEl->pvData = NULL;
     1009        }
     1010    }
     1011    pData->cElements = 0;
     1012}
     1013
     1014static int crVBoxServerFBImageDataInitEx(CRFBData *pData, CRContextInfo *pCtxInfo, CRMuralInfo *pMural, GLboolean fWrite, GLboolean fForceBackFrontOnly, GLuint overrideWidth, GLuint overrideHeight)
     1015{
     1016    CRContext *pContext;
     1017    GLuint i;
     1018    GLfloat *pF;
     1019    CRFBDataElement *pEl;
     1020    GLuint width;
     1021    GLuint height;
     1022
     1023    CRASSERT(pCtxInfo->currentMural);
     1024
     1025    crMemset(pData, 0, sizeof (*pData));
     1026
     1027    pContext = pCtxInfo->pContext;
     1028
     1029    width = overrideWidth ? overrideWidth : pMural->width;
     1030    height = overrideHeight ? overrideHeight : pMural->height;
     1031
     1032    if (!width || !height)
     1033        return VINF_SUCCESS;
     1034
     1035    pData->idFBO = pMural->fUseFBO ? pMural->aidColorTexs[fWrite ? pMural->iCurDrawBuffer : pMural->iCurReadBuffer] : 0;
     1036    pData->cElements = 0;
     1037
     1038    pEl = &pData->aElements[pData->cElements];
     1039    pEl->idFBO = pMural->fUseFBO ? pMural->aidFBOs[CR_SERVER_FBO_FB_IDX(pMural)] : 0;
     1040    pEl->enmBuffer = pData->aElements[1].idFBO ? GL_COLOR_ATTACHMENT0 : GL_FRONT;
     1041    pEl->posX = 0;
     1042    pEl->posY = 0;
     1043    pEl->width = width;
     1044    pEl->height = height;
     1045    pEl->enmFormat = GL_RGBA;
     1046    pEl->enmType = GL_UNSIGNED_BYTE;
     1047    pEl->cbData = width * height * 4;
     1048    pEl->pvData = crCalloc(pEl->cbData);
     1049    if (!pEl->pvData)
     1050    {
     1051        crVBoxServerFBImageDataTerm(pData);
     1052        crWarning("crVBoxServerFBImageDataInit: crCalloc failed");
     1053        return VERR_NO_MEMORY;
     1054    }
     1055    ++pData->cElements;
     1056
     1057    /* there is a lot of code that assumes we have double buffering, just assert here to print a warning in the log
     1058     * so that we know that something irregular is going on */
     1059    CRASSERT(pCtxInfo->CreateInfo.visualBits && CR_DOUBLE_BIT);
     1060    if ((pCtxInfo->CreateInfo.visualBits && CR_DOUBLE_BIT) || fForceBackFrontOnly)
     1061    {
     1062        pEl = &pData->aElements[pData->cElements];
     1063        pEl->idFBO = pMural->fUseFBO ? pMural->aidFBOs[CR_SERVER_FBO_BB_IDX(pMural)] : 0;
     1064        pEl->enmBuffer = pData->aElements[1].idFBO ? GL_COLOR_ATTACHMENT0 : GL_BACK;
     1065        pEl->posX = 0;
     1066        pEl->posY = 0;
     1067        pEl->width = width;
     1068        pEl->height = height;
     1069        pEl->enmFormat = GL_RGBA;
     1070        pEl->enmType = GL_UNSIGNED_BYTE;
     1071        pEl->cbData = width * height * 4;
     1072        pEl->pvData = crCalloc(pEl->cbData);
     1073        if (!pEl->pvData)
     1074        {
     1075            crVBoxServerFBImageDataTerm(pData);
     1076            crWarning("crVBoxServerFBImageDataInit: crCalloc failed");
     1077            return VERR_NO_MEMORY;
     1078        }
     1079        ++pData->cElements;
     1080    }
     1081
     1082    if (!fForceBackFrontOnly)
     1083    {
     1084        if (pCtxInfo->CreateInfo.visualBits && CR_DEPTH_BIT)
     1085        {
     1086            AssertCompile(sizeof (GLfloat) == 4);
     1087            pEl = &pData->aElements[pData->cElements];
     1088            pEl->idFBO = pMural->fUseFBO ? pMural->aidFBOs[CR_SERVER_FBO_FB_IDX(pMural)] : 0;
     1089            pEl->enmBuffer = 0; /* we do not care */
     1090            pEl->posX = 0;
     1091            pEl->posY = 0;
     1092            pEl->width = width;
     1093            pEl->height = height;
     1094            pEl->enmFormat = GL_DEPTH_COMPONENT;
     1095            pEl->enmType = GL_FLOAT;
     1096            pEl->cbData = width * height * 4;
     1097            pEl->pvData = crCalloc(pEl->cbData);
     1098            if (!pEl->pvData)
     1099            {
     1100                crVBoxServerFBImageDataTerm(pData);
     1101                crWarning("crVBoxServerFBImageDataInit: crCalloc failed");
     1102                return VERR_NO_MEMORY;
     1103            }
     1104
     1105            /* init to default depth value, just in case */
     1106            pF = (GLfloat*)pEl->pvData;
     1107            for (i = 0; i < width * height; ++i)
     1108            {
     1109                pF[i] = 1.;
     1110            }
     1111            ++pData->cElements;
     1112        }
     1113
     1114        if (pCtxInfo->CreateInfo.visualBits && CR_STENCIL_BIT)
     1115        {
     1116            AssertCompile(sizeof (GLuint) == 4);
     1117            pEl = &pData->aElements[pData->cElements];
     1118            pEl->idFBO = pMural->fUseFBO ? pMural->aidFBOs[CR_SERVER_FBO_FB_IDX(pMural)] : 0;
     1119            pEl->enmBuffer = 0; /* we do not care */
     1120            pEl->posX = 0;
     1121            pEl->posY = 0;
     1122            pEl->width = width;
     1123            pEl->height = height;
     1124            pEl->enmFormat = GL_STENCIL_INDEX;
     1125            pEl->enmType = GL_UNSIGNED_INT;
     1126            pEl->cbData = width * height * 4;
     1127            pEl->pvData = crCalloc(pEl->cbData);
     1128            if (!pEl->pvData)
     1129            {
     1130                crVBoxServerFBImageDataTerm(pData);
     1131                crWarning("crVBoxServerFBImageDataInit: crCalloc failed");
     1132                return VERR_NO_MEMORY;
     1133            }
     1134            ++pData->cElements;
     1135        }
     1136    }
     1137    return VINF_SUCCESS;
     1138}
     1139
     1140static int crVBoxServerFBImageDataInit(CRFBData *pData, CRContextInfo *pCtxInfo, CRMuralInfo *pMural, GLboolean fWrite)
     1141{
     1142    return crVBoxServerFBImageDataInitEx(pData, pCtxInfo, pMural, fWrite, GL_FALSE, 0, 0);
     1143}
     1144
    9981145static int crVBoxServerSaveFBImage(PSSMHANDLE pSSM)
    9991146{
    1000     int32_t rc;
     1147    CRContextInfo *pCtxInfo;
    10011148    CRContext *pContext;
    10021149    CRMuralInfo *pMural;
    1003     GLint cbData;
    1004 
    1005     CRASSERT(cr_server.currentCtxInfo);
    1006     CRASSERT(cr_server.currentCtxInfo->currentMural);
    1007 
    1008     pContext = cr_server.currentCtxInfo->pContext;
    1009     pMural = cr_server.currentCtxInfo->currentMural;
    1010     /* do crStateAcquireFBImage no matter whether offscreen drawing is used or not
    1011      * in the former case this would just free pContext->buffer.pFrontImg and pContext->buffer.pFrontImg
    1012      */
    1013     rc = crStateAcquireFBImage(pContext);
     1150    int32_t rc;
     1151    GLuint i;
     1152    struct
     1153    {
     1154        CRFBData data;
     1155        CRFBDataElement buffer[3]; /* CRFBData::aElements[1] + buffer[3] gives 4: back, front, depth and stencil  */
     1156    } Data;
     1157
     1158    Assert(sizeof (Data) >= RT_OFFSETOF(CRFBData, aElements[4]));
     1159
     1160    pCtxInfo = cr_server.currentCtxInfo;
     1161    pContext = pCtxInfo->pContext;
     1162    pMural = pCtxInfo->currentMural;
     1163
     1164    rc = crVBoxServerFBImageDataInit(&Data.data, pCtxInfo, pMural, GL_FALSE);
     1165    if (!RT_SUCCESS(rc))
     1166    {
     1167        crWarning("crVBoxServerFBImageDataInit failed rc %d", rc);
     1168        return rc;
     1169    }
     1170
     1171    rc = crStateAcquireFBImage(pContext, &Data.data);
    10141172    AssertRCReturn(rc, rc);
    10151173
    1016     if (!pMural->width || !pMural->height)
    1017         return VINF_SUCCESS;
    1018 
    1019 
    1020     cbData = crPixelSize(GL_RGBA, GL_UNSIGNED_BYTE) * pMural->width * pMural->height;
    1021 
    1022     if (!pMural->fUseFBO)
    1023     {
    1024         CRASSERT(pMural->width == pContext->buffer.storedWidth);
    1025         CRASSERT(pMural->width == pContext->buffer.width);
    1026         CRASSERT(pMural->height == pContext->buffer.storedHeight);
    1027         CRASSERT(pMural->height == pContext->buffer.height);
    1028 
    1029         rc = SSMR3PutMem(pSSM, pContext->buffer.pFrontImg, cbData);
     1174    for (i = 0; i < Data.data.cElements; ++i)
     1175    {
     1176        CRFBDataElement * pEl = &Data.data.aElements[i];
     1177        rc = SSMR3PutMem(pSSM, pEl->pvData, pEl->cbData);
    10301178        AssertRCReturn(rc, rc);
    1031         rc = SSMR3PutMem(pSSM, pContext->buffer.pBackImg, cbData);
    1032         AssertRCReturn(rc, rc);
    1033 
    1034         crStateFreeFBImage(pContext);
    1035     }
    1036     else
    1037     {
    1038         VBOXVR_TEXTURE Tex;
    1039         void *pvData;
    1040         GLuint idPBO = cr_server.bUsePBOForReadback ? pMural->idPBO : 0;
    1041 
    1042         CRASSERT(!pContext->buffer.width);
    1043         CRASSERT(!pContext->buffer.height);
    1044 
    1045         if (idPBO)
    1046         {
    1047             CRASSERT(pMural->fboWidth == pMural->width);
    1048             CRASSERT(pMural->fboHeight == pMural->height);
    1049         }
    1050 
    1051         Tex.width = pMural->width;
    1052         Tex.height = pMural->height;
    1053         Tex.target = GL_TEXTURE_2D;
    1054         Tex.hwid = pMural->aidColorTexs[CR_SERVER_FBO_FB_IDX(pMural)];
    1055 
    1056         CRASSERT(Tex.hwid);
    1057 
    1058         pvData = CrHlpGetTexImage(pContext, &Tex, idPBO, GL_RGBA);
    1059         if (!pvData)
    1060         {
    1061             crWarning("CrHlpGetTexImage failed for frontbuffer");
    1062             return VERR_NO_MEMORY;
    1063         }
    1064 
    1065         rc = SSMR3PutMem(pSSM, pvData, cbData);
    1066 
    1067         CrHlpFreeTexImage(pContext, idPBO, pvData);
    1068 
    1069         AssertRCReturn(rc, rc);
    1070 
    1071         Tex.hwid = pMural->aidColorTexs[CR_SERVER_FBO_BB_IDX(pMural)];
    1072 
    1073         CRASSERT(Tex.hwid);
    1074 
    1075         pvData = CrHlpGetTexImage(pContext, &Tex, idPBO, GL_RGBA);
    1076         if (!pvData)
    1077         {
    1078             crWarning("CrHlpGetTexImage failed for backbuffer");
    1079             return VERR_NO_MEMORY;
    1080         }
    1081 
    1082         rc = SSMR3PutMem(pSSM, pvData, cbData);
    1083 
    1084         CrHlpFreeTexImage(pContext, idPBO, pvData);
    1085 
    1086         AssertRCReturn(rc, rc);
    1087     }
     1179    }
     1180
     1181    crVBoxServerFBImageDataTerm(&Data.data);
    10881182
    10891183    return VINF_SUCCESS;
     
    15791673{
    15801674    CRContext *pContext = pContextInfo->pContext;
    1581     GLint storedWidth, storedHeight;
    15821675    int32_t rc = VINF_SUCCESS;
    1583 
    1584     if (version > SHCROGL_SSM_VERSION_WITH_BUGGY_FB_IMAGE_DATA)
     1676    GLuint i;
     1677    /* can apply the data right away */
     1678    struct
     1679    {
     1680        CRFBData data;
     1681        CRFBDataElement buffer[3]; /* CRFBData::aElements[1] + buffer[3] gives 4: back, front, depth and stencil  */
     1682    } Data;
     1683
     1684    Assert(sizeof (Data) >= RT_OFFSETOF(CRFBData, aElements[4]));
     1685
     1686    if (version >= SHCROGL_SSM_VERSION_WITH_SAVED_DEPTH_STENCIL_BUFFER)
    15851687    {
    15861688        CRASSERT(cr_server.currentCtxInfo == pContextInfo);
    15871689        CRASSERT(cr_server.currentMural = pMural);
    1588         storedWidth = pMural->width;
    1589         storedHeight = pMural->height;
     1690
     1691        if (!pMural->width || !pMural->height)
     1692            return VINF_SUCCESS;
     1693
     1694        rc = crVBoxServerFBImageDataInit(&Data.data, pContextInfo, pMural, GL_TRUE);
     1695        if (!RT_SUCCESS(rc))
     1696        {
     1697            crWarning("crVBoxServerFBImageDataInit failed rc %d", rc);
     1698            return rc;
     1699        }
    15901700    }
    15911701    else
    15921702    {
    1593         storedWidth = pContext->buffer.storedWidth;
    1594         storedHeight = pContext->buffer.storedHeight;
    1595     }
    1596 
    1597     if (storedWidth && storedHeight)
     1703        GLint storedWidth, storedHeight;
     1704
     1705        if (version > SHCROGL_SSM_VERSION_WITH_BUGGY_FB_IMAGE_DATA)
     1706        {
     1707            CRASSERT(cr_server.currentCtxInfo == pContextInfo);
     1708            CRASSERT(cr_server.currentMural = pMural);
     1709            storedWidth = pMural->width;
     1710            storedHeight = pMural->height;
     1711        }
     1712        else
     1713        {
     1714            storedWidth = pContext->buffer.storedWidth;
     1715            storedHeight = pContext->buffer.storedHeight;
     1716        }
     1717
     1718        if (!storedWidth || !storedHeight)
     1719            return VINF_SUCCESS;
     1720
     1721        rc = crVBoxServerFBImageDataInitEx(&Data.data, pContextInfo, pMural, GL_TRUE, GL_TRUE, storedWidth, storedHeight);
     1722        if (!RT_SUCCESS(rc))
     1723        {
     1724            crWarning("crVBoxServerFBImageDataInit failed rc %d", rc);
     1725            return rc;
     1726        }
     1727    }
     1728
     1729    CRASSERT(Data.data.cElements);
     1730
     1731    for (i = 0; i < Data.data.cElements; ++i)
     1732    {
     1733        CRFBDataElement * pEl = &Data.data.aElements[i];
     1734        rc = SSMR3GetMem(pSSM, pEl->pvData, pEl->cbData);
     1735        AssertRCReturn(rc, rc);
     1736    }
     1737
     1738    if (version > SHCROGL_SSM_VERSION_WITH_BUGGY_FB_IMAGE_DATA)
    15981739    {
    15991740        CRBufferState *pBuf = &pContext->buffer;
    1600         GLint cbData;
    1601         void *pData;
    1602 
    1603         cbData = crPixelSize(GL_RGBA, GL_UNSIGNED_BYTE) * storedWidth * storedHeight;
    1604 
    1605         pData = crAlloc(cbData);
    1606         if (!pData)
    1607         {
    1608             crWarning("crAlloc failed trying to allocate %d of fb data", cbData);
    1609             pBuf->pFrontImg = NULL;
    1610             pBuf->pBackImg = NULL;
    1611             return VERR_NO_MEMORY;
    1612         }
    1613 
    1614         rc = SSMR3GetMem(pSSM, pData, cbData);
     1741        /* can apply the data right away */
     1742        CRASSERT(cr_server.currentCtxInfo == pContextInfo);
     1743        CRASSERT(cr_server.currentMural = pMural);
     1744
     1745        crStateApplyFBImage(pContext, &Data.data);
    16151746        AssertRCReturn(rc, rc);
    1616 
    1617         pBuf->pFrontImg = pData;
    1618 
    1619         pData = crAlloc(cbData);
    1620         if (!pData)
    1621         {
    1622             crWarning("crAlloc failed trying to allocate %d of bb data", cbData);
    1623             pBuf->pBackImg = NULL;
    1624             return VERR_NO_MEMORY;
    1625         }
    1626 
    1627         rc = SSMR3GetMem(pSSM, pData, cbData);
    1628         AssertRCReturn(rc, rc);
    1629 
    1630         pBuf->pBackImg = pData;
    1631 
    1632         if (version > SHCROGL_SSM_VERSION_WITH_BUGGY_FB_IMAGE_DATA)
    1633         {
    1634             /* can apply the data right away */
    1635             if (!pMural->fUseFBO)
     1747        CRASSERT(!pBuf->pFrontImg);
     1748        CRASSERT(!pBuf->pBackImg);
     1749        crVBoxServerFBImageDataTerm(&Data.data);
     1750
     1751        if (pMural->fUseFBO && pMural->bVisible)
     1752        {
     1753            crServerPresentFBO(pMural);
     1754        }
     1755    }
     1756    else
     1757    {
     1758        CRBufferState *pBuf = &pContext->buffer;
     1759        CRASSERT(!pBuf->pFrontImg);
     1760        CRASSERT(!pBuf->pBackImg);
     1761        CRASSERT(Data.data.cElements); /* <- older versions always saved front and back, and we filtered out the null-sized buffers above */
     1762
     1763        if (Data.data.cElements)
     1764        {
     1765            CRFBData *pLazyData = crAlloc(RT_OFFSETOF(CRFBData, aElements[Data.data.cElements]));
     1766            if (!RT_SUCCESS(rc))
    16361767            {
    1637                 CRASSERT(cr_server.bForceOffscreenRendering == CR_SERVER_REDIR_NONE);
    1638                 crStateApplyFBImage(pContext);
     1768                crVBoxServerFBImageDataTerm(&Data.data);
     1769                crWarning("crAlloc failed");
     1770                return VERR_NO_MEMORY;
    16391771            }
    1640             else
    1641             {
    1642                 VBOXVR_TEXTURE Tex;
    1643                 Tex.width = pMural->width;
    1644                 Tex.height = pMural->height;
    1645                 Tex.target = GL_TEXTURE_2D;
    1646 
    1647                 CRASSERT(cr_server.bForceOffscreenRendering > CR_SERVER_REDIR_NONE);
    1648 
    1649                 if (pBuf->pFrontImg)
    1650                 {
    1651                     Tex.hwid = pMural->aidColorTexs[CR_SERVER_FBO_FB_IDX(pMural)];
    1652                     CRASSERT(Tex.hwid);
    1653                     CrHlpPutTexImage(pContext, &Tex, GL_RGBA, pBuf->pFrontImg);
    1654                 }
    1655 
    1656                 if (pBuf->pBackImg)
    1657                 {
    1658                     Tex.hwid = pMural->aidColorTexs[CR_SERVER_FBO_BB_IDX(pMural)];
    1659                     CRASSERT(Tex.hwid);
    1660                     CrHlpPutTexImage(pContext, &Tex, GL_RGBA, pBuf->pBackImg);
    1661                 }
    1662 
    1663                 if (pBuf->pFrontImg && pMural->width && pMural->height && pMural->bVisible)
    1664                 {
    1665                     crServerPresentFBO(pMural);
    1666                 }
    1667 
    1668                 crStateFreeFBImage(pContext);
    1669             }
    1670             CRASSERT(!pBuf->pFrontImg);
    1671             CRASSERT(!pBuf->pBackImg);
     1772
     1773            crMemcpy(pLazyData, &Data.data, RT_OFFSETOF(CRFBData, aElements[Data.data.cElements]));
     1774            pBuf->pFrontImg = pLazyData;
    16721775        }
    16731776    }
     
    21112214            if (cr_server.curClient->currentCtxInfo
    21122215                && cr_server.curClient->currentCtxInfo->pContext
    2113                 && (cr_server.curClient->currentCtxInfo->pContext->buffer.pFrontImg || cr_server.curClient->currentCtxInfo->pContext->buffer.pBackImg)
     2216                && (cr_server.curClient->currentCtxInfo->pContext->buffer.pFrontImg)
    21142217                && cr_server.curClient->currentMural
    21152218                && cr_server.curClient->currentMural->screenId == sIndex
     
    21192222                int clientWindow = cr_server.curClient->currentWindow;
    21202223                int clientContext = cr_server.curClient->currentContextNumber;
     2224                CRFBData *pLazyData = (CRFBData *)cr_server.curClient->currentCtxInfo->pContext->buffer.pFrontImg;
    21212225
    21222226                if (clientWindow && clientWindow != cr_server.currentWindow)
     
    21252229                }
    21262230
    2127                 crStateApplyFBImage(cr_server.curClient->currentCtxInfo->pContext);
     2231                crStateApplyFBImage(cr_server.curClient->currentCtxInfo->pContext, pLazyData);
     2232                crStateFreeFBImageLegacy(cr_server.curClient->currentCtxInfo->pContext);
    21282233            }
    21292234        }
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