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