From 544b94e15617fb69f77ebd57b1be49aafe2f64e6 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 17 Oct 2006 17:44:43 +0000 Subject: [PATCH] Lots of fixes/changes to select color depth at runtime. --- src/mesa/drivers/osmesa/osmesa.c | 209 +++++++++++++++---------------- 1 file changed, 100 insertions(+), 109 deletions(-) diff --git a/src/mesa/drivers/osmesa/osmesa.c b/src/mesa/drivers/osmesa/osmesa.c index 4ac5a043fa6..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,6 +1366,13 @@ OSMesaMakeCurrent( OSMesaContext osmesa, void *buffer, GLenum type, */ _glapi_check_multithread(); + /* 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 * osmesa_renderbuffer_storage() function to get called. */ @@ -1384,19 +1381,8 @@ OSMesaMakeCurrent( OSMesaContext osmesa, void *buffer, GLenum type, _mesa_make_current( &osmesa->mesa, osmesa->gl_buffer, osmesa->gl_buffer ); - /* Set the color renderbuffer's pointer to the user buffer, - * update row pointers, etc. - */ - if (osmesa->userRowLength) - osmesa->rowlength = osmesa->userRowLength; - else - osmesa->rowlength = width; - osmesa->rb->Data = buffer; - osmesa->rb->DataType = type; - compute_row_addresses( osmesa ); - /* 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); @@ -1438,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; @@ -1459,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; @@ -1520,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 -- 2.30.2