X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fcontext.c;h=aa9d11299961a1c31f73d40b2365974e1c92867d;hb=28876dd511ec2c9d5f5500499201df2588e8c7f1;hp=72c85de7ba2a13ac419705b1899d941e0f254c8e;hpb=d619cceea47dc3070ebb7f7ea4f8b6b31a672d38;p=mesa.git diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 72c85de7ba2..aa9d1129996 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -6,9 +6,9 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 7.1 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 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"), @@ -97,23 +97,17 @@ #include "fog.h" #include "framebuffer.h" #include "get.h" -#include "glthread.h" -#include "glapioffsets.h" #include "histogram.h" #include "hint.h" #include "hash.h" -#include "atifragshader.h" #include "light.h" #include "lines.h" #include "macros.h" #include "matrix.h" -#include "occlude.h" #include "pixel.h" #include "points.h" #include "polygon.h" -#if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program -#include "program.h" -#endif +#include "queryobj.h" #include "rastpos.h" #include "simple_list.h" #include "state.h" @@ -126,13 +120,18 @@ #include "varray.h" #include "version.h" #include "vtxfmt.h" +#include "glapi/glthread.h" +#if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program +#include "shader/program.h" +#endif +#include "shader/shader_api.h" +#include "shader/atifragshader.h" #if _HAVE_FULL_GL #include "math/m_translate.h" #include "math/m_matrix.h" #include "math/m_xform.h" #include "math/mathmod.h" #endif -#include "shader_api.h" #ifdef USE_SPARC_ASM #include "sparc/sparc.h" @@ -150,169 +149,7 @@ int MESA_DEBUG_FLAGS = 0; /* ubyte -> float conversion */ GLfloat _mesa_ubyte_to_float_color_tab[256]; -static void -free_shared_state( GLcontext *ctx, struct gl_shared_state *ss ); - - -/**********************************************************************/ -/** \name OpenGL SI-style interface (new in Mesa 3.5) - * - * \if subset - * \note Most of these functions are never called in the Mesa subset. - * \endif - */ -/*@{*/ - -/** - * Destroy context callback. - * - * \param gc context. - * \return GL_TRUE on success, or GL_FALSE on failure. - * - * \ifnot subset - * Called by window system/device driver (via __GLexports::destroyCurrent) when - * the rendering context is to be destroyed. - * \endif - * - * Frees the context data and the context structure. - */ -GLboolean -_mesa_destroyContext(__GLcontext *gc) -{ - if (gc) { - _mesa_free_context_data(gc); - _mesa_free(gc); - } - return GL_TRUE; -} - -/** - * Unbind context callback. - * - * \param gc context. - * \return GL_TRUE on success, or GL_FALSE on failure. - * - * \ifnot subset - * Called by window system/device driver (via __GLexports::loseCurrent) - * when the rendering context is made non-current. - * \endif - * - * No-op - */ -GLboolean -_mesa_loseCurrent(__GLcontext *gc) -{ - /* XXX unbind context from thread */ - (void) gc; - return GL_TRUE; -} - -/** - * Bind context callback. - * - * \param gc context. - * \return GL_TRUE on success, or GL_FALSE on failure. - * - * \ifnot subset - * Called by window system/device driver (via __GLexports::makeCurrent) - * when the rendering context is made current. - * \endif - * - * No-op - */ -GLboolean -_mesa_makeCurrent(__GLcontext *gc) -{ - /* XXX bind context to thread */ - (void) gc; - return GL_TRUE; -} - -/** - * Share context callback. - * - * \param gc context. - * \param gcShare shared context. - * \return GL_TRUE on success, or GL_FALSE on failure. - * - * \ifnot subset - * Called by window system/device driver (via __GLexports::shareContext) - * \endif - * - * Update the shared context reference count, gl_shared_state::RefCount. - */ -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; - } -} - - -#if _HAVE_FULL_GL -/** - * Copy context callback. - */ -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; - } -} -#endif - -/** No-op */ -GLboolean -_mesa_forceCurrent(__GLcontext *gc) -{ - (void) gc; - return GL_TRUE; -} -/** - * Windows/buffer resizing notification callback. - * - * \param gc GL context. - * \return GL_TRUE on success, or GL_FALSE on failure. - */ -GLboolean -_mesa_notifyResize(__GLcontext *gc) -{ - /* update viewport, resize software buffers, etc. */ - (void) gc; - return GL_TRUE; -} - -/** - * Window/buffer destruction notification callback. - * - * \param gc GL context. - * - * Called when the context's window/buffer is going to be destroyed. - * - * No-op - */ -void -_mesa_notifyDestroy(__GLcontext *gc) -{ - /* Unbind from it. */ - (void) gc; -} /** * Swap buffers notification callback. @@ -328,105 +165,6 @@ _mesa_notifySwapBuffers(__GLcontext *gc) FLUSH_VERTICES( gc, 0 ); } -/** No-op */ -struct __GLdispatchStateRec * -_mesa_dispatchExec(__GLcontext *gc) -{ - (void) gc; - return NULL; -} - -/** No-op */ -void -_mesa_beginDispatchOverride(__GLcontext *gc) -{ - (void) gc; -} - -/** No-op */ -void -_mesa_endDispatchOverride(__GLcontext *gc) -{ - (void) gc; -} - -/** - * \ifnot subset - * 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). - * \endif - * - * \if subset - * No-op. - * - * \endif - */ -static void -_mesa_init_default_exports(__GLexports *exports) -{ -#if _HAVE_FULL_GL - 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; -#else - (void) exports; -#endif -} - -/** - * Exported OpenGL SI interface. - */ -__GLcontext * -__glCoreCreateContext(__GLimports *imports, __GLcontextModes *modes) -{ - GLcontext *ctx; - - ctx = (GLcontext *) (*imports->calloc)(NULL, 1, sizeof(GLcontext)); - if (ctx == NULL) { - return NULL; - } - - /* XXX doesn't work at this time */ - _mesa_initialize_context(ctx, modes, NULL, NULL, NULL); - ctx->imports = *imports; - - return ctx; -} - -/** - * Exported OpenGL SI interface. - */ -void -__glCoreNopDispatch(void) -{ -#if 0 - /* SI */ - __gl_dispatch = __glNopDispatchState; -#else - /* Mesa */ - _glapi_set_dispatch(NULL); -#endif -} - -/*@}*/ - /**********************************************************************/ /** \name GL Visual allocation/destruction */ @@ -621,6 +359,8 @@ one_time_init( GLcontext *ctx ) assert( sizeof(GLint) == 4 ); assert( sizeof(GLuint) == 4 ); + _mesa_init_sqrt_table(); + #if _HAVE_FULL_GL _math_init(); @@ -678,12 +418,14 @@ alloc_shared_state( GLcontext *ctx ) #endif #if FEATURE_ARB_vertex_program - ss->DefaultVertexProgram = ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0); + ss->DefaultVertexProgram = (struct gl_vertex_program *) + ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0); if (!ss->DefaultVertexProgram) goto cleanup; #endif #if FEATURE_ARB_fragment_program - ss->DefaultFragmentProgram = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); + ss->DefaultFragmentProgram = (struct gl_fragment_program *) + ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); if (!ss->DefaultFragmentProgram) goto cleanup; #endif @@ -724,17 +466,20 @@ alloc_shared_state( GLcontext *ctx ) if (!ss->DefaultRect) goto cleanup; - /* Effectively bind the default textures to all texture units */ - ss->Default1D->RefCount += MAX_TEXTURE_IMAGE_UNITS; - ss->Default2D->RefCount += MAX_TEXTURE_IMAGE_UNITS; - ss->Default3D->RefCount += MAX_TEXTURE_IMAGE_UNITS; - ss->DefaultCubeMap->RefCount += MAX_TEXTURE_IMAGE_UNITS; - ss->DefaultRect->RefCount += MAX_TEXTURE_IMAGE_UNITS; + ss->Default1DArray = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D_ARRAY_EXT); + if (!ss->Default1DArray) + goto cleanup; + + ss->Default2DArray = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D_ARRAY_EXT); + if (!ss->Default2DArray) + goto cleanup; + + /* sanity check */ + assert(ss->Default1D->RefCount == 1); _glthread_INIT_MUTEX(ss->TexMutex); ss->TextureStateStamp = 0; - #if FEATURE_EXT_framebuffer_object ss->FrameBuffers = _mesa_NewHashTable(); if (!ss->FrameBuffers) @@ -744,10 +489,9 @@ alloc_shared_state( GLcontext *ctx ) goto cleanup; #endif - return GL_TRUE; - cleanup: +cleanup: /* Ran out of memory at some point. Free everything and return NULL */ if (ss->DisplayList) _mesa_DeleteHashTable(ss->DisplayList); @@ -758,12 +502,10 @@ alloc_shared_state( GLcontext *ctx ) _mesa_DeleteHashTable(ss->Programs); #endif #if FEATURE_ARB_vertex_program - if (ss->DefaultVertexProgram) - ctx->Driver.DeleteProgram(ctx, ss->DefaultVertexProgram); + _mesa_reference_vertprog(ctx, &ss->DefaultVertexProgram, NULL); #endif #if FEATURE_ARB_fragment_program - if (ss->DefaultFragmentProgram) - ctx->Driver.DeleteProgram(ctx, ss->DefaultFragmentProgram); + _mesa_reference_fragprog(ctx, &ss->DefaultFragmentProgram, NULL); #endif #if FEATURE_ATI_fragment_shader if (ss->DefaultFragmentShader) @@ -799,8 +541,13 @@ alloc_shared_state( GLcontext *ctx ) (*ctx->Driver.DeleteTexture)(ctx, ss->DefaultCubeMap); if (ss->DefaultRect) (*ctx->Driver.DeleteTexture)(ctx, ss->DefaultRect); - if (ss) - _mesa_free(ss); + if (ss->Default1DArray) + (*ctx->Driver.DeleteTexture)(ctx, ss->Default1DArray); + if (ss->Default2DArray) + (*ctx->Driver.DeleteTexture)(ctx, ss->Default2DArray); + + _mesa_free(ss); + return GL_FALSE; } @@ -835,6 +582,8 @@ delete_program_cb(GLuint id, void *data, void *userData) { struct gl_program *prog = (struct gl_program *) data; GLcontext *ctx = (GLcontext *) userData; + ASSERT(prog->RefCount == 1); /* should only be referenced by hash table */ + prog->RefCount = 0; /* now going away */ ctx->Driver.DeleteProgram(ctx, prog); } @@ -872,6 +621,21 @@ delete_arrayobj_cb(GLuint id, void *data, void *userData) _mesa_delete_array_object(ctx, arrayObj); } +/** + * Callback for freeing shader program data. Call it before delete_shader_cb + * to avoid memory access error. + */ +static void +free_shader_program_data_cb(GLuint id, void *data, void *userData) +{ + GLcontext *ctx = (GLcontext *) userData; + struct gl_shader_program *shProg = (struct gl_shader_program *) data; + + if (shProg->Type == GL_SHADER_PROGRAM_MESA) { + _mesa_free_shader_program_data(ctx, shProg); + } +} + /** * Callback for deleting shader and shader programs objects. * Called by _mesa_HashDeleteAll(). @@ -886,11 +650,44 @@ delete_shader_cb(GLuint id, void *data, void *userData) } else { struct gl_shader_program *shProg = (struct gl_shader_program *) data; - ASSERT(shProg->Type == GL_SHADER_PROGRAM); + ASSERT(shProg->Type == GL_SHADER_PROGRAM_MESA); _mesa_free_shader_program(ctx, shProg); } } +/** + * Callback for deleting a framebuffer object. Called by _mesa_HashDeleteAll() + */ +static void +delete_framebuffer_cb(GLuint id, void *data, void *userData) +{ + struct gl_framebuffer *fb = (struct gl_framebuffer *) data; + /* The fact that the framebuffer is in the hashtable means its refcount + * is one, but we're removing from the hashtable now. So clear refcount. + */ + /*assert(fb->RefCount == 1);*/ + fb->RefCount = 0; + + /* NOTE: Delete should always be defined but there are two reports + * of it being NULL (bugs 13507, 14293). Work-around for now. + */ + if (fb->Delete) + fb->Delete(fb); +} + +/** + * Callback for deleting a renderbuffer object. Called by _mesa_HashDeleteAll() + */ +static void +delete_renderbuffer_cb(GLuint id, void *data, void *userData) +{ + struct gl_renderbuffer *rb = (struct gl_renderbuffer *) data; + rb->RefCount = 0; /* see comment for FBOs above */ + if (rb->Delete) + rb->Delete(rb); +} + + /** * Deallocate a shared state object and all children structures. @@ -913,29 +710,21 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss ) _mesa_HashDeleteAll(ss->DisplayList, delete_displaylist_cb, ctx); _mesa_DeleteHashTable(ss->DisplayList); - /* - * Free texture objects - */ - ASSERT(ctx->Driver.DeleteTexture); - /* the default textures */ - ctx->Driver.DeleteTexture(ctx, ss->Default1D); - ctx->Driver.DeleteTexture(ctx, ss->Default2D); - ctx->Driver.DeleteTexture(ctx, ss->Default3D); - ctx->Driver.DeleteTexture(ctx, ss->DefaultCubeMap); - ctx->Driver.DeleteTexture(ctx, ss->DefaultRect); - /* all other textures */ - _mesa_HashDeleteAll(ss->TexObjects, delete_texture_cb, ctx); - _mesa_DeleteHashTable(ss->TexObjects); +#if FEATURE_ARB_shader_objects + _mesa_HashWalk(ss->ShaderObjects, free_shader_program_data_cb, ctx); + _mesa_HashDeleteAll(ss->ShaderObjects, delete_shader_cb, ctx); + _mesa_DeleteHashTable(ss->ShaderObjects); +#endif #if defined(FEATURE_NV_vertex_program) || defined(FEATURE_NV_fragment_program) _mesa_HashDeleteAll(ss->Programs, delete_program_cb, ctx); _mesa_DeleteHashTable(ss->Programs); #endif #if FEATURE_ARB_vertex_program - _mesa_delete_program(ctx, ss->DefaultVertexProgram); + _mesa_reference_vertprog(ctx, &ss->DefaultVertexProgram, NULL); #endif #if FEATURE_ARB_fragment_program - _mesa_delete_program(ctx, ss->DefaultFragmentProgram); + _mesa_reference_fragprog(ctx, &ss->DefaultFragmentProgram, NULL); #endif #if FEATURE_ATI_fragment_shader @@ -952,16 +741,30 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss ) _mesa_HashDeleteAll(ss->ArrayObjects, delete_arrayobj_cb, ctx); _mesa_DeleteHashTable(ss->ArrayObjects); -#if FEATURE_ARB_shader_objects - _mesa_HashDeleteAll(ss->ShaderObjects, delete_shader_cb, ctx); - _mesa_DeleteHashTable(ss->ShaderObjects); -#endif - #if FEATURE_EXT_framebuffer_object + _mesa_HashDeleteAll(ss->FrameBuffers, delete_framebuffer_cb, ctx); _mesa_DeleteHashTable(ss->FrameBuffers); + _mesa_HashDeleteAll(ss->RenderBuffers, delete_renderbuffer_cb, ctx); _mesa_DeleteHashTable(ss->RenderBuffers); #endif + /* + * Free texture objects (after FBOs since some textures might have + * been bound to FBOs). + */ + ASSERT(ctx->Driver.DeleteTexture); + /* the default textures */ + ctx->Driver.DeleteTexture(ctx, ss->Default1D); + ctx->Driver.DeleteTexture(ctx, ss->Default2D); + ctx->Driver.DeleteTexture(ctx, ss->Default3D); + ctx->Driver.DeleteTexture(ctx, ss->DefaultCubeMap); + ctx->Driver.DeleteTexture(ctx, ss->DefaultRect); + ctx->Driver.DeleteTexture(ctx, ss->Default1DArray); + ctx->Driver.DeleteTexture(ctx, ss->Default2DArray); + /* all other textures */ + _mesa_HashDeleteAll(ss->TexObjects, delete_texture_cb, ctx); + _mesa_DeleteHashTable(ss->TexObjects); + _glthread_DESTROY_MUTEX(ss->Mutex); _mesa_free(ss); @@ -982,7 +785,7 @@ _mesa_init_current(GLcontext *ctx) } /* redo special cases: */ - ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 1.0, 0.0, 0.0, 1.0 ); + ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 1.0, 0.0, 0.0, 0.0 ); ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], 0.0, 0.0, 1.0, 1.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, 1.0 ); @@ -1029,6 +832,7 @@ _mesa_init_constants(GLcontext *ctx) ctx->Const.Max3DTextureLevels = MAX_3D_TEXTURE_LEVELS; ctx->Const.MaxCubeTextureLevels = MAX_CUBE_TEXTURE_LEVELS; ctx->Const.MaxTextureRectSize = MAX_TEXTURE_RECT_SIZE; + ctx->Const.MaxArrayTextureLayers = MAX_ARRAY_TEXTURE_LAYERS; ctx->Const.MaxTextureCoordUnits = MAX_TEXTURE_COORD_UNITS; ctx->Const.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS; ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureCoordUnits, @@ -1062,10 +866,10 @@ _mesa_init_constants(GLcontext *ctx) ctx->Const.VertexProgram.MaxTexInstructions = 0; ctx->Const.VertexProgram.MaxTexIndirections = 0; ctx->Const.VertexProgram.MaxAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS; - ctx->Const.VertexProgram.MaxTemps = MAX_NV_VERTEX_PROGRAM_TEMPS; + ctx->Const.VertexProgram.MaxTemps = MAX_PROGRAM_TEMPS; ctx->Const.VertexProgram.MaxParameters = MAX_NV_VERTEX_PROGRAM_PARAMS; ctx->Const.VertexProgram.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS; - ctx->Const.VertexProgram.MaxEnvParams = MAX_NV_VERTEX_PROGRAM_PARAMS; + ctx->Const.VertexProgram.MaxEnvParams = MAX_PROGRAM_ENV_PARAMS; ctx->Const.VertexProgram.MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS; ctx->Const.VertexProgram.MaxUniformComponents = 4 * MAX_UNIFORMS; init_natives(&ctx->Const.VertexProgram); @@ -1077,10 +881,10 @@ _mesa_init_constants(GLcontext *ctx) ctx->Const.FragmentProgram.MaxTexInstructions = MAX_FRAGMENT_PROGRAM_TEX_INSTRUCTIONS; ctx->Const.FragmentProgram.MaxTexIndirections = MAX_FRAGMENT_PROGRAM_TEX_INDIRECTIONS; ctx->Const.FragmentProgram.MaxAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS; - ctx->Const.FragmentProgram.MaxTemps = MAX_NV_FRAGMENT_PROGRAM_TEMPS; + ctx->Const.FragmentProgram.MaxTemps = MAX_PROGRAM_TEMPS; ctx->Const.FragmentProgram.MaxParameters = MAX_NV_FRAGMENT_PROGRAM_PARAMS; ctx->Const.FragmentProgram.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS; - ctx->Const.FragmentProgram.MaxEnvParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS; + ctx->Const.FragmentProgram.MaxEnvParams = MAX_PROGRAM_ENV_PARAMS; ctx->Const.FragmentProgram.MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS; ctx->Const.FragmentProgram.MaxUniformComponents = 4 * MAX_UNIFORMS; init_natives(&ctx->Const.FragmentProgram); @@ -1180,6 +984,7 @@ init_attrib_groups(GLcontext *ctx) _mesa_init_debug( ctx ); _mesa_init_display_list( ctx ); _mesa_init_eval( ctx ); + _mesa_init_fbobjects( ctx ); _mesa_init_feedback( ctx ); _mesa_init_fog( ctx ); _mesa_init_histogram( ctx ); @@ -1210,7 +1015,28 @@ init_attrib_groups(GLcontext *ctx) /* Miscellaneous */ ctx->NewState = _NEW_ALL; ctx->ErrorValue = (GLenum) GL_NO_ERROR; - ctx->_Facing = 0; + + return GL_TRUE; +} + + +/** + * Update default objects in a GL context with respect to shared state. + * + * \param ctx GL context. + * + * Removes references to old default objects, (texture objects, program + * objects, etc.) and changes to reference those from the current shared + * state. + */ +static GLboolean +update_default_objects(GLcontext *ctx) +{ + assert(ctx); + + _mesa_update_default_objects_program(ctx); + _mesa_update_default_objects_texture(ctx); + _mesa_update_default_objects_buffer_objects(ctx); return GL_TRUE; } @@ -1224,7 +1050,7 @@ init_attrib_groups(GLcontext *ctx) static int generic_nop(void) { - _mesa_problem(NULL, "User called no-op dispatch function (an unsupported extension function?)"); + _mesa_warning(NULL, "User called no-op dispatch function (an unsupported extension function?)"); return 0; } @@ -1292,14 +1118,6 @@ _mesa_initialize_context(GLcontext *ctx, assert(driverFunctions->NewTextureObject); assert(driverFunctions->FreeTexImageData); - /* If the driver wants core Mesa to use special imports, it'll have to - * override these defaults. - */ - _mesa_init_default_imports( &(ctx->imports), driverContext ); - - /* initialize the exports (Mesa functions called by the window system) */ - _mesa_init_default_exports( &(ctx->exports) ); - /* misc one-time initializations */ one_time_init(ctx); @@ -1355,14 +1173,16 @@ _mesa_initialize_context(GLcontext *ctx, ctx->TnlModule.SwapCount = 0; #endif + ctx->FragmentProgram._MaintainTexEnvProgram + = (_mesa_getenv("MESA_TEX_PROG") != NULL); + ctx->FragmentProgram._UseTexEnvProgram = ctx->FragmentProgram._MaintainTexEnvProgram; + ctx->VertexProgram._MaintainTnlProgram = (_mesa_getenv("MESA_TNL_PROG") != NULL); - if (ctx->VertexProgram._MaintainTnlProgram) + if (ctx->VertexProgram._MaintainTnlProgram) { /* this is required... */ ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; - else - ctx->FragmentProgram._MaintainTexEnvProgram - = (_mesa_getenv("MESA_TEX_PROG") != NULL); + } ctx->FirstTimeCurrent = GL_TRUE; @@ -1420,18 +1240,28 @@ _mesa_create_context(const GLvisual *visual, void _mesa_free_context_data( GLcontext *ctx ) { - /* if we're destroying the current context, unbind it first */ - if (ctx == _mesa_get_current_context()) { - _mesa_make_current(NULL, NULL, NULL); - } - else { - /* unreference WinSysDraw/Read buffers */ - _mesa_unreference_framebuffer(&ctx->WinSysDrawBuffer); - _mesa_unreference_framebuffer(&ctx->WinSysReadBuffer); - _mesa_unreference_framebuffer(&ctx->DrawBuffer); - _mesa_unreference_framebuffer(&ctx->ReadBuffer); + if (!_mesa_get_current_context()){ + /* No current context, but we may need one in order to delete + * texture objs, etc. So temporarily bind the context now. + */ + _mesa_make_current(ctx, NULL, NULL); } + /* unreference WinSysDraw/Read buffers */ + _mesa_unreference_framebuffer(&ctx->WinSysDrawBuffer); + _mesa_unreference_framebuffer(&ctx->WinSysReadBuffer); + _mesa_unreference_framebuffer(&ctx->DrawBuffer); + _mesa_unreference_framebuffer(&ctx->ReadBuffer); + + _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL); + _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL); + _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, NULL); + + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL); + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL); + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL); + + _mesa_free_attrib_data(ctx); _mesa_free_lighting_data( ctx ); _mesa_free_eval_data( ctx ); _mesa_free_texture_data( ctx ); @@ -1463,6 +1293,11 @@ _mesa_free_context_data( GLcontext *ctx ) if (ctx->Extensions.String) _mesa_free((void *) ctx->Extensions.String); + + /* unbind the context if it's currently bound */ + if (ctx == _mesa_get_current_context()) { + _mesa_make_current(NULL, NULL, NULL); + } } @@ -1609,9 +1444,9 @@ _mesa_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask ) * Check if the given context can render into the given framebuffer * by checking visual attributes. * - * XXX this may go away someday because we're moving toward more freedom - * in binding contexts to drawables with different visual attributes. - * The GL_EXT_f_b_o extension is prompting some of that. + * Most of these tests could go away because Mesa is now pretty flexible + * in terms of mixing rendering contexts with framebuffers. As long + * as RGB vs. CI mode agree, we're probably good. * * \return GL_TRUE if compatible, GL_FALSE otherwise. */ @@ -1645,8 +1480,11 @@ check_compatible(const GLcontext *ctx, const GLframebuffer *buffer) return GL_FALSE; if (ctxvis->blueMask && ctxvis->blueMask != bufvis->blueMask) return GL_FALSE; +#if 0 + /* disabled (see bug 11161) */ if (ctxvis->depthBits && ctxvis->depthBits != bufvis->depthBits) return GL_FALSE; +#endif if (ctxvis->stencilBits && ctxvis->stencilBits != bufvis->stencilBits) return GL_FALSE; @@ -1691,8 +1529,6 @@ void _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer, GLframebuffer *readBuffer ) { - GET_CURRENT_CONTEXT(oldCtx); - if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(newCtx, "_mesa_make_current()\n"); @@ -1713,39 +1549,10 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer, } } -#if 0 /** XXX enable this someday */ - if (oldCtx && oldCtx != newCtx) { - /* unbind old context's draw/read buffers */ - if (oldCtx->DrawBuffer && oldCtx->DrawBuffer->Name == 0) { - oldCtx->DrawBuffer->RefCount--; - oldCtx->DrawBuffer = NULL; - } - if (oldCtx->ReadBuffer && oldCtx->ReadBuffer->Name == 0) { - oldCtx->ReadBuffer->RefCount--; - oldCtx->ReadBuffer = NULL; - } - if (oldCtx->WinSysDrawBuffer) { - ASSERT(oldCtx->WinSysDrawBuffer->Name == 0); - oldCtx->WinSysDrawBuffer->RefCount--; - oldCtx->WinSysDrawBuffer = NULL; - } - if (oldCtx->WinSysReadBuffer) { - ASSERT(oldCtx->WinSysReadBuffer->Name == 0); - oldCtx->WinSysReadBuffer->RefCount--; - oldCtx->WinSysReadBuffer = NULL; - } - } -#endif - /* We used to call _glapi_check_multithread() here. Now do it in drivers */ _glapi_set_context((void *) newCtx); ASSERT(_mesa_get_current_context() == newCtx); - if (oldCtx) { - _mesa_unreference_framebuffer(&oldCtx->WinSysDrawBuffer); - _mesa_unreference_framebuffer(&oldCtx->WinSysReadBuffer); - } - if (!newCtx) { _glapi_set_dispatch(NULL); /* none current */ } @@ -1771,6 +1578,9 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer, _mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer); } + /* XXX only set this flag if we're really changing the draw/read + * framebuffer bindings. + */ newCtx->NewState |= _NEW_BUFFERS; #if 1 @@ -1838,12 +1648,18 @@ GLboolean _mesa_share_state(GLcontext *ctx, GLcontext *ctxToShare) { if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) { - ctx->Shared->RefCount--; - if (ctx->Shared->RefCount == 0) { - free_shared_state(ctx, ctx->Shared); - } + struct gl_shared_state *oldSharedState = ctx->Shared; + ctx->Shared = ctxToShare->Shared; ctx->Shared->RefCount++; + + update_default_objects(ctx); + + oldSharedState->RefCount--; + if (oldSharedState->RefCount == 0) { + free_shared_state(ctx, oldSharedState); + } + return GL_TRUE; } else {