文章目录
1 概述
Mesa的核心数据结构包含以下几类:
- Context
- Interface
2 Context
2.1 GLXContext
include/GL/glx.h
typedef struct __GLXcontextRec *GLXContext;
src/gallium/state_trackers/glx/xlib/glx_api.c
/**
* The GLXContext typedef is defined as a pointer to this structure.
*/
struct __GLXcontextRec
{
Display *currentDpy;
GLboolean isDirect;
GLXDrawable currentDrawable;
GLXDrawable currentReadable;
XID xid;
XMesaContext xmesaContext;
};
2.2 XMesaContext
src/gallium/state_trackers/glx/xlib/xm_api.h
#include "main/mtypes.h" /* for gl_config */
#include "state_tracker/st_api.h"
#include "os/os_thread.h"
#include "state_tracker/xlibsw_api.h"
# include <X11/Xlib.h>
# include <X11/Xlibint.h>
# include <X11/Xutil.h>
struct hud_context;
typedef struct xmesa_display *XMesaDisplay;
typedef struct xmesa_buffer *XMesaBuffer;
typedef struct xmesa_context *XMesaContext;
typedef struct xmesa_visual *XMesaVisual;
struct xmesa_display {
mtx_t mutex;
Display *display;
struct pipe_screen *screen;
struct st_manager *smapi;
struct pipe_context *pipe;
};
// 省略
/**
* Context info, derived from st_context.
* Basically corresponds to a GLXContext.
*/
struct xmesa_context {
struct st_context_iface *st;
XMesaVisual xm_visual; /** pixel format info */
XMesaBuffer xm_buffer; /** current drawbuffer */
XMesaBuffer xm_read_buffer; /** current readbuffer */
struct hud_context *hud;
};
2.3 gl_context
src/mesa/main/mtypes.h
/**
* Mesa rendering context.
*
* This is the central context data structure for Mesa. Almost all
* OpenGL state is contained in this structure.
* Think of this as a base class from which device drivers will derive
* sub classes.
*/
struct gl_context
{
/** State possibly shared with other contexts in the address space */
struct gl_shared_state *Shared;
/** \name API function pointer tables */
/*@{*/
gl_api API;
/**
* The current dispatch table for non-displaylist-saving execution, either
* BeginEnd or OutsideBeginEnd
*/
struct _glapi_table *Exec;
/**
* The normal dispatch table for non-displaylist-saving, non-begin/end
*/
struct _glapi_table *OutsideBeginEnd;
/** The dispatch table used between glNewList() and glEndList() */
struct _glapi_table *Save;
/**
* The dispatch table used between glBegin() and glEnd() (outside of a
* display list). Only valid functions between those two are set, which is
* mostly just the set in a GLvertexformat struct.
*/
struct _glapi_table *BeginEnd;
/**
* Dispatch table for when a graphics reset has happened.
*/
struct _glapi_table *ContextLost;
/**
* Dispatch table used to marshal API calls from the client program to a
* separate server thread. NULL if API calls are not being marshalled to
* another thread.
*/
struct _glapi_table *MarshalExec;
/**
* Dispatch table currently in use for fielding API calls from the client
* program. If API calls are being marshalled to another thread, this ==
* MarshalExec. Otherwise it == CurrentServerDispatch.
*/
struct _glapi_table *CurrentClientDispatch;
/**
* Dispatch table currently in use for performing API calls. == Save or
* Exec.
*/
struct _glapi_table *CurrentServerDispatch;
/*@}*/
struct glthread_state *GLThread;
struct gl_config Visual;
struct gl_framebuffer *DrawBuffer; /**< buffer for writing */
struct gl_framebuffer *ReadBuffer; /**< buffer for reading */
struct gl_framebuffer *WinSysDrawBuffer; /**< set with MakeCurrent */
struct gl_framebuffer *WinSysReadBuffer; /**< set with MakeCurrent */
/**
* Device driver function pointer table
*/
struct dd_function_table Driver;
/** Core/Driver constants */
struct gl_constants Const;
/** \name The various 4x4 matrix stacks */
/*@{*/
struct gl_matrix_stack ModelviewMatrixStack;
struct gl_matrix_stack ProjectionMatrixStack;
struct gl_matrix_stack TextureMatrixStack[MAX_TEXTURE_UNITS];
struct gl_matrix_stack ProgramMatrixStack[MAX_PROGRAM_MATRICES];
struct gl_matrix_stack *CurrentStack; /**< Points to one of the above stacks */
/*@}*/
// 省略
};
2.4 st_context
src/mesa/state_tracker/st_context.h
struct st_context
{
struct st_context_iface iface;
struct gl_context *ctx;
struct pipe_context *pipe;
struct draw_context *draw; /**< For selection/feedback/rastpos only */
struct draw_stage *feedback_stage; /**< For GL_FEEDBACK rendermode */
struct draw_stage *selection_stage; /**< For GL_SELECT rendermode */
struct draw_stage *rastpos_stage; /**< For glRasterPos */
// 省略
};
src/mesa/state_tracker/st_context.c
static void
st_init_driver_functions(struct pipe_screen *screen,
struct dd_function_table *functions)
{
_mesa_init_sampler_object_functions(functions);
st_init_draw_functions(functions);
st_init_blit_functions(functions);
st_init_bufferobject_functions(screen, functions);
st_init_clear_functions(functions);
st_init_bitmap_functions(functions);
st_init_copy_image_functions(functions);
st_init_drawpixels_functions(functions);
st_init_rasterpos_functions(functions);
st_init_drawtex_functions(functions);
st_init_eglimage_functions(functions);
st_init_fbo_functions(functions);
// 省略
}
struct st_context *
st_create_context(gl_api api, struct pipe_context *pipe,
const struct gl_config *visual,
struct st_context *share,
const struct st_config_options *options,
bool no_error)
{
struct gl_context *ctx;
struct gl_context *shareCtx = share ? share->ctx : NULL;
struct dd_function_table funcs;
struct st_context *st;
util_cpu_detect();
memset(&funcs, 0, sizeof(funcs));
st_init_driver_functions(pipe->screen, &funcs);
// 省略
}
2.5 pipe_context
src/gallium/include/pipe/p_context.h
/**
* Gallium rendering context. Basically:
* - state setting functions
* - VBO drawing functions
* - surface functions
*/
struct pipe_context {
struct pipe_screen *screen;
void *priv; /**< context private data (for DRI for example) */
void *draw; /**< private, for draw module (temporary?) */
/**
* Stream uploaders created by the driver. All drivers, state trackers, and
* modules should use them.
*
* Use u_upload_alloc or u_upload_data as many times as you want.
* Once you are done, use u_upload_unmap.
*/
struct u_upload_mgr *stream_uploader; /* everything but shader constants */
struct u_upload_mgr *const_uploader; /* shader constants only */
void (*destroy)( struct pipe_context * );
3 Interface
3.1 Device driver interfaces
src/mesa/main/mtypes.h
struct gl_context --> struct dd_function_table Driver
/**
* Mesa rendering context.
*
* This is the central context data structure for Mesa. Almost all
* OpenGL state is contained in this structure.
* Think of this as a base class from which device drivers will derive
* sub classes.
*/
struct gl_context
{
// 省略
struct glthread_state *GLThread;
struct gl_config Visual;
struct gl_framebuffer *DrawBuffer; /**< buffer for writing */
struct gl_framebuffer *ReadBuffer; /**< buffer for reading */
struct gl_framebuffer *WinSysDrawBuffer; /**< set with MakeCurrent */
struct gl_framebuffer *WinSysReadBuffer; /**< set with MakeCurrent */
/**
* Device driver function pointer table
*/
struct dd_function_table Driver; // 死亡凝视
/** Core/Driver constants */
struct gl_constants Const;
/** \name The various 4x4 matrix stacks */
/*@{*/
struct gl_matrix_stack ModelviewMatrixStack;
struct gl_matrix_stack ProjectionMatrixStack;
struct gl_matrix_stack TextureMatrixStack[MAX_TEXTURE_UNITS];
struct gl_matrix_stack ProgramMatrixStack[MAX_PROGRAM_MATRICES];
struct gl_matrix_stack *CurrentStack; /**< Points to one of the above stacks */
// 省略
}
src/mesa/main/dd.h
/**
* Device driver function table.
* Core Mesa uses these function pointers to call into device drivers.
* Most of these functions directly correspond to OpenGL state commands.
* Core Mesa will call these functions after error checking has been done
* so that the drivers don't have to worry about error testing.
*
* Vertex transformation/clipping/lighting is patched into the T&L module.
* Rasterization functions are patched into the swrast module.
*
* Note: when new functions are added here, the drivers/common/driverfuncs.c
* file should be updated too!!!
*/
struct dd_function_table {
/**
* Return a string as needed by glGetString().
* Only the GL_RENDERER query must be implemented. Otherwise, NULL can be
* returned.
*/
const GLubyte * (*GetString)( struct gl_context *ctx, GLenum name );
/**
* Notify the driver after Mesa has made some internal state changes.
*
* This is in addition to any state change callbacks Mesa may already have
* made.
*/
void (*UpdateState)(struct gl_context *ctx);
/**
* This is called whenever glFinish() is called.
*/
void (*Finish)( struct gl_context *ctx );
/**
* This is called whenever glFlush() is called.
*/
void (*Flush)( struct gl_context *ctx );
/**
* Clear the color/depth/stencil/accum buffer(s).
* \param buffers a bitmask of BUFFER_BIT_* flags indicating which
* renderbuffers need to be cleared.
*/
void (*Clear)( struct gl_context *ctx, GLbitfield buffers );
/**
* Execute glRasterPos, updating the ctx->Current.Raster fields
*/
void (*RasterPos)( struct gl_context *ctx, const GLfloat v[4] );
// 省略
}
src/mesa/drivers/common/driverfuncs.h
#ifndef DRIVERFUNCS_H
#define DRIVERFUNCS_H
#ifdef __cplusplus
extern "C" {
#endif
extern void
_mesa_init_driver_functions(struct dd_function_table *driver);
extern void
_mesa_init_driver_state(struct gl_context *ctx);
#ifdef __cplusplus
} // extern "C"
#endif
#endif
src/mesa/drivers/common/driverfuncs.c
/**
* Plug in default functions for all pointers in the dd_function_table
* structure.
* Device drivers should call this function and then plug in any
* functions which it wants to override.
* Some functions (pointers) MUST be implemented by all drivers (REQUIRED).
*
* \param table the dd_function_table to initialize
*/
void
_mesa_init_driver_functions(struct dd_function_table *driver)
{
memset(driver, 0, sizeof(*driver));
driver->GetString = NULL; /* REQUIRED! */
driver->UpdateState = NULL; /* REQUIRED! */
driver->Finish = NULL;
driver->Flush = NULL;
// 省略
}
src/mesa/state_tracker/st_cb_fbo.c
driver->ReadPixels = _mesa_readpixels;
_mesa_readpixels -> read_stencil_pixels -> ctx->Driver.MapRenderbuffer -> st_MapRenderbuffer
void
st_init_fbo_functions(struct dd_function_table *functions)
{
functions->NewFramebuffer = _mesa_new_framebuffer;
functions->NewRenderbuffer = st_new_renderbuffer;
functions->FramebufferRenderbuffer = _mesa_FramebufferRenderbuffer_sw;
functions->RenderTexture = st_render_texture;
functions->FinishRenderTexture = st_finish_render_texture;
functions->ValidateFramebuffer = st_validate_framebuffer;
functions->DiscardFramebuffer = st_discard_framebuffer;
functions->DrawBufferAllocate = st_DrawBufferAllocate;
functions->ReadBuffer = st_ReadBuffer;
functions->MapRenderbuffer = st_MapRenderbuffer;
functions->UnmapRenderbuffer = st_UnmapRenderbuffer;
functions->EvaluateDepthValues = st_EvaluateDepthValues;
}
/**
* Called via
* ctx->Driver.MapRenderbuffer.
*/
static void
st_MapRenderbuffer(struct gl_context *ctx,
struct gl_renderbuffer *rb,
GLuint x, GLuint y, GLuint w, GLuint h,
GLbitfield mode,
GLubyte **mapOut, GLint *rowStrideOut,
bool flip_y)
{
struct st_context *st = st_context(ctx);
struct st_renderbuffer *strb = st_renderbuffer(rb);
struct pipe_context *pipe = st->pipe;
const GLboolean invert = flip_y;
GLuint y2;
GLubyte *map;
// 省略
}