Mesa3d Source Code Reading Notes (3) _ wglMakeCurrent Parsing

Source: Internet
Author: User

Next, let's take a look at what happened after the WMesaMakeCurrent function calls _ mesa_make_current:

_ Mesa_make_current // context. c from row 1,310th to row 1,436th GLboolean_mesa_make_current (GLcontext * newCtx, GLframebuffer * drawBuffer, GLframebuffer * readBuffer) {if (MESA_VERBOSE & VERBOSE_API) _ mesa_debug (newCtx, "_ mesa_make_current () \ n ");/* Check that the context's and framebuffer's comparator als are compatible. */if (newCtx & drawBuffer & newCtx-> WinSysDrawBuffer! = DrawBuffer) {if (! Check_compatible (newCtx, drawBuffer) {_ mesa_warning (newCtx, "MakeCurrent: incompatible events als for context and drawbuffer"); return GL_FALSE ;}} if (newCtx & readBuffer & newCtx-> WinSysReadBuffer! = ReadBuffer) {if (! Check_compatible (newCtx, readBuffer) {_ mesa_warning (newCtx, "MakeCurrent: incompatible logs als for context and readbuffer"); return GL_FALSE ;}/ * 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 (! NewCtx) {_ glapi_set_dispatch (NULL);/* none current */} else {_ glapi_set_dispatch (newCtx-> CurrentDispatch); if (drawBuffer & readBuffer) {/* TODO: check if newCtx and buffer's visual match ??? */ASSERT (drawBuffer-> Name = 0); ASSERT (readBuffer-> Name = 0); _ mesa_reference_framebuffer (& newCtx-> WinSysDrawBuffer, drawBuffer ); _ mesa_reference_framebuffer (& newCtx-> WinSysReadBuffer, readBuffer ); /** Only set the context's Draw/ReadBuffer fields if they're NULL * or not bound to a user-created FBO. */if (! NewCtx-> DrawBuffer | newCtx-> DrawBuffer-> Name = 0) {/* KW: merge conflict here, revisit. * // * fix up the fb fields-these will end up wrong otherwise * if the DRIdrawable changes, and everything relies on them. * This is a bit messy (same as needed in _ mesa_BindFramebufferEXT) */unsigned int I; GLenum buffers [MAX_DRAW_BUFFERS]; _ buffers (& newCtx-> DrawBuffer, drawBuffer); (I = 0; I <newCtx-> Const. maxDrawBuffers; I ++) {buffers [I] = newCtx-> Color. drawBuffer [I];} _ mesa_drawbuffers (newCtx, newCtx-> Const. maxDrawBuffers, buffers, NULL);} if (! NewCtx-> ReadBuffer | newCtx-> ReadBuffer-> Name = 0) {_ mesa_reference_framebuffer (& newCtx-> ReadBuffer, readBuffer );} /* XXX only set this flag if we're re really changing the draw/read * framebuffer bindings. */newCtx-> NewState | = _ NEW_BUFFERS; # if 1/* We want to get rid of these lines: */# if _ HAVE_FULL_GL if (! DrawBuffer-> Initialized) {initialize_framebuffer_size (newCtx, drawBuffer);} if (readBuffer! = DrawBuffer &&! ReadBuffer-> Initialized) {initialize_framebuffer_size (newCtx, readBuffer);} _ mesa_resizebuffers (newCtx); # endif # else/* We want the drawBuffer and readBuffer to be initialized by * the driver. * This generally means the Width and Height match the actual * window size and the renderbuffers (both hardware and software * based) are allocated to match. the later can generally be * done with a call to _ mesa_resize_framebuffer (). ** It's theoretically possible for a buffer to have zero width * or height, but for now, assert check that the driver did what's * expected of it. */ASSERT (drawBuffer-> Width> 0); ASSERT (drawBuffer-> Height> 0); # endif if (drawBuffer) {_ mesa_check_init_viewport (newCtx, drawBuffer-> Width, drawBuffer-> Height) ;}} if (newCtx-> FirstTimeCurrent) {check_context_limits (newCtx);/* We can use this to help debug user's problems. tell them to set * the MESA_INFO env variable before running their app. then the * first time each context is made current we'll print some useful * information. */if (_ mesa_getenv ("MESA_INFO") {_ mesa_print_info ();} newCtx-> FirstTimeCurrent = GL_FALSE;} return GL_TRUE ;}

