/**
- * OSMesa rendering context, derived from core Mesa GLcontext.
+ * OSMesa rendering context, derived from core Mesa struct gl_context.
*/
struct osmesa_context
{
- GLcontext mesa; /*< Base class - this must be first */
- GLvisual *gl_visual; /*< Describes the buffers */
+ struct gl_context mesa; /*< Base class - this must be first */
+ struct gl_config *gl_visual; /*< Describes the buffers */
struct gl_renderbuffer *rb; /*< The user's colorbuffer */
- GLframebuffer *gl_buffer; /*< The framebuffer, containing user's rb */
+ struct gl_framebuffer *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 */
static INLINE OSMesaContext
-OSMESA_CONTEXT(GLcontext *ctx)
+OSMESA_CONTEXT(struct gl_context *ctx)
{
/* Just cast, since we're using structure containment */
return (OSMesaContext) ctx;
static const GLubyte *
-get_string( GLcontext *ctx, GLenum name )
+get_string( struct gl_context *ctx, GLenum name )
{
(void) ctx;
switch (name) {
static void
-osmesa_update_state( GLcontext *ctx, GLuint new_state )
+osmesa_update_state( struct gl_context *ctx, GLuint new_state )
{
/* easy - just propogate */
_swrast_InvalidateState( ctx, new_state );
#include "swrast/s_spantemp.h"
-/* color index */
-#define NAME(PREFIX) PREFIX##_CI
-#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 = (GLubyte *) osmesa->rowaddr[Y] + (X)
-#define INC_PIXEL_PTR(P) P += 1
-#define STORE_PIXEL(DST, X, Y, VALUE) \
- *DST = VALUE[0]
-#define FETCH_PIXEL(DST, SRC) \
- DST = SRC[0]
-#include "swrast/s_spantemp.h"
-
-
-
-
/**
* Macros for optimized line/triangle rendering.
* Only for 8-bit channel, RGBA, BGRA, ARGB formats.
* function. Otherwise, return NULL.
*/
static swrast_line_func
-osmesa_choose_line_function( GLcontext *ctx )
+osmesa_choose_line_function( struct gl_context *ctx )
{
const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
const SWcontext *swrast = SWRAST_CONTEXT(ctx);
* Return pointer to an optimized triangle function if possible.
*/
static swrast_tri_func
-osmesa_choose_triangle_function( GLcontext *ctx )
+osmesa_choose_triangle_function( struct gl_context *ctx )
{
const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
const SWcontext *swrast = SWRAST_CONTEXT(ctx);
* standard swrast functions.
*/
static void
-osmesa_choose_triangle( GLcontext *ctx )
+osmesa_choose_triangle( struct gl_context *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
}
static void
-osmesa_choose_line( GLcontext *ctx )
+osmesa_choose_line( struct gl_context *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
return;
}
- if (osmesa->format == OSMESA_COLOR_INDEX) {
- /* CI mode */
- bytesPerPixel = 1 * sizeof(GLubyte);
- }
- else if ((osmesa->format == OSMESA_RGB) || (osmesa->format == OSMESA_BGR)) {
+ if ((osmesa->format == OSMESA_RGB) || (osmesa->format == OSMESA_BGR)) {
/* RGB mode */
bytesPerPixel = 3 * bpc;
}
static void
osmesa_delete_renderbuffer(struct gl_renderbuffer *rb)
{
- _mesa_free(rb);
+ free(rb);
}
* Just set up all the gl_renderbuffer methods.
*/
static GLboolean
-osmesa_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
+osmesa_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
GLenum internalFormat, GLuint width, GLuint height)
{
const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
rb->PutValues = put_values_RGB_565;
rb->PutMonoValues = put_mono_values_RGB_565;
}
- else if (osmesa->format == OSMESA_COLOR_INDEX) {
- rb->GetRow = get_row_CI;
- rb->GetValues = get_values_CI;
- rb->PutRow = put_row_CI;
- rb->PutMonoRow = put_mono_row_CI;
- rb->PutValues = put_values_CI;
- rb->PutMonoValues = put_mono_values_CI;
- }
else {
_mesa_problem(ctx, "bad pixel format in osmesa renderbuffer_storage");
}
* Allocate a new renderbuffer to describe the user-provided color buffer.
*/
static struct gl_renderbuffer *
-new_osmesa_renderbuffer(GLcontext *ctx, GLenum format, GLenum type)
+new_osmesa_renderbuffer(struct gl_context *ctx, GLenum format, GLenum type)
{
const GLuint name = 0;
struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, name);
rb->Delete = osmesa_delete_renderbuffer;
rb->AllocStorage = osmesa_renderbuffer_storage;
- if (format == OSMESA_COLOR_INDEX) {
- rb->InternalFormat = GL_COLOR_INDEX;
- rb->Format = MESA_FORMAT_CI8;
- rb->_BaseFormat = GL_COLOR_INDEX;
- rb->DataType = GL_UNSIGNED_BYTE;
- }
- else {
- rb->InternalFormat = GL_RGBA;
+ rb->InternalFormat = GL_RGBA;
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ rb->Format = MESA_FORMAT_RGBA8888;
+ break;
+ case GL_UNSIGNED_SHORT:
+ rb->Format = MESA_FORMAT_RGBA_16;
+ break;
+ case GL_FLOAT:
+ rb->Format = MESA_FORMAT_RGBA_FLOAT32;
+ break;
+ default:
+ assert(0 && "Unexpected type in new_osmesa_renderbuffer()");
rb->Format = MESA_FORMAT_RGBA8888;
- rb->_BaseFormat = GL_RGBA;
- rb->DataType = type;
}
+ rb->_BaseFormat = GL_RGBA;
+ rb->DataType = type;
}
return rb;
}
* 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
+ * Input: format - Must be GL_RGBA
* 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 GLint accumBits = (format == OSMESA_COLOR_INDEX) ? 0 : 16;
return OSMesaCreateContextExt(format, DEFAULT_SOFTWARE_DEPTH_BITS,
- 8, accumBits, sharelist);
+ 8, 0, sharelist);
}
OSMesaContext osmesa;
struct dd_function_table functions;
GLint rind, gind, bind, aind;
- GLint indexBits = 0, redBits = 0, greenBits = 0, blueBits = 0, alphaBits =0;
- GLboolean rgbmode;
- GLenum type = CHAN_TYPE;
+ GLint redBits = 0, greenBits = 0, blueBits = 0, alphaBits =0;
rind = gind = bind = aind = 0;
- if (format==OSMESA_COLOR_INDEX) {
- indexBits = 8;
- rgbmode = GL_FALSE;
- }
- else if (format==OSMESA_RGBA) {
- indexBits = 0;
+ if (format==OSMESA_RGBA) {
redBits = CHAN_BITS;
greenBits = CHAN_BITS;
blueBits = CHAN_BITS;
gind = 1;
bind = 2;
aind = 3;
- rgbmode = GL_TRUE;
}
else if (format==OSMESA_BGRA) {
- indexBits = 0;
redBits = CHAN_BITS;
greenBits = CHAN_BITS;
blueBits = CHAN_BITS;
gind = 1;
rind = 2;
aind = 3;
- rgbmode = GL_TRUE;
}
else if (format==OSMESA_ARGB) {
- indexBits = 0;
redBits = CHAN_BITS;
greenBits = CHAN_BITS;
blueBits = CHAN_BITS;
rind = 1;
gind = 2;
bind = 3;
- rgbmode = GL_TRUE;
}
else if (format==OSMESA_RGB) {
- indexBits = 0;
redBits = CHAN_BITS;
greenBits = CHAN_BITS;
blueBits = CHAN_BITS;
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;
rind = 2;
gind = 1;
bind = 0;
- rgbmode = GL_TRUE;
}
#if CHAN_TYPE == GL_UNSIGNED_BYTE
else if (format==OSMESA_RGB_565) {
- indexBits = 0;
redBits = 5;
greenBits = 6;
blueBits = 5;
rind = 0; /* not used */
gind = 0;
bind = 0;
- rgbmode = GL_TRUE;
}
#endif
else {
osmesa = (OSMesaContext) CALLOC_STRUCT(osmesa_context);
if (osmesa) {
- osmesa->gl_visual = _mesa_create_visual( rgbmode,
- GL_FALSE, /* double buffer */
+ osmesa->gl_visual = _mesa_create_visual( GL_FALSE, /* double buffer */
GL_FALSE, /* stereo */
redBits,
greenBits,
blueBits,
alphaBits,
- indexBits,
depthBits,
stencilBits,
accumBits,
1 /* num samples */
);
if (!osmesa->gl_visual) {
- _mesa_free(osmesa);
+ free(osmesa);
return NULL;
}
if (!_mesa_initialize_context(&osmesa->mesa,
osmesa->gl_visual,
sharelist ? &sharelist->mesa
- : (GLcontext *) NULL,
+ : (struct gl_context *) NULL,
&functions, (void *) osmesa)) {
_mesa_destroy_visual( osmesa->gl_visual );
- _mesa_free(osmesa);
+ free(osmesa);
return NULL;
}
if (!osmesa->gl_buffer) {
_mesa_destroy_visual( osmesa->gl_visual );
_mesa_free_context_data( &osmesa->mesa );
- _mesa_free(osmesa);
+ free(osmesa);
return NULL;
}
- /* create front color buffer in user-provided memory (no back buffer) */
- 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);
-
+ /* Create depth/stencil/accum buffers. We'll create the color
+ * buffer later in OSMesaMakeCurrent().
+ */
_mesa_add_soft_renderbuffers(osmesa->gl_buffer,
GL_FALSE, /* color */
osmesa->gl_visual->haveDepthBuffer,
/* Initialize the software rasterizer and helper modules. */
{
- GLcontext *ctx = &osmesa->mesa;
+ struct gl_context *ctx = &osmesa->mesa;
SWcontext *swrast;
TNLcontext *tnl;
!_swsetup_CreateContext( ctx )) {
_mesa_destroy_visual(osmesa->gl_visual);
_mesa_free_context_data(ctx);
- _mesa_free(osmesa);
+ free(osmesa);
return NULL;
}
_mesa_reference_framebuffer( &osmesa->gl_buffer, NULL );
_mesa_free_context_data( &osmesa->mesa );
- _mesa_free( osmesa );
+ free( osmesa );
}
}
*/
_glapi_check_multithread();
+
+ /* Create a front/left color buffer which wraps the user-provided buffer.
+ * There is no back color buffer.
+ * If the user tries to use a 8, 16 or 32-bit/channel buffer that
+ * doesn't match what Mesa was compiled for (CHAN_BITS) the
+ * _mesa_add_renderbuffer() function will create a "wrapper" renderbuffer
+ * that converts rendering from CHAN_BITS to the user-requested channel
+ * size.
+ */
+ if (!osmesa->rb) {
+ osmesa->rb = new_osmesa_renderbuffer(&osmesa->mesa, osmesa->format, type);
+ _mesa_remove_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT);
+ _mesa_add_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT, osmesa->rb);
+ assert(osmesa->rb->RefCount == 2);
+ }
+
/* 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;
/* Set the framebuffer's size. This causes the
GLAPI OSMesaContext GLAPIENTRY
OSMesaGetCurrentContext( void )
{
- GLcontext *ctx = _mesa_get_current_context();
+ struct gl_context *ctx = _mesa_get_current_context();
if (ctx)
return (OSMesaContext) ctx;
else