windows-nt/Source/XPSP1/NT/multimedia/opengl/gls/lib/ctx.c

619 lines
20 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*
** Copyright 1995-2095, Silicon Graphics, Inc.
** All Rights Reserved.
**
** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
** the contents of this file may not be disclosed to third parties, copied or
** duplicated in any form, in whole or in part, without the prior written
** permission of Silicon Graphics, Inc.
**
** RESTRICTED RIGHTS LEGEND:
** Use, duplication or disclosure by the Government is subject to restrictions
** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
** rights reserved under the Copyright Laws of the United States.
*/
#include "glslib.h"
#include <stdlib.h>
#include <string.h>
/******************************************************************************
__GLScontext
******************************************************************************/
static GLvoid* __glsGLRCbuf_alloc(__GLSglrcBuf *inoutBuf, size_t inByteCount) {
GLvoid *base;
if (inoutBuf->base && inoutBuf->byteCount >= inByteCount) {
return inoutBuf->base;
}
if (base = __glsMalloc(inByteCount)) {
free(inoutBuf->base);
inoutBuf->base = base;
inoutBuf->byteCount = inByteCount;
}
return base;
}
GLvoid* __glsContext_allocFeedbackBuf(
__GLScontext *inoutContext, size_t inByteCount
) {
return __glsGLRCbuf_alloc(
&inoutContext->header.glrcs[inoutContext->currentGLRC].feedbackBuf,
inByteCount
);
}
GLvoid* __glsContext_allocSelectBuf(
__GLScontext *inoutContext, size_t inByteCount
) {
return __glsGLRCbuf_alloc(
&inoutContext->header.glrcs[inoutContext->currentGLRC].selectBuf,
inByteCount
);
}
#if __GL_EXT_vertex_array
GLvoid* __glsContext_allocVertexArrayBuf(
__GLScontext *inoutContext, GLSopcode inOpcode, size_t inByteCount
) {
__GLSglrcBuf *buf;
__GLSglrc *const glrc = (
inoutContext->header.glrcs + inoutContext->currentGLRC
);
switch (inOpcode) {
case GLS_OP_glColorPointerEXT:
buf = &glrc->colorBuf;
break;
case GLS_OP_glEdgeFlagPointerEXT:
buf = &glrc->edgeFlagBuf;
break;
case GLS_OP_glIndexPointerEXT:
buf = &glrc->indexBuf;
break;
case GLS_OP_glNormalPointerEXT:
buf = &glrc->normalBuf;
break;
case GLS_OP_glTexCoordPointerEXT:
buf = &glrc->texCoordBuf;
break;
case GLS_OP_glVertexPointerEXT:
buf = &glrc->vertexBuf;
break;
default:
return GLS_NONE;
}
return __glsGLRCbuf_alloc(buf, inByteCount);
}
#endif /* __GL_EXT_vertex_array */
__GLScontext* __glsContext_create(GLuint inName) {
const GLubyte *listSep;
GLSopcode op;
__GLScontext *const outContext = __glsCalloc(1, sizeof(__GLScontext));
GLubyte *prefixPtr;
__GLSlistString *readPrefix;
if (!outContext) return GLS_NONE;
outContext->blockType = GLS_FRAME;
for (op = 0 ; op < __GLS_OPCODE_COUNT ; ++op) {
outContext->captureFlags[op] = GLS_CAPTURE_WRITE_BIT;
}
outContext->captureFlags[GLS_OP_glsBeginGLS] = GLS_NONE;
outContext->captureFlags[GLS_OP_glsEndGLS] = GLS_NONE;
outContext->captureFlags[GLS_OP_glsPad] = GLS_NONE;
__glsString_init(&outContext->returnString);
__glsString_init(&outContext->savedLocale);
if (!__glsHeader_init(&outContext->header)) {
return __glsContext_destroy(outContext);
}
outContext->contextStreamDict = __glsStrDict_create(1, GL_FALSE);
if (!outContext->contextStreamDict) {
return __glsContext_destroy(outContext);
}
outContext->currentGLRC = 1;
outContext->defaultReadChannel = stdin;
outContext->defaultWriteChannel = stdout;
listSep = glsCSTR(getenv("GLS_LIST_SEPARATOR"));
outContext->name = inName;
outContext->pixelSetupGen = GL_TRUE;
#if __GLS_PLATFORM_WIN32
// DrewB
outContext->captureExecOverride = GL_FALSE;
#endif
if (!listSep) listSep = glsCSTR(":");
if (prefixPtr = glsSTR(getenv("GLS_READ_PREFIX_LIST"))) {
__GLSstring prefixString;
__glsString_init(&prefixString);
if (!__glsString_append(&prefixString, prefixPtr)) {
__glsString_final(&prefixString);
return __glsContext_destroy(outContext);
}
prefixPtr = prefixString.head;
while (
prefixPtr = glsSTR(
strtok((char *)prefixPtr, (const char *)listSep)
)
) {
readPrefix = __glsListString_create(prefixPtr);
if (!readPrefix) {
__glsString_final(&prefixString);
return __glsContext_destroy(outContext);
}
__GLS_ITERLIST_APPEND(&outContext->readPrefixList, readPrefix);
prefixPtr = GLS_NONE;
}
__glsString_final(&prefixString);
}
readPrefix = __glsListString_create(glsCSTR(""));
if (!readPrefix) return __glsContext_destroy(outContext);
__GLS_ITERLIST_APPEND(&outContext->readPrefixList, readPrefix);
outContext->writePrefix = __glsListString_create(
glsCSTR(getenv("GLS_WRITE_PREFIX"))
);
if (!outContext->writePrefix) return __glsContext_destroy(outContext);
__glsContext_updateDispatchTables(outContext);
return outContext;
}
__GLScontext* __glsContext_destroy(__GLScontext *inContext) {
GLint i;
if (!inContext) return GLS_NONE;
__glsStrDict_destroy(inContext->contextStreamDict);
__GLS_ITERLIST_CLEAR_DESTROY(
&inContext->contextStreamList, __glsContextStream_destroy
);
__glsHeader_final(&inContext->header);
__GLS_ITERLIST_CLEAR_DESTROY(
&inContext->readPrefixList, __glsListString_destroy
);
__glsString_final(&inContext->returnString);
__glsString_final(&inContext->savedLocale);
for (i = 0 ; i < inContext->captureNesting ; ++i) {
__glsWriter_destroy(inContext->writers[i]);
}
__glsListString_destroy(inContext->writePrefix);
free(inContext);
return GLS_NONE;
}
#ifndef __GLS_PLATFORM_WIN32
// DrewB
static void __glsNullDecodeBinFunc(GLubyte *inoutPtr) {
}
#else
static void __glsNullDecodeBinFunc(__GLScontext *ctx, GLubyte *inoutPtr) {
}
#endif
void __glsContext_updateDispatchDecode_bin(__GLScontext *inoutContext) {
GLSopcode op;
if (inoutContext->abortMode) {
for (op = 0 ; op < __GLS_OPCODE_COUNT ; ++op) {
inoutContext->dispatchDecode_bin[op] = __glsNullDecodeBinFunc;
}
} else {
for (op = 0 ; op < __GLS_OPCODE_COUNT ; ++op) {
__GLSdecodeBinFunc decode = __glsDispatchDecode_bin_default[op];
if (decode) {
inoutContext->dispatchDecode_bin[op] = decode;
} else {
inoutContext->dispatchDecode_bin[op] = (
(__GLSdecodeBinFunc)inoutContext->dispatchCall[op]
);
}
}
}
}
void __glsContext_updateDispatchTables(__GLScontext *inoutContext) {
GLSopcode op;
if (inoutContext->captureNesting) {
for (op = 0 ; op < __GLS_OPCODE_COUNT ; ++op) {
inoutContext->dispatchAPI[op] = (GLSfunc)__glsDispatchCapture[op];
}
} else {
for (op = 0 ; op < __GLS_OPCODE_COUNT ; ++op) {
inoutContext->dispatchAPI[op] = __glsDispatchExec[op];
}
}
for (op = 0 ; op < __GLS_OPCODE_COUNT ; ++op) {
const GLSfunc commandFunc = inoutContext->commandFuncs[op];
if (commandFunc) {
inoutContext->dispatchCall[op] = commandFunc;
} else {
inoutContext->dispatchCall[op] = inoutContext->dispatchAPI[op];
}
}
__glsContext_updateDispatchDecode_bin(inoutContext);
__glsUpdateDispatchTables();
}
/******************************************************************************
__GLScontextStream
******************************************************************************/
__GLScontextStream* __glsContextStream_create(const GLubyte *inName) {
__GLScontextStream *const outStream = __glsCalloc(
1, sizeof(__GLScontextStream)
);
__GLScontextStreamBlock *block;
if (!outStream) return GLS_NONE;
__glsString_init(&outStream->name);
if (!__glsString_append(&outStream->name, inName)) {
return __glsContextStream_destroy(outStream);
}
block = __glsContextStream_appendBlock(outStream, __GLS_JUMP_ALLOC);
if (!block) return __glsContextStream_destroy(outStream);
__glsContextStreamBlock_addJump(block, GLS_NONE);
return outStream;
}
__GLScontextStream* __glsContextStream_destroy(__GLScontextStream *inStream) {
if (!inStream) return GLS_NONE;
__glsString_final(&inStream->name);
__GLS_LIST_CLEAR_DESTROY(
&inStream->blockList, __glsContextStreamBlock_destroy
);
free(inStream);
return GLS_NONE;
}
__GLScontextStreamBlock* __glsContextStream_appendBlock(
__GLScontextStream *inoutStream, size_t inBufSize
) {
__GLScontextStreamBlock *const outBlock = (
__glsContextStreamBlock_create(inBufSize)
);
__GLS_LIST_APPEND(&inoutStream->blockList, outBlock);
return outBlock;
}
#ifndef __GLS_PLATFORM_WIN32
// DrewB
#define __GLS_CONTEXT_STREAM_CALL_STEP \
if (word = *(GLuint *)pc) { \
dispatchDecode[__GLS_OP_SMALL(word)](pc + 4); \
pc += __GLS_COUNT_SMALL(word) << 2; \
} else if (word = __GLS_HEAD_LARGE(pc)->opLarge) { \
dispatchDecode[word](pc + 12); \
pc += __GLS_HEAD_LARGE(pc)->countLarge << 2; \
} else { \
pc = __GLS_COMMAND_JUMP(pc)->dest; \
if (!pc || __GLS_CONTEXT->abortMode) break; \
}
#else
#define __GLS_CONTEXT_STREAM_CALL_STEP \
if (word = *(GLuint *)pc) { \
dispatchDecode[__GLS_OP_SMALL(word)](ctx, pc + 4); \
pc += __GLS_COUNT_SMALL(word) << 2; \
} else if (word = __GLS_HEAD_LARGE(pc)->opLarge) { \
dispatchDecode[word](ctx, pc + 12); \
pc += __GLS_HEAD_LARGE(pc)->countLarge << 2; \
} else { \
pc = __GLS_COMMAND_JUMP(pc)->dest; \
if (!pc || __GLS_CONTEXT->abortMode) break; \
}
#endif
void __glsContextStream_call(__GLScontextStream *inoutStream) {
GLboolean callSave;
__GLScontext *const ctx = __GLS_CONTEXT;
__GLSdecodeBinFunc *const dispatchDecode = ctx->dispatchDecode_bin;
GLubyte *pc = inoutStream->blockList.head->buf;
GLuint word;
++inoutStream->callCount;
callSave = ctx->contextCall;
ctx->contextCall = GL_TRUE;
for (;;) {
__GLS_CONTEXT_STREAM_CALL_STEP
__GLS_CONTEXT_STREAM_CALL_STEP
__GLS_CONTEXT_STREAM_CALL_STEP
__GLS_CONTEXT_STREAM_CALL_STEP
}
ctx->contextCall = callSave;
if (!--inoutStream->callCount && inoutStream->deleted) {
__glsContextStream_destroy(inoutStream);
}
}
__GLScontextStreamBlock* __glsContextStream_firstBlock(
__GLScontextStream *inoutStream
) {
return inoutStream->blockList.head;
}
size_t __glsContextStream_getByteCount(__GLScontextStream *inoutStream) {
__GLScontextStreamBlockIter iter;
size_t outVal = 0;
__GLS_LIST_FIRST(&inoutStream->blockList, &iter);
while (iter.elem) {
outVal += (size_t)(iter.elem->writeTail - iter.elem->buf);
if (__glsContextStreamBlock_hasJump(iter.elem)) {
outVal -= sizeof(__GLSbinCommand_jump);
}
__GLS_LIST_NEXT(&inoutStream->blockList, &iter);
}
return outVal;
}
GLuint __glsContextStream_getCRC32(__GLScontextStream *inoutStream) {
__GLScontextStreamBlockIter iter;
GLuint outVal = 0xffffffff;
GLubyte *ptr, *tail;
__GLS_LIST_FIRST(&inoutStream->blockList, &iter);
while (iter.elem) {
ptr = iter.elem->buf;
tail = iter.elem->writeTail;
if (__glsContextStreamBlock_hasJump(iter.elem)) {
tail -= sizeof(__GLSbinCommand_jump);
}
while (ptr < tail) __GLS_CRC32_STEP(outVal, *ptr++);
__GLS_LIST_NEXT(&inoutStream->blockList, &iter);
}
return ~outVal;
}
__GLScontextStreamBlock* __glsContextStream_lastBlock(
__GLScontextStream *inoutStream
) {
__GLScontextStreamBlockIter iter;
__GLS_LIST_LAST(&inoutStream->blockList, &iter);
return iter.elem;
}
void __glsContextStream_truncate(
__GLScontextStream *inoutStream,
__GLScontextStreamBlock *inBlock,
size_t inOffset
) {
__GLScontextStreamBlockIter iter;
inBlock->writeTail = inBlock->buf + inOffset;
__glsContextStreamBlock_addJump(inBlock, GLS_NONE);
if (inBlock->writeTail < inBlock->bufTail) {
const size_t fillBytes = (size_t)(inBlock->writeTail - inBlock->buf);
GLubyte *const buf = __glsMalloc(fillBytes);
if (buf) {
size_t i;
for (i = 0 ; i < fillBytes ; ++i) buf[i] = inBlock->buf[i];
free(inBlock->buf);
inBlock->buf = buf;
inBlock->bufTail = inBlock->writeTail = buf + fillBytes;
iter.elem = inBlock;
__GLS_LIST_PREV(&inoutStream->blockList, &iter);
if (iter.elem) {
__glsContextStreamBlock_removeJump(iter.elem);
__glsContextStreamBlock_addJump(iter.elem, buf);
}
}
}
__GLS_LIST_LAST(&inoutStream->blockList, &iter);
while (iter.elem != inBlock) {
__GLScontextStreamBlock *const block = iter.elem;
__GLS_LIST_PREV(&inoutStream->blockList, &iter);
__GLS_LIST_REMOVE_DESTROY(
&inoutStream->blockList, block, __glsContextStreamBlock_destroy
);
}
}
__GLScontextStreamBlock* __glsContextStreamBlock_create(size_t inBufSize) {
__GLScontextStreamBlock *const outBlock = (
__glsCalloc(1, sizeof(__GLScontextStreamBlock))
);
if (!outBlock) return GLS_NONE;
outBlock->buf = __glsMalloc(inBufSize);
if (!outBlock->buf) return __glsContextStreamBlock_destroy(outBlock);
outBlock->bufTail = outBlock->buf + inBufSize;
outBlock->writeTail = outBlock->buf;
return outBlock;
}
__GLScontextStreamBlock* __glsContextStreamBlock_destroy(
__GLScontextStreamBlock *inBlock
) {
if (!inBlock) return GLS_NONE;
free(inBlock->buf);
free(inBlock);
return GLS_NONE;
}
GLboolean __glsContextStreamBlock_addJump(
__GLScontextStreamBlock *inoutBlock, GLubyte *inDest
) {
__GLSbinCommand_jump *jump;
const size_t wordCount = (
((size_t)(inoutBlock->writeTail - inoutBlock->buf)) >> 2
);
if ((wordCount & 1) && !__glsContextStreamBlock_addPad(inoutBlock)) {
return GL_FALSE;
}
jump = (__GLSbinCommand_jump *)inoutBlock->writeTail;
if (inoutBlock->writeTail + sizeof(*jump) > inoutBlock->bufTail) {
return GL_FALSE;
}
jump->head.opSmall = GLS_NONE;
jump->head.countSmall = 0;
jump->head.opLarge = GLS_NONE;
jump->head.countLarge = 0;
jump->pad = 0;
jump->dest = inDest;
inoutBlock->writeTail += sizeof(*jump);
return GL_TRUE;
}
GLboolean __glsContextStreamBlock_addPad(__GLScontextStreamBlock *inoutBlock) {
__GLSbinCommand_pad *const pad = (
(__GLSbinCommand_pad *)inoutBlock->writeTail
);
if (inoutBlock->writeTail + sizeof(*pad) > inoutBlock->bufTail) {
return GL_FALSE;
}
pad->head.opSmall = GLS_OP_glsPad;
pad->head.countSmall = 1;
inoutBlock->writeTail += sizeof(*pad);
return GL_TRUE;
}
GLboolean __glsContextStreamBlock_hasJump(__GLScontextStreamBlock *inBlock) {
GLubyte *const jumpPos = (
inBlock->writeTail - sizeof(__GLSbinCommand_jump)
);
__GLSbinCommand_jump *const jump = (__GLSbinCommand_jump *)jumpPos;
return (GLboolean)(
jumpPos >= inBlock->buf &&
!jump->head.opSmall &&
!jump->head.countSmall &&
!jump->head.opLarge &&
!jump->head.countLarge &&
!jump->pad
);
}
GLboolean __glsContextStreamBlock_removeJump(
__GLScontextStreamBlock *inoutBlock
) {
if (__glsContextStreamBlock_hasJump(inoutBlock)) {
inoutBlock->writeTail -= sizeof(__GLSbinCommand_jump);
return GL_TRUE;
} else {
return GL_FALSE;
}
}
/******************************************************************************
__GLSglrc
******************************************************************************/
void __glsGLRC_final(__GLSglrc *inoutGLRC) {
free(inoutGLRC->feedbackBuf.base);
free(inoutGLRC->selectBuf.base);
#if __GL_EXT_vertex_array
free(inoutGLRC->colorBuf.base);
free(inoutGLRC->edgeFlagBuf.base);
free(inoutGLRC->indexBuf.base);
free(inoutGLRC->normalBuf.base);
free(inoutGLRC->texCoordBuf.base);
free(inoutGLRC->vertexBuf.base);
#endif /* __GL_EXT_vertex_array */
}
void __glsGLRC_init(__GLSglrc *outGLRC) {
memset(outGLRC, 0, sizeof(__GLSglrc));
outGLRC->layer = 1;
}
/******************************************************************************
__GLSlayer
******************************************************************************/
void __glsLayer_init(__GLSlayer *outLayer) {
memset(outLayer, 0, sizeof(__GLSlayer));
outLayer->displayFormat = GLS_RGBA;
}
/******************************************************************************
__GLSheader
******************************************************************************/
void __glsHeader_final(__GLSheader *inoutHeader) {
while (inoutHeader->glrcCount > 0) {
__glsGLRC_final(inoutHeader->glrcs + --inoutHeader->glrcCount);
}
free(inoutHeader->glrcs);
free(inoutHeader->layers);
__glsString_final(&inoutHeader->extensions);
__glsString_final(&inoutHeader->author);
__glsString_final(&inoutHeader->description);
__glsString_final(&inoutHeader->notes);
__glsString_final(&inoutHeader->title);
__glsString_final(&inoutHeader->tools);
__glsString_final(&inoutHeader->version);
}
GLboolean __glsHeader_init(__GLSheader *outHeader) {
memset(outHeader, 0, sizeof(__GLSheader));
outHeader->glrcs = __glsMalloc(sizeof(__GLSglrc));
outHeader->layers = __glsMalloc(sizeof(__GLSlayer));
if (!outHeader->glrcs || !outHeader->layers) return GL_FALSE;
__glsGLRC_init(outHeader->glrcs);
__glsLayer_init(outHeader->layers);
outHeader->glrcCount = 1;
outHeader->layerCount = 1;
outHeader->tileable = GL_TRUE;
__glsString_init(&outHeader->extensions);
__glsString_init(&outHeader->author);
__glsString_init(&outHeader->description);
__glsString_init(&outHeader->notes);
__glsString_init(&outHeader->title);
__glsString_init(&outHeader->tools);
__glsString_init(&outHeader->version);
return GL_TRUE;
}
GLboolean __glsHeader_reset(__GLSheader *inoutHeader) {
__glsHeader_final(inoutHeader);
return __glsHeader_init(inoutHeader);
}
/******************************************************************************
__GLSlistString
******************************************************************************/
GLboolean __glsListString_prefix(
const __GLSlistString *inString,
const GLubyte *inName,
__GLSstring *outPath
) {
if (
__glsString_assign(outPath, inString->val.head) &&
__glsString_append(outPath, inName)
) {
return GL_TRUE;
} else {
__glsString_reset(outPath);
return GL_FALSE;
}
}
__GLSlistString* __glsListString_create(const GLubyte *inVal) {
__GLSlistString *const outString = __glsCalloc(1, sizeof(__GLSlistString));
if (!outString) return GLS_NONE;
__glsString_init(&outString->val);
if (inVal && !__glsString_append(&outString->val, inVal)) {
return __glsListString_destroy(outString);
}
return outString;
}
__GLSlistString* __glsListString_destroy(__GLSlistString *inString) {
if (!inString) return GLS_NONE;
__glsString_final(&inString->val);
free(inString);
return GLS_NONE;
}