|
|
/***************************************************************************\
* Module Name: subutil.c * * Section initialization code for client/server batching. * * Copyright (c) 1993-1996 Microsoft Corporation \***************************************************************************/
#include "precomp.h"
#pragma hdrstop
#include "glsbmsg.h"
#include "glgdimsg.h"
#include "batchinf.h"
#include "glsbcltu.h"
#include "wgldef.h"
#include "compsize.h"
#include "context.h"
#include "global.h"
#include "parray.h"
#include "lighting.h"
/******************************Public*Routine******************************\
* glsbAttentionAlt * * Calls glsbAttention() from the GLCLIENT_BEGIN macro. * It puts a null proc at the end of the current batch and flushes the batch. * * Returns the new message offset and updates pMsgBatchInfo->NextOffset. * This code is dependent on the GLCLIENT_BEGIN macro! * * History: * Thu Nov 11 18:02:26 1993 -by- Hock San Lee [hockl] * Wrote it. \**************************************************************************/
#ifdef CHECK_HEAP
PVOID AttnLastCaller = 0, AttnLastCallersCaller = 0; DWORD AttnCallThread = 0; #endif
ULONG APIENTRY glsbAttentionAlt(ULONG Offset) { GLMSGBATCHINFO *pMsgBatchInfo; ULONG MsgSize; PULONG pNullProcOffset; POLYARRAY *pa; POLYMATERIAL *pm;
#ifdef PRIMITIVE_TRACK
DbgPrint("*** glsbAttentionAlt\n"); #endif
pa = GLTEB_CLTPOLYARRAY(); pMsgBatchInfo = (GLMSGBATCHINFO *) pa->pMsgBatchInfo;
#ifdef CHECK_HEAP
AttnCallThread = GetCurrentThreadId(); RtlValidateHeap(RtlProcessHeap(), 0, 0); RtlGetCallersAddress(&AttnLastCaller, &AttnLastCallersCaller); #endif
if (Offset == pMsgBatchInfo->FirstOffset) return(pMsgBatchInfo->FirstOffset); // No messages, return
MsgSize = pMsgBatchInfo->NextOffset - Offset;
// If we are in the begin/end bracket, remove the invalid commands issued
// since the last Begin call.
if (pa->flags & POLYARRAY_IN_BEGIN) { // DrawElements should not cause a flush while building polydata's.
// pa->aIndices can be reset by VA_DrawElementsBegin, so allow
// this value as well.
ASSERTOPENGL( (!pa->aIndices || (pa->aIndices == PA_aIndices_INITIAL_VALUE)), "unexpected flush in DrawElements\n"); if (Offset == pa->nextMsgOffset) return(Offset); GLSETERROR(GL_INVALID_OPERATION); pMsgBatchInfo->NextOffset = pa->nextMsgOffset + MsgSize; return(pa->nextMsgOffset); }
#ifdef PRIMITIVE_TRACK
DbgPrint("! Reset on attention\n"); #endif
pa->pdBufferNext = pa->pdBuffer0; // reset vertex buffer pointer
pa->nextMsgOffset = PA_nextMsgOffset_RESET_VALUE; if (pm = GLTEB_CLTPOLYMATERIAL()) pm->iMat = 0; // reset material pointer
pNullProcOffset = (ULONG *)((BYTE *)pMsgBatchInfo + Offset); *pNullProcOffset = 0;
// #define POLYARRAY_CHECK_COLOR_POINTERS 1
#if POLYARRAY_CHECK_COLOR_POINTERS
{ POLYDATA *pd; for (pd = pa->pdBuffer0; pd < pa->pdBufferMax; pd++) { if (pd->color != &pd->colors[__GL_FRONTFACE]) DbgPrint("glsbAttentionAlt: pd 0x%x has modified color pointer\n", pd); } } #endif
(void) __wglAttention();
#if POLYARRAY_CHECK_COLOR_POINTERS
{ POLYDATA *pd; for (pd = pa->pdBuffer0; pd < pa->pdBufferMax; pd++) { if (pd->color != &pd->colors[__GL_FRONTFACE]) DbgPrint("glsbAttentionAlt: pd 0x%x has BAD color pointer\n", pd); } } #endif
pMsgBatchInfo->NextOffset = pMsgBatchInfo->FirstOffset + MsgSize; return(pMsgBatchInfo->FirstOffset); }
/******************************Public*Routine******************************\
* glsbAttention * * Let the server know that the section needs attention * * History: * 15-Oct-1993 -by- Gilman Wong [gilmanw] * Added bCheckRC flag. \**************************************************************************/
BOOL APIENTRY glsbAttention ( void ) { BOOL bRet = FALSE; GLMSGBATCHINFO *pMsgBatchInfo; PULONG pNullProcOffset; POLYARRAY *pa; POLYMATERIAL *pm; DWORD flags; __GL_SETUP();
pa = GLTEB_CLTPOLYARRAY(); pMsgBatchInfo = (GLMSGBATCHINFO *) pa->pMsgBatchInfo;
#ifdef CHECK_HEAP
AttnCallThread = GetCurrentThreadId(); RtlValidateHeap(RtlProcessHeap(), 0, 0); RtlGetCallersAddress(&AttnLastCaller, &AttnLastCallersCaller); #endif
if (pMsgBatchInfo->NextOffset == pMsgBatchInfo->FirstOffset) return(TRUE); // No messages, return
// If we are in the begin/end bracket, remove the invalid commands issued
// since the last Begin call.
if (pa->flags & POLYARRAY_IN_BEGIN) { // DrawElements should not cause a flush while building polydata's.
// pa->aIndices can be reset by VA_DrawElementsBegin, so allow
// the reset value as well.
ASSERTOPENGL( (!pa->aIndices || (pa->aIndices == PA_aIndices_INITIAL_VALUE)), "unexpected flush in DrawElements\n"); if (pMsgBatchInfo->NextOffset == pa->nextMsgOffset) return(TRUE); GLSETERROR(GL_INVALID_OPERATION); pMsgBatchInfo->NextOffset = pa->nextMsgOffset; return(TRUE); }
#ifdef PRIMITIVE_TRACK
DbgPrint("! Reset on attention\n"); #endif
pa->pdBufferNext = pa->pdBuffer0; // reset vertex buffer pointer
pa->nextMsgOffset = PA_nextMsgOffset_RESET_VALUE; // reset next DPA message offset
if (pm = GLTEB_CLTPOLYMATERIAL()) pm->iMat = 0; // reset material pointer
pNullProcOffset = (ULONG *)((BYTE *)pMsgBatchInfo + pMsgBatchInfo->NextOffset); *pNullProcOffset = 0;
#if POLYARRAY_CHECK_COLOR_POINTERS
{ POLYDATA *pd; for (pd = pa->pdBuffer0; pd < pa->pdBufferMax; pd++) { if (pd->color != &pd->colors[__GL_FRONTFACE]) DbgPrint("glsbAttention: pd 0x%x has modified color pointer\n", pd); } } #endif
bRet = __wglAttention();
#if POLYARRAY_CHECK_COLOR_POINTERS
{ POLYDATA *pd; for (pd = pa->pdBuffer0; pd < pa->pdBufferMax; pd++) { if (pd->color != &pd->colors[__GL_FRONTFACE]) DbgPrint("glsbAttention: pd 0x%x has BAD color pointer\n", pd); } } #endif
// Clear the Evaluator state flags
flags = GET_EVALSTATE (gc); flags = flags & ~(__EVALS_AFFECTS_1D_EVAL| __EVALS_AFFECTS_2D_EVAL| __EVALS_AFFECTS_ALL_EVAL| __EVALS_PUSH_EVAL_ATTRIB| __EVALS_POP_EVAL_ATTRIB); SET_EVALSTATE (gc, flags);
pMsgBatchInfo->NextOffset = pMsgBatchInfo->FirstOffset; return(bRet); }
/******************************Public*Routine******************************\
* glsbResetBuffers * * Reset the command buffer, the poly array buffer, and the poly material * buffer. * * History: * Tue Jan 09 17:38:22 1996 -by- Hock San Lee [hockl] * Wrote it. \**************************************************************************/
VOID APIENTRY glsbResetBuffers(BOOL bRestoreColorPointer) { GLMSGBATCHINFO *pMsgBatchInfo; POLYARRAY *pa; POLYMATERIAL *pm; GLMSG_DRAWPOLYARRAY *pMsgDrawPolyArray;
pa = GLTEB_CLTPOLYARRAY();
// Reset command buffer
pMsgBatchInfo = (GLMSGBATCHINFO *) pa->pMsgBatchInfo; pMsgBatchInfo->NextOffset = pMsgBatchInfo->FirstOffset;
#ifdef PRIMITIVE_TRACK
DbgPrint("! Reset on ResetBuffers\n"); #endif
#if POLYARRAY_CHECK_COLOR_POINTERS
{ POLYDATA *pd; for (pd = pa->pdBuffer0; pd < pa->pdBufferMax; pd++) { if (pd->color != &pd->colors[__GL_FRONTFACE]) DbgPrint("glsbResetBuffers: pd 0x%x has modified color pointer\n",pd); } } #endif
// In COMPILE mode, restore color pointer in the vertex buffer that
// may have been overwritten by the POLYARRAY structure. In normal
// and COMPILE_AND_EXECUTE modes, the server takes care of this.
// In addition, there can be no more than one DrawPolyArray command
// in the batch in COMPILE mode.
if (bRestoreColorPointer) { POLYARRAY *paCmd; POLYDATA *pd, *pdLast; // See also PolyArrayRestoreColorPointer
#if DBG
__GL_SETUP(); ASSERTOPENGL(gc->dlist.mode == GL_COMPILE, "not in compile mode\n"); #endif
pMsgDrawPolyArray = (GLMSG_DRAWPOLYARRAY *) ((BYTE *) pMsgBatchInfo + pa->nextMsgOffset - GLMSG_ALIGN(sizeof(GLMSG_DRAWPOLYARRAY))); paCmd = (POLYARRAY *) pMsgDrawPolyArray->paLast;
ASSERTOPENGL(pMsgDrawPolyArray->pa0 == pMsgDrawPolyArray->paLast && paCmd->paNext == NULL, "DrawPolyArray chain unexpected in COMPILE mode\n"); // Reset color pointer in output index array
if (paCmd->aIndices && (paCmd->aIndices != PA_aIndices_INITIAL_VALUE)) { pdLast = (POLYDATA *) (paCmd->aIndices + paCmd->nIndices); for (pd = (POLYDATA *) paCmd->aIndices; pd < pdLast; pd++) pd->color = &pd->colors[__GL_FRONTFACE];
ASSERTOPENGL(pd >= pa->pdBuffer0 && pd <= pa->pdBufferMax + 1, "bad polyarray pointer\n"); }
// Reset color pointer in the POLYARRAY structure last!
ASSERTOPENGL((POLYDATA *) paCmd >= pa->pdBuffer0 && (POLYDATA *) paCmd <= pa->pdBufferMax, "bad polyarray pointer\n"); ((POLYDATA *) paCmd)->color = &((POLYDATA *) paCmd)->colors[__GL_FRONTFACE]; }
// Reset material pointer
if (pm = GLTEB_CLTPOLYMATERIAL()) pm->iMat = 0;
// Reset vertex buffer pointer
pa->pdBufferNext = pa->pdBuffer0;
// Reset next DPA message offset
pa->nextMsgOffset = PA_nextMsgOffset_RESET_VALUE;
#if POLYARRAY_CHECK_COLOR_POINTERS
{ POLYDATA *pd; for (pd = pa->pdBuffer0; pd < pa->pdBufferMax; pd++) { if (pd->color != &pd->colors[__GL_FRONTFACE]) DbgPrint("glsbResetBuffers: pd 0x%x has BAD color pointer\n", pd); } } #endif
}
#if 0
// REWRITE THIS IF NEEDED
/******************************Public*Routine******************************\
* glsbMsgStats * * Batch area statistics. * * * History: \**************************************************************************/
BOOL APIENTRY glsbMsgStats ( LONG Action, GLMSGBATCHSTATS *BatchStats ) { #ifdef DOGLMSGBATCHSTATS
ULONG Result; GLMSGBATCHINFO *pMsgBatchInfo;
pMsgBatchInfo = GLTEB_SHAREDMEMORYSECTION();
if ( GLMSGBATCHSTATS_GETSTATS == Action ) { BatchStats->ClientCalls = pMsgBatchInfo->BatchStats.ClientCalls; } else { pMsgBatchInfo->BatchStats.ClientCalls = 0; }
// reset user's poll count so it counts this as output
// put it right next to BEGINMSG so that NtCurrentTeb() is optimized
RESETUSERPOLLCOUNT();
BEGINMSG( MSG_GLMSGBATCHSTATS, GLSBMSGSTATS ) pmsg->Action = Action;
Result = CALLSERVER();
if ( TRUE == Result ) { if ( GLMSGBATCHSTATS_GETSTATS == Action ) { BatchStats->ServerTrips = pmsg->BatchStats.ServerTrips; BatchStats->ServerCalls = pmsg->BatchStats.ServerCalls; } } else { DBGERROR("glsbMsgStats(): Server returned FALSE\n"); }
ENDMSG MSGERROR: return((BOOL)Result);
#else
return(FALSE);
#endif /* DOGLMSGBATCHSTATS */
} #endif // 0
|