/*
* 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"),
*/
-#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;
+}
/**********************************************************************/
/* 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]; \
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]; \
DST[BCOMP] = SRC[2]; \
- DST[BCOMP] = SRC[3]
+ DST[ACOMP] = SRC[3]
+#include "swrast/s_spantemp.h"
+
+
+/* 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) \
+ 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]; \
+ 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] = 255
+#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"
+
+/* 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) \
+ 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"
-/* BGRA */
-#define NAME(PREFIX) PREFIX##_BGRA
-#define FORMAT GL_RGBA
+/* 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) \
- GLchan *P = osmesa->rowaddr[Y] + 4 * (X)
+ 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[2] = VALUE[RCOMP]; \
DST[1] = VALUE[GCOMP]; \
DST[0] = VALUE[BCOMP]; \
- DST[3] = CHAN_MAX
+ DST[3] = 1.0F
#define FETCH_PIXEL(DST, SRC) \
DST[RCOMP] = SRC[2]; \
DST[GCOMP] = SRC[1]; \
DST[BCOMP] = SRC[0]; \
- DST[BCOMP] = SRC[3]
+ 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]; \
+ 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] = 255
+#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"
-/* ARGB */
-#define NAME(PREFIX) PREFIX##_ARGB
-#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[1] = VALUE[RCOMP]; \
DST[2] = VALUE[GCOMP]; \
DST[3] = VALUE[BCOMP]; \
- DST[0] = CHAN_MAX
+ DST[0] = 65535
#define FETCH_PIXEL(DST, SRC) \
DST[RCOMP] = SRC[1]; \
DST[GCOMP] = SRC[2]; \
DST[BCOMP] = SRC[3]; \
- DST[BCOMP] = SRC[0]
+ 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]; \
+ 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] = 255
+#include "swrast/s_spantemp.h"
+
+/* 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) \
+ 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"
-/* RGB */
-#define NAME(PREFIX) PREFIX##_RGB
-#define FORMAT GL_RGBA
+/* 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) \
- GLchan *P = osmesa->rowaddr[Y] + 4 * (X)
+ 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[RCOMP] = SRC[0]; \
DST[GCOMP] = SRC[1]; \
DST[BCOMP] = SRC[2]; \
- DST[BCOMP] = CHAN_MAX
+ DST[ACOMP] = 1.0F
#include "swrast/s_spantemp.h"
-/* BGR */
-#define NAME(PREFIX) PREFIX##_BGR
-#define FORMAT GL_RGBA
+
+/* 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) \
- GLchan *P = osmesa->rowaddr[Y] + 4 * (X)
+ 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]; \
DST[RCOMP] = SRC[2]; \
DST[GCOMP] = SRC[1]; \
DST[BCOMP] = SRC[0]; \
- DST[BCOMP] = 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) \
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]
-/**********************************************************************/
-/***** 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; \
(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 PIXELADDR4(X,Y) ((GLchan *) osmesa->rowaddr[Y] + 4 * (X))
-#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
-/*
+/**
* Draw a flat-shaded, Z-less, RGB line into an osmesa buffer.
*/
#define NAME flat_rgba_z_line
-/*
+/**
* 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 )
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;
#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), \
span.blue += span.blueStep; \
span.alpha += span.alphaStep; \
span.z += span.zStep; \
- }
+ } \
+}
#ifdef WIN32
#include "..\swrast\s_tritemp.h"
#else
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
-/*
- * 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 )
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;
}
-#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);
+ }
+ }
+}
+
/**
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;
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.
*
-/*
+/**
* New in Mesa 3.5
*
* Create context and specify size of ancillary buffers.
{
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) {
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) {
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) {
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) {
greenBits = CHAN_BITS;
blueBits = CHAN_BITS;
alphaBits = 0;
- bshift = 0;
- gshift = 8;
- rshift = 16;
- ashift = 24;
rind = 0;
gind = 1;
bind = 2;
greenBits = CHAN_BITS;
blueBits = CHAN_BITS;
alphaBits = 0;
- bshift = 0;
- gshift = 8;
- rshift = 16;
- ashift = 24;
rind = 2;
gind = 1;
bind = 0;
greenBits = 6;
blueBits = 5;
alphaBits = 0;
- rshift = 11;
- gshift = 5;
- bshift = 0;
- ashift = 0;
rind = 0; /* not used */
gind = 0;
bind = 0;
1 /* num samples */
);
if (!osmesa->gl_visual) {
- FREE(osmesa);
+ _mesa_free(osmesa);
return NULL;
}
/* 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,
: (GLcontext *) NULL,
&functions, (void *) osmesa)) {
_mesa_destroy_visual( osmesa->gl_visual );
- FREE(osmesa);
+ _mesa_free(osmesa);
return NULL;
}
_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;
}
- _mesa_add_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT,
- new_osmesa_renderbuffer(format));
+ /* 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);
+
_mesa_add_soft_renderbuffers(osmesa->gl_buffer,
GL_FALSE, /* color */
osmesa->gl_visual->haveDepthBuffer,
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;
{
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);
tnl = TNL_CONTEXT(ctx);
tnl->Driver.RunPipeline = _tnl_run_pipeline;
- swdd = _swrast_GetDeviceDriverReference( ctx );
- swdd->SetBuffer = set_buffer;
-
- /* no longer used */
- swdd->WriteRGBASpan = NULL;
- swdd->WriteRGBSpan = NULL;
- swdd->WriteMonoRGBASpan = NULL;
- swdd->WriteRGBAPixels = NULL;
- swdd->WriteMonoRGBAPixels = NULL;
- swdd->ReadRGBASpan = NULL;
- swdd->ReadRGBAPixels = NULL;
-
/* 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
* 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
+
+ osmesa_update_state( &osmesa->mesa, 0 );
- /* 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():
+ /* 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? */
- compute_row_addresses( ctx );
+ _mesa_make_current( &osmesa->mesa, osmesa->gl_buffer, osmesa->gl_buffer );
- /* this will make ensure we recognize the new buffer size */
- _mesa_resize_framebuffer(&ctx->mesa, ctx->gl_buffer, width, height);
-#if 00
- _mesa_ResizeBuffersMESA();
-#endif
+ /* 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);
+
+
+ /* 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;
}
return;
}
osmesa->userRowLength = value;
- osmesa->rowlength = value ? value : osmesa->width;
break;
case OSMESA_Y_UP:
osmesa->yup = value ? GL_TRUE : GL_FALSE;
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;
}
}
-/*
+
+/**
* Return the depth buffer associated with an OSMesa context.
* Input: c - the OSMesa context
* Output: width, height - size of buffer in pixels
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;
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
}
}
-/*
+
+/**
* Return the color buffer associated with an OSMesa context.
* Input: c - the OSMesa context
* Output: width, height - size of buffer in pixels
* 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;
- }
}
{ "OSMesaGetDepthBuffer", (OSMESAproc) OSMesaGetDepthBuffer },
{ "OSMesaGetColorBuffer", (OSMESAproc) OSMesaGetColorBuffer },
{ "OSMesaGetProcAddress", (OSMESAproc) OSMesaGetProcAddress },
+ { "OSMesaColorClamp", (OSMESAproc) OSMesaColorClamp },
{ NULL, NULL }
};
}
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;
+ }
+}
+
+