GLAPI void GLAPIENTRY OSMesaPixelStore( GLint pname, GLint value ) { OSMesaContext osmesa = OSMesaGetCurrentContext(); switch (pname) { case OSMESA_ROW_LENGTH: if (value<0) { _mesa_error( &osmesa->mesa, GL_INVALID_VALUE, "OSMesaPixelStore(value)" ); return; } osmesa->userRowLength = value; osmesa->rowlength = value ? value : osmesa->width; break; case OSMESA_Y_UP: osmesa->yup = value ? GL_TRUE : GL_FALSE; break; default: _mesa_error( &osmesa->mesa, GL_INVALID_ENUM, "OSMesaPixelStore(pname)" ); return; } compute_row_addresses( 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 * of 4 if using RGBA mode. * * Image data is stored in the order of glDrawPixels: row-major order * with the lower-left image pixel stored in the first array position * (ie. bottom-to-top). * * 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 * 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. * width, height - size of image buffer in pixels, at least 1 * Return: GL_TRUE if success, GL_FALSE if error because of invalid ctx, * 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, GLsizei width, GLsizei height ) { if (!ctx || !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; } else if (type != CHAN_TYPE) { 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(): */ ctx->buffer = buffer; ctx->width = width; ctx->height = height; osmesa_update_state( &ctx->mesa, 0 ); /* Call this periodically to detect when the user has begun using * GL rendering from multiple threads. */ _glapi_check_multithread(); _mesa_make_current( &ctx->mesa, ctx->gl_buffer, ctx->gl_buffer ); if (ctx->userRowLength) ctx->rowlength = ctx->userRowLength; else ctx->rowlength = width; compute_row_addresses( ctx ); /* this will make ensure we recognize the new buffer size */ _mesa_resize_framebuffer(&ctx->mesa, ctx->gl_buffer, width, height); return GL_TRUE; }
/* * 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 * of 4 if using RGBA mode. * * Image data is stored in the order of glDrawPixels: row-major order * with the lower-left image pixel stored in the first array position * (ie. bottom-to-top). * * Since the only type initially supported is GL_UNSIGNED_BYTE, if the * context is in RGBA mode, each pixel will be stored as a 4-byte RGBA * value. If the context is in color indexed mode, each pixel will be * stored as a 1-byte value. * * 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 * buffer - the image buffer memory * type - data type for pixel components, only GL_UNSIGNED_BYTE * supported now * width, height - size of image buffer in pixels, at least 1 * Return: GL_TRUE if success, GL_FALSE if error because of invalid ctx, * invalid buffer address, type!=GL_UNSIGNED_BYTE, width<1, height<1, * width>internal limit or height>internal limit. */ GLboolean OSMesaMakeCurrent( OSMesaContext ctx, void *buffer, GLenum type, GLsizei width, GLsizei height ) { if (!ctx || !buffer || type!=GL_UNSIGNED_BYTE || width<1 || height<1 || width>MAX_WIDTH || height>MAX_HEIGHT) { return GL_FALSE; } gl_make_current( ctx->gl_ctx, ctx->gl_buffer ); ctx->buffer = buffer; ctx->width = width; ctx->height = height; if (ctx->rowlength==0) { ctx->rowlength = width; } osmesa_setup_DD_pointers( ctx->gl_ctx ); #ifdef THREADS /* Set current context for the calling thread */ /* TODO */ #else /* Set current context for the address space, all threads */ Current = ctx; #endif compute_row_addresses( ctx ); /* init viewport */ if (ctx->gl_ctx->Viewport.Width==0) { /* initialize viewport and scissor box to buffer size */ gl_Viewport( ctx->gl_ctx, 0, 0, width, height ); ctx->gl_ctx->Scissor.Width = width; ctx->gl_ctx->Scissor.Height = height; } return GL_TRUE; }
void OSMesaPixelStore( GLint pname, GLint value ) { OSMesaContext ctx = OSMesaGetCurrentContext(); switch (pname) { case OSMESA_ROW_LENGTH: if (value<0) { gl_error( ctx->gl_ctx, GL_INVALID_VALUE, "OSMesaPixelStore(value)" ); return; } ctx->rowlength = value; break; case OSMESA_Y_UP: ctx->yup = value ? GL_TRUE : GL_FALSE; break; default: gl_error( ctx->gl_ctx, GL_INVALID_ENUM, "OSMesaPixelStore(pname)" ); return; } compute_row_addresses( ctx ); }
/** * 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); 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; }