📄 renderbuffer.c
字号:
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; /* the RGB buffer to wrap must already exist!! */ assert(fb->Attachment[b].Renderbuffer); /* only GLubyte supported for now */ assert(fb->Attachment[b].Renderbuffer->DataType == GL_UNSIGNED_BYTE); /* allocate alpha renderbuffer */ arb = _mesa_new_renderbuffer(ctx, 0); if (!arb) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating alpha buffer"); return GL_FALSE; } /* wrap the alpha renderbuffer around the RGB renderbuffer */ arb->Wrapped = fb->Attachment[b].Renderbuffer; /* Set up my alphabuffer fields and plug in my functions. * The functions will put/get the alpha values from/to RGBA arrays * and then call the wrapped buffer's functions to handle the RGB * values. */ arb->InternalFormat = arb->Wrapped->InternalFormat; arb->_ActualFormat = GL_ALPHA8; arb->_BaseFormat = arb->Wrapped->_BaseFormat; arb->DataType = arb->Wrapped->DataType; arb->AllocStorage = alloc_storage_alpha8; arb->Delete = delete_renderbuffer_alpha8; arb->GetPointer = get_pointer_alpha8; arb->GetRow = get_row_alpha8; arb->GetValues = get_values_alpha8; arb->PutRow = put_row_alpha8; arb->PutRowRGB = put_row_rgb_alpha8; arb->PutMonoRow = put_mono_row_alpha8; arb->PutValues = put_values_alpha8; arb->PutMonoValues = put_mono_values_alpha8; /* clear the pointer to avoid assertion/sanity check failure later */ fb->Attachment[b].Renderbuffer = NULL; /* plug the alpha renderbuffer into the colorbuffer attachment */ _mesa_add_renderbuffer(fb, b, arb); } return GL_TRUE;}/** * For framebuffers that use a software alpha channel wrapper * created by _mesa_add_alpha_renderbuffer or _mesa_add_soft_renderbuffers, * copy the back buffer alpha channel into the front buffer alpha channel. */void_mesa_copy_soft_alpha_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb){ if (fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer && fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer) copy_buffer_alpha8(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer, fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer); if (fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer && fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer) copy_buffer_alpha8(fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer, fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer);}/** * 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! */GLboolean_mesa_add_depth_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb, GLuint depthBits){ struct gl_renderbuffer *rb; if (depthBits > 32) { _mesa_problem(ctx, "Unsupported depthBits in _mesa_add_depth_renderbuffer"); return GL_FALSE; } assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL); rb = _mesa_new_renderbuffer(ctx, 0); if (!rb) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth buffer"); return GL_FALSE; } if (depthBits <= 16) { rb->_ActualFormat = GL_DEPTH_COMPONENT16; } else if (depthBits <= 24) { rb->_ActualFormat = GL_DEPTH_COMPONENT24; } else { rb->_ActualFormat = GL_DEPTH_COMPONENT32; } rb->InternalFormat = rb->_ActualFormat; rb->AllocStorage = _mesa_soft_renderbuffer_storage; _mesa_add_renderbuffer(fb, BUFFER_DEPTH, 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! */GLboolean_mesa_add_stencil_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb, GLuint stencilBits){ struct gl_renderbuffer *rb; if (stencilBits > 16) { _mesa_problem(ctx, "Unsupported stencilBits in _mesa_add_stencil_renderbuffer"); return GL_FALSE; } assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL); rb = _mesa_new_renderbuffer(ctx, 0); if (!rb) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating stencil buffer"); return GL_FALSE; } if (stencilBits <= 8) { rb->_ActualFormat = GL_STENCIL_INDEX8_EXT; } else { /* not really supported (see s_stencil.c code) */ rb->_ActualFormat = GL_STENCIL_INDEX16_EXT; } rb->InternalFormat = rb->_ActualFormat; rb->AllocStorage = _mesa_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! */GLboolean_mesa_add_accum_renderbuffer(GLcontext *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 _mesa_add_accum_renderbuffer"); return GL_FALSE; } assert(fb->Attachment[BUFFER_ACCUM].Renderbuffer == NULL); rb = _mesa_new_renderbuffer(ctx, 0); if (!rb) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer"); return GL_FALSE; } rb->_ActualFormat = GL_RGBA16; rb->InternalFormat = GL_RGBA16; rb->AllocStorage = _mesa_soft_renderbuffer_storage; _mesa_add_renderbuffer(fb, BUFFER_ACCUM, 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! * * NOTE: color-index aux buffers not supported. */GLboolean_mesa_add_aux_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb, GLuint colorBits, GLuint numBuffers){ GLuint i; if (colorBits > 16) { _mesa_problem(ctx, "Unsupported accumBits in _mesa_add_aux_renderbuffers"); return GL_FALSE; } assert(numBuffers < MAX_AUX_BUFFERS); for (i = 0; i < numBuffers; i++) { struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, 0); assert(fb->Attachment[BUFFER_AUX0 + i].Renderbuffer == NULL); if (!rb) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer"); return GL_FALSE; } if (colorBits <= 8) { rb->_ActualFormat = GL_RGBA8; } else { rb->_ActualFormat = GL_RGBA16; } rb->InternalFormat = rb->_ActualFormat; rb->AllocStorage = _mesa_soft_renderbuffer_storage; _mesa_add_renderbuffer(fb, BUFFER_AUX0 + i, rb); } return GL_TRUE;}/** * Create/attach software-based renderbuffers to the given framebuffer. * This is a helper routine for device drivers. Drivers can just as well * call the individual _mesa_add_*_renderbuffer() routines directly. */void_mesa_add_soft_renderbuffers(struct gl_framebuffer *fb, GLboolean color, GLboolean depth, GLboolean stencil, GLboolean accum, GLboolean alpha, GLboolean aux){ GLboolean frontLeft = GL_TRUE; GLboolean backLeft = fb->Visual.doubleBufferMode; GLboolean frontRight = fb->Visual.stereoMode; GLboolean backRight = fb->Visual.stereoMode && fb->Visual.doubleBufferMode; if (color) { if (fb->Visual.rgbMode) { assert(fb->Visual.redBits == fb->Visual.greenBits); assert(fb->Visual.redBits == fb->Visual.blueBits); _mesa_add_color_renderbuffers(NULL, fb, fb->Visual.redBits, fb->Visual.alphaBits, frontLeft, backLeft, frontRight, backRight); } else { _mesa_add_color_index_renderbuffers(NULL, fb, fb->Visual.indexBits, frontLeft, backLeft, frontRight, backRight); } } if (depth) { assert(fb->Visual.depthBits > 0); _mesa_add_depth_renderbuffer(NULL, fb, fb->Visual.depthBits); } if (stencil) { assert(fb->Visual.stencilBits > 0); _mesa_add_stencil_renderbuffer(NULL, fb, fb->Visual.stencilBits); } if (accum) { assert(fb->Visual.rgbMode); assert(fb->Visual.accumRedBits > 0); assert(fb->Visual.accumGreenBits > 0); assert(fb->Visual.accumBlueBits > 0); _mesa_add_accum_renderbuffer(NULL, fb, fb->Visual.accumRedBits, fb->Visual.accumGreenBits, fb->Visual.accumBlueBits, fb->Visual.accumAlphaBits); } if (aux) { assert(fb->Visual.rgbMode); assert(fb->Visual.numAuxBuffers > 0); _mesa_add_aux_renderbuffers(NULL, fb, fb->Visual.redBits, fb->Visual.numAuxBuffers); } if (alpha) { assert(fb->Visual.rgbMode); assert(fb->Visual.alphaBits > 0); _mesa_add_alpha_renderbuffers(NULL, fb, fb->Visual.alphaBits, frontLeft, backLeft, frontRight, backRight); }#if 0 if (multisample) { /* maybe someday */ }#endif}/** * Attach a renderbuffer to a framebuffer. */void_mesa_add_renderbuffer(struct gl_framebuffer *fb, GLuint bufferName, struct gl_renderbuffer *rb){ assert(fb); assert(rb); assert(bufferName < BUFFER_COUNT); /* There should be no previous renderbuffer on this attachment point, * with the exception of depth/stencil since the same renderbuffer may * be used for both. */ assert(bufferName == BUFFER_DEPTH || bufferName == BUFFER_STENCIL || fb->Attachment[bufferName].Renderbuffer == NULL); /* winsys vs. user-created buffer cross check */ if (fb->Name) { assert(rb->Name); } else { assert(!rb->Name); } /* If Mesa's compiled with deep color channels (16 or 32 bits / channel) * and the device driver is expecting 8-bit values (GLubyte), we can * use a "renderbuffer adaptor/wrapper" to do the necessary conversions. */ if (rb->_BaseFormat == GL_RGBA) { if (CHAN_BITS == 16 && rb->DataType == GL_UNSIGNED_BYTE) { GET_CURRENT_CONTEXT(ctx); rb = _mesa_new_renderbuffer_16wrap8(ctx, rb); } else if (CHAN_BITS == 32 && rb->DataType == GL_UNSIGNED_BYTE) { GET_CURRENT_CONTEXT(ctx); rb = _mesa_new_renderbuffer_32wrap8(ctx, rb); } else if (CHAN_BITS == 32 && rb->DataType == GL_UNSIGNED_SHORT) { GET_CURRENT_CONTEXT(ctx); rb = _mesa_new_renderbuffer_32wrap16(ctx, rb); } } fb->Attachment[bufferName].Type = GL_RENDERBUFFER_EXT; fb->Attachment[bufferName].Complete = GL_TRUE; _mesa_reference_renderbuffer(&fb->Attachment[bufferName].Renderbuffer, rb);}/** * Remove the named renderbuffer from the given framebuffer. */void_mesa_remove_renderbuffer(struct gl_framebuffer *fb, GLuint bufferName){ struct gl_renderbuffer *rb; assert(bufferName < BUFFER_COUNT); rb = fb->Attachment[bufferName].Renderbuffer; if (!rb) return; _mesa_reference_renderbuffer(&rb, NULL); fb->Attachment[bufferName].Renderbuffer = NULL;}/** * Set *ptr to point to rb. If *ptr points to another renderbuffer, * dereference that buffer first. The new renderbuffer's refcount will * be incremented. The old renderbuffer's refcount will be decremented. */void_mesa_reference_renderbuffer(struct gl_renderbuffer **ptr, struct gl_renderbuffer *rb){ assert(ptr); if (*ptr == rb) { /* no change */ return; } if (*ptr) { /* Unreference the old renderbuffer */ GLboolean deleteFlag = GL_FALSE; struct gl_renderbuffer *oldRb = *ptr; assert(oldRb->Magic == RB_MAGIC); _glthread_LOCK_MUTEX(o
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -