summaryrefslogtreecommitdiffstats
path: root/src/VBox/HostServices/SharedOpenGL/dlm
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 03:01:46 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 03:01:46 +0000
commitf8fe689a81f906d1b91bb3220acde2a4ecb14c5b (patch)
tree26484e9d7e2c67806c2d1760196ff01aaa858e8c /src/VBox/HostServices/SharedOpenGL/dlm
parentInitial commit. (diff)
downloadvirtualbox-f8fe689a81f906d1b91bb3220acde2a4ecb14c5b.tar.xz
virtualbox-f8fe689a81f906d1b91bb3220acde2a4ecb14c5b.zip
Adding upstream version 6.0.4-dfsg.upstream/6.0.4-dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/HostServices/SharedOpenGL/dlm')
-rw-r--r--src/VBox/HostServices/SharedOpenGL/dlm/Makefile.kup0
-rw-r--r--src/VBox/HostServices/SharedOpenGL/dlm/dlm.c575
-rw-r--r--src/VBox/HostServices/SharedOpenGL/dlm/dlm.h31
-rw-r--r--src/VBox/HostServices/SharedOpenGL/dlm/dlm_arrays.c387
-rw-r--r--src/VBox/HostServices/SharedOpenGL/dlm/dlm_checklist.c51
-rw-r--r--src/VBox/HostServices/SharedOpenGL/dlm/dlm_error.c56
-rwxr-xr-xsrc/VBox/HostServices/SharedOpenGL/dlm/dlm_generated.py355
-rw-r--r--src/VBox/HostServices/SharedOpenGL/dlm/dlm_header.py274
-rw-r--r--src/VBox/HostServices/SharedOpenGL/dlm/dlm_lists.c452
-rw-r--r--src/VBox/HostServices/SharedOpenGL/dlm/dlm_pointers.c1125
-rw-r--r--src/VBox/HostServices/SharedOpenGL/dlm/dlm_pointers.h81
-rw-r--r--src/VBox/HostServices/SharedOpenGL/dlm/dlm_special21
-rw-r--r--src/VBox/HostServices/SharedOpenGL/dlm/dlm_state.c280
13 files changed, 3688 insertions, 0 deletions
diff --git a/src/VBox/HostServices/SharedOpenGL/dlm/Makefile.kup b/src/VBox/HostServices/SharedOpenGL/dlm/Makefile.kup
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/VBox/HostServices/SharedOpenGL/dlm/Makefile.kup
diff --git a/src/VBox/HostServices/SharedOpenGL/dlm/dlm.c b/src/VBox/HostServices/SharedOpenGL/dlm/dlm.c
new file mode 100644
index 00000000..8ea6c69c
--- /dev/null
+++ b/src/VBox/HostServices/SharedOpenGL/dlm/dlm.c
@@ -0,0 +1,575 @@
+/* $Id: dlm.c $ */
+
+#include <float.h>
+#include "cr_dlm.h"
+#include "cr_mem.h"
+#include "dlm.h"
+
+/**
+ * \mainpage Dlm
+ *
+ * \section DlmIntroduction Introduction
+ *
+ * Chromium consists of all the top-level files in the cr
+ * directory. The dlm module basically takes care of API dispatch,
+ * and OpenGL state management.
+ *
+ */
+
+/**
+ * Module globals: the current DLM state, bound either to each thread, or
+ * to a global.
+ */
+#ifdef CHROMIUM_THREADSAFE
+CRtsd CRDLMTSDKey;
+#else
+CRDLMContextState *CRDLMCurrentState = NULL;
+#endif
+
+#define MIN(a,b) ((a)<(b)?(a):(b))
+
+
+/*************************************************************************/
+
+#ifdef CHROMIUM_THREADSAFE
+/**
+ * This is the thread-specific destructor function for the
+ * data used in the DLM. It's very simple: if a thread exits
+ * that has DLM-specific data, the data represents the listState
+ * for the thread. All data and buffers associated with the list
+ * can be deleted, and the structure itself can be freed.
+ *
+ * Most Chromium threads don't have such things; but then,
+ * if a thread dies elsewhere in Chromium, huge buffers
+ * of information won't still be floating around in
+ * unrecoverable allocated areas, either.
+ */
+static void threadDestructor(void *tsd)
+{
+ CRDLMContextState *listState = (CRDLMContextState *)tsd;
+
+ if (listState)
+ {
+ //if (listState->currentListInfo)
+ // crdlm_free_list(listState->currentListInfo);
+
+ crFree(listState);
+ }
+}
+#endif
+
+/**
+ * This function creates and initializes a new display list
+ * manager. It returns a pointer to the manager, or NULL in
+ * the case of insufficient memory. The dispatch table pointer
+ * is passed in to allow the utilities to muck with the table
+ * to gain functional control when GL calls are made.
+ */
+CRDLM DLM_APIENTRY *crDLMNewDLM(unsigned int userConfigSize, const CRDLMConfig *userConfig)
+{
+ CRDLM *dlm;
+
+ /* This is the default configuration. We'll overwrite it later
+ * with user-supplied configuration information.
+ */
+ CRDLMConfig config = {
+ CRDLM_DEFAULT_BUFFERSIZE,
+ };
+
+ dlm = crAlloc(sizeof(*dlm));
+ if (!dlm) {
+ return NULL;
+ }
+
+ /* Start off by initializing all entries that require further
+ * memory allocation, so we can free up all the memory if there's
+ * a problem.
+ */
+ if (!(dlm->displayLists = crAllocHashtable())) {
+ crFree(dlm);
+ return NULL;
+ }
+
+ /* The creator counts as the first user. */
+ dlm->userCount = 1;
+
+#ifdef CHROMIUM_THREADSAFE
+ /* This mutex ensures that only one thread is changing the displayLists
+ * hash at a time. Note that we may also need a mutex to guarantee that
+ * the hash is not changed by one thread while another thread is
+ * traversing it; this issue has not yet been resolved.
+ */
+ crInitMutex(&(dlm->dlMutex));
+
+ /* Although the thread-specific data (TSD) functions will initialize
+ * the thread key themselves when needed, those functions do not allow
+ * us to specify a thread destructor. Since a thread could potentially
+ * exit with considerable memory allocated (e.g. if a thread exits
+ * after it has issued NewList but before EndList, and while there
+ * are considerable content buffers allocated), I do the initialization
+ * myself, in order to be able to reclaim those resources if a thread
+ * exits.
+ */
+ crInitTSDF(&(dlm->tsdKey), threadDestructor);
+ crInitTSD(&CRDLMTSDKey);
+#endif
+
+ /* Copy over any appropriate configuration values */
+ if (userConfig != NULL) {
+ /* Copy over as much configuration information as is provided.
+ * Note that if the CRDLMConfig structure strictly grows, this
+ * allows forward compatability - routines compiled with
+ * older versions of the structure will only initialize that
+ * section of the structure that they know about.
+ */
+ crMemcpy((void *)&config, (void *) userConfig,
+ MIN(userConfigSize, sizeof(config)));
+ }
+ dlm->bufferSize = config.bufferSize;
+
+ /* Return the pointer to the newly-allocated display list manager */
+ return dlm;
+}
+
+void DLM_APIENTRY crDLMUseDLM(CRDLM *dlm)
+{
+ DLM_LOCK(dlm);
+ dlm->userCount++;
+ DLM_UNLOCK(dlm);
+}
+
+/**
+ * This routine is called when a context or thread is done with a DLM.
+ * It maintains an internal count of users, and will only actually destroy
+ * itself when no one is still using the DLM.
+ */
+void DLM_APIENTRY crDLMFreeDLM(CRDLM *dlm, SPUDispatchTable *dispatchTable)
+{
+ /* We're about to change the displayLists hash; lock it first */
+ DLM_LOCK(dlm)
+
+ /* Decrement the user count. If the user count has gone to
+ * 0, then free the rest of the DLM. Otherwise, other
+ * contexts or threads are still using this DLM; keep
+ * it around.
+ */
+ dlm->userCount--;
+ if (dlm->userCount == 0) {
+
+ crFreeHashtableEx(dlm->displayLists, crdlmFreeDisplayListResourcesCb, dispatchTable);
+ dlm->displayLists = NULL;
+
+ /* Must unlock before freeing the mutex */
+ DLM_UNLOCK(dlm)
+
+#ifdef CHROMIUM_THREADSAFE
+ /* We release the mutex here; we really should delete the
+ * thread data key, but there's no utility in Chromium to
+ * do this.
+ *
+ * Note that, should one thread release the entire DLM
+ * while other threads still believe they are using it,
+ * any other threads that have current display lists (i.e.
+ * have issued glNewList more recently than glEndList)
+ * will be unable to reclaim their (likely very large)
+ * content buffers, as there will be no way to reclaim
+ * the thread-specific data.
+ *
+ * On the other hand, if one thread really does release
+ * the DLM while other threads still believe they are
+ * using it, unreclaimed memory is the least of the
+ * application's problems...
+ */
+ crFreeMutex(&(dlm->dlMutex));
+
+ /* We free the TSD key here as well. Note that this will
+ * strand any threads that still have thread-specific data
+ * tied to this key; but as stated above, if any threads
+ * still do have thread-specific data attached to this DLM,
+ * they're in big trouble anyway.
+ */
+ crFreeTSD(&(dlm->tsdKey));
+ crFreeTSD(&CRDLMTSDKey);
+#endif
+
+ /* Free the master record, and we're all done. */
+ crFree(dlm);
+ }
+ else {
+ /* We're keeping the DLM around for other users. Unlock it,
+ * but retain its memory and display lists.
+ */
+ DLM_UNLOCK(dlm)
+ }
+}
+
+/**
+ * The actual run-time state of a DLM is bound to a context
+ * (because each context can be used by at most one thread at
+ * a time, and a thread can only use one context at a time,
+ * while multiple contexts can use the same DLM).
+ * This creates the structure required to hold the state, and
+ * returns it to the caller, who should store it with any other
+ * context-specific information.
+ */
+
+CRDLMContextState DLM_APIENTRY *crDLMNewContext(CRDLM *dlm)
+{
+ CRDLMContextState *state;
+
+ /* Get a record for our own internal state structure */
+ state = (CRDLMContextState *)crAlloc(sizeof(CRDLMContextState));
+ if (!state) {
+ return NULL;
+ }
+
+ state->dlm = dlm;
+ state->currentListIdentifier = 0;
+ state->currentListInfo = NULL;
+ state->currentListMode = GL_FALSE;
+ state->listBase = 0;
+
+ /* Increment the use count of the DLM provided. This guarantees that
+ * the DLM won't be released until all the contexts have released it.
+ */
+ crDLMUseDLM(dlm);
+
+ return state;
+}
+
+
+/**
+ * This routine should be called when a MakeCurrent changes the current
+ * context. It sets the thread data (or global data, in an unthreaded
+ * environment) appropriately; this in turn changes the behavior of
+ * the installed DLM API functions.
+ */
+void DLM_APIENTRY crDLMSetCurrentState(CRDLMContextState *state)
+{
+ CRDLMContextState *currentState = CURRENT_STATE();
+ if (currentState != state) {
+ SET_CURRENT_STATE(state);
+ }
+}
+
+CRDLMContextState DLM_APIENTRY *crDLMGetCurrentState(void)
+{
+ return CURRENT_STATE();
+}
+
+/**
+ * This routine, of course, is used to release a DLM context when it
+ * is no longer going to be used.
+ */
+
+void DLM_APIENTRY crDLMFreeContext(CRDLMContextState *state, SPUDispatchTable *dispatchTable)
+{
+ CRDLMContextState *listState = CURRENT_STATE();
+
+ /* If we're currently using this context, release it first */
+ if (listState == state)
+ crDLMSetCurrentState(NULL);
+
+ /* Try to free the DLM. This will either decrement the use count,
+ * or will actually free the DLM, if we were the last user.
+ */
+ crDLMFreeDLM(state->dlm, dispatchTable);
+ state->dlm = NULL;
+
+ /* If any buffers still remain (e.g. because there was an open
+ * display list), remove those as well.
+ */
+ if (state->currentListInfo)
+ {
+ crdlmFreeDisplayListResourcesCb((void *)state->currentListInfo, (void *)dispatchTable);
+ state->currentListInfo = NULL;
+ }
+ state->currentListIdentifier = 0;
+
+ /* Free the state record itself */
+ crFree(state);
+}
+
+
+/**
+ * This function can be used if the caller wishes to free up the
+ * potentially considerable resources used to store the display list
+ * content, without losing the rest of the display list management.
+ * For one example, consider an SPU that conditionally sends its
+ * input stream to multiple servers. It could broadcast all display
+ * lists to all servers, or it could only send display lists to servers
+ * that need them. After all servers have the display list, the SPU
+ * may wish to release the resources used to manage the content.
+ */
+CRDLMError DLM_APIENTRY crDLMDeleteListContent(CRDLM *dlm, unsigned long listIdentifier)
+{
+ DLMListInfo *listInfo;
+ DLMInstanceList *instance;
+
+ listInfo = (DLMListInfo *) crHashtableSearch(dlm->displayLists, listIdentifier);
+ if (listInfo && (instance = listInfo->first)) {
+ while (instance) {
+ DLMInstanceList *nextInstance;
+ nextInstance = instance->next;
+ crFree(instance);
+ instance = nextInstance;
+ }
+ listInfo->first = listInfo->last = NULL;
+ }
+ return GL_NO_ERROR;
+}
+
+/**
+ *
+ * Playback/execute a list.
+ * dlm - the display list manager context
+ * listIdentifier - the display list ID (as specified by app) to playback
+ * dispatchTable - the GL dispatch table to jump through as we execute commands
+ */
+void DLM_APIENTRY crDLMReplayDLMList(CRDLM *dlm, unsigned long listIdentifier, SPUDispatchTable *dispatchTable)
+{
+ DLMListInfo *listInfo;
+
+ listInfo = (DLMListInfo *)crHashtableSearch(dlm->displayLists, listIdentifier);
+ if (listInfo) {
+ DLMInstanceList *instance = listInfo->first;
+ while (instance) {
+ /* mutex, to make sure another thread doesn't change the list? */
+ /* For now, leave it alone. */
+ (*instance->execute)(instance, dispatchTable);
+ instance = instance->next;
+ }
+ }
+}
+
+/* Playback/execute a list in the current DLM */
+void DLM_APIENTRY crDLMReplayList(unsigned long listIdentifier, SPUDispatchTable *dispatchTable)
+{
+ CRDLMContextState *listState = CURRENT_STATE();
+ if (listState)
+ crDLMReplayDLMList(listState->dlm, listIdentifier, dispatchTable);
+}
+
+/*
+ * Playback/execute the state changing portions of a list.
+ * dlm - the display list manager context
+ * listIdentifier - the display list ID (as specified by app) to playback
+ * dispatchTable - the GL dispatch table to jump through as we execute commands
+ */
+void DLM_APIENTRY crDLMReplayDLMListState(CRDLM *dlm, unsigned long listIdentifier, SPUDispatchTable *dispatchTable)
+{
+ DLMListInfo *listInfo;
+
+ listInfo = (DLMListInfo *)crHashtableSearch(dlm->displayLists, listIdentifier);
+ if (listInfo) {
+ DLMInstanceList *instance = listInfo->stateFirst;
+ while (instance) {
+ /* mutex, to make sure another thread doesn't change the list? */
+ /* For now, leave it alone. */
+ (*instance->execute)(instance, dispatchTable);
+ instance = instance->stateNext;
+ }
+ }
+}
+
+void DLM_APIENTRY crDLMReplayListState(unsigned long listIdentifier, SPUDispatchTable *dispatchTable)
+{
+ CRDLMContextState *listState = CURRENT_STATE();
+ if (listState)
+ crDLMReplayDLMListState(listState->dlm, listIdentifier, dispatchTable);
+}
+
+/* This is a switch statement that lists every "type" value valid for a
+ * glCallLists() function call, with code for decoding the subsequent
+ * values correctly. It uses the current value of the EXPAND() macro,
+ * which must expand into an appropriate action to be taken.
+ * Its codification here allows for multiple uses.
+ */
+#define CALL_LISTS_SWITCH(type, defaultAction) \
+ switch (type) {\
+ EXPAND(GL_BYTE, GLbyte *, *p, p++)\
+ EXPAND(GL_UNSIGNED_BYTE, GLubyte *, *p, p++)\
+ EXPAND(GL_SHORT, GLshort *, *p, p++)\
+ EXPAND(GL_UNSIGNED_SHORT, GLushort *, *p, p++)\
+ EXPAND(GL_INT, GLint *, *p, p++)\
+ EXPAND(GL_FLOAT, GLfloat *, *p, p++)\
+ EXPAND(GL_2_BYTES, unsigned char *, 256*p[0] + p[1], p += 2)\
+ EXPAND(GL_3_BYTES, unsigned char *, 65536*p[0] + 256*p[1] + p[2], p += 3)\
+ EXPAND(GL_4_BYTES, unsigned char *, 16777216*p[0] + 65536*p[1] + 256*p[2] + p[3], p += 4)\
+ default:\
+ defaultAction;\
+ }
+
+void DLM_APIENTRY crDLMReplayDLMLists(CRDLM *dlm, GLsizei n, GLenum type, const GLvoid * lists, SPUDispatchTable *dispatchTable)
+{
+ unsigned long listId;
+ CRDLMContextState *listState = CURRENT_STATE();
+
+#define EXPAND(TYPENAME, TYPE, REFERENCE, INCREMENT) \
+ case TYPENAME: {\
+ TYPE p = (TYPE)lists;\
+ while (n--) {\
+ listId = listState->listBase + (unsigned long) (REFERENCE);\
+ crDLMReplayDLMList(dlm, listId, dispatchTable);\
+ INCREMENT;\
+ }\
+ break;\
+ }
+
+ CALL_LISTS_SWITCH(type, break)
+#undef EXPAND
+
+}
+
+void DLM_APIENTRY crDLMReplayLists(GLsizei n, GLenum type, const GLvoid * lists, SPUDispatchTable *dispatchTable)
+{
+ CRDLMContextState *listState = CURRENT_STATE();
+ if (listState) {
+ crDLMReplayDLMLists(listState->dlm, n, type, lists, dispatchTable);
+ }
+}
+
+void DLM_APIENTRY crDLMReplayDLMListsState(CRDLM *dlm, GLsizei n, GLenum type, const GLvoid * lists, SPUDispatchTable *dispatchTable)
+{
+ unsigned long listId;
+ CRDLMContextState *listState = CURRENT_STATE();
+
+#define EXPAND(TYPENAME, TYPE, REFERENCE, INCREMENT) \
+ case TYPENAME: {\
+ TYPE p = (TYPE)lists;\
+ while (n--) {\
+ listId = listState->listBase + (unsigned long) (REFERENCE);\
+ crDLMReplayDLMListState(dlm, listId, dispatchTable);\
+ INCREMENT;\
+ }\
+ break;\
+ }
+
+ CALL_LISTS_SWITCH(type, break)
+#undef EXPAND
+
+}
+
+void DLM_APIENTRY crDLMReplayListsState(GLsizei n, GLenum type, const GLvoid * lists, SPUDispatchTable *dispatchTable)
+{
+ CRDLMContextState *listState = CURRENT_STATE();
+ if (listState) {
+ crDLMReplayDLMListsState(listState->dlm, n, type, lists, dispatchTable);
+ }
+}
+
+/* When we compiled the display list, we packed all pixel data
+ * tightly. When we execute the display list, we have to make
+ * sure that the client state reflects that the pixel data is
+ * tightly packed, or it will be interpreted incorrectly.
+ */
+void DLM_APIENTRY crDLMSetupClientState(SPUDispatchTable *dispatchTable)
+{
+ dispatchTable->PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ dispatchTable->PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ dispatchTable->PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ dispatchTable->PixelStorei(GL_UNPACK_ALIGNMENT, 1);
+}
+
+void DLM_APIENTRY crDLMRestoreClientState(CRClientState *clientState, SPUDispatchTable *dispatchTable)
+{
+ if (clientState) {
+ dispatchTable->PixelStorei(GL_UNPACK_ROW_LENGTH, clientState->unpack.rowLength);
+ dispatchTable->PixelStorei(GL_UNPACK_SKIP_PIXELS, clientState->unpack.skipPixels);
+ dispatchTable->PixelStorei(GL_UNPACK_SKIP_ROWS, clientState->unpack.skipRows);
+ dispatchTable->PixelStorei(GL_UNPACK_ALIGNMENT, clientState->unpack.alignment);
+ }
+}
+
+void DLM_APIENTRY crDLMSendDLMList(CRDLM *dlm, unsigned long listIdentifier,
+ SPUDispatchTable *dispatchTable)
+{
+ dispatchTable->NewList(listIdentifier, GL_COMPILE);
+ crDLMReplayDLMList(dlm, listIdentifier, dispatchTable);
+ dispatchTable->EndList();
+}
+
+void DLM_APIENTRY crDLMSendList(unsigned long listIdentifier, SPUDispatchTable *dispatchTable)
+{
+ CRDLMContextState *listState = CURRENT_STATE();
+ if (listState) {
+ crDLMSendDLMList(listState->dlm, listIdentifier, dispatchTable);
+ }
+}
+
+struct sendListsCallbackParms {
+ CRDLM *dlm;
+ SPUDispatchTable *dispatchTable;
+};
+
+static void sendListsCallback(unsigned long key, void *data, void *dataPtr2)
+{
+ struct sendListsCallbackParms *parms = (struct sendListsCallbackParms *)dataPtr2;
+
+ crDLMSendDLMList(parms->dlm, key, parms->dispatchTable);
+}
+
+void DLM_APIENTRY crDLMSendAllDLMLists(CRDLM *dlm, SPUDispatchTable *dispatchTable)
+{
+ struct sendListsCallbackParms parms;
+
+ /* This is how we pass our parameter information to the callback routine -
+ * through a pointer to this local structure.
+ */
+ parms.dlm = dlm;
+ parms.dispatchTable = dispatchTable;
+
+ crHashtableWalk(dlm->displayLists, sendListsCallback, (void *)&parms);
+}
+
+void DLM_APIENTRY crDLMSendAllLists(SPUDispatchTable *dispatchTable)
+{
+ CRDLMContextState *listState = CURRENT_STATE();
+ if (listState) {
+ crDLMSendAllDLMLists(listState->dlm, dispatchTable);
+ }
+}
+
+/** Another clever callback arrangement to get the desired data. */
+struct getRefsCallbackParms {
+ int remainingOffset;
+ int remainingCount;
+ unsigned int *buffer;
+ int totalCount;
+};
+
+/*
+ * Return id of list currently being compiled. Returns 0 of there's no
+ * current DLM state, or if no list is being compiled.
+ */
+GLuint DLM_APIENTRY crDLMGetCurrentList(void)
+{
+ CRDLMContextState *listState = CURRENT_STATE();
+ return listState ? listState->currentListIdentifier : 0;
+}
+
+/*
+ * Return mode of list currently being compiled. Should be
+ * GL_FALSE if no list is being compiled, or GL_COMPILE if a
+ * list is being compiled but not executed, or GL_COMPILE_AND_EXECUTE
+ * if a list is being compiled and executed.
+ */
+GLenum DLM_APIENTRY crDLMGetCurrentMode(void)
+{
+ CRDLMContextState *listState = CURRENT_STATE();
+ return listState ? listState->currentListMode : 0;
+}
+
+
+static CRDLMErrorCallback ErrorCallback = NULL;
+
+void DLM_APIENTRY crDLMErrorFunction(CRDLMErrorCallback callback)
+{
+ ErrorCallback = callback;
+}
+
+void crdlm_error(int line, const char *file, GLenum error, const char *info)
+{
+ if (ErrorCallback)
+ (*ErrorCallback)(line, file, error, info);
+}
diff --git a/src/VBox/HostServices/SharedOpenGL/dlm/dlm.h b/src/VBox/HostServices/SharedOpenGL/dlm/dlm.h
new file mode 100644
index 00000000..2e6db46e
--- /dev/null
+++ b/src/VBox/HostServices/SharedOpenGL/dlm/dlm.h
@@ -0,0 +1,31 @@
+/* $Id: dlm.h $ */
+
+#ifndef _DLM_H
+#define _DLM_H
+
+#include "cr_dlm.h"
+#include "cr_spu.h"
+
+#ifdef CHROMIUM_THREADSAFE
+#define DLM_LOCK(dlm) crLockMutex(&(dlm->dlMutex));
+#define DLM_UNLOCK(dlm) crUnlockMutex(&(dlm->dlMutex));
+extern CRtsd CRDLMTSDKey;
+#define SET_CURRENT_STATE(state) crSetTSD(&CRDLMTSDKey, (void *)state);
+#define CURRENT_STATE() ((CRDLMContextState *)crGetTSD(&CRDLMTSDKey))
+#else
+#define DLM_LOCK(dlm)
+#define DLM_UNLOCK(dlm)
+extern CRDLMContextState *CRDLMCurrentState;
+#define SET_CURRENT_STATE(state) CRDLMCurrentState = (state);
+#define CURRENT_STATE() (CRDLMCurrentState)
+#endif
+
+/* These routines are intended to be used within the DLM library, across
+ * the modules therein, but not as an API into the DLM library from
+ * outside.
+ */
+extern void crdlmWarning( int line, char *file, GLenum error, char *format, ... );
+extern void crdlmFreeDisplayListResourcesCb(void *pParm1, void *pParam2);
+extern void crdlm_error(int line, const char *file, GLenum error, const char *info);
+
+#endif
diff --git a/src/VBox/HostServices/SharedOpenGL/dlm/dlm_arrays.c b/src/VBox/HostServices/SharedOpenGL/dlm/dlm_arrays.c
new file mode 100644
index 00000000..d14d7198
--- /dev/null
+++ b/src/VBox/HostServices/SharedOpenGL/dlm/dlm_arrays.c
@@ -0,0 +1,387 @@
+/* $Id: dlm_arrays.c $ */
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include "chromium.h"
+#include "cr_dlm.h"
+#include "dlm.h"
+
+/*
+ * XXX this code is awfully similar to the code in arrayspu.c
+ * We should try to write something reusable.
+ */
+
+void DLM_APIENTRY crDLMCompileArrayElement (GLint index, CRClientState *c)
+{
+ unsigned char *p;
+ int unit;
+
+ if (c->array.e.enabled)
+ {
+ crDLMCompileEdgeFlagv(c->array.e.p + index*c->array.e.stride);
+ }
+ for (unit = 0; unit < CR_MAX_TEXTURE_UNITS; unit++)
+ {
+ if (c->array.t[unit].enabled)
+ {
+ p = c->array.t[unit].p + index*c->array.t[unit].stride;
+ switch (c->array.t[unit].type)
+ {
+ case GL_SHORT:
+ switch (c->array.t[c->curClientTextureUnit].size)
+ {
+ case 1: crDLMCompileMultiTexCoord1svARB(GL_TEXTURE0_ARB + unit, (GLshort *)p); break;
+ case 2: crDLMCompileMultiTexCoord2svARB(GL_TEXTURE0_ARB + unit, (GLshort *)p); break;
+ case 3: crDLMCompileMultiTexCoord3svARB(GL_TEXTURE0_ARB + unit, (GLshort *)p); break;
+ case 4: crDLMCompileMultiTexCoord4svARB(GL_TEXTURE0_ARB + unit, (GLshort *)p); break;
+ }
+ break;
+ case GL_INT:
+ switch (c->array.t[c->curClientTextureUnit].size)
+ {
+ case 1: crDLMCompileMultiTexCoord1ivARB(GL_TEXTURE0_ARB + unit, (GLint *)p); break;
+ case 2: crDLMCompileMultiTexCoord2ivARB(GL_TEXTURE0_ARB + unit, (GLint *)p); break;
+ case 3: crDLMCompileMultiTexCoord3ivARB(GL_TEXTURE0_ARB + unit, (GLint *)p); break;
+ case 4: crDLMCompileMultiTexCoord4ivARB(GL_TEXTURE0_ARB + unit, (GLint *)p); break;
+ }
+ break;
+ case GL_FLOAT:
+ switch (c->array.t[c->curClientTextureUnit].size)
+ {
+ case 1: crDLMCompileMultiTexCoord1fvARB(GL_TEXTURE0_ARB + unit, (GLfloat *)p); break;
+ case 2: crDLMCompileMultiTexCoord2fvARB(GL_TEXTURE0_ARB + unit, (GLfloat *)p); break;
+ case 3: crDLMCompileMultiTexCoord3fvARB(GL_TEXTURE0_ARB + unit, (GLfloat *)p); break;
+ case 4: crDLMCompileMultiTexCoord4fvARB(GL_TEXTURE0_ARB + unit, (GLfloat *)p); break;
+ }
+ break;
+ case GL_DOUBLE:
+ switch (c->array.t[c->curClientTextureUnit].size)
+ {
+ case 1: crDLMCompileMultiTexCoord1dvARB(GL_TEXTURE0_ARB + unit, (GLdouble *)p); break;
+ case 2: crDLMCompileMultiTexCoord2dvARB(GL_TEXTURE0_ARB + unit, (GLdouble *)p); break;
+ case 3: crDLMCompileMultiTexCoord3dvARB(GL_TEXTURE0_ARB + unit, (GLdouble *)p); break;
+ case 4: crDLMCompileMultiTexCoord4dvARB(GL_TEXTURE0_ARB + unit, (GLdouble *)p); break;
+ }
+ break;
+ }
+ }
+ } /* loop over texture units */
+
+ if (c->array.i.enabled)
+ {
+ p = c->array.i.p + index*c->array.i.stride;
+ switch (c->array.i.type)
+ {
+ case GL_SHORT: crDLMCompileIndexsv((GLshort *)p); break;
+ case GL_INT: crDLMCompileIndexiv((GLint *)p); break;
+ case GL_FLOAT: crDLMCompileIndexfv((GLfloat *)p); break;
+ case GL_DOUBLE: crDLMCompileIndexdv((GLdouble *)p); break;
+ }
+ }
+ if (c->array.c.enabled)
+ {
+ p = c->array.c.p + index*c->array.c.stride;
+ switch (c->array.c.type)
+ {
+ case GL_BYTE:
+ switch (c->array.c.size)
+ {
+ case 3: crDLMCompileColor3bv((GLbyte *)p); break;
+ case 4: crDLMCompileColor4bv((GLbyte *)p); break;
+ }
+ break;
+ case GL_UNSIGNED_BYTE:
+ switch (c->array.c.size)
+ {
+ case 3: crDLMCompileColor3ubv((GLubyte *)p); break;
+ case 4: crDLMCompileColor4ubv((GLubyte *)p); break;
+ }
+ break;
+ case GL_SHORT:
+ switch (c->array.c.size)
+ {
+ case 3: crDLMCompileColor3sv((GLshort *)p); break;
+ case 4: crDLMCompileColor4sv((GLshort *)p); break;
+ }
+ break;
+ case GL_UNSIGNED_SHORT:
+ switch (c->array.c.size)
+ {
+ case 3: crDLMCompileColor3usv((GLushort *)p); break;
+ case 4: crDLMCompileColor4usv((GLushort *)p); break;
+ }
+ break;
+ case GL_INT:
+ switch (c->array.c.size)
+ {
+ case 3: crDLMCompileColor3iv((GLint *)p); break;
+ case 4: crDLMCompileColor4iv((GLint *)p); break;
+ }
+ break;
+ case GL_UNSIGNED_INT:
+ switch (c->array.c.size)
+ {
+ case 3: crDLMCompileColor3uiv((GLuint *)p); break;
+ case 4: crDLMCompileColor4uiv((GLuint *)p); break;
+ }
+ break;
+ case GL_FLOAT:
+ switch (c->array.c.size)
+ {
+ case 3: crDLMCompileColor3fv((GLfloat *)p); break;
+ case 4: crDLMCompileColor4fv((GLfloat *)p); break;
+ }
+ break;
+ case GL_DOUBLE:
+ switch (c->array.c.size)
+ {
+ case 3: crDLMCompileColor3dv((GLdouble *)p); break;
+ case 4: crDLMCompileColor4dv((GLdouble *)p); break;
+ }
+ break;
+ }
+ }
+ if (c->array.n.enabled)
+ {
+ p = c->array.n.p + index*c->array.n.stride;
+ switch (c->array.n.type)
+ {
+ case GL_BYTE: crDLMCompileNormal3bv((GLbyte *)p); break;
+ case GL_SHORT: crDLMCompileNormal3sv((GLshort *)p); break;
+ case GL_INT: crDLMCompileNormal3iv((GLint *)p); break;
+ case GL_FLOAT: crDLMCompileNormal3fv((GLfloat *)p); break;
+ case GL_DOUBLE: crDLMCompileNormal3dv((GLdouble *)p); break;
+ }
+ }
+#ifdef CR_EXT_secondary_color
+ if (c->array.s.enabled)
+ {
+ p = c->array.s.p + index*c->array.s.stride;
+ switch (c->array.s.type)
+ {
+ case GL_BYTE:
+ crDLMCompileSecondaryColor3bvEXT((GLbyte *)p); break;
+ case GL_UNSIGNED_BYTE:
+ crDLMCompileSecondaryColor3ubvEXT((GLubyte *)p); break;
+ case GL_SHORT:
+ crDLMCompileSecondaryColor3svEXT((GLshort *)p); break;
+ case GL_UNSIGNED_SHORT:
+ crDLMCompileSecondaryColor3usvEXT((GLushort *)p); break;
+ case GL_INT:
+ crDLMCompileSecondaryColor3ivEXT((GLint *)p); break;
+ case GL_UNSIGNED_INT:
+ crDLMCompileSecondaryColor3uivEXT((GLuint *)p); break;
+ case GL_FLOAT:
+ crDLMCompileSecondaryColor3fvEXT((GLfloat *)p); break;
+ case GL_DOUBLE:
+ crDLMCompileSecondaryColor3dvEXT((GLdouble *)p); break;
+ }
+ }
+#endif
+ if (c->array.v.enabled)
+ {
+ p = c->array.v.p + (index*c->array.v.stride);
+
+ switch (c->array.v.type)
+ {
+ case GL_SHORT:
+ switch (c->array.v.size)
+ {
+ case 2: crDLMCompileVertex2sv((GLshort *)p); break;
+ case 3: crDLMCompileVertex3sv((GLshort *)p); break;
+ case 4: crDLMCompileVertex4sv((GLshort *)p); break;
+ }
+ break;
+ case GL_INT:
+ switch (c->array.v.size)
+ {
+ case 2: crDLMCompileVertex2iv((GLint *)p); break;
+ case 3: crDLMCompileVertex3iv((GLint *)p); break;
+ case 4: crDLMCompileVertex4iv((GLint *)p); break;
+ }
+ break;
+ case GL_FLOAT:
+ switch (c->array.v.size)
+ {
+ case 2: crDLMCompileVertex2fv((GLfloat *)p); break;
+ case 3: crDLMCompileVertex3fv((GLfloat *)p); break;
+ case 4: crDLMCompileVertex4fv((GLfloat *)p); break;
+ }
+ break;
+ case GL_DOUBLE:
+ switch (c->array.v.size)
+ {
+ case 2: crDLMCompileVertex2dv((GLdouble *)p); break;
+ case 3: crDLMCompileVertex3dv((GLdouble *)p); break;
+ case 4: crDLMCompileVertex4dv((GLdouble *)p); break;
+ }
+ break;
+ }
+ }
+}
+
+void DLM_APIENTRY crDLMCompileDrawArrays(GLenum mode, GLint first, GLsizei count, CRClientState *c)
+{
+ int i;
+
+ if (count < 0)
+ {
+ crdlmWarning(__LINE__, __FILE__, GL_INVALID_VALUE, "DLM DrawArrays(negative count)");
+ return;
+ }
+
+ if (mode > GL_POLYGON)
+ {
+ crdlmWarning(__LINE__, __FILE__, GL_INVALID_ENUM, "DLM DrawArrays(bad mode)");
+ return;
+ }
+
+ crDLMCompileBegin(mode);
+ for (i=0; i<count; i++)
+ {
+ crDLMCompileArrayElement(first + i, c);
+ }
+ crDLMCompileEnd();
+}
+
+void DLM_APIENTRY crDLMCompileDrawElements(GLenum mode, GLsizei count,
+ GLenum type, const GLvoid *indices, CRClientState *c)
+{
+ int i;
+ GLubyte *p = (GLubyte *)indices;
+
+ if (count < 0)
+ {
+ crdlmWarning(__LINE__, __FILE__, GL_INVALID_VALUE, "DLM DrawElements(negative count)");
+ return;
+ }
+
+ if (mode > GL_POLYGON)
+ {
+ crdlmWarning(__LINE__, __FILE__, GL_INVALID_ENUM, "DLM DrawElements(bad mode)");
+ return;
+ }
+
+ if (type != GL_UNSIGNED_BYTE && type != GL_UNSIGNED_SHORT && type != GL_UNSIGNED_INT)
+ {
+ crdlmWarning(__LINE__, __FILE__, GL_INVALID_ENUM, "DLM DrawElements(bad type)");
+ return;
+ }
+
+ crDLMCompileBegin(mode);
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ for (i=0; i<count; i++)
+ {
+ crDLMCompileArrayElement((GLint) *p++, c);
+ }
+ break;
+ case GL_UNSIGNED_SHORT:
+ for (i=0; i<count; i++)
+ {
+ crDLMCompileArrayElement((GLint) * (GLushort *) p, c);
+ p+=sizeof (GLushort);
+ }
+ break;
+ case GL_UNSIGNED_INT:
+ for (i=0; i<count; i++)
+ {
+ crDLMCompileArrayElement((GLint) * (GLuint *) p, c);
+ p+=sizeof (GLuint);
+ }
+ break;
+ default:
+ crError( "this can't happen: DLM DrawElements" );
+ break;
+ }
+ crDLMCompileEnd();
+}
+
+void DLM_APIENTRY crDLMCompileDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count,
+ GLenum type, const GLvoid *indices, CRClientState *c)
+{
+ int i;
+ GLubyte *p = (GLubyte *)indices;
+
+ (void) end;
+
+ if (count < 0)
+ {
+ crdlmWarning(__LINE__, __FILE__, GL_INVALID_VALUE, "DLM DrawRangeElements(negative count)");
+ return;
+ }
+
+ if (mode > GL_POLYGON)
+ {
+ crdlmWarning(__LINE__, __FILE__, GL_INVALID_ENUM, "DLM DrawRangeElements(bad mode)");
+ return;
+ }
+
+ if (type != GL_UNSIGNED_BYTE && type != GL_UNSIGNED_SHORT && type != GL_UNSIGNED_INT)
+ {
+ crdlmWarning(__LINE__, __FILE__, GL_INVALID_ENUM, "DLM DrawRangeElements(bad type)");
+ return;
+ }
+
+ crDLMCompileBegin(mode);
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ for (i=start; i<count; i++)
+ {
+ crDLMCompileArrayElement((GLint) *p++, c);
+ }
+ break;
+ case GL_UNSIGNED_SHORT:
+ for (i=start; i<count; i++)
+ {
+ crDLMCompileArrayElement((GLint) * (GLushort *) p, c);
+ p+=sizeof (GLushort);
+ }
+ break;
+ case GL_UNSIGNED_INT:
+ for (i=start; i<count; i++)
+ {
+ crDLMCompileArrayElement((GLint) * (GLuint *) p, c);
+ p+=sizeof (GLuint);
+ }
+ break;
+ default:
+ crError( "this can't happen: DLM DrawRangeElements" );
+ break;
+ }
+ crDLMCompileEnd();
+}
+
+#ifdef CR_EXT_multi_draw_arrays
+void DLM_APIENTRY crDLMCompileMultiDrawArraysEXT( GLenum mode, GLint *first,
+ GLsizei *count, GLsizei primcount, CRClientState *c)
+{
+ GLint i;
+
+ for (i = 0; i < primcount; i++) {
+ if (count[i] > 0) {
+ crDLMCompileDrawArrays(mode, first[i], count[i], c);
+ }
+ }
+}
+
+
+void DLM_APIENTRY crDLMCompileMultiDrawElementsEXT( GLenum mode, const GLsizei *count, GLenum type,
+ const GLvoid **indices, GLsizei primcount, CRClientState *c)
+{
+ GLint i;
+
+ for (i = 0; i < primcount; i++) {
+ if (count[i] > 0) {
+ crDLMCompileDrawElements(mode, count[i], type, indices[i], c);
+ }
+ }
+}
+#endif /* CR_EXT_multi_draw_arrays */
diff --git a/src/VBox/HostServices/SharedOpenGL/dlm/dlm_checklist.c b/src/VBox/HostServices/SharedOpenGL/dlm/dlm_checklist.c
new file mode 100644
index 00000000..e631c02e
--- /dev/null
+++ b/src/VBox/HostServices/SharedOpenGL/dlm/dlm_checklist.c
@@ -0,0 +1,51 @@
+/* $Id: dlm_checklist.c $ */
+#include "cr_dlm.h"
+#include "cr_mem.h"
+#include "cr_pixeldata.h"
+#include "cr_string.h"
+#include "dlm.h"
+
+/*****************************************************************************
+ * These helper functions are used for GL functions that are listed in
+ * the APIspec.txt file as "checklist", meaning that sometimes they
+ * represent functions that can be stored in a display list, and sometimes
+ * they represent control functions that must be executed immediately.
+ *
+ * The calling SPU must use these check functions (or their equivalents)
+ * before asking the DLM to compile any elements of these types.
+ * They return nonzero (TRUE) if the element goes into a display list.
+ */
+
+int DLM_APIENTRY crDLMCheckListTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ return (target != GL_PROXY_TEXTURE_1D);
+}
+
+int DLM_APIENTRY crDLMCheckListCompressedTexImage1DARB(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imagesize, const GLvoid *data)
+{
+ return (target != GL_PROXY_TEXTURE_1D);
+}
+int DLM_APIENTRY crDLMCheckListTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ return (target != GL_PROXY_TEXTURE_2D);
+}
+
+int DLM_APIENTRY crDLMCheckListCompressedTexImage2DARB(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imagesize, const GLvoid *data)
+{
+ return (target != GL_PROXY_TEXTURE_2D);
+}
+
+int DLM_APIENTRY crDLMCheckListTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ return (target != GL_PROXY_TEXTURE_3D);
+}
+
+int DLM_APIENTRY crDLMCheckListTexImage3DEXT(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ return (target != GL_PROXY_TEXTURE_3D);
+}
+
+int DLM_APIENTRY crDLMCheckListCompressedTexImage3DARB(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imagesize, const GLvoid *data)
+{
+ return (target != GL_PROXY_TEXTURE_3D);
+}
diff --git a/src/VBox/HostServices/SharedOpenGL/dlm/dlm_error.c b/src/VBox/HostServices/SharedOpenGL/dlm/dlm_error.c
new file mode 100644
index 00000000..90590e76
--- /dev/null
+++ b/src/VBox/HostServices/SharedOpenGL/dlm/dlm_error.c
@@ -0,0 +1,56 @@
+/* $Id: dlm_error.c $ */
+#include <stdio.h>
+#include <stdarg.h>
+#include "chromium.h"
+#include "cr_mem.h"
+#include "dlm.h"
+#include "cr_environment.h"
+#include "cr_error.h"
+
+#define GLCLIENT_LIST_ALLOC 1024
+
+void crdlmWarning( int line, char *file, GLenum error, char *format, ... )
+{
+ char errstr[8096];
+ va_list args;
+
+ if (crGetenv("CR_DEBUG")) {
+ char *glerr;
+ va_start( args, format );
+ vsprintf( errstr, format, args );
+ va_end( args );
+
+ switch (error) {
+ case GL_NO_ERROR:
+ glerr = "GL_NO_ERROR";
+ break;
+ case GL_INVALID_VALUE:
+ glerr = "GL_INVALID_VALUE";
+ break;
+ case GL_INVALID_ENUM:
+ glerr = "GL_INVALID_ENUM";
+ break;
+ case GL_INVALID_OPERATION:
+ glerr = "GL_INVALID_OPERATION";
+ break;
+ case GL_STACK_OVERFLOW:
+ glerr = "GL_STACK_OVERFLOW";
+ break;
+ case GL_STACK_UNDERFLOW:
+ glerr = "GL_STACK_UNDERFLOW";
+ break;
+ case GL_OUT_OF_MEMORY:
+ glerr = "GL_OUT_OF_MEMORY";
+ break;
+ case GL_TABLE_TOO_LARGE:
+ glerr = "GL_TABLE_TOO_LARGE";
+ break;
+ default:
+ glerr = "unknown";
+ break;
+ }
+
+ crWarning( "DLM error in %s, line %d: %s: %s\n",
+ file, line, glerr, errstr );
+ }
+}
diff --git a/src/VBox/HostServices/SharedOpenGL/dlm/dlm_generated.py b/src/VBox/HostServices/SharedOpenGL/dlm/dlm_generated.py
new file mode 100755
index 00000000..e5468e2b
--- /dev/null
+++ b/src/VBox/HostServices/SharedOpenGL/dlm/dlm_generated.py
@@ -0,0 +1,355 @@
+# $Id: dlm_generated.py $
+import sys, cPickle, re
+
+sys.path.append( "../glapi_parser" )
+import apiutil
+
+# A routine that can create call strings from instance names
+def InstanceCallString( params ):
+ output = ''
+ for index in range(0,len(params)):
+ if index > 0:
+ output += ", "
+ if params[index][0] != '':
+ output += 'instance->' + params[index][0]
+ return output
+
+def GetPointerType(basetype):
+ words = basetype.split()
+ if words[0] == 'const':
+ words = words[1:]
+ if words[-1].endswith('*'):
+ words[-1] = words[-1][:-1].strip()
+ if words[-1] == '':
+ words = words[:-1]
+ if words[0] == 'void' or words[0] == 'GLvoid':
+ words[0] = 'int'
+ return ' '.join(words)
+
+
+def GetPointerInfo(functionName):
+ # We'll keep track of all the parameters that require pointers.
+ # They'll require special handling later.
+ params = apiutil.Parameters(functionName)
+ pointers = []
+ pointername=''
+ pointerarg=''
+ pointertype=''
+ pointersize=0
+ pointercomment=''
+
+ index = 0
+ for (name, type, vecSize) in params:
+ # Watch out for the word "const" (which should be ignored)
+ # and for types that end in "*" (which are pointers and need
+ # special treatment)
+ words = type.split()
+ if words[-1].endswith('*'):
+ pointers.append(index)
+ index += 1
+
+ # If any argument was a pointer, we need a special pointer data
+ # array. The pointer data will be stored into this array, and
+ # references to the array will be generated as parameters.
+ if len(pointers) == 1:
+ index = pointers[0]
+ pointername = params[index][0]
+ pointerarg = pointername + 'Data'
+ pointertype = GetPointerType(params[index][1])
+ pointersize = params[index][2]
+ if pointersize == 0:
+ pointersize = "special"
+ elif len(pointers) > 1:
+ pointerarg = 'data';
+ pointertype = GetPointerType(params[pointers[0]][1])
+ for index in range(1,len(pointers)):
+ if GetPointerType(params[pointers[index]][1]) != pointertype:
+ pointertype = 'GLvoid *'
+
+ return (pointers,pointername,pointerarg,pointertype,pointersize,pointercomment)
+
+def wrap_struct(functionName):
+ params = apiutil.Parameters(functionName)
+ argstring = apiutil.MakeDeclarationString(params)
+ extendedArgstring = argstring
+ props = apiutil.Properties(functionName)
+ if "useclient" in props or "pixelstore" in props:
+ extendedArgstring += ", CRClientState *c"
+
+ # We'll keep track of all the parameters that require pointers.
+ # They'll require special handling later.
+ (pointers, pointername, pointerarg, pointertype, pointersize, pointercomment) = GetPointerInfo(functionName)
+
+ # Start writing the header
+ print 'struct instance%s {' % (functionName)
+ print ' DLMInstanceList *next;'
+ print ' DLMInstanceList *stateNext;'
+ print ' int cbInstance;'
+ print ' VBoxDLOpCode iVBoxOpCode;'
+ print ' void (DLM_APIENTRY *execute)(DLMInstanceList *instance, SPUDispatchTable *dispatchTable);'
+ for (name, type, vecSize) in params:
+ # Watch out for the word "const" (which should be ignored)
+ # and for types that end in "*" (which are pointers and need
+ # special treatment)
+ words = type.split()
+ if words[0] == 'const':
+ words = words[1:]
+ if words[0] != "void":
+ print ' %s %s;' % (' '.join(words), name)
+
+ # If any argument was a pointer, we need a special pointer data
+ # array. The pointer data will be stored into this array, and
+ # references to the array will be generated as parameters.
+ if len(pointers) == 1:
+ if pointersize == None:
+ print " /* Oh no - pointer parameter %s found, but no pointer class specified and can't guess */" % pointername
+ else:
+ if pointersize == 'special':
+ print ' %s %s[1];%s' % (pointertype, pointerarg, pointercomment)
+ else:
+ print ' %s %s[%s];%s' % (pointertype, pointerarg, pointersize,pointercomment)
+ elif len(pointers) > 1:
+ print ' %s %s[1];%s' % (pointertype, pointerarg,pointercomment)
+
+ print '};'
+
+ # Pointers only happen with instances
+ if len(pointers) > 1 or (len(pointers) == 1 and pointersize == 'special'):
+ print 'int crdlm_pointers_%s(struct instance%s *instance, %s);' % (functionName, functionName, extendedArgstring)
+
+ # See if the GL function must sometimes allow passthrough even
+ # if the display list is open
+ if "checklist" in apiutil.ChromiumProps(functionName):
+ print 'int crdlm_checklist_%s(%s);' % (functionName, argstring)
+
+ return
+
+def wrap_execute(functionName):
+
+ params = apiutil.Parameters(functionName)
+ (pointers, _, pointerarg, _, _, _) = GetPointerInfo(functionName)
+
+ print 'static void execute%s(DLMInstanceList *x, SPUDispatchTable *dispatchTable)' % functionName
+ print '{'
+ if len(params) > 0:
+ print ' struct instance%s *instance = (struct instance%s *)x;' % (functionName, functionName)
+
+ if len(pointers) == 1:
+ print ' instance->%s = instance->%s;' % (params[pointers[0]][0], pointerarg)
+
+ print ' if (dispatchTable->%s != NULL)' % (functionName)
+ print ' dispatchTable->%s(%s);' % (functionName, InstanceCallString(params))
+ print ' else'
+ print ' crWarning("DLM warning: execute%s called with NULL dispatch entry");' % (functionName)
+ print '}'
+
+# These code snippets isolate the code required to add a given instance
+# to the display list correctly. They are used during generation, to
+# generate correct code, and also to create useful utilities.
+def AddInstanceToList(pad):
+ print '%s/* Add this instance to the current display list. */' % pad
+ print '%sinstance->next = NULL;' % pad
+ print '%sinstance->stateNext = NULL;' % pad
+ print '%sif (!state->currentListInfo->first) {' % pad
+ print '%s state->currentListInfo->first = (DLMInstanceList *)instance;' % pad
+ print '%s}' % pad
+ print '%selse {' % pad
+ print '%s state->currentListInfo->last->next = (DLMInstanceList *)instance;' % pad
+ print '%s}' % pad
+ print '%sstate->currentListInfo->last = (DLMInstanceList *)instance;' % pad
+ print '%sstate->currentListInfo->numInstances++;' % pad
+
+def AddInstanceToStateList(pad):
+ print '%s/* Instances that change state have to be added to the state list as well. */' % pad
+ print '%sif (!state->currentListInfo->stateFirst) {' % pad
+ print '%s state->currentListInfo->stateFirst = (DLMInstanceList *)instance;' % pad
+ print '%s}' % pad
+ print '%selse {' % pad
+ print '%s state->currentListInfo->stateLast->stateNext = (DLMInstanceList *)instance;' % pad
+ print '%s}' % pad
+ print '%sstate->currentListInfo->stateLast = (DLMInstanceList *)instance;' % pad
+
+
+# The compile wrapper collects the parameters into a DLMInstanceList
+# element, and adds that element to the end of the display list currently
+# being compiled.
+def wrap_compile(functionName):
+ params = apiutil.Parameters(functionName)
+ return_type = apiutil.ReturnType(functionName)
+ # Make sure the return type is void. It's nonsensical to compile
+ # an element with any other return type.
+ if return_type != 'void':
+ print '/* Nonsense: DL function %s has a %s return type?!? */' % (functionName, return_type)
+
+ # Define a structure to hold all the parameters. Note that the
+ # top parameters must exactly match the DLMInstanceList structure
+ # in include/cr_dlm.h, or everything will break horribly.
+ # Start off by getting all the pointer info we could ever use
+ # from the parameters
+ (pointers, pointername, pointerarg, pointertype, pointersize, pointercomment) = GetPointerInfo(functionName)
+
+ # Finally, the compile wrapper. This one will diverge strongly
+ # depending on whether or not there are pointer parameters.
+ callstring = apiutil.MakeCallString(params)
+ argstring = apiutil.MakeDeclarationString(params)
+ props = apiutil.Properties(functionName)
+ if "useclient" in props or "pixelstore" in props:
+ callstring += ", c"
+ argstring += ", CRClientState *c"
+ print 'void DLM_APIENTRY crDLMCompile%s(%s)' % (functionName, argstring)
+ print '{'
+ print ' CRDLMContextState *state = CURRENT_STATE();'
+ print ' struct instance%s *instance;' % (functionName)
+
+ # The calling SPU is supposed to verify that the element is supposed to be
+ # compiled before it is actually compiled; typically, this is done based
+ # on whether a glNewList has been executed more recently than a glEndList.
+ # But some functions are dual-natured, sometimes being compiled, and sometimes
+ # being executed immediately. We can check for this here.
+ if "checklist" in apiutil.ChromiumProps(functionName):
+ print ' if (crDLMCheckList%s(%s))' % (functionName, apiutil.MakeCallString(params))
+ print ' {'
+ print ' crdlm_error(__LINE__, __FILE__, GL_INVALID_OPERATION,'
+ print ' "this instance of function %s should not be compiled");' % functionName;
+ print ' return;'
+ print ' }'
+
+ if len(pointers) > 1 or pointersize == 'special':
+ # Pass NULL, to just allocate space
+ print ' instance = crCalloc(sizeof(struct instance%s) + crdlm_pointers_%s(NULL, %s));' % (functionName, functionName, callstring)
+ else:
+ print ' instance = crCalloc(sizeof(struct instance%s));' % (functionName)
+ print ' if (!instance)'
+ print ' {'
+ print ' crdlm_error(__LINE__, __FILE__, GL_OUT_OF_MEMORY,'
+ print ' "out of memory adding %s to display list");' % (functionName)
+ print ' return;'
+ print ' }'
+
+ # Put in the fields that must always exist
+ print ' instance->execute = execute%s;' % functionName
+
+ # Apply all the simple (i.e. non-pointer) parameters
+ for index in range(len(params)):
+ if index not in pointers:
+ name = params[index][0]
+ print ' instance->%s = %s;' % (name, name)
+
+ # We need to know instance size in bytes in order to save its state later.
+ print ' instance->cbInstance = sizeof(struct instance%s);' % functionName
+
+ # Set OPCODE.
+ print ' instance->iVBoxOpCode = VBOX_DL_OPCODE_%s;' % functionName
+
+ # If there's a pointer parameter, apply it.
+ if len(pointers) == 1:
+
+ print ' if (%s == NULL)' % (params[pointers[0]][0])
+ print ' instance->%s = NULL;' % (params[pointers[0]][0])
+ print ' else'
+ print ' instance->%s = instance->%s;' % (params[pointers[0]][0], pointerarg)
+
+ if pointersize == 'special':
+ print ' instance->cbInstance += crdlm_pointers_%s(instance, %s);' % (functionName, callstring)
+ else:
+ print ' crMemcpy((void *)instance->%s, (void *) %s, %s*sizeof(%s));' % (params[pointers[0]][0], params[pointers[0]][0], pointersize, pointertype)
+ elif len(pointers) == 2:
+ # this seems to work
+ print ' instance->cbInstance += crdlm_pointers_%s(instance, %s);' % (functionName, callstring)
+ elif len(pointers) > 2:
+ print "#error don't know how to handle pointer parameters for %s" % (functionName)
+
+ # Add the element to the current display list
+ AddInstanceToList(' ')
+ # If the element is a state-changing element, add it to the current state list
+ if apiutil.SetsTrackedState(functionName):
+ AddInstanceToStateList(' ')
+ print '}'
+
+whichfile=sys.argv[1]
+if whichfile == 'headers':
+ print """#ifndef _DLM_GENERATED_H
+#define _DLM_GENERATED_H
+
+#include <VBoxUhgsmi.h>
+
+/* DO NOT EDIT. This file is auto-generated by dlm_generated.py. */
+"""
+else:
+ print """#include <stdio.h>
+#include "cr_spu.h"
+#include "cr_dlm.h"
+#include "cr_mem.h"
+#include "cr_error.h"
+#include "state/cr_statefuncs.h"
+#include "dlm.h"
+#include "dlm_pointers.h"
+#include "dlm_generated.h"
+
+/* DO NOT EDIT. This file is auto-generated by dlm_generated.py. */
+"""
+
+# Add in the "add_to_dl" utility function, which will be used by
+# external (i.e. non-generated) functions. The utility ensures that
+# any external functions that are written for compiling elements
+# don't have to be rewritten if the conventions for adding to display
+# lists are changed.
+print """
+void crdlm_add_to_list(
+ DLMInstanceList *instance,
+ void (*executeFunc)(DLMInstanceList *x, SPUDispatchTable *dispatchTable)"""
+
+if (whichfile == 'headers'):
+ print ");"
+else:
+ print """) {
+ CRDLMContextState *state = CURRENT_STATE();
+ instance->execute = executeFunc;"""
+
+ # Add in the common code for adding the instance to the display list
+ AddInstanceToList(" ")
+
+ print '}'
+ print ''
+
+# Now generate the functions that won't use the crdlm_add_to_list utility.
+# These all directly add their own instances to the current display list
+# themselves, without using the crdlm_add_to_list() function.
+keys = apiutil.GetDispatchedFunctions(sys.argv[3]+"/APIspec.txt")
+for func_name in keys:
+ if apiutil.CanCompile(func_name):
+ print "\n/*** %s ***/" % func_name
+ # Auto-generate an appropriate DL function. First, functions
+ # that go into the display list but that rely on state will
+ # have to have their argument strings expanded, to take pointers
+ # to that appropriate state.
+ if whichfile == "headers":
+ wrap_struct(func_name)
+ elif not apiutil.FindSpecial("dlm", func_name):
+ wrap_execute(func_name)
+ wrap_compile(func_name)
+
+
+# Generate mapping between OPCODE and routines to be executed.
+
+if whichfile == "headers":
+ # Execute routine prototype needed to add static array of routines.
+ print ''
+ print 'struct DLMInstanceList;'
+ print 'typedef void (*VBoxDLMExecuteFn)(struct DLMInstanceList *instance, SPUDispatchTable *dispatchTable);'
+ print ''
+ print 'extern VBoxDLMExecuteFn g_VBoxDLMExecuteFns[VBOX_DL_OPCODE_MAX];'
+ print ''
+else:
+ print ''
+ print 'VBoxDLMExecuteFn g_VBoxDLMExecuteFns[] = {'
+
+ for func_name in keys:
+ if apiutil.CanCompile(func_name) and not apiutil.FindSpecial("dlm", func_name):
+ print ' execute%s,' % func_name
+
+ print '};'
+ print ''
+
+if whichfile == 'headers':
+ print "#endif /* _DLM_GENERATED_H */"
diff --git a/src/VBox/HostServices/SharedOpenGL/dlm/dlm_header.py b/src/VBox/HostServices/SharedOpenGL/dlm/dlm_header.py
new file mode 100644
index 00000000..f68ccaa0
--- /dev/null
+++ b/src/VBox/HostServices/SharedOpenGL/dlm/dlm_header.py
@@ -0,0 +1,274 @@
+# $Id: dlm_header.py $
+import sys, cPickle, re, os
+
+sys.path.append( "../glapi_parser" )
+import apiutil
+
+# mode is "header" or "defs"
+mode = sys.argv[1]
+
+keys = apiutil.GetDispatchedFunctions(sys.argv[3]+"/APIspec.txt")
+
+# Any new function implemented in the DLM has to have an entry added here.
+# Each function has its return type, function name, and parameters provided.
+# We'll use these to generate both a header file, and a definition file.
+additionalFunctions = [
+ ('CRDLM DLM_APIENTRY *', 'crDLMNewDLM', 'unsigned int configSize, const CRDLMConfig *config'),
+ ('CRDLMContextState DLM_APIENTRY *', 'crDLMNewContext', 'CRDLM *dlm'),
+ ('void DLM_APIENTRY', 'crDLMFreeContext', 'CRDLMContextState *state, SPUDispatchTable *dispatchTable'),
+ ('void DLM_APIENTRY', 'crDLMUseDLM', 'CRDLM *dlm'),
+ ('void DLM_APIENTRY','crDLMFreeDLM', 'CRDLM *dlm, SPUDispatchTable *dispatchTable'),
+ ('void DLM_APIENTRY', 'crDLMSetCurrentState', 'CRDLMContextState *state'),
+ ('CRDLMContextState DLM_APIENTRY *', 'crDLMGetCurrentState', 'void'),
+ ('void DLM_APIENTRY', 'crDLMSetupClientState', 'SPUDispatchTable *dispatchTable'),
+ ('void DLM_APIENTRY', 'crDLMRestoreClientState', 'CRClientState *clientState, SPUDispatchTable *dispatchTable'),
+ ('void DLM_APIENTRY', 'crDLMSendAllDLMLists', 'CRDLM *dlm, SPUDispatchTable *dispatchTable'),
+ ('void DLM_APIENTRY', 'crDLMSendAllLists', 'SPUDispatchTable *dispatchTable'),
+ ('void DLM_APIENTRY', 'crDLMSendDLMList', 'CRDLM *dlm, unsigned long listIdentifier, SPUDispatchTable *dispatchTable'),
+ ('void DLM_APIENTRY', 'crDLMSendList', 'unsigned long listIdentifier, SPUDispatchTable *dispatchTable'),
+ ('void DLM_APIENTRY', 'crDLMReplayDLMList', 'CRDLM *dlm, unsigned long listIdentifier, SPUDispatchTable *dispatchTable'),
+ ('void DLM_APIENTRY', 'crDLMReplayList', 'unsigned long listIdentifier, SPUDispatchTable *dispatchTable'),
+ ('void DLM_APIENTRY', 'crDLMReplayDLMListState', 'CRDLM *dlm, unsigned long listIdentifier, SPUDispatchTable *dispatchTable'),
+ ('void DLM_APIENTRY', 'crDLMReplayListState', 'unsigned long listIdentifier, SPUDispatchTable *dispatchTable'),
+ ('void DLM_APIENTRY', 'crDLMReplayDLMLists', 'CRDLM *dlm, GLsizei n, GLenum type, const GLvoid *lists, SPUDispatchTable *dispatchTable'),
+ ('void DLM_APIENTRY', 'crDLMReplayLists', 'GLsizei n, GLenum type, const GLvoid *lists, SPUDispatchTable *dispatchTable'),
+ ('void DLM_APIENTRY', 'crDLMReplayDLMListsState', 'CRDLM *dlm, GLsizei n, GLenum type, const GLvoid *lists, SPUDispatchTable *dispatchTable'),
+ ('void DLM_APIENTRY', 'crDLMReplayListsState', 'GLsizei n, GLenum type, const GLvoid *lists, SPUDispatchTable *dispatchTable'),
+ ('CRDLMError DLM_APIENTRY', 'crDLMDeleteListContent', 'CRDLM *dlm, unsigned long listIdentifier'),
+ ('void DLM_APIENTRY', 'crDLMComputeBoundingBox', 'unsigned long listId'),
+ ('GLuint DLM_APIENTRY', 'crDLMGetCurrentList', 'void'),
+ ('GLenum DLM_APIENTRY', 'crDLMGetCurrentMode', 'void'),
+ ('void DLM_APIENTRY', 'crDLMErrorFunction', 'CRDLMErrorCallback callback'),
+ ('void DLM_APIENTRY', 'crDLMNewList', 'GLuint list, GLenum mode, SPUDispatchTable *dispatchTable'),
+ ('void DLM_APIENTRY', 'crDLMEndList', 'SPUDispatchTable *dispatchTable'),
+ ('void DLM_APIENTRY', 'crDLMCallList', 'GLuint list, SPUDispatchTable *dispatchTable'),
+ ('void DLM_APIENTRY', 'crDLMCallLists', 'GLsizei n, GLenum type, const GLvoid *lists, SPUDispatchTable *dispatchTable'),
+ ('void DLM_APIENTRY', 'crDLMDeleteLists', 'GLuint list, GLsizei range, SPUDispatchTable *dispatchTable'),
+ ('void DLM_APIENTRY', 'crDLMListBase', 'GLuint base, SPUDispatchTable *dispatchTable'),
+ ('GLboolean DLM_APIENTRY', 'crDLMIsList', 'GLuint list, SPUDispatchTable *dispatchTable'),
+ ('GLuint DLM_APIENTRY', 'crDLMGenLists', 'GLsizei range, SPUDispatchTable *dispatchTable'),
+ ('int32_t DLM_APIENTRY', 'crDLMSaveState', 'CRDLM *dlm, PSSMHANDLE pSSM'),
+ ('bool DLM_APIENTRY', 'crDLMLoadState', 'CRDLM *dlm, PSSMHANDLE pSSM, SPUDispatchTable *dispatchTable'),
+ #('void DLM_APIENTRY', 'crDLMListSent', 'CRDLM *dlm, unsigned long listIdentifier'),
+ #('GLboolean DLM_APIENTRY', 'crDLMIsListSent', 'CRDLM *dlm, unsigned long listIdentifier'),
+ #('GLint DLM_APIENTRY', 'crDLMListSize', 'CRDLM *dlm, unsigned long listIdentifier'),
+]
+
+if mode == 'header':
+ print """#ifndef CR_DLM_H
+
+/* DO NOT EDIT. This file is auto-generated by %s. */
+#define CR_DLM_H
+
+#if defined(WINDOWS)
+#define DLM_APIENTRY
+#else
+#define DLM_APIENTRY
+#endif
+
+#include "chromium.h"
+#include "state/cr_client.h"
+#include "cr_spu.h"
+#include "cr_hash.h"
+#include "cr_threads.h"
+#include "cr_pack.h"
+#ifdef CHROMIUM_THREADSAFE
+#include "cr_threads.h"
+#endif
+#include <VBox/types.h>
+""" % os.path.basename(sys.argv[0])
+
+ # Generate operation codes enum to be used for saving and restoring lists.
+ print "/* OpCodes codes enum to be used for saving and restoring lists. */"
+ print "typedef enum {"
+
+ for func_name in keys:
+ if apiutil.CanCompile(func_name) and not apiutil.FindSpecial("dlm", func_name):
+ print " VBOX_DL_OPCODE_%s," % func_name
+
+ print " VBOX_DL_OPCODE_MAX,"
+ print "} VBoxDLOpCode;"
+
+ print """
+/* 3D bounding box */
+typedef struct {
+ double xmin, xmax, ymin, ymax, zmin, zmax;
+} CRDLMBounds;
+
+/* Indicates whether we're currently involved in playback or not */
+typedef enum {
+ CRDLM_IMMEDIATE = 0,
+ CRDLM_REPLAY_STATE_FUNCTIONS = 1,
+ CRDLM_REPLAY_ALL_FUNCTIONS = 2
+} CRDLMReplayState;
+
+/* This is enough information to hold an instance of a single function call. */
+typedef struct DLMInstanceList {
+ struct DLMInstanceList *next;
+ struct DLMInstanceList *stateNext;
+ int cbInstance;
+ VBoxDLOpCode iVBoxOpCode; /* This field name should not interfere w/ OpenGL function parameters names (for example w/ param 'opcode' for glLogicOp()). */
+ void (*execute)(struct DLMInstanceList *instance, SPUDispatchTable *dispatchTable);
+} DLMInstanceList;
+
+typedef struct {
+ DLMInstanceList *first, *last;
+ uint32_t numInstances;
+ DLMInstanceList *stateFirst, *stateLast;
+ GLuint hwid;
+} DLMListInfo;
+
+typedef struct {
+ /* This holds all the display list information, hashed by list identifier. */
+ CRHashTable *displayLists;
+
+ /* This is a count of the number of contexts/users that are using
+ * this DLM.
+ */
+ unsigned int userCount;
+
+#ifdef CHROMIUM_THREADSAFE
+ /* This mutex protects the displayLists hash table from simultaneous
+ * updates by multiple contexts.
+ */
+ CRmutex dlMutex;
+ CRtsd tsdKey;
+#endif
+
+ /* Configuration information - see the CRDLMConfig structure below
+ * for details.
+ */
+ unsigned int bufferSize;
+} CRDLM;
+
+/* This structure holds thread-specific state. Each thread can be
+ * associated with one (and only one) context; and each context can
+ * be associated with one (and only one) DLM. Making things interesting,
+ * though, is that each DLM can be associated with multiple contexts.
+ *
+ * So the thread-specific data key is associated with each context, not
+ * with each DLM. Two different threads can, through two different
+ * contexts that share a single DLM, each have independent state and
+ * conditions.
+ */
+
+typedef struct {
+ CRDLM *dlm; /* the DLM associated with this state */
+ unsigned long currentListIdentifier; /* open display list */
+ DLMListInfo *currentListInfo; /* open display list data */
+ GLenum currentListMode; /* GL_COMPILE or GL_COMPILE_AND_EXECUTE */
+ GLuint listBase;
+
+} CRDLMContextState;
+
+/* These additional structures are for passing information to and from the
+ * CRDLM interface routines.
+ */
+typedef struct {
+ /* The size, in bytes, that the packer will initially allocate for
+ * each new buffer.
+ */
+#define CRDLM_DEFAULT_BUFFERSIZE (1024*1024)
+ unsigned int bufferSize; /* this will be allocated for each buffer */
+} CRDLMConfig;
+
+/* Positive values match GL error values.
+ * 0 (GL_NO_ERROR) is returned for success
+ * Negative values are internal errors.
+ * Possible positive values (from GL/gl.h) are:
+ * GL_NO_ERROR (0x0)
+ * GL_INVALID_ENUM (0x0500)
+ * GL_INVALID_VALUE (0x0501)
+ * GL_INVALID_OPERATION (0x0502)
+ * GL_STACK_OVERFLOW (0x0503)
+ * GL_STACK_UNDERFLOW (0x0504)
+ * GL_OUT_OF_MEMORY (0x0505)
+ */
+typedef int CRDLMError;
+
+/* This error reported if there's no current state. The caller is responsible
+ * for appropriately allocating context state with crDLMNewContext(), and
+ * for making it current with crDLMMakeCurrent().
+ */
+#define CRDLM_ERROR_STATE (-1)
+
+
+typedef void (*CRDLMErrorCallback)(int line, const char *file, GLenum error, const char *info);
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+"""
+elif mode == 'defs':
+ apiutil.CopyrightDef()
+ print '''\t; DO NOT EDIT. This code is generated by %s.
+
+EXPORTS''' % os.path.basename(sys.argv[0])
+else:
+ raise "unknown generation mode '%s'" % mode
+
+# Generate the list of functions, starting with those coded into
+# the module
+for (returnValue, name, parameters) in additionalFunctions:
+ if mode == 'header':
+ print "extern %s %s(%s);" % (returnValue, name, parameters)
+ elif mode == 'defs':
+ print "%s" % name
+
+# Continue with functions that are auto-generated.
+
+if mode == 'header':
+ print
+ print "/* auto-generated compilation functions begin here */"
+
+
+
+for func_name in keys:
+ props = apiutil.Properties(func_name)
+ # We're interested in intercepting all calls that:
+ # - can be put into a display list (i.e. "not ("nolist" in props)")
+ # - change client-side state that affects saving DL elements (i.e. "setclient" in props)
+
+ if apiutil.CanCompile(func_name):
+ params = apiutil.Parameters(func_name)
+ argstring = apiutil.MakeDeclarationString(params)
+ if "useclient" in props or "pixelstore" in props:
+ argstring = argstring + ", CRClientState *c"
+
+ if mode == 'header':
+ print 'extern void DLM_APIENTRY crDLMCompile%s(%s);' % (func_name, argstring)
+ elif mode == 'defs':
+ print "crDLMCompile%s" % func_name
+
+# Next make declarations for all the checklist functions.
+if mode == 'header':
+ print """
+/* auto-generated CheckList functions begin here. There is one for each
+ * function that has a dual nature: even when there's an active glNewList,
+ * sometimes they are compiled into the display list, and sometimes they
+ * are treated like a control function. The CheckList function will
+ * return TRUE if the function should really be compiled into a display
+ * list. The calling SPU is responsible for checking this; but the
+ * DLM will also print an error if it detects an invalid use.
+ */
+"""
+elif mode == 'defs':
+ pass
+
+for func_name in keys:
+ if "checklist" in apiutil.ChromiumProps(func_name):
+ params = apiutil.Parameters(func_name)
+ argstring = apiutil.MakeDeclarationString(params)
+ if mode == 'header':
+ print 'int DLM_APIENTRY crDLMCheckList%s(%s);' % (func_name, argstring)
+ elif mode == 'defs':
+ print "crDLMCheckList%s" % func_name
+
+if mode == 'header':
+ print """
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CR_DLM_H */"""
diff --git a/src/VBox/HostServices/SharedOpenGL/dlm/dlm_lists.c b/src/VBox/HostServices/SharedOpenGL/dlm/dlm_lists.c
new file mode 100644
index 00000000..495819a1
--- /dev/null
+++ b/src/VBox/HostServices/SharedOpenGL/dlm/dlm_lists.c
@@ -0,0 +1,452 @@
+/* $Id: dlm_lists.c $ */
+/** @file
+ * Implementation of all the Display Lists related routines:
+ *
+ * glGenLists, glDeleteLists, glNewList, glEndList, glCallList, glCallLists,
+ * glListBase and glIsList.
+ *
+ * Provide OpenGL IDs mapping between host and guest.
+ */
+
+/*
+ * 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 <float.h>
+#include "cr_dlm.h"
+#include "cr_mem.h"
+#include "dlm.h"
+
+
+/**
+ * Destroy each list entry.
+ */
+static void crdlmFreeDisplayListElements(DLMInstanceList *instance)
+{
+ while (instance)
+ {
+ DLMInstanceList *nextInstance = instance->next;
+ crFree(instance);
+ instance = nextInstance;
+ }
+}
+
+
+/**
+ * A callback routine used when iterating over all
+ * available lists in order to remove them.
+ *
+ * NOTE: @param pParam2 might be NULL.
+ */
+void crdlmFreeDisplayListResourcesCb(void *pParm1, void *pParam2)
+{
+ DLMListInfo *pListInfo = (DLMListInfo *)pParm1;
+ SPUDispatchTable *dispatchTable = (SPUDispatchTable *)pParam2;
+
+ if (pListInfo)
+ {
+ crdlmFreeDisplayListElements(pListInfo->first);
+ pListInfo->first = pListInfo->last = NULL;
+
+ /* Free host OpenGL resources. */
+ if (dispatchTable)
+ dispatchTable->DeleteLists(pListInfo->hwid, 1);
+
+ crFree(pListInfo);
+ }
+}
+
+
+/**
+ * Generate host and guest IDs, setup IDs mapping between host and guest.
+ */
+GLuint DLM_APIENTRY crDLMGenLists(GLsizei range, SPUDispatchTable *dispatchTable)
+{
+ CRDLMContextState *listState = CURRENT_STATE();
+ GLuint idHostRangeStart = 0;
+ GLuint idGuestRangeStart = 0;
+
+ crDebug("DLM: GenLists(%d) (DLM=%p).", range, listState ? listState->dlm : 0);
+
+ if (listState)
+ {
+ idHostRangeStart = dispatchTable->GenLists(range);
+ if (idHostRangeStart > 0)
+ {
+ idGuestRangeStart = crHashtableAllocKeys(listState->dlm->displayLists, range);
+ if (idGuestRangeStart > 0)
+ {
+ GLuint i;
+ bool fSuccess = true;
+
+ /* Now have successfully generated IDs range for host and guest. Let's make IDs association. */
+ for (i = 0; i < (GLuint)range; i++)
+ {
+ DLMListInfo *pListInfo;
+
+ pListInfo = (DLMListInfo *)crCalloc(sizeof(DLMListInfo));
+ if (pListInfo)
+ {
+ crMemset(pListInfo, 0, sizeof(DLMListInfo));
+ pListInfo->hwid = idHostRangeStart + i;
+
+ /* Insert pre-initialized list data which contains IDs mapping into the hash. */
+ crHashtableReplace(listState->dlm->displayLists, idGuestRangeStart + i, pListInfo, NULL);
+ }
+ else
+ {
+ fSuccess = false;
+ break;
+ }
+ }
+
+ /* All structures allocated and initialized successfully. */
+ if (fSuccess)
+ return idGuestRangeStart;
+
+ /* Rollback some data was not allocated. */
+ crDLMDeleteLists(idGuestRangeStart, range, NULL /* we do DeleteLists() later in this routine */ );
+ }
+ else
+ crDebug("DLM: Can't allocate Display List IDs range for the guest.");
+
+ dispatchTable->DeleteLists(idHostRangeStart, range);
+ }
+ else
+ crDebug("DLM: Can't allocate Display List IDs range on the host side.");
+ }
+ else
+ crDebug("DLM: GenLists(%u) called with no current state.", range);
+
+ /* Can't reserve IDs range. */
+ return 0;
+}
+
+
+/**
+ * Release host and guest IDs, free memory resources.
+ */
+void DLM_APIENTRY crDLMDeleteLists(GLuint list, GLsizei range, SPUDispatchTable *dispatchTable)
+{
+ CRDLMContextState *listState = CURRENT_STATE();
+
+ crDebug("DLM: DeleteLists(%u, %d) (DLM=%p).", list, range, listState ? listState->dlm : 0);
+
+ if (listState)
+ {
+ if (range >= 0)
+ {
+ int i;
+
+ /* Free resources: host memory, host IDs and guest IDs. */
+ DLM_LOCK(listState->dlm)
+ for (i = 0; i < range; i++)
+ crHashtableDeleteEx(listState->dlm->displayLists, list + i, crdlmFreeDisplayListResourcesCb, dispatchTable);
+ DLM_UNLOCK(listState->dlm)
+ }
+ else
+ crDebug("DLM: DeleteLists(%u, %d) not allowed.", list, range);
+ }
+ else
+ crDebug("DLM: DeleteLists(%u, %d) called with no current state.", list, range);
+}
+
+
+/**
+ * Start recording a list.
+ */
+void DLM_APIENTRY
+crDLMNewList(GLuint list, GLenum mode, SPUDispatchTable *dispatchTable)
+{
+ DLMListInfo *listInfo;
+ CRDLMContextState *listState = CURRENT_STATE();
+
+ crDebug("DLM: NewList(%u, %u) (DLM=%p).", list, mode, listState ? listState->dlm : 0);
+
+ if (listState)
+ {
+ /* Valid list ID should be > 0. */
+ if (list > 0)
+ {
+ if (listState->currentListInfo == NULL)
+ {
+ listInfo = (DLMListInfo *)crHashtableSearch(listState->dlm->displayLists, list);
+ if (listInfo)
+ {
+ listInfo->first = listInfo->last = NULL;
+ listInfo->stateFirst = listInfo->stateLast = NULL;
+
+ listInfo->numInstances = 0;
+
+ listState->currentListInfo = listInfo;
+ listState->currentListIdentifier = list;
+ listState->currentListMode = mode;
+
+ dispatchTable->NewList(listInfo->hwid, mode);
+
+ crDebug("DLM: create new list with [guest, host] ID pair [%u, %u].", list, listInfo->hwid);
+
+ return;
+ }
+ else
+ crDebug("DLM: Requested Display List %u was not previously reserved with glGenLists().", list);
+ }
+ else
+ crDebug("DLM: NewList called with display list %u while display list %u was already open.", list, listState->currentListIdentifier);
+ }
+ else
+ crDebug("DLM: NewList called with a list identifier of 0.");
+ }
+ else
+ crDebug("DLM: NewList(%u, %u) called with no current state.\n", list, mode);
+}
+
+
+/**
+ * Stop recording a list.
+ */
+void DLM_APIENTRY crDLMEndList(SPUDispatchTable *dispatchTable)
+{
+ CRDLMContextState *listState = CURRENT_STATE();
+
+ crDebug("DLM: EndList() (DLM=%p).", listState ? listState->dlm : 0);
+
+ if (listState)
+ {
+ /* Check if list was ever started. */
+ if (listState->currentListInfo)
+ {
+ /* reset the current state to show the list had been ended */
+ listState->currentListIdentifier = 0;
+ listState->currentListInfo = NULL;
+ listState->currentListMode = GL_FALSE;
+
+ dispatchTable->EndList();
+ }
+ else
+ crDebug("DLM: glEndList() is assuming glNewList() was issued previously.");
+ }
+ else
+ crDebug("DLM: EndList called with no current state.");
+}
+
+
+/**
+ * Execute list on hardware and cach ethis call if we currently recording a list.
+ */
+void DLM_APIENTRY crDLMCallList(GLuint list, SPUDispatchTable *dispatchTable)
+{
+ CRDLMContextState *listState = CURRENT_STATE();
+
+ //crDebug("DLM: CallList(%u).", list);
+
+ if (listState)
+ {
+ DLMListInfo *listInfo;
+
+ /* Add to calls cache if we recording a list. */
+ if (listState->currentListInfo)
+ crDLMCompileCallList(list);
+
+ /* Find hwid for list.
+ * We need to take into account listBase:
+ * - displayLists hash table contains absolute IDs, so we need to add offset in order to resolve guest ID;
+ * - we also need to substract from hwid in order to execute correct list. */
+ listInfo = (DLMListInfo *)crHashtableSearch(listState->dlm->displayLists, list + listState->listBase);
+ if (listInfo)
+ dispatchTable->CallList(listInfo->hwid - listState->listBase);
+ else
+ crDebug("DLM: CallList(%u) issued for non-existent list.", list);
+ }
+ else
+ crDebug("DLM: CallList(%u) called with no current state.", list);
+}
+
+
+/* This routine translates guest Display List IDs in given format to host IDs
+ * and return resulting IDs as an array of elements of type GL_UNSIGNED_INT.
+ * It is based on TranslateListIDs() function from crserverlib/server_lists.c. */
+static bool
+crDLMConvertListIDs(CRDLMContextState *pListState, GLsizei n, GLenum type, const GLvoid *aGuest, GLuint *aHost)
+{
+#define CRDLM_HANDLE_CONVERSION_CASE(_type, _item) \
+ { \
+ const _type *src = (const _type *)aGuest; \
+ for (i = 0; i < n; i++) \
+ { \
+ GLuint idGuest = (GLuint)(_item) + pListState->listBase; \
+ pListInfo = (DLMListInfo *)crHashtableSearch(pListState->dlm->displayLists, idGuest); \
+ if (pListInfo) \
+ { \
+ aHost[i] = pListInfo->hwid - pListState->listBase; \
+ } \
+ else \
+ { \
+ crDebug("DLM: CallLists() cannot resolve host list ID for guest ID %u.", idGuest); \
+ fSuccess = false; \
+ break; \
+ } \
+ } \
+ }
+
+ GLsizei i;
+ DLMListInfo *pListInfo;
+ bool fSuccess = true;
+
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE: CRDLM_HANDLE_CONVERSION_CASE(GLubyte, src[i]); break;
+ case GL_BYTE: CRDLM_HANDLE_CONVERSION_CASE(GLbyte, src[i]); break;
+ case GL_UNSIGNED_SHORT: CRDLM_HANDLE_CONVERSION_CASE(GLushort, src[i]); break;
+ case GL_SHORT: CRDLM_HANDLE_CONVERSION_CASE(GLshort, src[i]); break;
+ case GL_UNSIGNED_INT: CRDLM_HANDLE_CONVERSION_CASE(GLuint, src[i]); break;
+ case GL_INT: CRDLM_HANDLE_CONVERSION_CASE(GLint, src[i]); break;
+ case GL_FLOAT: CRDLM_HANDLE_CONVERSION_CASE(GLfloat, src[i]); break;
+
+ case GL_2_BYTES:
+ {
+ CRDLM_HANDLE_CONVERSION_CASE(GLubyte, src[i * 2 + 0] * 256 +
+ src[i * 2 + 1]);
+ break;
+ }
+
+ case GL_3_BYTES:
+ {
+ CRDLM_HANDLE_CONVERSION_CASE(GLubyte, src[i * 3 + 0] * 256 * 256 +
+ src[i * 3 + 1] * 256 +
+ src[i * 3 + 2]);
+ break;
+ }
+
+ case GL_4_BYTES:
+ {
+ CRDLM_HANDLE_CONVERSION_CASE(GLubyte, src[i * 4 + 0] * 256 * 256 * 256 +
+ src[i * 4 + 1] * 256 * 256 +
+ src[i * 4 + 2] * 256 +
+ src[i * 4 + 3]);
+ break;
+ }
+
+ default:
+ crWarning("DLM: attempt to pass to crDLMCallLists() an unknown type: 0x%x.", type);
+ }
+
+ return fSuccess;
+#undef CRDLM_HANDLE_CONVERSION_CASE
+}
+
+
+/**
+ * Execute lists on hardware and cache this call if we currently recording a list.
+ */
+void DLM_APIENTRY crDLMCallLists(GLsizei n, GLenum type, const GLvoid *lists, SPUDispatchTable *dispatchTable)
+{
+ CRDLMContextState *pListState = CURRENT_STATE();
+
+ crDebug("DLM: CallLists(%d, %u, %p).", n, type, lists);
+
+ if (n <= 0 || n >= INT32_MAX / sizeof(GLuint))
+ {
+ crError("crDLMCallLists: parameter 'n' is out of range");
+ return;
+ }
+
+ if (pListState)
+ {
+ GLsizei i;
+ GLuint *aHostIDs;
+
+ /* Add to calls cache if we recording a list. */
+ if (pListState->currentListInfo)
+ crDLMCompileCallLists(n, type, lists);
+
+ aHostIDs = (GLuint *)crAlloc(n * sizeof(GLuint));
+ if (aHostIDs)
+ {
+ /* Convert IDs. Resulting array contains elements of type of GL_UNSIGNED_INT. */
+ if (crDLMConvertListIDs(pListState, n, type, lists, aHostIDs))
+ dispatchTable->CallLists(n, GL_UNSIGNED_INT, aHostIDs);
+ else
+ crDebug("DLM: CallLists() failed.");
+
+ crFree(aHostIDs);
+ }
+ else
+ crDebug("DLM: no memory on CallLists().");
+ }
+ else
+ crDebug("DLM: CallLists(%d, %u, %p) called with no current state.", n, type, lists);
+}
+
+
+/**
+ * Set list base, remember its value and add call to the cache.
+ */
+void DLM_APIENTRY crDLMListBase(GLuint base, SPUDispatchTable *dispatchTable)
+{
+ CRDLMContextState *pListState = CURRENT_STATE();
+
+ crDebug("DLM: ListBase(%u).", base);
+
+ if (pListState)
+ {
+ pListState->listBase = base;
+
+ /* Only add to cache if we are currently recording a list. */
+ /** @todo Do we really need to chache it? */
+ if (pListState->currentListInfo)
+ crDLMCompileListBase(base);
+
+ dispatchTable->ListBase(base);
+ }
+ else
+ crDebug("DLM: ListBase(%u) called with no current state.", base);
+}
+
+
+/**
+ * Check if specified list ID belongs to valid Display List.
+ * Positive result is only returned in case both conditions below are satisfied:
+ *
+ * - given list found in DLM hash table (i.e., it was previously allocated
+ * with crDLMGenLists and still not released with crDLMDeleteLists);
+ *
+ * - list is valid on the host side.
+ */
+GLboolean DLM_APIENTRY crDLMIsList(GLuint list, SPUDispatchTable *dispatchTable)
+{
+ CRDLMContextState *listState = CURRENT_STATE();
+
+ crDebug("DLM: IsList(%u).", list);
+
+ if (listState)
+ {
+ if (list > 0)
+ {
+ DLMListInfo *listInfo = (DLMListInfo *)crHashtableSearch(listState->dlm->displayLists, list);
+ if (listInfo)
+ {
+ if (dispatchTable->IsList(listInfo->hwid))
+ return true;
+ else
+ crDebug("DLM: list [%u, %u] not found on the host side.", list, listInfo->hwid);
+ }
+ else
+ crDebug("DLM: list %u not found in guest cache.", list);
+ }
+ else
+ crDebug("DLM: IsList(%u) is not allowed.", list);
+ }
+ else
+ crDebug("DLM: IsList(%u) called with no current state.", list);
+
+ return false;
+}
diff --git a/src/VBox/HostServices/SharedOpenGL/dlm/dlm_pointers.c b/src/VBox/HostServices/SharedOpenGL/dlm/dlm_pointers.c
new file mode 100644
index 00000000..718ebdec
--- /dev/null
+++ b/src/VBox/HostServices/SharedOpenGL/dlm/dlm_pointers.c
@@ -0,0 +1,1125 @@
+/* $Id: dlm_pointers.c $ */
+#include "cr_dlm.h"
+#include "cr_mem.h"
+#include "cr_pixeldata.h"
+#include "cr_string.h"
+#include "dlm.h"
+#include "dlm_pointers.h"
+
+/**
+ * These helper functions are used for GL functions that take a pointers,
+ * if the size of the arrays that the pointers refer to is not constant.
+ * These helper functions will determine, on a case-by-case basis,
+ * how much space is needed to store the array. If the buffer
+ * parameter is not NULL, they will also pack the data into the given
+ * array.
+ *
+ * Many of the functions included deal with pixel state (Bitmap, DrawPixels,
+ * etc.). In all these cases, when the function instance is stored in a
+ * display list, its data is read from memory (as per the parameters
+ * to PixelStore) and is stored in a tightly packed format (with no
+ * excess row length, no pixels skipped, no rows, skipped, and a byte
+ * alignment).
+ *
+ * When the instances are executed again, care must be taken to ensure
+ * that the PixelStore client state that unpacks them is set to reflect
+ * the tight packing actually used, instead of whatever the current
+ * client state indicates.
+ *
+ * So to do this, client PixelStore state is forced to known values
+ * before any instances in the display list are executed. The client
+ * state is then restored to known values afterwards. (The difficulty
+ * of this is somewhat mollified by the observation that PixelStore
+ * instances affect client state, and cannot be stored in a display list.)
+ *
+ */
+
+int crdlm_pointers_Bitmap( struct instanceBitmap *instance, GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap, CRClientState *c)
+{
+ unsigned int size = ((int)((width + 7) / 8)) * height;
+ /* glBitmap can be called with a NULL size 0 bitmap, say for
+ * an empty glyph that only moves the current raster position.
+ * crMemcpy will raise an exception with a NULL source pointer, even if
+ * the size to copy is 0. So make sure we don't ram into this.
+ * Also, the bitmap isn't necessarily just sitting in memory; the PixelStore
+ * client-side state affects how it is read from memory. It's easiest to just
+ * use the utility.
+ */
+ if (instance && size > 0) {
+ crBitmapCopy(width, height, instance->bitmap, bitmap,
+ &c->unpack);
+ }
+
+ return size;
+}
+
+int crdlm_pointers_DrawPixels( struct instanceDrawPixels *instance, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c )
+{
+ unsigned int size = crImageSize(format, type, width, height);
+
+ if (instance && size > 0) {
+ crPixelCopy2D(width, height,
+ instance->pixels, format, type, NULL,
+ pixels, format, type, &c->unpack);
+ }
+
+ return size;
+}
+int crdlm_pointers_Fogfv( struct instanceFogfv *instance, GLenum pname, const GLfloat *params )
+{
+ unsigned int size = (pname == GL_FOG_COLOR?4:1)*sizeof(GLfloat);
+ if (instance) crMemcpy(instance->params, params, size);
+ return size;
+}
+int crdlm_pointers_Fogiv( struct instanceFogiv *instance, GLenum pname, const GLint *params )
+{
+ unsigned int size = (pname == GL_FOG_COLOR?4:1)*sizeof(GLint);
+ if (instance) crMemcpy(instance->params, params, size);
+ return size;
+}
+int crdlm_pointers_LightModelfv( struct instanceLightModelfv *instance, GLenum pname, const GLfloat *params )
+{
+ unsigned int size = (pname == GL_LIGHT_MODEL_AMBIENT?4:1)*sizeof(GLfloat);
+ if (instance) crMemcpy(instance->params, params, size);
+ return size;
+}
+int crdlm_pointers_LightModeliv( struct instanceLightModeliv *instance, GLenum pname, const GLint *params )
+{
+ unsigned int size = (pname == GL_LIGHT_MODEL_AMBIENT?4:1)*sizeof(GLfloat);
+ if (instance) crMemcpy(instance->params, params, size);
+ return size;
+}
+int crdlm_pointers_Lightfv( struct instanceLightfv *instance, GLenum light, GLenum pname, const GLfloat *params )
+{
+ unsigned int size;
+ switch(pname) {
+ case GL_AMBIENT: case GL_DIFFUSE: case GL_SPECULAR: case GL_POSITION:
+ size = 4 * sizeof(GLfloat);
+ break;
+ case GL_SPOT_DIRECTION:
+ size = 3 * sizeof(GLfloat);
+ break;
+ default:
+ size = 1 * sizeof(GLfloat);
+ break;
+ }
+ if (instance) crMemcpy(instance->params, params, size);
+ return size;
+}
+int crdlm_pointers_Lightiv( struct instanceLightiv *instance, GLenum light, GLenum pname, const GLint *params )
+{
+ unsigned int size;
+ switch(pname) {
+ case GL_AMBIENT: case GL_DIFFUSE: case GL_SPECULAR: case GL_POSITION:
+ size = 4 * sizeof(GLint);
+ break;
+ case GL_SPOT_DIRECTION:
+ size = 3 * sizeof(GLint);
+ break;
+ default:
+ size = 1 * sizeof(GLint);
+ break;
+ }
+ if (instance) crMemcpy(instance->params, params, size);
+ return size;
+}
+
+/* This utility routine returns the number of components per
+ * mapping point for all the glMap* functions.
+ */
+static int map_num_components(GLenum target)
+{
+ switch(target) {
+ case GL_MAP1_INDEX: case GL_MAP1_TEXTURE_COORD_1:
+ return 1;
+ case GL_MAP1_TEXTURE_COORD_2:
+ return 2;
+ case GL_MAP1_VERTEX_3: case GL_MAP1_NORMAL:
+ case GL_MAP1_TEXTURE_COORD_3:
+ return 3;
+ case GL_MAP1_VERTEX_4: case GL_MAP1_COLOR_4:
+ case GL_MAP1_TEXTURE_COORD_4:
+ return 4;
+
+ case GL_MAP2_INDEX: case GL_MAP2_TEXTURE_COORD_1:
+ return 1;
+ case GL_MAP2_TEXTURE_COORD_2:
+ return 2;
+ case GL_MAP2_VERTEX_3: case GL_MAP2_NORMAL:
+ case GL_MAP2_TEXTURE_COORD_3:
+ return 3;
+ case GL_MAP2_VERTEX_4: case GL_MAP2_COLOR_4:
+ case GL_MAP2_TEXTURE_COORD_4:
+ return 4;
+ }
+ return 0;
+}
+
+
+int crdlm_pointers_Map1d( struct instanceMap1d *instance, GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points )
+{
+ unsigned int numValues = map_num_components(target);
+ unsigned int size = order * numValues * sizeof(GLdouble);
+ if (instance) {
+ /* This one's a little different - we rearrange the order to
+ * compress it, and change the instance's stride value to
+ * match.
+ */
+ const GLdouble *src = points;
+ GLdouble *dest = instance->points;
+ register int i;
+ for (i = 0; i < order; i++) {
+ crMemcpy(dest, src, numValues * sizeof(GLdouble));
+ dest += numValues;
+ src += stride;
+ }
+
+ /* We override the stride to show we've compressed the data */
+ instance->stride = numValues;
+ }
+ return size;
+}
+int crdlm_pointers_Map1f( struct instanceMap1f *instance, GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points )
+{
+ unsigned int numValues = map_num_components(target);
+ unsigned int size = order * numValues * sizeof(GLfloat);
+ if (instance) {
+ /* This one's a little different - we rearrange the order to
+ * compress it, and change the instance's stride value to
+ * match.
+ */
+ const GLfloat *src = points;
+ GLfloat *dest = instance->points;
+ register int i;
+ for (i = 0; i < order; i++) {
+ crMemcpy(dest, src, numValues * sizeof(GLfloat));
+ dest += numValues;
+ src += stride;
+ }
+
+ /* We override the stride to show we've compressed the data */
+ instance->stride = numValues;
+ }
+ return size;
+}
+int crdlm_pointers_Map2d( struct instanceMap2d *instance, GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points )
+{
+ unsigned int numValues = map_num_components(target);
+ unsigned int size = uorder * vorder * numValues * sizeof(GLdouble);
+ if (instance) {
+ register int v, u;
+ const GLdouble *src = points;
+ GLdouble *dest = instance->points;
+ for (v = 0; v < vorder; v++) {
+ for (u = 0; u < uorder; u++) {
+ crMemcpy(dest, src, numValues * sizeof(GLdouble));
+ dest += numValues;
+ src += ustride;
+ }
+ src += vstride - ustride*uorder;
+ }
+ /* We override the stride to show we've compressed the data */
+ instance->ustride = numValues;
+ instance->vstride = ustride * uorder;
+ }
+ return size;
+}
+int crdlm_pointers_Map2f( struct instanceMap2f *instance, GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points )
+{
+ unsigned int numValues = map_num_components(target);
+ unsigned int size = uorder * vorder * numValues * sizeof(GLfloat);
+ if (instance) {
+ register int v, u;
+ const GLfloat *src = points;
+ GLfloat *dest = instance->points;
+ for (v = 0; v < vorder; v++) {
+ for (u = 0; u < uorder; u++) {
+ crMemcpy(dest, src, numValues * sizeof(GLfloat));
+ dest += numValues;
+ src += ustride;
+ }
+ src += vstride - ustride*uorder;
+ }
+ /* We override the stride to show we've compressed the data */
+ instance->ustride = numValues;
+ instance->vstride = ustride * uorder;
+ }
+ return size;
+}
+
+int crdlm_pointers_Materialfv(struct instanceMaterialfv *instance, GLenum face, GLenum pname, const GLfloat *params)
+{
+ unsigned int size = 0;
+ switch(pname) {
+ case GL_AMBIENT_AND_DIFFUSE:
+ size = 8 * sizeof(GLfloat);
+ break;
+ case GL_AMBIENT:
+ case GL_DIFFUSE:
+ case GL_SPECULAR:
+ case GL_EMISSION:
+ size = 4 * sizeof(GLfloat);
+ break;
+ case GL_SHININESS:
+ size = 1 * sizeof(GLfloat);
+ break;
+ case GL_COLOR_INDEXES:
+ size = 3 * sizeof(GLfloat);
+ break;
+ default:
+ break;
+ }
+ if (instance && size > 0) crMemcpy(instance->params, params, size);
+ return size;
+}
+
+int crdlm_pointers_Materialiv(struct instanceMaterialiv *instance, GLenum face, GLenum pname, const GLint *params)
+{
+ unsigned int size = 0;
+ switch(pname) {
+ case GL_AMBIENT_AND_DIFFUSE:
+ size = 8 * sizeof(GLint);
+ break;
+ case GL_AMBIENT:
+ case GL_DIFFUSE:
+ case GL_SPECULAR:
+ case GL_EMISSION:
+ size = 4 * sizeof(GLint);
+ break;
+ case GL_SHININESS:
+ size = 1 * sizeof(GLint);
+ break;
+ case GL_COLOR_INDEXES:
+ size = 3 * sizeof(GLint);
+ break;
+ default:
+ break;
+ }
+ if (instance && size > 0) crMemcpy(instance->params, params, size);
+ return size;
+}
+
+int crdlm_pointers_PixelMapfv( struct instancePixelMapfv *instance, GLenum map, GLsizei mapsize, const GLfloat *values )
+{
+ unsigned int size = mapsize * sizeof(GLfloat);
+ if (instance && size > 0) crMemcpy(instance->values, values, size);
+ return size;
+}
+int crdlm_pointers_PixelMapuiv( struct instancePixelMapuiv *instance, GLenum map, GLsizei mapsize, const GLuint *values )
+{
+ unsigned int size = mapsize * sizeof(GLuint);
+ if (instance && size > 0) crMemcpy(instance->values, values, size);
+ return size;
+}
+int crdlm_pointers_PixelMapusv( struct instancePixelMapusv *instance, GLenum map, GLsizei mapsize, const GLushort *values )
+{
+ unsigned int size = mapsize * sizeof(GLushort);
+ if (instance && size > 0) crMemcpy(instance->values, values, size);
+ return size;
+}
+
+int crdlm_pointers_PointParameterfvARB( struct instancePointParameterfvARB *instance, GLenum pname, const GLfloat *params)
+{
+ unsigned int size = 0;
+ switch(pname) {
+ case GL_POINT_DISTANCE_ATTENUATION_ARB:
+ size = 3 * sizeof(GLfloat);
+ break;
+ default:
+ size = 1 * sizeof(GLfloat);
+ break;
+ }
+ return size;
+}
+
+int crdlm_pointers_PointParameteriv( struct instancePointParameteriv *instance, GLenum pname, const GLint *params)
+{
+ unsigned int size = 0;
+ switch(pname) {
+ case GL_POINT_DISTANCE_ATTENUATION_ARB:
+ size = 3 * sizeof(GLint);
+ break;
+ default:
+ size = 1 * sizeof(GLint);
+ break;
+ }
+ return size;
+}
+
+int crdlm_pointers_TexEnvfv( struct instanceTexEnvfv *instance, GLenum target, GLenum pname, const GLfloat *params )
+{
+ unsigned int size = (pname == GL_TEXTURE_ENV_COLOR?4:1)*sizeof(GLfloat);
+ if (instance) crMemcpy(instance->params, params, size);
+ return size;
+}
+int crdlm_pointers_TexEnviv( struct instanceTexEnviv *instance, GLenum target, GLenum pname, const GLint *params )
+{
+ unsigned int size = (pname == GL_TEXTURE_ENV_COLOR?4:1)*sizeof(GLint);
+ if (instance) crMemcpy(instance->params, params, size);
+ return size;
+}
+int crdlm_pointers_TexGendv( struct instanceTexGendv *instance, GLenum coord, GLenum pname, const GLdouble *params )
+{
+ unsigned int size = (pname == GL_OBJECT_PLANE||pname==GL_EYE_PLANE?4:1)*sizeof(GLdouble);
+ if (instance) crMemcpy(instance->params, params, size);
+ return size;
+}
+int crdlm_pointers_TexGenfv( struct instanceTexGenfv *instance, GLenum coord, GLenum pname, const GLfloat *params )
+{
+ unsigned int size = (pname == GL_OBJECT_PLANE||pname==GL_EYE_PLANE?4:1)*sizeof(GLfloat);
+ if (instance) crMemcpy(instance->params, params, size);
+ return size;
+}
+int crdlm_pointers_TexGeniv( struct instanceTexGeniv *instance, GLenum coord, GLenum pname, const GLint *params )
+{
+ unsigned int size = (pname == GL_OBJECT_PLANE||pname==GL_EYE_PLANE?4:1)*sizeof(GLint);
+ if (instance) crMemcpy(instance->params, params, size);
+ return size;
+}
+int crdlm_pointers_TexImage1D( struct instanceTexImage1D *instance, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c )
+{
+ unsigned int size = crImageSize(format, type, width, 1);
+
+ if (instance && size > 0) {
+ crPixelCopy1D(instance->pixels, format, type,
+ pixels, format, type, width, &c->unpack);
+ }
+
+ return size;
+}
+int crdlm_pointers_CompressedTexImage1DARB(struct instanceCompressedTexImage1DARB *instance, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imagesize, const GLvoid *data)
+{
+ unsigned int size = imagesize;
+
+ if (instance && size > 0) {
+ crMemcpy(instance->data, data, size);
+ }
+
+ return size;
+}
+
+int crdlm_pointers_TexImage2D( struct instanceTexImage2D *instance, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c )
+{
+ unsigned int size = crImageSize(format, type, width, height);
+
+ if (instance && size > 0) {
+ crPixelCopy2D(width, height,
+ instance->pixels, format, type, NULL,
+ pixels, format, type, &c->unpack);
+ }
+
+ return size;
+}
+int crdlm_pointers_CompressedTexImage2DARB(struct instanceCompressedTexImage2DARB *instance, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imagesize, const GLvoid *data)
+{
+ unsigned int size = imagesize;
+
+ if (instance && size > 0) {
+ crMemcpy(instance->data, data, size);
+ }
+
+ return size;
+}
+
+int crdlm_pointers_TexImage3D( struct instanceTexImage3D *instance, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c )
+{
+ unsigned int size;
+ int is_distrib = ((type == GL_TRUE) || (type == GL_FALSE));
+
+ if (pixels == NULL) {
+ size = 0;
+ }
+ else if (is_distrib) {
+ size = crStrlen(pixels) + 1 + (type==GL_TRUE?width*height*3:0);
+ }
+ else {
+ size = crTextureSize(format, type, width, height, depth);
+ }
+
+ if (instance && size > 0) {
+ if (is_distrib) {
+ crMemcpy(instance->pixels, pixels, size);
+ }
+ else {
+ crPixelCopy3D(width, height, depth,
+ instance->pixels, format, type, NULL,
+ pixels, format, type, &c->unpack);
+ }
+ }
+
+ return size;
+}
+int crdlm_pointers_TexImage3DEXT( struct instanceTexImage3DEXT *instance, GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c )
+{
+ unsigned int size;
+ int is_distrib = ((type == GL_TRUE) || (type == GL_FALSE));
+
+ if (pixels == NULL) {
+ size = 0;
+ }
+ else if (is_distrib) {
+ size = crStrlen(pixels) + 1 + (type==GL_TRUE?width*height*3:0);
+ }
+ else {
+ size = crTextureSize(format, type, width, height, depth);
+ }
+
+ if (instance && size > 0) {
+ if (is_distrib) {
+ crMemcpy(instance->pixels, pixels, size);
+ }
+ else {
+ crPixelCopy3D(width, height, depth,
+ instance->pixels, format, type, NULL,
+ pixels, format, type, &c->unpack);
+ }
+ }
+
+ return size;
+}
+
+int crdlm_pointers_CompressedTexImage3DARB(struct instanceCompressedTexImage3DARB *instance, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imagesize, const GLvoid *data)
+{
+ unsigned int size = imagesize;
+
+ if (instance && size > 0) {
+ crMemcpy(instance->data, data, size);
+ }
+
+ return size;
+}
+
+int crdlm_pointers_TexParameterfv( struct instanceTexParameterfv *instance, GLenum target, GLenum pname, const GLfloat *params )
+{
+ unsigned int size = (pname == GL_TEXTURE_BORDER_COLOR?4:1)*sizeof(GLfloat);
+ if (instance) crMemcpy(instance->params, params, size);
+ return size;
+}
+int crdlm_pointers_TexParameteriv( struct instanceTexParameteriv *instance, GLenum target, GLenum pname, const GLint *params )
+{
+ unsigned int size = (pname == GL_TEXTURE_BORDER_COLOR?4:1)*sizeof(GLfloat);
+ if (instance) crMemcpy(instance->params, params, size);
+ return size;
+}
+int crdlm_pointers_TexSubImage1D( struct instanceTexSubImage1D *instance, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c )
+{
+ unsigned int size = crImageSize(format, type, width, 1);
+
+ if (instance && size > 0) {
+ crPixelCopy1D(instance->pixels, format, type,
+ pixels, format, type, width, &c->unpack);
+ }
+
+ return size;
+}
+int crdlm_pointers_TexSubImage2D( struct instanceTexSubImage2D *instance, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c )
+{
+ unsigned int size = crImageSize(format, type, width, height);
+
+ if (instance && size > 0) {
+ crPixelCopy2D(width, height,
+ instance->pixels, format, type, NULL,
+ pixels, format, type, &c->unpack);
+ }
+
+ return size;
+}
+int crdlm_pointers_TexSubImage3D( struct instanceTexSubImage3D *instance, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c )
+{
+ unsigned int size;
+ int is_distrib = ((type == GL_TRUE) || (type == GL_FALSE));
+
+ if (pixels == NULL) {
+ size = 0;
+ }
+ else if (is_distrib) {
+ size = crStrlen(pixels) + 1 + (type==GL_TRUE?width*height*3:0);
+ }
+ else {
+ size = crTextureSize(format, type, width, height, depth);
+ }
+
+ if (instance && size > 0) {
+ if (is_distrib) {
+ crMemcpy(instance->pixels, pixels, size);
+ }
+ else {
+ crPixelCopy3D(width, height, depth,
+ instance->pixels, format, type, NULL,
+ pixels, format, type, &c->unpack);
+ }
+ }
+
+ return size;
+}
+
+int crdlm_pointers_CompressedTexSubImage1DARB(struct instanceCompressedTexSubImage1DARB *instance, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imagesize, const GLvoid *data)
+{
+ unsigned int size = imagesize;
+
+ if (instance && size > 0) {
+ crMemcpy(instance->data, data, size);
+ }
+
+ return size;
+}
+
+int crdlm_pointers_CompressedTexSubImage2DARB(struct instanceCompressedTexSubImage2DARB *instance, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imagesize, const GLvoid *data)
+{
+ unsigned int size = imagesize;
+
+ if (instance && size > 0) {
+ crMemcpy(instance->data, data, size);
+ }
+
+ return size;
+}
+int crdlm_pointers_CompressedTexSubImage3DARB(struct instanceCompressedTexSubImage3DARB *instance, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imagesize, const GLvoid *data)
+{
+ unsigned int size = imagesize;
+
+ if (instance && size > 0) {
+ crMemcpy(instance->data, data, size);
+ }
+
+ return size;
+}
+
+int crdlm_pointers_Rectdv(struct instanceRectdv *instance, const GLdouble *v1, const GLdouble *v2)
+{
+ unsigned int size = 4 * sizeof(GLdouble);
+ if (instance) {
+ instance->data[0] = v1[0];
+ instance->data[1] = v1[1];
+ instance->data[2] = v2[0];
+ instance->data[3] = v2[1];
+ instance->v1 = &instance->data[0];
+ instance->v2 = &instance->data[2];
+ }
+ return size;
+}
+int crdlm_pointers_Rectfv(struct instanceRectfv *instance, const GLfloat *v1, const GLfloat *v2)
+{
+ unsigned int size = 4 * sizeof(GLfloat);
+ if (instance) {
+ instance->data[0] = v1[0];
+ instance->data[1] = v1[1];
+ instance->data[2] = v2[0];
+ instance->data[3] = v2[1];
+ instance->v1 = &instance->data[0];
+ instance->v2 = &instance->data[2];
+ }
+ return size;
+}
+int crdlm_pointers_Rectiv(struct instanceRectiv *instance, const GLint *v1, const GLint *v2)
+{
+ unsigned int size = 4 * sizeof(GLint);
+ if (instance) {
+ instance->data[0] = v1[0];
+ instance->data[1] = v1[1];
+ instance->data[2] = v2[0];
+ instance->data[3] = v2[1];
+ instance->v1 = &instance->data[0];
+ instance->v2 = &instance->data[2];
+ }
+ return size;
+}
+int crdlm_pointers_Rectsv(struct instanceRectsv *instance, const GLshort *v1, const GLshort *v2)
+{
+ unsigned int size = 4 * sizeof(GLshort);
+ if (instance) {
+ instance->data[0] = v1[0];
+ instance->data[1] = v1[1];
+ instance->data[2] = v2[0];
+ instance->data[3] = v2[1];
+ instance->v1 = &instance->data[0];
+ instance->v2 = &instance->data[2];
+ }
+ return size;
+}
+
+int crdlm_pointers_PrioritizeTextures(struct instancePrioritizeTextures *instance, GLsizei n, const GLuint *textures, const GLclampf *priorities)
+{
+ unsigned int size = n * (sizeof(GLuint) + sizeof(GLclampf));
+ if (instance) {
+ instance->textures = (GLuint *)&instance->data[0];
+ instance->priorities = (GLclampf *)(((char *)&instance->data[0]) + n * sizeof(GLuint));
+ if (size > 0) {
+ crMemcpy(instance->textures, textures, n * sizeof(GLuint));
+ crMemcpy(instance->priorities, priorities, n * sizeof(GLclampf));
+ }
+ }
+
+ return size;
+}
+
+static int combiner_num_components(GLenum pname)
+{
+ switch(pname) {
+ case GL_CONSTANT_COLOR0_NV:
+ case GL_CONSTANT_COLOR1_NV:
+ return 4;
+ case GL_NUM_GENERAL_COMBINERS_NV:
+ case GL_COLOR_SUM_CLAMP_NV:
+ return 1;
+ }
+ return 0;
+}
+int crdlm_pointers_CombinerParameterivNV(struct instanceCombinerParameterivNV *instance, GLenum pname, const GLint *params)
+{
+ unsigned int size = combiner_num_components(pname) * sizeof(GLint);
+ if (instance && size > 0) crMemcpy(instance->params, params, size);
+ return size;
+}
+int crdlm_pointers_CombinerParameterfvNV(struct instanceCombinerParameterfvNV *instance, GLenum pname, const GLfloat *params)
+{
+ unsigned int size = combiner_num_components(pname) * sizeof(GLfloat);
+ if (instance && size > 0) crMemcpy(instance->params, params, size);
+ return size;
+}
+
+static int combinerstage_num_components(GLenum pname)
+{
+ switch(pname) {
+ case GL_CONSTANT_COLOR0_NV:
+ case GL_CONSTANT_COLOR1_NV:
+ return 4;
+ }
+ return 0;
+}
+int crdlm_pointers_CombinerStageParameterfvNV(struct instanceCombinerStageParameterfvNV *instance, GLenum stage, GLenum pname, const GLfloat *params)
+{
+ unsigned int size = combinerstage_num_components(pname) * sizeof(GLfloat);
+ if (instance && size > 0) crMemcpy(instance->params, params, size);
+ return size;
+}
+
+static int program_num_components(GLenum target)
+{
+ switch(target) {
+ case GL_VERTEX_STATE_PROGRAM_NV:
+ return 4;
+ }
+ return 0;
+}
+int crdlm_pointers_ExecuteProgramNV(struct instanceExecuteProgramNV *instance, GLenum target, GLuint id, const GLfloat *params)
+{
+ unsigned int size = program_num_components(target) * sizeof(GLfloat);
+ if (instance && size > 0) crMemcpy(instance->params, params, size);
+ return size;
+}
+
+int crdlm_pointers_RequestResidentProgramsNV(struct instanceRequestResidentProgramsNV *instance, GLsizei n, const GLuint *ids)
+{
+ unsigned int size = 4*sizeof(GLuint);
+ if (instance && size > 0) crMemcpy(instance->ids, ids, size);
+ return size;
+}
+
+int crdlm_pointers_LoadProgramNV(struct instanceLoadProgramNV *instance, GLenum target, GLuint id, GLsizei len, const GLubyte *program)
+{
+ unsigned int size = len*sizeof(GLubyte);
+ if (instance && size > 0) crMemcpy(instance->program, program, size);
+ return size;
+}
+
+int crdlm_pointers_ProgramNamedParameter4dNV(struct instanceProgramNamedParameter4dNV *instance, GLuint id, GLsizei len, const GLubyte * name, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+ unsigned int size = len * sizeof(GLubyte);
+ /* XXX */
+ return size;
+}
+
+int crdlm_pointers_ProgramNamedParameter4dvNV(struct instanceProgramNamedParameter4dvNV *instance, GLuint id, GLsizei len, const GLubyte * name, const GLdouble * v)
+{
+ unsigned int size = len * sizeof(GLubyte);
+ /* XXX */
+ return size;
+}
+
+int crdlm_pointers_ProgramNamedParameter4fNV(struct instanceProgramNamedParameter4fNV *instance, GLuint id, GLsizei len, const GLubyte * name, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ unsigned int size = len * sizeof(GLubyte);
+ /* XXX */
+ return size;
+}
+
+int crdlm_pointers_ProgramNamedParameter4fvNV(struct instanceProgramNamedParameter4fvNV *instance, GLuint id, GLsizei len, const GLubyte * name, const GLfloat * v)
+{
+ unsigned int size = len * sizeof(GLubyte);
+ /* XXX */
+ return size;
+}
+
+int crdlm_pointers_ProgramStringARB(struct instanceProgramStringARB *instance, GLenum target, GLenum format, GLsizei len, const GLvoid * string)
+{
+ unsigned int size = len*sizeof(GLubyte);
+ if (instance && size > 0) crMemcpy(instance->string, string, size);
+ return size;
+}
+
+int crdlm_pointers_CallLists(struct instanceCallLists *instance, GLsizei n, GLenum type, const GLvoid *lists )
+{
+ unsigned int size;
+ switch (type) {
+ case GL_BYTE:
+ size = sizeof(GLbyte);
+ break;
+ case GL_UNSIGNED_BYTE:
+ size = sizeof(GLubyte);
+ break;
+ case GL_SHORT:
+ size = sizeof(GLshort);
+ break;
+ case GL_UNSIGNED_SHORT:
+ size = sizeof(GLushort);
+ break;
+ case GL_INT:
+ size = sizeof(GLint);
+ break;
+ case GL_UNSIGNED_INT:
+ size = sizeof(GLuint);
+ break;
+ case GL_FLOAT:
+ size = sizeof(GLfloat);
+ break;
+ case GL_2_BYTES:
+ size = 2 * sizeof(GLbyte);
+ break;
+ case GL_3_BYTES:
+ size = 3 * sizeof(GLbyte);
+ break;
+ case GL_4_BYTES:
+ size = 4 * sizeof(GLbyte);
+ break;
+ default:
+ size = 0;
+ }
+ size *= n;
+ if (instance && size > 0) crMemcpy(instance->lists, lists, size);
+ return size;
+}
+
+
+int crdlm_pointers_VertexAttribs1dvNV(struct instanceVertexAttribs1dvNV *instance, GLuint index, GLsizei n, const GLdouble *v)
+{
+ return 1 * n * sizeof(GLdouble);
+}
+
+int crdlm_pointers_VertexAttribs1fvNV(struct instanceVertexAttribs1fvNV *instance, GLuint index, GLsizei n, const GLfloat *v)
+{
+ return 1 * n * sizeof(GLfloat);
+}
+
+int crdlm_pointers_VertexAttribs1svNV(struct instanceVertexAttribs1svNV *instance, GLuint index, GLsizei n, const GLshort *v)
+{
+ return 1 * n * sizeof(GLshort);
+}
+
+int crdlm_pointers_VertexAttribs2dvNV(struct instanceVertexAttribs2dvNV *instance, GLuint index, GLsizei n, const GLdouble *v)
+{
+ return 2 * n * sizeof(GLdouble);
+}
+
+int crdlm_pointers_VertexAttribs2fvNV(struct instanceVertexAttribs2fvNV *instance, GLuint index, GLsizei n, const GLfloat *v)
+{
+ return 2 * n * sizeof(GLfloat);
+}
+
+int crdlm_pointers_VertexAttribs2svNV(struct instanceVertexAttribs2svNV *instance, GLuint index, GLsizei n, const GLshort *v)
+{
+ return 2 * n * sizeof(GLshort);
+}
+
+int crdlm_pointers_VertexAttribs3dvNV(struct instanceVertexAttribs3dvNV *instance, GLuint index, GLsizei n, const GLdouble *v)
+{
+ return 3 * n * sizeof(GLdouble);
+}
+
+int crdlm_pointers_VertexAttribs3fvNV(struct instanceVertexAttribs3fvNV *instance, GLuint index, GLsizei n, const GLfloat *v)
+{
+ return 3 * n * sizeof(GLfloat);
+}
+
+int crdlm_pointers_VertexAttribs3svNV(struct instanceVertexAttribs3svNV *instance, GLuint index, GLsizei n, const GLshort *v)
+{
+ return 3 * n * sizeof(GLshort);
+}
+
+int crdlm_pointers_VertexAttribs4dvNV(struct instanceVertexAttribs4dvNV *instance, GLuint index, GLsizei n, const GLdouble *v)
+{
+ return 4 * n * sizeof(GLdouble);
+}
+
+int crdlm_pointers_VertexAttribs4fvNV(struct instanceVertexAttribs4fvNV *instance, GLuint index, GLsizei n, const GLfloat *v)
+{
+ return 4 * n * sizeof(GLfloat);
+}
+
+int crdlm_pointers_VertexAttribs4svNV(struct instanceVertexAttribs4svNV *instance, GLuint index, GLsizei n, const GLshort *v)
+{
+ return 4 * n * sizeof(GLshort);
+}
+
+int crdlm_pointers_VertexAttribs4ubvNV(struct instanceVertexAttribs4ubvNV *instance, GLuint index, GLsizei n, const GLubyte *v)
+{
+ return 4 * n * sizeof(GLubyte);
+}
+
+int crdlm_pointers_ZPixCR( struct instanceZPixCR *instance, GLsizei width,
+ GLsizei height, GLenum format, GLenum type,
+ GLenum ztype, GLint zparm, GLint length,
+ const GLvoid *pixels, CRClientState *c)
+{
+ unsigned int size = length;
+ if (instance && size > 0) {
+ crMemcpy(instance->pixels,pixels,length);
+ }
+
+ return size;
+}
+
+
+/*
+ * Prototypes for functions below are auto-generated and definded at out/<os.arch>/<build type>/obj/VBoxOGLgen/dlm_generated.h.
+ *
+ * All non-pointer structure fields are already assifned to *instance in out/<os.arch>/<build type>/obj/VBoxOGLgen/dlm_generated.c.
+ * Here we need to specify the additional size which is required to store data from pointers.
+ * This size will be added to sizeof(*instance) when dlm_generated.c will dynamically allocate memory for it. Also,
+ * data from pointers shouls be copied to *instance in case if instance != NULL. Each of functions below is called
+ * twice from dlm_generated.c:
+ * - first time with instance = NULL in order to get actual size of data provided by pointer
+ * - the second time with valid instance in order to copy data into it.
+ */
+
+int crdlm_pointers_BindAttribLocation(struct instanceBindAttribLocation *instance, GLuint program, GLuint index, const char * name)
+{
+ int cbExtraSpace = (name ? crStrlen(name) + 1 : 0);
+ if (instance && name && cbExtraSpace)
+ {
+ crMemcpy(instance->name, name, cbExtraSpace);
+ }
+
+ return cbExtraSpace;
+}
+
+int crdlm_pointers_DeleteFramebuffersEXT(struct instanceDeleteFramebuffersEXT *instance, GLsizei n, const GLuint * framebuffers)
+{
+ int cbExtraSpace = n * sizeof(GLuint);
+
+ if (instance && framebuffers && cbExtraSpace)
+ crMemcpy(instance->framebuffers, framebuffers, cbExtraSpace);
+
+ return cbExtraSpace;
+}
+
+int crdlm_pointers_DeleteRenderbuffersEXT(struct instanceDeleteRenderbuffersEXT *instance, GLsizei n, const GLuint * renderbuffers)
+{
+ int cbExtraSpace = n * sizeof(GLuint);
+
+ if (instance && renderbuffers && cbExtraSpace)
+ crMemcpy(instance->renderbuffers, renderbuffers, cbExtraSpace);
+
+ return cbExtraSpace;
+}
+
+int crdlm_pointers_DrawBuffers(struct instanceDrawBuffers *instance, GLsizei n, const GLenum* bufs)
+{
+ int cbExtraSpace = n * sizeof(GLenum);
+
+ if (instance && bufs && cbExtraSpace)
+ crMemcpy(instance->bufs, bufs, cbExtraSpace);
+
+ return cbExtraSpace;
+}
+
+int crdlm_pointers_ShaderSource(struct instanceShaderSource *instance, GLuint shader, GLsizei count, const char ** string, const GLint * length)
+{
+ int cbExtraSpace = 0;
+ int cbStrings = 0;
+ int cbLenghts = 0;
+ int i;
+
+ /* Calculate reported source code size. */
+ if (length && count)
+ for (i = 0; i < count; i++)
+ cbStrings += length[i] + /* termination character */ 1;
+
+ /* Calculate size of the rest of parameters. */
+ cbLenghts = count * sizeof(GLint);
+
+ /* Resulting size is a summ. */
+ cbExtraSpace = cbStrings + cbLenghts;
+
+ /* Copy data if requested. */
+ if (instance)
+ {
+ if (string && *string && cbStrings)
+ crMemcpy(instance->string, *string, cbStrings);
+ if (length && cbLenghts)
+ crMemcpy(instance->length, length, cbLenghts);
+ }
+
+ return cbExtraSpace;
+}
+
+int crdlm_pointers_StringMarkerGREMEDY(struct instanceStringMarkerGREMEDY *instance, GLsizei len, const GLvoid* string)
+{
+ /* @param len assumed to indicate string lenght in bytes. No termination character assumed. */
+ int cbExtraSpace = (string && len) ? len : 0;
+
+ if (instance && string && cbExtraSpace)
+ crMemcpy(instance->string, string, cbExtraSpace);
+
+ return cbExtraSpace;
+}
+
+/* Simplify things a bit. Use this macro instead of copy/paste to similar functions. */
+#define _VBOX_crdlm_pointers_UniformX(_uniformType) \
+ int cbExtraSpace = count * sizeof(_uniformType); \
+ if (instance && cbExtraSpace && value) \
+ crMemcpy(instance->value, value, cbExtraSpace); \
+ return cbExtraSpace;
+
+int crdlm_pointers_Uniform1fv(struct instanceUniform1fv *instance, GLint location, GLsizei count, const GLfloat * value)
+{
+ _VBOX_crdlm_pointers_UniformX(GLfloat);
+}
+
+int crdlm_pointers_Uniform1iv(struct instanceUniform1iv *instance, GLint location, GLsizei count, const GLint * value)
+{
+ _VBOX_crdlm_pointers_UniformX(GLint);
+}
+
+int crdlm_pointers_Uniform2fv(struct instanceUniform2fv *instance, GLint location, GLsizei count, const GLfloat * value)
+{
+ _VBOX_crdlm_pointers_UniformX(GLfloat);
+}
+
+int crdlm_pointers_Uniform2iv(struct instanceUniform2iv *instance, GLint location, GLsizei count, const GLint * value)
+{
+ _VBOX_crdlm_pointers_UniformX(GLint);
+}
+
+int crdlm_pointers_Uniform3fv(struct instanceUniform3fv *instance, GLint location, GLsizei count, const GLfloat * value)
+{
+ _VBOX_crdlm_pointers_UniformX(GLfloat);
+}
+
+int crdlm_pointers_Uniform3iv(struct instanceUniform3iv *instance, GLint location, GLsizei count, const GLint * value)
+{
+ _VBOX_crdlm_pointers_UniformX(GLint);
+}
+
+int crdlm_pointers_Uniform4fv(struct instanceUniform4fv *instance, GLint location, GLsizei count, const GLfloat * value)
+{
+ _VBOX_crdlm_pointers_UniformX(GLfloat);
+}
+
+int crdlm_pointers_Uniform4iv(struct instanceUniform4iv *instance, GLint location, GLsizei count, const GLint * value)
+{
+ _VBOX_crdlm_pointers_UniformX(GLint);
+}
+
+#undef crdlm_pointers_Uniform4iv
+
+/* Now do the same for UniformMatrix. */
+#define _VBOX_crdlm_pointers_UniformMatrixX(_uniformMatrixType) \
+ int cbExtraSpace = count * sizeof(_uniformMatrixType); \
+ if (instance && value && cbExtraSpace) \
+ crMemcpy(instance->value, value, cbExtraSpace); \
+ return cbExtraSpace;
+
+int crdlm_pointers_UniformMatrix2fv(struct instanceUniformMatrix2fv *instance, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ _VBOX_crdlm_pointers_UniformMatrixX(GLfloat);
+}
+
+int crdlm_pointers_UniformMatrix2x3fv(struct instanceUniformMatrix2x3fv *instance, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ _VBOX_crdlm_pointers_UniformMatrixX(GLfloat);
+}
+
+int crdlm_pointers_UniformMatrix2x4fv(struct instanceUniformMatrix2x4fv *instance, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ _VBOX_crdlm_pointers_UniformMatrixX(GLfloat);
+}
+
+int crdlm_pointers_UniformMatrix3fv(struct instanceUniformMatrix3fv *instance, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ _VBOX_crdlm_pointers_UniformMatrixX(GLfloat);
+}
+
+int crdlm_pointers_UniformMatrix3x2fv(struct instanceUniformMatrix3x2fv *instance, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ _VBOX_crdlm_pointers_UniformMatrixX(GLfloat);
+}
+
+int crdlm_pointers_UniformMatrix3x4fv(struct instanceUniformMatrix3x4fv *instance, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ _VBOX_crdlm_pointers_UniformMatrixX(GLfloat);
+}
+
+int crdlm_pointers_UniformMatrix4fv(struct instanceUniformMatrix4fv *instance, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ _VBOX_crdlm_pointers_UniformMatrixX(GLfloat);
+}
+
+int crdlm_pointers_UniformMatrix4x2fv(struct instanceUniformMatrix4x2fv *instance, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ _VBOX_crdlm_pointers_UniformMatrixX(GLfloat);
+}
+
+int crdlm_pointers_UniformMatrix4x3fv(struct instanceUniformMatrix4x3fv *instance, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+ _VBOX_crdlm_pointers_UniformMatrixX(GLfloat);
+}
+
+#undef _VBOX_crdlm_pointers_UniformMatrixX
+
+#if 0
+VBoxConCreate
+VBoxCreateContext
+VBoxPackSetInjectThread
+VBoxPresentComposition
+VBoxWindowCreate
+#endif
+
+int crdlm_pointers_VBoxConCreate(struct instanceVBoxConCreate *instance, struct VBOXUHGSMI * pHgsmi)
+{
+ CRASSERT(0);
+ return 0;
+}
+
+int crdlm_pointers_VBoxCreateContext(struct instanceVBoxCreateContext *instance, GLint con, const char * dpyName, GLint visual, GLint shareCtx)
+{
+ int cbExtraSpace = (dpyName ? crStrlen(dpyName) + 1 : 0);
+
+ if (instance && dpyName && cbExtraSpace)
+ crMemcpy(instance->dpyName, dpyName, cbExtraSpace);
+
+ return cbExtraSpace;
+}
+
+int crdlm_pointers_VBoxPackSetInjectThread(struct instanceVBoxPackSetInjectThread *instance, struct VBOXUHGSMI * pHgsmi)
+{
+ CRASSERT(0);
+ return 0;
+}
+
+int crdlm_pointers_VBoxPresentComposition(struct instanceVBoxPresentComposition *instance, GLint win,
+ const struct VBOXVR_SCR_COMPOSITOR * pCompositor, const struct VBOXVR_SCR_COMPOSITOR_ENTRY * pChangedEntry)
+{
+ CRASSERT(0);
+ return 0;
+}
+
+int crdlm_pointers_VBoxWindowCreate(struct instanceVBoxWindowCreate *instance, GLint con, const char * dpyName, GLint visBits)
+{
+ int cbExtraSpace = (dpyName ? crStrlen(dpyName) + 1 : 0);
+
+ if (instance && dpyName && cbExtraSpace)
+ crMemcpy(instance->dpyName, dpyName, cbExtraSpace);
+
+ return cbExtraSpace;
+}
diff --git a/src/VBox/HostServices/SharedOpenGL/dlm/dlm_pointers.h b/src/VBox/HostServices/SharedOpenGL/dlm/dlm_pointers.h
new file mode 100644
index 00000000..51ac2085
--- /dev/null
+++ b/src/VBox/HostServices/SharedOpenGL/dlm/dlm_pointers.h
@@ -0,0 +1,81 @@
+/* $Id: dlm_pointers.h $ */
+#include <VBoxUhgsmi.h>
+
+#include "cr_dlm.h"
+#include "dlm_generated.h"
+
+#ifndef _DLM_POINTERS_H
+#define _DLM_POINTERS_H
+
+extern int crdlm_pointers_Bitmap( struct instanceBitmap *instance, GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap, CRClientState *c);
+extern int crdlm_pointers_DrawPixels( struct instanceDrawPixels *instance, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c );
+extern int crdlm_pointers_Fogfv( struct instanceFogfv *instance, GLenum pname, const GLfloat *params );
+extern int crdlm_pointers_Fogiv( struct instanceFogiv *instance, GLenum pname, const GLint *params );
+extern int crdlm_pointers_LightModelfv( struct instanceLightModelfv *instance, GLenum pname, const GLfloat *params );
+extern int crdlm_pointers_LightModeliv( struct instanceLightModeliv *instance, GLenum pname, const GLint *params );
+extern int crdlm_pointers_Lightfv( struct instanceLightfv *instance, GLenum light, GLenum pname, const GLfloat *params );
+extern int crdlm_pointers_Lightiv( struct instanceLightiv *instance, GLenum light, GLenum pname, const GLint *params );
+extern int crdlm_pointers_Map1d( struct instanceMap1d *instance, GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points );
+extern int crdlm_pointers_Map1f( struct instanceMap1f *instance, GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points );
+extern int crdlm_pointers_Map2d( struct instanceMap2d *instance, GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points );
+extern int crdlm_pointers_Map2f( struct instanceMap2f *instance, GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points );
+extern int crdlm_pointers_Materialfv(struct instanceMaterialfv *instance, GLenum face, GLenum pname, const GLfloat *params);
+extern int crdlm_pointers_Materialiv(struct instanceMaterialiv *instance, GLenum face, GLenum pname, const GLint *params);
+extern int crdlm_pointers_PixelMapfv( struct instancePixelMapfv *instance, GLenum map, GLsizei mapsize, const GLfloat *values );
+extern int crdlm_pointers_PixelMapuiv( struct instancePixelMapuiv *instance, GLenum map, GLsizei mapsize, const GLuint *values );
+extern int crdlm_pointers_PixelMapusv( struct instancePixelMapusv *instance, GLenum map, GLsizei mapsize, const GLushort *values );
+extern int crdlm_pointers_PointParameterfvARB( struct instancePointParameterfvARB *instance, GLenum pname, const GLfloat *params);
+extern int crdlm_pointers_PointParameteriv( struct instancePointParameteriv *instance, GLenum pname, const GLint *params);
+extern int crdlm_pointers_TexEnvfv( struct instanceTexEnvfv *instance, GLenum target, GLenum pname, const GLfloat *params );
+extern int crdlm_pointers_TexEnviv( struct instanceTexEnviv *instance, GLenum target, GLenum pname, const GLint *params );
+extern int crdlm_pointers_TexGendv( struct instanceTexGendv *instance, GLenum coord, GLenum pname, const GLdouble *params );
+extern int crdlm_pointers_TexGenfv( struct instanceTexGenfv *instance, GLenum coord, GLenum pname, const GLfloat *params );
+extern int crdlm_pointers_TexGeniv( struct instanceTexGeniv *instance, GLenum coord, GLenum pname, const GLint *params );
+extern int crdlm_pointers_TexImage1D( struct instanceTexImage1D *instance, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c );
+extern int crdlm_pointers_CompressedTexImage1DARB(struct instanceCompressedTexImage1DARB *instance, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imagesize, const GLvoid *data);
+extern int crdlm_pointers_TexImage2D( struct instanceTexImage2D *instance, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c );
+extern int crdlm_pointers_CompressedTexImage2DARB(struct instanceCompressedTexImage2DARB *instance, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imagesize, const GLvoid *data);
+extern int crdlm_pointers_TexImage3D( struct instanceTexImage3D *instance, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c );
+extern int crdlm_pointers_TexImage3DEXT( struct instanceTexImage3DEXT *instance, GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c );
+extern int crdlm_pointers_CompressedTexImage3DARB(struct instanceCompressedTexImage3DARB *instance, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imagesize, const GLvoid *data);
+extern int crdlm_pointers_TexParameterfv( struct instanceTexParameterfv *instance, GLenum target, GLenum pname, const GLfloat *params );
+extern int crdlm_pointers_TexParameteriv( struct instanceTexParameteriv *instance, GLenum target, GLenum pname, const GLint *params );
+extern int crdlm_pointers_TexSubImage1D( struct instanceTexSubImage1D *instance, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c );
+extern int crdlm_pointers_TexSubImage2D( struct instanceTexSubImage2D *instance, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c );
+extern int crdlm_pointers_TexSubImage3D( struct instanceTexSubImage3D *instance, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c );
+extern int crdlm_pointers_CompressedTexSubImage1DARB(struct instanceCompressedTexSubImage1DARB *instance, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imagesize, const GLvoid *data);
+extern int crdlm_pointers_CompressedTexSubImage2DARB(struct instanceCompressedTexSubImage2DARB *instance, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imagesize, const GLvoid *data);
+extern int crdlm_pointers_CompressedTexSubImage3DARB(struct instanceCompressedTexSubImage3DARB *instance, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imagesize, const GLvoid *data);
+extern int crdlm_pointers_Rectdv(struct instanceRectdv *instance, const GLdouble *v1, const GLdouble *v2);
+extern int crdlm_pointers_Rectfv(struct instanceRectfv *instance, const GLfloat *v1, const GLfloat *v2);
+extern int crdlm_pointers_Rectiv(struct instanceRectiv *instance, const GLint *v1, const GLint *v2);
+extern int crdlm_pointers_Rectsv(struct instanceRectsv *instance, const GLshort *v1, const GLshort *v2);
+extern int crdlm_pointers_PrioritizeTextures(struct instancePrioritizeTextures *instance, GLsizei n, const GLuint *textures, const GLclampf *priorities);
+extern int crdlm_pointers_CombinerParameterivNV(struct instanceCombinerParameterivNV *instance, GLenum pname, const GLint *params);
+extern int crdlm_pointers_CombinerParameterfvNV(struct instanceCombinerParameterfvNV *instance, GLenum pname, const GLfloat *params);
+extern int crdlm_pointers_CombinerStageParameterfvNV(struct instanceCombinerStageParameterfvNV *instance, GLenum stage, GLenum pname, const GLfloat *params);
+extern int crdlm_pointers_ExecuteProgramNV(struct instanceExecuteProgramNV *instance, GLenum target, GLuint id, const GLfloat *params);
+extern int crdlm_pointers_RequestResidentProgramsNV(struct instanceRequestResidentProgramsNV *instance, GLsizei n, const GLuint *ids);
+extern int crdlm_pointers_LoadProgramNV(struct instanceLoadProgramNV *instance, GLenum target, GLuint id, GLsizei len, const GLubyte *program);
+extern int crdlm_pointers_ProgramNamedParameter4dNV(struct instanceProgramNamedParameter4dNV *instance, GLuint id, GLsizei len, const GLubyte * name, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+extern int crdlm_pointers_ProgramNamedParameter4dvNV(struct instanceProgramNamedParameter4dvNV *instance, GLuint id, GLsizei len, const GLubyte * name, const GLdouble * v);
+extern int crdlm_pointers_ProgramNamedParameter4fNV(struct instanceProgramNamedParameter4fNV *instance, GLuint id, GLsizei len, const GLubyte * name, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+extern int crdlm_pointers_ProgramNamedParameter4fvNV(struct instanceProgramNamedParameter4fvNV *instance, GLuint id, GLsizei len, const GLubyte * name, const GLfloat * v);
+extern int crdlm_pointers_ProgramStringARB(struct instanceProgramStringARB *instance, GLenum target, GLenum format, GLsizei len, const GLvoid * string);
+extern int crdlm_pointers_CallLists(struct instanceCallLists *instance, GLsizei n, GLenum type, const GLvoid *lists );
+extern int crdlm_pointers_VertexAttribs1dvNV(struct instanceVertexAttribs1dvNV *instance, GLuint index, GLsizei n, const GLdouble *v);
+extern int crdlm_pointers_VertexAttribs1fvNV(struct instanceVertexAttribs1fvNV *instance, GLuint index, GLsizei n, const GLfloat *v);
+extern int crdlm_pointers_VertexAttribs1svNV(struct instanceVertexAttribs1svNV *instance, GLuint index, GLsizei n, const GLshort *v);
+extern int crdlm_pointers_VertexAttribs2dvNV(struct instanceVertexAttribs2dvNV *instance, GLuint index, GLsizei n, const GLdouble *v);
+extern int crdlm_pointers_VertexAttribs2fvNV(struct instanceVertexAttribs2fvNV *instance, GLuint index, GLsizei n, const GLfloat *v);
+extern int crdlm_pointers_VertexAttribs2svNV(struct instanceVertexAttribs2svNV *instance, GLuint index, GLsizei n, const GLshort *v);
+extern int crdlm_pointers_VertexAttribs3dvNV(struct instanceVertexAttribs3dvNV *instance, GLuint index, GLsizei n, const GLdouble *v);
+extern int crdlm_pointers_VertexAttribs3fvNV(struct instanceVertexAttribs3fvNV *instance, GLuint index, GLsizei n, const GLfloat *v);
+extern int crdlm_pointers_VertexAttribs3svNV(struct instanceVertexAttribs3svNV *instance, GLuint index, GLsizei n, const GLshort *v);
+extern int crdlm_pointers_VertexAttribs4dvNV(struct instanceVertexAttribs4dvNV *instance, GLuint index, GLsizei n, const GLdouble *v);
+extern int crdlm_pointers_VertexAttribs4fvNV(struct instanceVertexAttribs4fvNV *instance, GLuint index, GLsizei n, const GLfloat *v);
+extern int crdlm_pointers_VertexAttribs4svNV(struct instanceVertexAttribs4svNV *instance, GLuint index, GLsizei n, const GLshort *v);
+extern int crdlm_pointers_VertexAttribs4ubvNV(struct instanceVertexAttribs4ubvNV *instance, GLuint index, GLsizei n, const GLubyte *v);
+extern int crdlm_pointers_ZPixCR( struct instanceZPixCR *instance, GLsizei width, GLsizei height, GLenum format, GLenum type, GLenum ztype, GLint zparm, GLint length, const GLvoid *pixels, CRClientState *c );
+
+#endif
diff --git a/src/VBox/HostServices/SharedOpenGL/dlm/dlm_special b/src/VBox/HostServices/SharedOpenGL/dlm/dlm_special
new file mode 100644
index 00000000..bcbd643e
--- /dev/null
+++ b/src/VBox/HostServices/SharedOpenGL/dlm/dlm_special
@@ -0,0 +1,21 @@
+# dlm_arrays.c: these have to be expanded out into
+# their components before being stored in a display list
+ArrayElement
+DrawArrays
+DrawElements
+DrawRangeElements
+MultiDrawArraysEXT
+MultiDrawElementsEXT
+
+# dlm_calllist.c: since the DLM can manage state stored
+# inside display lists, we can manage state updates for
+# these sorts of elements.
+#CallList
+#CallLists
+
+# Calls to be ignored.
+#VBoxConCreate
+#VBoxCreateContext
+#VBoxPackSetInjectThread
+#VBoxPresentComposition
+#VBoxWindowCreate
diff --git a/src/VBox/HostServices/SharedOpenGL/dlm/dlm_state.c b/src/VBox/HostServices/SharedOpenGL/dlm/dlm_state.c
new file mode 100644
index 00000000..341d62e6
--- /dev/null
+++ b/src/VBox/HostServices/SharedOpenGL/dlm/dlm_state.c
@@ -0,0 +1,280 @@
+/* $Id: dlm_state.c $ */
+/** @file
+ * Implementation of saving and restoring Display Lists.
+ */
+
+/*
+ * 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 "cr_mem.h"
+#include "cr_dlm.h"
+#include "dlm.h"
+#include "dlm_generated.h"
+
+#include "VBox/vmm/ssm.h"
+#include <iprt/errcore.h>
+
+
+typedef struct {
+
+ PSSMHANDLE pSSM;
+ uint32_t err;
+
+} CRDLMSaveListsCbArg;
+
+static void crDLMSaveListsCb(unsigned long key, void *pData1, void *pData2)
+{
+ DLMListInfo *pListInfo = (DLMListInfo*)pData1;
+ CRDLMSaveListsCbArg *pArg = (CRDLMSaveListsCbArg *)pData2;
+ PSSMHANDLE pSSM = pArg->pSSM;
+ DLMInstanceList *pInstance = pListInfo->first;
+ uint32_t cInstanceCheck = 0;
+ int32_t rc;
+
+ crDebug("Saving Display Lists: found ID=%u, numInstances=%d.", key, pListInfo->numInstances);
+
+ /* Store Display List length. */
+ rc = SSMR3PutU32(pSSM, pListInfo->numInstances);
+ if (RT_SUCCESS(rc))
+ {
+ /* Store Display List (guest) ID. */
+ rc = SSMR3PutU32(pSSM, (uint32_t)key);
+ if (RT_SUCCESS(rc))
+ {
+ /* Store each Display List item one by one. */
+ while (pInstance)
+ {
+ /* Let's count each list item and compare total number with pListInfo->numInstances.
+ * This is simple consistency check. */
+ cInstanceCheck++;
+
+ /* Store instance data size. */
+ rc = SSMR3PutU32(pSSM, (uint32_t)pInstance->cbInstance);
+ if (RT_SUCCESS(rc))
+ {
+ rc = SSMR3PutMem(pSSM, pInstance, pInstance->cbInstance);
+ if (RT_SUCCESS(rc))
+ {
+ /* We just stored all we need. Let's move on to the next list element. */
+ pInstance = pInstance->next;
+ continue;
+ }
+ }
+
+ crError("Saving Display Lists: can't store data.");
+
+ pArg->err = 1;
+ return;
+ }
+
+ if (cInstanceCheck == pListInfo->numInstances)
+ return;
+
+ crError("Saving Display Lists: list currupted.");
+ }
+ }
+
+ pArg->err = 1;
+}
+
+int32_t DLM_APIENTRY crDLMSaveState(CRDLM *dlm, PSSMHANDLE pSSM)
+{
+ uint32_t ui32;
+ int32_t rc;
+
+ CRDLMSaveListsCbArg arg;
+
+ arg.pSSM = pSSM;
+ arg.err = 0;
+
+ /* Save number of Display Lists assigned to current DLM context. */
+ ui32 = (uint32_t)crHashtableNumElements(dlm->displayLists);
+ rc = SSMR3PutU32(pSSM, ui32); AssertRCReturn(rc, rc);
+
+ crHashtableWalk(dlm->displayLists, crDLMSaveListsCb, (void *)&arg);
+
+ return arg.err == 0;
+}
+
+static VBoxDLMExecuteFn crDLMGetExecuteRoutine(VBoxDLOpCode opcode)
+{
+ if (opcode < VBOX_DL_OPCODE_MAX)
+ return g_VBoxDLMExecuteFns[opcode];
+
+ crError("Restoring Display Lists: Invalid opcode %u.", opcode);
+
+ return NULL;
+}
+
+static bool
+crDLMLoadListInstance(PSSMHANDLE pSSM, DLMListInfo *pListInfo, SPUDispatchTable *dispatchTable)
+{
+ uint32_t cbInstance = 0;
+ DLMInstanceList *pInstance;
+ int32_t rc;
+
+ /* Get Display List item size. */
+ rc = SSMR3GetU32(pSSM, &cbInstance);
+ if (RT_SUCCESS(rc))
+ {
+ /* Allocate memory for the item, initialize it and put into the list. */
+ pInstance = crCalloc(cbInstance);
+ if (pInstance)
+ {
+ crMemset(pInstance, 0, cbInstance);
+
+ rc = SSMR3GetMem(pSSM, pInstance, cbInstance); AssertRCReturn(rc, rc);
+ if (RT_SUCCESS(rc))
+ {
+ pInstance->execute = crDLMGetExecuteRoutine(pInstance->iVBoxOpCode);
+ if (pInstance->execute)
+ {
+ pInstance->execute(pInstance, dispatchTable);
+
+ pInstance->next = NULL;
+ pInstance->stateNext = NULL;
+ pInstance->cbInstance = cbInstance;
+
+ pListInfo->numInstances++;
+
+ if (!pListInfo->first)
+ pListInfo->first = pInstance;
+
+ if (pListInfo->last)
+ pListInfo->last->next = pInstance;
+
+ pListInfo->last = pInstance;
+
+ return true;
+ }
+ else
+ crError("Restoring Display Lists: unknown list item (opcode=%u).", pInstance->iVBoxOpCode);
+ }
+ else
+ crError("Restoring Display Lists: can't read list element size.");
+ }
+ else
+ crError("Restoring Display Lists: not enough memory, aborting.");
+ }
+ else
+ crError("Restoring Display Lists: saved state file might be corrupted.");
+
+ return false;
+}
+
+static bool
+crDLMLoadList(CRDLM *dlm, PSSMHANDLE pSSM, SPUDispatchTable *dispatchTable)
+{
+ uint32_t cElements = 0;
+ uint32_t idList = 0;
+ uint32_t i;
+ int32_t rc;
+
+ /* Restore Display List length. */
+ rc = SSMR3GetU32(pSSM, &cElements);
+ if (RT_SUCCESS(rc))
+ {
+ /* Restore Display List ID. */
+ rc = SSMR3GetU32(pSSM, &idList);
+ if (RT_SUCCESS(rc))
+ {
+ /* Initialize new list data and start recording it. */
+ DLMListInfo *pListInfo;
+
+ pListInfo = (DLMListInfo *)crCalloc(sizeof(DLMListInfo));
+ if (pListInfo)
+ {
+ GLuint hwid;
+
+ crMemset(pListInfo, 0, sizeof(DLMListInfo));
+
+ hwid = dispatchTable->GenLists(1);
+ if (hwid > 0)
+ {
+ bool fSuccess = true;
+ CRDLMContextState *pDLMContextState;
+
+ pListInfo->numInstances = 0;
+ pListInfo->stateFirst = pListInfo->stateLast = NULL;
+ pListInfo->hwid = hwid;
+
+ dispatchTable->NewList(hwid, GL_COMPILE);
+
+ /* Fake list state in order to prevent expando SPU from double caching. */
+ pDLMContextState = crDLMGetCurrentState();
+ pDLMContextState->currentListMode = GL_FALSE;
+
+ crDebug("Restoring Display Lists:\t%u elements to restore.", cElements);
+
+ /* Iterate over list instances. */
+ for (i = 0; i < cElements; i++)
+ {
+ fSuccess = crDLMLoadListInstance(pSSM, pListInfo, dispatchTable);
+ if (!fSuccess)
+ break;
+ }
+
+ dispatchTable->EndList();
+
+ if (fSuccess)
+ {
+ /* Add list to cache. */
+ crHashtableReplace(dlm->displayLists, idList, pListInfo, NULL);
+ return true;
+ }
+ else
+ crError("Restoring Display Lists: some elements could not be restored.");
+ }
+ else
+ crError("Restoring Display Lists: can't allocate hwid for list %u.", idList);
+
+ crFree(pListInfo);
+ }
+ else
+ crError("Restoring Display Lists: can't allocate memory.");
+ }
+ else
+ crError("Restoring Display Lists: can't get list ID.");
+ }
+ else
+ crError("Restoring Display Lists: can't get number of elements in list.");
+
+ return false;
+}
+
+
+bool DLM_APIENTRY
+crDLMLoadState(CRDLM *dlm, PSSMHANDLE pSSM, SPUDispatchTable *dispatchTable)
+{
+ uint32_t cLists = 0;
+ uint32_t i;
+ int32_t rc;
+ bool fSuccess = true;
+
+ /* Get number of Display Lists assigned to current DLM context. */
+ rc = SSMR3GetU32(pSSM, &cLists);
+ if (RT_SUCCESS(rc))
+ {
+ crDebug("Restoring Display Lists: %u lists to restore.", cLists);
+
+ for (i = 0; i < cLists; i++)
+ {
+ fSuccess = crDLMLoadList(dlm, pSSM, dispatchTable);
+ if (!fSuccess)
+ break;
+ }
+ }
+ else
+ crError("Restoring Display Lists: can't get number of lists.");
+
+ return fSuccess;
+}