378 lines
10 KiB
C
378 lines
10 KiB
C
/***************************************************************************\
|
|
* 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.
|
|
ASSERTOPENGL(!pa->aIndices, "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 = (ULONG) -1; // reset next DPA message offset
|
|
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;
|
|
|
|
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.
|
|
ASSERTOPENGL(!pa->aIndices, "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 = (ULONG) -1; // 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
|
|
|
|
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 != (GLubyte *) -1)
|
|
{
|
|
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 = (ULONG) -1;
|
|
|
|
#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
|