VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/expando/expandospu_init.c@ 67954

Last change on this file since 67954 was 57058, checked in by vboxsync, 9 years ago

Host 3D: Display Lists: treat more carefully with contexts when restoring.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.2 KB
Line 
1/* $Id: expandospu_init.c 57058 2015-07-23 06:19:30Z vboxsync $ */
2/* Copyright (c) 2001, Stanford University
3 * All rights reserved
4 *
5 * See the file LICENSE.txt for information on redistributing this software.
6 */
7
8#include <stdio.h>
9#include "cr_spu.h"
10#include "cr_dlm.h"
11#include "cr_hash.h"
12#include "cr_mem.h"
13#include "expandospu.h"
14
15/* This magic number is used for SSM data consistency check. */
16#define VBOX_EXPANDOSPU_SSM_MAGIC 0x3d3d3d3d
17/* Modify VBox Expando SPU SSM version if SSM data structure changed. */
18#define VBOX_EXPANDOSPU_SSM_VERSION_ONE 1
19#define VBOX_EXPANDOSPU_SSM_VERSION VBOX_EXPANDOSPU_SSM_VERSION_ONE
20
21ExpandoSPU expando_spu;
22
23static SPUFunctions expando_functions = {
24 NULL, /* CHILD COPY */
25 NULL, /* DATA */
26 _cr_expando_table /* THE ACTUAL FUNCTIONS */
27};
28
29/*
30 * Structure of SSM data:
31 *
32 * <VBOX_EXPANDOSPU_SSM_MAGIC>
33 * <VBOX_EXPANDOSPU_SSM_VERSION>
34 * <Number of Expando SPU contexts>
35 *
36 * <Context ID>
37 * <CRDLMContextState structure>
38 * <DLM module data>
39 *
40 * <Next context...>
41 *
42 * <VBOX_EXPANDOSPU_SSM_MAGIC>
43 */
44
45static void
46expandoSPUSaveContextCb(unsigned long id, void *pData1, void *pData2)
47{
48 uint32_t ui32 = (uint32_t)id;
49 PSSMHANDLE pSSM = (PSSMHANDLE)pData2;
50 int32_t rc;
51
52 ExpandoContextState *pExpandoContextState = (ExpandoContextState *)pData1;
53 CRDLMContextState dlmContextState;
54
55 /* Save context ID. */
56 rc = SSMR3PutU32(pSSM, ui32); AssertRCReturnVoid(rc);
57
58 /* Save DLM context state. Clean fields which will not be valid on restore (->dlm and ->currentListInfo).
59 * We interested only in fields: currentListIdentifier, currentListMode and listBase. */
60 crMemcpy(&dlmContextState, pExpandoContextState->dlmContext, sizeof(CRDLMContextState));
61 dlmContextState.dlm = NULL;
62 dlmContextState.currentListInfo = NULL;
63 rc = SSMR3PutMem(pSSM, &dlmContextState, sizeof(CRDLMContextState)); AssertRCReturnVoid(rc);
64
65 /* Delegate the rest of work to DLM module. */
66 crDLMSaveState(pExpandoContextState->dlmContext->dlm, pSSM);
67}
68
69static int
70expandoSPUSaveState(void *pData)
71{
72 uint32_t magic = VBOX_EXPANDOSPU_SSM_MAGIC;
73 uint32_t version = VBOX_EXPANDOSPU_SSM_VERSION;
74 PSSMHANDLE pSSM = (PSSMHANDLE)pData;
75 int32_t rc;
76 uint32_t cStates;
77
78 crDebug("Saving state of Expando SPU.");
79
80 AssertReturn(pSSM, 1);
81
82 /* Magic & version first. */
83 rc = SSMR3PutU32(pSSM, magic); AssertRCReturn(rc, rc);
84 rc = SSMR3PutU32(pSSM, version); AssertRCReturn(rc, rc);
85
86 /* Store number of Expando SPU contexts. */
87 cStates = (uint32_t)crHashtableNumElements(expando_spu.contextTable);
88 rc = SSMR3PutU32(pSSM, cStates); AssertRCReturn(rc, rc);
89
90 /* Walk over context table and store required data. */
91 crHashtableWalk(expando_spu.contextTable, expandoSPUSaveContextCb, pSSM);
92
93 /* Expando SPU and DLM data should end with magic (consistency check). */
94 rc = SSMR3PutU32(pSSM, magic); AssertRCReturn(rc, rc);
95
96 return 0;
97}
98
99static int
100expandoSPULoadState(void *pData)
101{
102 uint32_t magic = 0;
103 uint32_t version = 0;
104 PSSMHANDLE pSSM = (PSSMHANDLE)pData;
105 int32_t rc;
106
107 crDebug("Loading state of Expando SPU.");
108
109 AssertReturn(pSSM, 1);
110
111 /* Check magic and version. */
112 rc = SSMR3GetU32(pSSM, &magic);
113 AssertRCReturn(rc, rc);
114
115 if (magic == VBOX_EXPANDOSPU_SSM_MAGIC)
116 {
117 rc = SSMR3GetU32(pSSM, &version);
118 AssertRCReturn(rc, rc);
119
120 if (version >= VBOX_EXPANDOSPU_SSM_VERSION_ONE)
121 {
122 uint32_t cStates = 0;
123 uint32_t i;
124 bool fSuccess = false;
125
126 CRDLMContextState *pCurrentDLMState;
127 CRContext *pCurrentCRState;
128
129 /* Remember current state. */
130 pCurrentDLMState = crDLMGetCurrentState();
131 pCurrentCRState = crStateGetCurrent();
132
133 /* Restore number of Expando SPU contexts. */
134 rc = SSMR3GetU32(pSSM, &cStates);
135 AssertRCReturn(rc, rc);
136
137 /* Restore and update Expando SPU contexts one by one. */
138 for (i = 0; i < cStates; i++)
139 {
140 uint32_t idContext = 0;
141 ExpandoContextState *pExpandoContextState;
142
143 rc = SSMR3GetU32(pSSM, &idContext);
144 AssertRCReturn(rc, rc);
145
146 /* Find context which was previously created by CR Server. */
147 pExpandoContextState = crHashtableSearch(expando_spu.contextTable, idContext);
148 if (pExpandoContextState)
149 {
150 CRDLMContextState dlmContextState;
151
152 /* Restore and update DLM context state. */
153 rc = SSMR3GetMem(pSSM, &dlmContextState, sizeof(CRDLMContextState));
154 if (RT_SUCCESS(rc))
155 {
156 pExpandoContextState->dlmContext->currentListIdentifier = dlmContextState.currentListIdentifier;
157 pExpandoContextState->dlmContext->currentListMode = dlmContextState.currentListMode;
158 pExpandoContextState->dlmContext->listBase = dlmContextState.listBase;
159
160 crDLMSetCurrentState(pExpandoContextState->dlmContext);
161 crStateMakeCurrent(pExpandoContextState->State);
162
163 /* Delegate the rest of work to DLM module. */
164 fSuccess = crDLMLoadState(pExpandoContextState->dlmContext->dlm, pSSM, &expando_spu.server->dispatch);
165 if (fSuccess)
166 {
167 continue;
168 }
169 else
170 {
171 crError("Expando SPU: stop restoring Display Lists.");
172 break;
173 }
174 }
175 else
176 {
177 crError("Expando SPU: unable to load state: state file structure error (1).");
178 break;
179 }
180 }
181 else
182 {
183 crError("Expando SPU: unable to load state: no context ID %u found.", idContext);
184 break;
185 }
186 }
187
188 /* Restore original state. */
189 crDLMSetCurrentState(pCurrentDLMState);
190 crStateMakeCurrent(pCurrentCRState);
191
192 if (fSuccess)
193 {
194 /* Expando SPU and DLM data should end with magic (consistency check). */
195 magic = 0;
196 rc = SSMR3GetU32(pSSM, &magic);
197 if (RT_SUCCESS(rc))
198 {
199 if (magic == VBOX_EXPANDOSPU_SSM_MAGIC)
200 {
201 crInfo("Expando SPU state loaded.");
202 return 0;
203 }
204 else
205 crError("Expando SPU: unable to load state: SSM data corrupted.");
206 }
207 else
208 crError("Expando SPU: unable to load state: state file structure error (2): no magic.");
209 }
210 else
211 crError("Expando SPU: unable to load state: some list(s) could not be restored.");
212 }
213 else
214 crError("Expando SPU: unable to load state: unexpected SSM version (0x%x).", version);
215 }
216 else
217 crError("Expando SPU: unable to load state: SSM data possibly corrupted.");
218
219 return VERR_SSM_UNEXPECTED_DATA;
220}
221
222static SPUFunctions *
223expandoSPUInit(int id, SPU *child, SPU *self, unsigned int context_id, unsigned int num_contexts)
224{
225
226 (void)self;
227 (void)context_id;
228 (void)num_contexts;
229
230 expando_spu.id = id;
231 expando_spu.has_child = 0;
232 expando_spu.server = NULL;
233
234 if (child)
235 {
236 crSPUInitDispatchTable(&(expando_spu.child));
237 crSPUCopyDispatchTable(&(expando_spu.child), &(child->dispatch_table));
238 expando_spu.has_child = 1;
239 }
240
241 crSPUInitDispatchTable(&(expando_spu.super));
242 crSPUCopyDispatchTable(&(expando_spu.super), &(self->superSPU->dispatch_table));
243 expandospuGatherConfiguration();
244
245 /* Expando-specific initialization */
246 expando_spu.contextTable = crAllocHashtable();
247
248 /* We'll be using the state tracker for each context */
249 crStateInit();
250
251 /* Export optional interfaces for SPU save/restore. */
252 self->dispatch_table.spu_save_state = expandoSPUSaveState;
253 self->dispatch_table.spu_load_state = expandoSPULoadState;
254
255 return &expando_functions;
256}
257
258static void
259expandoSPUSelfDispatch(SPUDispatchTable *self)
260{
261 crSPUInitDispatchTable(&(expando_spu.self));
262 crSPUCopyDispatchTable(&(expando_spu.self), self);
263
264 expando_spu.server = (CRServer *)(self->server);
265}
266
267
268static int
269expandoSPUCleanup(void)
270{
271 crFreeHashtable(expando_spu.contextTable, expando_free_context_state);
272 crStateDestroy();
273 return 1;
274}
275
276int
277SPULoad(char **name, char **super, SPUInitFuncPtr *init, SPUSelfDispatchFuncPtr *self,
278 SPUCleanupFuncPtr *cleanup, SPUOptionsPtr *options, int *flags)
279{
280 *name = "expando";
281 *super = "render";
282 *init = expandoSPUInit;
283 *self = expandoSPUSelfDispatch;
284 *cleanup = expandoSPUCleanup;
285 *options = expandoSPUOptions;
286 *flags = (SPU_NO_PACKER|SPU_NOT_TERMINAL|SPU_MAX_SERVERS_ZERO);
287
288 return 1;
289}
Note: See TracBrowser for help on using the repository browser.

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