static void sw_init_renderbuffers(struct sw_framebuffer *fb) { _mesa_init_renderbuffer(&fb->frontbuffer.swrast.Base, 0); fb->frontbuffer.swrast.Base.ClassID = SW_FRONT_RENDERBUFFER_CLASS; fb->frontbuffer.swrast.Base.AllocStorage = sw_fb_renderbuffer_storage; fb->frontbuffer.swrast.Base.Delete = sw_fb_renderbuffer_delete; fb->frontbuffer.swrast.Base.InternalFormat = GL_RGBA; fb->frontbuffer.swrast.Base._BaseFormat = GL_RGBA; _mesa_remove_renderbuffer(fb->gl_buffer, BUFFER_FRONT_LEFT); _mesa_add_renderbuffer(fb->gl_buffer, BUFFER_FRONT_LEFT, &fb->frontbuffer.swrast.Base); if(fb->flags & SW_FB_DOUBLEBUFFERED) { _mesa_init_renderbuffer(&fb->backbuffer.Base, 0); fb->backbuffer.Base.ClassID = SW_BACK_RENDERBUFFER_CLASS; fb->backbuffer.Base.AllocStorage = sw_bb_renderbuffer_storage; fb->backbuffer.Base.Delete = sw_bb_renderbuffer_delete; fb->backbuffer.Base.InternalFormat = GL_RGBA; fb->backbuffer.Base._BaseFormat = GL_RGBA; _mesa_remove_renderbuffer(fb->gl_buffer, BUFFER_BACK_LEFT); _mesa_add_renderbuffer(fb->gl_buffer, BUFFER_BACK_LEFT, &fb->backbuffer.Base); } }
static GLboolean dri_create_buffer(__DRIscreen * sPriv, __DRIdrawable * dPriv, const struct gl_config * visual, GLboolean isPixmap) { struct dri_drawable *drawable = NULL; struct gl_framebuffer *fb; struct dri_swrast_renderbuffer *frontrb, *backrb; TRACE; (void) sPriv; (void) isPixmap; drawable = CALLOC_STRUCT(dri_drawable); if (drawable == NULL) goto drawable_fail; dPriv->driverPrivate = drawable; drawable->dPriv = dPriv; drawable->row = malloc(SWRAST_MAX_WIDTH * 4); if (drawable->row == NULL) goto drawable_fail; fb = &drawable->Base; /* basic framebuffer setup */ _mesa_initialize_window_framebuffer(fb, visual); /* add front renderbuffer */ frontrb = swrast_new_renderbuffer(visual, dPriv, GL_TRUE); _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontrb->Base.Base); /* add back renderbuffer */ if (visual->doubleBufferMode) { backrb = swrast_new_renderbuffer(visual, dPriv, GL_FALSE); _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backrb->Base.Base); } /* add software renderbuffers */ _swrast_add_soft_renderbuffers(fb, GL_FALSE, /* color */ visual->haveDepthBuffer, visual->haveStencilBuffer, visual->haveAccumBuffer, GL_FALSE, /* alpha */ GL_FALSE /* aux bufs */); return GL_TRUE; drawable_fail: if (drawable) free(drawable->row); free(drawable); return GL_FALSE; }
/** * Add a renderbuffer to the framebuffer. */ static boolean st_framebuffer_add_renderbuffer(struct st_framebuffer *stfb, gl_buffer_index idx) { struct gl_renderbuffer *rb; enum pipe_format format; int samples; boolean sw; if (!stfb->iface) return FALSE; /* do not distinguish depth/stencil buffers */ if (idx == BUFFER_STENCIL) idx = BUFFER_DEPTH; switch (idx) { case BUFFER_DEPTH: format = stfb->iface->visual->depth_stencil_format; sw = FALSE; break; case BUFFER_ACCUM: format = stfb->iface->visual->accum_format; sw = TRUE; break; default: format = stfb->iface->visual->color_format; sw = FALSE; break; } if (format == PIPE_FORMAT_NONE) return FALSE; samples = stfb->iface->visual->samples; if (!samples) samples = st_get_msaa(); rb = st_new_renderbuffer_fb(format, samples, sw); if (!rb) return FALSE; if (idx != BUFFER_DEPTH) { _mesa_add_renderbuffer(&stfb->Base, idx, rb); } else { if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 0)) _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, rb); if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1)) _mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL, rb); } return TRUE; }
/** * Add a software-based aux renderbuffer to the given framebuffer. * This is a helper routine for device drivers when creating a * window system framebuffer (not a user-created render/framebuffer). * Once this function is called, you can basically forget about this * renderbuffer; core Mesa will handle all the buffer management and * rendering! * * NOTE: color-index aux buffers not supported. */ static GLboolean add_aux_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb, GLuint colorBits, GLuint numBuffers) { GLuint i; if (colorBits > 16) { _mesa_problem(ctx, "Unsupported colorBits in add_aux_renderbuffers"); return GL_FALSE; } assert(numBuffers <= MAX_AUX_BUFFERS); for (i = 0; i < numBuffers; i++) { struct gl_renderbuffer *rb = _swrast_new_soft_renderbuffer(ctx, 0); assert(fb->Attachment[BUFFER_AUX0 + i].Renderbuffer == NULL); if (!rb) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating aux buffer"); return GL_FALSE; } assert (colorBits <= 8); rb->InternalFormat = GL_RGBA; rb->AllocStorage = soft_renderbuffer_storage; _mesa_add_renderbuffer(fb, BUFFER_AUX0 + i, rb); } return GL_TRUE; }
/** * Add a software-based stencil renderbuffer to the given framebuffer. * This is a helper routine for device drivers when creating a * window system framebuffer (not a user-created render/framebuffer). * Once this function is called, you can basically forget about this * renderbuffer; core Mesa will handle all the buffer management and * rendering! */ static GLboolean add_stencil_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, GLuint stencilBits) { struct gl_renderbuffer *rb; if (stencilBits > 16) { _mesa_problem(ctx, "Unsupported stencilBits in add_stencil_renderbuffer"); return GL_FALSE; } assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL); rb = _swrast_new_soft_renderbuffer(ctx, 0); if (!rb) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating stencil buffer"); return GL_FALSE; } assert(stencilBits <= 8); rb->InternalFormat = GL_STENCIL_INDEX8; rb->AllocStorage = soft_renderbuffer_storage; _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb); return GL_TRUE; }
/** * Add a software-based accumulation renderbuffer to the given framebuffer. * This is a helper routine for device drivers when creating a * window system framebuffer (not a user-created render/framebuffer). * Once this function is called, you can basically forget about this * renderbuffer; core Mesa will handle all the buffer management and * rendering! */ static GLboolean add_accum_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, GLuint redBits, GLuint greenBits, GLuint blueBits, GLuint alphaBits) { struct gl_renderbuffer *rb; if (redBits > 16 || greenBits > 16 || blueBits > 16 || alphaBits > 16) { _mesa_problem(ctx, "Unsupported accumBits in add_accum_renderbuffer"); return GL_FALSE; } assert(fb->Attachment[BUFFER_ACCUM].Renderbuffer == NULL); rb = _swrast_new_soft_renderbuffer(ctx, 0); if (!rb) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer"); return GL_FALSE; } rb->InternalFormat = GL_RGBA16_SNORM; rb->AllocStorage = soft_renderbuffer_storage; _mesa_add_renderbuffer(fb, BUFFER_ACCUM, rb); return GL_TRUE; }
/** * Add a software-based depth renderbuffer to the given framebuffer. * This is a helper routine for device drivers when creating a * window system framebuffer (not a user-created render/framebuffer). * Once this function is called, you can basically forget about this * renderbuffer; core Mesa will handle all the buffer management and * rendering! */ static GLboolean add_depth_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, GLuint depthBits) { struct gl_renderbuffer *rb; if (depthBits > 32) { _mesa_problem(ctx, "Unsupported depthBits in add_depth_renderbuffer"); return GL_FALSE; } assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL); rb = _swrast_new_soft_renderbuffer(ctx, 0); if (!rb) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth buffer"); return GL_FALSE; } if (depthBits <= 16) { rb->InternalFormat = GL_DEPTH_COMPONENT16; } else if (depthBits <= 24) { rb->InternalFormat = GL_DEPTH_COMPONENT24; } else { rb->InternalFormat = GL_DEPTH_COMPONENT32; } rb->AllocStorage = soft_renderbuffer_storage; _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb); 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). * * If the context's viewport hasn't been initialized yet, it will now be * initialized to (0,0,width,height). * * 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 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 osmesa, * invalid buffer address, invalid type, width<1, height<1, * width>internal limit or height>internal limit. */ GLAPI GLboolean GLAPIENTRY OSMesaMakeCurrent( OSMesaContext osmesa, void *buffer, GLenum type, GLsizei width, GLsizei height ) { if (!osmesa || !buffer || width < 1 || height < 1 || width > MAX_WIDTH || height > MAX_HEIGHT) { return GL_FALSE; } if (osmesa->format == OSMESA_RGB_565 && type != GL_UNSIGNED_SHORT_5_6_5) { 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; } #endif osmesa_update_state( &osmesa->mesa, 0 ); /* Call this periodically to detect when the user has begun using * GL rendering from multiple threads. */ _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. */ _mesa_resize_framebuffer(&osmesa->mesa, osmesa->gl_buffer, width, height); osmesa->gl_buffer->Initialized = GL_TRUE; /* XXX TEMPORARY? */ _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 (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); /* update the framebuffer size */ _mesa_resize_framebuffer(&osmesa->mesa, osmesa->gl_buffer, width, height); return GL_TRUE; }
static GLboolean nouveau_create_buffer(__DRIscreen *dri_screen, __DRIdrawable *drawable, const struct gl_config *visual, GLboolean is_pixmap) { struct gl_renderbuffer *rb; struct gl_framebuffer *fb; GLenum color_format; if (is_pixmap) return GL_FALSE; /* not implemented */ if (visual->redBits == 5) color_format = GL_RGB5; else if (visual->alphaBits == 0) color_format = GL_RGB8; else color_format = GL_RGBA8; fb = nouveau_framebuffer_dri_new(visual); if (!fb) return GL_FALSE; /* Front buffer. */ rb = nouveau_renderbuffer_dri_new(color_format, drawable); _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, rb); /* Back buffer */ if (visual->doubleBufferMode) { rb = nouveau_renderbuffer_dri_new(color_format, drawable); _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, rb); } /* Depth/stencil buffer. */ if (visual->depthBits == 24 && visual->stencilBits == 8) { rb = nouveau_renderbuffer_dri_new(GL_DEPTH24_STENCIL8_EXT, drawable); _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb); _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb); } else if (visual->depthBits == 24) { rb = nouveau_renderbuffer_dri_new(GL_DEPTH_COMPONENT24, drawable); _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb); } else if (visual->depthBits == 16) { rb = nouveau_renderbuffer_dri_new(GL_DEPTH_COMPONENT16, drawable); _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb); } /* Software renderbuffers. */ _swrast_add_soft_renderbuffers(fb, GL_FALSE, GL_FALSE, GL_FALSE, visual->accumRedBits > 0, GL_FALSE, GL_FALSE); drawable->driverPrivate = fb; return GL_TRUE; }
static GLboolean add_depth_stencil_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb) { struct gl_renderbuffer *rb; assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL); assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL); rb = _swrast_new_soft_renderbuffer(ctx, 0); if (!rb) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth+stencil buffer"); return GL_FALSE; } rb->InternalFormat = GL_DEPTH_STENCIL; rb->AllocStorage = soft_renderbuffer_storage; _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb); _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb); return GL_TRUE; }
/** * Add software-based color renderbuffers to the given framebuffer. * This is a helper routine for device drivers when creating a * window system framebuffer (not a user-created render/framebuffer). * Once this function is called, you can basically forget about this * renderbuffer; core Mesa will handle all the buffer management and * rendering! */ static GLboolean add_color_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb, GLuint rgbBits, GLuint alphaBits, GLboolean frontLeft, GLboolean backLeft, GLboolean frontRight, GLboolean backRight) { gl_buffer_index b; if (rgbBits > 16 || alphaBits > 16) { _mesa_problem(ctx, "Unsupported bit depth in add_color_renderbuffers"); return GL_FALSE; } assert(MAX_COLOR_ATTACHMENTS >= 4); for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) { struct gl_renderbuffer *rb; if (b == BUFFER_FRONT_LEFT && !frontLeft) continue; else if (b == BUFFER_BACK_LEFT && !backLeft) continue; else if (b == BUFFER_FRONT_RIGHT && !frontRight) continue; else if (b == BUFFER_BACK_RIGHT && !backRight) continue; assert(fb->Attachment[b].Renderbuffer == NULL); rb = ctx->Driver.NewRenderbuffer(ctx, 0); if (!rb) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer"); return GL_FALSE; } rb->InternalFormat = GL_RGBA; rb->AllocStorage = soft_renderbuffer_storage; _mesa_add_renderbuffer(fb, b, rb); } return GL_TRUE; }
/** * Create a drawing surface which can be directly displayed on a screen. */ static EGLSurface fbCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg, const EGLint *attrib_list) { _EGLConfig *config = _eglLookupConfig(drv, dpy, cfg); fbDisplay *display = Lookup_fbDisplay(dpy); fbSurface *surface; EGLSurface surf; GLvisual vis; GLcontext *ctx = NULL; /* this should be OK */ int origin, bytesPerPixel; int width, height, stride; surface = (fbSurface *) malloc(sizeof(*surface)); if (!surface) { return EGL_NO_SURFACE; } /* init base class, error check, etc. */ surf = _eglInitScreenSurface(&surface->Base, drv, dpy, cfg, attrib_list); if (surf == EGL_NO_SURFACE) { free(surface); return EGL_NO_SURFACE; } /* convert EGLConfig to GLvisual */ _eglConfigToContextModesRec(config, &vis); /* create Mesa framebuffer */ surface->mesa_framebuffer = _mesa_create_framebuffer(&vis); if (!surface->mesa_framebuffer) { free(surface); _eglRemoveSurface(&surface->Base); return EGL_NO_SURFACE; } width = surface->Base.Width; height = surface->Base.Height; bytesPerPixel = vis.rgbBits / 8; stride = width * bytesPerPixel; origin = 0; /* front color renderbuffer */ { driRenderbuffer *drb = driNewRenderbuffer(GL_RGBA, display->pFB, bytesPerPixel, origin, stride, NULL); fbSetSpanFunctions(drb, &vis); _mesa_add_renderbuffer(surface->mesa_framebuffer, BUFFER_FRONT_LEFT, &drb->Base); } /* back color renderbuffer */ if (vis.doubleBufferMode) { GLubyte *backBuf = _mesa_malloc(stride * height); driRenderbuffer *drb = driNewRenderbuffer(GL_RGBA, backBuf, bytesPerPixel, origin, stride, NULL); fbSetSpanFunctions(drb, &vis); _mesa_add_renderbuffer(surface->mesa_framebuffer, BUFFER_BACK_LEFT, &drb->Base); } /* other renderbuffers- software based */ _mesa_add_soft_renderbuffers(surface->mesa_framebuffer, GL_FALSE, /* color */ vis.haveDepthBuffer, vis.haveStencilBuffer, vis.haveAccumBuffer, GL_FALSE, /* alpha */ GL_FALSE /* aux */); _mesa_resize_framebuffer(ctx, surface->mesa_framebuffer, width, height); return surf; }
void sisUpdateBufferSize(sisContextPtr smesa) { __GLSiSHardware *current = &smesa->current; __GLSiSHardware *prev = &smesa->prev; struct gl_framebuffer *fb = smesa->glCtx->DrawBuffer; if (!smesa->front.Base.InternalFormat) { /* do one-time init for the renderbuffers */ sisInitRenderbuffer(&smesa->front.Base, GL_RGBA); sisSetSpanFunctions(&smesa->front, &fb->Visual); _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &smesa->front.Base); if (fb->Visual.doubleBufferMode) { sisInitRenderbuffer(&smesa->back.Base, GL_RGBA); sisSetSpanFunctions(&smesa->back, &fb->Visual); _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &smesa->back.Base); } if (smesa->glCtx->Visual.depthBits > 0) { sisInitRenderbuffer(&smesa->depth.Base, (smesa->glCtx->Visual.depthBits == 16 ? GL_DEPTH_COMPONENT16 : GL_DEPTH_COMPONENT24)); sisSetSpanFunctions(&smesa->depth, &fb->Visual); _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &smesa->depth.Base); } if (smesa->glCtx->Visual.stencilBits > 0) { sisInitRenderbuffer(&smesa->stencil.Base, GL_STENCIL_INDEX8_EXT); sisSetSpanFunctions(&smesa->stencil, &fb->Visual); _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &smesa->stencil.Base); } } /* Make sure initialization did what we think it should */ assert(smesa->front.Base.InternalFormat); assert(smesa->front.Base.AllocStorage); if (fb->Visual.doubleBufferMode) { assert(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer); assert(smesa->front.Base.AllocStorage); } if (fb->Visual.depthBits) { assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer); assert(smesa->depth.Base.AllocStorage); } /* XXX Should get the base offset of the frontbuffer from the X Server */ smesa->front.offset = smesa->driDrawable->x * smesa->bytesPerPixel + smesa->driDrawable->y * smesa->front.pitch; smesa->front.map = (char *) smesa->driScreen->pFB + smesa->front.offset; if ( smesa->width == smesa->driDrawable->w && smesa->height == smesa->driDrawable->h ) { return; } smesa->front.bpp = smesa->bytesPerPixel * 8; /* Front pitch set on context create */ smesa->front.size = smesa->front.pitch * smesa->driDrawable->h; smesa->width = smesa->driDrawable->w; smesa->height = smesa->driDrawable->h; smesa->bottom = smesa->height - 1; if (smesa->back.offset) sisFreeBackbuffer( smesa ); if (smesa->depth.offset) sisFreeZStencilBuffer( smesa ); if ( smesa->glCtx->Visual.depthBits > 0 ) sisAllocZStencilBuffer( smesa ); if ( smesa->glCtx->Visual.doubleBufferMode ) sisAllocBackbuffer( smesa ); current->hwZ &= ~MASK_ZBufferPitch; current->hwZ |= smesa->depth.pitch >> 2; current->hwOffsetZ = smesa->depth.offset >> 2; if ((current->hwOffsetZ != prev->hwOffsetZ) || (current->hwZ != prev->hwZ)) { prev->hwOffsetZ = current->hwOffsetZ; prev->hwZ = current->hwZ; smesa->GlobalFlag |= GFLAG_ZSETTING; } sisUpdateClipping( smesa->glCtx ); }
/** * 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: 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 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 osmesa, * invalid buffer address, invalid type, width<1, height<1, * width>internal limit or height>internal limit. */ GLAPI GLboolean GLAPIENTRY OSMesaMakeCurrent( OSMesaContext osmesa, void *buffer, GLenum type, GLsizei width, GLsizei height ) { if (!osmesa || !buffer || width < 1 || height < 1 || width > SWRAST_MAX_WIDTH || height > SWRAST_MAX_HEIGHT) { return GL_FALSE; } if (osmesa->format == OSMESA_RGB_565 && type != GL_UNSIGNED_SHORT_5_6_5) { 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; } #endif osmesa_update_state( &osmesa->mesa, 0 ); /* Call this periodically to detect when the user has begun using * GL rendering from multiple threads. */ _glapi_check_multithread(); /* Create a front/left color buffer which wraps the user-provided buffer. * There is no back color buffer. * If the user tries to use a 8, 16 or 32-bit/channel buffer that * doesn't match what Mesa was compiled for (CHAN_BITS) the * _mesa_add_renderbuffer() function will create a "wrapper" renderbuffer * that converts rendering from CHAN_BITS to the user-requested channel * size. */ if (!osmesa->srb) { osmesa->srb = new_osmesa_renderbuffer(&osmesa->mesa, osmesa->format, type); _mesa_remove_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT); _mesa_add_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT, &osmesa->srb->Base); assert(osmesa->srb->Base.RefCount == 2); } osmesa->DataType = type; /* Set renderbuffer fields. Set width/height = 0 to force * osmesa_renderbuffer_storage() being called by _mesa_resize_framebuffer() */ osmesa->srb->Buffer = buffer; osmesa->srb->Base.Width = osmesa->srb->Base.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? */ _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 (for bpp conversion). */ _mesa_remove_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT); _mesa_add_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT, &osmesa->srb->Base); /* this updates the visual's red/green/blue/alphaBits fields */ _mesa_update_framebuffer_visual(&osmesa->mesa, osmesa->gl_buffer); /* update the framebuffer size */ _mesa_resize_framebuffer(&osmesa->mesa, osmesa->gl_buffer, width, height); return GL_TRUE; }
/* * New in Mesa 3.5 * * Create context and specify size of ancillary buffers. */ GLAPI OSMesaContext GLAPIENTRY OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits, GLint accumBits, OSMesaContext sharelist ) { OSMesaContext osmesa; struct dd_function_table functions; GLint rind, gind, bind, aind; GLint indexBits = 0, redBits = 0, greenBits = 0, blueBits = 0, alphaBits =0; GLboolean rgbmode; rind = gind = bind = aind = 0; if (format==OSMESA_COLOR_INDEX) { indexBits = 8; rgbmode = GL_FALSE; } else if (format==OSMESA_RGBA) { indexBits = 0; redBits = CHAN_BITS; greenBits = CHAN_BITS; blueBits = CHAN_BITS; alphaBits = CHAN_BITS; rind = 0; gind = 1; bind = 2; aind = 3; rgbmode = GL_TRUE; } else if (format==OSMESA_BGRA) { indexBits = 0; redBits = CHAN_BITS; greenBits = CHAN_BITS; blueBits = CHAN_BITS; alphaBits = CHAN_BITS; bind = 0; gind = 1; rind = 2; aind = 3; rgbmode = GL_TRUE; } else if (format==OSMESA_ARGB) { indexBits = 0; redBits = CHAN_BITS; greenBits = CHAN_BITS; blueBits = CHAN_BITS; alphaBits = CHAN_BITS; aind = 0; rind = 1; gind = 2; bind = 3; rgbmode = GL_TRUE; } else if (format==OSMESA_RGB) { indexBits = 0; redBits = CHAN_BITS; greenBits = CHAN_BITS; blueBits = CHAN_BITS; alphaBits = 0; rind = 0; gind = 1; bind = 2; rgbmode = GL_TRUE; } else if (format==OSMESA_BGR) { indexBits = 0; redBits = CHAN_BITS; greenBits = CHAN_BITS; blueBits = CHAN_BITS; alphaBits = 0; rind = 2; gind = 1; bind = 0; rgbmode = GL_TRUE; } #if CHAN_TYPE == GL_UNSIGNED_BYTE else if (format==OSMESA_RGB_565) { indexBits = 0; redBits = 5; greenBits = 6; blueBits = 5; alphaBits = 0; rind = 0; /* not used */ gind = 0; bind = 0; rgbmode = GL_TRUE; } #endif else { return NULL; } osmesa = (OSMesaContext) CALLOC_STRUCT(osmesa_context); if (osmesa) { osmesa->gl_visual = _mesa_create_visual( rgbmode, GL_FALSE, /* double buffer */ GL_FALSE, /* stereo */ redBits, greenBits, blueBits, alphaBits, indexBits, depthBits, stencilBits, accumBits, accumBits, accumBits, alphaBits ? accumBits : 0, 1 /* num samples */ ); if (!osmesa->gl_visual) { FREE(osmesa); return NULL; } /* Initialize device driver function table */ _mesa_init_driver_functions(&functions); /* override with our functions */ functions.GetString = get_string; functions.UpdateState = osmesa_update_state; functions.GetBufferSize = get_buffer_size; if (!_mesa_initialize_context(&osmesa->mesa, osmesa->gl_visual, sharelist ? &sharelist->mesa : (GLcontext *) NULL, &functions, (void *) osmesa)) { _mesa_destroy_visual( osmesa->gl_visual ); FREE(osmesa); return NULL; } _mesa_enable_sw_extensions(&(osmesa->mesa)); _mesa_enable_1_3_extensions(&(osmesa->mesa)); _mesa_enable_1_4_extensions(&(osmesa->mesa)); _mesa_enable_1_5_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); return NULL; } /* create front color buffer in user-provided memory (no back buffer) */ _mesa_add_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT, new_osmesa_renderbuffer(format)); _mesa_add_soft_renderbuffers(osmesa->gl_buffer, GL_FALSE, /* color */ osmesa->gl_visual->haveDepthBuffer, osmesa->gl_visual->haveStencilBuffer, osmesa->gl_visual->haveAccumBuffer, GL_FALSE, /* alpha */ 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->rInd = rind; osmesa->gInd = gind; osmesa->bInd = bind; osmesa->aInd = aind; /* Initialize the software rasterizer and helper modules. */ { GLcontext *ctx = &osmesa->mesa; SWcontext *swrast; TNLcontext *tnl; if (!_swrast_CreateContext( ctx ) || !_ac_CreateContext( ctx ) || !_tnl_CreateContext( ctx ) || !_swsetup_CreateContext( ctx )) { _mesa_destroy_visual(osmesa->gl_visual); _mesa_free_context_data(ctx); _mesa_free(osmesa); return NULL; } _swsetup_Wakeup( ctx ); /* use default TCL pipeline */ tnl = TNL_CONTEXT(ctx); tnl->Driver.RunPipeline = _tnl_run_pipeline; /* 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; } } return osmesa; }
/* Create and initialize the Mesa and driver specific pixmap buffer * data. */ static GLboolean fbCreateBuffer( __DRIscreenPrivate *driScrnPriv, __DRIdrawablePrivate *driDrawPriv, const __GLcontextModes *mesaVis, GLboolean isPixmap ) { struct gl_framebuffer *mesa_framebuffer; if (isPixmap) { return GL_FALSE; /* not implemented */ } else { const GLboolean swDepth = mesaVis->depthBits > 0; const GLboolean swAlpha = mesaVis->alphaBits > 0; const GLboolean swAccum = mesaVis->accumRedBits > 0; const GLboolean swStencil = mesaVis->stencilBits > 0; mesa_framebuffer = _mesa_create_framebuffer(mesaVis); if (!mesa_framebuffer) return 0; /* XXX double-check these parameters (bpp vs cpp, etc) */ { driRenderbuffer *drb = driNewRenderbuffer(GL_RGBA, driScrnPriv->pFB, driScrnPriv->fbBPP / 8, driScrnPriv->fbOrigin, driScrnPriv->fbStride, driDrawPriv); fbSetSpanFunctions(drb, mesaVis); _mesa_add_renderbuffer(mesa_framebuffer, BUFFER_FRONT_LEFT, &drb->Base); } if (mesaVis->doubleBufferMode) { /* XXX what are the correct origin/stride values? */ GLvoid *backBuf = _mesa_malloc(driScrnPriv->fbStride * driScrnPriv->fbHeight); driRenderbuffer *drb = driNewRenderbuffer(GL_RGBA, backBuf, driScrnPriv->fbBPP /8, driScrnPriv->fbOrigin, driScrnPriv->fbStride, driDrawPriv); fbSetSpanFunctions(drb, mesaVis); _mesa_add_renderbuffer(mesa_framebuffer, BUFFER_BACK_LEFT, &drb->Base); } _mesa_add_soft_renderbuffers(mesa_framebuffer, GL_FALSE, /* color */ swDepth, swStencil, swAccum, swAlpha, /* or always zero? */ GL_FALSE /* aux */); driDrawPriv->driverPrivate = mesa_framebuffer; return 1; } }
/** * Allocate a new XMesaBuffer object which corresponds to the given drawable. * Note that XMesaBuffer is derived from struct gl_framebuffer. * The new XMesaBuffer will not have any size (Width=Height=0). * * \param d the corresponding X drawable (window or pixmap) * \param type either WINDOW, PIXMAP or PBUFFER, describing d * \param vis the buffer's visual * \param cmap the window's colormap, if known. * \return new XMesaBuffer or NULL if any problem */ static XMesaBuffer create_xmesa_buffer(XMesaDrawable d, BufferType type, XMesaVisual vis, XMesaColormap cmap) { XMesaBuffer b; ASSERT(type == WINDOW || type == PIXMAP || type == PBUFFER); b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer); if (!b) return NULL; b->display = vis->display; b->xm_visual = vis; b->type = type; b->cmap = cmap; _mesa_initialize_window_framebuffer(&b->mesa_buffer, &vis->mesa_visual); b->mesa_buffer.Delete = xmesa_delete_framebuffer; /* * Front renderbuffer */ b->frontxrb = xmesa_new_renderbuffer(NULL, 0, vis, GL_FALSE); if (!b->frontxrb) { free(b); return NULL; } b->frontxrb->Parent = b; b->frontxrb->drawable = d; b->frontxrb->pixmap = (XMesaPixmap) d; _mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_FRONT_LEFT, &b->frontxrb->Base.Base); /* * Back renderbuffer */ if (vis->mesa_visual.doubleBufferMode) { b->backxrb = xmesa_new_renderbuffer(NULL, 0, vis, GL_TRUE); if (!b->backxrb) { /* XXX free front xrb too */ free(b); return NULL; } b->backxrb->Parent = b; /* determine back buffer implementation */ b->db_mode = vis->ximage_flag ? BACK_XIMAGE : BACK_PIXMAP; _mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_BACK_LEFT, &b->backxrb->Base.Base); } /* * Other renderbuffer (depth, stencil, etc) */ _swrast_add_soft_renderbuffers(&b->mesa_buffer, GL_FALSE, /* color */ vis->mesa_visual.haveDepthBuffer, vis->mesa_visual.haveStencilBuffer, vis->mesa_visual.haveAccumBuffer, GL_FALSE, /* software alpha buffer */ vis->mesa_visual.numAuxBuffers > 0 ); /* GLX_EXT_texture_from_pixmap */ b->TextureTarget = 0; b->TextureFormat = GLX_TEXTURE_FORMAT_NONE_EXT; b->TextureMipmap = 0; /* insert buffer into linked list */ b->Next = XMesaBufferList; XMesaBufferList = b; return b; }
/** * Create the Mesa framebuffer and renderbuffers for a given window/drawable. * * \todo This function (and its interface) will need to be updated to support * pbuffers. */ static GLboolean radeonCreateBuffer( __DRIscreen *driScrnPriv, __DRIdrawable *driDrawPriv, const struct gl_config *mesaVis, GLboolean isPixmap ) { radeonScreenPtr screen = (radeonScreenPtr) driScrnPriv->driverPrivate; const GLboolean swDepth = GL_FALSE; const GLboolean swAlpha = GL_FALSE; const GLboolean swAccum = mesaVis->accumRedBits > 0; const GLboolean swStencil = mesaVis->stencilBits > 0 && mesaVis->depthBits != 24; mesa_format rgbFormat; struct radeon_framebuffer *rfb; if (isPixmap) return GL_FALSE; /* not implemented */ rfb = CALLOC_STRUCT(radeon_framebuffer); if (!rfb) return GL_FALSE; _mesa_initialize_window_framebuffer(&rfb->base, mesaVis); if (mesaVis->redBits == 5) rgbFormat = _mesa_little_endian() ? MESA_FORMAT_B5G6R5_UNORM : MESA_FORMAT_R5G6B5_UNORM; else if (mesaVis->alphaBits == 0) rgbFormat = _mesa_little_endian() ? MESA_FORMAT_B8G8R8X8_UNORM : MESA_FORMAT_X8R8G8B8_UNORM; else rgbFormat = _mesa_little_endian() ? MESA_FORMAT_B8G8R8A8_UNORM : MESA_FORMAT_A8R8G8B8_UNORM; /* front color renderbuffer */ rfb->color_rb[0] = radeon_create_renderbuffer(rgbFormat, driDrawPriv); _mesa_add_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT, &rfb->color_rb[0]->base.Base); rfb->color_rb[0]->has_surface = 1; /* back color renderbuffer */ if (mesaVis->doubleBufferMode) { rfb->color_rb[1] = radeon_create_renderbuffer(rgbFormat, driDrawPriv); _mesa_add_renderbuffer(&rfb->base, BUFFER_BACK_LEFT, &rfb->color_rb[1]->base.Base); rfb->color_rb[1]->has_surface = 1; } if (mesaVis->depthBits == 24) { if (mesaVis->stencilBits == 8) { struct radeon_renderbuffer *depthStencilRb = radeon_create_renderbuffer(MESA_FORMAT_Z24_UNORM_S8_UINT, driDrawPriv); _mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depthStencilRb->base.Base); _mesa_add_renderbuffer(&rfb->base, BUFFER_STENCIL, &depthStencilRb->base.Base); depthStencilRb->has_surface = screen->depthHasSurface; } else { /* depth renderbuffer */ struct radeon_renderbuffer *depth = radeon_create_renderbuffer(MESA_FORMAT_Z24_UNORM_X8_UINT, driDrawPriv); _mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base.Base); depth->has_surface = screen->depthHasSurface; } } else if (mesaVis->depthBits == 16) { /* just 16-bit depth buffer, no hw stencil */ struct radeon_renderbuffer *depth = radeon_create_renderbuffer(MESA_FORMAT_Z_UNORM16, driDrawPriv); _mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base.Base); depth->has_surface = screen->depthHasSurface; } _swrast_add_soft_renderbuffers(&rfb->base, GL_FALSE, /* color */ swDepth, swStencil, swAccum, swAlpha, GL_FALSE /* aux */); driDrawPriv->driverPrivate = (void *) rfb; return (driDrawPriv->driverPrivate != NULL); }
GLFBDevBufferPtr glFBDevCreateBuffer( const struct fb_fix_screeninfo *fixInfo, const struct fb_var_screeninfo *varInfo, const GLFBDevVisualPtr visual, void *frontBuffer, void *backBuffer, size_t size ) { struct GLFBDevRenderbufferRec *frontrb, *backrb; GLFBDevBufferPtr buf; ASSERT(visual); ASSERT(frontBuffer); ASSERT(size > 0); /* this is to update the visual if there was a resize and the buffer is created again */ visual->var = *varInfo; visual->fix = *fixInfo; if (visual->fix.visual != fixInfo->visual || visual->fix.type != fixInfo->type || visual->var.bits_per_pixel != varInfo->bits_per_pixel || visual->var.grayscale != varInfo->grayscale || visual->var.red.offset != varInfo->red.offset || visual->var.green.offset != varInfo->green.offset || visual->var.blue.offset != varInfo->blue.offset || visual->var.transp.offset != varInfo->transp.offset) { /* visual mismatch! */ return NULL; } buf = CALLOC_STRUCT(GLFBDevBufferRec); if (!buf) return NULL; /* basic framebuffer setup */ _mesa_initialize_window_framebuffer(&buf->glframebuffer, &visual->glvisual); /* add front renderbuffer */ frontrb = new_glfbdev_renderbuffer(frontBuffer, visual); _mesa_add_renderbuffer(&buf->glframebuffer, BUFFER_FRONT_LEFT, &frontrb->Base); /* add back renderbuffer */ if (visual->glvisual.doubleBufferMode) { const int malloced = !backBuffer; if (malloced) { /* malloc a back buffer */ backBuffer = malloc(size); if (!backBuffer) { _mesa_free_framebuffer_data(&buf->glframebuffer); free(buf); return NULL; } } backrb = new_glfbdev_renderbuffer(backBuffer, visual); if (!backrb) { /* out of mem */ return NULL; } backrb->mallocedBuffer = malloced; _mesa_add_renderbuffer(&buf->glframebuffer, BUFFER_BACK_LEFT, &backrb->Base); } /* add software renderbuffers */ _mesa_add_soft_renderbuffers(&buf->glframebuffer, GL_FALSE, /* color */ visual->glvisual.haveDepthBuffer, visual->glvisual.haveStencilBuffer, visual->glvisual.haveAccumBuffer, GL_FALSE, /* alpha */ GL_FALSE /* aux bufs */); buf->fix = *fixInfo; /* struct assignment */ buf->var = *varInfo; /* struct assignment */ buf->visual = visual; /* ptr assignment */ buf->size = size; buf->bytesPerPixel = visual->var.bits_per_pixel / 8; return buf; }
/** * This is called when we need to set up GL rendering to a new X window. */ static GLboolean intelCreateBuffer(__DRIscreen * driScrnPriv, __DRIdrawable * driDrawPriv, const struct gl_config * mesaVis, GLboolean isPixmap) { struct intel_renderbuffer *rb; struct intel_screen *screen = (struct intel_screen*) driScrnPriv->driverPrivate; gl_format rgbFormat; unsigned num_samples = intel_quantize_num_samples(screen, mesaVis->samples); struct gl_framebuffer *fb; if (isPixmap) return false; fb = CALLOC_STRUCT(gl_framebuffer); if (!fb) return false; _mesa_initialize_window_framebuffer(fb, mesaVis); if (mesaVis->redBits == 5) rgbFormat = MESA_FORMAT_RGB565; else if (mesaVis->sRGBCapable) rgbFormat = MESA_FORMAT_SARGB8; else if (mesaVis->alphaBits == 0) rgbFormat = MESA_FORMAT_XRGB8888; else rgbFormat = MESA_FORMAT_ARGB8888; /* setup the hardware-based renderbuffers */ rb = intel_create_renderbuffer(rgbFormat, num_samples); _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &rb->Base.Base); if (mesaVis->doubleBufferMode) { rb = intel_create_renderbuffer(rgbFormat, num_samples); _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &rb->Base.Base); } /* * Assert here that the gl_config has an expected depth/stencil bit * combination: one of d24/s8, d16/s0, d0/s0. (See intelInitScreen2(), * which constructs the advertised configs.) */ if (mesaVis->depthBits == 24) { assert(mesaVis->stencilBits == 8); if (screen->hw_has_separate_stencil) { rb = intel_create_private_renderbuffer(MESA_FORMAT_X8_Z24, num_samples); _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base); rb = intel_create_private_renderbuffer(MESA_FORMAT_S8, num_samples); _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base.Base); } else { /* * Use combined depth/stencil. Note that the renderbuffer is * attached to two attachment points. */ rb = intel_create_private_renderbuffer(MESA_FORMAT_S8_Z24, num_samples); _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base); _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base.Base); } } else if (mesaVis->depthBits == 16) { assert(mesaVis->stencilBits == 0); rb = intel_create_private_renderbuffer(MESA_FORMAT_Z16, num_samples); _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base); } else { assert(mesaVis->depthBits == 0); assert(mesaVis->stencilBits == 0); } /* now add any/all software-based renderbuffers we may need */ _swrast_add_soft_renderbuffers(fb, false, /* never sw color */ false, /* never sw depth */ false, /* never sw stencil */ mesaVis->accumRedBits > 0, false, /* never sw alpha */ false /* never sw aux */ ); driDrawPriv->driverPrivate = fb; return true; }
MesaSoftwareRenderer::MesaSoftwareRenderer(BGLView* view, ulong options, BGLDispatcher* dispatcher) : BGLRenderer(view, options, dispatcher), fBitmap(NULL), fDirectModeEnabled(false), fInfo(NULL), fInfoLocker("info locker"), fContext(NULL), fVisual(NULL), fFrameBuffer(NULL), fFrontRenderBuffer(NULL), fBackRenderBuffer(NULL), fColorSpace(B_NO_COLOR_SPACE) { CALLED(); fClearColor[BE_RCOMP] = 0; fClearColor[BE_GCOMP] = 0; fClearColor[BE_BCOMP] = 0; fClearColor[BE_ACOMP] = 0; fClearIndex = 0; fColorSpace = BScreen(GLView()->Window()).ColorSpace(); // We force single buffering for the time being //options &= !BGL_DOUBLE; const GLboolean rgbFlag = ((options & BGL_INDEX) == 0); const GLboolean alphaFlag = ((options & BGL_ALPHA) == BGL_ALPHA); const GLboolean dblFlag = ((options & BGL_DOUBLE) == BGL_DOUBLE); const GLboolean stereoFlag = false; const GLint depth = (options & BGL_DEPTH) ? 16 : 0; const GLint stencil = (options & BGL_STENCIL) ? 8 : 0; const GLint accum = (options & BGL_ACCUM) ? 16 : 0; const GLint index = (options & BGL_INDEX) ? 32 : 0; const GLint red = rgbFlag ? 8 : 0; const GLint green = rgbFlag ? 8 : 0; const GLint blue = rgbFlag ? 8 : 0; const GLint alpha = alphaFlag ? 8 : 0; fOptions = options; // | BGL_INDIRECT; struct dd_function_table functions; fVisual = _mesa_create_visual(rgbFlag, dblFlag, stereoFlag, red, green, blue, alpha, index, depth, stencil, accum, accum, accum, alpha ? accum : 0, 1); // Initialize device driver function table _mesa_init_driver_functions(&functions); functions.GetString = _GetString; functions.UpdateState = _UpdateState; functions.GetBufferSize = NULL; functions.Error = _Error; functions.Viewport = _Viewport; functions.Flush = _Flush; // create core context fContext = _mesa_create_context(fVisual, NULL, &functions, this); if (!fContext) { _mesa_destroy_visual(fVisual); return; } /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext(fContext); _vbo_CreateContext(fContext); _tnl_CreateContext(fContext); _swsetup_CreateContext(fContext); _swsetup_Wakeup(fContext); // Use default TCL pipeline TNL_CONTEXT(fContext)->Driver.RunPipeline = _tnl_run_pipeline; _mesa_enable_sw_extensions(fContext); _mesa_enable_1_3_extensions(fContext); _mesa_enable_1_4_extensions(fContext); _mesa_enable_1_5_extensions(fContext); _mesa_enable_2_0_extensions(fContext); _mesa_enable_2_1_extensions(fContext); // create core framebuffer fFrameBuffer = (struct msr_framebuffer*)_mesa_calloc( sizeof(*fFrameBuffer)); _mesa_initialize_framebuffer(&fFrameBuffer->Base, fVisual); fFrontRenderBuffer = (struct msr_renderbuffer*)_mesa_calloc( sizeof(*fFrontRenderBuffer)); _mesa_init_renderbuffer(&fFrontRenderBuffer->Base, 0); fFrontRenderBuffer->Base.AllocStorage = _FrontRenderbufferStorage; fFrontRenderBuffer->Base.Data = NULL; fFrontRenderBuffer->Base.InternalFormat = GL_RGBA; fFrontRenderBuffer->Base._BaseFormat = GL_RGBA; fFrontRenderBuffer->Base.DataType = GL_UNSIGNED_BYTE; fFrontRenderBuffer->Base.RedBits = 8 * sizeof(GLubyte); fFrontRenderBuffer->Base.GreenBits = 8 * sizeof(GLubyte); fFrontRenderBuffer->Base.BlueBits = 8 * sizeof(GLubyte); fFrontRenderBuffer->Base.AlphaBits = 8 * sizeof(GLubyte); _SetSpanFuncs(fFrontRenderBuffer, fColorSpace); _mesa_add_renderbuffer(&fFrameBuffer->Base, BUFFER_FRONT_LEFT, &fFrontRenderBuffer->Base); if (dblFlag) { fBackRenderBuffer = (struct msr_renderbuffer*)_mesa_calloc( sizeof(*fBackRenderBuffer)); _mesa_init_renderbuffer(&fBackRenderBuffer->Base, 0); fBackRenderBuffer->Base.AllocStorage = _BackRenderbufferStorage; fBackRenderBuffer->Base.Data = NULL; fBackRenderBuffer->Base.Delete = _DeleteBackBuffer; fBackRenderBuffer->Base.InternalFormat = GL_RGBA; fBackRenderBuffer->Base._BaseFormat = GL_RGBA; fBackRenderBuffer->Base.DataType = GL_UNSIGNED_BYTE; fBackRenderBuffer->Base.RedBits = 8 * sizeof(GLubyte); fBackRenderBuffer->Base.GreenBits = 8 * sizeof(GLubyte); fBackRenderBuffer->Base.BlueBits = 8 * sizeof(GLubyte); fBackRenderBuffer->Base.AlphaBits = 8 * sizeof(GLubyte); _SetSpanFuncs(fBackRenderBuffer, fColorSpace); _mesa_add_renderbuffer(&fFrameBuffer->Base, BUFFER_BACK_LEFT, &fBackRenderBuffer->Base); } _mesa_add_soft_renderbuffers(&fFrameBuffer->Base, GL_FALSE, fVisual->haveDepthBuffer, fVisual->haveStencilBuffer, fVisual->haveAccumBuffer, alphaFlag, GL_FALSE); BRect bounds = view->Bounds(); fWidth = fNewWidth = (GLint)bounds.Width(); fHeight = fNewHeight = (GLint)bounds.Height(); // some stupid applications (Quake2) don't even think about calling LockGL() // before using glGetString and its glGet*() friends... // so make sure there is at least a valid context. if (!_mesa_get_current_context()) { LockGL(); // not needed, we don't have a looper yet: UnlockLooper(); } }
MesaSoftwareRenderer::MesaSoftwareRenderer(BGLView* view, ulong options, BGLDispatcher* dispatcher) : BGLRenderer(view, options, dispatcher), fBitmap(NULL), fDirectModeEnabled(false), fInfo(NULL), fInfoLocker("info locker"), fContext(NULL), fVisual(NULL), fFrameBuffer(NULL), fFrontRenderBuffer(NULL), fBackRenderBuffer(NULL), fColorSpace(B_NO_COLOR_SPACE) { CALLED(); fClearColor[BE_RCOMP] = 0; fClearColor[BE_GCOMP] = 0; fClearColor[BE_BCOMP] = 0; fClearColor[BE_ACOMP] = 0; fClearIndex = 0; fColorSpace = BScreen(GLView()->Window()).ColorSpace(); // We force single buffering for the time being options &= ~BGL_DOUBLE; const GLboolean rgbFlag = ((options & BGL_INDEX) == 0); const GLboolean alphaFlag = ((options & BGL_ALPHA) == BGL_ALPHA); const GLboolean dblFlag = ((options & BGL_DOUBLE) == BGL_DOUBLE); const GLboolean stereoFlag = false; const GLint depth = (options & BGL_DEPTH) ? 16 : 0; const GLint stencil = (options & BGL_STENCIL) ? 8 : 0; const GLint accum = (options & BGL_ACCUM) ? 16 : 0; const GLint red = rgbFlag ? 8 : 0; const GLint green = rgbFlag ? 8 : 0; const GLint blue = rgbFlag ? 8 : 0; const GLint alpha = alphaFlag ? 8 : 0; fOptions = options; // | BGL_INDIRECT; struct dd_function_table functions; fVisual = _mesa_create_visual(dblFlag, stereoFlag, red, green, blue, alpha, depth, stencil, accum, accum, accum, alpha ? accum : 0, 1); // Initialize device driver function table _mesa_init_driver_functions(&functions); functions.GetString = _GetString; functions.UpdateState = _UpdateState; functions.GetBufferSize = NULL; functions.Error = _Error; functions.Viewport = _Viewport; functions.Flush = _Flush; // create core context #if HAIKU_MESA_VER <= 708 fContext = _mesa_create_context(fVisual, NULL, &functions, this); #else fContext = _mesa_create_context(API_OPENGL, fVisual, NULL, &functions, this); #endif if (!fContext) { ERROR("%s: Failed to create Mesa context!\n", __func__); _mesa_destroy_visual(fVisual); return; } /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext(fContext); _vbo_CreateContext(fContext); _tnl_CreateContext(fContext); _swsetup_CreateContext(fContext); _swsetup_Wakeup(fContext); // Use default TCL pipeline TNL_CONTEXT(fContext)->Driver.RunPipeline = _tnl_run_pipeline; _mesa_meta_init(fContext); _mesa_enable_sw_extensions(fContext); _mesa_enable_1_3_extensions(fContext); _mesa_enable_1_4_extensions(fContext); _mesa_enable_1_5_extensions(fContext); _mesa_enable_2_0_extensions(fContext); _mesa_enable_2_1_extensions(fContext); // create core framebuffer fFrameBuffer = (struct msr_framebuffer*)calloc(1, sizeof(*fFrameBuffer)); if (fFrameBuffer == NULL) { ERROR("%s: Unable to calloc GL FrameBuffer!\n", __func__); _mesa_destroy_visual(fVisual); return; } _mesa_initialize_window_framebuffer(&fFrameBuffer->base, fVisual); // Setup front render buffer fFrontRenderBuffer = _NewRenderBuffer(true); if (fFrontRenderBuffer == NULL) { ERROR("%s: FrontRenderBuffer is requested but unallocated!\n", __func__); _mesa_destroy_visual(fVisual); free(fFrameBuffer); return; } _mesa_add_renderbuffer(&fFrameBuffer->base, BUFFER_FRONT_LEFT, &fFrontRenderBuffer->base); // Setup back render buffer (if requested) if (fVisual->doubleBufferMode) { fBackRenderBuffer = _NewRenderBuffer(false); if (fBackRenderBuffer == NULL) { ERROR("%s: BackRenderBuffer is requested but unallocated!\n", __func__); _mesa_destroy_visual(fVisual); free(fFrameBuffer); return; } _mesa_add_renderbuffer(&fFrameBuffer->base, BUFFER_BACK_LEFT, &fBackRenderBuffer->base); } #if HAIKU_MESA_VER >= 709 // New Mesa _swrast_add_soft_renderbuffers(&fFrameBuffer->base, GL_FALSE, fVisual->haveDepthBuffer, fVisual->haveStencilBuffer, fVisual->haveAccumBuffer, alphaFlag, GL_FALSE); #else // Old Mesa _mesa_add_soft_renderbuffers(&fFrameBuffer->base, GL_FALSE, fVisual->haveDepthBuffer, fVisual->haveStencilBuffer, fVisual->haveAccumBuffer, alphaFlag, GL_FALSE); #endif BRect bounds = view->Bounds(); fWidth = fNewWidth = (GLint)bounds.Width(); fHeight = fNewHeight = (GLint)bounds.Height(); // some stupid applications (Quake2) don't even think about calling LockGL() // before using glGetString and its glGet*() friends... // so make sure there is at least a valid context. if (!_mesa_get_current_context()) { LockGL(); // not needed, we don't have a looper yet: UnlockLooper(); } }