-/* $Id: osmesa.c,v 1.96 2002/10/30 19:49:30 brianp Exp $ */
+/* $Id: osmesa.c,v 1.97 2002/11/13 16:57:44 brianp Exp $ */
/*
* Mesa 3-D graphics library
};
-
-/* A forward declaration: */
-static void osmesa_update_state( GLcontext *ctx, GLuint newstate );
-static void osmesa_register_swrast_functions( GLcontext *ctx );
-
-
-
#define OSMESA_CONTEXT(ctx) ((OSMesaContext) (ctx->DriverCtx))
/**********************************************************************/
-/***** Public Functions *****/
+/*** Private Device Driver Functions ***/
/**********************************************************************/
-/*
- * Create an Off-Screen Mesa rendering context. The only attribute needed is
- * an RGBA vs Color-Index mode flag.
- *
- * Input: format - either GL_RGBA or GL_COLOR_INDEX
- * sharelist - specifies another OSMesaContext with which to share
- * display lists. NULL indicates no sharing.
- * Return: an OSMesaContext or 0 if error
- */
-GLAPI OSMesaContext GLAPIENTRY
-OSMesaCreateContext( GLenum format, OSMesaContext sharelist )
+static const GLubyte *
+get_string( GLcontext *ctx, GLenum name )
{
- return OSMesaCreateContextExt(format, DEFAULT_SOFTWARE_DEPTH_BITS,
- 8, 16, sharelist);
+ (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 void
+osmesa_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 );
+}
+
-/*
- * New in Mesa 3.5
- *
- * Create context and specify size of ancillary buffers.
- */
-GLAPI OSMesaContext GLAPIENTRY
-OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits,
- GLint accumBits, OSMesaContext sharelist )
+static void
+set_buffer( GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit )
{
- OSMesaContext osmesa;
- GLint rshift, gshift, bshift, ashift;
- GLint rind, gind, bind, aind;
- GLint indexBits = 0, redBits = 0, greenBits = 0, blueBits = 0, alphaBits =0;
- GLboolean rgbmode;
- const GLuint i4 = 1;
- const GLubyte *i1 = (GLubyte *) &i4;
- const GLint little_endian = *i1;
+ /* separate read buffer not supported */
+ ASSERT(buffer == ctx->DrawBuffer);
+ ASSERT(bufferBit == FRONT_LEFT_BIT);
+}
- rind = gind = bind = aind = 0;
- if (format==OSMESA_COLOR_INDEX) {
- indexBits = 8;
- rshift = gshift = bshift = ashift = 0;
- rgbmode = GL_FALSE;
- }
- else if (format==OSMESA_RGBA) {
- indexBits = 0;
- redBits = CHAN_BITS;
- greenBits = CHAN_BITS;
- blueBits = CHAN_BITS;
- alphaBits = CHAN_BITS;
- rind = 0;
- gind = 1;
- bind = 2;
- aind = 3;
- if (little_endian) {
- rshift = 0;
- gshift = 8;
- bshift = 16;
- ashift = 24;
- }
- else {
- rshift = 24;
- gshift = 16;
- bshift = 8;
- ashift = 0;
- }
- rgbmode = GL_TRUE;
- }
- else if (format==OSMESA_BGRA) {
- indexBits = 0;
- redBits = CHAN_BITS;
- greenBits = CHAN_BITS;
- blueBits = CHAN_BITS;
- alphaBits = CHAN_BITS;
- bind = 0;
- gind = 1;
- rind = 2;
- aind = 3;
- if (little_endian) {
- bshift = 0;
- gshift = 8;
- rshift = 16;
- ashift = 24;
- }
- else {
- bshift = 24;
- gshift = 16;
- rshift = 8;
- ashift = 0;
- }
- rgbmode = GL_TRUE;
+
+static void
+get_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;
}
- else if (format==OSMESA_ARGB) {
- indexBits = 0;
- redBits = CHAN_BITS;
- greenBits = CHAN_BITS;
- blueBits = CHAN_BITS;
- alphaBits = CHAN_BITS;
- aind = 0;
- rind = 1;
- gind = 2;
- bind = 3;
- if (little_endian) {
- ashift = 0;
- rshift = 8;
- gshift = 16;
- bshift = 24;
+}
+
+
+static void
+clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
+ GLint x, GLint y, GLint width, GLint height )
+{
+ OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
+ const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask;
+
+ /* sanity check - we only have a front-left buffer */
+ ASSERT((mask & (DD_FRONT_RIGHT_BIT |
+ DD_BACK_LEFT_BIT |
+ DD_BACK_RIGHT_BIT)) == 0);
+
+ /* use optimized clear for common cases (clear whole buffer to black) */
+ if (mask & DD_FRONT_LEFT_BIT) {
+ if (osmesa->format == OSMESA_COLOR_INDEX) {
+ if (ctx->Color.ClearIndex == 0 &&
+ ctx->Color.IndexMask == ~0 &&
+ osmesa->rowlength == osmesa->width &&
+ all) {
+ /* clear whole buffer to zeros */
+ _mesa_bzero(osmesa->buffer,
+ osmesa->width * osmesa->height * sizeof(GLchan));
+ mask &= ~DD_FRONT_LEFT_BIT;
+ }
}
else {
- ashift = 24;
- rshift = 16;
- gshift = 8;
- bshift = 0;
+ /* RGB[A] format */
+ if (*colorMask == 0xffffffff &&
+ ctx->Color.ClearColor[0] == 0.0F &&
+ ctx->Color.ClearColor[1] == 0.0F &&
+ ctx->Color.ClearColor[2] == 0.0F &&
+ ctx->Color.ClearColor[3] == 0.0F &&
+ osmesa->rowlength == osmesa->width &&
+ all) {
+ GLint bytesPerPixel;
+ /* clear whole buffer to black */
+ if (osmesa->format == OSMESA_RGBA ||
+ osmesa->format == OSMESA_BGRA ||
+ osmesa->format == OSMESA_ARGB)
+ bytesPerPixel = 4 * sizeof(GLchan);
+ else if (osmesa->format == OSMESA_RGB ||
+ osmesa->format == OSMESA_BGR)
+ bytesPerPixel = 3 * sizeof(GLchan);
+ else if (osmesa->format == OSMESA_RGB_565)
+ bytesPerPixel = sizeof(GLushort);
+ else {
+ _mesa_problem(ctx, "bad pixel format in osmesa_clear()");
+ return;
+ }
+ _mesa_bzero(osmesa->buffer,
+ bytesPerPixel * osmesa->width * osmesa->height);
+ mask &= ~DD_FRONT_LEFT_BIT;
+ }
}
- rgbmode = GL_TRUE;
- }
- else if (format==OSMESA_RGB) {
- indexBits = 0;
- redBits = CHAN_BITS;
- greenBits = CHAN_BITS;
- blueBits = CHAN_BITS;
- alphaBits = 0;
- bshift = 0;
- gshift = 8;
- rshift = 16;
- ashift = 24;
- rind = 0;
- gind = 1;
- bind = 2;
- rgbmode = GL_TRUE;
- }
- else if (format==OSMESA_BGR) {
- indexBits = 0;
- redBits = CHAN_BITS;
- greenBits = CHAN_BITS;
- blueBits = CHAN_BITS;
- alphaBits = 0;
- bshift = 0;
- gshift = 8;
- rshift = 16;
- ashift = 24;
- rind = 2;
- gind = 1;
- bind = 0;
- rgbmode = GL_TRUE;
- }
- else if (format==OSMESA_RGB_565) {
- indexBits = 0;
- redBits = 5;
- greenBits = 6;
- blueBits = 5;
- alphaBits = 0;
- rshift = 11;
- gshift = 5;
- bshift = 0;
- ashift = 0;
- rind = 0; /* not used */
- gind = 0;
- bind = 0;
- rgbmode = GL_TRUE;
- }
- else {
- return NULL;
}
+ if (mask) {
+ /* software fallback (spans) for everything else. */
+ _swrast_Clear(ctx, mask, all, x, y, width, height);
+ }
+}
- osmesa = (OSMesaContext) CALLOC_STRUCT(osmesa_context);
- if (osmesa) {
- osmesa->gl_visual = _mesa_create_visual( rgbmode,
- GL_FALSE, /* double buffer */
- GL_FALSE, /* stereo */
- redBits,
- greenBits,
- blueBits,
- alphaBits,
- indexBits,
- depthBits,
- stencilBits,
- accumBits,
- accumBits,
- accumBits,
- alphaBits ? accumBits : 0,
- 1 /* num samples */
- );
- if (!osmesa->gl_visual) {
- FREE(osmesa);
- return NULL;
- }
- if (!_mesa_initialize_context(&osmesa->gl_ctx,
- osmesa->gl_visual,
- sharelist ? &sharelist->gl_ctx
- : (GLcontext *) NULL,
- (void *) osmesa,
- GL_FALSE)) {
- _mesa_destroy_visual( osmesa->gl_visual );
- FREE(osmesa);
- return NULL;
- }
+/**********************************************************************/
+/***** Read/write spans/arrays of pixels *****/
+/**********************************************************************/
- _mesa_enable_sw_extensions(&(osmesa->gl_ctx));
- _mesa_enable_1_3_extensions(&(osmesa->gl_ctx));
- _mesa_enable_1_4_extensions(&(osmesa->gl_ctx));
- osmesa->gl_buffer = _mesa_create_framebuffer( osmesa->gl_visual,
- (GLboolean) ( osmesa->gl_visual->depthBits > 0 ),
- (GLboolean) ( osmesa->gl_visual->stencilBits > 0 ),
- (GLboolean) ( osmesa->gl_visual->accumRedBits > 0 ),
- GL_FALSE /* s/w alpha */ );
+/* RGBA */
+#define NAME(PREFIX) PREFIX##_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_RGB_PIXEL(P, R, G, B) \
+ P[0] = MAX2((R), 0.0F);
+ P[1] = MAX2((G), 0.0F);
+ P[2] = MAX2((B), 0.0F);
+ P[3] = CHAN_MAXF
+#define STORE_RGBA_PIXEL(P, R, G, B, A) \
+ P[0] = MAX2((R), 0.0F);
+ P[1] = MAX2((G), 0.0F);
+ P[2] = MAX2((B), 0.0F);
+ P[3] = CLAMP((A), 0.0F, CHAN_MAXF)
+#else
+#define STORE_RGB_PIXEL(P, R, G, B) \
+ P[0] = R; P[1] = G; P[2] = B; P[3] = CHAN_MAX
+#define STORE_RGBA_PIXEL(P, R, G, B, A) \
+ P[0] = R; P[1] = G; P[2] = B; P[3] = A
+#endif
+#define FETCH_RGBA_PIXEL(R, G, B, A, P) \
+ R = P[0]; G = P[1]; B = P[2]; A = P[3]
+#include "swrast/s_spantemp.h"
- if (!osmesa->gl_buffer) {
- _mesa_destroy_visual( osmesa->gl_visual );
- _mesa_free_context_data( &osmesa->gl_ctx );
- FREE(osmesa);
- return NULL;
- }
- osmesa->format = format;
- osmesa->buffer = NULL;
- osmesa->width = 0;
- osmesa->height = 0;
- osmesa->userRowLength = 0;
- osmesa->rowlength = 0;
- osmesa->yup = GL_TRUE;
- osmesa->rshift = rshift;
- osmesa->gshift = gshift;
- osmesa->bshift = bshift;
- osmesa->ashift = ashift;
- osmesa->rInd = rind;
- osmesa->gInd = gind;
- osmesa->bInd = bind;
- osmesa->aInd = aind;
+/* BGRA */
+#define NAME(PREFIX) PREFIX##_BGRA
+#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_RGB_PIXEL(P, R, G, B) \
+ P[2] = R; P[1] = G; P[0] = B; P[3] = CHAN_MAX
+#define STORE_RGBA_PIXEL(P, R, G, B, A) \
+ P[2] = R; P[1] = G; P[0] = B; P[3] = A
+#define FETCH_RGBA_PIXEL(R, G, B, A, P) \
+ R = P[2]; G = P[1]; B = P[0]; A = P[3]
+#include "swrast/s_spantemp.h"
+
+/* ARGB */
+#define NAME(PREFIX) PREFIX##_ARGB
+#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_RGB_PIXEL(P, R, G, B) \
+ P[1] = R; P[2] = G; P[3] = B; P[0] = CHAN_MAX
+#define STORE_RGBA_PIXEL(P, R, G, B, A) \
+ P[1] = R; P[2] = G; P[3] = B; P[0] = A
+#define FETCH_RGBA_PIXEL(R, G, B, A, P) \
+ R = P[1]; G = P[2]; B = P[3]; A = P[0]
+#include "swrast/s_spantemp.h"
+
+/* RGB */
+#define NAME(PREFIX) PREFIX##_RGB
+#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_RGB_PIXEL(P, R, G, B) \
+ P[0] = R; P[1] = G; P[2] = B
+#define STORE_RGBA_PIXEL(P, R, G, B, A) \
+ P[0] = R; P[1] = G; P[2] = B
+#define FETCH_RGBA_PIXEL(R, G, B, A, P) \
+ R = P[0]; G = P[1]; B = P[2]; A = CHAN_MAX
+#include "swrast/s_spantemp.h"
+
+/* BGR */
+#define NAME(PREFIX) PREFIX##_BGR
+#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_RGB_PIXEL(P, R, G, B) \
+ P[0] = B; P[1] = G; P[2] = R
+#define STORE_RGBA_PIXEL(P, R, G, B, A) \
+ P[0] = B; P[1] = G; P[2] = R
+#define FETCH_RGBA_PIXEL(R, G, B, A, P) \
+ B = P[0]; G = P[1]; R = P[2]; A = CHAN_MAX
+#include "swrast/s_spantemp.h"
+
+/* 16-bit BGR */
+#define NAME(PREFIX) PREFIX##_RGB_565
+#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_RGB_PIXEL(P, R, G, B) \
+ *P = ( (((R) & 0xf8) << 8) | (((G) & 0xfc) << 3) | ((B) >> 3) )
+#define STORE_RGBA_PIXEL(P, R, G, B, A) \
+ *P = ( (((R) & 0xf8) << 8) | (((G) & 0xfc) << 3) | ((B) >> 3) )
+#define FETCH_RGBA_PIXEL(R, G, B, A, P) \
+ R = ( (((*P) >> 8) & 0xf8) | (((*P) >> 11) & 0x7) ); \
+ G = ( (((*P) >> 3) & 0xfc) | (((*P) >> 5) & 0x3) ); \
+ B = ( (((*P) << 3) & 0xf8) | (((*P) ) & 0x7) ); \
+ A = CHAN_MAX
+#include "swrast/s_spantemp.h"
+
+/* color index */
+#define NAME(PREFIX) PREFIX##_CI
+#define SPAN_VARS \
+ const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
+#define INIT_PIXEL_PTR(P, X, Y) \
+ GLchan *P = osmesa->rowaddr[Y] + (X)
+#define INC_PIXEL_PTR(P) P += 1
+#define STORE_CI_PIXEL(P, CI) \
+ P[0] = CI
+#define FETCH_CI_PIXEL(CI, P) \
+ CI = P[0]
+#include "swrast/s_spantemp.h"
- /* Initialize the software rasterizer and helper modules.
- */
- {
- GLcontext *ctx = &osmesa->gl_ctx;
+/**********************************************************************/
+/***** Optimized line rendering *****/
+/**********************************************************************/
- _swrast_CreateContext( ctx );
- _ac_CreateContext( ctx );
- _tnl_CreateContext( ctx );
- _swsetup_CreateContext( ctx );
-
- _swsetup_Wakeup( ctx );
- osmesa_register_swrast_functions( ctx );
- }
- }
- return osmesa;
-}
+#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))
/*
- * Destroy an Off-Screen Mesa rendering context.
- *
- * Input: ctx - the context to destroy
+ * Draw a flat-shaded, RGB line into an osmesa buffer.
*/
-GLAPI void GLAPIENTRY OSMesaDestroyContext( OSMesaContext ctx )
+static void
+flat_rgba_line( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
{
- if (ctx) {
- _swsetup_DestroyContext( &ctx->gl_ctx );
- _tnl_DestroyContext( &ctx->gl_ctx );
- _ac_DestroyContext( &ctx->gl_ctx );
- _swrast_DestroyContext( &ctx->gl_ctx );
+ const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
+ const GLchan *color = vert1->color;
- _mesa_destroy_visual( ctx->gl_visual );
- _mesa_destroy_framebuffer( ctx->gl_buffer );
- _mesa_free_context_data( &ctx->gl_ctx );
- FREE( ctx );
- }
-}
+#define INTERP_XY 1
+#define CLIP_HACK 1
+#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
+}
/*
- * Recompute the values of the context's rowaddr array.
+ * Draw a flat-shaded, Z-less, RGB line into an osmesa buffer.
*/
-static void compute_row_addresses( OSMesaContext ctx )
+static void
+flat_rgba_z_line(GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1)
{
- GLint bytesPerPixel, bytesPerRow, i;
- GLubyte *origin = (GLubyte *) ctx->buffer;
+ const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
+ const GLchan *color = vert1->color;
- if (ctx->format == OSMESA_COLOR_INDEX) {
- /* CI mode */
- bytesPerPixel = 1 * sizeof(GLchan);
- }
- else if ((ctx->format == OSMESA_RGB) || (ctx->format == OSMESA_BGR)) {
- /* RGB mode */
- bytesPerPixel = 3 * sizeof(GLchan);
- }
- else if (ctx->format == OSMESA_RGB_565) {
- /* 5/6/5 RGB pixel in 16 bits */
- bytesPerPixel = 2;
- }
- else {
- /* RGBA mode */
- bytesPerPixel = 4 * sizeof(GLchan);
- }
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
+#define CLIP_HACK 1
+#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)
- bytesPerRow = ctx->rowlength * bytesPerPixel;
- if (ctx->yup) {
- /* Y=0 is bottom line of window */
- for (i = 0; i < MAX_HEIGHT; i++) {
- ctx->rowaddr[i] = (GLchan *) ((GLubyte *) origin + i * bytesPerRow);
- }
- }
- else {
- /* Y=0 is top line of window */
- for (i = 0; i < MAX_HEIGHT; i++) {
- GLint j = ctx->height - i - 1;
- ctx->rowaddr[i] = (GLchan *) ((GLubyte *) origin + j * bytesPerRow);
- }
- }
+#ifdef WIN32
+#include "..\swrast\s_linetemp.h"
+#else
+#include "swrast/s_linetemp.h"
+#endif
}
/*
- * Bind an OSMesaContext to an image buffer. The image buffer is just a
- * block of memory which the client provides. Its size must be at least
- * as large as width*height*sizeof(type). Its address should be a multiple
- * of 4 if using RGBA mode.
- *
- * Image data is stored in the order of glDrawPixels: row-major order
- * with the lower-left image pixel stored in the first array position
- * (ie. bottom-to-top).
- *
- * If the context's viewport hasn't been initialized yet, it will now be
- * initialized to (0,0,width,height).
- *
- * Input: ctx - the rendering context
- * buffer - the image buffer memory
- * type - data type for pixel components
- * Normally, only GL_UNSIGNED_BYTE and GL_UNSIGNED_SHORT_5_6_5
- * are supported. But if Mesa's been compiled with CHAN_BITS==16
- * then type must be GL_UNSIGNED_SHORT. And if Mesa's been build
- * with CHAN_BITS==32 then type must be GL_FLOAT.
- * width, height - size of image buffer in pixels, at least 1
- * Return: GL_TRUE if success, GL_FALSE if error because of invalid ctx,
- * invalid buffer address, invalid type, width<1, height<1,
- * width>internal limit or height>internal limit.
+ * Draw a flat-shaded, alpha-blended, RGB line into an osmesa buffer.
+ * XXX update for GLchan
*/
-GLAPI GLboolean GLAPIENTRY
-OSMesaMakeCurrent( OSMesaContext ctx, void *buffer, GLenum type,
- GLsizei width, GLsizei height )
+static void
+flat_blend_rgba_line( GLcontext *ctx,
+ const SWvertex *vert0, const SWvertex *vert1 )
{
- if (!ctx || !buffer ||
- width < 1 || height < 1 ||
- width > MAX_WIDTH || height > MAX_HEIGHT) {
- return GL_FALSE;
- }
+ const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
+ const GLint rshift = osmesa->rshift;
+ const GLint gshift = osmesa->gshift;
+ const GLint bshift = osmesa->bshift;
+ const GLint avalue = vert0->color[3];
+ const GLint msavalue = CHAN_MAX - avalue;
+ const GLint rvalue = vert1->color[0]*avalue;
+ const GLint gvalue = vert1->color[1]*avalue;
+ const GLint bvalue = vert1->color[2]*avalue;
- if (ctx->format == OSMESA_RGB_565) {
- if (type != GL_UNSIGNED_SHORT_5_6_5)
- return GL_FALSE;
+#define INTERP_XY 1
+#define CLIP_HACK 1
+#define PLOT(X,Y) \
+ { GLuint *ptr4 = (GLuint *) PIXELADDR4(X, Y); \
+ GLuint pixel = 0; \
+ pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);\
+ pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);\
+ pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);\
+ *ptr4 = pixel; \
}
- else if (type != CHAN_TYPE) {
- return GL_FALSE;
+
+#if 0 /* XXX use this in the future */
+#define PLOT(X,Y) \
+ { \
+ GLchan *pixel = (GLchan *) PIXELADDR4(X, Y); \
+ pixel[rInd] = (pixel[rInd] * msavalue + rvalue) >> CHAN_BITS; \
+ pixel[gInd] = (pixel[gInd] * msavalue + gvalue) >> CHAN_BITS; \
+ pixel[bInd] = (pixel[bInd] * msavalue + bvalue) >> CHAN_BITS; \
+ pixel[aInd] = (pixel[aInd] * msavalue + avalue) >> CHAN_BITS; \
}
+#endif
- osmesa_update_state( &ctx->gl_ctx, 0 );
- _mesa_make_current( &ctx->gl_ctx, ctx->gl_buffer );
+#ifdef WIN32
+#include "..\swrast\s_linetemp.h"
+#else
+#include "swrast/s_linetemp.h"
+#endif
+}
- ctx->buffer = buffer;
- ctx->width = width;
- ctx->height = height;
- if (ctx->userRowLength)
- ctx->rowlength = ctx->userRowLength;
- else
- ctx->rowlength = width;
- compute_row_addresses( ctx );
+/*
+ * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
+ * But don't write to Z buffer.
+ * XXX update for GLchan
+ */
+static void
+flat_blend_rgba_z_line( GLcontext *ctx,
+ const SWvertex *vert0, const SWvertex *vert1 )
+{
+ const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
+ const GLint rshift = osmesa->rshift;
+ const GLint gshift = osmesa->gshift;
+ const GLint bshift = osmesa->bshift;
+ const GLint avalue = vert0->color[3];
+ const GLint msavalue = 256 - avalue;
+ const GLint rvalue = vert1->color[0]*avalue;
+ const GLint gvalue = vert1->color[1]*avalue;
+ const GLint bvalue = vert1->color[2]*avalue;
- /* init viewport */
- if (ctx->gl_ctx.Viewport.Width == 0) {
- /* initialize viewport and scissor box to buffer size */
- _mesa_Viewport( 0, 0, width, height );
- ctx->gl_ctx.Scissor.Width = width;
- ctx->gl_ctx.Scissor.Height = height;
- }
- else {
- /* this will make ensure we recognize the new buffer size */
- _mesa_ResizeBuffersMESA();
- }
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
+#define CLIP_HACK 1
+#define PLOT(X,Y) \
+ if (Z < *zPtr) { \
+ GLuint *ptr4 = (GLuint *) PIXELADDR4(X, Y); \
+ GLuint pixel = 0; \
+ pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift); \
+ pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift); \
+ pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift); \
+ *ptr4 = pixel; \
+ }
- /* Added by Gerk Huisma: */
- _tnl_MakeCurrent( &ctx->gl_ctx, ctx->gl_ctx.DrawBuffer,
- ctx->gl_ctx.ReadBuffer );
+#if 0 /* XXX use this in the future */
+#define PLOT(X,Y) \
+ if (Z < *zPtr) { \
+ GLchan *pixel = (GLchan *) PIXELADDR4(X, Y); \
+ pixel[rInd] = (pixel[rInd] * msavalue + rvalue) >> CHAN_BITS; \
+ pixel[gInd] = (pixel[gInd] * msavalue + gvalue) >> CHAN_BITS; \
+ pixel[bInd] = (pixel[bInd] * msavalue + bvalue) >> CHAN_BITS; \
+ pixel[aInd] = (pixel[aInd] * msavalue + avalue) >> CHAN_BITS; \
+ }
+#endif
- return GL_TRUE;
+#ifdef WIN32
+#include "..\swrast\s_linetemp.h"
+#else
+#include "swrast/s_linetemp.h"
+#endif
}
-
-GLAPI OSMesaContext GLAPIENTRY OSMesaGetCurrentContext( void )
+/*
+ * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
+ * XXX update for GLchan
+ */
+static void
+flat_blend_rgba_z_line_write( GLcontext *ctx,
+ const SWvertex *vert0, const SWvertex *vert1 )
{
- GLcontext *ctx = _mesa_get_current_context();
- if (ctx)
- return (OSMesaContext) ctx;
- else
- return NULL;
-}
-
-
+ const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
+ const GLint rshift = osmesa->rshift;
+ const GLint gshift = osmesa->gshift;
+ const GLint bshift = osmesa->bshift;
+ const GLint avalue = vert0->color[3];
+ const GLint msavalue = 256 - avalue;
+ const GLint rvalue = vert1->color[0]*avalue;
+ const GLint gvalue = vert1->color[1]*avalue;
+ const GLint bvalue = vert1->color[2]*avalue;
-GLAPI void GLAPIENTRY OSMesaPixelStore( GLint pname, GLint value )
-{
- OSMesaContext ctx = OSMesaGetCurrentContext();
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
+#define CLIP_HACK 1
+#define PLOT(X,Y) \
+ if (Z < *zPtr) { \
+ GLuint *ptr4 = (GLuint *) PIXELADDR4(X, Y); \
+ GLuint pixel = 0; \
+ pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift); \
+ pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift); \
+ pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift); \
+ *ptr4 = pixel; \
+ *zPtr = Z; \
+ }
- switch (pname) {
- case OSMESA_ROW_LENGTH:
- if (value<0) {
- _mesa_error( &ctx->gl_ctx, GL_INVALID_VALUE,
- "OSMesaPixelStore(value)" );
- return;
- }
- ctx->userRowLength = value;
- ctx->rowlength = value;
- break;
- case OSMESA_Y_UP:
- ctx->yup = value ? GL_TRUE : GL_FALSE;
- break;
- default:
- _mesa_error( &ctx->gl_ctx, GL_INVALID_ENUM, "OSMesaPixelStore(pname)" );
- return;
+#if 0 /* XXX use this in the future */
+#define PLOT(X,Y) \
+ if (Z < *zPtr) { \
+ GLchan *pixel = (GLchan *) PIXELADDR4(X, Y); \
+ pixel[rInd] = (pixel[rInd] * msavalue + rvalue) >> CHAN_BITS; \
+ pixel[gInd] = (pixel[gInd] * msavalue + gvalue) >> CHAN_BITS; \
+ pixel[bInd] = (pixel[bInd] * msavalue + bvalue) >> CHAN_BITS; \
+ pixel[aInd] = (pixel[aInd] * msavalue + avalue) >> CHAN_BITS; \
+ *zPtr = Z; \
}
+#endif
- compute_row_addresses( ctx );
+#ifdef WIN32
+#include "..\swrast\s_linetemp.h"
+#else
+#include "swrast/s_linetemp.h"
+#endif
}
-GLAPI void GLAPIENTRY OSMesaGetIntegerv( GLint pname, GLint *value )
+/*
+ * 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_func
+osmesa_choose_line_function( GLcontext *ctx )
{
- OSMesaContext ctx = OSMesaGetCurrentContext();
+ const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
+ const SWcontext *swrast = SWRAST_CONTEXT(ctx);
- switch (pname) {
- case OSMESA_WIDTH:
- *value = ctx->width;
- return;
- case OSMESA_HEIGHT:
- *value = ctx->height;
- return;
- case OSMESA_FORMAT:
- *value = ctx->format;
- return;
- case OSMESA_TYPE:
- *value = CHAN_TYPE;
- return;
- case OSMESA_ROW_LENGTH:
- *value = ctx->rowlength;
- return;
- case OSMESA_Y_UP:
- *value = ctx->yup;
- return;
- case OSMESA_MAX_WIDTH:
- *value = MAX_WIDTH;
- return;
- case OSMESA_MAX_HEIGHT:
- *value = MAX_HEIGHT;
- return;
- default:
- _mesa_error(&ctx->gl_ctx, GL_INVALID_ENUM, "OSMesaGetIntergerv(pname)");
- return;
+ 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 &&
+ osmesa->format != OSMESA_ARGB) return NULL;
+
+ if (swrast->_RasterMask==DEPTH_BIT
+ && ctx->Depth.Func==GL_LESS
+ && ctx->Depth.Mask==GL_TRUE
+ && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) {
+ return (swrast_line_func) flat_rgba_z_line;
}
-}
-/*
- * Return the depth buffer associated with an OSMesa context.
- * Input: c - the OSMesa context
- * Output: width, height - size of buffer in pixels
- * bytesPerValue - bytes per depth value (2 or 4)
- * buffer - pointer to depth buffer values
- * Return: GL_TRUE or GL_FALSE to indicate success or failure.
- */
-GLAPI GLboolean GLAPIENTRY
-OSMesaGetDepthBuffer( OSMesaContext c, GLint *width, GLint *height,
- GLint *bytesPerValue, void **buffer )
-{
- if ((!c->gl_buffer) || (!c->gl_buffer->DepthBuffer)) {
- *width = 0;
- *height = 0;
- *bytesPerValue = 0;
- *buffer = 0;
- return GL_FALSE;
+ if (swrast->_RasterMask == 0) {
+ return (swrast_line_func) flat_rgba_line;
}
- else {
- *width = c->gl_buffer->Width;
- *height = c->gl_buffer->Height;
- if (c->gl_visual->depthBits <= 16)
- *bytesPerValue = sizeof(GLushort);
- else
- *bytesPerValue = sizeof(GLuint);
- *buffer = c->gl_buffer->DepthBuffer;
- return GL_TRUE;
+
+ if (swrast->_RasterMask==(DEPTH_BIT|BLEND_BIT)
+ && ctx->Depth.Func==GL_LESS
+ && ctx->Depth.Mask==GL_TRUE
+ && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS
+ && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA
+ && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA
+ && ctx->Color.BlendSrcA==GL_SRC_ALPHA
+ && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA
+ && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
+ return (swrast_line_func) flat_blend_rgba_z_line_write;
+ }
+
+ if (swrast->_RasterMask==(DEPTH_BIT|BLEND_BIT)
+ && ctx->Depth.Func==GL_LESS
+ && ctx->Depth.Mask==GL_FALSE
+ && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS
+ && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA
+ && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA
+ && ctx->Color.BlendSrcA==GL_SRC_ALPHA
+ && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA
+ && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
+ return (swrast_line_func) flat_blend_rgba_z_line;
+ }
+
+ if (swrast->_RasterMask==BLEND_BIT
+ && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA
+ && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA
+ && ctx->Color.BlendSrcA==GL_SRC_ALPHA
+ && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA
+ && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
+ return (swrast_line_func) flat_blend_rgba_line;
}
+
+ return (swrast_line_func) NULL;
}
+
+/**********************************************************************/
+/***** Optimized triangle rendering *****/
+/**********************************************************************/
+
+
/*
- * Return the color buffer associated with an OSMesa context.
- * Input: c - the OSMesa context
- * Output: width, height - size of buffer in pixels
- * format - the pixel format (OSMESA_FORMAT)
- * buffer - pointer to color buffer values
- * Return: GL_TRUE or GL_FALSE to indicate success or failure.
+ * Smooth-shaded, z-less triangle, RGBA color.
*/
-GLAPI GLboolean GLAPIENTRY
-OSMesaGetColorBuffer( OSMesaContext c, GLint *width,
- GLint *height, GLint *format, void **buffer )
-{
- if (!c->buffer) {
- *width = 0;
- *height = 0;
- *format = 0;
- *buffer = 0;
- return GL_FALSE;
- }
- else {
- *width = c->width;
- *height = c->height;
- *format = c->format;
- *buffer = c->buffer;
- return GL_TRUE;
- }
-}
-
-
-
-struct name_address {
- const char *Name;
- GLvoid *Address;
-};
-
-static struct name_address functions[] = {
- { "OSMesaCreateContext", (void *) OSMesaCreateContext },
- { "OSMesaCreateContextExt", (void *) OSMesaCreateContextExt },
- { "OSMesaDestroyContext", (void *) OSMesaDestroyContext },
- { "OSMesaMakeCurrent", (void *) OSMesaMakeCurrent },
- { "OSMesaGetCurrentContext", (void *) OSMesaGetCurrentContext },
- { "OSMesaPixelsStore", (void *) OSMesaPixelStore },
- { "OSMesaGetIntegerv", (void *) OSMesaGetIntegerv },
- { "OSMesaGetDepthBuffer", (void *) OSMesaGetDepthBuffer },
- { "OSMesaGetColorBuffer", (void *) OSMesaGetColorBuffer },
- { "OSMesaGetProcAddress", (void *) OSMesaGetProcAddress },
- { NULL, NULL }
-};
-
-GLAPI void * GLAPIENTRY
-OSMesaGetProcAddress( const char *funcName )
-{
- int i;
- for (i = 0; functions[i].Name; i++) {
- if (_mesa_strcmp(functions[i].Name, funcName) == 0)
- return (void *) functions[i].Address;
+#define NAME smooth_rgba_z_triangle
+#define INTERP_Z 1
+#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
+#define INTERP_RGB 1
+#define INTERP_ALPHA 1
+#define SETUP_CODE \
+ const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
+#define RENDER_SPAN( span ) \
+ GLuint i; \
+ GLchan *img = PIXELADDR4(span.x, span.y); \
+ for (i = 0; i < span.end; i++, img += 4) { \
+ const GLdepth z = FixedToDepth(span.z); \
+ if (z < zRow[i]) { \
+ PACK_RGBA(img, FixedToChan(span.red), \
+ FixedToChan(span.green), FixedToChan(span.blue), \
+ FixedToChan(span.alpha)); \
+ zRow[i] = z; \
+ } \
+ span.red += span.redStep; \
+ span.green += span.greenStep; \
+ span.blue += span.blueStep; \
+ span.alpha += span.alphaStep; \
+ span.z += span.zStep; \
}
- return (void *) _glapi_get_proc_address(funcName);
-}
-
+#ifdef WIN32
+#include "..\swrast\s_tritemp.h"
+#else
+#include "swrast/s_tritemp.h"
+#endif
-/**********************************************************************/
-/*** Device Driver Functions ***/
-/**********************************************************************/
/*
- * Useful macros:
+ * Flat-shaded, z-less triangle, RGBA color.
*/
+#define NAME flat_rgba_z_triangle
+#define INTERP_Z 1
+#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
+#define SETUP_CODE \
+ const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); \
+ GLuint pixel; \
+ PACK_RGBA((GLchan *) &pixel, v2->color[0], v2->color[1], \
+ v2->color[2], v2->color[3]);
-#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)
+#define RENDER_SPAN( span ) \
+ GLuint i; \
+ GLuint *img = (GLuint *) PIXELADDR4(span.x, span.y); \
+ for (i = 0; i < span.end; i++) { \
+ const GLdepth z = FixedToDepth(span.z); \
+ if (z < zRow[i]) { \
+ img[i] = pixel; \
+ zRow[i] = z; \
+ } \
+ span.z += span.zStep; \
+ }
+#ifdef WIN32
+#include "..\swrast\s_tritemp.h"
#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)
+#include "swrast/s_tritemp.h"
#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))
-
-static void set_buffer( GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit )
-{
- /* separate read buffer not supported */
- ASSERT(buffer == ctx->DrawBuffer);
- ASSERT(bufferBit == FRONT_LEFT_BIT);
-}
-
-
-static void clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
- GLint x, GLint y, GLint width, GLint height )
+/*
+ * Return pointer to an accelerated triangle function if possible.
+ */
+static swrast_tri_func
+osmesa_choose_triangle_function( GLcontext *ctx )
{
- OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask;
+ const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
+ const SWcontext *swrast = SWRAST_CONTEXT(ctx);
- /* sanity check - we only have a front-left buffer */
- ASSERT((mask & (DD_FRONT_RIGHT_BIT | DD_BACK_LEFT_BIT | DD_BACK_RIGHT_BIT)) == 0);
- if (*colorMask == 0xffffffff && ctx->Color.IndexMask == 0xffffffff) {
- if (mask & DD_FRONT_LEFT_BIT) {
- if (osmesa->format == OSMESA_COLOR_INDEX) {
- if (all) {
- /* Clear whole CI buffer */
-#if CHAN_TYPE == GL_UNSIGNED_BYTE
- MEMSET(osmesa->buffer, ctx->Color.ClearIndex,
- osmesa->rowlength * osmesa->height);
-#else
- const GLint n = osmesa->rowlength * osmesa->height;
- GLchan *buffer = (GLchan *) osmesa->buffer;
- GLint i;
- for (i = 0; i < n; i ++) {
- buffer[i] = ctx->Color.ClearIndex;
- }
-#endif
- }
- else {
- /* Clear part of CI buffer */
- const GLchan clearIndex = (GLchan) ctx->Color.ClearIndex;
- GLint i, j;
- for (i = 0; i < height; i++) {
- GLchan *ptr1 = PIXELADDR1(x, (y + i));
- for (j = 0; j < width; j++) {
- *ptr1++ = clearIndex;
- }
- }
- }
- }
- else if (osmesa->format == OSMESA_RGB) {
- GLchan r, g, b;
- CLAMPED_FLOAT_TO_CHAN(r, ctx->Color.ClearColor[0]);
- CLAMPED_FLOAT_TO_CHAN(g, ctx->Color.ClearColor[1]);
- CLAMPED_FLOAT_TO_CHAN(b, ctx->Color.ClearColor[2]);
- if (all) {
- /* Clear whole RGB buffer */
- GLuint n = osmesa->rowlength * osmesa->height;
- GLchan *ptr3 = (GLchan *) osmesa->buffer;
- GLuint i;
- for (i = 0; i < n; i++) {
- PACK_RGB(ptr3, r, g, b);
- ptr3 += 3;
- }
- }
- else {
- /* Clear part of RGB buffer */
- GLint i, j;
- for (i = 0; i < height; i++) {
- GLchan *ptr3 = PIXELADDR3(x, (y + i));
- for (j = 0; j < width; j++) {
- PACK_RGB(ptr3, r, g, b);
- ptr3 += 3;
- }
- }
- }
- }
- else if (osmesa->format == OSMESA_BGR) {
- GLchan r, g, b;
- CLAMPED_FLOAT_TO_CHAN(r, ctx->Color.ClearColor[0]);
- CLAMPED_FLOAT_TO_CHAN(g, ctx->Color.ClearColor[1]);
- CLAMPED_FLOAT_TO_CHAN(b, ctx->Color.ClearColor[2]);
- if (all) {
- /* Clear whole RGB buffer */
- const GLint n = osmesa->rowlength * osmesa->height;
- GLchan *ptr3 = (GLchan *) osmesa->buffer;
- GLint i;
- for (i = 0; i < n; i++) {
- PACK_BGR(ptr3, r, g, b);
- ptr3 += 3;
- }
- }
- else {
- /* Clear part of RGB buffer */
- GLint i, j;
- for (i = 0; i < height; i++) {
- GLchan *ptr3 = PIXELADDR3(x, (y + i));
- for (j = 0; j < width; j++) {
- PACK_BGR(ptr3, r, g, b);
- ptr3 += 3;
- }
- }
- }
- }
- else if (osmesa->format == OSMESA_RGB_565) {
- GLushort clearPixel;
- GLchan r, g, b;
- CLAMPED_FLOAT_TO_CHAN(r, ctx->Color.ClearColor[0]);
- CLAMPED_FLOAT_TO_CHAN(g, ctx->Color.ClearColor[1]);
- CLAMPED_FLOAT_TO_CHAN(b, ctx->Color.ClearColor[2]);
- PACK_RGB_565(clearPixel, r, g, b);
- if (all) {
- /* Clear whole RGB buffer */
- const GLuint n = osmesa->rowlength * osmesa->height;
- GLushort *ptr2 = (GLushort *) osmesa->buffer;
- GLuint i;
- for (i = 0; i < n; i++) {
- *ptr2 = clearPixel;
- ptr2++;
- }
- }
- else {
- /* clear scissored region */
- GLint i, j;
- for (i = 0; i < height; i++) {
- GLushort *ptr2 = (GLushort *) PIXELADDR2(x, (y + i));
- for (j = 0; j < width; j++) {
- *ptr2 = clearPixel;
- ptr2++;
- }
- }
- }
- }
- else {
-#if CHAN_TYPE == GL_UNSIGNED_BYTE
- /* 4-byte pixel value */
- GLuint clearPixel;
- GLchan *clr = (GLchan *) &clearPixel;
- CLAMPED_FLOAT_TO_CHAN(clr[osmesa->rInd], ctx->Color.ClearColor[0]);
- CLAMPED_FLOAT_TO_CHAN(clr[osmesa->gInd], ctx->Color.ClearColor[1]);
- CLAMPED_FLOAT_TO_CHAN(clr[osmesa->bInd], ctx->Color.ClearColor[2]);
- CLAMPED_FLOAT_TO_CHAN(clr[osmesa->aInd], ctx->Color.ClearColor[3]);
- if (all) {
- /* Clear whole RGBA buffer */
- const GLuint n = osmesa->rowlength * osmesa->height;
- GLuint *ptr4 = (GLuint *) osmesa->buffer;
- GLuint i;
- if (clearPixel) {
- for (i = 0; i < n; i++) {
- *ptr4++ = clearPixel;
- }
- }
- else {
- _mesa_bzero(ptr4, n * sizeof(GLuint));
- }
- }
- else {
- /* Clear part of RGBA buffer */
- GLint i, j;
- for (i = 0; i < height; i++) {
- GLuint *ptr4 = (GLuint *) PIXELADDR4(x, (y + i));
- for (j = 0; j < width; j++) {
- *ptr4++ = clearPixel;
- }
- }
- }
-#else
- GLchan r, g, b, a;
- CLAMPED_FLOAT_TO_CHAN(r, ctx->Color.ClearColor[0]);
- CLAMPED_FLOAT_TO_CHAN(g, ctx->Color.ClearColor[1]);
- CLAMPED_FLOAT_TO_CHAN(b, ctx->Color.ClearColor[2]);
- CLAMPED_FLOAT_TO_CHAN(a, ctx->Color.ClearColor[3]);
- if (all) {
- /* Clear whole RGBA buffer */
- const GLuint n = osmesa->rowlength * osmesa->height;
- GLchan *p = (GLchan *) osmesa->buffer;
- GLuint i;
- for (i = 0; i < n; i++) {
- PACK_RGBA(p, r, g, b, a);
- p += 4;
- }
- }
- else {
- /* Clear part of RGBA buffer */
- GLint i, j;
- for (i = 0; i < height; i++) {
- GLchan *p = PIXELADDR4(x, (y + i));
- for (j = 0; j < width; j++) {
- PACK_RGBA(p, r, g, b, a);
- p += 4;
- }
- }
- }
+ if (CHAN_BITS != 8) return (swrast_tri_func) NULL;
+ if (ctx->RenderMode != GL_RENDER) return (swrast_tri_func) NULL;
+ if (ctx->Polygon.SmoothFlag) return (swrast_tri_func) NULL;
+ if (ctx->Polygon.StippleFlag) return (swrast_tri_func) NULL;
+ if (ctx->Texture._EnabledUnits) return (swrast_tri_func) NULL;
+ if (osmesa->format != OSMESA_RGBA &&
+ osmesa->format != OSMESA_BGRA &&
+ osmesa->format != OSMESA_ARGB) return (swrast_tri_func) NULL;
+ if (ctx->Polygon.CullFlag &&
+ ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)
+ return (swrast_tri_func) NULL;
-#endif
- }
- mask &= ~DD_FRONT_LEFT_BIT;
+ if (swrast->_RasterMask == DEPTH_BIT &&
+ ctx->Depth.Func == GL_LESS &&
+ ctx->Depth.Mask == GL_TRUE &&
+ ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) {
+ if (ctx->Light.ShadeModel == GL_SMOOTH) {
+ return (swrast_tri_func) smooth_rgba_z_triangle;
+ }
+ else {
+ return (swrast_tri_func) flat_rgba_z_triangle;
}
}
-
- if (mask)
- _swrast_Clear( ctx, mask, all, x, y, width, height );
+ return (swrast_tri_func) NULL;
}
-static void buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height )
+/* Override for the swrast triangle-selection function. Try to use one
+ * of our internal triangle functions, otherwise fall back to the
+ * standard swrast functions.
+ */
+static void
+osmesa_choose_triangle( GLcontext *ctx )
{
- /* 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;
- }
-}
-
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
-/**********************************************************************/
-/***** Read/write spans/arrays of RGBA pixels *****/
-/**********************************************************************/
+ swrast->Triangle = osmesa_choose_triangle_function( ctx );
+ if (!swrast->Triangle)
+ _swrast_choose_triangle( ctx );
+}
-/* Write RGBA pixels to an RGBA (or permuted) buffer. */
static void
-write_rgba_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
- CONST GLchan rgba[][4], const GLubyte mask[] )
+osmesa_choose_line( GLcontext *ctx )
{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLchan *p = PIXELADDR4(x, y);
- GLuint i;
- if (mask) {
- for (i = 0; i < n; i++, p += 4) {
- if (mask[i]) {
- PACK_RGBA(p, rgba[i][RCOMP], rgba[i][GCOMP],
- rgba[i][BCOMP], rgba[i][ACOMP]);
- }
- }
- }
- else {
- for (i = 0; i < n; i++, p += 4) {
- PACK_RGBA(p, rgba[i][RCOMP], rgba[i][GCOMP],
- rgba[i][BCOMP], rgba[i][ACOMP]);
- }
- }
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+
+ swrast->Line = osmesa_choose_line_function( ctx );
+ if (!swrast->Line)
+ _swrast_choose_line( ctx );
}
-/* Write RGBA pixels to an RGBA buffer. This is the fastest span-writer. */
+#define OSMESA_NEW_LINE (_NEW_LINE | \
+ _NEW_TEXTURE | \
+ _NEW_LIGHT | \
+ _NEW_DEPTH | \
+ _NEW_RENDERMODE | \
+ _SWRAST_NEW_RASTERMASK)
+
+#define OSMESA_NEW_TRIANGLE (_NEW_POLYGON | \
+ _NEW_TEXTURE | \
+ _NEW_LIGHT | \
+ _NEW_DEPTH | \
+ _NEW_RENDERMODE | \
+ _SWRAST_NEW_RASTERMASK)
+
+/* one-time, per-context initialization */
static void
-write_rgba_span_rgba( const GLcontext *ctx, GLuint n, GLint x, GLint y,
- CONST GLchan rgba[][4], const GLubyte mask[] )
+hook_in_driver_functions( GLcontext *ctx )
{
OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLuint *ptr4 = (GLuint *) PIXELADDR4(x, y);
- const GLuint *rgba4 = (const GLuint *) rgba;
- GLuint i;
- ASSERT(CHAN_TYPE == GL_UNSIGNED_BYTE);
- if (mask) {
- for (i = 0; i < n; i++) {
- if (mask[i]) {
- ptr4[i] = rgba4[i];
- }
- }
- }
- else {
- MEMCPY( ptr4, rgba4, n * 4 );
- }
-}
-
-
-/* Write RGB pixels to an RGBA (or permuted) buffer. */
-static void
-write_rgb_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
- CONST GLchan rgb[][3], const GLubyte mask[] )
-{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLchan *p = PIXELADDR4(x, y);
- GLuint i;
- if (mask) {
- for (i = 0; i < n; i++, p+=4) {
- if (mask[i]) {
- PACK_RGBA(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], CHAN_MAX);
- }
- }
- }
- else {
- for (i = 0; i < n; i++, p+=4) {
- PACK_RGBA(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], CHAN_MAX);
- }
- }
-}
+ SWcontext *swrast = SWRAST_CONTEXT( ctx );
+ struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx );
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ ASSERT((void *) osmesa == (void *) ctx->DriverCtx);
+ /* use default TCL pipeline */
+ tnl->Driver.RunPipeline = _tnl_run_pipeline;
-static void
-write_monocolor_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLchan color[4], const GLubyte mask[] )
-{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLchan *p = PIXELADDR4(x, y);
- GLuint i;
- for (i = 0; i < n; i++, p += 4) {
- if (mask[i]) {
- PACK_RGBA(p, color[RCOMP], color[GCOMP], color[BCOMP], color[ACOMP]);
- }
- }
-}
+ ctx->Driver.GetString = get_string;
+ ctx->Driver.UpdateState = osmesa_update_state;
+ ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
+ ctx->Driver.GetBufferSize = get_buffer_size;
+ ctx->Driver.Accum = _swrast_Accum;
+ ctx->Driver.Bitmap = _swrast_Bitmap;
+ ctx->Driver.Clear = clear; /* = _swrast_Clear */
+ ctx->Driver.CopyPixels = _swrast_CopyPixels;
+ ctx->Driver.DrawPixels = _swrast_DrawPixels;
+ ctx->Driver.ReadPixels = _swrast_ReadPixels;
+ ctx->Driver.DrawBuffer = _swrast_DrawBuffer;
+ ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
+ ctx->Driver.TexImage1D = _mesa_store_teximage1d;
+ ctx->Driver.TexImage2D = _mesa_store_teximage2d;
+ ctx->Driver.TexImage3D = _mesa_store_teximage3d;
+ ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
+ ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
+ ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
+ ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
-static void
-write_rgba_pixels( const GLcontext *ctx, GLuint n,
- const GLint x[], const GLint y[],
- CONST GLchan rgba[][4], const GLubyte mask[] )
-{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLuint i;
- for (i = 0; i < n; i++) {
- if (mask[i]) {
- GLchan *p = PIXELADDR4(x[i], y[i]);
- PACK_RGBA(p, rgba[i][RCOMP], rgba[i][GCOMP],
- rgba[i][BCOMP], rgba[i][ACOMP]);
- }
- }
-}
+ ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d;
+ ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d;
+ ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d;
+ ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d;
+ ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d;
+ ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d;
+ ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
+ ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
+ ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
+ ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
+ ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
+ ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
+ ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
+ ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
+ ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
+ swdd->SetBuffer = set_buffer;
-static void
-write_monocolor_pixels( const GLcontext *ctx, GLuint n,
- const GLint x[], const GLint y[],
- const GLchan color[4], const GLubyte mask[] )
-{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLuint i;
- for (i = 0; i < n; i++) {
- if (mask[i]) {
- GLchan *p = PIXELADDR4(x[i], y[i]);
- PACK_RGBA(p, color[RCOMP], color[GCOMP], color[BCOMP], color[ACOMP]);
- }
+ /* RGB(A) span/pixel functions */
+ if (osmesa->format == OSMESA_RGB) {
+ swdd->WriteRGBASpan = write_rgba_span_RGB;
+ swdd->WriteRGBSpan = write_rgb_span_RGB;
+ swdd->WriteMonoRGBASpan = write_monorgba_span_RGB;
+ swdd->WriteRGBAPixels = write_rgba_pixels_RGB;
+ swdd->WriteMonoRGBAPixels = write_monorgba_pixels_RGB;
+ swdd->ReadRGBASpan = read_rgba_span_RGB;
+ swdd->ReadRGBAPixels = read_rgba_pixels_RGB;
}
-}
-
-
-static void
-read_rgba_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
- GLchan rgba[][4] )
-{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLuint i;
- GLchan *p = PIXELADDR4(x, y);
- for (i = 0; i < n; i++, p += 4) {
- rgba[i][RCOMP] = UNPACK_RED(p);
- rgba[i][GCOMP] = UNPACK_GREEN(p);
- rgba[i][BCOMP] = UNPACK_BLUE(p);
- rgba[i][ACOMP] = UNPACK_ALPHA(p);
+ else if (osmesa->format == OSMESA_BGR) {
+ swdd->WriteRGBASpan = write_rgba_span_BGR;
+ swdd->WriteRGBSpan = write_rgb_span_BGR;
+ swdd->WriteMonoRGBASpan = write_monorgba_span_BGR;
+ swdd->WriteRGBAPixels = write_rgba_pixels_BGR;
+ swdd->WriteMonoRGBAPixels = write_monorgba_pixels_BGR;
+ swdd->ReadRGBASpan = read_rgba_span_BGR;
+ swdd->ReadRGBAPixels = read_rgba_pixels_BGR;
+ }
+ else if (osmesa->format == OSMESA_RGB_565) {
+ swdd->WriteRGBASpan = write_rgba_span_RGB_565;
+ swdd->WriteRGBSpan = write_rgb_span_RGB_565;
+ swdd->WriteMonoRGBASpan = write_monorgba_span_RGB_565;
+ swdd->WriteRGBAPixels = write_rgba_pixels_RGB_565;
+ swdd->WriteMonoRGBAPixels = write_monorgba_pixels_RGB_565;
+ swdd->ReadRGBASpan = read_rgba_span_RGB_565;
+ swdd->ReadRGBAPixels = read_rgba_pixels_RGB_565;
+ }
+ else if (osmesa->format == OSMESA_RGBA) {
+ swdd->WriteRGBASpan = write_rgba_span_RGBA;
+ swdd->WriteRGBSpan = write_rgb_span_RGBA;
+ swdd->WriteMonoRGBASpan = write_monorgba_span_RGBA;
+ swdd->WriteRGBAPixels = write_rgba_pixels_RGBA;
+ swdd->WriteMonoRGBAPixels = write_monorgba_pixels_RGBA;
+ swdd->ReadRGBASpan = read_rgba_span_RGBA;
+ swdd->ReadRGBAPixels = read_rgba_pixels_RGBA;
+ }
+ else if (osmesa->format == OSMESA_BGRA) {
+ swdd->WriteRGBASpan = write_rgba_span_BGRA;
+ swdd->WriteRGBSpan = write_rgb_span_BGRA;
+ swdd->WriteMonoRGBASpan = write_monorgba_span_BGRA;
+ swdd->WriteRGBAPixels = write_rgba_pixels_BGRA;
+ swdd->WriteMonoRGBAPixels = write_monorgba_pixels_BGRA;
+ swdd->ReadRGBASpan = read_rgba_span_BGRA;
+ swdd->ReadRGBAPixels = read_rgba_pixels_BGRA;
+ }
+ else if (osmesa->format == OSMESA_ARGB) {
+ swdd->WriteRGBASpan = write_rgba_span_ARGB;
+ swdd->WriteRGBSpan = write_rgb_span_ARGB;
+ swdd->WriteMonoRGBASpan = write_monorgba_span_ARGB;
+ swdd->WriteRGBAPixels = write_rgba_pixels_ARGB;
+ swdd->WriteMonoRGBAPixels = write_monorgba_pixels_ARGB;
+ swdd->ReadRGBASpan = read_rgba_span_ARGB;
+ swdd->ReadRGBAPixels = read_rgba_pixels_ARGB;
+ }
+ else if (osmesa->format == OSMESA_COLOR_INDEX) {
+ swdd->WriteCI32Span = write_index32_span_CI;
+ swdd->WriteCI8Span = write_index8_span_CI;
+ swdd->WriteMonoCISpan = write_monoindex_span_CI;
+ swdd->WriteCI32Pixels = write_index_pixels_CI;
+ swdd->WriteMonoCIPixels = write_monoindex_pixels_CI;
+ swdd->ReadCI32Span = read_index_span_CI;
+ swdd->ReadCI32Pixels = read_index_pixels_CI;
+ }
+ else {
+ _mesa_problem(ctx, "bad pixel format in osmesa_update_state!\n");
}
-}
-
-/* Read RGBA pixels from an RGBA buffer */
-static void
-read_rgba_span_rgba( const GLcontext *ctx, GLuint n, GLint x, GLint y,
- GLchan rgba[][4] )
-{
- OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLuint *ptr4 = (GLuint *) PIXELADDR4(x, y);
- MEMCPY( rgba, ptr4, n * 4 * sizeof(GLchan) );
+ /* Extend the software rasterizer with our optimized line and triangle
+ * drawin functions.
+ */
+ swrast->choose_line = osmesa_choose_line;
+ swrast->choose_triangle = osmesa_choose_triangle;
+ swrast->invalidate_line |= OSMESA_NEW_LINE;
+ swrast->invalidate_triangle |= OSMESA_NEW_TRIANGLE;
}
-static void
-read_rgba_pixels( const GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- GLchan rgba[][4], const GLubyte mask[] )
-{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLuint i;
- for (i = 0; i < n; i++) {
- if (mask[i]) {
- const GLchan *p = PIXELADDR4(x[i], y[i]);
- rgba[i][RCOMP] = UNPACK_RED(p);
- rgba[i][GCOMP] = UNPACK_GREEN(p);
- rgba[i][BCOMP] = UNPACK_BLUE(p);
- rgba[i][ACOMP] = UNPACK_ALPHA(p);
- }
- }
-}
+
/**********************************************************************/
-/***** 3 byte RGB pixel support funcs *****/
+/***** Public Functions *****/
/**********************************************************************/
-/* Write RGBA pixels to an RGB buffer. */
-static void
-write_rgba_span_RGB( const GLcontext *ctx, GLuint n, GLint x, GLint y,
- CONST GLchan rgba[][4], const GLubyte mask[] )
-{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLchan *p = PIXELADDR3(x, y);
- GLuint i;
- if (mask) {
- for (i = 0; i < n; i++, p += 3) {
- if (mask[i]) {
- PACK_RGB(p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
- }
- }
- }
- else {
- for (i = 0; i < n; i++, p += 3) {
- PACK_RGB(p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
- }
- }
-}
-
-/* Write RGBA pixels to an BGR buffer. */
-static void
-write_rgba_span_BGR( const GLcontext *ctx, GLuint n, GLint x, GLint y,
- CONST GLchan rgba[][4], const GLubyte mask[] )
-{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLchan *p = PIXELADDR3(x, y);
- GLuint i;
- if (mask) {
- for (i = 0; i < n; i++, p += 3) {
- if (mask[i]) {
- PACK_BGR(p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
- }
- }
- }
- else {
- for (i = 0; i < n; i++, p += 3) {
- PACK_BGR(p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
- }
- }
-}
-
-/* Write RGB pixels to an RGB buffer. */
-static void
-write_rgb_span_RGB( const GLcontext *ctx, GLuint n, GLint x, GLint y,
- CONST GLchan rgb[][3], const GLubyte mask[] )
-{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLchan *p = PIXELADDR3(x, y);
- GLuint i;
- if (mask) {
- for (i = 0; i < n; i++, p += 3) {
- if (mask[i]) {
- PACK_RGB(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
- }
- }
- }
- else {
- for (i = 0; i < n; i++, p += 3) {
- PACK_RGB(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
- }
- }
-}
-/* Write RGB pixels to an BGR buffer. */
-static void
-write_rgb_span_BGR( const GLcontext *ctx, GLuint n, GLint x, GLint y,
- CONST GLchan rgb[][3], const GLubyte mask[] )
+/*
+ * Create an Off-Screen Mesa rendering context. The only attribute needed is
+ * an RGBA vs Color-Index mode flag.
+ *
+ * Input: format - either GL_RGBA or GL_COLOR_INDEX
+ * sharelist - specifies another OSMesaContext with which to share
+ * display lists. NULL indicates no sharing.
+ * Return: an OSMesaContext or 0 if error
+ */
+GLAPI OSMesaContext GLAPIENTRY
+OSMesaCreateContext( GLenum format, OSMesaContext sharelist )
{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLchan *p = PIXELADDR3(x, y);
- GLuint i;
- if (mask) {
- for (i = 0; i < n; i++, p += 3) {
- if (mask[i]) {
- PACK_BGR(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
- }
- }
- }
- else {
- for (i = 0; i < n; i++, p += 3) {
- PACK_BGR(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
- }
- }
+ return OSMesaCreateContextExt(format, DEFAULT_SOFTWARE_DEPTH_BITS,
+ 8, 16, sharelist);
}
-static void
-write_monocolor_span_RGB( const GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLchan color[4], const GLubyte mask[] )
-{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLchan *p = PIXELADDR3(x, y);
- GLuint i;
- for (i = 0; i < n; i++, p += 3) {
- if (mask[i]) {
- PACK_RGB(p, color[RCOMP], color[GCOMP], color[BCOMP]);
- }
- }
-}
-static void
-write_monocolor_span_BGR( const GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLchan color[4], const GLubyte mask[] )
+/*
+ * New in Mesa 3.5
+ *
+ * Create context and specify size of ancillary buffers.
+ */
+GLAPI OSMesaContext GLAPIENTRY
+OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits,
+ GLint accumBits, OSMesaContext sharelist )
{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLchan *p = PIXELADDR3(x, y);
- GLuint i;
- for (i = 0; i < n; i++, p += 3) {
- if (mask[i]) {
- PACK_BGR(p, color[RCOMP], color[GCOMP], color[BCOMP]);
- }
- }
-}
+ OSMesaContext osmesa;
+ GLint rshift, gshift, bshift, ashift;
+ GLint rind, gind, bind, aind;
+ GLint indexBits = 0, redBits = 0, greenBits = 0, blueBits = 0, alphaBits =0;
+ GLboolean rgbmode;
+ const GLuint i4 = 1;
+ const GLubyte *i1 = (GLubyte *) &i4;
+ const GLint little_endian = *i1;
-static void
-write_rgba_pixels_RGB( const GLcontext *ctx, GLuint n,
- const GLint x[], const GLint y[],
- CONST GLchan rgba[][4], const GLubyte mask[] )
-{
- const OSMesaContext osmesa = (const OSMesaContext) ctx;
- GLuint i;
- for (i = 0; i < n; i++) {
- if (mask[i]) {
- GLchan *p = PIXELADDR3(x[i], y[i]);
- PACK_RGB(p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
- }
+ rind = gind = bind = aind = 0;
+ if (format==OSMESA_COLOR_INDEX) {
+ indexBits = 8;
+ rshift = gshift = bshift = ashift = 0;
+ rgbmode = GL_FALSE;
}
-}
-
-static void
-write_rgba_pixels_BGR( const GLcontext *ctx, GLuint n,
- const GLint x[], const GLint y[],
- CONST GLchan rgba[][4], const GLubyte mask[] )
-{
- const OSMesaContext osmesa = (const OSMesaContext) ctx;
- GLuint i;
- for (i = 0; i < n; i++) {
- if (mask[i]) {
- GLchan *p = PIXELADDR3(x[i], y[i]);
- PACK_BGR(p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
+ else if (format==OSMESA_RGBA) {
+ indexBits = 0;
+ redBits = CHAN_BITS;
+ greenBits = CHAN_BITS;
+ blueBits = CHAN_BITS;
+ alphaBits = CHAN_BITS;
+ rind = 0;
+ gind = 1;
+ bind = 2;
+ aind = 3;
+ if (little_endian) {
+ rshift = 0;
+ gshift = 8;
+ bshift = 16;
+ ashift = 24;
}
- }
-}
-
-static void
-write_monocolor_pixels_RGB( const GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLchan color[4], const GLubyte mask[] )
-{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLuint i;
- for (i = 0; i < n; i++) {
- if (mask[i]) {
- GLchan *p = PIXELADDR3(x[i], y[i]);
- PACK_RGB(p, color[RCOMP], color[GCOMP], color[BCOMP]);
+ else {
+ rshift = 24;
+ gshift = 16;
+ bshift = 8;
+ ashift = 0;
}
+ rgbmode = GL_TRUE;
}
-}
-
-static void
-write_monocolor_pixels_BGR( const GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLchan color[4], const GLubyte mask[] )
-{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLuint i;
- for (i = 0; i < n; i++) {
- if (mask[i]) {
- GLchan *p = PIXELADDR3(x[i], y[i]);
- PACK_BGR(p, color[RCOMP], color[GCOMP], color[BCOMP]);
+ else if (format==OSMESA_BGRA) {
+ indexBits = 0;
+ redBits = CHAN_BITS;
+ greenBits = CHAN_BITS;
+ blueBits = CHAN_BITS;
+ alphaBits = CHAN_BITS;
+ bind = 0;
+ gind = 1;
+ rind = 2;
+ aind = 3;
+ if (little_endian) {
+ bshift = 0;
+ gshift = 8;
+ rshift = 16;
+ ashift = 24;
}
- }
-}
-
-static void
-read_rgba_span3( const GLcontext *ctx, GLuint n, GLint x, GLint y,
- GLchan rgba[][4] )
-{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLuint i;
- const GLchan *p = PIXELADDR3(x, y);
- for (i = 0; i < n; i++, p += 3) {
- rgba[i][RCOMP] = UNPACK_RED(p);
- rgba[i][GCOMP] = UNPACK_GREEN(p);
- rgba[i][BCOMP] = UNPACK_BLUE(p);
- rgba[i][ACOMP] = CHAN_MAX;
- }
-}
-
-static void
-read_rgba_pixels3( const GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- GLchan rgba[][4], const GLubyte mask[] )
-{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLuint i;
- for (i = 0; i < n; i++) {
- if (mask[i]) {
- const GLchan *p = PIXELADDR3(x[i], y[i]);
- rgba[i][RCOMP] = UNPACK_RED(p);
- rgba[i][GCOMP] = UNPACK_GREEN(p);
- rgba[i][BCOMP] = UNPACK_BLUE(p);
- rgba[i][ACOMP] = CHAN_MAX;
+ else {
+ bshift = 24;
+ gshift = 16;
+ rshift = 8;
+ ashift = 0;
}
+ rgbmode = GL_TRUE;
}
-}
-
-
-/**********************************************************************/
-/***** 2 byte RGB pixel support funcs *****/
-/**********************************************************************/
-
-/* Write RGBA pixels to an RGB_565 buffer. */
-static void
-write_rgba_span2( const GLcontext *ctx,
- GLuint n, GLint x, GLint y,
- CONST GLchan rgba[][4], const GLubyte mask[] )
-{
- OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLushort *ptr2 = (GLushort *) PIXELADDR2(x, y);
- GLuint i;
- if (mask) {
- for (i = 0; i < n; i++, ptr2++) {
- if (mask[i]) {
- PACK_RGB_565(*ptr2, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
- }
- }
- }
- else {
- for (i = 0; i < n; i++, ptr2++) {
- PACK_RGB_565(*ptr2, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
- }
- }
-}
-
-
-/* Write RGB pixels to an RGB_565 buffer. */
-static void
-write_rgb_span2( const GLcontext *ctx,
- GLuint n, GLint x, GLint y,
- CONST GLchan rgb[][3], const GLubyte mask[] )
-{
- OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLushort *ptr2 = (GLushort *) PIXELADDR2(x, y);
- GLuint i;
- if (mask) {
- for (i = 0; i < n; i++, ptr2++) {
- if (mask[i]) {
- PACK_RGB_565(*ptr2, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
- }
- }
- }
- else {
- for (i = 0; i < n; i++, ptr2++) {
- PACK_RGB_565(*ptr2, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
- }
- }
-}
-
-
-static void
-write_monocolor_span2( const GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLchan color[4], const GLubyte mask[] )
-{
- OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLushort pixel;
- GLushort *ptr2 = (GLushort *) PIXELADDR2(x, y);
- GLuint i;
- PACK_RGB_565(pixel, color[RCOMP], color[GCOMP], color[BCOMP]);
- for (i = 0; i < n; i++, ptr2++) {
- if (mask[i]) {
- *ptr2 = pixel;
- }
- }
-}
-
-
-static void
-write_rgba_pixels2( const GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- CONST GLchan rgba[][4], const GLubyte mask[] )
-{
- OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLuint i;
- for (i = 0; i < n; i++) {
- if (mask[i]) {
- GLushort *ptr2 = (GLushort *) PIXELADDR2(x[i],y[i]);
- PACK_RGB_565(*ptr2, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
- }
- }
-}
-
-static void
-write_monocolor_pixels2( const GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLchan color[4], const GLubyte mask[] )
-{
- OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLuint i;
- GLushort pixel;
- PACK_RGB_565(pixel, color[RCOMP], color[GCOMP], color[BCOMP]);
- for (i = 0; i < n; i++) {
- if (mask[i]) {
- GLushort *ptr2 = (GLushort *) PIXELADDR2(x[i],y[i]);
- *ptr2 = pixel;
+ else if (format==OSMESA_ARGB) {
+ indexBits = 0;
+ redBits = CHAN_BITS;
+ greenBits = CHAN_BITS;
+ blueBits = CHAN_BITS;
+ alphaBits = CHAN_BITS;
+ aind = 0;
+ rind = 1;
+ gind = 2;
+ bind = 3;
+ if (little_endian) {
+ ashift = 0;
+ rshift = 8;
+ gshift = 16;
+ bshift = 24;
}
- }
-}
-
-static void
-read_rgba_span2( const GLcontext *ctx,
- GLuint n, GLint x, GLint y,
- GLchan rgba[][4] )
-{
- OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLuint i;
- const GLushort *ptr2 = (const GLushort *) PIXELADDR2(x, y);
- for (i = 0; i < n; i++, ptr2++) {
- /* This should be fixed to get the low bits right */
- rgba[i][RCOMP] = (*ptr2 >> 8) & 0xFe;
- rgba[i][GCOMP] = (*ptr2 >> 3) & 0xFc;
- rgba[i][BCOMP] = (*ptr2 << 3) & 0xFe;
- rgba[i][ACOMP] = 0;
- }
-}
-
-static void
-read_rgba_pixels2( const GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- GLchan rgba[][4], const GLubyte mask[] )
-{
- OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLuint i;
- for (i = 0; i < n; i++) {
- if (mask[i]) {
- /* This should be fixed to get the low bits right */
- const GLushort *ptr2 = (const GLushort *) PIXELADDR2(x[i],y[i]);
- rgba[i][RCOMP] = (*ptr2 >> 8) & 0xFE;
- rgba[i][GCOMP] = (*ptr2 >> 3) & 0xFC;
- rgba[i][BCOMP] = (*ptr2 << 3) & 0xFE;
- rgba[i][ACOMP] = 0;
+ else {
+ ashift = 24;
+ rshift = 16;
+ gshift = 8;
+ bshift = 0;
}
+ rgbmode = GL_TRUE;
}
-}
-
-
-
-/**********************************************************************/
-/***** Read/write spans/arrays of CI pixels *****/
-/**********************************************************************/
-
-/* Write 32-bit color index to buffer */
-static void
-write_index32_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLuint index[], const GLubyte mask[] )
-{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLchan *ptr1 = PIXELADDR1(x, y);
- GLuint i;
- if (mask) {
- for (i=0;i<n;i++,ptr1++) {
- if (mask[i]) {
- *ptr1 = (GLchan) index[i];
- }
- }
+ else if (format==OSMESA_RGB) {
+ indexBits = 0;
+ redBits = CHAN_BITS;
+ greenBits = CHAN_BITS;
+ blueBits = CHAN_BITS;
+ alphaBits = 0;
+ bshift = 0;
+ gshift = 8;
+ rshift = 16;
+ ashift = 24;
+ rind = 0;
+ gind = 1;
+ bind = 2;
+ rgbmode = GL_TRUE;
}
- else {
- for (i=0;i<n;i++,ptr1++) {
- *ptr1 = (GLchan) index[i];
- }
+ else if (format==OSMESA_BGR) {
+ indexBits = 0;
+ redBits = CHAN_BITS;
+ greenBits = CHAN_BITS;
+ blueBits = CHAN_BITS;
+ alphaBits = 0;
+ bshift = 0;
+ gshift = 8;
+ rshift = 16;
+ ashift = 24;
+ rind = 2;
+ gind = 1;
+ bind = 0;
+ rgbmode = GL_TRUE;
}
-}
-
-
-/* Write 8-bit color index to buffer */
-static void
-write_index8_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
- const GLubyte index[], const GLubyte mask[] )
-{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLchan *ptr1 = PIXELADDR1(x, y);
- GLuint i;
- if (mask) {
- for (i=0;i<n;i++,ptr1++) {
- if (mask[i]) {
- *ptr1 = (GLchan) index[i];
- }
- }
+ else if (format==OSMESA_RGB_565) {
+ indexBits = 0;
+ redBits = 5;
+ greenBits = 6;
+ blueBits = 5;
+ alphaBits = 0;
+ rshift = 11;
+ gshift = 5;
+ bshift = 0;
+ ashift = 0;
+ rind = 0; /* not used */
+ gind = 0;
+ bind = 0;
+ rgbmode = GL_TRUE;
}
else {
- MEMCPY(ptr1, index, n * sizeof(GLchan));
- }
-}
-
-
-static void
-write_monoindex_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
- GLuint colorIndex, const GLubyte mask[] )
-{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLchan *ptr1 = PIXELADDR1(x, y);
- GLuint i;
- for (i=0;i<n;i++,ptr1++) {
- if (mask[i]) {
- *ptr1 = (GLchan) colorIndex;
- }
- }
-}
-
-
-static void
-write_index_pixels( const GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLuint index[], const GLubyte mask[] )
-{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLchan *ptr1 = PIXELADDR1(x[i], y[i]);
- *ptr1 = (GLchan) index[i];
- }
+ return NULL;
}
-}
-static void
-write_monoindex_pixels( const GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- GLuint colorIndex, const GLubyte mask[] )
-{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLchan *ptr1 = PIXELADDR1(x[i], y[i]);
- *ptr1 = (GLchan) colorIndex;
+ osmesa = (OSMesaContext) CALLOC_STRUCT(osmesa_context);
+ if (osmesa) {
+ osmesa->gl_visual = _mesa_create_visual( rgbmode,
+ GL_FALSE, /* double buffer */
+ GL_FALSE, /* stereo */
+ redBits,
+ greenBits,
+ blueBits,
+ alphaBits,
+ indexBits,
+ depthBits,
+ stencilBits,
+ accumBits,
+ accumBits,
+ accumBits,
+ alphaBits ? accumBits : 0,
+ 1 /* num samples */
+ );
+ if (!osmesa->gl_visual) {
+ FREE(osmesa);
+ return NULL;
}
- }
-}
-
-
-static void
-read_index_span( const GLcontext *ctx,
- GLuint n, GLint x, GLint y, GLuint index[] )
-{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLuint i;
- const GLchan *ptr1 = (const GLchan *) PIXELADDR1(x, y);
- for (i=0;i<n;i++,ptr1++) {
- index[i] = (GLuint) *ptr1;
- }
-}
-
-static void
-read_index_pixels( const GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- GLuint index[], const GLubyte mask[] )
-{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- GLuint i;
- for (i=0;i<n;i++) {
- if (mask[i] ) {
- const GLchan *ptr1 = PIXELADDR1(x[i], y[i]);
- index[i] = (GLuint) *ptr1;
+ if (!_mesa_initialize_context(&osmesa->gl_ctx,
+ osmesa->gl_visual,
+ sharelist ? &sharelist->gl_ctx
+ : (GLcontext *) NULL,
+ (void *) osmesa,
+ GL_FALSE)) {
+ _mesa_destroy_visual( osmesa->gl_visual );
+ FREE(osmesa);
+ return NULL;
}
- }
-}
-
-
-
-/**********************************************************************/
-/***** Optimized line rendering *****/
-/**********************************************************************/
-
-
-/*
- * Draw a flat-shaded, RGB line into an osmesa buffer.
- */
-static void
-flat_rgba_line( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
-{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- const GLchan *color = vert1->color;
-
-#define INTERP_XY 1
-#define CLIP_HACK 1
-#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.
- */
-static void
-flat_rgba_z_line(GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1)
-{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- const GLchan *color = vert1->color;
-
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
-#define CLIP_HACK 1
-#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
-}
-
-
-/*
- * Draw a flat-shaded, alpha-blended, RGB line into an osmesa buffer.
- * XXX update for GLchan
- */
-static void
-flat_blend_rgba_line( GLcontext *ctx,
- const SWvertex *vert0, const SWvertex *vert1 )
-{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- const GLint rshift = osmesa->rshift;
- const GLint gshift = osmesa->gshift;
- const GLint bshift = osmesa->bshift;
- const GLint avalue = vert0->color[3];
- const GLint msavalue = CHAN_MAX - avalue;
- const GLint rvalue = vert1->color[0]*avalue;
- const GLint gvalue = vert1->color[1]*avalue;
- const GLint bvalue = vert1->color[2]*avalue;
-
-#define INTERP_XY 1
-#define CLIP_HACK 1
-#define PLOT(X,Y) \
- { GLuint *ptr4 = (GLuint *) PIXELADDR4(X, Y); \
- GLuint pixel = 0; \
- pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);\
- pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);\
- pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);\
- *ptr4 = pixel; \
- }
-
-#if 0 /* XXX use this in the future */
-#define PLOT(X,Y) \
- { \
- GLchan *pixel = (GLchan *) PIXELADDR4(X, Y); \
- pixel[rInd] = (pixel[rInd] * msavalue + rvalue) >> CHAN_BITS; \
- pixel[gInd] = (pixel[gInd] * msavalue + gvalue) >> CHAN_BITS; \
- pixel[bInd] = (pixel[bInd] * msavalue + bvalue) >> CHAN_BITS; \
- pixel[aInd] = (pixel[aInd] * msavalue + avalue) >> CHAN_BITS; \
- }
-#endif
-
-#ifdef WIN32
-#include "..\swrast\s_linetemp.h"
-#else
-#include "swrast/s_linetemp.h"
-#endif
-}
-
-
-/*
- * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
- * But don't write to Z buffer.
- * XXX update for GLchan
- */
-static void
-flat_blend_rgba_z_line( GLcontext *ctx,
- const SWvertex *vert0, const SWvertex *vert1 )
-{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- const GLint rshift = osmesa->rshift;
- const GLint gshift = osmesa->gshift;
- const GLint bshift = osmesa->bshift;
- const GLint avalue = vert0->color[3];
- const GLint msavalue = 256 - avalue;
- const GLint rvalue = vert1->color[0]*avalue;
- const GLint gvalue = vert1->color[1]*avalue;
- const GLint bvalue = vert1->color[2]*avalue;
-
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
-#define CLIP_HACK 1
-#define PLOT(X,Y) \
- if (Z < *zPtr) { \
- GLuint *ptr4 = (GLuint *) PIXELADDR4(X, Y); \
- GLuint pixel = 0; \
- pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift); \
- pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift); \
- pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift); \
- *ptr4 = pixel; \
- }
-
-#if 0 /* XXX use this in the future */
-#define PLOT(X,Y) \
- if (Z < *zPtr) { \
- GLchan *pixel = (GLchan *) PIXELADDR4(X, Y); \
- pixel[rInd] = (pixel[rInd] * msavalue + rvalue) >> CHAN_BITS; \
- pixel[gInd] = (pixel[gInd] * msavalue + gvalue) >> CHAN_BITS; \
- pixel[bInd] = (pixel[bInd] * msavalue + bvalue) >> CHAN_BITS; \
- pixel[aInd] = (pixel[aInd] * msavalue + avalue) >> CHAN_BITS; \
- }
-#endif
-
-#ifdef WIN32
-#include "..\swrast\s_linetemp.h"
-#else
-#include "swrast/s_linetemp.h"
-#endif
-}
-
-
-/*
- * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
- * XXX update for GLchan
- */
-static void
-flat_blend_rgba_z_line_write( GLcontext *ctx,
- const SWvertex *vert0, const SWvertex *vert1 )
-{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- const GLint rshift = osmesa->rshift;
- const GLint gshift = osmesa->gshift;
- const GLint bshift = osmesa->bshift;
- const GLint avalue = vert0->color[3];
- const GLint msavalue = 256 - avalue;
- const GLint rvalue = vert1->color[0]*avalue;
- const GLint gvalue = vert1->color[1]*avalue;
- const GLint bvalue = vert1->color[2]*avalue;
-
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
-#define CLIP_HACK 1
-#define PLOT(X,Y) \
- if (Z < *zPtr) { \
- GLuint *ptr4 = (GLuint *) PIXELADDR4(X, Y); \
- GLuint pixel = 0; \
- pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift); \
- pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift); \
- pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift); \
- *ptr4 = pixel; \
- *zPtr = Z; \
- }
-
-#if 0 /* XXX use this in the future */
-#define PLOT(X,Y) \
- if (Z < *zPtr) { \
- GLchan *pixel = (GLchan *) PIXELADDR4(X, Y); \
- pixel[rInd] = (pixel[rInd] * msavalue + rvalue) >> CHAN_BITS; \
- pixel[gInd] = (pixel[gInd] * msavalue + gvalue) >> CHAN_BITS; \
- pixel[bInd] = (pixel[bInd] * msavalue + bvalue) >> CHAN_BITS; \
- pixel[aInd] = (pixel[aInd] * msavalue + avalue) >> CHAN_BITS; \
- *zPtr = Z; \
- }
-#endif
-
-#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_func
-osmesa_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 &&
- osmesa->format != OSMESA_ARGB) return NULL;
- if (swrast->_RasterMask==DEPTH_BIT
- && ctx->Depth.Func==GL_LESS
- && ctx->Depth.Mask==GL_TRUE
- && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) {
- return (swrast_line_func) flat_rgba_z_line;
- }
+ _mesa_enable_sw_extensions(&(osmesa->gl_ctx));
+ _mesa_enable_1_3_extensions(&(osmesa->gl_ctx));
+ /*_mesa_enable_1_4_extensions(&(osmesa->gl_ctx));*/
- if (swrast->_RasterMask == 0) {
- return (swrast_line_func) flat_rgba_line;
- }
+ osmesa->gl_buffer = _mesa_create_framebuffer( osmesa->gl_visual,
+ (GLboolean) ( osmesa->gl_visual->depthBits > 0 ),
+ (GLboolean) ( osmesa->gl_visual->stencilBits > 0 ),
+ (GLboolean) ( osmesa->gl_visual->accumRedBits > 0 ),
+ GL_FALSE /* s/w alpha */ );
- if (swrast->_RasterMask==(DEPTH_BIT|BLEND_BIT)
- && ctx->Depth.Func==GL_LESS
- && ctx->Depth.Mask==GL_TRUE
- && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS
- && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA
- && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA
- && ctx->Color.BlendSrcA==GL_SRC_ALPHA
- && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA
- && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
- return (swrast_line_func) flat_blend_rgba_z_line_write;
- }
+ if (!osmesa->gl_buffer) {
+ _mesa_destroy_visual( osmesa->gl_visual );
+ _mesa_free_context_data( &osmesa->gl_ctx );
+ FREE(osmesa);
+ return NULL;
+ }
+ osmesa->format = format;
+ osmesa->buffer = NULL;
+ osmesa->width = 0;
+ osmesa->height = 0;
+ osmesa->userRowLength = 0;
+ osmesa->rowlength = 0;
+ osmesa->yup = GL_TRUE;
+ osmesa->rshift = rshift;
+ osmesa->gshift = gshift;
+ osmesa->bshift = bshift;
+ osmesa->ashift = ashift;
+ osmesa->rInd = rind;
+ osmesa->gInd = gind;
+ osmesa->bInd = bind;
+ osmesa->aInd = aind;
- if (swrast->_RasterMask==(DEPTH_BIT|BLEND_BIT)
- && ctx->Depth.Func==GL_LESS
- && ctx->Depth.Mask==GL_FALSE
- && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS
- && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA
- && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA
- && ctx->Color.BlendSrcA==GL_SRC_ALPHA
- && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA
- && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
- return (swrast_line_func) flat_blend_rgba_z_line;
- }
+ /* Initialize the software rasterizer and helper modules. */
+ {
+ GLcontext *ctx = &osmesa->gl_ctx;
- if (swrast->_RasterMask==BLEND_BIT
- && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA
- && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA
- && ctx->Color.BlendSrcA==GL_SRC_ALPHA
- && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA
- && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
- return (swrast_line_func) flat_blend_rgba_line;
+ _swrast_CreateContext( ctx );
+ _ac_CreateContext( ctx );
+ _tnl_CreateContext( ctx );
+ _swsetup_CreateContext( ctx );
+
+ _swsetup_Wakeup( ctx );
+ hook_in_driver_functions( ctx );
+ }
}
-
- return (swrast_line_func) NULL;
+ return osmesa;
}
-/**********************************************************************/
-/***** Optimized triangle rendering *****/
-/**********************************************************************/
-
-
/*
- * Smooth-shaded, z-less triangle, RGBA color.
+ * Destroy an Off-Screen Mesa rendering context.
+ *
+ * Input: ctx - the context to destroy
*/
-static void smooth_rgba_z_triangle( GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1,
- const SWvertex *v2 )
+GLAPI void GLAPIENTRY
+OSMesaDestroyContext( OSMesaContext ctx )
{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
-#define INTERP_Z 1
-#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
-#define INTERP_RGB 1
-#define INTERP_ALPHA 1
-#define RENDER_SPAN( span ) \
- GLuint i; \
- GLchan *img = PIXELADDR4(span.x, span.y); \
- for (i = 0; i < span.end; i++, img += 4) { \
- const GLdepth z = FixedToDepth(span.z); \
- if (z < zRow[i]) { \
- PACK_RGBA(img, FixedToChan(span.red), \
- FixedToChan(span.green), FixedToChan(span.blue), \
- FixedToChan(span.alpha)); \
- zRow[i] = z; \
- } \
- span.red += span.redStep; \
- span.green += span.greenStep; \
- span.blue += span.blueStep; \
- span.alpha += span.alphaStep; \
- span.z += span.zStep; \
- }
+ if (ctx) {
+ _swsetup_DestroyContext( &ctx->gl_ctx );
+ _tnl_DestroyContext( &ctx->gl_ctx );
+ _ac_DestroyContext( &ctx->gl_ctx );
+ _swrast_DestroyContext( &ctx->gl_ctx );
-#ifdef WIN32
-#include "..\swrast\s_tritemp.h"
-#else
-#include "swrast/s_tritemp.h"
-#endif
+ _mesa_destroy_visual( ctx->gl_visual );
+ _mesa_destroy_framebuffer( ctx->gl_buffer );
+ _mesa_free_context_data( &ctx->gl_ctx );
+ FREE( ctx );
+ }
}
-
-
/*
- * Flat-shaded, z-less triangle, RGBA color.
+ * Recompute the values of the context's rowaddr array.
*/
-static void flat_rgba_z_triangle( GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1,
- const SWvertex *v2 )
+static void
+compute_row_addresses( OSMesaContext ctx )
{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
-#define INTERP_Z 1
-#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
-#define SETUP_CODE \
- GLuint pixel; \
- PACK_RGBA((GLchan *) &pixel, v2->color[0], v2->color[1], \
- v2->color[2], v2->color[3]);
+ GLint bytesPerPixel, bytesPerRow, i;
+ GLubyte *origin = (GLubyte *) ctx->buffer;
-#define RENDER_SPAN( span ) \
- GLuint i; \
- GLuint *img = (GLuint *) PIXELADDR4(span.x, span.y); \
- for (i = 0; i < span.end; i++) { \
- const GLdepth z = FixedToDepth(span.z); \
- if (z < zRow[i]) { \
- img[i] = pixel; \
- zRow[i] = z; \
- } \
- span.z += span.zStep; \
+ if (ctx->format == OSMESA_COLOR_INDEX) {
+ /* CI mode */
+ bytesPerPixel = 1 * sizeof(GLchan);
+ }
+ else if ((ctx->format == OSMESA_RGB) || (ctx->format == OSMESA_BGR)) {
+ /* RGB mode */
+ bytesPerPixel = 3 * sizeof(GLchan);
+ }
+ else if (ctx->format == OSMESA_RGB_565) {
+ /* 5/6/5 RGB pixel in 16 bits */
+ bytesPerPixel = 2;
+ }
+ else {
+ /* RGBA mode */
+ bytesPerPixel = 4 * sizeof(GLchan);
}
-#ifdef WIN32
-#include "..\swrast\s_tritemp.h"
-#else
-#include "swrast/s_tritemp.h"
-#endif
-}
+ bytesPerRow = ctx->rowlength * bytesPerPixel;
+ if (ctx->yup) {
+ /* Y=0 is bottom line of window */
+ for (i = 0; i < MAX_HEIGHT; i++) {
+ ctx->rowaddr[i] = (GLchan *) ((GLubyte *) origin + i * bytesPerRow);
+ }
+ }
+ else {
+ /* Y=0 is top line of window */
+ for (i = 0; i < MAX_HEIGHT; i++) {
+ GLint j = ctx->height - i - 1;
+ ctx->rowaddr[i] = (GLchan *) ((GLubyte *) origin + j * bytesPerRow);
+ }
+ }
+}
/*
- * Return pointer to an accelerated triangle function if possible.
+ * Bind an OSMesaContext to an image buffer. The image buffer is just a
+ * block of memory which the client provides. Its size must be at least
+ * as large as width*height*sizeof(type). Its address should be a multiple
+ * of 4 if using RGBA mode.
+ *
+ * Image data is stored in the order of glDrawPixels: row-major order
+ * with the lower-left image pixel stored in the first array position
+ * (ie. bottom-to-top).
+ *
+ * If the context's viewport hasn't been initialized yet, it will now be
+ * initialized to (0,0,width,height).
+ *
+ * Input: ctx - the rendering context
+ * buffer - the image buffer memory
+ * type - data type for pixel components
+ * Normally, only GL_UNSIGNED_BYTE and GL_UNSIGNED_SHORT_5_6_5
+ * are supported. But if Mesa's been compiled with CHAN_BITS==16
+ * then type must be GL_UNSIGNED_SHORT. And if Mesa's been build
+ * with CHAN_BITS==32 then type must be GL_FLOAT.
+ * width, height - size of image buffer in pixels, at least 1
+ * Return: GL_TRUE if success, GL_FALSE if error because of invalid ctx,
+ * invalid buffer address, invalid type, width<1, height<1,
+ * width>internal limit or height>internal limit.
*/
-static swrast_tri_func
-osmesa_choose_triangle_function( GLcontext *ctx )
+GLAPI GLboolean GLAPIENTRY
+OSMesaMakeCurrent( OSMesaContext ctx, void *buffer, GLenum type,
+ GLsizei width, GLsizei height )
{
- const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- const SWcontext *swrast = SWRAST_CONTEXT(ctx);
-
- if (CHAN_BITS != 8) return (swrast_tri_func) NULL;
- if (ctx->RenderMode != GL_RENDER) return (swrast_tri_func) NULL;
- if (ctx->Polygon.SmoothFlag) return (swrast_tri_func) NULL;
- if (ctx->Polygon.StippleFlag) return (swrast_tri_func) NULL;
- if (ctx->Texture._EnabledUnits) return (swrast_tri_func) NULL;
- if (osmesa->format != OSMESA_RGBA &&
- osmesa->format != OSMESA_BGRA &&
- osmesa->format != OSMESA_ARGB) return (swrast_tri_func) NULL;
- if (ctx->Polygon.CullFlag &&
- ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)
- return (swrast_tri_func) NULL;
+ if (!ctx || !buffer ||
+ width < 1 || height < 1 ||
+ width > MAX_WIDTH || height > MAX_HEIGHT) {
+ return GL_FALSE;
+ }
- if (swrast->_RasterMask == DEPTH_BIT &&
- ctx->Depth.Func == GL_LESS &&
- ctx->Depth.Mask == GL_TRUE &&
- ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) {
- if (ctx->Light.ShadeModel == GL_SMOOTH) {
- return (swrast_tri_func) smooth_rgba_z_triangle;
- }
- else {
- return (swrast_tri_func) flat_rgba_z_triangle;
- }
+ if (ctx->format == OSMESA_RGB_565) {
+ if (type != GL_UNSIGNED_SHORT_5_6_5)
+ return GL_FALSE;
}
- return (swrast_tri_func) NULL;
-}
+ else if (type != CHAN_TYPE) {
+ return GL_FALSE;
+ }
+
+ osmesa_update_state( &ctx->gl_ctx, 0 );
+ _mesa_make_current( &ctx->gl_ctx, ctx->gl_buffer );
+
+ ctx->buffer = buffer;
+ ctx->width = width;
+ ctx->height = height;
+ if (ctx->userRowLength)
+ ctx->rowlength = ctx->userRowLength;
+ else
+ ctx->rowlength = width;
+ compute_row_addresses( ctx );
+ /* init viewport */
+ if (ctx->gl_ctx.Viewport.Width == 0) {
+ /* initialize viewport and scissor box to buffer size */
+ _mesa_Viewport( 0, 0, width, height );
+ ctx->gl_ctx.Scissor.Width = width;
+ ctx->gl_ctx.Scissor.Height = height;
+ }
+ else {
+ /* this will make ensure we recognize the new buffer size */
+ _mesa_ResizeBuffersMESA();
+ }
-/* Override for the swrast triangle-selection function. Try to use one
- * of our internal triangle functions, otherwise fall back to the
- * standard swrast functions.
- */
-static void osmesa_choose_triangle( GLcontext *ctx )
-{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ /* Added by Gerk Huisma: */
+ _tnl_MakeCurrent( &ctx->gl_ctx, ctx->gl_ctx.DrawBuffer,
+ ctx->gl_ctx.ReadBuffer );
- swrast->Triangle = osmesa_choose_triangle_function( ctx );
- if (!swrast->Triangle)
- _swrast_choose_triangle( ctx );
+ return GL_TRUE;
}
-static void osmesa_choose_line( GLcontext *ctx )
-{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
-
- swrast->Line = osmesa_choose_line_function( ctx );
- if (!swrast->Line)
- _swrast_choose_line( ctx );
-}
-#define OSMESA_NEW_LINE (_NEW_LINE | \
- _NEW_TEXTURE | \
- _NEW_LIGHT | \
- _NEW_DEPTH | \
- _NEW_RENDERMODE | \
- _SWRAST_NEW_RASTERMASK)
+GLAPI OSMesaContext GLAPIENTRY OSMesaGetCurrentContext( void )
+{
+ GLcontext *ctx = _mesa_get_current_context();
+ if (ctx)
+ return (OSMesaContext) ctx;
+ else
+ return NULL;
+}
-#define OSMESA_NEW_TRIANGLE (_NEW_POLYGON | \
- _NEW_TEXTURE | \
- _NEW_LIGHT | \
- _NEW_DEPTH | \
- _NEW_RENDERMODE | \
- _SWRAST_NEW_RASTERMASK)
-/* Extend the software rasterizer with our line and triangle
- * functions.
- */
-static void osmesa_register_swrast_functions( GLcontext *ctx )
+GLAPI void GLAPIENTRY OSMesaPixelStore( GLint pname, GLint value )
{
- SWcontext *swrast = SWRAST_CONTEXT( ctx );
+ OSMesaContext osmesa = OSMesaGetCurrentContext();
- swrast->choose_line = osmesa_choose_line;
- swrast->choose_triangle = osmesa_choose_triangle;
+ switch (pname) {
+ case OSMESA_ROW_LENGTH:
+ if (value<0) {
+ _mesa_error( &osmesa->gl_ctx, GL_INVALID_VALUE,
+ "OSMesaPixelStore(value)" );
+ return;
+ }
+ osmesa->userRowLength = value;
+ osmesa->rowlength = value ? value : osmesa->width;
+ break;
+ case OSMESA_Y_UP:
+ osmesa->yup = value ? GL_TRUE : GL_FALSE;
+ break;
+ default:
+ _mesa_error( &osmesa->gl_ctx, GL_INVALID_ENUM, "OSMesaPixelStore(pname)" );
+ return;
+ }
- swrast->invalidate_line |= OSMESA_NEW_LINE;
- swrast->invalidate_triangle |= OSMESA_NEW_TRIANGLE;
+ compute_row_addresses( osmesa );
}
-static const GLubyte *get_string( GLcontext *ctx, GLenum name )
+GLAPI void GLAPIENTRY OSMesaGetIntegerv( GLint pname, GLint *value )
{
- (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
+ OSMesaContext osmesa = OSMesaGetCurrentContext();
+
+ switch (pname) {
+ case OSMESA_WIDTH:
+ *value = osmesa->width;
+ return;
+ case OSMESA_HEIGHT:
+ *value = osmesa->height;
+ return;
+ case OSMESA_FORMAT:
+ *value = osmesa->format;
+ return;
+ case OSMESA_TYPE:
+ *value = CHAN_TYPE;
+ return;
+ case OSMESA_ROW_LENGTH:
+ *value = osmesa->userRowLength;
+ return;
+ case OSMESA_Y_UP:
+ *value = osmesa->yup;
+ return;
+ case OSMESA_MAX_WIDTH:
+ *value = MAX_WIDTH;
+ return;
+ case OSMESA_MAX_HEIGHT:
+ *value = MAX_HEIGHT;
+ return;
default:
- return NULL;
+ _mesa_error(&osmesa->gl_ctx, GL_INVALID_ENUM, "OSMesaGetIntergerv(pname)");
+ return;
}
}
-
-static void osmesa_update_state( GLcontext *ctx, GLuint new_state )
+/*
+ * Return the depth buffer associated with an OSMesa context.
+ * Input: c - the OSMesa context
+ * Output: width, height - size of buffer in pixels
+ * bytesPerValue - bytes per depth value (2 or 4)
+ * buffer - pointer to depth buffer values
+ * Return: GL_TRUE or GL_FALSE to indicate success or failure.
+ */
+GLAPI GLboolean GLAPIENTRY
+OSMesaGetDepthBuffer( OSMesaContext c, GLint *width, GLint *height,
+ GLint *bytesPerValue, void **buffer )
{
- OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
- struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx );
- TNLcontext *tnl = TNL_CONTEXT(ctx);
-
- ASSERT((void *) osmesa == (void *) ctx->DriverCtx);
-
- /*
- * XXX these function pointers could be initialized just once during
- * context creation since they don't depend on any state changes.
- */
-
- ctx->Driver.GetString = get_string;
- ctx->Driver.UpdateState = osmesa_update_state;
- ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
- ctx->Driver.GetBufferSize = buffer_size;
-
- ctx->Driver.Accum = _swrast_Accum;
- ctx->Driver.Bitmap = _swrast_Bitmap;
- ctx->Driver.Clear = clear;
- ctx->Driver.CopyPixels = _swrast_CopyPixels;
- ctx->Driver.DrawPixels = _swrast_DrawPixels;
- ctx->Driver.ReadPixels = _swrast_ReadPixels;
- ctx->Driver.DrawBuffer = _swrast_DrawBuffer;
-
- ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
- ctx->Driver.TexImage1D = _mesa_store_teximage1d;
- ctx->Driver.TexImage2D = _mesa_store_teximage2d;
- ctx->Driver.TexImage3D = _mesa_store_teximage3d;
- ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
- ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
- ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
- ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
-
- ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d;
- ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d;
- ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d;
- ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d;
- ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d;
- ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d;
-
- ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
- ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
- ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
- ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
- ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
- ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
- ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
- ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
- ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
-
- swdd->SetBuffer = set_buffer;
-
- /* RGB(A) span/pixel functions */
- if (osmesa->format == OSMESA_RGB) {
- swdd->WriteRGBASpan = write_rgba_span_RGB;
- swdd->WriteRGBSpan = write_rgb_span_RGB;
- swdd->WriteMonoRGBASpan = write_monocolor_span_RGB;
- swdd->WriteRGBAPixels = write_rgba_pixels_RGB;
- swdd->WriteMonoRGBAPixels = write_monocolor_pixels_RGB;
- swdd->ReadRGBASpan = read_rgba_span3;
- swdd->ReadRGBAPixels = read_rgba_pixels3;
+ if ((!c->gl_buffer) || (!c->gl_buffer->DepthBuffer)) {
+ *width = 0;
+ *height = 0;
+ *bytesPerValue = 0;
+ *buffer = 0;
+ return GL_FALSE;
}
- else if (osmesa->format == OSMESA_BGR) {
- swdd->WriteRGBASpan = write_rgba_span_BGR;
- swdd->WriteRGBSpan = write_rgb_span_BGR;
- swdd->WriteMonoRGBASpan = write_monocolor_span_BGR;
- swdd->WriteRGBAPixels = write_rgba_pixels_BGR;
- swdd->WriteMonoRGBAPixels = write_monocolor_pixels_BGR;
- swdd->ReadRGBASpan = read_rgba_span3;
- swdd->ReadRGBAPixels = read_rgba_pixels3;
+ else {
+ *width = c->gl_buffer->Width;
+ *height = c->gl_buffer->Height;
+ if (c->gl_visual->depthBits <= 16)
+ *bytesPerValue = sizeof(GLushort);
+ else
+ *bytesPerValue = sizeof(GLuint);
+ *buffer = c->gl_buffer->DepthBuffer;
+ return GL_TRUE;
}
- else if (osmesa->format == OSMESA_RGB_565) {
- swdd->WriteRGBASpan = write_rgba_span2;
- swdd->WriteRGBSpan = write_rgb_span2;
- swdd->WriteMonoRGBASpan = write_monocolor_span2;
- swdd->WriteRGBAPixels = write_rgba_pixels2;
- swdd->WriteMonoRGBAPixels = write_monocolor_pixels2;
- swdd->ReadRGBASpan = read_rgba_span2;
- swdd->ReadRGBAPixels = read_rgba_pixels2;
+}
+
+/*
+ * Return the color buffer associated with an OSMesa context.
+ * Input: c - the OSMesa context
+ * Output: width, height - size of buffer in pixels
+ * format - the pixel format (OSMESA_FORMAT)
+ * buffer - pointer to color buffer values
+ * Return: GL_TRUE or GL_FALSE to indicate success or failure.
+ */
+GLAPI GLboolean GLAPIENTRY
+OSMesaGetColorBuffer( OSMesaContext c, GLint *width,
+ GLint *height, GLint *format, void **buffer )
+{
+ if (!c->buffer) {
+ *width = 0;
+ *height = 0;
+ *format = 0;
+ *buffer = 0;
+ return GL_FALSE;
}
else {
- /* 4 GLchan / pixel in frame buffer */
- swdd->WriteRGBSpan = write_rgb_span;
- swdd->WriteRGBAPixels = write_rgba_pixels;
- swdd->WriteMonoRGBASpan = write_monocolor_span;
- swdd->WriteMonoRGBAPixels = write_monocolor_pixels;
- if (osmesa->format == OSMESA_RGBA &&
- CHAN_TYPE == GL_UNSIGNED_BYTE &&
- RCOMP==0 && GCOMP==1 && BCOMP==2 && ACOMP==3) {
- /* special, fast case */
- swdd->WriteRGBASpan = write_rgba_span_rgba;
- swdd->ReadRGBASpan = read_rgba_span_rgba;
- }
- else {
- swdd->WriteRGBASpan = write_rgba_span;
- swdd->ReadRGBASpan = read_rgba_span;
- }
- swdd->ReadRGBAPixels = read_rgba_pixels;
+ *width = c->width;
+ *height = c->height;
+ *format = c->format;
+ *buffer = c->buffer;
+ return GL_TRUE;
}
+}
- /* CI span/pixel functions */
- swdd->WriteCI32Span = write_index32_span;
- swdd->WriteCI8Span = write_index8_span;
- swdd->WriteMonoCISpan = write_monoindex_span;
- swdd->WriteCI32Pixels = write_index_pixels;
- swdd->WriteMonoCIPixels = write_monoindex_pixels;
- swdd->ReadCI32Span = read_index_span;
- swdd->ReadCI32Pixels = read_index_pixels;
- tnl->Driver.RunPipeline = _tnl_run_pipeline;
- _swrast_InvalidateState( ctx, new_state );
- _swsetup_InvalidateState( ctx, new_state );
- _ac_InvalidateState( ctx, new_state );
- _tnl_InvalidateState( ctx, new_state );
+struct name_address {
+ const char *Name;
+ GLvoid *Address;
+};
+
+static struct name_address functions[] = {
+ { "OSMesaCreateContext", (void *) OSMesaCreateContext },
+ { "OSMesaCreateContextExt", (void *) OSMesaCreateContextExt },
+ { "OSMesaDestroyContext", (void *) OSMesaDestroyContext },
+ { "OSMesaMakeCurrent", (void *) OSMesaMakeCurrent },
+ { "OSMesaGetCurrentContext", (void *) OSMesaGetCurrentContext },
+ { "OSMesaPixelsStore", (void *) OSMesaPixelStore },
+ { "OSMesaGetIntegerv", (void *) OSMesaGetIntegerv },
+ { "OSMesaGetDepthBuffer", (void *) OSMesaGetDepthBuffer },
+ { "OSMesaGetColorBuffer", (void *) OSMesaGetColorBuffer },
+ { "OSMesaGetProcAddress", (void *) OSMesaGetProcAddress },
+ { NULL, NULL }
+};
+
+GLAPI void * GLAPIENTRY
+OSMesaGetProcAddress( const char *funcName )
+{
+ int i;
+ for (i = 0; functions[i].Name; i++) {
+ if (_mesa_strcmp(functions[i].Name, funcName) == 0)
+ return (void *) functions[i].Address;
+ }
+ return (void *) _glapi_get_proc_address(funcName);
}