/** * Analyze context state to see if we can provide a fast line drawing * function. Otherwise, return NULL. */ static swrast_line_func osmesa_choose_line_function( struct gl_context *ctx ) { const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); const SWcontext *swrast = SWRAST_CONTEXT(ctx); if (ctx->RenderMode != GL_RENDER) return NULL; if (ctx->Line.SmoothFlag) return NULL; if (ctx->Texture._EnabledUnits) return NULL; if (ctx->Light.ShadeModel != GL_FLAT) return NULL; if (ctx->Line.Width != 1.0F) return NULL; if (ctx->Line.StippleFlag) return NULL; if (ctx->Line.SmoothFlag) return NULL; if (osmesa->format != OSMESA_RGBA && osmesa->format != OSMESA_BGRA && osmesa->format != OSMESA_ARGB) return NULL; if (swrast->_RasterMask==DEPTH_BIT && ctx->Depth.Func==GL_LESS && ctx->Depth.Mask==GL_TRUE && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) { return (swrast_line_func) flat_rgba_z_line; } if (swrast->_RasterMask == 0) { return (swrast_line_func) flat_rgba_line; } return (swrast_line_func) NULL; }
/** * Return pointer to an optimized triangle function if possible. */ static swrast_tri_func osmesa_choose_triangle_function( struct gl_context *ctx ) { const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); const SWcontext *swrast = SWRAST_CONTEXT(ctx); 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; if (ctx->Texture._EnabledUnits) return (swrast_tri_func) NULL; if (osmesa->format != OSMESA_RGBA && osmesa->format != OSMESA_BGRA && osmesa->format != OSMESA_ARGB) return (swrast_tri_func) NULL; if (ctx->Polygon.CullFlag && ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) return (swrast_tri_func) NULL; if (swrast->_RasterMask == DEPTH_BIT && ctx->Depth.Func == GL_LESS && ctx->Depth.Mask == GL_TRUE && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) { if (ctx->Light.ShadeModel == GL_SMOOTH) { return (swrast_tri_func) smooth_rgba_z_triangle; } else { return (swrast_tri_func) flat_rgba_z_triangle; } } return (swrast_tri_func) NULL; }
/* * 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; } }
/** * Return pointer to an optimized triangle function if possible. */ static swrast_tri_func osmesa_choose_triangle_function( struct gl_context *ctx ) { const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); const SWcontext *swrast = SWRAST_CONTEXT(ctx); if (ctx->DrawBuffer && ctx->DrawBuffer->Visual.redBits == 32) { /* the special-case triangle functions in this file don't work * for float color channels. */ return NULL; } if (ctx->RenderMode != GL_RENDER || ctx->Polygon.SmoothFlag || ctx->Polygon.StippleFlag || ctx->Texture._MaxEnabledTexImageUnit != -1) { return NULL; } if (osmesa->format != OSMESA_RGBA && osmesa->format != OSMESA_BGRA && osmesa->format != OSMESA_ARGB) { return NULL; } if (ctx->Polygon.CullFlag && ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) { return NULL; } if (swrast->_RasterMask == DEPTH_BIT && ctx->Depth.Func == GL_LESS && ctx->Depth.Mask == GL_TRUE && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) { if (ctx->Light.ShadeModel == GL_SMOOTH) { return smooth_rgba_z_triangle; } else { return flat_rgba_z_triangle; } } return NULL; }
/** * Analyze context state to see if we can provide a fast line drawing * function. Otherwise, return NULL. */ static swrast_line_func osmesa_choose_line_function( struct gl_context *ctx ) { const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); const SWcontext *swrast = SWRAST_CONTEXT(ctx); if (ctx->DrawBuffer && ctx->DrawBuffer->Visual.redBits == 32) { /* the special-case line functions in this file don't work * for float color channels. */ return NULL; } if (ctx->RenderMode != GL_RENDER || ctx->Line.SmoothFlag || ctx->Texture._MaxEnabledTexImageUnit == -1 || ctx->Light.ShadeModel != GL_FLAT || ctx->Line.Width != 1.0F || ctx->Line.StippleFlag || ctx->Line.SmoothFlag) { return NULL; } if (osmesa->format != OSMESA_RGBA && osmesa->format != OSMESA_BGRA && osmesa->format != OSMESA_ARGB) { return NULL; } if (swrast->_RasterMask == DEPTH_BIT && ctx->Depth.Func == GL_LESS && ctx->Depth.Mask == GL_TRUE && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) { return flat_rgba_z_line; } if (swrast->_RasterMask == 0) { return flat_rgba_line; } return (swrast_line_func) NULL; }
static void osmesa_MapRenderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint x, GLuint y, GLuint w, GLuint h, GLbitfield mode, GLubyte **mapOut, GLint *rowStrideOut) { const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); if (rb->ClassID == OSMESA_RENDERBUFFER_CLASS) { /* this is an OSMesa renderbuffer which wraps user memory */ struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); const GLuint bpp = _mesa_get_format_bytes(rb->Format); GLint rowStride; /* in bytes */ if (osmesa->userRowLength) rowStride = osmesa->userRowLength * bpp; else rowStride = rb->Width * bpp; if (!osmesa->yup) { /* Y=0 is top line of window */ y = rb->Height - y - 1; *rowStrideOut = -rowStride; } else { *rowStrideOut = rowStride; } *mapOut = (GLubyte *) srb->Buffer + y * rowStride + x * bpp; } else { _swrast_map_soft_renderbuffer(ctx, rb, x, y, w, h, mode, mapOut, rowStrideOut); } }
/** * Allocate renderbuffer storage. We don't actually allocate any storage * since we're using a user-provided buffer. * Just set up all the gl_renderbuffer methods. */ static GLboolean osmesa_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb, GLenum internalFormat, GLuint width, GLuint height) { const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); /* Note: we can ignoring internalFormat for "window-system" renderbuffers */ (void) internalFormat; /* Given the user-provided format and type, figure out which MESA_FORMAT_x * to use. * XXX There aren't Mesa formats for all the possible combinations here! * XXX Specifically, there's only RGBA-order 16-bit/channel and float * XXX formats. * XXX The 8-bit/channel formats should all be OK. */ if (osmesa->format == OSMESA_RGBA) { if (osmesa->DataType == GL_UNSIGNED_BYTE) { if (_mesa_little_endian()) rb->Format = MESA_FORMAT_RGBA8888_REV; else rb->Format = MESA_FORMAT_RGBA8888; } else if (osmesa->DataType == GL_UNSIGNED_SHORT) { rb->Format = MESA_FORMAT_RGBA_16; } else { rb->Format = MESA_FORMAT_RGBA_FLOAT32; } } else if (osmesa->format == OSMESA_BGRA) { if (osmesa->DataType == GL_UNSIGNED_BYTE) { if (_mesa_little_endian()) rb->Format = MESA_FORMAT_ARGB8888; else rb->Format = MESA_FORMAT_ARGB8888_REV; } else if (osmesa->DataType == GL_UNSIGNED_SHORT) { _mesa_warning(ctx, "Unsupported OSMesa format BGRA/GLushort"); rb->Format = MESA_FORMAT_RGBA_16; /* not exactly right */ } else { _mesa_warning(ctx, "Unsupported OSMesa format BGRA/GLfloat"); rb->Format = MESA_FORMAT_RGBA_FLOAT32; /* not exactly right */ } } else if (osmesa->format == OSMESA_ARGB) { if (osmesa->DataType == GL_UNSIGNED_BYTE) { if (_mesa_little_endian()) rb->Format = MESA_FORMAT_ARGB8888_REV; else rb->Format = MESA_FORMAT_ARGB8888; } else if (osmesa->DataType == GL_UNSIGNED_SHORT) { _mesa_warning(ctx, "Unsupported OSMesa format ARGB/GLushort"); rb->Format = MESA_FORMAT_RGBA_16; /* not exactly right */ } else { _mesa_warning(ctx, "Unsupported OSMesa format ARGB/GLfloat"); rb->Format = MESA_FORMAT_RGBA_FLOAT32; /* not exactly right */ } } else if (osmesa->format == OSMESA_RGB) { if (osmesa->DataType == GL_UNSIGNED_BYTE) { rb->Format = MESA_FORMAT_RGB888; } else if (osmesa->DataType == GL_UNSIGNED_SHORT) { _mesa_warning(ctx, "Unsupported OSMesa format RGB/GLushort"); rb->Format = MESA_FORMAT_RGBA_16; /* not exactly right */ } else { _mesa_warning(ctx, "Unsupported OSMesa format RGB/GLfloat"); rb->Format = MESA_FORMAT_RGBA_FLOAT32; /* not exactly right */ } } else if (osmesa->format == OSMESA_BGR) { if (osmesa->DataType == GL_UNSIGNED_BYTE) { rb->Format = MESA_FORMAT_BGR888; } else if (osmesa->DataType == GL_UNSIGNED_SHORT) { _mesa_warning(ctx, "Unsupported OSMesa format BGR/GLushort"); rb->Format = MESA_FORMAT_RGBA_16; /* not exactly right */ } else { _mesa_warning(ctx, "Unsupported OSMesa format BGR/GLfloat"); rb->Format = MESA_FORMAT_RGBA_FLOAT32; /* not exactly right */ } } else if (osmesa->format == OSMESA_RGB_565) { ASSERT(osmesa->DataType == GL_UNSIGNED_BYTE); rb->Format = MESA_FORMAT_RGB565; } 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 renderbuffer storage. We don't actually allocate any storage * since we're using a user-provided buffer. * Just set up all the gl_renderbuffer methods. */ static GLboolean osmesa_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, GLenum internalFormat, GLuint width, GLuint height) { const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); /* Note: we can ignoring internalFormat for "window-system" renderbuffers */ 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; rb->RedBits = rb->GreenBits = rb->BlueBits = rb->AlphaBits = 8 * sizeof(GLchan); } 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; rb->RedBits = rb->GreenBits = rb->BlueBits = rb->AlphaBits = 8 * sizeof(GLchan); } 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; rb->RedBits = rb->GreenBits = rb->BlueBits = rb->AlphaBits = 8 * sizeof(GLchan); } 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; rb->RedBits = rb->GreenBits = rb->BlueBits = 8 * sizeof(GLchan); } 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; rb->RedBits = rb->GreenBits = rb->BlueBits = 8 * sizeof(GLchan); } #if CHAN_TYPE == GL_UNSIGNED_BYTE else if (osmesa->format == OSMESA_RGB_565) { rb->GetRow = get_row_RGB_565; rb->GetValues = get_values_RGB_565; rb->PutRow = put_row_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->PutRow = put_row_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"); } return GL_TRUE; }
/** * Allocate renderbuffer storage. We don't actually allocate any storage * since we're using a user-provided buffer. * Just set up all the gl_renderbuffer methods. */ static GLboolean 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) { 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) { 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) { 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) { 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) { 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; } 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->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; } 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; 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; }