📄 context.c
字号:
#if FEATURE_ATI_fragment_shader
_mesa_delete_program(ctx, ss->DefaultFragmentShader);
#endif
#if FEATURE_ARB_vertex_buffer_object
_mesa_DeleteHashTable(ss->BufferObjects);
#endif
_mesa_DeleteHashTable (ss->GL2Objects);
#if FEATURE_EXT_framebuffer_object
_mesa_DeleteHashTable(ss->FrameBuffers);
_mesa_DeleteHashTable(ss->RenderBuffers);
#endif
_glthread_DESTROY_MUTEX(ss->Mutex);
FREE(ss);
}
/**
* Initialize fields of gl_current_attrib (aka ctx->Current.*)
*/
static void
_mesa_init_current( GLcontext *ctx )
{
GLuint i;
/* Current group */
for (i = 0; i < VERT_ATTRIB_MAX; i++) {
ASSIGN_4V( ctx->Current.Attrib[i], 0.0, 0.0, 0.0, 1.0 );
}
/* 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_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 );
ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_FOG], 0.0, 0.0, 0.0, 0.0 );
ctx->Current.Index = 1;
ctx->Current.EdgeFlag = GL_TRUE;
}
/**
* Initialize fields of gl_constants (aka ctx->Const.*).
* Use defaults from config.h. The device drivers will often override
* some of these values (such as number of texture units).
*/
static void
_mesa_init_constants( GLcontext *ctx )
{
assert(ctx);
assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS);
assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS);
/* Constants, may be overriden (usually only reduced) by device drivers */
ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS;
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.MaxTextureCoordUnits = MAX_TEXTURE_COORD_UNITS;
ctx->Const.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_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 = (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 = (GLfloat) LINE_WIDTH_GRANULARITY;
ctx->Const.MaxColorTableSize = MAX_COLOR_TABLE_SIZE;
ctx->Const.MaxConvolutionWidth = MAX_CONVOLUTION_WIDTH;
ctx->Const.MaxConvolutionHeight = MAX_CONVOLUTION_HEIGHT;
ctx->Const.MaxClipPlanes = MAX_CLIP_PLANES;
ctx->Const.MaxLights = MAX_LIGHTS;
ctx->Const.MaxShininess = 128.0;
ctx->Const.MaxSpotExponent = 128.0;
ctx->Const.MaxViewportWidth = MAX_WIDTH;
ctx->Const.MaxViewportHeight = MAX_HEIGHT;
#if FEATURE_ARB_vertex_program
ctx->Const.MaxVertexProgramInstructions = MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS;
ctx->Const.MaxVertexProgramAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS;
ctx->Const.MaxVertexProgramTemps = MAX_NV_VERTEX_PROGRAM_TEMPS;
ctx->Const.MaxVertexProgramLocalParams = MAX_NV_VERTEX_PROGRAM_PARAMS;
ctx->Const.MaxVertexProgramEnvParams = MAX_NV_VERTEX_PROGRAM_PARAMS;/*XXX*/
ctx->Const.MaxVertexProgramAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
#endif
#if FEATURE_ARB_fragment_program
ctx->Const.MaxFragmentProgramInstructions = MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS;
ctx->Const.MaxFragmentProgramAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS;
ctx->Const.MaxFragmentProgramTemps = MAX_NV_FRAGMENT_PROGRAM_TEMPS;
ctx->Const.MaxFragmentProgramLocalParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
ctx->Const.MaxFragmentProgramEnvParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;/*XXX*/
ctx->Const.MaxFragmentProgramAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
ctx->Const.MaxFragmentProgramAluInstructions = MAX_FRAGMENT_PROGRAM_ALU_INSTRUCTIONS;
ctx->Const.MaxFragmentProgramTexInstructions = MAX_FRAGMENT_PROGRAM_TEX_INSTRUCTIONS;
ctx->Const.MaxFragmentProgramTexIndirections = MAX_FRAGMENT_PROGRAM_TEX_INDIRECTIONS;
#endif
ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES;
ctx->Const.MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH;
/* If we're running in the X server, do bounds checking to prevent
* segfaults and server crashes!
*/
#if defined(XFree86LOADER) && defined(IN_MODULE)
ctx->Const.CheckArrayBounds = GL_TRUE;
#else
ctx->Const.CheckArrayBounds = GL_FALSE;
#endif
ctx->Const.MaxDrawBuffers = MAX_DRAW_BUFFERS;
/* GL_OES_read_format */
ctx->Const.ColorReadFormat = GL_RGBA;
ctx->Const.ColorReadType = GL_UNSIGNED_BYTE;
#if FEATURE_EXT_framebuffer_object
ctx->Const.MaxColorAttachments = MAX_COLOR_ATTACHMENTS;
ctx->Const.MaxRenderbufferSize = MAX_WIDTH;
#endif
/* sanity checks */
ASSERT(ctx->Const.MaxTextureUnits == MAX2(ctx->Const.MaxTextureImageUnits, ctx->Const.MaxTextureCoordUnits));
}
/**
* Initialize the attribute groups in a GL context.
*
* \param ctx GL context.
*
* Initializes all the attributes, calling the respective <tt>init*</tt>
* functions for the more complex data structures.
*/
static GLboolean
init_attrib_groups( GLcontext *ctx )
{
assert(ctx);
/* Constants */
_mesa_init_constants( ctx );
/* Extensions */
_mesa_init_extensions( ctx );
/* Attribute Groups */
_mesa_init_accum( ctx );
_mesa_init_attrib( ctx );
_mesa_init_buffer_objects( ctx );
_mesa_init_color( ctx );
_mesa_init_colortables( ctx );
_mesa_init_current( ctx );
_mesa_init_depth( ctx );
_mesa_init_debug( ctx );
_mesa_init_display_list( ctx );
_mesa_init_eval( ctx );
_mesa_init_feedback( ctx );
_mesa_init_fog( ctx );
_mesa_init_histogram( ctx );
_mesa_init_hint( ctx );
_mesa_init_line( ctx );
_mesa_init_lighting( ctx );
_mesa_init_matrix( ctx );
_mesa_init_multisample( ctx );
_mesa_init_occlude( ctx );
_mesa_init_pixel( ctx );
_mesa_init_point( ctx );
_mesa_init_polygon( ctx );
_mesa_init_program( ctx );
_mesa_init_rastpos( ctx );
_mesa_init_scissor( ctx );
_mesa_init_shaderobjects (ctx);
_mesa_init_stencil( ctx );
_mesa_init_transform( ctx );
_mesa_init_varray( ctx );
_mesa_init_viewport( ctx );
if (!_mesa_init_texture( ctx ))
return GL_FALSE;
_mesa_init_texture_s3tc( ctx );
_mesa_init_texture_fxt1( ctx );
/* Miscellaneous */
ctx->NewState = _NEW_ALL;
ctx->ErrorValue = (GLenum) GL_NO_ERROR;
ctx->_Facing = 0;
#if CHAN_TYPE == GL_FLOAT
ctx->ClampFragmentColors = GL_FALSE; /* XXX temporary */
#else
ctx->ClampFragmentColors = GL_TRUE;
#endif
ctx->ClampVertexColors = GL_TRUE;
return GL_TRUE;
}
/**
* This is the default function we plug into all dispatch table slots
* This helps prevents a segfault when someone calls a GL function without
* first checking if the extension's supported.
*/
static int
generic_nop(void)
{
_mesa_problem(NULL, "User called no-op dispatch function (an unsupported extension function?)");
return 0;
}
/**
* Allocate and initialize a new dispatch table.
*/
static struct _glapi_table *
alloc_dispatch_table(void)
{
/* 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
* Mesa we do this to accomodate different versions of libGL and various
* DRI drivers.
*/
GLint numEntries = MAX2(_glapi_get_dispatch_table_size(),
sizeof(struct _glapi_table) / sizeof(_glapi_proc));
struct _glapi_table *table =
(struct _glapi_table *) _mesa_malloc(numEntries * sizeof(_glapi_proc));
if (table) {
_glapi_proc *entry = (_glapi_proc *) table;
GLint i;
for (i = 0; i < numEntries; i++) {
entry[i] = (_glapi_proc) generic_nop;
}
}
return table;
}
/**
* Initialize a GLcontext struct (rendering context).
*
* This includes allocating all the other structs and arrays which hang off of
* the context by pointers.
* Note that the driver needs to pass in its dd_function_table here since
* we need to at least call driverFunctions->NewTextureObject to create the
* default texture objects.
*
* Called by _mesa_create_context().
*
* Performs the imports and exports callback tables initialization, and
* miscellaneous one-time initializations. If no shared context is supplied one
* is allocated, and increase its reference count. Setups the GL API dispatch
* tables. Initialize the TNL module. Sets the maximum Z buffer depth.
* Finally queries the \c MESA_DEBUG and \c MESA_VERBOSE environment variables
* for debug flags.
*
* \param ctx the context to initialize
* \param visual describes the visual attributes for this context
* \param share_list points to context to share textures, display lists,
* etc with, or NULL
* \param driverFunctions table of device driver functions for this context
* to use
* \param driverContext pointer to driver-specific context data
*/
GLboolean
_mesa_initialize_context( GLcontext *ctx,
const GLvisual *visual,
GLcontext *share_list,
const struct dd_function_table *driverFunctions,
void *driverContext )
{
ASSERT(driverContext);
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);
ctx->Visual = *visual;
ctx->DrawBuffer = NULL;
ctx->ReadBuffer = NULL;
ctx->WinSysDrawBuffer = NULL;
ctx->WinSysReadBuffer = NULL;
/* Plug in driver functions and context pointer here.
* This is important because when we call alloc_shared_state() below
* we'll call ctx->Driver.NewTextureObject() to create the default
* textures.
*/
ctx->Driver = *driverFunctions;
ctx->DriverCtx = driverContext;
if (share_list) {
/* share state with another context */
ctx->Shared = share_list->Shared;
}
else {
/* allocate new, unshared state */
if (!alloc_shared_state( ctx )) {
return GL_FALSE;
}
}
_glthread_LOCK_MUTEX(ctx->Shared->Mutex);
ctx->Shared->RefCount++;
_glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
if (!init_attrib_groups( ctx )) {
free_shared_state(ctx, ctx->Shared);
return GL_FALSE;
}
/* setup the API dispatch tables */
ctx->Exec = alloc_dispatch_table();
ctx->Save = alloc_dispatch_table();
if (!ctx->Exec || !ctx->Save) {
free_shared_state(ctx, ctx->Shared);
if (ctx->Exec)
_mesa_free(ctx->Exec);
}
_mesa_init_exec_table(ctx->Exec);
ctx->CurrentDispatch = ctx->Exec;
#if _HAVE_FULL_GL
_mesa_init_dlist_table(ctx->Save);
_mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
/* Neutral tnl module stuff */
_mesa_init_exec_vtxfmt( ctx );
ctx->TnlModule.Current = NULL;
ctx->TnlModule.SwapCount = 0;
#endif
ctx->_MaintainTexEnvProgram = (_mesa_getenv("MESA_TEX_PROG") != NULL);
ctx->_MaintainTnlProgram = (_mesa_getenv("MESA_TNL_PROG") != NULL);
return GL_TRUE;
}
/**
* Allocate and initialize a GLcontext structure.
* Note that the driver needs to pass in its dd_function_table here since
* we need to at least call driverFunctions->NewTextureObject to initialize
* the rendering context.
*
* \param visual a GLvisual pointer (we copy the struct contents)
* \param share_list another context to share display lists with or NULL
* \param driverFunctions points to the dd_function_table into which the
* driver has plugged in all its special functions.
* \param driverCtx points to the device driver's private context state
*
* \return pointer to a new __GLcontextRec or NULL if error.
*/
GLcontext *
_mesa_create_context( const GLvisual *visual,
GLcontext *share_list,
const struct dd_function_table *driverFunctions,
void *driverContext )
{
GLcontext *ctx;
ASSERT(visual);
ASSERT(driverContext);
ctx = (GLcontext *) _mesa_calloc(sizeof(GLcontext));
if (!ctx)
return NULL;
if (_mesa_initialize_context(ctx, visual, share_list,
driverFunctions, driverContext)) {
return ctx;
}
else {
_mesa_free(ctx);
return NULL;
}
}
/**
* Free the data associated with the given context.
*
* But doesn't free the GLcontext struct itself.
*
* \sa _mesa_initialize_context() and init_attrib_groups().
*/
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);
}
_mesa_free_lighting_data( ctx );
_mesa_free_eval_data( ctx );
_mesa_free_texture_data( ctx );
_mesa_free_matrix_data( ctx );
_mesa_free_viewport_data( ctx );
_mesa_free_colortables_data( ctx );
_mesa_free_program_data(ctx);
_mesa_free_occlude_data(ctx);
#if FEATURE_ARB_vertex_buffer_object
_mesa_delete_buffer_object(ctx, ctx->Array.NullBufferObj);
#endif
/* free dispatch tables */
_mesa_free(ctx->Exec);
_mesa_free(ctx->Save);
/* Shared context state (display lists, textures, etc) */
_glthread_LOCK_MUTEX(ctx->Shared->Mutex);
ctx->Shared->RefCount--;
assert(ctx->Shared->RefCount >= 0);
_glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
if (ctx->Shared->RefCount == 0) {
/* free shared state */
free_shared_state( ctx, ctx->Shared );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -