Bug 685184 - Delay attachment of RBs to FBs. - r=bjacob

This commit is contained in:
Jeff Gilbert 2013-10-01 17:30:05 -07:00
parent 1855d7c9a6
commit 664751db15
4 changed files with 71 additions and 49 deletions

View File

@ -325,6 +325,10 @@ WebGLContext::CheckFramebufferStatus(GLenum target)
return LOCAL_GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
if(mBoundFramebuffer->HasAttachmentsOfMismatchedDimensions())
return LOCAL_GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
// Ok, attach our chosen flavor of {DEPTH, STENCIL, DEPTH_STENCIL}.
mBoundFramebuffer->FinalizeAttachments();
return gl->fCheckFramebufferStatus(target);
}
@ -2288,7 +2292,7 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width,
// now, same computation as above to find the size of the intermediate buffer to allocate for the subrect
// no need to check again for integer overflow here, since we already know the sizes aren't greater than before
uint32_t subrect_plainRowSize = subrect_width * bytesPerPixel;
// There are checks above to ensure that this doesn't overflow.
// There are checks above to ensure that this doesn't overflow.
uint32_t subrect_alignedRowSize =
RoundedToNextMultipleOf(subrect_plainRowSize, mPixelStorePackAlignment).value();
uint32_t subrect_byteLength = (subrect_height-1)*subrect_alignedRowSize + subrect_plainRowSize;

View File

