summaryrefslogtreecommitdiffstats
path: root/src/VBox/HostServices/SharedOpenGL/expando
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/HostServices/SharedOpenGL/expando')
-rw-r--r--src/VBox/HostServices/SharedOpenGL/expando/Makefile.kup0
-rw-r--r--src/VBox/HostServices/SharedOpenGL/expando/expando.py91
-rw-r--r--src/VBox/HostServices/SharedOpenGL/expando/expando_special18
-rw-r--r--src/VBox/HostServices/SharedOpenGL/expando/expandospu.c182
-rw-r--r--src/VBox/HostServices/SharedOpenGL/expando/expandospu.def6
-rw-r--r--src/VBox/HostServices/SharedOpenGL/expando/expandospu.h69
-rw-r--r--src/VBox/HostServices/SharedOpenGL/expando/expandospu_config.c48
-rw-r--r--src/VBox/HostServices/SharedOpenGL/expando/expandospu_init.c289
8 files changed, 703 insertions, 0 deletions
diff --git a/src/VBox/HostServices/SharedOpenGL/expando/Makefile.kup b/src/VBox/HostServices/SharedOpenGL/expando/Makefile.kup
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/VBox/HostServices/SharedOpenGL/expando/Makefile.kup
diff --git a/src/VBox/HostServices/SharedOpenGL/expando/expando.py b/src/VBox/HostServices/SharedOpenGL/expando/expando.py
new file mode 100644
index 00000000..86c45950
--- /dev/null
+++ b/src/VBox/HostServices/SharedOpenGL/expando/expando.py
@@ -0,0 +1,91 @@
+# $Id: expando.py $
+# This script generates calls for display list compilation
+# and state management.
+import sys
+
+sys.path.append( "../../glapi_parser" )
+import apiutil
+
+apiutil.CopyrightC()
+
+print """
+/* DO NOT EDIT - THIS FILE AUTOMATICALLY GENERATED BY expando.py SCRIPT */
+#include <stdio.h>
+#include "cr_error.h"
+#include "cr_spu.h"
+#include "cr_dlm.h"
+#include "expandospu.h"
+"""
+
+allFunctions = []
+generatedFunctions = []
+
+for func_name in apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt"):
+ if apiutil.FindSpecial("expando", func_name):
+ allFunctions.append(func_name)
+ elif apiutil.CanCompile(func_name) or apiutil.SetsClientState(func_name):
+ generatedFunctions.append(func_name)
+ allFunctions.append(func_name)
+
+for func_name in generatedFunctions:
+ params = apiutil.Parameters(func_name)
+ return_type = apiutil.ReturnType(func_name)
+ basicCallString = apiutil.MakeCallString(params)
+ declarationString = apiutil.MakeDeclarationString(params)
+ dlmCallString = basicCallString
+ chromiumProps = apiutil.ChromiumProps(func_name)
+
+ needClientState = 0
+ if apiutil.UsesClientState(func_name):
+ dlmCallString = basicCallString + ", clientState"
+ needClientState = 1
+
+ needDL = 0
+ if apiutil.CanCompile(func_name):
+ needDL = 1
+
+ print 'static %s EXPANDOSPU_APIENTRY expando%s(%s)' % ( return_type, func_name, declarationString)
+ print '{'
+ if needDL:
+ print '\tGLenum dlMode = crDLMGetCurrentMode();'
+ if needClientState:
+ print '\tCRContext *stateContext = crStateGetCurrent();'
+ print '\tCRClientState *clientState = NULL;'
+ print '\tif (stateContext != NULL) {'
+ print '\t\tclientState = &(stateContext->client);'
+ print '\t}'
+
+ if needDL:
+ if "checklist" in chromiumProps:
+ print '\tif (dlMode != GL_FALSE && crDLMCheckList%s(%s)) {' % (func_name, basicCallString)
+ else:
+ print '\tif (dlMode != GL_FALSE) {'
+ print '\t\tcrDLMCompile%s(%s);' % (func_name, dlmCallString)
+ # If we're only compiling, return now.
+ print '\t\tif (dlMode == GL_COMPILE) return %s;' % '0' if return_type != "void" else ""
+ print '\t}'
+
+ # If it gets this far, we're either just executing, or executing
+ # and compiling. Either way, pass the call to the super SPU,
+ # and to the state tracker (if appropriate; note that we only
+ # track client-side state, not all state).
+ if return_type != "void":
+ print '\t%s rc = expando_spu.super.%s(%s);' % (return_type, func_name, basicCallString)
+ else:
+ print '\texpando_spu.super.%s(%s);' % (func_name, basicCallString)
+ if apiutil.SetsClientState(func_name):
+ print '\tcrState%s(%s);' % (func_name, basicCallString)
+
+ if return_type != "void":
+ print "\treturn rc;"
+
+ print '}'
+ print ''
+
+# Generate the table of named functions. including all the static generated
+# functions as well as the special functions.
+print 'SPUNamedFunctionTable _cr_expando_table[] = {'
+for func_name in allFunctions:
+ print '\t{ "%s", (SPUGenericFunction) expando%s },' % (func_name, func_name )
+print '\t{ NULL, NULL }'
+print '};'
diff --git a/src/VBox/HostServices/SharedOpenGL/expando/expando_special b/src/VBox/HostServices/SharedOpenGL/expando/expando_special
new file mode 100644
index 00000000..9a8cd569
--- /dev/null
+++ b/src/VBox/HostServices/SharedOpenGL/expando/expando_special
@@ -0,0 +1,18 @@
+CreateContext
+DestroyContext
+MakeCurrent
+NewList
+EndList
+DeleteLists
+GenLists
+ListBase
+IsList
+CallList
+CallLists
+
+# Calls to be ignored.
+#VBoxConCreate
+#VBoxCreateContext
+#VBoxPackSetInjectThread
+#VBoxPresentComposition
+#VBoxWindowCreate
diff --git a/src/VBox/HostServices/SharedOpenGL/expando/expandospu.c b/src/VBox/HostServices/SharedOpenGL/expando/expandospu.c
new file mode 100644
index 00000000..8db885a5
--- /dev/null
+++ b/src/VBox/HostServices/SharedOpenGL/expando/expandospu.c
@@ -0,0 +1,182 @@
+/* $Id: expandospu.c $ */
+/** @file
+ * Implementation of routines which Expando SPU explicitly overrides.
+ */
+
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+
+/*
+ * Copyright (C) 2015-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <stdio.h>
+#include "cr_spu.h"
+#include "cr_dlm.h"
+#include "cr_mem.h"
+#include "expandospu.h"
+
+extern GLint EXPANDOSPU_APIENTRY
+expandoCreateContext(const char *displayName, GLint visBits, GLint shareCtx)
+{
+ ExpandoContextState *contextState;
+
+ /* Allocate our own per-context record */
+ contextState = crCalloc(sizeof(ExpandoContextState));
+ if (contextState)
+ {
+ GLint contextId;
+
+ /* Get an official context ID from our super */
+ contextId = expando_spu.super.CreateContext(displayName, visBits, shareCtx);
+
+ /* Supplement that with our DLM. In a more correct situation, we should
+ * see if we've been called through glXCreateContext, which has a parameter
+ * for sharing DLMs. We don't currently get that information, so for now
+ * give each context its own DLM.
+ */
+ contextState->dlm = crDLMNewDLM(0, NULL);
+ if (contextState->dlm)
+ {
+ contextState->dlmContext = crDLMNewContext(contextState->dlm);
+ if (contextState->dlmContext)
+ {
+ /* The DLM needs us to use the state tracker to track client
+ * state, so we can compile client-state-using functions correctly.
+ */
+ contextState->State = crStateCreateContext(NULL, visBits, NULL);
+
+ /* Associate the Expando context with the user context. */
+ crHashtableAdd(expando_spu.contextTable, contextId, (void *)contextState);
+
+ crDebug("Expando SPU: created context %d (contextState=%p, contextState->dlm=%p, "
+ "contextState->dlmContext=%p, contextState->State=%p).",
+ contextId, contextState, contextState->dlm, contextState->dlmContext, contextState->State);
+
+ return contextId;
+ }
+ else
+ crError("Expando SPU: can't allocate new DLM context.");
+
+ crDLMFreeDLM(contextState->dlm, &expando_spu.super);
+ }
+ else
+ crError("Expando SPU: can't allocate new DLM.");
+
+ crFree(contextState);
+ }
+ else
+ crError("Expando SPU: couldn't allocate per-context state");
+
+ return 0;
+}
+
+void expando_free_context_state(void *data)
+{
+ ExpandoContextState *contextState = (ExpandoContextState *)data;
+
+ crDebug("Expando SPU: destroying context internals: "
+ "contextState=%p, contextState->dlm=%p, contextState->dlmContext=%p, contextState->State=%p",
+ contextState, contextState->dlm, contextState->dlmContext, contextState->State);
+
+ crDLMFreeContext(contextState->dlmContext, &expando_spu.super);
+ crDLMFreeDLM(contextState->dlm, &expando_spu.super);
+ crStateDestroyContext(contextState->State);
+ crFree(contextState);
+}
+
+void EXPANDOSPU_APIENTRY
+expandoDestroyContext(GLint contextId)
+{
+ crDebug("Expando SPU: destroy context %d.", contextId);
+
+ /* Destroy our context information */
+ crHashtableDelete(expando_spu.contextTable, contextId, expando_free_context_state);
+
+ /* Pass along the destruction to our super. */
+ expando_spu.super.DestroyContext(contextId);
+}
+
+void EXPANDOSPU_APIENTRY
+expandoMakeCurrent(GLint crWindow, GLint nativeWindow, GLint contextId)
+{
+ ExpandoContextState *expandoContextState;
+
+ expando_spu.super.MakeCurrent(crWindow, nativeWindow, contextId);
+
+ expandoContextState = crHashtableSearch(expando_spu.contextTable, contextId);
+ if (expandoContextState)
+ {
+ crDebug("Expando SPU: switch to context %d.", contextId);
+
+ crDLMSetCurrentState(expandoContextState->dlmContext);
+ crStateMakeCurrent(expandoContextState->State);
+ }
+ else
+ {
+ crDebug("Expando SPU: can't switch to context %d: not found.", contextId);
+
+ crDLMSetCurrentState(NULL);
+ crStateMakeCurrent(NULL);
+ }
+}
+
+extern void EXPANDOSPU_APIENTRY
+expandoNewList(GLuint list, GLenum mode)
+{
+ crDLMNewList(list, mode, &expando_spu.super);
+}
+
+extern void EXPANDOSPU_APIENTRY
+expandoEndList(void)
+{
+ crDLMEndList(&expando_spu.super);
+}
+
+extern void EXPANDOSPU_APIENTRY
+expandoDeleteLists(GLuint first, GLsizei range)
+{
+ crDLMDeleteLists(first, range, &expando_spu.super);
+}
+
+extern GLuint EXPANDOSPU_APIENTRY
+expandoGenLists(GLsizei range)
+{
+ return crDLMGenLists(range, &expando_spu.super);
+}
+
+void EXPANDOSPU_APIENTRY
+expandoListBase(GLuint base)
+{
+ crDLMListBase(base, &expando_spu.super);
+}
+
+extern GLboolean EXPANDOSPU_APIENTRY
+expandoIsList(GLuint list)
+{
+ return crDLMIsList(list, &expando_spu.super);
+}
+
+extern void EXPANDOSPU_APIENTRY
+expandoCallList(GLuint list)
+{
+ crDLMCallList(list, &expando_spu.super);
+}
+
+extern void EXPANDOSPU_APIENTRY
+expandoCallLists(GLsizei n, GLenum type, const GLvoid *lists)
+{
+ crDLMCallLists(n, type, lists, &expando_spu.super);
+}
diff --git a/src/VBox/HostServices/SharedOpenGL/expando/expandospu.def b/src/VBox/HostServices/SharedOpenGL/expando/expandospu.def
new file mode 100644
index 00000000..9edc7163
--- /dev/null
+++ b/src/VBox/HostServices/SharedOpenGL/expando/expandospu.def
@@ -0,0 +1,6 @@
+; Copyright (c) 2001, Stanford University
+; All rights reserved.
+;
+; See the file LICENSE.txt for information on redistributing this software.
+EXPORTS
+SPULoad
diff --git a/src/VBox/HostServices/SharedOpenGL/expando/expandospu.h b/src/VBox/HostServices/SharedOpenGL/expando/expandospu.h
new file mode 100644
index 00000000..dad5e120
--- /dev/null
+++ b/src/VBox/HostServices/SharedOpenGL/expando/expandospu.h
@@ -0,0 +1,69 @@
+/* $Id: expandospu.h $ */
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved.
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#ifndef EXPANDO_SPU_H
+#define EXPANDO_SPU_H
+
+#ifdef WINDOWS
+#define EXPANDOSPU_APIENTRY __stdcall
+#else
+#define EXPANDOSPU_APIENTRY
+#endif
+
+#include "cr_glstate.h"
+#include "cr_spu.h"
+#include "cr_server.h"
+#include "cr_dlm.h"
+
+typedef struct {
+ int id;
+ int has_child;
+ SPUDispatchTable self, child, super;
+ CRServer *server;
+
+ /* Expando-specific variables */
+ CRHashTable *contextTable;
+} ExpandoSPU;
+
+typedef struct {
+ /* Local copy of state, needed by DLM to compile client-side stuff.
+ * We only collect client-side state; we ignore all server-side
+ * state (we just don't need it).
+ */
+ CRContext *State;
+
+ /* The DLM, and the per-context state for a DLM. Right now, every
+ * context will have its own DLM; it's possible in OpenGL to share
+ * DLMs, but the Chromium interface doesn't allow it yet.
+ */
+ CRDLM *dlm;
+ CRDLMContextState *dlmContext;
+} ExpandoContextState;
+
+extern ExpandoSPU expando_spu;
+
+extern SPUNamedFunctionTable _cr_expando_table[];
+
+extern SPUOptions expandoSPUOptions[];
+
+extern void expandospuGatherConfiguration( void );
+
+extern void expando_free_context_state(void *data);
+
+extern GLint EXPANDOSPU_APIENTRY expandoCreateContext(const char *displayName, GLint visBits, GLint shareCtx);
+extern void EXPANDOSPU_APIENTRY expandoDestroyContext(GLint contextId);
+extern void EXPANDOSPU_APIENTRY expandoMakeCurrent(GLint crWindow, GLint nativeWindow, GLint contextId);
+extern void EXPANDOSPU_APIENTRY expandoNewList(GLuint list, GLenum mode);
+extern void EXPANDOSPU_APIENTRY expandoEndList(void);
+extern void EXPANDOSPU_APIENTRY expandoDeleteLists(GLuint first, GLsizei range);
+extern GLuint EXPANDOSPU_APIENTRY expandoGenLists(GLsizei range);
+extern void EXPANDOSPU_APIENTRY expandoListBase(GLuint base);
+extern GLboolean EXPANDOSPU_APIENTRY expandoIsList(GLuint list);
+extern void EXPANDOSPU_APIENTRY expandoCallList(GLuint list);
+extern void EXPANDOSPU_APIENTRY expandoCallLists(GLsizei n, GLenum type, const GLvoid *lists);
+
+#endif /* EXPANDO_SPU_H */
diff --git a/src/VBox/HostServices/SharedOpenGL/expando/expandospu_config.c b/src/VBox/HostServices/SharedOpenGL/expando/expandospu_config.c
new file mode 100644
index 00000000..9843f486
--- /dev/null
+++ b/src/VBox/HostServices/SharedOpenGL/expando/expandospu_config.c
@@ -0,0 +1,48 @@
+/* $Id: expandospu_config.c $ */
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "expandospu.h"
+
+//#include "cr_mothership.h"
+#include "cr_string.h"
+
+#include <stdio.h>
+
+static void __setDefaults( void )
+{
+}
+
+/* option, type, nr, default, min, max, title, callback
+ */
+SPUOptions expandoSPUOptions[] = {
+ { NULL, CR_BOOL, 0, NULL, NULL, NULL, NULL, NULL },
+};
+
+
+void expandospuGatherConfiguration( void )
+{
+ CRConnection *conn;
+
+ __setDefaults();
+#if 0
+ /* Connect to the mothership and identify ourselves. */
+
+ conn = crMothershipConnect( );
+ if (!conn)
+ {
+ /* The mothership isn't running. Some SPU's can recover gracefully, some
+ * should issue an error here. */
+ crSPUSetDefaultParams( &expando_spu, expandoSPUOptions );
+ return;
+ }
+ crMothershipIdentifySPU( conn, expando_spu.id );
+
+ crSPUGetMothershipParams( conn, &expando_spu, expandoSPUOptions );
+
+ crMothershipDisconnect( conn );
+#endif
+}
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;
+}