📄 osmesa.c
字号:
/* * Mesa 3-D graphics library * Version: 6.5 * * Copyright (C) 1999-2006 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"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *//* * Off-Screen Mesa rendering / Rendering into client memory space * * Note on thread safety: this driver is thread safe. All * functions are reentrant. The notion of current context is * managed by the core _mesa_make_current() and _mesa_get_current_context() * functions. Those functions are thread-safe. */#include "glheader.h"#include "GL/osmesa.h"#include "context.h"#include "extensions.h"#include "framebuffer.h"#include "fbobject.h"#include "imports.h"#include "mtypes.h"#include "renderbuffer.h"#include "array_cache/acache.h"#include "swrast/swrast.h"#include "swrast_setup/swrast_setup.h"#include "swrast/s_context.h"#include "swrast/s_depth.h"#include "swrast/s_lines.h"#include "swrast/s_triangle.h"#include "tnl/tnl.h"#include "tnl/t_context.h"#include "tnl/t_pipeline.h"#include "drivers/common/driverfuncs.h"/* * This is the OS/Mesa context struct. * Notice how it includes a GLcontext. By doing this we're mimicking * C++ inheritance/derivation. * Later, we can cast a GLcontext pointer into an OSMesaContext pointer * or vice versa. */struct osmesa_context { GLcontext mesa; /* The core GL/Mesa context */ GLvisual *gl_visual; /* Describes the buffers */ GLframebuffer *gl_buffer; /* Depth, stencil, accum, etc buffers */ GLenum format; /* either GL_RGBA or GL_COLOR_INDEX */ void *buffer; /* the image buffer */ GLint width, height; /* size of image buffer */ GLint rowlength; /* number of pixels per row */ GLint userRowLength; /* user-specified number of pixels per row */ GLint rInd, gInd, bInd, aInd;/* index offsets for RGBA formats */ GLchan *rowaddr[MAX_HEIGHT]; /* address of first pixel in each image row */ GLboolean yup; /* TRUE -> Y increases upward */ /* FALSE -> Y increases downward */};/* Just cast, since we're using structure containment */#define OSMESA_CONTEXT(ctx) ((OSMesaContext) (ctx->DriverCtx))/**********************************************************************//*** Private Device Driver Functions ***//**********************************************************************/static const GLubyte *get_string( GLcontext *ctx, GLenum name ){ (void) ctx; switch (name) { case GL_RENDERER:#if CHAN_BITS == 32 return (const GLubyte *) "Mesa OffScreen32";#elif CHAN_BITS == 16 return (const GLubyte *) "Mesa OffScreen16";#else return (const GLubyte *) "Mesa OffScreen";#endif default: return NULL; }}static voidosmesa_update_state( GLcontext *ctx, GLuint new_state ){ /* easy - just propogate */ _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); _ac_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state );}/* * Just return the current buffer size. * There's no window to track the size of. */static voidget_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height ){ /* don't use GET_CURRENT_CONTEXT(ctx) here - it's a problem on Windows */ GLcontext *ctx = (GLcontext *) _glapi_get_context(); (void) buffer; if (ctx) { OSMesaContext osmesa = OSMESA_CONTEXT(ctx); *width = osmesa->width; *height = osmesa->height; }}/**********************************************************************//***** Read/write spans/arrays of pixels *****//**********************************************************************//* RGBA */#define NAME(PREFIX) PREFIX##_RGBA#define FORMAT GL_RGBA#define SPAN_VARS \ const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);#define INIT_PIXEL_PTR(P, X, Y) \ GLchan *P = osmesa->rowaddr[Y] + 4 * (X)#define INC_PIXEL_PTR(P) P += 4#if CHAN_TYPE == GL_FLOAT#define STORE_PIXEL(DST, X, Y, VALUE) \ DST[0] = MAX2((VALUE[RCOMP]), 0.0F); \ DST[1] = MAX2((VALUE[GCOMP]), 0.0F); \ DST[2] = MAX2((VALUE[BCOMP]), 0.0F); \ DST[3] = CLAMP((VALUE[ACOMP]), 0.0F, CHAN_MAXF)#define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ DST[0] = MAX2((VALUE[RCOMP]), 0.0F); \ DST[1] = MAX2((VALUE[GCOMP]), 0.0F); \ DST[2] = MAX2((VALUE[BCOMP]), 0.0F); \ DST[3] = CHAN_MAXF#else#define STORE_PIXEL(DST, X, Y, VALUE) \ DST[0] = VALUE[RCOMP]; \ DST[1] = VALUE[GCOMP]; \ DST[2] = VALUE[BCOMP]; \ DST[3] = VALUE[ACOMP]#define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ DST[0] = VALUE[RCOMP]; \ DST[1] = VALUE[GCOMP]; \ DST[2] = VALUE[BCOMP]; \ DST[3] = CHAN_MAX#endif#define FETCH_PIXEL(DST, SRC) \ DST[RCOMP] = SRC[0]; \ DST[GCOMP] = SRC[1]; \ DST[BCOMP] = SRC[2]; \ DST[ACOMP] = SRC[3]#include "swrast/s_spantemp.h"/* BGRA */#define NAME(PREFIX) PREFIX##_BGRA#define FORMAT GL_RGBA#define SPAN_VARS \ const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);#define INIT_PIXEL_PTR(P, X, Y) \ GLchan *P = osmesa->rowaddr[Y] + 4 * (X)#define INC_PIXEL_PTR(P) P += 4#define STORE_PIXEL(DST, X, Y, VALUE) \ DST[2] = VALUE[RCOMP]; \ DST[1] = VALUE[GCOMP]; \ DST[0] = VALUE[BCOMP]; \ DST[3] = VALUE[ACOMP]#define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ DST[2] = VALUE[RCOMP]; \ DST[1] = VALUE[GCOMP]; \ DST[0] = VALUE[BCOMP]; \ DST[3] = CHAN_MAX#define FETCH_PIXEL(DST, SRC) \ DST[RCOMP] = SRC[2]; \ DST[GCOMP] = SRC[1]; \ DST[BCOMP] = SRC[0]; \ DST[ACOMP] = SRC[3]#include "swrast/s_spantemp.h"/* ARGB */#define NAME(PREFIX) PREFIX##_ARGB#define FORMAT GL_RGBA#define SPAN_VARS \ const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);#define INIT_PIXEL_PTR(P, X, Y) \ GLchan *P = osmesa->rowaddr[Y] + 4 * (X)#define INC_PIXEL_PTR(P) P += 4#define STORE_PIXEL(DST, X, Y, VALUE) \ DST[1] = VALUE[RCOMP]; \ DST[2] = VALUE[GCOMP]; \ DST[3] = VALUE[BCOMP]; \ DST[0] = VALUE[ACOMP]#define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ DST[1] = VALUE[RCOMP]; \ DST[2] = VALUE[GCOMP]; \ DST[3] = VALUE[BCOMP]; \ DST[0] = CHAN_MAX#define FETCH_PIXEL(DST, SRC) \ DST[RCOMP] = SRC[1]; \ DST[GCOMP] = SRC[2]; \ DST[BCOMP] = SRC[3]; \ DST[ACOMP] = SRC[0]#include "swrast/s_spantemp.h"/* RGB */#define NAME(PREFIX) PREFIX##_RGB#define FORMAT GL_RGBA#define SPAN_VARS \ const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);#define INIT_PIXEL_PTR(P, X, Y) \ GLchan *P = osmesa->rowaddr[Y] + 3 * (X)#define INC_PIXEL_PTR(P) P += 3#define STORE_PIXEL(DST, X, Y, VALUE) \ DST[0] = VALUE[RCOMP]; \ DST[1] = VALUE[GCOMP]; \ DST[2] = VALUE[BCOMP]#define FETCH_PIXEL(DST, SRC) \ DST[RCOMP] = SRC[0]; \ DST[GCOMP] = SRC[1]; \ DST[BCOMP] = SRC[2]; \ DST[ACOMP] = CHAN_MAX#include "swrast/s_spantemp.h"/* BGR */#define NAME(PREFIX) PREFIX##_BGR#define FORMAT GL_RGBA#define SPAN_VARS \ const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);#define INIT_PIXEL_PTR(P, X, Y) \ GLchan *P = osmesa->rowaddr[Y] + 3 * (X)#define INC_PIXEL_PTR(P) P += 3#define STORE_PIXEL(DST, X, Y, VALUE) \ DST[2] = VALUE[RCOMP]; \ DST[1] = VALUE[GCOMP]; \ DST[0] = VALUE[BCOMP]#define FETCH_PIXEL(DST, SRC) \ DST[RCOMP] = SRC[2]; \ DST[GCOMP] = SRC[1]; \ DST[BCOMP] = SRC[0]; \ DST[ACOMP] = CHAN_MAX#include "swrast/s_spantemp.h"/* 16-bit RGB */#if CHAN_TYPE == GL_UNSIGNED_BYTE#define NAME(PREFIX) PREFIX##_RGB_565#define FORMAT GL_RGBA#define SPAN_VARS \ const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);#define INIT_PIXEL_PTR(P, X, Y) \ GLushort *P = (GLushort *) osmesa->rowaddr[Y] + (X)#define INC_PIXEL_PTR(P) P += 1#define STORE_PIXEL(DST, X, Y, VALUE) \ *DST = ( (((VALUE[RCOMP]) & 0xf8) << 8) | (((VALUE[GCOMP]) & 0xfc) << 3) | ((VALUE[BCOMP]) >> 3) )#define FETCH_PIXEL(DST, SRC) \ DST[RCOMP] = ( (((*SRC) >> 8) & 0xf8) | (((*SRC) >> 11) & 0x7) ); \ DST[GCOMP] = ( (((*SRC) >> 3) & 0xfc) | (((*SRC) >> 5) & 0x3) ); \ DST[BCOMP] = ( (((*SRC) << 3) & 0xf8) | (((*SRC) ) & 0x7) ); \ DST[ACOMP] = CHAN_MAX#include "swrast/s_spantemp.h"#endif /* CHAN_TYPE == GL_UNSIGNED_BYTE *//* color index */#define NAME(PREFIX) PREFIX##_CI#define FORMAT GL_COLOR_INDEX8_EXT#define SPAN_VARS \ const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);#define INIT_PIXEL_PTR(P, X, Y) \ GLubyte *P = (GLubyte *) osmesa->rowaddr[Y] + (X)#define INC_PIXEL_PTR(P) P += 1#define STORE_PIXEL(DST, X, Y, VALUE) \ *DST = VALUE[0]#define FETCH_PIXEL(DST, SRC) \ DST = SRC[0]#include "swrast/s_spantemp.h"/**********************************************************************//***** Optimized line rendering *****//**********************************************************************/#if CHAN_TYPE == GL_FLOAT#define PACK_RGBA(DST, R, G, B, A) \do { \ (DST)[0] = MAX2( R, 0.0F ); \ (DST)[1] = MAX2( G, 0.0F ); \ (DST)[2] = MAX2( B, 0.0F ); \ (DST)[3] = CLAMP(A, 0.0F, CHAN_MAXF);\} while (0)#else#define PACK_RGBA(DST, R, G, B, A) \do { \ (DST)[osmesa->rInd] = R; \ (DST)[osmesa->gInd] = G; \ (DST)[osmesa->bInd] = B; \ (DST)[osmesa->aInd] = A; \} while (0)#endif#define PACK_RGB(DST, R, G, B) \do { \ (DST)[0] = R; \ (DST)[1] = G; \ (DST)[2] = B; \} while (0)#define PACK_BGR(DST, R, G, B) \do { \ (DST)[0] = B; \ (DST)[1] = G; \ (DST)[2] = R; \} while (0)#define PACK_RGB_565(DST, R, G, B) \do { \ (DST) = (((int) (R) << 8) & 0xf800) | (((int) (G) << 3) & 0x7e0) | ((int) (B) >> 3);\} while (0)#define UNPACK_RED(P) ( (P)[osmesa->rInd] )#define UNPACK_GREEN(P) ( (P)[osmesa->gInd] )#define UNPACK_BLUE(P) ( (P)[osmesa->bInd] )#define UNPACK_ALPHA(P) ( (P)[osmesa->aInd] )#define PIXELADDR1(X,Y) (osmesa->rowaddr[Y] + (X))#define PIXELADDR2(X,Y) (osmesa->rowaddr[Y] + 2 * (X))#define PIXELADDR3(X,Y) (osmesa->rowaddr[Y] + 3 * (X))#define PIXELADDR4(X,Y) (osmesa->rowaddr[Y] + 4 * (X))/* * Draw a flat-shaded, RGB line into an osmesa buffer. */#define NAME flat_rgba_line#define CLIP_HACK 1#define SETUP_CODE \ const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); \ const GLchan *color = vert1->color;#define PLOT(X, Y) \do { \ GLchan *p = PIXELADDR4(X, Y); \ PACK_RGBA(p, color[0], color[1], color[2], color[3]); \} while (0)#ifdef WIN32#include "..\swrast\s_linetemp.h"#else#include "swrast/s_linetemp.h"#endif/* * Draw a flat-shaded, Z-less, RGB line into an osmesa buffer. */#define NAME flat_rgba_z_line#define CLIP_HACK 1#define INTERP_Z 1#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE#define SETUP_CODE \ const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); \ const GLchan *color = vert1->color;#define PLOT(X, Y) \do { \ if (Z < *zPtr) { \ GLchan *p = PIXELADDR4(X, Y); \ PACK_RGBA(p, color[RCOMP], color[GCOMP], \ color[BCOMP], color[ACOMP]); \ *zPtr = Z; \ } \} while (0)#ifdef WIN32#include "..\swrast\s_linetemp.h"#else#include "swrast/s_linetemp.h"#endif/* * Analyze context state to see if we can provide a fast line drawing * function, like those in lines.c. Otherwise, return NULL. */static swrast_line_funcosmesa_choose_line_function( GLcontext *ctx ){ const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); const SWcontext *swrast = SWRAST_CONTEXT(ctx); if (CHAN_BITS != 8) return NULL; if (ctx->RenderMode != GL_RENDER) return NULL; if (ctx->Line.SmoothFlag) return NULL; if (ctx->Texture._EnabledUnits) return NULL; if (ctx->Light.ShadeModel != GL_FLAT) return NULL; if (ctx->Line.Width != 1.0F) return NULL; if (ctx->Line.StippleFlag) return NULL; if (ctx->Line.SmoothFlag) return NULL; if (osmesa->format != OSMESA_RGBA && osmesa->format != OSMESA_BGRA &&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -