context.c
来自「Mesa is an open-source implementation of」· C语言 代码 · 共 1,776 行 · 第 1/4 页
C
1,776 行
ctx->Const.FragmentProgram.MaxUniformComponents = 4 * MAX_UNIFORMS; init_natives(&ctx->Const.FragmentProgram);#endif ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES; ctx->Const.MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH; /* CheckArrayBounds is overriden by drivers/x11 for X server */ ctx->Const.CheckArrayBounds = GL_FALSE; /* GL_ARB_draw_buffers */ 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#if FEATURE_ARB_vertex_shader ctx->Const.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS; ctx->Const.MaxVarying = MAX_VARYING;#endif /* sanity checks */ ASSERT(ctx->Const.MaxTextureUnits == MIN2(ctx->Const.MaxTextureImageUnits, ctx->Const.MaxTextureCoordUnits)); ASSERT(ctx->Const.FragmentProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS); ASSERT(ctx->Const.VertexProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS); ASSERT(MAX_NV_FRAGMENT_PROGRAM_TEMPS <= MAX_PROGRAM_TEMPS); ASSERT(MAX_NV_VERTEX_PROGRAM_TEMPS <= MAX_PROGRAM_TEMPS); ASSERT(MAX_NV_VERTEX_PROGRAM_INPUTS <= VERT_ATTRIB_MAX); ASSERT(MAX_NV_VERTEX_PROGRAM_OUTPUTS <= VERT_RESULT_MAX);}/** * Do some sanity checks on the limits/constants for the given context. * Only called the first time a context is bound. */static voidcheck_context_limits(GLcontext *ctx){ /* Many context limits/constants are limited by the size of * internal arrays. */ assert(ctx->Const.MaxTextureImageUnits <= MAX_TEXTURE_IMAGE_UNITS); assert(ctx->Const.MaxTextureCoordUnits <= MAX_TEXTURE_COORD_UNITS); assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_IMAGE_UNITS); assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_COORD_UNITS); assert(ctx->Const.MaxViewportWidth <= MAX_WIDTH); assert(ctx->Const.MaxViewportHeight <= MAX_WIDTH); /* make sure largest texture image is <= MAX_WIDTH in size */ assert((1 << (ctx->Const.MaxTextureLevels -1 )) <= MAX_WIDTH); assert((1 << (ctx->Const.MaxCubeTextureLevels -1 )) <= MAX_WIDTH); assert((1 << (ctx->Const.Max3DTextureLevels -1 )) <= MAX_WIDTH); assert(ctx->Const.MaxDrawBuffers <= MAX_DRAW_BUFFERS); /* XXX probably add more tests */}/** * 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 GLbooleaninit_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_fbobjects( 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_pixel( ctx ); _mesa_init_point( ctx ); _mesa_init_polygon( ctx ); _mesa_init_program( ctx ); _mesa_init_query( ctx ); _mesa_init_rastpos( ctx ); _mesa_init_scissor( ctx ); _mesa_init_shader_state( 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; 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 GLbooleanupdate_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;}/** * 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 intgeneric_nop(void){ _mesa_warning(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); /* 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->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) { /* this is required... */ ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; } ctx->FirstTimeCurrent = GL_TRUE; 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 (!_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 ); _mesa_free_matrix_data( ctx ); _mesa_free_viewport_data( ctx ); _mesa_free_colortables_data( ctx ); _mesa_free_program_data(ctx); _mesa_free_shader_state(ctx); _mesa_free_query_data(ctx);#if FEATURE_ARB_vertex_buffer_object _mesa_delete_buffer_object(ctx, ctx->Array.NullBufferObj);#endif _mesa_delete_array_object(ctx, ctx->Array.DefaultArrayObj); /* 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 ); } 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); }}/** * Destroy a GLcontext structure. * * \param ctx GL context. * * Calls _mesa_free_context_data() and frees the GLcontext structure itself. */void_mesa_destroy_context( GLcontext *ctx ){ if (ctx) { _mesa_free_context_data(ctx); _mesa_free( (void *) ctx ); }}#if _HAVE_FULL_GL/** * Copy attribute groups from one context to another. * * \param src source context * \param dst destination context * \param mask bitwise OR of GL_*_BIT flags * * According to the bits specified in \p mask, copies the corresponding * attributes from \p src into \p dst. For many of the attributes a simple \c * memcpy is not enough due to the existence of internal pointers in their data * structures.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?