Changeset 44802 in vbox for trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
- Timestamp:
- Feb 22, 2013 2:34:46 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
r44748 r44802 996 996 } 997 997 998 static 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 1014 static 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 1140 static int crVBoxServerFBImageDataInit(CRFBData *pData, CRContextInfo *pCtxInfo, CRMuralInfo *pMural, GLboolean fWrite) 1141 { 1142 return crVBoxServerFBImageDataInitEx(pData, pCtxInfo, pMural, fWrite, GL_FALSE, 0, 0); 1143 } 1144 998 1145 static int crVBoxServerSaveFBImage(PSSMHANDLE pSSM) 999 1146 { 1000 int32_t rc;1147 CRContextInfo *pCtxInfo; 1001 1148 CRContext *pContext; 1002 1149 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); 1014 1172 AssertRCReturn(rc, rc); 1015 1173 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); 1030 1178 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); 1088 1182 1089 1183 return VINF_SUCCESS; … … 1579 1673 { 1580 1674 CRContext *pContext = pContextInfo->pContext; 1581 GLint storedWidth, storedHeight;1582 1675 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) 1585 1687 { 1586 1688 CRASSERT(cr_server.currentCtxInfo == pContextInfo); 1587 1689 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 } 1590 1700 } 1591 1701 else 1592 1702 { 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) 1598 1739 { 1599 1740 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); 1615 1746 AssertRCReturn(rc, rc); 1616 1617 pBuf->pFrontImg = pData;1618 1619 pData = crAlloc(cbData); 1620 if ( !pData)1621 { 1622 cr Warning("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)) 1636 1767 { 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; 1639 1771 } 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; 1672 1775 } 1673 1776 } … … 2111 2214 if (cr_server.curClient->currentCtxInfo 2112 2215 && 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) 2114 2217 && cr_server.curClient->currentMural 2115 2218 && cr_server.curClient->currentMural->screenId == sIndex … … 2119 2222 int clientWindow = cr_server.curClient->currentWindow; 2120 2223 int clientContext = cr_server.curClient->currentContextNumber; 2224 CRFBData *pLazyData = (CRFBData *)cr_server.curClient->currentCtxInfo->pContext->buffer.pFrontImg; 2121 2225 2122 2226 if (clientWindow && clientWindow != cr_server.currentWindow) … … 2125 2229 } 2126 2230 2127 crStateApplyFBImage(cr_server.curClient->currentCtxInfo->pContext); 2231 crStateApplyFBImage(cr_server.curClient->currentCtxInfo->pContext, pLazyData); 2232 crStateFreeFBImageLegacy(cr_server.curClient->currentCtxInfo->pContext); 2128 2233 } 2129 2234 }
Note:
See TracChangeset
for help on using the changeset viewer.