summaryrefslogtreecommitdiffstats
path: root/src/VBox/HostServices/SharedOpenGL/expando/expandospu_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/HostServices/SharedOpenGL/expando/expandospu_init.c')
-rw-r--r--src/VBox/HostServices/SharedOpenGL/expando/expandospu_init.c289
1 files changed, 289 insertions, 0 deletions
diff --git a/src/VBox/HostServices/SharedOpenGL/expando/expandospu_init.c b/src/VBox/HostServices/SharedOpenGL/expando/expandospu_init.c
new file mode 100644
index 00000000..f49dffbb
--- /dev/null
+++ b/src/VBox/HostServices/SharedOpenGL/expando/expandospu_init.c
@@ -0,0 +1,289 @@
+/* $Id: expandospu_init.c $ */
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include <stdio.h>
+#include "cr_spu.h"
+#include "cr_dlm.h"
+#include "cr_hash.h"
+#include "cr_mem.h"
+#include "expandospu.h"
+
+/* This magic number is used for SSM data consistency check. */
+#define VBOX_EXPANDOSPU_SSM_MAGIC 0x3d3d3d3d
+/* Modify VBox Expando SPU SSM version if SSM data structure changed. */
+#define VBOX_EXPANDOSPU_SSM_VERSION_ONE 1
+#define VBOX_EXPANDOSPU_SSM_VERSION VBOX_EXPANDOSPU_SSM_VERSION_ONE
+
+ExpandoSPU expando_spu;
+
+static SPUFunctions expando_functions = {
+ NULL, /* CHILD COPY */
+ NULL, /* DATA */
+ _cr_expando_table /* THE ACTUAL FUNCTIONS */
+};
+
+/*
+ * Structure of SSM data:
+ *
+ * <VBOX_EXPANDOSPU_SSM_MAGIC>
+ * <VBOX_EXPANDOSPU_SSM_VERSION>
+ * <Number of Expando SPU contexts>
+ *
+ * <Context ID>
+ * <CRDLMContextState structure>
+ * <DLM module data>
+ *
+ * <Next context...>
+ *
+ * <VBOX_EXPANDOSPU_SSM_MAGIC>
+ */
+
+static void
+expandoSPUSaveContextCb(unsigned long id, void *pData1, void *pData2)
+{
+ uint32_t ui32 = (uint32_t)id;
+ PSSMHANDLE pSSM = (PSSMHANDLE)pData2;
+ int32_t rc;
+
+ ExpandoContextState *pExpandoContextState = (ExpandoContextState *)pData1;
+ CRDLMContextState dlmContextState;
+
+ /* Save context ID. */
+ rc = SSMR3PutU32(pSSM, ui32); AssertRCReturnVoid(rc);
+
+ /* Save DLM context state. Clean fields which will not be valid on restore (->dlm and ->currentListInfo).
+ * We interested only in fields: currentListIdentifier, currentListMode and listBase. */
+ crMemcpy(&dlmContextState, pExpandoContextState->dlmContext, sizeof(CRDLMContextState));
+ dlmContextState.dlm = NULL;
+ dlmContextState.currentListInfo = NULL;
+ rc = SSMR3PutMem(pSSM, &dlmContextState, sizeof(CRDLMContextState)); AssertRCReturnVoid(rc);
+
+ /* Delegate the rest of work to DLM module. */
+ crDLMSaveState(pExpandoContextState->dlmContext->dlm, pSSM);
+}
+
+static int
+expandoSPUSaveState(void *pData)
+{
+ uint32_t magic = VBOX_EXPANDOSPU_SSM_MAGIC;
+ uint32_t version = VBOX_EXPANDOSPU_SSM_VERSION;
+ PSSMHANDLE pSSM = (PSSMHANDLE)pData;
+ int32_t rc;
+ uint32_t cStates;
+
+ crDebug("Saving state of Expando SPU.");
+
+ AssertReturn(pSSM, 1);
+
+ /* Magic & version first. */
+ rc = SSMR3PutU32(pSSM, magic); AssertRCReturn(rc, rc);
+ rc = SSMR3PutU32(pSSM, version); AssertRCReturn(rc, rc);
+
+ /* Store number of Expando SPU contexts. */
+ cStates = (uint32_t)crHashtableNumElements(expando_spu.contextTable);
+ rc = SSMR3PutU32(pSSM, cStates); AssertRCReturn(rc, rc);
+
+ /* Walk over context table and store required data. */
+ crHashtableWalk(expando_spu.contextTable, expandoSPUSaveContextCb, pSSM);
+
+ /* Expando SPU and DLM data should end with magic (consistency check). */
+ rc = SSMR3PutU32(pSSM, magic); AssertRCReturn(rc, rc);
+
+ return 0;
+}
+
+static int
+expandoSPULoadState(void *pData)
+{
+ uint32_t magic = 0;
+ uint32_t version = 0;
+ PSSMHANDLE pSSM = (PSSMHANDLE)pData;
+ int32_t rc;
+
+ crDebug("Loading state of Expando SPU.");
+
+ AssertReturn(pSSM, 1);
+
+ /* Check magic and version. */
+ rc = SSMR3GetU32(pSSM, &magic);
+ AssertRCReturn(rc, rc);
+
+ if (magic == VBOX_EXPANDOSPU_SSM_MAGIC)
+ {
+ rc = SSMR3GetU32(pSSM, &version);
+ AssertRCReturn(rc, rc);
+
+ if (version >= VBOX_EXPANDOSPU_SSM_VERSION_ONE)
+ {
+ uint32_t cStates = 0;
+ uint32_t i;
+ bool fSuccess = false;
+
+ CRDLMContextState *pCurrentDLMState;
+ CRContext *pCurrentCRState;
+
+ /* Remember current state. */
+ pCurrentDLMState = crDLMGetCurrentState();
+ pCurrentCRState = crStateGetCurrent();
+
+ /* Restore number of Expando SPU contexts. */
+ rc = SSMR3GetU32(pSSM, &cStates);
+ AssertRCReturn(rc, rc);
+
+ /* Restore and update Expando SPU contexts one by one. */
+ for (i = 0; i < cStates; i++)
+ {
+ uint32_t idContext = 0;
+ ExpandoContextState *pExpandoContextState;
+
+ rc = SSMR3GetU32(pSSM, &idContext);
+ AssertRCReturn(rc, rc);
+
+ /* Find context which was previously created by CR Server. */
+ pExpandoContextState = crHashtableSearch(expando_spu.contextTable, idContext);
+ if (pExpandoContextState)
+ {
+ CRDLMContextState dlmContextState;
+
+ /* Restore and update DLM context state. */
+ rc = SSMR3GetMem(pSSM, &dlmContextState, sizeof(CRDLMContextState));
+ if (RT_SUCCESS(rc))
+ {
+ pExpandoContextState->dlmContext->currentListIdentifier = dlmContextState.currentListIdentifier;
+ pExpandoContextState->dlmContext->currentListMode = dlmContextState.currentListMode;
+ pExpandoContextState->dlmContext->listBase = dlmContextState.listBase;
+
+ crDLMSetCurrentState(pExpandoContextState->dlmContext);
+ crStateMakeCurrent(pExpandoContextState->State);
+
+ /* Delegate the rest of work to DLM module. */
+ fSuccess = crDLMLoadState(pExpandoContextState->dlmContext->dlm, pSSM, &expando_spu.server->dispatch);
+ if (fSuccess)
+ {
+ continue;
+ }
+ else
+ {
+ crError("Expando SPU: stop restoring Display Lists.");
+ break;
+ }
+ }
+ else
+ {
+ crError("Expando SPU: unable to load state: state file structure error (1).");
+ break;
+ }
+ }
+ else
+ {
+ crError("Expando SPU: unable to load state: no context ID %u found.", idContext);
+ break;
+ }
+ }
+
+ /* Restore original state. */
+ crDLMSetCurrentState(pCurrentDLMState);
+ crStateMakeCurrent(pCurrentCRState);
+
+ if (fSuccess)
+ {
+ /* Expando SPU and DLM data should end with magic (consistency check). */
+ magic = 0;
+ rc = SSMR3GetU32(pSSM, &magic);
+ if (RT_SUCCESS(rc))
+ {
+ if (magic == VBOX_EXPANDOSPU_SSM_MAGIC)
+ {
+ crInfo("Expando SPU state loaded.");
+ return 0;
+ }
+ else
+ crError("Expando SPU: unable to load state: SSM data corrupted.");
+ }
+ else
+ crError("Expando SPU: unable to load state: state file structure error (2): no magic.");
+ }
+ else
+ crError("Expando SPU: unable to load state: some list(s) could not be restored.");
+ }
+ else
+ crError("Expando SPU: unable to load state: unexpected SSM version (0x%x).", version);
+ }
+ else
+ crError("Expando SPU: unable to load state: SSM data possibly corrupted.");
+
+ return VERR_SSM_UNEXPECTED_DATA;
+}
+
+static SPUFunctions *
+expandoSPUInit(int id, SPU *child, SPU *self, unsigned int context_id, unsigned int num_contexts)
+{
+
+ (void)self;
+ (void)context_id;
+ (void)num_contexts;
+
+ expando_spu.id = id;
+ expando_spu.has_child = 0;
+ expando_spu.server = NULL;
+
+ if (child)
+ {
+ crSPUInitDispatchTable(&(expando_spu.child));
+ crSPUCopyDispatchTable(&(expando_spu.child), &(child->dispatch_table));
+ expando_spu.has_child = 1;
+ }
+
+ crSPUInitDispatchTable(&(expando_spu.super));
+ crSPUCopyDispatchTable(&(expando_spu.super), &(self->superSPU->dispatch_table));
+ expandospuGatherConfiguration();
+
+ /* Expando-specific initialization */
+ expando_spu.contextTable = crAllocHashtable();
+
+ /* We'll be using the state tracker for each context */
+ crStateInit();
+
+ /* Export optional interfaces for SPU save/restore. */
+ self->dispatch_table.spu_save_state = expandoSPUSaveState;
+ self->dispatch_table.spu_load_state = expandoSPULoadState;
+
+ return &expando_functions;
+}
+
+static void
+expandoSPUSelfDispatch(SPUDispatchTable *self)
+{
+ crSPUInitDispatchTable(&(expando_spu.self));
+ crSPUCopyDispatchTable(&(expando_spu.self), self);
+
+ expando_spu.server = (CRServer *)(self->server);
+}
+
+
+static int
+expandoSPUCleanup(void)
+{
+ crFreeHashtable(expando_spu.contextTable, expando_free_context_state);
+ crStateDestroy();
+ return 1;
+}
+
+int
+SPULoad(char **name, char **super, SPUInitFuncPtr *init, SPUSelfDispatchFuncPtr *self,
+ SPUCleanupFuncPtr *cleanup, SPUOptionsPtr *options, int *flags)
+{
+ *name = "expando";
+ *super = "render";
+ *init = expandoSPUInit;
+ *self = expandoSPUSelfDispatch;
+ *cleanup = expandoSPUCleanup;
+ *options = expandoSPUOptions;
+ *flags = (SPU_NO_PACKER|SPU_NOT_TERMINAL|SPU_MAX_SERVERS_ZERO);
+
+ return 1;
+}