@ -14,6 +14,7 @@
#include "GLContext.h"
using namespace mozilla;
using namespace mozilla::gl;
JSObject*
WebGLFramebuffer::WrapObject(JSContext *cx, JS::Handle<JSObject*> scope) {
@ -58,9 +59,10 @@ WebGLFramebuffer::Attachment::HasAlpha() const {
}
void
WebGLFramebuffer::Attachment::SetTexture(WebGLTexture *tex, GLint level, GLenum face) {
WebGLFramebuffer::Attachment::SetTexture(WebGLTexture *tex, GLenum target, GLint level, GLenum face) {
mTexturePtr = tex;
mRenderbufferPtr = nullptr;
mTextureTarget = target;
mTextureLevel = level;
mTextureCubeMapFace = face;
}
@ -146,6 +148,26 @@ WebGLFramebuffer::Attachment::IsComplete() const {
return false;
}
void
WebGLFramebuffer::Attachment::FinalizeAttachment(GLenum attachmentLoc) const {
if (Texture()) {
GLContext* gl = Texture()->Context()->gl;
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, attachmentLoc,
TextureTarget(), Texture()->GLName(), TextureLevel());
return;
}
if (Renderbuffer()) {
GLContext* gl = Renderbuffer()->Context()->gl;
gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, attachmentLoc,
LOCAL_GL_RENDERBUFFER, Renderbuffer()->GLName());
return;
}
// Neither?
MOZ_ASSERT(false, "FB attachment without a tex or RB.");
}
void
WebGLFramebuffer::Delete() {
mColorAttachments.Clear();
@ -196,25 +218,6 @@ WebGLFramebuffer::FramebufferRenderbuffer(GLenum target,
mColorAttachments[colorAttachmentId].SetRenderbuffer(wrb);
break;
}
mContext->MakeContextCurrent();
GLuint parambuffername = wrb ? wrb->GLName() : 0;
if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
GLuint depthbuffername = parambuffername;
GLuint stencilbuffername = parambuffername;
if (!parambuffername){
depthbuffername = mDepthAttachment.Renderbuffer() ? mDepthAttachment.Renderbuffer()->GLName() : 0;
stencilbuffername = mStencilAttachment.Renderbuffer() ? mStencilAttachment.Renderbuffer()->GLName() : 0;
}
mContext->gl->fFramebufferRenderbuffer(target, LOCAL_GL_DEPTH_ATTACHMENT, rbtarget, depthbuffername);
mContext->gl->fFramebufferRenderbuffer(target, LOCAL_GL_STENCIL_ATTACHMENT, rbtarget, stencilbuffername);
} else {
GLuint renderbuffername = parambuffername;
if(!parambuffername && (attachment == LOCAL_GL_DEPTH_ATTACHMENT || attachment == LOCAL_GL_STENCIL_ATTACHMENT)){
renderbuffername = mDepthStencilAttachment.Renderbuffer() ? mDepthStencilAttachment.Renderbuffer()->GLName() : 0;
}
mContext->gl->fFramebufferRenderbuffer(target, attachment, rbtarget, renderbuffername);
}
}
void
@ -245,13 +248,13 @@ WebGLFramebuffer::FramebufferTexture2D(GLenum target,
size_t face = WebGLTexture::FaceForTarget(textarget);
switch (attachment) {
case LOCAL_GL_DEPTH_ATTACHMENT:
mDepthAttachment.SetTexture(wtex, level, face);
mDepthAttachment.SetTexture(wtex, textarget, level, face);
break;
case LOCAL_GL_STENCIL_ATTACHMENT:
mStencilAttachment.SetTexture(wtex, level, face);
mStencilAttachment.SetTexture(wtex, textarget, level, face);
break;
case LOCAL_GL_DEPTH_STENCIL_ATTACHMENT:
mDepthStencilAttachment.SetTexture(wtex, level, face);
mDepthStencilAttachment.SetTexture(wtex, textarget, level, face);
break;
default:
if (!CheckColorAttachementNumber(attachment, "framebufferTexture2D")){
@ -260,30 +263,9 @@ WebGLFramebuffer::FramebufferTexture2D(GLenum target,
size_t colorAttachmentId = size_t(attachment - LOCAL_GL_COLOR_ATTACHMENT0);
EnsureColorAttachments(colorAttachmentId);
mColorAttachments[colorAttachmentId].SetTexture(wtex, level, face);
mColorAttachments[colorAttachmentId].SetTexture(wtex, textarget, level, face);
break;
}
mContext->MakeContextCurrent();
GLuint paramtexturename = wtex ? wtex->GLName() : 0;
if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
GLuint depthtexturename = paramtexturename;
GLuint stenciltexturename = paramtexturename;
if(!paramtexturename){
depthtexturename = mDepthAttachment.Texture() ? mDepthAttachment.Texture()->GLName() : 0;
stenciltexturename = mStencilAttachment.Texture() ? mStencilAttachment.Texture()->GLName() : 0;
}
mContext->gl->fFramebufferTexture2D(target, LOCAL_GL_DEPTH_ATTACHMENT, textarget, depthtexturename, level);
mContext->gl->fFramebufferTexture2D(target, LOCAL_GL_STENCIL_ATTACHMENT, textarget, stenciltexturename, level);
} else {
GLuint texturename = paramtexturename;
if(!paramtexturename && (attachment == LOCAL_GL_DEPTH_ATTACHMENT || attachment == LOCAL_GL_STENCIL_ATTACHMENT)){
texturename = mDepthStencilAttachment.Texture() ? mDepthStencilAttachment.Texture()->GLName() : 0;
}
mContext->gl->fFramebufferTexture2D(target, attachment, textarget, texturename, level);
}
return;
}
bool
@ -421,6 +403,9 @@ WebGLFramebuffer::CheckAndInitializeRenderbuffers()
mContext->MakeContextCurrent();
// Ok, attach our chosen flavor of {DEPTH, STENCIL, DEPTH_STENCIL}.
FinalizeAttachments();
GLenum status = mContext->CheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE)
return false;
@ -520,6 +505,25 @@ void WebGLFramebuffer::EnsureColorAttachments(size_t colorAttachmentId) {
}
}
void
WebGLFramebuffer::FinalizeAttachments() const {
for (size_t i = 0; i < ColorAttachmentCount(); i++) {
if (ColorAttachment(i).IsDefined())
ColorAttachment(i).FinalizeAttachment(LOCAL_GL_COLOR_ATTACHMENT0 + i);
}
if (DepthAttachment().IsDefined())
DepthAttachment().FinalizeAttachment(LOCAL_GL_DEPTH_ATTACHMENT);
if (StencilAttachment().IsDefined())
StencilAttachment().FinalizeAttachment(LOCAL_GL_STENCIL_ATTACHMENT);
if (DepthStencilAttachment().IsDefined()) {
DepthStencilAttachment().FinalizeAttachment(LOCAL_GL_DEPTH_ATTACHMENT);
DepthStencilAttachment().FinalizeAttachment(LOCAL_GL_STENCIL_ATTACHMENT);
}
}
inline void
ImplCycleCollectionUnlink(mozilla::WebGLFramebuffer::Attachment& aField)
{

View File

@ -16,6 +16,9 @@ namespace mozilla {
class WebGLTexture;
class WebGLRenderbuffer;
namespace gl {
class GLContext;
}
class WebGLFramebuffer MOZ_FINAL
: public nsWrapperCache
@ -37,6 +40,7 @@ public:
WebGLRefPtr<WebGLRenderbuffer> mRenderbufferPtr;
GLenum mAttachmentPoint;
GLint mTextureLevel;
GLenum mTextureTarget;
GLenum mTextureCubeMapFace;
Attachment(GLenum aAttachmentPoint = LOCAL_GL_COLOR_ATTACHMENT0)
@ -51,7 +55,7 @@ public:
bool HasAlpha() const;
void SetTexture(WebGLTexture *tex, GLint level, GLenum face);
void SetTexture(WebGLTexture *tex, GLenum target, GLint level, GLenum face);
void SetRenderbuffer(WebGLRenderbuffer *rb) {
mTexturePtr = nullptr;
mRenderbufferPtr = rb;
@ -68,6 +72,9 @@ public:
WebGLRenderbuffer *Renderbuffer() {
return mRenderbufferPtr;
}
GLenum TextureTarget() const {
return mTextureTarget;
}
GLint TextureLevel() const {
return mTextureLevel;
}
@ -86,6 +93,8 @@ public:
bool HasSameDimensionsAs(const Attachment& other) const;
bool IsComplete() const;
void FinalizeAttachment(GLenum attachmentLoc) const;
};
void Delete();
@ -115,6 +124,9 @@ public:
bool HasAttachmentsOfMismatchedDimensions() const;
const size_t ColorAttachmentCount() const {
return mColorAttachments.Length();
}
const Attachment& ColorAttachment(uint32_t colorAttachmentId) const {
return mColorAttachments[colorAttachmentId];
}
@ -145,6 +157,8 @@ public:
return Context();
}
void FinalizeAttachments() const;
virtual JSObject* WrapObject(JSContext *cx,
JS::Handle<JSObject*> scope) MOZ_OVERRIDE;

View File

@ -38,9 +38,9 @@ public:
void Delete();
bool HasEverBeenBound() { return mHasEverBeenBound; }
bool HasEverBeenBound() const { return mHasEverBeenBound; }
void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; }
GLuint GLName() { return mGLName; }
GLuint GLName() const { return mGLName; }
GLenum Target() const { return mTarget; }
WebGLContext *GetParentObject() const {