Line 3 calls glapi. the _ glapi_set_context function in c sets the current ctx, that is, the value of the project global variable _ glapi_Context points to the context, and the first member in the wmesa_context structure is GLcontext, so the pointer addresses of the two are the same;
In line 3, call _ glapi_set_dispatch in glapi. c to set the current function handle, that is, set the global variable _ glapi_Dispatch to point.
In glapitable. h defines the _ glapi_table structure, which includes all the gl * function pointer member variables of the OpenGL release function. Basically, the Code body of the function released in the gl * series obtains the address of the current _ glapi_Dispatch member, call the function pointer address pointed to by the Member. The assignment of these members is done when the _ mesa_initialize_context function is executed. Here, call _ glapi_set_dispatch to match _ glapi_Dispatch with the specific corresponding function address.
If _ mesa_make_current is not called to associate the two, _ glapi_Dispatch points to _ glapi_noop_table. If NULL is used to call _ mesa_make_current, _ glapi_Dispatch points to _ glapi_noop_table.
The global variable _ glapi_noop_table in the file domain is in glapi. c contains glapitemp. h define macro replacement to declare the definition. On the one hand, the macro replacement defines a group of empty gl * functions that only warn and do not do anything. The first is Noop *, like their functions, these function pointers are then collected to indicate the value of the _ glapi_noop_table variable. Obviously, if the user does not call wglMakeCurrent beforehand to associate it with the available hglrc, therefore, gl * series functions should not be used.
The operations on the frame cache area will not be followed for the time being.

Now let's look back at the members related to _ glapi_table in the GLcontext structure and their initialization values:

// mtypes.h  /*2893*/ struct __GLcontextRec/*2894*/ {            // ....../*2898*/    /** \name API function pointer tables *//*2899*/    /*@{*//*2900*/    struct _glapi_table *Save;/**< Display list save functions *//*2901*/    struct _glapi_table *Exec;/**< Execute functions *//*2902*/    struct _glapi_table *CurrentDispatch;  /**< == Save or Exec !! *//*2903*/    /*@}*/            // ....../*3094*/ };

_ GLcontextRec is the GLcontext structure. Members Save and Exec are initialized when _ mesa_initialize_context. Many gl * release functions set the corresponding function pointer address here, the following code tries to figure out the specific work done by the function:

_ Mesa_initialize_context/context. c from row 843rd to row 933 (GLcontext * ctx, const GLvisual * visual, GLcontext * share_list, const struct dd_function_table * driverFunctions, void * driverContext) {struct gl_shared_state * shared; /* 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 (cmd_list) {/* share state with another context */shared = cmd_list-> Shared;} else {/* allocate new, unshared state */shared = _ mesa_alloc_shared_state (ctx); if (! Shared) return GL_FALSE;} _ glthread_LOCK_MUTEX (shared-> Mutex); ctx-> Shared = shared; shared-> RefCount ++; _ glthread_UNLOCK_MUTEX (shared-> Mutex ); if (! Init_attrib_groups (ctx) {_ mesa_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) {_ mesa_free_shared_state (ctx, ctx-> Shared); if (ctx-> Exec) _ mesa_free (ctx-> Exec); return GL_FALSE ;} # if FEATURE_dispatch _ mesa_init_exec_table (ctx-> Exec); # endif ctx-> CurrentDispatch = ctx-> Exec; # if FEATURE_dlist _ mesa_init_dlist_table (ctx-> Save ); _ mesa_install_save_vtxfmt (ctx, & ctx-> ListState. listVtxfmt); # endif/* Neutral tnl module stuff */_ mesa_init_exec_vtxfmt (ctx); ctx-> TnlModu Le. Current = NULL; ctx-> TnlModule. SwapCount = 0; ctx-> FragmentProgram. _ MaintainTexEnvProgram = (_ mesa_getenv ("MESA_TEX_PROG ")! = NULL); ctx-> VertexProgram. _ MaintainTnlProgram = (_ mesa_getenv ("MESA_TNL_PROG ")! = NULL); if (ctx-> VertexProgram. _ MaintainTnlProgram) {/* this is required... */ctx-> FragmentProgram. _ MaintainTexEnvProgram = GL_TRUE;} # ifdef FEATURE_extra_context_init _ mesa_initialize_context_extra (ctx); # endif ctx-> FirstTimeCurrent = GL_TRUE; return GL_TRUE ;}

Row 3: apply for the _ glapi_table structure, initialize with a warning function pointer, and assign it to ctx-> Exec. The 896th rows are the same;
Row 3: Call the _ mesa_init_exec_table function of Row 3 in api_exec.c to set the pointer of each member of ctx-> Exec to the corresponding engineering function;
Row 3: sets the current function Shard to point to ctx-> Exec;
Rows 908th and 909th initialize ctx-> Save and do not parse the data temporarily;
The second line is to call the _ mesa_init_exec_vtxfmt function in vtxfmt. c to set the initialization of the member function pointer corresponding to the GLvertexformat structure in ctx-> Exec;
The GLvertexformat structure is defined in the dd. h header file. All the functions it contains are functions that may be used between glBegin () and glEnd.
Neutral_vtxfmt is a file domain global variable defined by vtxfmt_tmp.h in the definition macro vtxfmt_tmp.h. The Code bodies of these functions are similar and it is estimated that they interact with the tnl module;
Lines 913rd and 914 indicate that no Member values have been exchanged between the vtxfmt and tnl modules.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.