X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fosmesa%2Fosmesa.c;h=f2367bbbb70cf953c7d80957ffe295aeb49f7710;hb=8abc860bd46a6cd584f9a64cb4613be76f82db06;hp=8a85b5ecf7c8e8451d9feaa623290d273e336ab2;hpb=22652f952fbd3968f3d5a3db7898911508d76145;p=mesa.git diff --git a/src/mesa/drivers/osmesa/osmesa.c b/src/mesa/drivers/osmesa/osmesa.c index 8a85b5ecf7c..f2367bbbb70 100644 --- a/src/mesa/drivers/osmesa/osmesa.c +++ b/src/mesa/drivers/osmesa/osmesa.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.3 + * Version: 6.5.3 * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -33,57 +33,51 @@ */ -#include "glheader.h" +#include "main/glheader.h" #include "GL/osmesa.h" -#include "context.h" -#include "extensions.h" -#include "framebuffer.h" -#include "fbobject.h" -#include "imports.h" -#include "mtypes.h" -#include "renderbuffer.h" -#include "array_cache/acache.h" +#include "main/context.h" +#include "main/extensions.h" +#include "main/framebuffer.h" +#include "main/imports.h" +#include "main/mtypes.h" +#include "main/renderbuffer.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "swrast/s_context.h" -#include "swrast/s_depth.h" #include "swrast/s_lines.h" #include "swrast/s_triangle.h" #include "tnl/tnl.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" #include "drivers/common/driverfuncs.h" +#include "vbo/vbo.h" -/* - * This is the OS/Mesa context struct. - * Notice how it includes a GLcontext. By doing this we're mimicking - * C++ inheritance/derivation. - * Later, we can cast a GLcontext pointer into an OSMesaContext pointer - * or vice versa. +/** + * OSMesa rendering context, derived from core Mesa GLcontext. */ -struct osmesa_context { - GLcontext mesa; /* The core GL/Mesa context */ - GLvisual *gl_visual; /* Describes the buffers */ - GLframebuffer *gl_buffer; /* Depth, stencil, accum, etc buffers */ - GLenum format; /* either GL_RGBA or GL_COLOR_INDEX */ - void *buffer; /* the image buffer */ - GLint width, height; /* size of image buffer */ - GLint rowlength; /* number of pixels per row */ - GLint userRowLength; /* user-specified number of pixels per row */ - GLint rshift, gshift; /* bit shifts for RGBA formats */ - GLint bshift, ashift; - GLint rInd, gInd, bInd, aInd;/* index offsets for RGBA formats */ - GLchan *rowaddr[MAX_HEIGHT]; /* address of first pixel in each image row */ - GLboolean yup; /* TRUE -> Y increases upward */ - /* FALSE -> Y increases downward */ +struct osmesa_context +{ + GLcontext mesa; /*< Base class - this must be first */ + GLvisual *gl_visual; /*< Describes the buffers */ + struct gl_renderbuffer *rb; /*< The user's colorbuffer */ + GLframebuffer *gl_buffer; /*< The framebuffer, containing user's rb */ + GLenum format; /*< User-specified context format */ + GLint userRowLength; /*< user-specified number of pixels per row */ + GLint rInd, gInd, bInd, aInd;/*< index offsets for RGBA formats */ + GLvoid *rowaddr[MAX_HEIGHT]; /*< address of first pixel in each image row */ + GLboolean yup; /*< TRUE -> Y increases upward */ + /*< FALSE -> Y increases downward */ }; -/* Just cast, since we're using structure containment */ -#define OSMESA_CONTEXT(ctx) ((OSMesaContext) (ctx->DriverCtx)) - +static INLINE OSMesaContext +OSMESA_CONTEXT(GLcontext *ctx) +{ + /* Just cast, since we're using structure containment */ + return (OSMesaContext) ctx; +} /**********************************************************************/ @@ -116,62 +110,49 @@ 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 ); + _vbo_InvalidateState( ctx, new_state ); } -static void -set_buffer( GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit ) -{ - /* separate read buffer not supported */ - ASSERT(buffer == ctx->DrawBuffer); - ASSERT(bufferBit == BUFFER_BIT_FRONT_LEFT); -} - - -/* - * Just return the current buffer size. - * There's no window to track the size of. - */ -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; - } -} - /**********************************************************************/ /***** Read/write spans/arrays of pixels *****/ /**********************************************************************/ -/* RGBA */ -#define NAME(PREFIX) PREFIX##_RGBA -#define FORMAT GL_RGBA +/* 8-bit RGBA */ +#define NAME(PREFIX) PREFIX##_RGBA8 +#define RB_TYPE GLubyte #define SPAN_VARS \ const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); #define INIT_PIXEL_PTR(P, X, Y) \ - GLchan *P = osmesa->rowaddr[Y] + 4 * (X) + GLubyte *P = (GLubyte *) osmesa->rowaddr[Y] + 4 * (X) #define INC_PIXEL_PTR(P) P += 4 -#if CHAN_TYPE == GL_FLOAT #define STORE_PIXEL(DST, X, Y, VALUE) \ - DST[0] = MAX2((VALUE[RCOMP]), 0.0F); \ - DST[1] = MAX2((VALUE[GCOMP]), 0.0F); \ - DST[2] = MAX2((VALUE[BCOMP]), 0.0F); \ - DST[3] = CLAMP((VALUE[ACOMP]), 0.0F, CHAN_MAXF) + DST[0] = VALUE[RCOMP]; \ + DST[1] = VALUE[GCOMP]; \ + DST[2] = VALUE[BCOMP]; \ + DST[3] = VALUE[ACOMP] #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ - DST[0] = MAX2((VALUE[RCOMP]), 0.0F); \ - DST[1] = MAX2((VALUE[GCOMP]), 0.0F); \ - DST[2] = MAX2((VALUE[BCOMP]), 0.0F); \ - DST[3] = CHAN_MAXF -#else + DST[0] = VALUE[RCOMP]; \ + DST[1] = VALUE[GCOMP]; \ + DST[2] = VALUE[BCOMP]; \ + DST[3] = 255 +#define FETCH_PIXEL(DST, SRC) \ + DST[RCOMP] = SRC[0]; \ + DST[GCOMP] = SRC[1]; \ + DST[BCOMP] = SRC[2]; \ + DST[ACOMP] = SRC[3] +#include "swrast/s_spantemp.h" + +/* 16-bit RGBA */ +#define NAME(PREFIX) PREFIX##_RGBA16 +#define RB_TYPE GLushort +#define SPAN_VARS \ + const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); +#define INIT_PIXEL_PTR(P, X, Y) \ + GLushort *P = (GLushort *) osmesa->rowaddr[Y] + 4 * (X) +#define INC_PIXEL_PTR(P) P += 4 #define STORE_PIXEL(DST, X, Y, VALUE) \ DST[0] = VALUE[RCOMP]; \ DST[1] = VALUE[GCOMP]; \ @@ -181,8 +162,32 @@ get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height ) DST[0] = VALUE[RCOMP]; \ DST[1] = VALUE[GCOMP]; \ DST[2] = VALUE[BCOMP]; \ - DST[3] = CHAN_MAX -#endif + DST[3] = 65535 +#define FETCH_PIXEL(DST, SRC) \ + DST[RCOMP] = SRC[0]; \ + DST[GCOMP] = SRC[1]; \ + DST[BCOMP] = SRC[2]; \ + DST[ACOMP] = SRC[3] +#include "swrast/s_spantemp.h" + +/* 32-bit RGBA */ +#define NAME(PREFIX) PREFIX##_RGBA32 +#define RB_TYPE GLfloat +#define SPAN_VARS \ + const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); +#define INIT_PIXEL_PTR(P, X, Y) \ + GLfloat *P = (GLfloat *) osmesa->rowaddr[Y] + 4 * (X) +#define INC_PIXEL_PTR(P) P += 4 +#define STORE_PIXEL(DST, X, Y, VALUE) \ + DST[0] = MAX2((VALUE[RCOMP]), 0.0F); \ + DST[1] = MAX2((VALUE[GCOMP]), 0.0F); \ + DST[2] = MAX2((VALUE[BCOMP]), 0.0F); \ + DST[3] = CLAMP((VALUE[ACOMP]), 0.0F, 1.0F) +#define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ + DST[0] = MAX2((VALUE[RCOMP]), 0.0F); \ + DST[1] = MAX2((VALUE[GCOMP]), 0.0F); \ + DST[2] = MAX2((VALUE[BCOMP]), 0.0F); \ + DST[3] = 1.0F #define FETCH_PIXEL(DST, SRC) \ DST[RCOMP] = SRC[0]; \ DST[GCOMP] = SRC[1]; \ @@ -190,13 +195,14 @@ get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height ) DST[ACOMP] = SRC[3] #include "swrast/s_spantemp.h" -/* BGRA */ -#define NAME(PREFIX) PREFIX##_BGRA -#define FORMAT GL_RGBA + +/* 8-bit BGRA */ +#define NAME(PREFIX) PREFIX##_BGRA8 +#define RB_TYPE GLubyte #define SPAN_VARS \ const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); #define INIT_PIXEL_PTR(P, X, Y) \ - GLchan *P = osmesa->rowaddr[Y] + 4 * (X) + GLubyte *P = (GLubyte *) osmesa->rowaddr[Y] + 4 * (X) #define INC_PIXEL_PTR(P) P += 4 #define STORE_PIXEL(DST, X, Y, VALUE) \ DST[2] = VALUE[RCOMP]; \ @@ -207,7 +213,7 @@ get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height ) DST[2] = VALUE[RCOMP]; \ DST[1] = VALUE[GCOMP]; \ DST[0] = VALUE[BCOMP]; \ - DST[3] = CHAN_MAX + DST[3] = 255 #define FETCH_PIXEL(DST, SRC) \ DST[RCOMP] = SRC[2]; \ DST[GCOMP] = SRC[1]; \ @@ -215,13 +221,64 @@ get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height ) DST[ACOMP] = SRC[3] #include "swrast/s_spantemp.h" -/* ARGB */ -#define NAME(PREFIX) PREFIX##_ARGB -#define FORMAT GL_RGBA +/* 16-bit BGRA */ +#define NAME(PREFIX) PREFIX##_BGRA16 +#define RB_TYPE GLushort #define SPAN_VARS \ const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); #define INIT_PIXEL_PTR(P, X, Y) \ - GLchan *P = osmesa->rowaddr[Y] + 4 * (X) + GLushort *P = (GLushort *) osmesa->rowaddr[Y] + 4 * (X) +#define INC_PIXEL_PTR(P) P += 4 +#define STORE_PIXEL(DST, X, Y, VALUE) \ + DST[2] = VALUE[RCOMP]; \ + DST[1] = VALUE[GCOMP]; \ + DST[0] = VALUE[BCOMP]; \ + DST[3] = VALUE[ACOMP] +#define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ + DST[2] = VALUE[RCOMP]; \ + DST[1] = VALUE[GCOMP]; \ + DST[0] = VALUE[BCOMP]; \ + DST[3] = 65535 +#define FETCH_PIXEL(DST, SRC) \ + DST[RCOMP] = SRC[2]; \ + DST[GCOMP] = SRC[1]; \ + DST[BCOMP] = SRC[0]; \ + DST[ACOMP] = SRC[3] +#include "swrast/s_spantemp.h" + +/* 32-bit BGRA */ +#define NAME(PREFIX) PREFIX##_BGRA32 +#define RB_TYPE GLfloat +#define SPAN_VARS \ + const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); +#define INIT_PIXEL_PTR(P, X, Y) \ + GLfloat *P = (GLfloat *) osmesa->rowaddr[Y] + 4 * (X) +#define INC_PIXEL_PTR(P) P += 4 +#define STORE_PIXEL(DST, X, Y, VALUE) \ + DST[2] = VALUE[RCOMP]; \ + DST[1] = VALUE[GCOMP]; \ + DST[0] = VALUE[BCOMP]; \ + DST[3] = VALUE[ACOMP] +#define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ + DST[2] = VALUE[RCOMP]; \ + DST[1] = VALUE[GCOMP]; \ + DST[0] = VALUE[BCOMP]; \ + DST[3] = 1.0F +#define FETCH_PIXEL(DST, SRC) \ + DST[RCOMP] = SRC[2]; \ + DST[GCOMP] = SRC[1]; \ + DST[BCOMP] = SRC[0]; \ + DST[ACOMP] = SRC[3] +#include "swrast/s_spantemp.h" + + +/* 8-bit ARGB */ +#define NAME(PREFIX) PREFIX##_ARGB8 +#define RB_TYPE GLubyte +#define SPAN_VARS \ + const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); +#define INIT_PIXEL_PTR(P, X, Y) \ + GLubyte *P = (GLubyte *) osmesa->rowaddr[Y] + 4 * (X) #define INC_PIXEL_PTR(P) P += 4 #define STORE_PIXEL(DST, X, Y, VALUE) \ DST[1] = VALUE[RCOMP]; \ @@ -232,7 +289,7 @@ get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height ) DST[1] = VALUE[RCOMP]; \ DST[2] = VALUE[GCOMP]; \ DST[3] = VALUE[BCOMP]; \ - DST[0] = CHAN_MAX + DST[0] = 255 #define FETCH_PIXEL(DST, SRC) \ DST[RCOMP] = SRC[1]; \ DST[GCOMP] = SRC[2]; \ @@ -240,13 +297,64 @@ get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height ) DST[ACOMP] = SRC[0] #include "swrast/s_spantemp.h" -/* RGB */ -#define NAME(PREFIX) PREFIX##_RGB -#define FORMAT GL_RGBA +/* 16-bit ARGB */ +#define NAME(PREFIX) PREFIX##_ARGB16 +#define RB_TYPE GLushort #define SPAN_VARS \ const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); #define INIT_PIXEL_PTR(P, X, Y) \ - GLchan *P = osmesa->rowaddr[Y] + 4 * (X) + GLushort *P = (GLushort *) osmesa->rowaddr[Y] + 4 * (X) +#define INC_PIXEL_PTR(P) P += 4 +#define STORE_PIXEL(DST, X, Y, VALUE) \ + DST[1] = VALUE[RCOMP]; \ + DST[2] = VALUE[GCOMP]; \ + DST[3] = VALUE[BCOMP]; \ + DST[0] = VALUE[ACOMP] +#define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ + DST[1] = VALUE[RCOMP]; \ + DST[2] = VALUE[GCOMP]; \ + DST[3] = VALUE[BCOMP]; \ + DST[0] = 65535 +#define FETCH_PIXEL(DST, SRC) \ + DST[RCOMP] = SRC[1]; \ + DST[GCOMP] = SRC[2]; \ + DST[BCOMP] = SRC[3]; \ + DST[ACOMP] = SRC[0] +#include "swrast/s_spantemp.h" + +/* 32-bit ARGB */ +#define NAME(PREFIX) PREFIX##_ARGB32 +#define RB_TYPE GLfloat +#define SPAN_VARS \ + const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); +#define INIT_PIXEL_PTR(P, X, Y) \ + GLfloat *P = (GLfloat *) osmesa->rowaddr[Y] + 4 * (X) +#define INC_PIXEL_PTR(P) P += 4 +#define STORE_PIXEL(DST, X, Y, VALUE) \ + DST[1] = VALUE[RCOMP]; \ + DST[2] = VALUE[GCOMP]; \ + DST[3] = VALUE[BCOMP]; \ + DST[0] = VALUE[ACOMP] +#define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ + DST[1] = VALUE[RCOMP]; \ + DST[2] = VALUE[GCOMP]; \ + DST[3] = VALUE[BCOMP]; \ + DST[0] = 1.0F +#define FETCH_PIXEL(DST, SRC) \ + DST[RCOMP] = SRC[1]; \ + DST[GCOMP] = SRC[2]; \ + DST[BCOMP] = SRC[3]; \ + DST[ACOMP] = SRC[0] +#include "swrast/s_spantemp.h" + + +/* 8-bit RGB */ +#define NAME(PREFIX) PREFIX##_RGB8 +#define RB_TYPE GLubyte +#define SPAN_VARS \ + const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); +#define INIT_PIXEL_PTR(P, X, Y) \ + GLubyte *P = (GLubyte *) osmesa->rowaddr[Y] + 3 * (X) #define INC_PIXEL_PTR(P) P += 3 #define STORE_PIXEL(DST, X, Y, VALUE) \ DST[0] = VALUE[RCOMP]; \ @@ -256,16 +364,55 @@ get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height ) DST[RCOMP] = SRC[0]; \ DST[GCOMP] = SRC[1]; \ DST[BCOMP] = SRC[2]; \ - DST[ACOMP] = CHAN_MAX + DST[ACOMP] = 255 #include "swrast/s_spantemp.h" -/* BGR */ -#define NAME(PREFIX) PREFIX##_BGR -#define FORMAT GL_RGBA +/* 16-bit RGB */ +#define NAME(PREFIX) PREFIX##_RGB16 +#define RB_TYPE GLushort #define SPAN_VARS \ const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); #define INIT_PIXEL_PTR(P, X, Y) \ - GLchan *P = osmesa->rowaddr[Y] + 4 * (X) + GLushort *P = (GLushort *) osmesa->rowaddr[Y] + 3 * (X) +#define INC_PIXEL_PTR(P) P += 3 +#define STORE_PIXEL(DST, X, Y, VALUE) \ + DST[0] = VALUE[RCOMP]; \ + DST[1] = VALUE[GCOMP]; \ + DST[2] = VALUE[BCOMP] +#define FETCH_PIXEL(DST, SRC) \ + DST[RCOMP] = SRC[0]; \ + DST[GCOMP] = SRC[1]; \ + DST[BCOMP] = SRC[2]; \ + DST[ACOMP] = 65535U +#include "swrast/s_spantemp.h" + +/* 32-bit RGB */ +#define NAME(PREFIX) PREFIX##_RGB32 +#define RB_TYPE GLfloat +#define SPAN_VARS \ + const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); +#define INIT_PIXEL_PTR(P, X, Y) \ + GLfloat *P = (GLfloat *) osmesa->rowaddr[Y] + 3 * (X) +#define INC_PIXEL_PTR(P) P += 3 +#define STORE_PIXEL(DST, X, Y, VALUE) \ + DST[0] = VALUE[RCOMP]; \ + DST[1] = VALUE[GCOMP]; \ + DST[2] = VALUE[BCOMP] +#define FETCH_PIXEL(DST, SRC) \ + DST[RCOMP] = SRC[0]; \ + DST[GCOMP] = SRC[1]; \ + DST[BCOMP] = SRC[2]; \ + DST[ACOMP] = 1.0F +#include "swrast/s_spantemp.h" + + +/* 8-bit BGR */ +#define NAME(PREFIX) PREFIX##_BGR8 +#define RB_TYPE GLubyte +#define SPAN_VARS \ + const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); +#define INIT_PIXEL_PTR(P, X, Y) \ + GLubyte *P = (GLubyte *) osmesa->rowaddr[Y] + 3 * (X) #define INC_PIXEL_PTR(P) P += 3 #define STORE_PIXEL(DST, X, Y, VALUE) \ DST[2] = VALUE[RCOMP]; \ @@ -275,13 +422,51 @@ get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height ) DST[RCOMP] = SRC[2]; \ DST[GCOMP] = SRC[1]; \ DST[BCOMP] = SRC[0]; \ - DST[ACOMP] = CHAN_MAX + DST[ACOMP] = 255 #include "swrast/s_spantemp.h" /* 16-bit BGR */ -#if CHAN_TYPE == GL_UNSIGNED_BYTE +#define NAME(PREFIX) PREFIX##_BGR16 +#define RB_TYPE GLushort +#define SPAN_VARS \ + const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); +#define INIT_PIXEL_PTR(P, X, Y) \ + GLushort *P = (GLushort *) osmesa->rowaddr[Y] + 3 * (X) +#define INC_PIXEL_PTR(P) P += 3 +#define STORE_PIXEL(DST, X, Y, VALUE) \ + DST[2] = VALUE[RCOMP]; \ + DST[1] = VALUE[GCOMP]; \ + DST[0] = VALUE[BCOMP] +#define FETCH_PIXEL(DST, SRC) \ + DST[RCOMP] = SRC[2]; \ + DST[GCOMP] = SRC[1]; \ + DST[BCOMP] = SRC[0]; \ + DST[ACOMP] = 65535 +#include "swrast/s_spantemp.h" + +/* 32-bit BGR */ +#define NAME(PREFIX) PREFIX##_BGR32 +#define RB_TYPE GLfloat +#define SPAN_VARS \ + const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); +#define INIT_PIXEL_PTR(P, X, Y) \ + GLfloat *P = (GLfloat *) osmesa->rowaddr[Y] + 3 * (X) +#define INC_PIXEL_PTR(P) P += 3 +#define STORE_PIXEL(DST, X, Y, VALUE) \ + DST[2] = VALUE[RCOMP]; \ + DST[1] = VALUE[GCOMP]; \ + DST[0] = VALUE[BCOMP] +#define FETCH_PIXEL(DST, SRC) \ + DST[RCOMP] = SRC[2]; \ + DST[GCOMP] = SRC[1]; \ + DST[BCOMP] = SRC[0]; \ + DST[ACOMP] = 1.0F +#include "swrast/s_spantemp.h" + + +/* 16-bit 5/6/5 RGB */ #define NAME(PREFIX) PREFIX##_RGB_565 -#define FORMAT GL_RGBA +#define RB_TYPE GLubyte #define SPAN_VARS \ const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); #define INIT_PIXEL_PTR(P, X, Y) \ @@ -295,15 +480,16 @@ get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height ) DST[BCOMP] = ( (((*SRC) << 3) & 0xf8) | (((*SRC) ) & 0x7) ); \ DST[ACOMP] = CHAN_MAX #include "swrast/s_spantemp.h" -#endif /* CHAN_TYPE == GL_UNSIGNED_BYTE */ + /* color index */ #define NAME(PREFIX) PREFIX##_CI -#define FORMAT GL_COLOR_INDEX8_EXT +#define CI_MODE +#define RB_TYPE GLubyte #define SPAN_VARS \ const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); #define INIT_PIXEL_PTR(P, X, Y) \ - GLubyte *P = osmesa->rowaddr[Y] + (X) + GLubyte *P = (GLubyte *) osmesa->rowaddr[Y] + (X) #define INC_PIXEL_PTR(P) P += 1 #define STORE_PIXEL(DST, X, Y, VALUE) \ *DST = VALUE[0] @@ -314,20 +500,11 @@ get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height ) -/**********************************************************************/ -/***** Optimized line rendering *****/ -/**********************************************************************/ - +/** + * Macros for optimized line/triangle rendering. + * Only for 8-bit channel, RGBA, BGRA, ARGB formats. + */ -#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; \ @@ -335,39 +512,11 @@ do { \ (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 PIXELADDR4(X,Y) ((GLchan *) osmesa->rowaddr[Y] + 4 * (X)) -#define PACK_BGR(DST, R, G, B) \ -do { \ - (DST)[0] = B; \ - (DST)[1] = G; \ - (DST)[2] = R; \ -} while (0) -#define PACK_RGB_565(DST, R, G, B) \ -do { \ - (DST) = (((int) (R) << 8) & 0xf800) | (((int) (G) << 3) & 0x7e0) | ((int) (B) >> 3);\ -} while (0) - -#define UNPACK_RED(P) ( (P)[osmesa->rInd] ) -#define UNPACK_GREEN(P) ( (P)[osmesa->gInd] ) -#define UNPACK_BLUE(P) ( (P)[osmesa->bInd] ) -#define UNPACK_ALPHA(P) ( (P)[osmesa->aInd] ) - -#define PIXELADDR1(X,Y) (osmesa->rowaddr[Y] + (X)) -#define PIXELADDR2(X,Y) (osmesa->rowaddr[Y] + 2 * (X)) -#define PIXELADDR3(X,Y) (osmesa->rowaddr[Y] + 3 * (X)) -#define PIXELADDR4(X,Y) (osmesa->rowaddr[Y] + 4 * (X)) - - -/* +/** * Draw a flat-shaded, RGB line into an osmesa buffer. */ #define NAME flat_rgba_line @@ -390,7 +539,7 @@ do { \ -/* +/** * Draw a flat-shaded, Z-less, RGB line into an osmesa buffer. */ #define NAME flat_rgba_z_line @@ -419,9 +568,9 @@ do { \ -/* +/** * Analyze context state to see if we can provide a fast line drawing - * function, like those in lines.c. Otherwise, return NULL. + * function. Otherwise, return NULL. */ static swrast_line_func osmesa_choose_line_function( GLcontext *ctx ) @@ -429,7 +578,9 @@ 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 (osmesa->rb->DataType != GL_UNSIGNED_BYTE) + return NULL; + if (ctx->RenderMode != GL_RENDER) return NULL; if (ctx->Line.SmoothFlag) return NULL; if (ctx->Texture._EnabledUnits) return NULL; @@ -471,11 +622,11 @@ osmesa_choose_line_function( GLcontext *ctx ) #define INTERP_ALPHA 1 #define SETUP_CODE \ const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); -#define RENDER_SPAN( span ) \ +#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); \ + const GLuint z = FixedToDepth(span.z); \ if (z < zRow[i]) { \ PACK_RGBA(img, FixedToChan(span.red), \ FixedToChan(span.green), FixedToChan(span.blue), \ @@ -487,7 +638,8 @@ osmesa_choose_line_function( GLcontext *ctx ) span.blue += span.blueStep; \ span.alpha += span.alphaStep; \ span.z += span.zStep; \ - } + } \ +} #ifdef WIN32 #include "..\swrast\s_tritemp.h" #else @@ -508,17 +660,18 @@ osmesa_choose_line_function( GLcontext *ctx ) PACK_RGBA((GLchan *) &pixel, v2->color[0], v2->color[1], \ v2->color[2], v2->color[3]); -#define RENDER_SPAN( span ) \ +#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); \ + const GLuint 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 @@ -527,8 +680,8 @@ osmesa_choose_line_function( GLcontext *ctx ) -/* - * Return pointer to an accelerated triangle function if possible. +/** + * Return pointer to an optimized triangle function if possible. */ static swrast_tri_func osmesa_choose_triangle_function( GLcontext *ctx ) @@ -536,7 +689,9 @@ osmesa_choose_triangle_function( GLcontext *ctx ) const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); const SWcontext *swrast = SWRAST_CONTEXT(ctx); - if (CHAN_BITS != 8) return (swrast_tri_func) NULL; + if (osmesa->rb->DataType != GL_UNSIGNED_BYTE) + 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; @@ -589,19 +744,70 @@ osmesa_choose_line( GLcontext *ctx ) } -#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) +/** + * Recompute the values of the context's rowaddr array. + */ +static void +compute_row_addresses( OSMesaContext osmesa ) +{ + GLint bytesPerPixel, bytesPerRow, i; + GLubyte *origin = (GLubyte *) osmesa->rb->Data; + GLint bpc; /* bytes per channel */ + GLint rowlength; /* in pixels */ + GLint height = osmesa->rb->Height; + + if (osmesa->userRowLength) + rowlength = osmesa->userRowLength; + else + rowlength = osmesa->rb->Width; + + if (osmesa->rb->DataType == GL_UNSIGNED_BYTE) + bpc = 1; + else if (osmesa->rb->DataType == GL_UNSIGNED_SHORT) + bpc = 2; + else if (osmesa->rb->DataType == GL_FLOAT) + bpc = 4; + else { + _mesa_problem(&osmesa->mesa, + "Unexpected datatype in osmesa::compute_row_addresses"); + return; + } + + if (osmesa->format == OSMESA_COLOR_INDEX) { + /* CI mode */ + bytesPerPixel = 1 * sizeof(GLubyte); + } + else if ((osmesa->format == OSMESA_RGB) || (osmesa->format == OSMESA_BGR)) { + /* RGB mode */ + bytesPerPixel = 3 * bpc; + } + else if (osmesa->format == OSMESA_RGB_565) { + /* 5/6/5 RGB pixel in 16 bits */ + bytesPerPixel = 2; + } + else { + /* RGBA mode */ + bytesPerPixel = 4 * bpc; + } + + bytesPerRow = rowlength * bytesPerPixel; + + if (osmesa->yup) { + /* Y=0 is bottom line of window */ + for (i = 0; i < height; i++) { + osmesa->rowaddr[i] = (GLvoid *) ((GLubyte *) origin + i * bytesPerRow); + } + } + else { + /* Y=0 is top line of window */ + for (i = 0; i < height; i++) { + GLint j = height - i - 1; + osmesa->rowaddr[i] = (GLvoid *) ((GLubyte *) origin + j * bytesPerRow); + } + } +} + /** @@ -624,63 +830,186 @@ osmesa_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, GLenum internalFormat, GLuint width, GLuint height) { const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); + GLint bpc; /* bits per channel */ + + if (rb->DataType == GL_UNSIGNED_BYTE) + bpc = 8; + else if (rb->DataType == GL_UNSIGNED_SHORT) + bpc = 16; + else + bpc = 32; + + rb->RedBits = + rb->GreenBits = + rb->BlueBits = + rb->AlphaBits = bpc; + + /* Note: we can ignoring internalFormat for "window-system" renderbuffers */ + (void) internalFormat; if (osmesa->format == OSMESA_RGBA) { - rb->GetRow = get_row_RGBA; - rb->GetValues = get_values_RGBA; - rb->PutRow = put_row_RGBA; - rb->PutRowRGB = put_row_rgb_RGBA; - rb->PutMonoRow = put_mono_row_RGBA; - rb->PutValues = put_values_RGBA; - rb->PutMonoValues = put_mono_values_RGBA; + if (rb->DataType == GL_UNSIGNED_BYTE) { + rb->GetRow = get_row_RGBA8; + rb->GetValues = get_values_RGBA8; + rb->PutRow = put_row_RGBA8; + rb->PutRowRGB = put_row_rgb_RGBA8; + rb->PutMonoRow = put_mono_row_RGBA8; + rb->PutValues = put_values_RGBA8; + rb->PutMonoValues = put_mono_values_RGBA8; + } + else if (rb->DataType == GL_UNSIGNED_SHORT) { + rb->GetRow = get_row_RGBA16; + rb->GetValues = get_values_RGBA16; + rb->PutRow = put_row_RGBA16; + rb->PutRowRGB = put_row_rgb_RGBA16; + rb->PutMonoRow = put_mono_row_RGBA16; + rb->PutValues = put_values_RGBA16; + rb->PutMonoValues = put_mono_values_RGBA16; + } + else { + rb->GetRow = get_row_RGBA32; + rb->GetValues = get_values_RGBA32; + rb->PutRow = put_row_RGBA32; + rb->PutRowRGB = put_row_rgb_RGBA32; + rb->PutMonoRow = put_mono_row_RGBA32; + rb->PutValues = put_values_RGBA32; + rb->PutMonoValues = put_mono_values_RGBA32; + } + rb->RedBits = rb->GreenBits = rb->BlueBits = rb->AlphaBits = bpc; } else if (osmesa->format == OSMESA_BGRA) { - rb->GetRow = get_row_BGRA; - rb->GetValues = get_values_BGRA; - rb->PutRow = put_row_BGRA; - rb->PutRowRGB = put_row_rgb_BGRA; - rb->PutMonoRow = put_mono_row_BGRA; - rb->PutValues = put_values_BGRA; - rb->PutMonoValues = put_mono_values_BGRA; + if (rb->DataType == GL_UNSIGNED_BYTE) { + rb->GetRow = get_row_BGRA8; + rb->GetValues = get_values_BGRA8; + rb->PutRow = put_row_BGRA8; + rb->PutRowRGB = put_row_rgb_BGRA8; + rb->PutMonoRow = put_mono_row_BGRA8; + rb->PutValues = put_values_BGRA8; + rb->PutMonoValues = put_mono_values_BGRA8; + } + else if (rb->DataType == GL_UNSIGNED_SHORT) { + rb->GetRow = get_row_BGRA16; + rb->GetValues = get_values_BGRA16; + rb->PutRow = put_row_BGRA16; + rb->PutRowRGB = put_row_rgb_BGRA16; + rb->PutMonoRow = put_mono_row_BGRA16; + rb->PutValues = put_values_BGRA16; + rb->PutMonoValues = put_mono_values_BGRA16; + } + else { + rb->GetRow = get_row_BGRA32; + rb->GetValues = get_values_BGRA32; + rb->PutRow = put_row_BGRA32; + rb->PutRowRGB = put_row_rgb_BGRA32; + rb->PutMonoRow = put_mono_row_BGRA32; + rb->PutValues = put_values_BGRA32; + rb->PutMonoValues = put_mono_values_BGRA32; + } + rb->RedBits = rb->GreenBits = rb->BlueBits = rb->AlphaBits = bpc; } else if (osmesa->format == OSMESA_ARGB) { - rb->GetRow = get_row_ARGB; - rb->GetValues = get_values_ARGB; - rb->PutRow = put_row_ARGB; - rb->PutRowRGB = put_row_rgb_ARGB; - rb->PutMonoRow = put_mono_row_ARGB; - rb->PutValues = put_values_ARGB; - rb->PutMonoValues = put_mono_values_ARGB; + if (rb->DataType == GL_UNSIGNED_BYTE) { + rb->GetRow = get_row_ARGB8; + rb->GetValues = get_values_ARGB8; + rb->PutRow = put_row_ARGB8; + rb->PutRowRGB = put_row_rgb_ARGB8; + rb->PutMonoRow = put_mono_row_ARGB8; + rb->PutValues = put_values_ARGB8; + rb->PutMonoValues = put_mono_values_ARGB8; + } + else if (rb->DataType == GL_UNSIGNED_SHORT) { + rb->GetRow = get_row_ARGB16; + rb->GetValues = get_values_ARGB16; + rb->PutRow = put_row_ARGB16; + rb->PutRowRGB = put_row_rgb_ARGB16; + rb->PutMonoRow = put_mono_row_ARGB16; + rb->PutValues = put_values_ARGB16; + rb->PutMonoValues = put_mono_values_ARGB16; + } + else { + rb->GetRow = get_row_ARGB32; + rb->GetValues = get_values_ARGB32; + rb->PutRow = put_row_ARGB32; + rb->PutRowRGB = put_row_rgb_ARGB32; + rb->PutMonoRow = put_mono_row_ARGB32; + rb->PutValues = put_values_ARGB32; + rb->PutMonoValues = put_mono_values_ARGB32; + } + rb->RedBits = rb->GreenBits = rb->BlueBits = rb->AlphaBits = bpc; } else if (osmesa->format == OSMESA_RGB) { - rb->GetRow = get_row_RGB; - rb->GetValues = get_values_RGB; - rb->PutRow = put_row_RGB; - rb->PutRowRGB = put_row_rgb_RGB; - rb->PutMonoRow = put_mono_row_RGB; - rb->PutValues = put_values_RGB; - rb->PutMonoValues = put_mono_values_RGB; + if (rb->DataType == GL_UNSIGNED_BYTE) { + rb->GetRow = get_row_RGB8; + rb->GetValues = get_values_RGB8; + rb->PutRow = put_row_RGB8; + rb->PutRowRGB = put_row_rgb_RGB8; + rb->PutMonoRow = put_mono_row_RGB8; + rb->PutValues = put_values_RGB8; + rb->PutMonoValues = put_mono_values_RGB8; + } + else if (rb->DataType == GL_UNSIGNED_SHORT) { + rb->GetRow = get_row_RGB16; + rb->GetValues = get_values_RGB16; + rb->PutRow = put_row_RGB16; + rb->PutRowRGB = put_row_rgb_RGB16; + rb->PutMonoRow = put_mono_row_RGB16; + rb->PutValues = put_values_RGB16; + rb->PutMonoValues = put_mono_values_RGB16; + } + else { + rb->GetRow = get_row_RGB32; + rb->GetValues = get_values_RGB32; + rb->PutRow = put_row_RGB32; + rb->PutRowRGB = put_row_rgb_RGB32; + rb->PutMonoRow = put_mono_row_RGB32; + rb->PutValues = put_values_RGB32; + rb->PutMonoValues = put_mono_values_RGB32; + } + rb->RedBits = rb->GreenBits = rb->BlueBits = bpc; } else if (osmesa->format == OSMESA_BGR) { - rb->GetRow = get_row_BGR; - rb->GetValues = get_values_BGR; - rb->PutRow = put_row_BGR; - rb->PutRowRGB = put_row_rgb_BGR; - rb->PutMonoRow = put_mono_row_BGR; - rb->PutValues = put_values_BGR; - rb->PutMonoValues = put_mono_values_BGR; + if (rb->DataType == GL_UNSIGNED_BYTE) { + rb->GetRow = get_row_BGR8; + rb->GetValues = get_values_BGR8; + rb->PutRow = put_row_BGR8; + rb->PutRowRGB = put_row_rgb_BGR8; + rb->PutMonoRow = put_mono_row_BGR8; + rb->PutValues = put_values_BGR8; + rb->PutMonoValues = put_mono_values_BGR8; + } + else if (rb->DataType == GL_UNSIGNED_SHORT) { + rb->GetRow = get_row_BGR16; + rb->GetValues = get_values_BGR16; + rb->PutRow = put_row_BGR16; + rb->PutRowRGB = put_row_rgb_BGR16; + rb->PutMonoRow = put_mono_row_BGR16; + rb->PutValues = put_values_BGR16; + rb->PutMonoValues = put_mono_values_BGR16; + } + else { + rb->GetRow = get_row_BGR32; + rb->GetValues = get_values_BGR32; + rb->PutRow = put_row_BGR32; + rb->PutRowRGB = put_row_rgb_BGR32; + rb->PutMonoRow = put_mono_row_BGR32; + rb->PutValues = put_values_BGR32; + rb->PutMonoValues = put_mono_values_BGR32; + } + rb->RedBits = rb->GreenBits = rb->BlueBits = bpc; } -#if CHAN_TYPE == GL_UNSIGNED_BYTE else if (osmesa->format == OSMESA_RGB_565) { + ASSERT(rb->DataType == GL_UNSIGNED_BYTE); rb->GetRow = get_row_RGB_565; rb->GetValues = get_values_RGB_565; rb->PutRow = put_row_RGB_565; - rb->PutRow = put_row_rgb_RGB_565; + rb->PutRowRGB = put_row_rgb_RGB_565; rb->PutMonoRow = put_mono_row_RGB_565; rb->PutValues = put_values_RGB_565; rb->PutMonoValues = put_mono_values_RGB_565; + rb->RedBits = 5; + rb->GreenBits = 6; + rb->BlueBits = 5; } -#endif else if (osmesa->format == OSMESA_COLOR_INDEX) { rb->GetRow = get_row_CI; rb->GetValues = get_values_CI; @@ -688,51 +1017,57 @@ osmesa_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, rb->PutMonoRow = put_mono_row_CI; rb->PutValues = put_values_CI; rb->PutMonoValues = put_mono_values_CI; + rb->IndexBits = 8; } else { _mesa_problem(ctx, "bad pixel format in osmesa renderbuffer_storage"); } + rb->Width = width; + rb->Height = height; + + compute_row_addresses( osmesa ); + return GL_TRUE; } /** - * Allocate a new renderbuffer tpo describe the user-provided color buffer. + * Allocate a new renderbuffer to describe the user-provided color buffer. */ static struct gl_renderbuffer * -new_osmesa_renderbuffer(GLenum format) +new_osmesa_renderbuffer(GLcontext *ctx, GLenum format, GLenum type) { - struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer); + const GLuint name = 0; + struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, name); if (rb) { - const GLuint name = 0; - _mesa_init_renderbuffer(rb, name); - + rb->RefCount = 1; rb->Delete = osmesa_delete_renderbuffer; rb->AllocStorage = osmesa_renderbuffer_storage; if (format == OSMESA_COLOR_INDEX) { - rb->_BaseFormat = GL_COLOR_INDEX; rb->InternalFormat = GL_COLOR_INDEX; + rb->_ActualFormat = GL_COLOR_INDEX8_EXT; + rb->_BaseFormat = GL_COLOR_INDEX; rb->DataType = GL_UNSIGNED_BYTE; } else { - rb->_BaseFormat = GL_RGBA; rb->InternalFormat = GL_RGBA; - rb->DataType = CHAN_TYPE; + rb->_ActualFormat = GL_RGBA; + rb->_BaseFormat = GL_RGBA; + rb->DataType = type; } } return rb; } - /**********************************************************************/ /***** Public Functions *****/ /**********************************************************************/ -/* +/** * Create an Off-Screen Mesa rendering context. The only attribute needed is * an RGBA vs Color-Index mode flag. * @@ -751,7 +1086,7 @@ OSMesaCreateContext( GLenum format, OSMesaContext sharelist ) -/* +/** * New in Mesa 3.5 * * Create context and specify size of ancillary buffers. @@ -762,18 +1097,14 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits, { OSMesaContext osmesa; struct dd_function_table functions; - 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; + GLenum type = CHAN_TYPE; 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) { @@ -786,18 +1117,6 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits, 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) { @@ -810,18 +1129,6 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits, 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; } else if (format==OSMESA_ARGB) { @@ -834,18 +1141,6 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits, rind = 1; gind = 2; bind = 3; - if (little_endian) { - ashift = 0; - rshift = 8; - gshift = 16; - bshift = 24; - } - else { - ashift = 24; - rshift = 16; - gshift = 8; - bshift = 0; - } rgbmode = GL_TRUE; } else if (format==OSMESA_RGB) { @@ -854,10 +1149,6 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits, greenBits = CHAN_BITS; blueBits = CHAN_BITS; alphaBits = 0; - bshift = 0; - gshift = 8; - rshift = 16; - ashift = 24; rind = 0; gind = 1; bind = 2; @@ -869,10 +1160,6 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits, greenBits = CHAN_BITS; blueBits = CHAN_BITS; alphaBits = 0; - bshift = 0; - gshift = 8; - rshift = 16; - ashift = 24; rind = 2; gind = 1; bind = 0; @@ -885,10 +1172,6 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits, greenBits = 6; blueBits = 5; alphaBits = 0; - rshift = 11; - gshift = 5; - bshift = 0; - ashift = 0; rind = 0; /* not used */ gind = 0; bind = 0; @@ -918,7 +1201,7 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits, 1 /* num samples */ ); if (!osmesa->gl_visual) { - FREE(osmesa); + _mesa_free(osmesa); return NULL; } @@ -927,7 +1210,7 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits, /* override with our functions */ functions.GetString = get_string; functions.UpdateState = osmesa_update_state; - functions.GetBufferSize = get_buffer_size; + functions.GetBufferSize = NULL; if (!_mesa_initialize_context(&osmesa->mesa, osmesa->gl_visual, @@ -935,7 +1218,7 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits, : (GLcontext *) NULL, &functions, (void *) osmesa)) { _mesa_destroy_visual( osmesa->gl_visual ); - FREE(osmesa); + _mesa_free(osmesa); return NULL; } @@ -943,18 +1226,22 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits, _mesa_enable_1_3_extensions(&(osmesa->mesa)); _mesa_enable_1_4_extensions(&(osmesa->mesa)); _mesa_enable_1_5_extensions(&(osmesa->mesa)); + _mesa_enable_2_0_extensions(&(osmesa->mesa)); + _mesa_enable_2_1_extensions(&(osmesa->mesa)); osmesa->gl_buffer = _mesa_create_framebuffer(osmesa->gl_visual); if (!osmesa->gl_buffer) { _mesa_destroy_visual( osmesa->gl_visual ); _mesa_free_context_data( &osmesa->mesa ); - FREE(osmesa); + _mesa_free(osmesa); return NULL; } /* create front color buffer in user-provided memory (no back buffer) */ - _mesa_add_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT, - new_osmesa_renderbuffer(format)); + osmesa->rb = new_osmesa_renderbuffer(&osmesa->mesa, format, type); + _mesa_add_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT, osmesa->rb); + assert(osmesa->rb->RefCount == 2); + _mesa_add_soft_renderbuffers(osmesa->gl_buffer, GL_FALSE, /* color */ osmesa->gl_visual->haveDepthBuffer, @@ -964,16 +1251,8 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits, GL_FALSE /* aux */ ); 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; @@ -983,11 +1262,10 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits, { GLcontext *ctx = &osmesa->mesa; SWcontext *swrast; - struct swrast_device_driver *swdd; TNLcontext *tnl; if (!_swrast_CreateContext( ctx ) || - !_ac_CreateContext( ctx ) || + !_vbo_CreateContext( ctx ) || !_tnl_CreateContext( ctx ) || !_swsetup_CreateContext( ctx )) { _mesa_destroy_visual(osmesa->gl_visual); @@ -1002,90 +1280,45 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits, tnl = TNL_CONTEXT(ctx); tnl->Driver.RunPipeline = _tnl_run_pipeline; - swdd = _swrast_GetDeviceDriverReference( ctx ); - swdd->SetBuffer = set_buffer; - /* Extend the software rasterizer with our optimized line and triangle * drawing functions. */ swrast = SWRAST_CONTEXT( ctx ); swrast->choose_line = osmesa_choose_line; swrast->choose_triangle = osmesa_choose_triangle; - swrast->invalidate_line |= OSMESA_NEW_LINE; - swrast->invalidate_triangle |= OSMESA_NEW_TRIANGLE; } } return osmesa; } -/* +/** * Destroy an Off-Screen Mesa rendering context. * - * Input: ctx - the context to destroy + * \param osmesa the context to destroy */ GLAPI void GLAPIENTRY -OSMesaDestroyContext( OSMesaContext ctx ) +OSMesaDestroyContext( OSMesaContext osmesa ) { - if (ctx) { - _swsetup_DestroyContext( &ctx->mesa ); - _tnl_DestroyContext( &ctx->mesa ); - _ac_DestroyContext( &ctx->mesa ); - _swrast_DestroyContext( &ctx->mesa ); - - _mesa_destroy_visual( ctx->gl_visual ); - _mesa_destroy_framebuffer( ctx->gl_buffer ); - _mesa_free_context_data( &ctx->mesa ); - FREE( ctx ); - } -} + if (osmesa) { + if (osmesa->rb) + _mesa_reference_renderbuffer(&osmesa->rb, NULL); + _swsetup_DestroyContext( &osmesa->mesa ); + _tnl_DestroyContext( &osmesa->mesa ); + _vbo_DestroyContext( &osmesa->mesa ); + _swrast_DestroyContext( &osmesa->mesa ); -/* - * Recompute the values of the context's rowaddr array. - */ -static void -compute_row_addresses( OSMesaContext ctx ) -{ - GLint bytesPerPixel, bytesPerRow, i; - GLubyte *origin = (GLubyte *) ctx->buffer; + _mesa_destroy_visual( osmesa->gl_visual ); + _mesa_unreference_framebuffer( &osmesa->gl_buffer ); - 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); - } - - 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); - } + _mesa_free_context_data( &osmesa->mesa ); + _mesa_free( osmesa ); } } -/* +/** * 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 @@ -1098,61 +1331,76 @@ compute_row_addresses( OSMesaContext ctx ) * 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 + * Input: osmesa - 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. + * then type may be GL_UNSIGNED_SHORT or GL_UNSIGNED_BYTE. And if + * Mesa's been build with CHAN_BITS==32 then type may be GL_FLOAT, + * GL_UNSIGNED_SHORT or GL_UNSIGNED_BYTE. * width, height - size of image buffer in pixels, at least 1 - * Return: GL_TRUE if success, GL_FALSE if error because of invalid ctx, + * Return: GL_TRUE if success, GL_FALSE if error because of invalid osmesa, * invalid buffer address, invalid type, width<1, height<1, * width>internal limit or height>internal limit. */ GLAPI GLboolean GLAPIENTRY -OSMesaMakeCurrent( OSMesaContext ctx, void *buffer, GLenum type, +OSMesaMakeCurrent( OSMesaContext osmesa, void *buffer, GLenum type, GLsizei width, GLsizei height ) { - if (!ctx || !buffer || + if (!osmesa || !buffer || width < 1 || height < 1 || width > MAX_WIDTH || height > MAX_HEIGHT) { return GL_FALSE; } - if (ctx->format == OSMESA_RGB_565) { - if (type != GL_UNSIGNED_SHORT_5_6_5) - return GL_FALSE; + if (osmesa->format == OSMESA_RGB_565 && type != GL_UNSIGNED_SHORT_5_6_5) { + return GL_FALSE; } - else if (type != CHAN_TYPE) { + +#if 0 + if (!(type == GL_UNSIGNED_BYTE || + (type == GL_UNSIGNED_SHORT && CHAN_BITS >= 16) || + (type == GL_FLOAT && CHAN_BITS == 32))) { + /* i.e. is sizeof(type) * 8 > CHAN_BITS? */ return GL_FALSE; } +#endif - /* Need to set these before calling _mesa_make_current() since the first - * time the context is bound, _mesa_make_current() will call our - * get_buffer_size() function to initialize the viewport. These are the - * values returned by get_buffer_size(): + osmesa_update_state( &osmesa->mesa, 0 ); + + /* Call this periodically to detect when the user has begun using + * GL rendering from multiple threads. */ - ctx->buffer = buffer; - ctx->width = width; - ctx->height = height; + _glapi_check_multithread(); - osmesa_update_state( &ctx->mesa, 0 ); - _mesa_make_current( &ctx->mesa, ctx->gl_buffer, ctx->gl_buffer ); + /* Set renderbuffer fields. Set width/height = 0 to force + * osmesa_renderbuffer_storage() being called by _mesa_resize_framebuffer() + */ + osmesa->rb->Data = buffer; + osmesa->rb->DataType = type; + osmesa->rb->Width = osmesa->rb->Height = 0; - if (ctx->userRowLength) - ctx->rowlength = ctx->userRowLength; - else - ctx->rowlength = width; + /* Set the framebuffer's size. This causes the + * osmesa_renderbuffer_storage() function to get called. + */ + _mesa_resize_framebuffer(&osmesa->mesa, osmesa->gl_buffer, width, height); + osmesa->gl_buffer->Initialized = GL_TRUE; /* XXX TEMPORARY? */ + + _mesa_make_current( &osmesa->mesa, osmesa->gl_buffer, osmesa->gl_buffer ); + + /* Remove renderbuffer attachment, then re-add. This installs the + * renderbuffer adaptor/wrapper if needed (for bpp conversion). + */ + _mesa_remove_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT); + _mesa_add_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT, osmesa->rb); - compute_row_addresses( ctx ); - /* this will make ensure we recognize the new buffer size */ - _mesa_resize_framebuffer(&ctx->mesa, ctx->gl_buffer, width, height); + /* this updates the visual's red/green/blue/alphaBits fields */ + _mesa_update_framebuffer_visual(osmesa->gl_buffer); - /* Added by Gerk Huisma: */ - _tnl_MakeCurrent( &ctx->mesa, ctx->mesa.DrawBuffer, - ctx->mesa.ReadBuffer ); + /* update the framebuffer size */ + _mesa_resize_framebuffer(&osmesa->mesa, osmesa->gl_buffer, width, height); return GL_TRUE; } @@ -1184,7 +1432,6 @@ OSMesaPixelStore( GLint pname, GLint value ) return; } osmesa->userRowLength = value; - osmesa->rowlength = value ? value : osmesa->width; break; case OSMESA_Y_UP: osmesa->yup = value ? GL_TRUE : GL_FALSE; @@ -1205,16 +1452,28 @@ OSMesaGetIntegerv( GLint pname, GLint *value ) switch (pname) { case OSMESA_WIDTH: - *value = osmesa->width; + if (osmesa->gl_buffer) + *value = osmesa->gl_buffer->Width; + else + *value = 0; return; case OSMESA_HEIGHT: - *value = osmesa->height; + if (osmesa->gl_buffer) + *value = osmesa->gl_buffer->Height; + else + *value = 0; return; case OSMESA_FORMAT: *value = osmesa->format; return; case OSMESA_TYPE: - *value = CHAN_TYPE; + /* current color buffer's data type */ + if (osmesa->rb) { + *value = osmesa->rb->DataType; + } + else { + *value = 0; + } return; case OSMESA_ROW_LENGTH: *value = osmesa->userRowLength; @@ -1234,7 +1493,8 @@ OSMesaGetIntegerv( GLint pname, GLint *value ) } } -/* + +/** * Return the depth buffer associated with an OSMesa context. * Input: c - the OSMesa context * Output: width, height - size of buffer in pixels @@ -1252,7 +1512,6 @@ OSMesaGetDepthBuffer( OSMesaContext c, GLint *width, GLint *height, rb = c->gl_buffer->Attachment[BUFFER_DEPTH].Renderbuffer; if (!rb || !rb->Data) { - /*if ((!c->gl_buffer) || (!c->gl_buffer->DepthBuffer)) {*/ *width = 0; *height = 0; *bytesPerValue = 0; @@ -1260,8 +1519,8 @@ OSMesaGetDepthBuffer( OSMesaContext c, GLint *width, GLint *height, return GL_FALSE; } else { - *width = c->gl_buffer->Width; - *height = c->gl_buffer->Height; + *width = rb->Width; + *height = rb->Height; if (c->gl_visual->depthBits <= 16) *bytesPerValue = sizeof(GLushort); else @@ -1271,7 +1530,8 @@ OSMesaGetDepthBuffer( OSMesaContext c, GLint *width, GLint *height, } } -/* + +/** * Return the color buffer associated with an OSMesa context. * Input: c - the OSMesa context * Output: width, height - size of buffer in pixels @@ -1280,23 +1540,23 @@ OSMesaGetDepthBuffer( OSMesaContext c, GLint *width, GLint *height, * Return: GL_TRUE or GL_FALSE to indicate success or failure. */ GLAPI GLboolean GLAPIENTRY -OSMesaGetColorBuffer( OSMesaContext c, GLint *width, +OSMesaGetColorBuffer( OSMesaContext osmesa, GLint *width, GLint *height, GLint *format, void **buffer ) { - if (!c->buffer) { + if (osmesa->rb && osmesa->rb->Data) { + *width = osmesa->rb->Width; + *height = osmesa->rb->Height; + *format = osmesa->format; + *buffer = osmesa->rb->Data; + return GL_TRUE; + } + else { *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; - } } @@ -1317,6 +1577,7 @@ static struct name_function functions[] = { { "OSMesaGetDepthBuffer", (OSMESAproc) OSMesaGetDepthBuffer }, { "OSMesaGetColorBuffer", (OSMESAproc) OSMesaGetColorBuffer }, { "OSMesaGetProcAddress", (OSMESAproc) OSMesaGetProcAddress }, + { "OSMesaColorClamp", (OSMESAproc) OSMesaColorClamp }, { NULL, NULL } }; @@ -1331,3 +1592,19 @@ OSMesaGetProcAddress( const char *funcName ) } return _glapi_get_proc_address(funcName); } + + +GLAPI void GLAPIENTRY +OSMesaColorClamp(GLboolean enable) +{ + OSMesaContext osmesa = OSMesaGetCurrentContext(); + + if (enable == GL_TRUE) { + osmesa->mesa.Color.ClampFragmentColor = GL_TRUE; + } + else { + osmesa->mesa.Color.ClampFragmentColor = GL_FIXED_ONLY_ARB; + } +} + +