/* $Id: expandospu.c 54905 2015-03-23 11:20:58Z vboxsync $ */ /* Copyright (c) 2001, Stanford University * All rights reserved * * See the file LICENSE.txt for information on redistributing this software. */ #include #include "cr_spu.h" #include "cr_dlm.h" #include "cr_mem.h" #include "expandospu.h" extern GLint EXPANDOSPU_APIENTRY expandoCreateContext(const char *displayName, GLint visBits, GLint shareCtx) { ExpandoContextState *contextState; GLint contextId; /* Allocate our own per-context record */ contextState = crCalloc(sizeof(ExpandoContextState)); if (contextState == NULL) { crError("expando: couldn't allocate per-context state"); return 0; } /* Get an official context ID from our super */ contextId = expando_spu.super.CreateContext(displayName, visBits, shareCtx); /* Supplement that with our DLM. In a more correct situation, we should * see if we've been called through glXCreateContext, which has a parameter * for sharing DLMs. We don't currently get that information, so for now * give each context its own DLM. */ contextState->dlm = crDLMNewDLM(0, NULL); if (!contextState->dlm) { crError("expando: couldn't get DLM!"); } contextState->dlmContext = crDLMNewContext(contextState->dlm); if (!contextState->dlmContext) { crError("expando: couldn't get dlmContext"); } /* The DLM needs us to use the state tracker to track client * state, so we can compile client-state-using functions correctly. */ contextState->State = crStateCreateContext(NULL, visBits, NULL); /* Associate the Expando context with the user context. */ crHashtableAdd(expando_spu.contextTable, contextId, (void *)contextState); return contextId; } void expando_free_context_state(void *data) { ExpandoContextState *expandoContextState = (ExpandoContextState *)data; crDLMFreeContext(expandoContextState->dlmContext); crDLMFreeDLM(expandoContextState->dlm); crStateDestroyContext(expandoContextState->State); crFree(expandoContextState); } extern void EXPANDOSPU_APIENTRY expandoDestroyContext(GLint contextId) { /* Destroy our context information */ crHashtableDelete(expando_spu.contextTable, contextId, expando_free_context_state); /* Pass along the destruction to our super. */ expando_spu.super.DestroyContext(contextId); } extern void EXPANDOSPU_APIENTRY expandoMakeCurrent(GLint crWindow, GLint nativeWindow, GLint contextId) { ExpandoContextState *expandoContextState; expando_spu.super.MakeCurrent(crWindow, nativeWindow, contextId); expandoContextState = crHashtableSearch(expando_spu.contextTable, contextId); if (expandoContextState) { crDLMSetCurrentState(expandoContextState->dlmContext); crStateMakeCurrent(expandoContextState->State); } else { crDLMSetCurrentState(NULL); crStateMakeCurrent(NULL); } } extern void EXPANDOSPU_APIENTRY expandoNewList(GLuint list, GLenum mode) { crDebug("Expando SPU: expandoNewList()"); crDLMNewList(list, mode); } extern void EXPANDOSPU_APIENTRY expandoEndList(void) { crDebug("Expando SPU: expandoEndList()"); crDLMEndList(); } extern void EXPANDOSPU_APIENTRY expandoDeleteLists(GLuint first, GLsizei range) { crDLMDeleteLists(first, range); } extern GLuint EXPANDOSPU_APIENTRY expandoGenLists(GLsizei range) { return crDLMGenLists(range); } extern GLboolean EXPANDOSPU_APIENTRY expandoIsList(GLuint list) { return crDLMIsList(list); } extern void EXPANDOSPU_APIENTRY expandoCallList(GLuint list) { GLenum mode = crDLMGetCurrentMode(); if (mode != GL_FALSE) { crDLMCompileCallList(list); if (mode == GL_COMPILE) return; } /* Instead of passing through the CallList, * expand it into its components. This will cause * a recursion if there are any compiled CallList * elements within the display list. */ crDLMReplayList(list, &expando_spu.self); } extern void EXPANDOSPU_APIENTRY expandoCallLists(GLsizei n, GLenum type, const GLvoid *lists) { GLenum mode = crDLMGetCurrentMode(); if (mode != GL_FALSE) { crDLMCompileCallLists(n, type, lists); if (mode == GL_COMPILE) return; } /* Instead of passing through the CallLists, * expand it into its components. This will cause * a recursion if there are any compiled CallLists * elements within the display list. */ crDLMReplayLists(n, type, lists, &expando_spu.self); }