NT4/private/windows/opengl/server/inc/context.h
2020-09-30 17:12:29 +02:00

718 lines
26 KiB
C

#ifndef __glcontext_h_
#define __glcontext_h_
/*
** Copyright 1991, 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.
**
** Graphics context structures.
*/
#include "os.h"
#include "attrib.h"
#include "feedback.h"
#include "select.h"
#include "buffers.h"
#include "pixel.h"
#include "dlist.h"
#include "xform.h"
#include "render.h"
#include "glinterf.h"
#include "dispatch.h"
#include "parray.h"
#include "procs.h"
#include "gldrv.h"
#include "glarray.h"
// Disable long to float conversion warning. see also gencx.h
#pragma warning (disable:4244)
/*
** Various constants. Most of these will never change through the life
** of the context.
*/
typedef struct __GLcontextConstantsRec {
#ifdef NT_DEADCODE_CONSTANTS
__GLfloat half;
__GLfloat one;
__GLfloat val255;
__GLfloat oneOver255;
__GLfloat val65535;
__GLfloat oneOver65535;
/*
** Not quite 2^31-1 because of possible floating point errors. 4294965000
** is a much safer number to use.
*/
__GLfloat val4294965000;
__GLfloat oneOver4294965000;
#endif // NT_DEADCODE_CONSTANTS
#ifdef NT_DEADCODE_GETSTRING
/* Stuff for glGetString */
char *vendor;
char *renderer;
char *version;
char *extensions;
#endif // NT_DEADCODE_GETSTRING
/* Specific size limits */
GLint numberOfLights;
GLint numberOfClipPlanes;
GLint numberOfTextures;
GLint numberOfTextureEnvs;
GLint maxViewportWidth;
GLint maxViewportHeight;
/*
** Viewport offsets: These numbers are added to the viewport center
** values to adjust the computed window coordinates into a
** numerically well behaved space (fixed point represented in a
** floating point number).
*/
GLint viewportXAdjust;
GLint viewportYAdjust;
__GLfloat fviewportXAdjust;
__GLfloat fviewportYAdjust;
/*
** These values are computed from viewportXAdjust when the context
** is created. It is assumed that x and y are forced into the same
** fixed point range by viewportXAdjust and viewportYAdjust.
**
** viewportEpsilon is computed as the smallest possible value that can
** be represented in that fixed point space.
**
** viewportAlmostHalf is equal to 0.5 - viewportEpsilon.
*/
__GLfloat viewportEpsilon;
__GLfloat viewportAlmostHalf;
/* Scales that bring colors values from 0.0 to 1.0 into internal range */
__GLfloat redScale, blueScale, greenScale, alphaScale;
/*
** Geometry of the current window.
*/
GLint width, height;
/*
** Size of the alpha lookup table for alpha testing, and conversion
** value to convert from scaled alpha to alpha to be used for lookup table.
*/
GLint alphaTestSize;
__GLfloat alphaTableConv;
/*
** Random getable constants
*/
GLint maxTextureSize;
GLint maxMipMapLevel;
GLint subpixelBits;
GLint maxListNesting;
__GLfloat pointSizeMinimum;
__GLfloat pointSizeMaximum;
__GLfloat pointSizeGranularity;
__GLfloat lineWidthMinimum;
__GLfloat lineWidthMaximum;
__GLfloat lineWidthGranularity;
GLint maxEvalOrder;
GLint maxPixelMapTable;
GLint maxAttribStackDepth;
GLint maxClientAttribStackDepth;
GLint maxNameStackDepth;
#ifdef NT_DEADCODE_MATRIX
GLint maxModelViewStackDepth;
GLint maxProjectionStackDepth;
GLint maxTextureStackDepth;
#endif // NT_DEADCODE_MATRIX
#ifdef NT_DEADCODE_CONSTANTS
// This is now a global (__glUByteToFloat).
/*
** This is used by the macro __GL_UB_TO_FLOAT which converts
** unsigned bytes to floats in the range [0,1]. Once is enough!
*/
GLfloat uByteToFloat[256];
#endif // NT_DEADCODE_CONSTANTS
/*
** On the REX, y is inverted. These two constants help out.
*/
GLboolean yInverted;
GLint ySign;
} __GLcontextConstants;
/************************************************************************/
typedef enum __GLbeginModeEnum {
__GL_NOT_IN_BEGIN = 0,
__GL_IN_BEGIN = 1,
__GL_NEED_VALIDATE = 2
} __GLbeginMode;
#ifdef unix
/*
** Bits for gcState
** __GL_INIT_HW is set if the hardware has been initialized.
** __GL_HW_MODE is set if the hardware was mode was used last.
** __GL_PIXMAP_MODE is set if pixmap rendering was done last.
*/
#define __GL_INIT_HW 0x00000001
#define __GL_HW_MODE 0x00000002
#define __GL_PIXMAP_MODE 0x00000004
#endif
#ifdef NT
/*
** NT Bits for gcState
*/
#define __GL_INIT_CONTEXT 0x00000001
#endif /* NT */
#ifdef NT_SERVER_SHARE_LISTS
//
// Information for tracking dlist locks so we know what to unlock during
// cleanup
//
typedef struct _DlLockEntry
{
__GLdlist *dlist;
} DlLockEntry;
typedef struct _DlLockArray
{
GLsizei nAllocated;
GLsizei nFilled;
DlLockEntry *pdleEntries;
} DlLockArray;
#endif
struct __GLcontextRec {
/*
** Os related interfaces; these *must* be the first members of this
** structure, because they are exposed to the outside world (i.e. GLX
** extension).
*/
__GLimports imports;
#ifdef NT_DEADCODE_EXPORTS
__GLexports exports;
#endif // NT_DEADCODE_EXPORTS
/************************************************************************/
/*
** State var indicating what the state of this GC is.
*/
GLint gcState;
/************************************************************************/
/*
** Stackable state. All of the current user controllable state
** is resident here.
*/
__GLattribute state;
/************************************************************************/
/*
** Unstackable State
*/
/*
** Current glBegin mode. Legal values are 0 (not in begin mode), 1
** (in beginMode), or 2 (not in begin mode, some validation is
** needed). Because all state changing routines have to fetch this
** value, we have overloaded state validation into it. There is
** special code in the __glim_Begin (for software renderers) which
** deals with validation.
*/
__GLbeginMode beginMode;
/* Current rendering mode */
GLenum renderMode;
/*
** Most recent error code, or GL_NO_ERROR if no error has occurred
** since the last glGetError.
*/
GLint error;
/*
** Mode information that describes the kind of buffers and rendering
** modes that this context manages.
*/
__GLcontextModes modes;
/* Implementation dependent constants */
__GLcontextConstants constants;
/* Feedback and select state */
__GLfeedbackMachine feedback;
__GLselectMachine select;
/* Display list state */
__GLdlistMachine dlist;
#ifdef NT
/* Server side dispatch table */
__GLsrvDispatchTable srvDispatchTable;
/* Saved client side dispatch tables. Used by display list. */
GLCLTPROCTABLE savedCltProcTable;
GLEXTPROCTABLE savedExtProcTable;
#endif
#ifdef NT_DEADCODE_DISPATCH
/*
** Current dispatch tables state. currentDispatchState is used to
** save/restore the global dispatch pointers state by glXMakeCurrent.
** When making a new context current, first the old context's global
** pointers state will be saved in its currentDispatchState and then
** the new context's dispatch table pointers state will be copied
** from its currentDispatchState into the global pointers state.
**
** When entering list-compilation mode (NewList) the value of the
** global state will be copied into savedDispatchState. Then the
** global state will be loaded with the values in listCompState. For
** compile and execute to work, the compilation routines will invoke
** procedures as follows:
**
** (*gc->savedDispatchState.vertex->vertex3fv)(v).
**
** Any "pick" procs that might be updating the dispatch tables on the
** fly as state changes occur need to know which set of pointers
** to update. In this case the "pick" procs use the dispatchState
** pointer which will point to either the global pointers or to
** savedDispatchState.
**
** Finally, executing a CallList or CallLists while in display list
** compile and execute mode requires special treatment. In this case
** the CallList/CallLists call will be recorded in the display list
** being constructed. Next, the code will temporarily switch the
** global pointers to contain the contents of savedDispatchState.
** After calling the immediate mode CallList/CallLists code (using
** gc->savedDispatchState to get its address), the global pointers
** will be reset to point back to the list compilation routines.
*/
__GLdispatchState *dispatchState;
__GLdispatchState listCompState;
__GLdispatchState currentDispatchState;
__GLdispatchState savedDispatchState;
#endif // NT_DEADCODE_DISPATCH
/************************************************************************/
/*
** The remaining state is used primarily by the software renderer.
*/
/*
** Mask word for validation state to help guide the gc validation
** code. Only operations which are largely expensive are broken
** out here. See the #define's below for the values being used.
*/
GLuint validateMask;
/*
** Mask word of dirty bits. Most routines just set the GENERIC bit to
** dirty, others may set more specific bits. The list of bits is
** listed below.
*/
GLuint dirtyMask;
/* Current draw buffer, set by glDrawBuffer */
__GLcolorBuffer *drawBuffer;
/* Current read buffer, set by glReadBuffer */
__GLcolorBuffer *readBuffer;
/* Function pointers that are mode dependent */
__GLprocs procs;
/* Attribute stack state */
__GLattributeMachine attributes;
/* Client attribute stack state */
__GLclientAttributeMachine clientAttributes;
/* Machine structures defining software rendering "machine" state */
__GLvertexMachine vertex;
__GLlightMachine light;
__GLtextureMachine texture;
__GLevaluatorMachine eval;
__GLtransformMachine transform;
__GLlineMachine line;
__GLpolygonMachine polygon;
__GLpixelMachine pixel;
__GLbufferMachine buffers;
#ifdef NT
__GLfloat redClampTable[4];
__GLfloat greenClampTable[4];
__GLfloat blueClampTable[4];
__GLfloat alphaClampTable[4];
__GLfloat oneOverRedVertexScale;
__GLfloat oneOverGreenVertexScale;
__GLfloat oneOverBlueVertexScale;
__GLfloat oneOverAlphaVertexScale;
__GLfloat redVertexScale;
__GLfloat greenVertexScale;
__GLfloat blueVertexScale;
__GLfloat alphaVertexScale;
GLuint textureKey;
#endif
/* Buffers */
__GLcolorBuffer *front;
__GLcolorBuffer *back;
__GLcolorBuffer frontBuffer;
__GLcolorBuffer backBuffer;
__GLcolorBuffer *auxBuffer;
__GLstencilBuffer stencilBuffer;
__GLdepthBuffer depthBuffer;
__GLaccumBuffer accumBuffer;
/* Pointer to drawable private data */
__GLdrawablePrivate *drawablePrivate;
#ifdef NT
// Temporary buffers allocated by the gc. The abnormal process exit
// code will release these buffers.
void * apvTempBuf[6];
#endif // NT
#ifdef NT_SERVER_SHARE_LISTS
DlLockArray dla;
#endif
#ifdef NT
// TEB polyarray pointer for this thread. It allows fast access to the
// polyarray structure in the TEB equivalent to the GLTEB_CLTPOLYARRAY
// macro. This field is kept current in MakeCurrent.
POLYARRAY *paTeb;
// Vertex array client states
__GLvertexArray vertexArray;
// Saved vertex array state for execution of display-listed
// vertex array calls
__GLvertexArray savedVertexArray;
__GLmatrix *mInv;
#endif // NT
};
#ifdef NT
// Temporay buffer management functions
BOOL __wglInitTempAlloc(void);
void * __wglTempAlloc(__GLcontext *Gc, size_t Size);
void __wglTempFree(__GLcontext *Gc, void *Addr);
// Associate the temporary buffer with the gc for abnormal process cleanup.
#define GC_TEMP_BUFFER_ALLOC(gc, pv) \
{ \
int _i; \
for (_i = 0; _i < sizeof(gc->apvTempBuf)/sizeof(void *); _i++)\
{ \
if (!gc->apvTempBuf[_i]) \
{ \
gc->apvTempBuf[_i] = pv; \
break; \
} \
} \
ASSERTOPENGL(_i < sizeof(gc->apvTempBuf)/sizeof(void *), \
"gc->apvTempBuf overflows\n"); \
}
// Unassociate the temporary buffer with the gc.
#define GC_TEMP_BUFFER_FREE(gc, pv) \
{ \
int _i; \
for (_i = 0; _i < sizeof(gc->apvTempBuf)/sizeof(void *); _i++)\
{ \
if (gc->apvTempBuf[_i] == pv) \
{ \
gc->apvTempBuf[_i] = (void *) NULL; \
break; \
} \
} \
ASSERTOPENGL(_i < sizeof(gc->apvTempBuf)/sizeof(void *), \
"gc->apvTempBuf entry not found\n"); \
}
// Cleanup any temporary buffer allocated in gc in abnormal process exit.
#define GC_TEMP_BUFFER_EXIT_CLEANUP(gc) \
{ \
int _i; \
for (_i = 0; _i < sizeof(gc->apvTempBuf)/sizeof(void *); _i++)\
{ \
if (gc->apvTempBuf[_i]) \
{ \
WARNING("Abnormal process exit: free allocated buffers\n");\
__wglTempFree(gc, gc->apvTempBuf[_i]); \
gc->apvTempBuf[_i] = (void *) NULL; \
} \
} \
}
#endif // NT
/*
** Bit values for the validateMask word
*/
#define __GL_VALIDATE_ALPHA_FUNC 0x00000001
#define __GL_VALIDATE_STENCIL_FUNC 0x00000002
#define __GL_VALIDATE_STENCIL_OP 0x00000004
/*
** Bit values for dirtyMask word.
**
** These are all for delayed validation. There are a few things that do
** not trigger delayed validation. They are:
**
** Matrix operations -- matrices are validated immediately.
** Material changes -- they also validate immediately.
** Color Material change -- validated immediately.
** Color Material enable -- validated immediately.
** Pixel Map changes -- no validation.
*/
/*
** All things not listed elsewhere.
*/
#define __GL_DIRTY_GENERIC 0x00000001
/*
** Line stipple, line stipple enable, line width, line smooth enable,
** line smooth hint.
*/
#define __GL_DIRTY_LINE 0x00000002
/*
** Polygon stipple, polygon stipple enable, polygon smooth enable, face
** culling, front face orientation, polygon mode, point smooth hint.
*/
#define __GL_DIRTY_POLYGON 0x00000004
/*
** Point smooth, point smooth hint, point width.
*/
#define __GL_DIRTY_POINT 0x00000008
/*
** Pixel store, pixel zoom, pixel transfer, (pixel maps don't cause
** validation), read buffer.
*/
#define __GL_DIRTY_PIXEL 0x00000010
/*
** Light, Light Model, lighting enable, lightx enable, (color material
** validates immediately), (NOT shade model -- it is generic), (color material
** enable validates immediately)
*/
#define __GL_DIRTY_LIGHTING 0x00000020
/*
** Polygon stipple
*/
#define __GL_DIRTY_POLYGON_STIPPLE 0x00000040
/*
** the depth mode has changed. Need to update depth function pointers.
*/
#define __GL_DIRTY_DEPTH 0x00000080
#define __GL_DIRTY_ALL 0x000000ff
/*
** Bit values for changes to material colors
*/
#define __GL_MATERIAL_AMBIENT 0x00000001
#define __GL_MATERIAL_DIFFUSE 0x00000002
#define __GL_MATERIAL_SPECULAR 0x00000004
#define __GL_MATERIAL_EMISSIVE 0x00000008
#define __GL_MATERIAL_SHININESS 0x00000010
#define __GL_MATERIAL_COLORINDEXES 0x00000020
#define __GL_MATERIAL_ALL 0x0000003f
#define __GL_DELAY_VALIDATE(gc) \
assert((gc)->beginMode != __GL_IN_BEGIN); \
(gc)->beginMode = __GL_NEED_VALIDATE; \
(gc)->dirtyMask |= __GL_DIRTY_GENERIC
#define __GL_DELAY_VALIDATE_MASK(gc, mask) \
assert((gc)->beginMode != __GL_IN_BEGIN); \
(gc)->beginMode = __GL_NEED_VALIDATE; \
(gc)->dirtyMask |= (mask)
#define __GL_CLAMP_CI(target, gc, r) \
{ \
if ((r) > (GLfloat)(gc)->frontBuffer.redMax) { \
GLfloat fraction; \
GLint integer; \
\
integer = (GLint) (r); \
fraction = (r) - (GLfloat) integer; \
integer = integer & (GLint)(gc)->frontBuffer.redMax; \
target = (GLfloat) integer + fraction; \
} else if ((r) < 0) { \
GLfloat fraction; \
GLint integer; \
\
integer = (GLint) __GL_FLOORF(r); \
fraction = (r) - (GLfloat) integer; \
integer = integer & (GLint)(gc)->frontBuffer.redMax; \
target = (GLfloat) integer + fraction; \
} else { \
target = r; \
}\
}
#define __GL_CHECK_CLAMP_CI(target, gc, flags, r) \
{ \
if (((r) > (GLfloat)(gc)->frontBuffer.redMax) || \
((r) < 0)) \
flags |= POLYARRAY_CLAMP_COLOR; \
(target) = (r); \
}
#define __GL_COLOR_CLAMP_INDEX_R(value) \
(((ULONG)((CASTINT(value) & 0x80000000)) >> 30) | \
((ULONG)(((CASTINT(gc->redVertexScale) - CASTINT(value)) & 0x80000000)) >> 31)) \
#define __GL_COLOR_CLAMP_INDEX_G(value) \
(((ULONG)((CASTINT(value) & 0x80000000)) >> 30) | \
((ULONG)(((CASTINT(gc->greenVertexScale) - CASTINT(value)) & 0x80000000)) >> 31)) \
#define __GL_COLOR_CLAMP_INDEX_B(value) \
(((ULONG)((CASTINT(value) & 0x80000000)) >> 30) | \
((ULONG)(((CASTINT(gc->blueVertexScale) - CASTINT(value)) & 0x80000000)) >> 31)) \
#define __GL_COLOR_CLAMP_INDEX_A(value) \
(((ULONG)((CASTINT(value) & 0x80000000)) >> 30) | \
((ULONG)(((CASTINT(gc->alphaVertexScale) - CASTINT(value)) & 0x80000000)) >> 31)) \
#define __GL_SCALE_R(target, gc, r) \
(target) = (r) * (gc)->redVertexScale
#define __GL_SCALE_G(target, gc, g) \
(target) = (g) * (gc)->greenVertexScale
#define __GL_SCALE_B(target, gc, b) \
(target) = (b) * (gc)->blueVertexScale
#define __GL_SCALE_A(target, gc, a) \
(target) = (a) * (gc)->alphaVertexScale
#define __GL_COLOR_CHECK_CLAMP_R(value, flags) \
(flags) |= \
((ULONG)(CASTINT(value) & 0x80000000) | \
(ULONG)((CASTINT(gc->redVertexScale) - CASTINT(value)) & 0x80000000))
#define __GL_COLOR_CHECK_CLAMP_G(value, flags) \
(flags) |= \
((ULONG)(CASTINT(value) & 0x80000000) | \
(ULONG)((CASTINT(gc->greenVertexScale) - CASTINT(value)) & 0x80000000))
#define __GL_COLOR_CHECK_CLAMP_B(value, flags) \
(flags) |= \
((ULONG)(CASTINT(value) & 0x80000000) | \
(ULONG)((CASTINT(gc->blueVertexScale) - CASTINT(value)) & 0x80000000))
#define __GL_COLOR_CHECK_CLAMP_A(value, flags) \
(flags) |= \
((ULONG)(CASTINT(value) & 0x80000000) | \
(ULONG)((CASTINT(gc->alphaVertexScale) - CASTINT(value)) & 0x80000000))
#define __GL_SCALE_AND_CHECK_CLAMP_R(target, gc, flags, r) \
{ \
__GL_SCALE_R(target, gc, r); \
__GL_COLOR_CHECK_CLAMP_R(target, flags); \
}
#define __GL_SCALE_AND_CHECK_CLAMP_G(target, gc, flags, g) \
{ \
__GL_SCALE_G(target, gc, g); \
__GL_COLOR_CHECK_CLAMP_G(target, flags); \
}
#define __GL_SCALE_AND_CHECK_CLAMP_B(target, gc, flags, b) \
{ \
__GL_SCALE_B(target, gc, b); \
__GL_COLOR_CHECK_CLAMP_B(target, flags); \
}
#define __GL_SCALE_AND_CHECK_CLAMP_A(target, gc, flags, a) \
{ \
__GL_SCALE_A(target, gc, a); \
__GL_COLOR_CHECK_CLAMP_A(target, flags); \
}
#define __GL_CLAMP_R(target, gc, r) \
{ \
(gc)->redClampTable[0] = (r); \
target = (gc)->redClampTable[__GL_COLOR_CLAMP_INDEX_R((gc)->redClampTable[0])]; \
}
#define __GL_CLAMP_G(target, gc, g) \
{ \
(gc)->greenClampTable[0] = (g); \
target = (gc)->greenClampTable[__GL_COLOR_CLAMP_INDEX_G((gc)->greenClampTable[0])]; \
}
#define __GL_CLAMP_B(target, gc, b) \
{ \
(gc)->blueClampTable[0] = (b); \
target = (gc)->blueClampTable[__GL_COLOR_CLAMP_INDEX_B((gc)->blueClampTable[0])]; \
}
#define __GL_CLAMP_A(target, gc, a) \
{ \
(gc)->alphaClampTable[0] = (a); \
target = (gc)->alphaClampTable[__GL_COLOR_CLAMP_INDEX_A((gc)->alphaClampTable[0])]; \
}
/************************************************************************/
/* Applies to current context */
extern void FASTCALL __glSetError(GLenum code);
#ifdef NT
/* Used when no RC is current */
extern void FASTCALL __glSetErrorEarly(__GLcontext *gc, GLenum code);
#endif // NT
extern void FASTCALL __glFreeEvaluatorState(__GLcontext *gc);
extern void FASTCALL __glFreeDlistState(__GLcontext *gc);
extern void FASTCALL __glFreeMachineState(__GLcontext *gc);
extern void FASTCALL __glFreePixelState(__GLcontext *gc);
extern void FASTCALL __glFreeTextureState(__GLcontext *gc);
extern void FASTCALL __glInitDlistState(__GLcontext *gc);
extern void FASTCALL __glInitEvaluatorState(__GLcontext *gc);
extern void FASTCALL __glInitPixelState(__GLcontext *gc);
extern void FASTCALL __glInitTextureState(__GLcontext *gc);
extern void FASTCALL __glInitTransformState(__GLcontext *gc);
void FASTCALL __glEarlyInitContext(__GLcontext *gc);
void FASTCALL __glContextSetColorScales(__GLcontext *gc);
void FASTCALL __glContextUnsetColorScales(__GLcontext *gc);
void FASTCALL __glSoftResetContext(__GLcontext *gc);
void FASTCALL __glDestroyContext(__GLcontext *gc);
#endif /* __glcontext_h_ */