NT4/private/windows/opengl/client/subutil.c
2020-09-30 17:12:29 +02:00

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