Changeset 44290 in vbox for trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
- Timestamp:
- Jan 14, 2013 9:49:11 PM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 83199
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
r44196 r44290 14 14 #include "cr_hash.h" 15 15 #include "cr_environment.h" 16 #include "cr_pixeldata.h" 16 17 #include "server_dispatch.h" 17 18 #include "state/cr_texture.h" … … 119 120 } 120 121 122 static void deleteMuralInfoCallback( void *data ) 123 { 124 CRMuralInfo *m = (CRMuralInfo *) data; 125 if (m->spuWindow) /* <- do not do term for default mural as it does not contain any info to be freed, 126 * and renderspu will destroy it up itself*/ 127 { 128 crServerMuralTerm(m); 129 } 130 crFree(m); 131 } 121 132 122 133 static void crServerTearDown( void ) … … 152 163 /* Free vertex programs */ 153 164 crFreeHashtable(cr_server.programTable, crFree); 165 166 /* Free dummy murals */ 167 crFreeHashtable(cr_server.dummyMuralTable, deleteMuralInfoCallback); 168 169 /* Free murals */ 170 crFreeHashtable(cr_server.muralTable, deleteMuralInfoCallback); 154 171 155 172 for (i = 0; i < cr_server.numClients; i++) { … … 309 326 cr_server.curClient->currentCtxInfo = &cr_server.MainContextInfo; 310 327 328 cr_server.dummyMuralTable = crAllocHashtable(); 329 311 330 crServerInitDispatch(); 312 331 crStateDiffAPI( &(cr_server.head_spu->dispatch_table) ); … … 383 402 */ 384 403 cr_server.contextTable = crAllocHashtable(); 404 405 cr_server.dummyMuralTable = crAllocHashtable(); 385 406 386 407 crServerSetVBoxConfigurationHGCM(); … … 693 714 rc = SSMR3PutMem(pSSM, pMI->pVisibleRects, 4*sizeof(GLint)*pMI->cVisibleRects); 694 715 } 716 717 rc = SSMR3PutMem(pSSM, pMI->ctxUsage, sizeof (pMI->ctxUsage)); 718 CRASSERT(rc == VINF_SUCCESS); 695 719 } 696 720 … … 745 769 } 746 770 771 typedef struct CRVBOX_SAVE_STATE_GLOBAL 772 { 773 /* context id -> mural association 774 * on context data save, each context will be made current with the corresponding mural from this table 775 * thus saving the mural front & back buffer data */ 776 CRHashTable *contextMuralTable; 777 /* mural id -> context info 778 * for murals that do not have associated context in contextMuralTable 779 * we still need to save*/ 780 CRHashTable *additionalMuralContextTable; 781 782 PSSMHANDLE pSSM; 783 784 int rc; 785 } CRVBOX_SAVE_STATE_GLOBAL, *PCRVBOX_SAVE_STATE_GLOBAL; 786 787 788 typedef struct CRVBOX_CTXWND_CTXWALKER_CB 789 { 790 PCRVBOX_SAVE_STATE_GLOBAL pGlobal; 791 CRHashTable *usedMuralTable; 792 GLuint cAdditionalMurals; 793 } CRVBOX_CTXWND_CTXWALKER_CB, *PCRVBOX_CTXWND_CTXWALKER_CB; 794 795 static void crVBoxServerBuildAdditionalWindowContextMapCB(unsigned long key, void *data1, void *data2) 796 { 797 CRMuralInfo * pMural = (CRMuralInfo *) data1; 798 PCRVBOX_CTXWND_CTXWALKER_CB pData = (PCRVBOX_CTXWND_CTXWALKER_CB)data2; 799 CRContextInfo *pContextInfo = NULL; 800 801 if (!pMural->CreateInfo.externalID) 802 return; 803 804 if (crHashtableSearch(pData->usedMuralTable, pMural->CreateInfo.externalID)) 805 { 806 Assert(crHashtableGetDataKey(pData->pGlobal->contextMuralTable, pMural, NULL)); 807 return; 808 } 809 810 Assert(!crHashtableGetDataKey(pData->pGlobal->contextMuralTable, pMural, NULL)); 811 812 if (cr_server.MainContextInfo.CreateInfo.visualBits == pMural->CreateInfo.visualBits) 813 { 814 pContextInfo = &cr_server.MainContextInfo; 815 } 816 else 817 { 818 crWarning("different visual bits not implemented!"); 819 pContextInfo = &cr_server.MainContextInfo; 820 } 821 822 crHashtableAdd(pData->pGlobal->additionalMuralContextTable, pMural->CreateInfo.externalID, pContextInfo); 823 } 824 825 826 typedef struct CRVBOX_CTXWND_WNDWALKER_CB 827 { 828 PCRVBOX_SAVE_STATE_GLOBAL pGlobal; 829 CRHashTable *usedMuralTable; 830 CRContextInfo *pContextInfo; 831 CRMuralInfo * pMural; 832 } CRVBOX_CTXWND_WNDWALKER_CB, *PCRVBOX_CTXWND_WNDWALKER_CB; 833 834 static void crVBoxServerBuildContextWindowMapWindowWalkerCB(unsigned long key, void *data1, void *data2) 835 { 836 CRMuralInfo * pMural = (CRMuralInfo *) data1; 837 PCRVBOX_CTXWND_WNDWALKER_CB pData = (PCRVBOX_CTXWND_WNDWALKER_CB)data2; 838 839 Assert(pData->pMural != pMural); 840 Assert(pData->pContextInfo); 841 842 if (pData->pMural) 843 return; 844 845 if (!pMural->CreateInfo.externalID) 846 return; 847 848 if (!CR_STATE_SHAREDOBJ_USAGE_IS_SET(pMural, pData->pContextInfo->pContext)) 849 return; 850 851 if (crHashtableSearch(pData->usedMuralTable, pMural->CreateInfo.externalID)) 852 return; 853 854 CRASSERT(pMural->CreateInfo.visualBits == pData->pContextInfo->CreateInfo.visualBits); 855 pData->pMural = pMural; 856 } 857 858 static void crVBoxServerBuildContextUsedWindowMapCB(unsigned long key, void *data1, void *data2) 859 { 860 CRContextInfo *pContextInfo = (CRContextInfo *)data1; 861 PCRVBOX_CTXWND_CTXWALKER_CB pData = (PCRVBOX_CTXWND_CTXWALKER_CB)data2; 862 863 if (!pContextInfo->currentMural) 864 return; 865 866 crHashtableAdd(pData->pGlobal->contextMuralTable, pContextInfo->CreateInfo.externalID, pContextInfo->currentMural); 867 crHashtableAdd(pData->usedMuralTable, pContextInfo->currentMural->CreateInfo.externalID, pContextInfo->currentMural); 868 } 869 870 CRMuralInfo * crServerGetDummyMural(GLint visualBits) 871 { 872 CRMuralInfo * pMural = (CRMuralInfo *)crHashtableSearch(cr_server.dummyMuralTable, visualBits); 873 if (!pMural) 874 { 875 GLint id; 876 pMural = (CRMuralInfo *) crCalloc(sizeof(CRMuralInfo)); 877 if (!pMural) 878 { 879 crWarning("crCalloc failed!"); 880 return NULL; 881 } 882 id = crServerMuralInit(pMural, "", visualBits, -1); 883 if (id < 0) 884 { 885 crWarning("crServerMuralInit failed!"); 886 crFree(pMural); 887 return NULL; 888 } 889 890 crHashtableAdd(cr_server.dummyMuralTable, visualBits, pMural); 891 } 892 893 return pMural; 894 } 895 896 static void crVBoxServerBuildContextUnusedWindowMapCB(unsigned long key, void *data1, void *data2) 897 { 898 CRContextInfo *pContextInfo = (CRContextInfo *)data1; 899 PCRVBOX_CTXWND_CTXWALKER_CB pData = (PCRVBOX_CTXWND_CTXWALKER_CB)data2; 900 CRMuralInfo * pMural = NULL; 901 902 if (pContextInfo->currentMural) 903 return; 904 905 Assert(crHashtableNumElements(pData->pGlobal->contextMuralTable) <= crHashtableNumElements(cr_server.muralTable) - 1); 906 if (crHashtableNumElements(pData->pGlobal->contextMuralTable) < crHashtableNumElements(cr_server.muralTable) - 1) 907 { 908 CRVBOX_CTXWND_WNDWALKER_CB MuralData; 909 MuralData.pGlobal = pData->pGlobal; 910 MuralData.usedMuralTable = pData->usedMuralTable; 911 MuralData.pContextInfo = pContextInfo; 912 MuralData.pMural = NULL; 913 914 crHashtableWalk(cr_server.muralTable, crVBoxServerBuildContextWindowMapWindowWalkerCB, &MuralData); 915 916 pMural = MuralData.pMural; 917 918 } 919 920 if (!pMural) 921 { 922 pMural = crServerGetDummyMural(pContextInfo->CreateInfo.visualBits); 923 if (!pMural) 924 { 925 crWarning("crServerGetDummyMural failed"); 926 return; 927 } 928 } 929 else 930 { 931 crHashtableAdd(pData->usedMuralTable, pMural->CreateInfo.externalID, pMural); 932 ++pData->cAdditionalMurals; 933 } 934 935 crHashtableAdd(pData->pGlobal->contextMuralTable, pContextInfo->CreateInfo.externalID, pMural); 936 } 937 938 static void crVBoxServerBuildSaveStateGlobal(PCRVBOX_SAVE_STATE_GLOBAL pGlobal) 939 { 940 CRVBOX_CTXWND_CTXWALKER_CB Data; 941 GLuint cMurals; 942 pGlobal->contextMuralTable = crAllocHashtable(); 943 pGlobal->additionalMuralContextTable = crAllocHashtable(); 944 /* 1. go through all contexts and match all having currentMural set */ 945 Data.pGlobal = pGlobal; 946 Data.usedMuralTable = crAllocHashtable(); 947 Data.cAdditionalMurals = 0; 948 crHashtableWalk(cr_server.contextTable, crVBoxServerBuildContextUsedWindowMapCB, &Data); 949 950 cMurals = crHashtableNumElements(pGlobal->contextMuralTable); 951 CRASSERT(cMurals <= crHashtableNumElements(cr_server.contextTable)); 952 CRASSERT(cMurals <= crHashtableNumElements(cr_server.muralTable) - 1); 953 CRASSERT(cMurals == crHashtableNumElements(Data.usedMuralTable)); 954 if (cMurals < crHashtableNumElements(cr_server.contextTable)) 955 { 956 Data.cAdditionalMurals = 0; 957 crHashtableWalk(cr_server.contextTable, crVBoxServerBuildContextUnusedWindowMapCB, &Data); 958 } 959 960 CRASSERT(crHashtableNumElements(pGlobal->contextMuralTable) == crHashtableNumElements(cr_server.contextTable)); 961 CRASSERT(cMurals + Data.cAdditionalMurals <= crHashtableNumElements(cr_server.muralTable) - 1); 962 if (cMurals + Data.cAdditionalMurals < crHashtableNumElements(cr_server.muralTable) - 1) 963 { 964 crHashtableWalk(cr_server.muralTable, crVBoxServerBuildAdditionalWindowContextMapCB, &Data); 965 CRASSERT(cMurals + Data.cAdditionalMurals + crHashtableNumElements(pGlobal->additionalMuralContextTable) == crHashtableNumElements(cr_server.muralTable) - 1); 966 } 967 } 968 969 static int crVBoxServerSaveFBImage(PSSMHANDLE pSSM) 970 { 971 int32_t rc; 972 CRContext *pContext; 973 CRMuralInfo *pMural; 974 GLint cbData; 975 976 CRASSERT(cr_server.currentCtxInfo); 977 CRASSERT(cr_server.currentCtxInfo->currentMural); 978 979 pContext = cr_server.currentCtxInfo->pContext; 980 pMural = cr_server.currentCtxInfo->currentMural; 981 /* do crStateAcquireFBImage no matter whether offscreen drawing is used or not 982 * in the former case this would just free pContext->buffer.pFrontImg and pContext->buffer.pFrontImg 983 */ 984 rc = crStateAcquireFBImage(pContext); 985 AssertRCReturn(rc, rc); 986 987 if (!pMural->width || !pMural->height) 988 return VINF_SUCCESS; 989 990 991 cbData = crPixelSize(GL_RGBA, GL_UNSIGNED_BYTE) * pMural->width * pMural->height; 992 993 if (!pMural->fUseFBO) 994 { 995 CRASSERT(pMural->width == pContext->buffer.storedWidth); 996 CRASSERT(pMural->width == pContext->buffer.width); 997 CRASSERT(pMural->height == pContext->buffer.storedHeight); 998 CRASSERT(pMural->height == pContext->buffer.height); 999 1000 rc = SSMR3PutMem(pSSM, pContext->buffer.pFrontImg, cbData); 1001 AssertRCReturn(rc, rc); 1002 rc = SSMR3PutMem(pSSM, pContext->buffer.pBackImg, cbData); 1003 AssertRCReturn(rc, rc); 1004 1005 crStateFreeFBImage(pContext); 1006 } 1007 else 1008 { 1009 CR_BLITTER_TEXTURE Tex; 1010 void *pvData; 1011 GLuint idPBO = cr_server.bUsePBOForReadback ? pMural->idPBO : 0; 1012 1013 if (idPBO) 1014 { 1015 CRASSERT(pMural->fboWidth == pMural->width); 1016 CRASSERT(pMural->fboHeight == pMural->height); 1017 } 1018 1019 Tex.width = pMural->width; 1020 Tex.height = pMural->height; 1021 Tex.target = GL_TEXTURE_2D; 1022 Tex.hwid = pMural->aidColorTexs[CR_SERVER_FBO_FB_IDX(pMural)]; 1023 1024 CRASSERT(Tex.hwid); 1025 1026 pvData = CrHlpGetTexImage(pContext, &Tex, idPBO); 1027 if (!pvData) 1028 { 1029 crWarning("CrHlpGetTexImage failed for frontbuffer"); 1030 return VERR_NO_MEMORY; 1031 } 1032 1033 rc = SSMR3PutMem(pSSM, pvData, cbData); 1034 1035 CrHlpFreeTexImage(pContext, idPBO, pvData); 1036 1037 AssertRCReturn(rc, rc); 1038 1039 Tex.hwid = pMural->aidColorTexs[CR_SERVER_FBO_BB_IDX(pMural)]; 1040 1041 CRASSERT(Tex.hwid); 1042 1043 pvData = CrHlpGetTexImage(pContext, &Tex, idPBO); 1044 if (!pvData) 1045 { 1046 crWarning("CrHlpGetTexImage failed for backbuffer"); 1047 return VERR_NO_MEMORY; 1048 } 1049 1050 rc = SSMR3PutMem(pSSM, pvData, cbData); 1051 1052 CrHlpFreeTexImage(pContext, idPBO, pvData); 1053 1054 AssertRCReturn(rc, rc); 1055 } 1056 1057 return VINF_SUCCESS; 1058 } 1059 1060 #define CRSERVER_ASSERTRC_RETURN_VOID(_rc) do { \ 1061 if(!RT_SUCCESS((_rc))) { \ 1062 AssertFailed(); \ 1063 return; \ 1064 } \ 1065 } while (0) 1066 1067 static void crVBoxServerSaveAdditionalMuralsCB(unsigned long key, void *data1, void *data2) 1068 { 1069 CRContextInfo *pContextInfo = (CRContextInfo *) data1; 1070 PCRVBOX_SAVE_STATE_GLOBAL pData = (PCRVBOX_SAVE_STATE_GLOBAL)data2; 1071 CRMuralInfo *pMural = (CRMuralInfo*)crHashtableSearch(cr_server.muralTable, key); 1072 PSSMHANDLE pSSM = pData->pSSM; 1073 CRbitvalue initialCtxUsage[CR_MAX_BITARRAY]; 1074 CRMuralInfo *pInitialCurMural = pContextInfo->currentMural; 1075 1076 crMemcpy(initialCtxUsage, pMural->ctxUsage, sizeof (initialCtxUsage)); 1077 1078 CRSERVER_ASSERTRC_RETURN_VOID(pData->rc); 1079 1080 pData->rc = SSMR3PutMem(pSSM, &key, sizeof(key)); 1081 CRSERVER_ASSERTRC_RETURN_VOID(pData->rc); 1082 1083 pData->rc = SSMR3PutMem(pSSM, &pContextInfo->CreateInfo.externalID, sizeof(pContextInfo->CreateInfo.externalID)); 1084 CRSERVER_ASSERTRC_RETURN_VOID(pData->rc); 1085 1086 crServerPerformMakeCurrent(pMural, pContextInfo); 1087 1088 pData->rc = crVBoxServerSaveFBImage(pSSM); 1089 1090 /* restore the reference data, we synchronize it with the HW state in a later crServerPerformMakeCurrent call */ 1091 crMemcpy(pMural->ctxUsage, initialCtxUsage, sizeof (initialCtxUsage)); 1092 pContextInfo->currentMural = pInitialCurMural; 1093 1094 CRSERVER_ASSERTRC_RETURN_VOID(pData->rc); 1095 } 1096 747 1097 static void crVBoxServerSaveContextStateCB(unsigned long key, void *data1, void *data2) 748 1098 { 749 1099 CRContextInfo *pContextInfo = (CRContextInfo *) data1; 750 1100 CRContext *pContext = pContextInfo->pContext; 751 PSSMHANDLE pSSM = (PSSMHANDLE) data2; 752 int32_t rc; 1101 PCRVBOX_SAVE_STATE_GLOBAL pData = (PCRVBOX_SAVE_STATE_GLOBAL)data2; 1102 PSSMHANDLE pSSM = pData->pSSM; 1103 CRMuralInfo *pMural = (CRMuralInfo*)crHashtableSearch(pData->contextMuralTable, key); 1104 CRMuralInfo *pContextCurrentMural = pContextInfo->currentMural; 1105 const int32_t i32Dummy = 0; 1106 1107 AssertCompile(sizeof (i32Dummy) == sizeof (pMural->CreateInfo.externalID)); 1108 CRSERVER_ASSERTRC_RETURN_VOID(pData->rc); 753 1109 754 1110 CRASSERT(pContext && pSSM); 1111 CRASSERT(pMural); 755 1112 756 1113 /* We could have skipped saving the key and use similar callback to load context states back, 757 1114 * but there's no guarantee we'd traverse hashtable in same order after loading. 758 1115 */ 759 rc = SSMR3PutMem(pSSM, &key, sizeof(key)); 760 CRASSERT(rc == VINF_SUCCESS); 761 762 #ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE 763 CRASSERT(cr_server.curClient); 764 if (cr_server.curClient) 765 { 766 # ifdef DEBUG_misha 767 { 1116 pData->rc = SSMR3PutMem(pSSM, &key, sizeof(key)); 1117 CRSERVER_ASSERTRC_RETURN_VOID(pData->rc); 1118 1119 #ifdef DEBUG_misha 1120 { 768 1121 unsigned long id; 769 1122 if (!crHashtableGetDataKey(cr_server.contextTable, pContextInfo, &id)) 770 crWarning("No client id for server ctx %d", pContext ->id);1123 crWarning("No client id for server ctx %d", pContextInfo->CreateInfo.externalID); 771 1124 else 772 1125 CRASSERT(id == key); 773 } 774 # endif 775 crServerDispatchMakeCurrent(cr_server.curClient->currentWindow, 0, key); 776 } 777 #endif 778 779 rc = crStateSaveContext(pContext, pSSM); 780 CRASSERT(rc == VINF_SUCCESS); 1126 } 1127 #endif 1128 1129 #ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE 1130 if (pContextInfo->currentMural || crHashtableSearch(cr_server.muralTable, key)) 1131 { 1132 CRASSERT(pMural->CreateInfo.externalID); 1133 pData->rc = SSMR3PutMem(pSSM, &pMural->CreateInfo.externalID, sizeof(pMural->CreateInfo.externalID)); 1134 } 1135 else 1136 { 1137 CRASSERT(!pMural->width); 1138 CRASSERT(!pMural->height); 1139 CRASSERT(crHashtableSearch(cr_server.dummyMuralTable, key)); 1140 pData->rc = SSMR3PutMem(pSSM, &i32Dummy, sizeof(pMural->CreateInfo.externalID)); 1141 } 1142 CRSERVER_ASSERTRC_RETURN_VOID(pData->rc); 1143 1144 CRASSERT(CR_STATE_SHAREDOBJ_USAGE_IS_SET(pMural, pContext)); 1145 CRASSERT(pContextInfo->currentMural == pMural || !pContextInfo->currentMural); 1146 CRASSERT(cr_server.curClient); 1147 1148 crServerPerformMakeCurrent(pMural, pContextInfo); 1149 #endif 1150 1151 pData->rc = crStateSaveContext(pContext, pSSM); 1152 CRSERVER_ASSERTRC_RETURN_VOID(pData->rc); 1153 1154 pData->rc = crVBoxServerSaveFBImage(pSSM); 1155 CRSERVER_ASSERTRC_RETURN_VOID(pData->rc); 1156 1157 /* restore the initial current mural */ 1158 pContextInfo->currentMural = pContextCurrentMural; 781 1159 } 782 1160 … … 910 1288 GLenum err; 911 1289 #ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE 912 unsigned long ctxID=-1, winID=-1; 913 #endif 1290 CRClient *curClient; 1291 CRMuralInfo *curMural = NULL; 1292 CRContextInfo *curCtxInfo = NULL; 1293 #endif 1294 CRVBOX_SAVE_STATE_GLOBAL Data = {0}; 914 1295 915 1296 #if 0 … … 950 1331 951 1332 #ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE 1333 curClient = cr_server.curClient; 952 1334 /* Save current win and ctx IDs, as we'd rebind contexts when saving textures */ 953 if (cr_server.curClient) 954 { 955 ctxID = cr_server.curClient->currentContextNumber; 956 winID = cr_server.curClient->currentWindow; 957 } 958 #endif 959 960 /* Save contexts state tracker data */ 961 /* @todo For now just some blind data dumps, 962 * but I've a feeling those should be saved/restored in a very strict sequence to 963 * allow diff_api to work correctly. 964 * Should be tested more with multiply guest opengl apps working when saving VM snapshot. 965 */ 966 crHashtableWalk(cr_server.contextTable, crVBoxServerSaveContextStateCB, pSSM); 967 968 #ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE 969 /* Restore original win and ctx IDs*/ 970 if (cr_server.curClient) 971 { 972 crServerDispatchMakeCurrent(winID, 0, ctxID); 973 } 974 #endif 975 1335 if (curClient) 1336 { 1337 curCtxInfo = cr_server.curClient->currentCtxInfo; 1338 curMural = cr_server.curClient->currentMural; 1339 } 1340 else if (cr_server.numClients) 1341 { 1342 cr_server.curClient = cr_server.clients[0]; 1343 } 1344 #endif 1345 1346 /* first save windows info */ 976 1347 /* Save windows creation info */ 977 1348 ui32 = crHashtableNumElements(cr_server.muralTable); … … 989 1360 crHashtableWalk(cr_server.muralTable, crVBoxServerSaveMuralCB, pSSM); 990 1361 991 /* Save starting free context and window IDs */ 992 rc = SSMR3PutMem(pSSM, &cr_server.idsPool, sizeof(cr_server.idsPool)); 1362 /* we need to save front & backbuffer data for each mural first create a context -> mural association */ 1363 crVBoxServerBuildSaveStateGlobal(&Data); 1364 1365 rc = crStateSaveGlobals(pSSM); 993 1366 AssertRCReturn(rc, rc); 1367 1368 Data.pSSM = pSSM; 1369 /* Save contexts state tracker data */ 1370 /* @todo For now just some blind data dumps, 1371 * but I've a feeling those should be saved/restored in a very strict sequence to 1372 * allow diff_api to work correctly. 1373 * Should be tested more with multiply guest opengl apps working when saving VM snapshot. 1374 */ 1375 crHashtableWalk(cr_server.contextTable, crVBoxServerSaveContextStateCB, &Data); 1376 AssertRCReturn(Data.rc, Data.rc); 1377 1378 ui32 = crHashtableNumElements(Data.additionalMuralContextTable); 1379 rc = SSMR3PutU32(pSSM, (uint32_t) ui32); 1380 AssertRCReturn(rc, rc); 1381 1382 crHashtableWalk(Data.additionalMuralContextTable, crVBoxServerSaveAdditionalMuralsCB, &Data); 1383 AssertRCReturn(Data.rc, Data.rc); 1384 1385 #ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE 1386 cr_server.curClient = curClient; 1387 /* Restore original win and ctx IDs*/ 1388 if (curClient && curMural && curCtxInfo) 1389 { 1390 crServerPerformMakeCurrent(curMural, curCtxInfo); 1391 } 1392 else 1393 { 1394 cr_server.bForceMakeCurrentOnClientSwitch = GL_TRUE; 1395 } 1396 #endif 994 1397 995 1398 /* Save clients info */ … … 1048 1451 } 1049 1452 1453 static int32_t crVBoxServerLoadMurals(PSSMHANDLE pSSM, uint32_t version) 1454 { 1455 unsigned long key; 1456 uint32_t ui, uiNumElems; 1457 /* Load windows */ 1458 int32_t rc = SSMR3GetU32(pSSM, &uiNumElems); 1459 AssertRCReturn(rc, rc); 1460 for (ui=0; ui<uiNumElems; ++ui) 1461 { 1462 CRCreateInfo_t createInfo; 1463 char psz[200]; 1464 GLint winID; 1465 unsigned long key; 1466 1467 rc = SSMR3GetMem(pSSM, &key, sizeof(key)); 1468 AssertRCReturn(rc, rc); 1469 rc = SSMR3GetMem(pSSM, &createInfo, sizeof(createInfo)); 1470 AssertRCReturn(rc, rc); 1471 1472 if (createInfo.pszDpyName) 1473 { 1474 rc = SSMR3GetStrZEx(pSSM, psz, 200, NULL); 1475 AssertRCReturn(rc, rc); 1476 createInfo.pszDpyName = psz; 1477 } 1478 1479 winID = crServerDispatchWindowCreateEx(createInfo.pszDpyName, createInfo.visualBits, key); 1480 CRASSERT((int64_t)winID == (int64_t)key); 1481 } 1482 1483 /* Load cr_server.muralTable */ 1484 rc = SSMR3GetU32(pSSM, &uiNumElems); 1485 AssertRCReturn(rc, rc); 1486 for (ui=0; ui<uiNumElems; ++ui) 1487 { 1488 CRMuralInfo muralInfo; 1489 1490 rc = SSMR3GetMem(pSSM, &key, sizeof(key)); 1491 AssertRCReturn(rc, rc); 1492 rc = SSMR3GetMem(pSSM, &muralInfo, RT_OFFSETOF(CRMuralInfo, CreateInfo)); 1493 AssertRCReturn(rc, rc); 1494 1495 if (version <= SHCROGL_SSM_VERSION_BEFORE_FRONT_DRAW_TRACKING) 1496 muralInfo.bFbDraw = GL_TRUE; 1497 1498 if (muralInfo.pVisibleRects) 1499 { 1500 muralInfo.pVisibleRects = crAlloc(4*sizeof(GLint)*muralInfo.cVisibleRects); 1501 if (!muralInfo.pVisibleRects) 1502 { 1503 return VERR_NO_MEMORY; 1504 } 1505 1506 rc = SSMR3GetMem(pSSM, muralInfo.pVisibleRects, 4*sizeof(GLint)*muralInfo.cVisibleRects); 1507 AssertRCReturn(rc, rc); 1508 } 1509 1510 if (version >= SHCROGL_SSM_VERSION_WITH_WINDOW_CTX_USAGE) 1511 { 1512 CRMuralInfo *pActualMural = (CRMuralInfo *)crHashtableSearch(cr_server.muralTable, key);; 1513 CRASSERT(pActualMural); 1514 rc = SSMR3GetMem(pSSM, pActualMural->ctxUsage, sizeof (pActualMural->ctxUsage)); 1515 CRASSERT(rc == VINF_SUCCESS); 1516 } 1517 1518 /* Restore windows geometry info */ 1519 crServerDispatchWindowSize(key, muralInfo.width, muralInfo.height); 1520 crServerDispatchWindowPosition(key, muralInfo.gX, muralInfo.gY); 1521 /* Same workaround as described in stub.c:stubUpdateWindowVisibileRegions for compiz on a freshly booted VM*/ 1522 if (muralInfo.bReceivedRects) 1523 { 1524 crServerDispatchWindowVisibleRegion(key, muralInfo.cVisibleRects, muralInfo.pVisibleRects); 1525 } 1526 crServerDispatchWindowShow(key, muralInfo.bVisible); 1527 1528 if (muralInfo.pVisibleRects) 1529 { 1530 crFree(muralInfo.pVisibleRects); 1531 } 1532 } 1533 1534 CRASSERT(RT_SUCCESS(rc)); 1535 return VINF_SUCCESS; 1536 } 1537 1538 static int crVBoxServerLoadFBImage(PSSMHANDLE pSSM, uint32_t version, 1539 CRContextInfo* pContextInfo, CRMuralInfo *pMural) 1540 { 1541 CRContext *pContext = pContextInfo->pContext; 1542 GLint storedWidth, storedHeight; 1543 int32_t rc = VINF_SUCCESS; 1544 1545 if (version > SHCROGL_SSM_VERSION_WITH_BUGGY_FB_IMAGE_DATA) 1546 { 1547 CRASSERT(cr_server.currentCtxInfo == pContextInfo); 1548 CRASSERT(cr_server.currentMural = pMural); 1549 storedWidth = pMural->width; 1550 storedHeight = pMural->height; 1551 CRASSERT(pContext->buffer.storedWidth == storedWidth); 1552 CRASSERT(pContext->buffer.storedHeight == storedHeight); 1553 } 1554 else 1555 { 1556 storedWidth = pContext->buffer.storedWidth; 1557 storedHeight = pContext->buffer.storedHeight; 1558 } 1559 1560 if (storedWidth && storedHeight) 1561 { 1562 CRBufferState *pBuf = &pContext->buffer; 1563 GLint cbData; 1564 void *pData; 1565 1566 cbData = crPixelSize(GL_RGBA, GL_UNSIGNED_BYTE) * storedWidth * storedHeight; 1567 1568 pData = crAlloc(cbData); 1569 if (!pData) 1570 { 1571 crWarning("crAlloc failed trying to allocate %d of fb data", cbData); 1572 pBuf->pFrontImg = NULL; 1573 pBuf->pBackImg = NULL; 1574 return VERR_NO_MEMORY; 1575 } 1576 1577 rc = SSMR3GetMem(pSSM, pData, cbData); 1578 AssertRCReturn(rc, rc); 1579 1580 pBuf->pFrontImg = pData; 1581 1582 pData = crAlloc(cbData); 1583 if (!pData) 1584 { 1585 crWarning("crAlloc failed trying to allocate %d of bb data", cbData); 1586 pBuf->pBackImg = NULL; 1587 return VERR_NO_MEMORY; 1588 } 1589 1590 rc = SSMR3GetMem(pSSM, pData, cbData); 1591 AssertRCReturn(rc, rc); 1592 1593 pBuf->pBackImg = pData; 1594 1595 if (version > SHCROGL_SSM_VERSION_WITH_BUGGY_FB_IMAGE_DATA) 1596 { 1597 /* can apply the data right away */ 1598 crStateApplyFBImage(pContext); 1599 CRASSERT(!pBuf->pFrontImg); 1600 CRASSERT(!pBuf->pBackImg); 1601 } 1602 } 1603 1604 CRASSERT(RT_SUCCESS(rc)); 1605 return VINF_SUCCESS; 1606 } 1607 1050 1608 DECLEXPORT(int32_t) crVBoxServerLoadState(PSSMHANDLE pSSM, uint32_t version) 1051 1609 { … … 1111 1669 } 1112 1670 1671 if (version > SHCROGL_SSM_VERSION_WITH_BUGGY_FB_IMAGE_DATA) 1672 { 1673 /* we have a mural data here */ 1674 rc = crVBoxServerLoadMurals(pSSM, version); 1675 AssertRCReturn(rc, rc); 1676 } 1677 1678 if (version > SHCROGL_SSM_VERSION_WITH_BUGGY_FB_IMAGE_DATA && uiNumElems) 1679 { 1680 /* set the current client to allow doing crServerPerformMakeCurrent later */ 1681 CRASSERT(cr_server.numClients); 1682 cr_server.curClient = cr_server.clients[0]; 1683 } 1684 1685 rc = crStateLoadGlobals(pSSM, version); 1686 AssertRCReturn(rc, rc); 1687 1113 1688 /* Restore context state data */ 1114 1689 for (ui=0; ui<uiNumElems; ++ui) … … 1116 1691 CRContextInfo* pContextInfo; 1117 1692 CRContext *pContext; 1693 CRMuralInfo *pMural = NULL; 1694 int32_t winId = 0; 1118 1695 1119 1696 rc = SSMR3GetMem(pSSM, &key, sizeof(key)); … … 1125 1702 pContext = pContextInfo->pContext; 1126 1703 1704 if (version > SHCROGL_SSM_VERSION_WITH_BUGGY_FB_IMAGE_DATA) 1705 { 1706 rc = SSMR3GetMem(pSSM, &winId, sizeof(winId)); 1707 AssertRCReturn(rc, rc); 1708 1709 if (winId) 1710 { 1711 pMural = (CRMuralInfo*)crHashtableSearch(cr_server.muralTable, winId); 1712 CRASSERT(pMural); 1713 } 1714 else 1715 { 1716 /* null winId means a dummy mural, get it */ 1717 pMural = crServerGetDummyMural(pContextInfo->CreateInfo.visualBits); 1718 CRASSERT(pMural); 1719 } 1720 1721 crServerPerformMakeCurrent(pMural, pContextInfo); 1722 } 1723 1127 1724 rc = crStateLoadContext(pContext, cr_server.contextTable, crVBoxServerGetContextCB, pSSM, version); 1128 1725 AssertRCReturn(rc, rc); 1129 } 1130 1131 /* Load windows */ 1132 rc = SSMR3GetU32(pSSM, &uiNumElems); 1133 AssertRCReturn(rc, rc); 1134 for (ui=0; ui<uiNumElems; ++ui) 1135 { 1136 CRCreateInfo_t createInfo; 1137 char psz[200]; 1138 GLint winID; 1139 unsigned long key; 1140 1141 rc = SSMR3GetMem(pSSM, &key, sizeof(key)); 1726 1727 /*Restore front/back buffer images*/ 1728 rc = crVBoxServerLoadFBImage(pSSM, version, pContextInfo, pMural); 1142 1729 AssertRCReturn(rc, rc); 1143 rc = SSMR3GetMem(pSSM, &createInfo, sizeof(createInfo)); 1730 } 1731 1732 if (version > SHCROGL_SSM_VERSION_WITH_BUGGY_FB_IMAGE_DATA) 1733 { 1734 CRContextInfo *pContextInfo; 1735 CRMuralInfo *pMural; 1736 GLint ctxId; 1737 1738 rc = SSMR3GetU32(pSSM, &uiNumElems); 1144 1739 AssertRCReturn(rc, rc); 1145 1146 if (createInfo.pszDpyName) 1147 { 1148 rc = SSMR3GetStrZEx(pSSM, psz, 200, NULL); 1740 for (ui=0; ui<uiNumElems; ++ui) 1741 { 1742 CRbitvalue initialCtxUsage[CR_MAX_BITARRAY]; 1743 CRMuralInfo *pInitialCurMural; 1744 1745 rc = SSMR3GetMem(pSSM, &key, sizeof(key)); 1149 1746 AssertRCReturn(rc, rc); 1150 createInfo.pszDpyName = psz; 1151 } 1152 1153 winID = crServerDispatchWindowCreateEx(createInfo.pszDpyName, createInfo.visualBits, key); 1154 CRASSERT((int64_t)winID == (int64_t)key); 1155 } 1156 1157 /* Load cr_server.muralTable */ 1158 rc = SSMR3GetU32(pSSM, &uiNumElems); 1159 AssertRCReturn(rc, rc); 1160 for (ui=0; ui<uiNumElems; ++ui) 1161 { 1162 CRMuralInfo muralInfo; 1163 1164 rc = SSMR3GetMem(pSSM, &key, sizeof(key)); 1747 1748 rc = SSMR3GetMem(pSSM, &ctxId, sizeof(ctxId)); 1749 AssertRCReturn(rc, rc); 1750 1751 pMural = (CRMuralInfo*)crHashtableSearch(cr_server.muralTable, key); 1752 CRASSERT(pMural); 1753 if (ctxId) 1754 { 1755 pContextInfo = (CRContextInfo *)crHashtableSearch(cr_server.contextTable, ctxId); 1756 CRASSERT(pContextInfo); 1757 } 1758 else 1759 pContextInfo = &cr_server.MainContextInfo; 1760 1761 crMemcpy(initialCtxUsage, pMural->ctxUsage, sizeof (initialCtxUsage)); 1762 pInitialCurMural = pContextInfo->currentMural; 1763 1764 crServerPerformMakeCurrent(pMural, pContextInfo); 1765 1766 rc = crVBoxServerLoadFBImage(pSSM, version, pContextInfo, pMural); 1767 AssertRCReturn(rc, rc); 1768 1769 /* restore the reference data, we synchronize it with the HW state in a later crServerPerformMakeCurrent call */ 1770 crMemcpy(pMural->ctxUsage, initialCtxUsage, sizeof (initialCtxUsage)); 1771 pContextInfo->currentMural = pInitialCurMural; 1772 } 1773 1774 if (cr_server.currentCtxInfo != &cr_server.MainContextInfo) 1775 { 1776 /* most ogl data gets loaded to hw on chromium 3D state switch, i.e. inside crStateMakeCurrent -> crStateSwitchContext 1777 * to force the crStateSwitchContext being called later, we need to set the current context to our dummy one */ 1778 pMural = crServerGetDummyMural(cr_server.MainContextInfo.CreateInfo.visualBits); 1779 CRASSERT(pMural); 1780 crServerPerformMakeCurrent(pMural, &cr_server.MainContextInfo); 1781 } 1782 1783 cr_server.curClient = NULL; 1784 cr_server.bForceMakeCurrentOnClientSwitch = GL_TRUE; 1785 } 1786 else 1787 { 1788 CRServerFreeIDsPool_t dummyIdsPool; 1789 1790 /* we have a mural data here */ 1791 rc = crVBoxServerLoadMurals(pSSM, version); 1165 1792 AssertRCReturn(rc, rc); 1166 rc = SSMR3GetMem(pSSM, &muralInfo, RT_OFFSETOF(CRMuralInfo, CreateInfo)); 1167 AssertRCReturn(rc, rc); 1168 1169 if (version <= SHCROGL_SSM_VERSION_BEFORE_FRONT_DRAW_TRACKING) 1170 muralInfo.bFbDraw = GL_TRUE; 1171 1172 if (muralInfo.pVisibleRects) 1173 { 1174 muralInfo.pVisibleRects = crAlloc(4*sizeof(GLint)*muralInfo.cVisibleRects); 1175 if (!muralInfo.pVisibleRects) 1176 { 1177 return VERR_NO_MEMORY; 1178 } 1179 1180 rc = SSMR3GetMem(pSSM, muralInfo.pVisibleRects, 4*sizeof(GLint)*muralInfo.cVisibleRects); 1181 AssertRCReturn(rc, rc); 1182 } 1183 1184 /* Restore windows geometry info */ 1185 crServerDispatchWindowSize(key, muralInfo.width, muralInfo.height); 1186 crServerDispatchWindowPosition(key, muralInfo.gX, muralInfo.gY); 1187 /* Same workaround as described in stub.c:stubUpdateWindowVisibileRegions for compiz on a freshly booted VM*/ 1188 if (muralInfo.bReceivedRects) 1189 { 1190 crServerDispatchWindowVisibleRegion(key, muralInfo.cVisibleRects, muralInfo.pVisibleRects); 1191 } 1192 crServerDispatchWindowShow(key, muralInfo.bVisible); 1193 1194 if (muralInfo.pVisibleRects) 1195 { 1196 crFree(muralInfo.pVisibleRects); 1197 } 1198 } 1199 1200 /* Load starting free context and window IDs */ 1201 rc = SSMR3GetMem(pSSM, &cr_server.idsPool, sizeof(cr_server.idsPool)); 1202 CRASSERT(rc == VINF_SUCCESS); 1793 1794 /* not used any more, just read it out and ignore */ 1795 rc = SSMR3GetMem(pSSM, &dummyIdsPool, sizeof(dummyIdsPool)); 1796 CRASSERT(rc == VINF_SUCCESS); 1797 } 1203 1798 1204 1799 /* Load clients info */
Note:
See TracChangeset
for help on using the changeset viewer.