X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fcontext.c;h=986dbc5aca9912bcaad93032f09f2e15de6f6656;hb=89fb06fcc11cbe3f23521312155d6c55d869f526;hp=9da1526535ea35970795e1a3738f9bb0389b0c4f;hpb=ae47121fa336f53c5ab51df3dc699db018feff18;p=mesa.git diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 9da1526535e..986dbc5aca9 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1,10 +1,10 @@ -/* $Id: context.c,v 1.142 2001/06/12 22:08:41 brianp Exp $ */ +/* $Id: context.c,v 1.177 2002/09/27 02:45:37 brianp Exp $ */ /* * Mesa 3-D graphics library - * Version: 3.5 + * Version: 4.1 * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -41,7 +41,6 @@ #include "get.h" #include "glthread.h" #include "hash.h" -#include "imports.h" #include "light.h" #include "macros.h" #include "mem.h" @@ -50,12 +49,12 @@ #include "state.h" #include "teximage.h" #include "texobj.h" +#include "texstate.h" #include "mtypes.h" #include "varray.h" +#include "vpstate.h" #include "vtxfmt.h" - #include "math/m_translate.h" -#include "math/m_vertices.h" #include "math/m_matrix.h" #include "math/m_xform.h" #include "math/mathmod.h" @@ -71,30 +70,27 @@ #endif #ifndef MESA_VERBOSE -int MESA_VERBOSE = 0 -/* | VERBOSE_PIPELINE */ -/* | VERBOSE_IMMEDIATE */ -/* | VERBOSE_VARRAY */ -/* | VERBOSE_TEXTURE */ -/* | VERBOSE_API */ -/* | VERBOSE_DRIVER */ -/* | VERBOSE_STATE */ -/* | VERBOSE_DISPLAY_LIST */ -; +int MESA_VERBOSE = 0; #endif #ifndef MESA_DEBUG_FLAGS -int MESA_DEBUG_FLAGS = 0 -/* | DEBUG_ALWAYS_FLUSH */ -; +int MESA_DEBUG_FLAGS = 0; #endif + +static void +free_shared_state( GLcontext *ctx, struct gl_shared_state *ss ); + + /**********************************************************************/ /***** OpenGL SI-style interface (new in Mesa 3.5) *****/ /**********************************************************************/ -static GLboolean -_mesa_DestroyContext(__GLcontext *gc) +/* Called by window system/device driver (via gc->exports.destroyCurrent()) + * when the rendering context is to be destroyed. + */ +GLboolean +_mesa_destroyContext(__GLcontext *gc) { if (gc) { _mesa_free_context_data(gc); @@ -103,6 +99,133 @@ _mesa_DestroyContext(__GLcontext *gc) return GL_TRUE; } +/* Called by window system/device driver (via gc->exports.loseCurrent()) + * when the rendering context is made non-current. + */ +GLboolean +_mesa_loseCurrent(__GLcontext *gc) +{ + /* XXX unbind context from thread */ + return GL_TRUE; +} + +/* Called by window system/device driver (via gc->exports.makeCurrent()) + * when the rendering context is made current. + */ +GLboolean +_mesa_makeCurrent(__GLcontext *gc) +{ + /* XXX bind context to thread */ + return GL_TRUE; +} + +/* Called by window system/device driver - yadda, yadda, yadda. + * See above comments. + */ +GLboolean +_mesa_shareContext(__GLcontext *gc, __GLcontext *gcShare) +{ + if (gc && gcShare && gc->Shared && gcShare->Shared) { + gc->Shared->RefCount--; + if (gc->Shared->RefCount == 0) { + free_shared_state(gc, gc->Shared); + } + gc->Shared = gcShare->Shared; + gc->Shared->RefCount++; + return GL_TRUE; + } + else { + return GL_FALSE; + } +} + +GLboolean +_mesa_copyContext(__GLcontext *dst, const __GLcontext *src, GLuint mask) +{ + if (dst && src) { + _mesa_copy_context( src, dst, mask ); + return GL_TRUE; + } + else { + return GL_FALSE; + } +} + +GLboolean +_mesa_forceCurrent(__GLcontext *gc) +{ + return GL_TRUE; +} + +GLboolean +_mesa_notifyResize(__GLcontext *gc) +{ + GLint x, y; + GLuint width, height; + __GLdrawablePrivate *d = gc->imports.getDrawablePrivate(gc); + if (!d || !d->getDrawableSize) + return GL_FALSE; + d->getDrawableSize( d, &x, &y, &width, &height ); + /* update viewport, resize software buffers, etc. */ + return GL_TRUE; +} + +void +_mesa_notifyDestroy(__GLcontext *gc) +{ +} + +/* Called by window system just before swapping buffers. + * We have to finish any pending rendering. + */ +void +_mesa_notifySwapBuffers(__GLcontext *gc) +{ + FLUSH_VERTICES( gc, 0 ); +} + +struct __GLdispatchStateRec * +_mesa_dispatchExec(__GLcontext *gc) +{ + return NULL; +} + +void +_mesa_beginDispatchOverride(__GLcontext *gc) +{ +} + +void +_mesa_endDispatchOverride(__GLcontext *gc) +{ +} + +/* Setup the exports. The window system will call these functions + * when it needs Mesa to do something. + * NOTE: Device drivers should override these functions! For example, + * the Xlib driver should plug in the XMesa*-style functions into this + * structure. The XMesa-style functions should then call the _mesa_* + * version of these functions. This is an approximation to OO design + * (inheritance and virtual functions). + */ +static void +_mesa_init_default_exports(__GLexports *exports) +{ + exports->destroyContext = _mesa_destroyContext; + exports->loseCurrent = _mesa_loseCurrent; + exports->makeCurrent = _mesa_makeCurrent; + exports->shareContext = _mesa_shareContext; + exports->copyContext = _mesa_copyContext; + exports->forceCurrent = _mesa_forceCurrent; + exports->notifyResize = _mesa_notifyResize; + exports->notifyDestroy = _mesa_notifyDestroy; + exports->notifySwapBuffers = _mesa_notifySwapBuffers; + exports->dispatchExec = _mesa_dispatchExec; + exports->beginDispatchOverride = _mesa_beginDispatchOverride; + exports->endDispatchOverride = _mesa_endDispatchOverride; +} + + /* exported OpenGL SI interface */ __GLcontext * @@ -110,11 +233,13 @@ __glCoreCreateContext(__GLimports *imports, __GLcontextModes *modes) { GLcontext *ctx; - ctx = (GLcontext *) (*imports->calloc)(0, 1, sizeof(GLcontext)); + ctx = (GLcontext *) (*imports->calloc)(NULL, 1, sizeof(GLcontext)); if (ctx == NULL) { return NULL; } + ctx->Driver.CurrentExecPrimitive=0; /* XXX why is this here??? */ ctx->imports = *imports; + _mesa_init_default_exports(&(ctx->exports)); _mesa_initialize_visual(&ctx->Visual, modes->rgbMode, @@ -133,10 +258,7 @@ __glCoreCreateContext(__GLimports *imports, __GLcontextModes *modes) modes->accumAlphaBits, 0); - /* KW: was imports->wscx */ - _mesa_initialize_context(ctx, &ctx->Visual, NULL, imports->other, GL_FALSE); - - ctx->exports.destroyContext = _mesa_DestroyContext; + _mesa_initialize_context(ctx, &ctx->Visual, NULL, imports); return ctx; } @@ -156,12 +278,6 @@ __glCoreNopDispatch(void) } -/**********************************************************************/ -/***** Context and Thread management *****/ -/**********************************************************************/ - - - /**********************************************************************/ /***** GL Visual allocation/destruction *****/ /**********************************************************************/ @@ -346,6 +462,8 @@ _mesa_initialize_framebuffer( GLframebuffer *buffer, assert(buffer); assert(visual); + BZERO(buffer, sizeof(GLframebuffer)); + /* sanity checks */ if (softwareDepth ) { assert(visual->depthBits > 0); @@ -395,31 +513,31 @@ _mesa_free_framebuffer_data( GLframebuffer *buffer ) return; if (buffer->DepthBuffer) { - FREE( buffer->DepthBuffer ); + MESA_PBUFFER_FREE( buffer->DepthBuffer ); buffer->DepthBuffer = NULL; } if (buffer->Accum) { - FREE( buffer->Accum ); + MESA_PBUFFER_FREE( buffer->Accum ); buffer->Accum = NULL; } if (buffer->Stencil) { - FREE( buffer->Stencil ); + MESA_PBUFFER_FREE( buffer->Stencil ); buffer->Stencil = NULL; } if (buffer->FrontLeftAlpha) { - FREE( buffer->FrontLeftAlpha ); + MESA_PBUFFER_FREE( buffer->FrontLeftAlpha ); buffer->FrontLeftAlpha = NULL; } if (buffer->BackLeftAlpha) { - FREE( buffer->BackLeftAlpha ); + MESA_PBUFFER_FREE( buffer->BackLeftAlpha ); buffer->BackLeftAlpha = NULL; } if (buffer->FrontRightAlpha) { - FREE( buffer->FrontRightAlpha ); + MESA_PBUFFER_FREE( buffer->FrontRightAlpha ); buffer->FrontRightAlpha = NULL; } if (buffer->BackRightAlpha) { - FREE( buffer->BackRightAlpha ); + MESA_PBUFFER_FREE( buffer->BackRightAlpha ); buffer->BackRightAlpha = NULL; } } @@ -438,7 +556,7 @@ _glthread_DECLARE_STATIC_MUTEX(OneTimeLock); * This function just calls all the various one-time-init functions in Mesa. */ static void -one_time_init( void ) +one_time_init( GLcontext *ctx ) { static GLboolean alreadyCalled = GL_FALSE; _glthread_LOCK_MUTEX(OneTimeLock); @@ -459,15 +577,16 @@ one_time_init( void ) #ifdef USE_SPARC_ASM _mesa_init_sparc_glapi_relocs(); #endif - if (getenv("MESA_DEBUG")) { + if (ctx->imports.getenv(ctx, "MESA_DEBUG")) { _glapi_noop_enable_warnings(GL_TRUE); + _glapi_set_warning_func( (_glapi_warning_func) _mesa_warning ); } else { _glapi_noop_enable_warnings(GL_FALSE); } #if defined(DEBUG) && defined(__DATE__) && defined(__TIME__) - fprintf(stderr, "Mesa DEBUG build %s %s\n", __DATE__, __TIME__); + _mesa_debug(ctx, "Mesa DEBUG build %s %s\n", __DATE__, __TIME__); #endif alreadyCalled = GL_TRUE; @@ -476,6 +595,36 @@ one_time_init( void ) } +static void +init_matrix_stack( struct matrix_stack *stack, + GLuint maxDepth, GLuint dirtyFlag ) +{ + GLuint i; + + stack->Depth = 0; + stack->MaxDepth = maxDepth; + stack->DirtyFlag = dirtyFlag; + /* The stack */ + stack->Stack = (GLmatrix *) CALLOC(maxDepth * sizeof(GLmatrix)); + for (i = 0; i < maxDepth; i++) { + _math_matrix_ctr(&stack->Stack[i]); + _math_matrix_alloc_inv(&stack->Stack[i]); + } + stack->Top = stack->Stack; +} + + +static void +free_matrix_stack( struct matrix_stack *stack ) +{ + GLuint i; + for (i = 0; i < stack->MaxDepth; i++) { + _math_matrix_dtr(&stack->Stack[i]); + } + FREE(stack->Stack); + stack->Stack = stack->Top = NULL; +} + /* * Allocate and initialize a shared context state structure. @@ -494,36 +643,47 @@ alloc_shared_state( void ) ss->DisplayList = _mesa_NewHashTable(); ss->TexObjects = _mesa_NewHashTable(); + ss->VertexPrograms = _mesa_NewHashTable(); /* Default Texture objects */ outOfMemory = GL_FALSE; - ss->Default1D = _mesa_alloc_texture_object(ss, 0, 1); + ss->Default1D = _mesa_alloc_texture_object(ss, 0, GL_TEXTURE_1D); if (!ss->Default1D) { outOfMemory = GL_TRUE; } - ss->Default2D = _mesa_alloc_texture_object(ss, 0, 2); + ss->Default2D = _mesa_alloc_texture_object(ss, 0, GL_TEXTURE_2D); if (!ss->Default2D) { outOfMemory = GL_TRUE; } - ss->Default3D = _mesa_alloc_texture_object(ss, 0, 3); + ss->Default3D = _mesa_alloc_texture_object(ss, 0, GL_TEXTURE_3D); if (!ss->Default3D) { outOfMemory = GL_TRUE; } - ss->DefaultCubeMap = _mesa_alloc_texture_object(ss, 0, 6); + ss->DefaultCubeMap = _mesa_alloc_texture_object(ss, 0, + GL_TEXTURE_CUBE_MAP_ARB); if (!ss->DefaultCubeMap) { outOfMemory = GL_TRUE; } - if (!ss->DisplayList || !ss->TexObjects || outOfMemory) { + ss->DefaultRect = _mesa_alloc_texture_object(ss, 0, + GL_TEXTURE_RECTANGLE_NV); + if (!ss->DefaultRect) { + outOfMemory = GL_TRUE; + } + + if (!ss->DisplayList || !ss->TexObjects || !ss->VertexPrograms + || outOfMemory) { /* Ran out of memory at some point. Free everything and return NULL */ if (ss->DisplayList) _mesa_DeleteHashTable(ss->DisplayList); if (ss->TexObjects) _mesa_DeleteHashTable(ss->TexObjects); + if (ss->VertexPrograms) + _mesa_DeleteHashTable(ss->VertexPrograms); if (ss->Default1D) _mesa_free_texture_object(ss, ss->Default1D); if (ss->Default2D) @@ -532,6 +692,8 @@ alloc_shared_state( void ) _mesa_free_texture_object(ss, ss->Default3D); if (ss->DefaultCubeMap) _mesa_free_texture_object(ss, ss->DefaultCubeMap); + if (ss->DefaultRect) + _mesa_free_texture_object(ss, ss->DefaultRect); FREE(ss); return NULL; } @@ -568,6 +730,18 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss ) } _mesa_DeleteHashTable(ss->TexObjects); + /* Free vertex programs */ + while (1) { + GLuint prog = _mesa_HashFirstEntry(ss->VertexPrograms); + if (prog) { + _mesa_delete_program(ctx, prog); + } + else { + break; + } + } + _mesa_DeleteHashTable(ss->VertexPrograms); + FREE(ss); } @@ -608,7 +782,7 @@ init_light( struct gl_light *l, GLuint n ) static void init_lightmodel( struct gl_lightmodel *lm ) { - ASSIGN_4V( lm->Ambient, 0.2, 0.2, 0.2, 1.0 ); + ASSIGN_4V( lm->Ambient, 0.2F, 0.2F, 0.2F, 1.0F ); lm->LocalViewer = GL_FALSE; lm->TwoSide = GL_FALSE; lm->ColorControl = GL_SINGLE_COLOR; @@ -618,10 +792,10 @@ init_lightmodel( struct gl_lightmodel *lm ) static void init_material( struct gl_material *m ) { - ASSIGN_4V( m->Ambient, 0.2, 0.2, 0.2, 1.0 ); - ASSIGN_4V( m->Diffuse, 0.8, 0.8, 0.8, 1.0 ); - ASSIGN_4V( m->Specular, 0.0, 0.0, 0.0, 1.0 ); - ASSIGN_4V( m->Emission, 0.0, 0.0, 0.0, 1.0 ); + ASSIGN_4V( m->Ambient, 0.2F, 0.2F, 0.2F, 1.0F ); + ASSIGN_4V( m->Diffuse, 0.8F, 0.8F, 0.8F, 1.0F ); + ASSIGN_4V( m->Specular, 0.0F, 0.0F, 0.0F, 1.0F ); + ASSIGN_4V( m->Emission, 0.0F, 0.0F, 0.0F, 1.0F ); m->Shininess = 0.0; m->AmbientIndex = 0; m->DiffuseIndex = 1; @@ -678,6 +852,7 @@ init_texture_unit( GLcontext *ctx, GLuint unit ) texUnit->Current2D = ctx->Shared->Default2D; texUnit->Current3D = ctx->Shared->Default3D; texUnit->CurrentCubeMap = ctx->Shared->DefaultCubeMap; + texUnit->CurrentRect = ctx->Shared->DefaultRect; } @@ -724,76 +899,58 @@ init_2d_map( struct gl_2d_map *map, int n, const float *initial ) static void init_attrib_groups( GLcontext *ctx ) { - GLuint i, j; + GLuint i; assert(ctx); + assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS); + assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS); + /* Constants, may be overriden by device drivers */ ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS; - ctx->Const.MaxTextureSize = 1 << (MAX_TEXTURE_LEVELS - 1); - ctx->Const.MaxCubeTextureSize = ctx->Const.MaxTextureSize; + ctx->Const.Max3DTextureLevels = MAX_3D_TEXTURE_LEVELS; + ctx->Const.MaxCubeTextureLevels = MAX_CUBE_TEXTURE_LEVELS; + ctx->Const.MaxTextureRectSize = MAX_TEXTURE_RECT_SIZE; ctx->Const.MaxTextureUnits = MAX_TEXTURE_UNITS; ctx->Const.MaxTextureMaxAnisotropy = MAX_TEXTURE_MAX_ANISOTROPY; + ctx->Const.MaxTextureLodBias = MAX_TEXTURE_LOD_BIAS; ctx->Const.MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE; ctx->Const.SubPixelBits = SUB_PIXEL_BITS; ctx->Const.MinPointSize = MIN_POINT_SIZE; ctx->Const.MaxPointSize = MAX_POINT_SIZE; ctx->Const.MinPointSizeAA = MIN_POINT_SIZE; ctx->Const.MaxPointSizeAA = MAX_POINT_SIZE; - ctx->Const.PointSizeGranularity = POINT_SIZE_GRANULARITY; + ctx->Const.PointSizeGranularity = (GLfloat) POINT_SIZE_GRANULARITY; ctx->Const.MinLineWidth = MIN_LINE_WIDTH; ctx->Const.MaxLineWidth = MAX_LINE_WIDTH; ctx->Const.MinLineWidthAA = MIN_LINE_WIDTH; ctx->Const.MaxLineWidthAA = MAX_LINE_WIDTH; - ctx->Const.LineWidthGranularity = LINE_WIDTH_GRANULARITY; + ctx->Const.LineWidthGranularity = (GLfloat) LINE_WIDTH_GRANULARITY; ctx->Const.NumAuxBuffers = NUM_AUX_BUFFERS; ctx->Const.MaxColorTableSize = MAX_COLOR_TABLE_SIZE; ctx->Const.MaxConvolutionWidth = MAX_CONVOLUTION_WIDTH; ctx->Const.MaxConvolutionHeight = MAX_CONVOLUTION_HEIGHT; - ctx->Const.NumCompressedTextureFormats = 0; ctx->Const.MaxClipPlanes = MAX_CLIP_PLANES; ctx->Const.MaxLights = MAX_LIGHTS; - /* Modelview matrix */ - _math_matrix_ctr( &ctx->ModelView ); - _math_matrix_alloc_inv( &ctx->ModelView ); - - ctx->ModelViewStackDepth = 0; - for (i = 0; i < MAX_MODELVIEW_STACK_DEPTH - 1; i++) { - _math_matrix_ctr( &ctx->ModelViewStack[i] ); - _math_matrix_alloc_inv( &ctx->ModelViewStack[i] ); - } - - /* Projection matrix - need inv for user clipping in clip space*/ - _math_matrix_ctr( &ctx->ProjectionMatrix ); - _math_matrix_alloc_inv( &ctx->ProjectionMatrix ); - - ctx->ProjectionStackDepth = 0; - for (i = 0; i < MAX_PROJECTION_STACK_DEPTH - 1; i++) { - _math_matrix_ctr( &ctx->ProjectionStack[i] ); - _math_matrix_alloc_inv( &ctx->ProjectionStack[i] ); - } - - /* Derived ModelProject matrix */ + /* Initialize matrix stacks */ + init_matrix_stack(&ctx->ModelviewMatrixStack, MAX_MODELVIEW_STACK_DEPTH, + _NEW_MODELVIEW); + init_matrix_stack(&ctx->ProjectionMatrixStack, MAX_PROJECTION_STACK_DEPTH, + _NEW_PROJECTION); + init_matrix_stack(&ctx->ColorMatrixStack, MAX_COLOR_STACK_DEPTH, + _NEW_COLOR_MATRIX); + for (i = 0; i < MAX_TEXTURE_UNITS; i++) + init_matrix_stack(&ctx->TextureMatrixStack[i], MAX_TEXTURE_STACK_DEPTH, + _NEW_TEXTURE_MATRIX); + for (i = 0; i < MAX_PROGRAM_MATRICES; i++) + init_matrix_stack(&ctx->ProgramMatrixStack[i], MAX_PROGRAM_STACK_DEPTH, + _NEW_TRACK_MATRIX); + ctx->CurrentStack = &ctx->ModelviewMatrixStack; + + /* Init combined Modelview*Projection matrix */ _math_matrix_ctr( &ctx->_ModelProjectMatrix ); - /* Texture matrix */ - for (i = 0; i < MAX_TEXTURE_UNITS; i++) { - _math_matrix_ctr( &ctx->TextureMatrix[i] ); - ctx->TextureStackDepth[i] = 0; - for (j = 0; j < MAX_TEXTURE_STACK_DEPTH - 1; j++) { - _math_matrix_ctr( &ctx->TextureStack[i][j] ); - ctx->TextureStack[i][j].inv = 0; - } - } - - /* Color matrix */ - _math_matrix_ctr(&ctx->ColorMatrix); - ctx->ColorStackDepth = 0; - for (j = 0; j < MAX_COLOR_STACK_DEPTH - 1; j++) { - _math_matrix_ctr(&ctx->ColorStack[j]); - } - /* Accumulate buffer group */ ASSIGN_4V( ctx->Accum.ClearColor, 0.0, 0.0, 0.0, 0.0 ); @@ -820,23 +977,25 @@ init_attrib_groups( GLcontext *ctx ) ctx->Color.ColorLogicOpEnabled = GL_FALSE; ctx->Color.LogicOp = GL_COPY; ctx->Color.DitherFlag = GL_TRUE; - ctx->Color.MultiDrawBuffer = GL_FALSE; /* Current group */ - ASSIGN_4V( ctx->Current.Color, 1.0, 1.0, 1.0, 1.0 ); + ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 0.0, 0.0, 0.0, 0.0 ); + ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], 0.0, 0.0, 1.0, 0.0 ); + ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1.0, 1.0, 1.0, 1.0 ); + ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 0.0 ); + ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_FOG], 0.0, 0.0, 0.0, 0.0 ); + for (i = 0; i < MAX_TEXTURE_UNITS; i++) + ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_TEX0 + i], 0.0, 0.0, 0.0, 1.0 ); ctx->Current.Index = 1; - for (i=0; iCurrent.Texcoord[i], 0.0, 0.0, 0.0, 1.0 ); + ctx->Current.EdgeFlag = GL_TRUE; + ASSIGN_4V( ctx->Current.RasterPos, 0.0, 0.0, 0.0, 1.0 ); ctx->Current.RasterDistance = 0.0; ASSIGN_4V( ctx->Current.RasterColor, 1.0, 1.0, 1.0, 1.0 ); ctx->Current.RasterIndex = 1; for (i=0; iCurrent.RasterMultiTexCoord[i], 0.0, 0.0, 0.0, 1.0 ); - ctx->Current.RasterTexCoord = ctx->Current.RasterMultiTexCoord[0]; + ASSIGN_4V( ctx->Current.RasterTexCoords[i], 0.0, 0.0, 0.0, 1.0 ); ctx->Current.RasterPosValid = GL_TRUE; - ctx->Current.EdgeFlag = GL_TRUE; - ASSIGN_3V( ctx->Current.Normal, 0.0, 0.0, 1.0 ); /* Depth buffer group */ @@ -856,6 +1015,7 @@ init_attrib_groups( GLcontext *ctx ) ctx->Eval.Map1TextureCoord4 = GL_FALSE; ctx->Eval.Map1Vertex3 = GL_FALSE; ctx->Eval.Map1Vertex4 = GL_FALSE; + MEMSET(ctx->Eval.Map1Attrib, 0, sizeof(ctx->Eval.Map1Attrib)); ctx->Eval.Map2Color4 = GL_FALSE; ctx->Eval.Map2Index = GL_FALSE; ctx->Eval.Map2Normal = GL_FALSE; @@ -865,6 +1025,7 @@ init_attrib_groups( GLcontext *ctx ) ctx->Eval.Map2TextureCoord4 = GL_FALSE; ctx->Eval.Map2Vertex3 = GL_FALSE; ctx->Eval.Map2Vertex4 = GL_FALSE; + MEMSET(ctx->Eval.Map2Attrib, 0, sizeof(ctx->Eval.Map2Attrib)); ctx->Eval.AutoNormal = GL_FALSE; ctx->Eval.MapGrid1un = 1; ctx->Eval.MapGrid1u1 = 0.0; @@ -883,6 +1044,7 @@ init_attrib_groups( GLcontext *ctx ) static GLfloat index[1] = { 1.0 }; static GLfloat color[4] = { 1.0, 1.0, 1.0, 1.0 }; static GLfloat texcoord[4] = { 0.0, 0.0, 0.0, 1.0 }; + static GLfloat attrib[4] = { 0.0, 0.0, 0.0, 1.0 }; init_1d_map( &ctx->EvalMap.Map1Vertex3, 3, vertex ); init_1d_map( &ctx->EvalMap.Map1Vertex4, 4, vertex ); @@ -893,6 +1055,8 @@ init_attrib_groups( GLcontext *ctx ) init_1d_map( &ctx->EvalMap.Map1Texture2, 2, texcoord ); init_1d_map( &ctx->EvalMap.Map1Texture3, 3, texcoord ); init_1d_map( &ctx->EvalMap.Map1Texture4, 4, texcoord ); + for (i = 0; i < 16; i++) + init_1d_map( ctx->EvalMap.Map1Attrib + i, 4, attrib ); init_2d_map( &ctx->EvalMap.Map2Vertex3, 3, vertex ); init_2d_map( &ctx->EvalMap.Map2Vertex4, 4, vertex ); @@ -903,6 +1067,8 @@ init_attrib_groups( GLcontext *ctx ) init_2d_map( &ctx->EvalMap.Map2Texture2, 2, texcoord ); init_2d_map( &ctx->EvalMap.Map2Texture3, 3, texcoord ); init_2d_map( &ctx->EvalMap.Map2Texture4, 4, texcoord ); + for (i = 0; i < 16; i++) + init_2d_map( ctx->EvalMap.Map2Attrib + i, 4, attrib ); } /* Fog group */ @@ -1087,7 +1253,11 @@ init_attrib_groups( GLcontext *ctx ) ctx->Point.MinSize = 0.0; ctx->Point.MaxSize = ctx->Const.MaxPointSize; ctx->Point.Threshold = 1.0; - ctx->Point.SpriteMode = GL_FALSE; /* GL_MESA_sprite_point */ + ctx->Point.PointSprite = GL_FALSE; /* GL_NV_point_sprite */ + ctx->Point.SpriteRMode = GL_ZERO; /* GL_NV_point_sprite */ + for (i = 0; i < MAX_TEXTURE_UNITS; i++) { + ctx->Point.CoordReplace[i] = GL_FALSE; /* GL_NV_point_sprite */ + } /* Polygon group */ ctx->Polygon.CullFlag = GL_FALSE; @@ -1117,18 +1287,28 @@ init_attrib_groups( GLcontext *ctx ) /* Stencil group */ ctx->Stencil.Enabled = GL_FALSE; - ctx->Stencil.Function = GL_ALWAYS; - ctx->Stencil.FailFunc = GL_KEEP; - ctx->Stencil.ZPassFunc = GL_KEEP; - ctx->Stencil.ZFailFunc = GL_KEEP; - ctx->Stencil.Ref = 0; - ctx->Stencil.ValueMask = STENCIL_MAX; + ctx->Stencil.TestTwoSide = GL_FALSE; + ctx->Stencil.ActiveFace = 0; /* 0 = GL_FRONT, 1 = GL_BACK */ + ctx->Stencil.Function[0] = GL_ALWAYS; + ctx->Stencil.Function[1] = GL_ALWAYS; + ctx->Stencil.FailFunc[0] = GL_KEEP; + ctx->Stencil.FailFunc[1] = GL_KEEP; + ctx->Stencil.ZPassFunc[0] = GL_KEEP; + ctx->Stencil.ZPassFunc[1] = GL_KEEP; + ctx->Stencil.ZFailFunc[0] = GL_KEEP; + ctx->Stencil.ZFailFunc[1] = GL_KEEP; + ctx->Stencil.Ref[0] = 0; + ctx->Stencil.Ref[1] = 0; + ctx->Stencil.ValueMask[0] = STENCIL_MAX; + ctx->Stencil.ValueMask[1] = STENCIL_MAX; + ctx->Stencil.WriteMask[0] = STENCIL_MAX; + ctx->Stencil.WriteMask[1] = STENCIL_MAX; ctx->Stencil.Clear = 0; - ctx->Stencil.WriteMask = STENCIL_MAX; /* Texture group */ ctx->Texture.CurrentUnit = 0; /* multitexture */ - ctx->Texture._ReallyEnabled = 0; + ctx->Texture._ReallyEnabled = 0; /* XXX obsolete */ + ctx->Texture._EnabledUnits = 0; for (i=0; iTexture.SharedPalette = GL_FALSE; @@ -1138,11 +1318,11 @@ init_attrib_groups( GLcontext *ctx ) ctx->Transform.MatrixMode = GL_MODELVIEW; ctx->Transform.Normalize = GL_FALSE; ctx->Transform.RescaleNormals = GL_FALSE; + ctx->Transform.RasterPositionUnclipped = GL_FALSE; for (i=0;iTransform.ClipEnabled[i] = GL_FALSE; ASSIGN_4V( ctx->Transform.EyeUserPlane[i], 0.0, 0.0, 0.0, 0.0 ); } - ctx->Transform._AnyClip = GL_FALSE; + ctx->Transform.ClipPlanesEnabled = 0; /* Viewport group */ ctx->Viewport.X = 0; @@ -1155,8 +1335,8 @@ init_attrib_groups( GLcontext *ctx ) #define Sz 10 #define Tz 14 - ctx->Viewport._WindowMap.m[Sz] = 0.5 * ctx->DepthMaxF; - ctx->Viewport._WindowMap.m[Tz] = 0.5 * ctx->DepthMaxF; + ctx->Viewport._WindowMap.m[Sz] = 0.5F * ctx->DepthMaxF; + ctx->Viewport._WindowMap.m[Tz] = 0.5F * ctx->DepthMaxF; #undef Sz #undef Tz @@ -1273,6 +1453,18 @@ init_attrib_groups( GLcontext *ctx ) _mesa_init_colortable(&ctx->PostColorMatrixColorTable); _mesa_init_colortable(&ctx->ProxyPostColorMatrixColorTable); + /* GL_NV_vertex_program */ + ctx->VertexProgram.Enabled = GL_FALSE; + ctx->VertexProgram.PointSizeEnabled = GL_FALSE; + ctx->VertexProgram.TwoSideEnabled = GL_FALSE; + ctx->VertexProgram.CurrentID = 0; + ctx->VertexProgram.ErrorPos = -1; + ctx->VertexProgram.Current = NULL; + for (i = 0; i < VP_NUM_PROG_REGS / 4; i++) { + ctx->VertexProgram.TrackMatrix[i] = GL_NONE; + ctx->VertexProgram.TrackMatrixTransform[i] = GL_IDENTITY_NV; + } + /* Miscellaneous */ ctx->NewState = _NEW_ALL; ctx->RenderMode = GL_RENDER; @@ -1289,14 +1481,14 @@ init_attrib_groups( GLcontext *ctx ) ctx->OcclusionResultSaved = GL_FALSE; /* For debug/development only */ - ctx->NoRaster = getenv("MESA_NO_RASTER") ? GL_TRUE : GL_FALSE; + ctx->NoRaster = ctx->imports.getenv(ctx, "MESA_NO_RASTER") ? GL_TRUE : GL_FALSE; ctx->FirstTimeCurrent = GL_TRUE; /* Dither disable */ - ctx->NoDither = getenv("MESA_NO_DITHER") ? GL_TRUE : GL_FALSE; + ctx->NoDither = ctx->imports.getenv(ctx, "MESA_NO_DITHER") ? GL_TRUE : GL_FALSE; if (ctx->NoDither) { - if (getenv("MESA_DEBUG")) { - fprintf(stderr, "MESA_NO_DITHER set - dithering disabled\n"); + if (ctx->imports.getenv(ctx, "MESA_DEBUG")) { + _mesa_debug(ctx, "MESA_NO_DITHER set - dithering disabled\n"); } ctx->Color.DitherFlag = GL_FALSE; } @@ -1316,25 +1508,26 @@ alloc_proxy_textures( GLcontext *ctx ) GLboolean out_of_memory; GLint i; - ctx->Texture.Proxy1D = _mesa_alloc_texture_object(NULL, 0, 1); + ctx->Texture.Proxy1D = _mesa_alloc_texture_object(NULL, 0, GL_TEXTURE_1D); if (!ctx->Texture.Proxy1D) { return GL_FALSE; } - ctx->Texture.Proxy2D = _mesa_alloc_texture_object(NULL, 0, 2); + ctx->Texture.Proxy2D = _mesa_alloc_texture_object(NULL, 0, GL_TEXTURE_2D); if (!ctx->Texture.Proxy2D) { _mesa_free_texture_object(NULL, ctx->Texture.Proxy1D); return GL_FALSE; } - ctx->Texture.Proxy3D = _mesa_alloc_texture_object(NULL, 0, 3); + ctx->Texture.Proxy3D = _mesa_alloc_texture_object(NULL, 0, GL_TEXTURE_3D); if (!ctx->Texture.Proxy3D) { _mesa_free_texture_object(NULL, ctx->Texture.Proxy1D); _mesa_free_texture_object(NULL, ctx->Texture.Proxy2D); return GL_FALSE; } - ctx->Texture.ProxyCubeMap = _mesa_alloc_texture_object(NULL, 0, 6); + ctx->Texture.ProxyCubeMap = _mesa_alloc_texture_object(NULL, 0, + GL_TEXTURE_CUBE_MAP_ARB); if (!ctx->Texture.ProxyCubeMap) { _mesa_free_texture_object(NULL, ctx->Texture.Proxy1D); _mesa_free_texture_object(NULL, ctx->Texture.Proxy2D); @@ -1342,17 +1535,33 @@ alloc_proxy_textures( GLcontext *ctx ) return GL_FALSE; } + ctx->Texture.ProxyRect = _mesa_alloc_texture_object(NULL, 0, + GL_TEXTURE_RECTANGLE_NV); + if (!ctx->Texture.ProxyRect) { + _mesa_free_texture_object(NULL, ctx->Texture.Proxy1D); + _mesa_free_texture_object(NULL, ctx->Texture.Proxy2D); + _mesa_free_texture_object(NULL, ctx->Texture.Proxy3D); + _mesa_free_texture_object(NULL, ctx->Texture.ProxyCubeMap); + return GL_FALSE; + } + out_of_memory = GL_FALSE; for (i=0;iTexture.Proxy1D->Image[i] = _mesa_alloc_texture_image(); ctx->Texture.Proxy2D->Image[i] = _mesa_alloc_texture_image(); ctx->Texture.Proxy3D->Image[i] = _mesa_alloc_texture_image(); + ctx->Texture.ProxyCubeMap->Image[i] = _mesa_alloc_texture_image(); if (!ctx->Texture.Proxy1D->Image[i] || !ctx->Texture.Proxy2D->Image[i] - || !ctx->Texture.Proxy3D->Image[i]) { + || !ctx->Texture.Proxy3D->Image[i] + || !ctx->Texture.ProxyCubeMap->Image[i]) { out_of_memory = GL_TRUE; } } + ctx->Texture.ProxyRect->Image[0] = _mesa_alloc_texture_image(); + if (!ctx->Texture.ProxyRect->Image[0]) + out_of_memory = GL_TRUE; + if (out_of_memory) { for (i=0;iTexture.Proxy1D->Image[i]) { @@ -1364,10 +1573,18 @@ alloc_proxy_textures( GLcontext *ctx ) if (ctx->Texture.Proxy3D->Image[i]) { _mesa_free_texture_image(ctx->Texture.Proxy3D->Image[i]); } + if (ctx->Texture.ProxyCubeMap->Image[i]) { + _mesa_free_texture_image(ctx->Texture.ProxyCubeMap->Image[i]); + } + } + if (ctx->Texture.ProxyRect->Image[0]) { + _mesa_free_texture_image(ctx->Texture.ProxyRect->Image[0]); } _mesa_free_texture_object(NULL, ctx->Texture.Proxy1D); _mesa_free_texture_object(NULL, ctx->Texture.Proxy2D); _mesa_free_texture_object(NULL, ctx->Texture.Proxy3D); + _mesa_free_texture_object(NULL, ctx->Texture.ProxyCubeMap); + _mesa_free_texture_object(NULL, ctx->Texture.ProxyRect); return GL_FALSE; } else { @@ -1376,6 +1593,44 @@ alloc_proxy_textures( GLcontext *ctx ) } +static void add_debug_flags( const char *debug ) +{ +#ifdef MESA_DEBUG + if (strstr(debug, "varray")) + MESA_VERBOSE |= VERBOSE_VARRAY; + + if (strstr(debug, "tex")) + MESA_VERBOSE |= VERBOSE_TEXTURE; + + if (strstr(debug, "imm")) + MESA_VERBOSE |= VERBOSE_IMMEDIATE; + + if (strstr(debug, "pipe")) + MESA_VERBOSE |= VERBOSE_PIPELINE; + + if (strstr(debug, "driver")) + MESA_VERBOSE |= VERBOSE_DRIVER; + + if (strstr(debug, "state")) + MESA_VERBOSE |= VERBOSE_STATE; + + if (strstr(debug, "api")) + MESA_VERBOSE |= VERBOSE_API; + + if (strstr(debug, "list")) + MESA_VERBOSE |= VERBOSE_DISPLAY_LIST; + + if (strstr(debug, "lighting")) + MESA_VERBOSE |= VERBOSE_LIGHTING; + + /* Debug flag: + */ + if (strstr(debug, "flush")) + MESA_DEBUG_FLAGS |= DEBUG_ALWAYS_FLUSH; +#endif +} + + /* * Initialize a GLcontext struct. This includes allocating all the * other structs and arrays which hang off of the context by pointers. @@ -1384,25 +1639,33 @@ GLboolean _mesa_initialize_context( GLcontext *ctx, const GLvisual *visual, GLcontext *share_list, - void *driver_ctx, - GLboolean direct ) + const __GLimports *imports ) { GLuint dispatchSize; - (void) direct; /* not used */ + ASSERT(imports); + ASSERT(imports->other); /* other points to the device driver's context */ + + /* assing imports */ + ctx->imports = *imports; + + /* initialize the exports (Mesa functions called by the window system) */ + _mesa_init_default_exports( &(ctx->exports) ); /* misc one-time initializations */ - one_time_init(); + one_time_init(ctx); +#if 0 /** ** OpenGL SI stuff **/ if (!ctx->imports.malloc) { - _mesa_InitDefaultImports(&ctx->imports, driver_ctx, NULL); + _mesa_init_default_imports(&ctx->imports, driver_ctx); } /* exports are setup by the device driver */ +#endif - ctx->DriverCtx = driver_ctx; + ctx->DriverCtx = imports->other; ctx->Visual = *visual; ctx->DrawBuffer = NULL; ctx->ReadBuffer = NULL; @@ -1427,22 +1690,23 @@ _mesa_initialize_context( GLcontext *ctx, ctx->Shared->Default2D->RefCount += MAX_TEXTURE_UNITS; ctx->Shared->Default3D->RefCount += MAX_TEXTURE_UNITS; ctx->Shared->DefaultCubeMap->RefCount += MAX_TEXTURE_UNITS; + ctx->Shared->DefaultRect->RefCount += MAX_TEXTURE_UNITS; init_attrib_groups( ctx ); if (visual->doubleBufferMode) { ctx->Color.DrawBuffer = GL_BACK; - ctx->Color.DriverDrawBuffer = GL_BACK_LEFT; - ctx->Color.DrawDestMask = BACK_LEFT_BIT; + ctx->Color._DriverDrawBuffer = GL_BACK_LEFT; + ctx->Color._DrawDestMask = BACK_LEFT_BIT; ctx->Pixel.ReadBuffer = GL_BACK; - ctx->Pixel.DriverReadBuffer = GL_BACK_LEFT; + ctx->Pixel._DriverReadBuffer = GL_BACK_LEFT; } else { ctx->Color.DrawBuffer = GL_FRONT; - ctx->Color.DriverDrawBuffer = GL_FRONT_LEFT; - ctx->Color.DrawDestMask = FRONT_LEFT_BIT; + ctx->Color._DriverDrawBuffer = GL_FRONT_LEFT; + ctx->Color._DrawDestMask = FRONT_LEFT_BIT; ctx->Pixel.ReadBuffer = GL_FRONT; - ctx->Pixel.DriverReadBuffer = GL_FRONT_LEFT; + ctx->Pixel._DriverReadBuffer = GL_FRONT_LEFT; } if (!alloc_proxy_textures(ctx)) { @@ -1459,6 +1723,8 @@ _mesa_initialize_context( GLcontext *ctx, _glapi_add_entrypoint("glCompressedTexSubImage2DARB", 558); _glapi_add_entrypoint("glCompressedTexSubImage1DARB", 559); _glapi_add_entrypoint("glGetCompressedTexImageARB", 560); + /* XXX we should add a bunch of new functions here */ + /* Find the larger of Mesa's dispatch table and libGL's dispatch table. * In practice, this'll be the same for stand-alone Mesa. But for DRI @@ -1539,6 +1805,13 @@ _mesa_initialize_context( GLcontext *ctx, trInitDispatch(ctx->TraceDispatch); #endif + + if (ctx->imports.getenv(ctx, "MESA_DEBUG")) + add_debug_flags(ctx->imports.getenv(ctx, "MESA_DEBUG")); + + if (ctx->imports.getenv(ctx, "MESA_VERBOSE")) + add_debug_flags(ctx->imports.getenv(ctx, "MESA_VERBOSE")); + return GL_TRUE; } @@ -1548,25 +1821,31 @@ _mesa_initialize_context( GLcontext *ctx, * Allocate and initialize a GLcontext structure. * Input: visual - a GLvisual pointer (we copy the struct contents) * sharelist - another context to share display lists with or NULL - * driver_ctx - pointer to device driver's context state struct + * imports - points to a fully-initialized __GLimports object. * Return: pointer to a new __GLcontextRec or NULL if error. */ GLcontext * _mesa_create_context( const GLvisual *visual, GLcontext *share_list, - void *driver_ctx, - GLboolean direct ) + const __GLimports *imports ) { - GLcontext *ctx = (GLcontext *) CALLOC( sizeof(GLcontext) ); - if (!ctx) { + GLcontext *ctx; + + ASSERT(visual); + ASSERT(imports); + ASSERT(imports->calloc); + + ctx = (GLcontext *) imports->calloc(NULL, 1, sizeof(GLcontext)); + if (!ctx) return NULL; - } - if (_mesa_initialize_context(ctx, visual, share_list, driver_ctx, direct)) { + ctx->Driver.CurrentExecPrimitive = 0; /* XXX why is this here??? */ + + if (_mesa_initialize_context(ctx, visual, share_list, imports)) { return ctx; } else { - FREE(ctx); + imports->free(NULL, ctx); return NULL; } } @@ -1581,28 +1860,34 @@ void _mesa_free_context_data( GLcontext *ctx ) { struct gl_shine_tab *s, *tmps; - GLuint i, j; + GLuint i; /* if we're destroying the current context, unbind it first */ if (ctx == _mesa_get_current_context()) { _mesa_make_current(NULL, NULL); } - _math_matrix_dtr( &ctx->ModelView ); - for (i = 0; i < MAX_MODELVIEW_STACK_DEPTH - 1; i++) { - _math_matrix_dtr( &ctx->ModelViewStack[i] ); - } - _math_matrix_dtr( &ctx->ProjectionMatrix ); - for (i = 0; i < MAX_PROJECTION_STACK_DEPTH - 1; i++) { - _math_matrix_dtr( &ctx->ProjectionStack[i] ); - } - for (i = 0; i < MAX_TEXTURE_UNITS; i++) { - _math_matrix_dtr( &ctx->TextureMatrix[i] ); - for (j = 0; j < MAX_TEXTURE_STACK_DEPTH - 1; j++) { - _math_matrix_dtr( &ctx->TextureStack[i][j] ); - } + /* + * Free transformation matrix stacks + */ + free_matrix_stack(&ctx->ModelviewMatrixStack); + free_matrix_stack(&ctx->ProjectionMatrixStack); + free_matrix_stack(&ctx->ColorMatrixStack); + for (i = 0; i < MAX_TEXTURE_UNITS; i++) + free_matrix_stack(&ctx->TextureMatrixStack[i]); + for (i = 0; i < MAX_PROGRAM_MATRICES; i++) + free_matrix_stack(&ctx->ProgramMatrixStack[i]); + /* combined Modelview*Projection matrix */ + _math_matrix_dtr( &ctx->_ModelProjectMatrix ); + + + if (ctx->VertexProgram.Current) { + ctx->VertexProgram.Current->RefCount--; + if (ctx->VertexProgram.Current->RefCount <= 0) + _mesa_delete_program(ctx, ctx->VertexProgram.CurrentID); } + /* Shared context state (display lists, textures, etc) */ _glthread_LOCK_MUTEX(ctx->Shared->Mutex); ctx->Shared->RefCount--; assert(ctx->Shared->RefCount >= 0); @@ -1612,6 +1897,7 @@ _mesa_free_context_data( GLcontext *ctx ) free_shared_state( ctx, ctx->Shared ); } + /* Free lighting shininess exponentiation table */ foreach_s( s, tmps, ctx->_ShineTabList ) { FREE( s ); } @@ -1621,6 +1907,8 @@ _mesa_free_context_data( GLcontext *ctx ) _mesa_free_texture_object( NULL, ctx->Texture.Proxy1D ); _mesa_free_texture_object( NULL, ctx->Texture.Proxy2D ); _mesa_free_texture_object( NULL, ctx->Texture.Proxy3D ); + _mesa_free_texture_object( NULL, ctx->Texture.ProxyCubeMap ); + _mesa_free_texture_object( NULL, ctx->Texture.ProxyRect ); /* Free evaluator data */ if (ctx->EvalMap.Map1Vertex3.Points) @@ -1641,6 +1929,8 @@ _mesa_free_context_data( GLcontext *ctx ) FREE( ctx->EvalMap.Map1Texture3.Points ); if (ctx->EvalMap.Map1Texture4.Points) FREE( ctx->EvalMap.Map1Texture4.Points ); + for (i = 0; i < 16; i++) + FREE((ctx->EvalMap.Map1Attrib[i].Points)); if (ctx->EvalMap.Map2Vertex3.Points) FREE( ctx->EvalMap.Map2Vertex3.Points ); @@ -1660,12 +1950,16 @@ _mesa_free_context_data( GLcontext *ctx ) FREE( ctx->EvalMap.Map2Texture3.Points ); if (ctx->EvalMap.Map2Texture4.Points) FREE( ctx->EvalMap.Map2Texture4.Points ); + for (i = 0; i < 16; i++) + FREE((ctx->EvalMap.Map2Attrib[i].Points)); _mesa_free_colortable_data( &ctx->ColorTable ); _mesa_free_colortable_data( &ctx->PostConvolutionColorTable ); _mesa_free_colortable_data( &ctx->PostColorMatrixColorTable ); _mesa_free_colortable_data( &ctx->Texture.Palette ); + _math_matrix_dtr(&ctx->Viewport._WindowMap); + _mesa_extensions_dtr(ctx); FREE(ctx->Exec); @@ -1698,116 +1992,149 @@ void _mesa_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask ) { if (mask & GL_ACCUM_BUFFER_BIT) { - MEMCPY( &dst->Accum, &src->Accum, sizeof(struct gl_accum_attrib) ); + /* OK to memcpy */ + dst->Accum = src->Accum; } if (mask & GL_COLOR_BUFFER_BIT) { - MEMCPY( &dst->Color, &src->Color, sizeof(struct gl_colorbuffer_attrib) ); + /* OK to memcpy */ + dst->Color = src->Color; } if (mask & GL_CURRENT_BIT) { - MEMCPY( &dst->Current, &src->Current, sizeof(struct gl_current_attrib) ); + /* OK to memcpy */ + dst->Current = src->Current; } if (mask & GL_DEPTH_BUFFER_BIT) { - MEMCPY( &dst->Depth, &src->Depth, sizeof(struct gl_depthbuffer_attrib) ); + /* OK to memcpy */ + dst->Depth = src->Depth; } if (mask & GL_ENABLE_BIT) { /* no op */ } if (mask & GL_EVAL_BIT) { - MEMCPY( &dst->Eval, &src->Eval, sizeof(struct gl_eval_attrib) ); + /* OK to memcpy */ + dst->Eval = src->Eval; } if (mask & GL_FOG_BIT) { - MEMCPY( &dst->Fog, &src->Fog, sizeof(struct gl_fog_attrib) ); + /* OK to memcpy */ + dst->Fog = src->Fog; } if (mask & GL_HINT_BIT) { - MEMCPY( &dst->Hint, &src->Hint, sizeof(struct gl_hint_attrib) ); + /* OK to memcpy */ + dst->Hint = src->Hint; } if (mask & GL_LIGHTING_BIT) { - MEMCPY( &dst->Light, &src->Light, sizeof(struct gl_light_attrib) ); - /* gl_reinit_light_attrib( &dst->Light ); */ + GLuint i; + /* begin with memcpy */ + MEMCPY( &dst->Light, &src->Light, sizeof(struct gl_light) ); + /* fixup linked lists to prevent pointer insanity */ + make_empty_list( &(dst->Light.EnabledList) ); + for (i = 0; i < MAX_LIGHTS; i++) { + if (dst->Light.Light[i].Enabled) { + insert_at_tail(&(dst->Light.EnabledList), &(dst->Light.Light[i])); + } + } } if (mask & GL_LINE_BIT) { - MEMCPY( &dst->Line, &src->Line, sizeof(struct gl_line_attrib) ); + /* OK to memcpy */ + dst->Line = src->Line; } if (mask & GL_LIST_BIT) { - MEMCPY( &dst->List, &src->List, sizeof(struct gl_list_attrib) ); + /* OK to memcpy */ + dst->List = src->List; } if (mask & GL_PIXEL_MODE_BIT) { - MEMCPY( &dst->Pixel, &src->Pixel, sizeof(struct gl_pixel_attrib) ); + /* OK to memcpy */ + dst->Pixel = src->Pixel; } if (mask & GL_POINT_BIT) { - MEMCPY( &dst->Point, &src->Point, sizeof(struct gl_point_attrib) ); + /* OK to memcpy */ + dst->Point = src->Point; } if (mask & GL_POLYGON_BIT) { - MEMCPY( &dst->Polygon, &src->Polygon, sizeof(struct gl_polygon_attrib) ); + /* OK to memcpy */ + dst->Polygon = src->Polygon; } if (mask & GL_POLYGON_STIPPLE_BIT) { /* Use loop instead of MEMCPY due to problem with Portland Group's * C compiler. Reported by John Stone. */ - int i; - for (i=0;i<32;i++) { + GLuint i; + for (i = 0; i < 32; i++) { dst->PolygonStipple[i] = src->PolygonStipple[i]; } } if (mask & GL_SCISSOR_BIT) { - MEMCPY( &dst->Scissor, &src->Scissor, sizeof(struct gl_scissor_attrib) ); + /* OK to memcpy */ + dst->Scissor = src->Scissor; } if (mask & GL_STENCIL_BUFFER_BIT) { - MEMCPY( &dst->Stencil, &src->Stencil, sizeof(struct gl_stencil_attrib) ); + /* OK to memcpy */ + dst->Stencil = src->Stencil; } if (mask & GL_TEXTURE_BIT) { - MEMCPY( &dst->Texture, &src->Texture, sizeof(struct gl_texture_attrib) ); + /* Cannot memcpy because of pointers */ + _mesa_copy_texture_state(src, dst); } if (mask & GL_TRANSFORM_BIT) { - MEMCPY( &dst->Transform, &src->Transform, sizeof(struct gl_transform_attrib) ); + /* OK to memcpy */ + dst->Transform = src->Transform; } if (mask & GL_VIEWPORT_BIT) { - MEMCPY( &dst->Viewport, &src->Viewport, sizeof(struct gl_viewport_attrib) ); + /* Cannot use memcpy, because of pointers in GLmatrix _WindowMap */ + dst->Viewport.X = src->Viewport.X; + dst->Viewport.Y = src->Viewport.Y; + dst->Viewport.Width = src->Viewport.Width; + dst->Viewport.Height = src->Viewport.Height; + dst->Viewport.Near = src->Viewport.Near; + dst->Viewport.Far = src->Viewport.Far; + _math_matrix_copy(&dst->Viewport._WindowMap, &src->Viewport._WindowMap); } + /* XXX FIXME: Call callbacks? */ dst->NewState = _NEW_ALL; } -/* - * Set the current context, binding the given frame buffer to the context. - */ -void -_mesa_make_current( GLcontext *newCtx, GLframebuffer *buffer ) -{ - _mesa_make_current2( newCtx, buffer, buffer ); -} - static void print_info( void ) { - fprintf(stderr, "Mesa GL_VERSION = %s\n", + _mesa_debug(NULL, "Mesa GL_VERSION = %s\n", (char *) _mesa_GetString(GL_VERSION)); - fprintf(stderr, "Mesa GL_RENDERER = %s\n", + _mesa_debug(NULL, "Mesa GL_RENDERER = %s\n", (char *) _mesa_GetString(GL_RENDERER)); - fprintf(stderr, "Mesa GL_VENDOR = %s\n", + _mesa_debug(NULL, "Mesa GL_VENDOR = %s\n", (char *) _mesa_GetString(GL_VENDOR)); - fprintf(stderr, "Mesa GL_EXTENSIONS = %s\n", + _mesa_debug(NULL, "Mesa GL_EXTENSIONS = %s\n", (char *) _mesa_GetString(GL_EXTENSIONS)); #if defined(THREADS) - fprintf(stderr, "Mesa thread-safe: YES\n"); + _mesa_debug(NULL, "Mesa thread-safe: YES\n"); #else - fprintf(stderr, "Mesa thread-safe: NO\n"); + _mesa_debug(NULL, "Mesa thread-safe: NO\n"); #endif #if defined(USE_X86_ASM) - fprintf(stderr, "Mesa x86-optimized: YES\n"); + _mesa_debug(NULL, "Mesa x86-optimized: YES\n"); #else - fprintf(stderr, "Mesa x86-optimized: NO\n"); + _mesa_debug(NULL, "Mesa x86-optimized: NO\n"); #endif #if defined(USE_SPARC_ASM) - fprintf(stderr, "Mesa sparc-optimized: YES\n"); + _mesa_debug(NULL, "Mesa sparc-optimized: YES\n"); #else - fprintf(stderr, "Mesa sparc-optimized: NO\n"); + _mesa_debug(NULL, "Mesa sparc-optimized: NO\n"); #endif } +/* + * Set the current context, binding the given frame buffer to the context. + */ +void +_mesa_make_current( GLcontext *newCtx, GLframebuffer *buffer ) +{ + _mesa_make_current2( newCtx, buffer, buffer ); +} + + /* * Bind the given context to the given draw-buffer and read-buffer * and make it the current context for this thread. @@ -1817,7 +2144,7 @@ _mesa_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer, GLframebuffer *readBuffer ) { if (MESA_VERBOSE) - fprintf(stderr, "_mesa_make_current2()\n"); + _mesa_debug(newCtx, "_mesa_make_current2()\n"); /* Check that the context's and framebuffer's visuals are compatible. * We could do a lot more checking here but this'll catch obvious @@ -1853,9 +2180,42 @@ _mesa_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer, newCtx->DrawBuffer = drawBuffer; newCtx->ReadBuffer = readBuffer; newCtx->NewState |= _NEW_BUFFERS; - /* _mesa_update_state( newCtx ); */ + + if (drawBuffer->Width == 0 && drawBuffer->Height == 0) { + /* get initial window size */ + GLuint bufWidth, bufHeight; + + /* ask device driver for size of output buffer */ + (*newCtx->Driver.GetBufferSize)( drawBuffer, &bufWidth, &bufHeight ); + + if (drawBuffer->Width == bufWidth && drawBuffer->Height == bufHeight) + return; /* size is as expected */ + + drawBuffer->Width = bufWidth; + drawBuffer->Height = bufHeight; + + newCtx->Driver.ResizeBuffers( drawBuffer ); + } + + if (readBuffer != drawBuffer && + readBuffer->Width == 0 && readBuffer->Height == 0) { + /* get initial window size */ + GLuint bufWidth, bufHeight; + + /* ask device driver for size of output buffer */ + (*newCtx->Driver.GetBufferSize)( readBuffer, &bufWidth, &bufHeight ); + + if (readBuffer->Width == bufWidth && readBuffer->Height == bufHeight) + return; /* size is as expected */ + + readBuffer->Width = bufWidth; + readBuffer->Height = bufHeight; + + newCtx->Driver.ResizeBuffers( readBuffer ); + } } + /* This is only for T&L - a bit out of place, or misnamed (BP) */ if (newCtx->Driver.MakeCurrent) newCtx->Driver.MakeCurrent( newCtx, drawBuffer, readBuffer ); @@ -1865,7 +2225,7 @@ _mesa_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer, * information. */ if (newCtx->FirstTimeCurrent) { - if (getenv("MESA_INFO")) { + if (newCtx->imports.getenv(newCtx, "MESA_INFO")) { print_info(); } newCtx->FirstTimeCurrent = GL_FALSE; @@ -1891,6 +2251,7 @@ _mesa_get_current_context( void ) /* * This should be called by device drivers just before they do a * swapbuffers. Any pending rendering commands will be executed. + * XXX we should really rename this function to _mesa_flush() or something. */ void _mesa_swapbuffers(GLcontext *ctx) @@ -1919,110 +2280,14 @@ _mesa_get_dispatch(GLcontext *ctx) /* - * This function is called when the Mesa user has stumbled into a code - * path which may not be implemented fully or correctly. - */ -void _mesa_problem( const GLcontext *ctx, const char *s ) -{ - fprintf( stderr, "Mesa implementation error: %s\n", s ); -#ifdef XF86DRI - fprintf( stderr, "Please report to the DRI bug database at dri.sourceforge.net\n"); -#else - fprintf( stderr, "Please report to the Mesa bug database at www.mesa3d.org\n" ); -#endif - (void) ctx; -} - - - -/* - * This is called to inform the user that he or she has tried to do - * something illogical or if there's likely a bug in their program - * (like enabled depth testing without a depth buffer). + * Record the given error code and call the driver's Error function if defined. + * This is called via _mesa_error(). */ void -_mesa_warning( const GLcontext *ctx, const char *s ) +_mesa_record_error( GLcontext *ctx, GLenum error ) { - (*ctx->imports.warning)((__GLcontext *) ctx, (char *) s); -} - - - -/* - * Compile an error into current display list. - */ -void -_mesa_compile_error( GLcontext *ctx, GLenum error, const char *s ) -{ - if (ctx->CompileFlag) - _mesa_save_error( ctx, error, s ); - - if (ctx->ExecuteFlag) - _mesa_error( ctx, error, s ); -} - - - -/* - * This is Mesa's error handler. Normally, all that's done is the updating - * of the current error value. If Mesa is compiled with -DDEBUG or if the - * environment variable "MESA_DEBUG" is defined then a real error message - * is printed to stderr. - * Input: ctx - the GL context - * error - the error value - * where - usually the name of function where error was detected - */ -void -_mesa_error( GLcontext *ctx, GLenum error, const char *where ) -{ - const char *debugEnv = getenv("MESA_DEBUG"); - GLboolean debug; - -#ifdef DEBUG - if (debugEnv && strstr(debugEnv, "silent")) - debug = GL_FALSE; - else - debug = GL_TRUE; -#else - if (debugEnv) - debug = GL_TRUE; - else - debug = GL_FALSE; -#endif - - if (debug) { - const char *errstr; - switch (error) { - case GL_NO_ERROR: - errstr = "GL_NO_ERROR"; - break; - case GL_INVALID_VALUE: - errstr = "GL_INVALID_VALUE"; - break; - case GL_INVALID_ENUM: - errstr = "GL_INVALID_ENUM"; - break; - case GL_INVALID_OPERATION: - errstr = "GL_INVALID_OPERATION"; - break; - case GL_STACK_OVERFLOW: - errstr = "GL_STACK_OVERFLOW"; - break; - case GL_STACK_UNDERFLOW: - errstr = "GL_STACK_UNDERFLOW"; - break; - case GL_OUT_OF_MEMORY: - errstr = "GL_OUT_OF_MEMORY"; - break; - case GL_TABLE_TOO_LARGE: - errstr = "GL_TABLE_TOO_LARGE"; - break; - default: - errstr = "unknown"; - break; - } - fprintf(stderr, "Mesa user error: %s in %s\n", errstr, where); - } + if (!ctx) + return; if (ctx->ErrorValue == GL_NO_ERROR) { ctx->ErrorValue = error; @@ -2035,7 +2300,6 @@ _mesa_error( GLcontext *ctx, GLenum error, const char *where ) } - void _mesa_Finish( void ) {