summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/osmesa/osmesa.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/osmesa/osmesa.c')
-rw-r--r--src/mesa/drivers/osmesa/osmesa.c213
1 files changed, 104 insertions, 109 deletions
diff --git a/src/mesa/drivers/osmesa/osmesa.c b/src/mesa/drivers/osmesa/osmesa.c
index 942692c8bb0..0b027eddec5 100644
--- a/src/mesa/drivers/osmesa/osmesa.c
+++ b/src/mesa/drivers/osmesa/osmesa.c
@@ -64,8 +64,6 @@ struct osmesa_context
struct gl_renderbuffer *rb; /*< The user's colorbuffer */
GLframebuffer *gl_buffer; /*< The framebuffer, containing user's rb */
GLenum format; /*< User-specified context format */
- GLint width, height; /*< size of image buffer */
- GLint rowlength; /*< number of pixels per row */
GLint userRowLength; /*< user-specified number of pixels per row */
GLint rInd, gInd, bInd, aInd;/*< index offsets for RGBA formats */
GLvoid *rowaddr[MAX_HEIGHT]; /*< address of first pixel in each image row */
@@ -117,23 +115,6 @@ osmesa_update_state( GLcontext *ctx, GLuint new_state )
}
-/**
- * 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 *****/
@@ -597,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;
@@ -706,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;
@@ -759,6 +744,72 @@ osmesa_choose_line( GLcontext *ctx )
}
+
+/**
+ * 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);
+ }
+ }
+}
+
+
+
/**
* Don't use _mesa_delete_renderbuffer since we can't free rb->Data.
*/
@@ -788,6 +839,11 @@ osmesa_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
else
bpc = 32;
+ rb->RedBits =
+ rb->GreenBits =
+ rb->BlueBits =
+ rb->AlphaBits = bpc;
+
/* Note: we can ignoring internalFormat for "window-system" renderbuffers */
(void) internalFormat;
@@ -970,6 +1026,8 @@ osmesa_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
rb->Width = width;
rb->Height = height;
+ compute_row_addresses( osmesa );
+
return GL_TRUE;
}
@@ -1003,65 +1061,6 @@ new_osmesa_renderbuffer(GLcontext *ctx, GLenum format, GLenum type)
}
-
-/**
- * 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 */
-
- 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 = osmesa->rowlength * bytesPerPixel;
-
- if (osmesa->yup) {
- /* Y=0 is bottom line of window */
- for (i = 0; i < MAX_HEIGHT; i++) {
- osmesa->rowaddr[i] = (GLvoid *) ((GLubyte *) origin + i * bytesPerRow);
- }
- }
- else {
- /* Y=0 is top line of window */
- for (i = 0; i < MAX_HEIGHT; i++) {
- GLint j = osmesa->height - i - 1;
- osmesa->rowaddr[i] = (GLvoid *) ((GLubyte *) origin + j * bytesPerRow);
- }
- }
-}
-
-
-
/**********************************************************************/
/***** Public Functions *****/
/**********************************************************************/
@@ -1210,7 +1209,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,
@@ -1248,10 +1247,7 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits,
GL_FALSE /* aux */ );
osmesa->format = format;
- osmesa->width = 0;
- osmesa->height = 0;
osmesa->userRowLength = 0;
- osmesa->rowlength = 0;
osmesa->yup = GL_TRUE;
osmesa->rInd = rind;
osmesa->gInd = gind;
@@ -1354,20 +1350,14 @@ OSMesaMakeCurrent( OSMesaContext osmesa, void *buffer, GLenum type,
return GL_FALSE;
}
+#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;
}
-
- /* 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->width = width;
- osmesa->height = height;
+#endif
osmesa_update_state( &osmesa->mesa, 0 );
@@ -1376,23 +1366,23 @@ OSMesaMakeCurrent( OSMesaContext osmesa, void *buffer, GLenum type,
*/
_glapi_check_multithread();
- _mesa_make_current( &osmesa->mesa, osmesa->gl_buffer, osmesa->gl_buffer );
-
- if (osmesa->userRowLength)
- osmesa->rowlength = osmesa->userRowLength;
- else
- osmesa->rowlength = width;
-
+ /* 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;
- compute_row_addresses( osmesa );
+ osmesa->rb->Width = osmesa->rb->Height = 0;
+
+ /* 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? */
- /* update the color renderbuffer's format, type, width, height */
- osmesa_renderbuffer_storage(&osmesa->mesa, osmesa->rb,
- osmesa->rb->InternalFormat, width, height);
+ _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.
+ * 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);
@@ -1434,7 +1424,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;
@@ -1455,10 +1444,16 @@ 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;
@@ -1516,8 +1511,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