Bug 981240 - Finalize null attachments back to zero. - r=kamidphish
--- a/content/canvas/src/WebGLFramebuffer.cpp
+++ b/content/canvas/src/WebGLFramebuffer.cpp
@@ -91,16 +91,27 @@ WebGLFramebuffer::Attachment::IsReadable
void
WebGLFramebuffer::Attachment::SetTexImage(WebGLTexture* tex, GLenum target, GLint level)
{
mTexturePtr = tex;
mRenderbufferPtr = nullptr;
mTexImageTarget = target;
mTexImageLevel = level;
+
+ mNeedsFinalize = true;
+}
+
+void
+WebGLFramebuffer::Attachment::SetRenderbuffer(WebGLRenderbuffer* rb)
+{
+ mTexturePtr = nullptr;
+ mRenderbufferPtr = rb;
+
+ mNeedsFinalize = true;
}
bool
WebGLFramebuffer::Attachment::HasUninitializedImageData() const
{
if (!HasImage())
return false;
@@ -310,22 +321,41 @@ WebGLFramebuffer::Attachment::IsComplete
return false;
}
MOZ_ASSERT(false, "Should not get here.");
return false;
}
void
-WebGLFramebuffer::Attachment::FinalizeAttachment(GLenum attachmentLoc) const
+WebGLFramebuffer::Attachment::FinalizeAttachment(GLContext* gl, GLenum attachmentLoc) const
{
+ if (!mNeedsFinalize)
+ return;
+
+ mNeedsFinalize = false;
+
+ if (!HasImage()) {
+ if (attachmentLoc == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
+ gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_ATTACHMENT,
+ LOCAL_GL_RENDERBUFFER, 0);
+ gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_STENCIL_ATTACHMENT,
+ LOCAL_GL_RENDERBUFFER, 0);
+ } else {
+ gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, attachmentLoc,
+ LOCAL_GL_RENDERBUFFER, 0);
+ }
+
+ return;
+ }
MOZ_ASSERT(HasImage());
if (Texture()) {
- GLContext* gl = Texture()->Context()->gl;
+ MOZ_ASSERT(gl == Texture()->Context()->gl);
+
if (attachmentLoc == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_ATTACHMENT,
TexImageTarget(), Texture()->GLName(), TexImageLevel());
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_STENCIL_ATTACHMENT,
TexImageTarget(), Texture()->GLName(), TexImageLevel());
} else {
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, attachmentLoc,
TexImageTarget(), Texture()->GLName(), TexImageLevel());
@@ -827,32 +857,28 @@ FinalizeDrawAndReadBuffers(GLContext* aG
GLenum colorBufferSource = aColorBufferDefined ? LOCAL_GL_COLOR_ATTACHMENT0 : LOCAL_GL_NONE;
aGL->fDrawBuffer(colorBufferSource);
aGL->fReadBuffer(colorBufferSource);
}
void
WebGLFramebuffer::FinalizeAttachments() const
{
+ GLContext* gl = mContext->gl;
+
size_t count = ColorAttachmentCount();
for (size_t i = 0; i < count; i++) {
- if (ColorAttachment(i).IsDefined())
- ColorAttachment(i).FinalizeAttachment(LOCAL_GL_COLOR_ATTACHMENT0 + i);
+ ColorAttachment(i).FinalizeAttachment(gl, LOCAL_GL_COLOR_ATTACHMENT0 + i);
}
- if (DepthAttachment().IsDefined())
- DepthAttachment().FinalizeAttachment(LOCAL_GL_DEPTH_ATTACHMENT);
+ DepthAttachment().FinalizeAttachment(gl, LOCAL_GL_DEPTH_ATTACHMENT);
+ StencilAttachment().FinalizeAttachment(gl, LOCAL_GL_STENCIL_ATTACHMENT);
+ DepthStencilAttachment().FinalizeAttachment(gl, LOCAL_GL_DEPTH_STENCIL_ATTACHMENT);
- if (StencilAttachment().IsDefined())
- StencilAttachment().FinalizeAttachment(LOCAL_GL_STENCIL_ATTACHMENT);
-
- if (DepthStencilAttachment().IsDefined())
- DepthStencilAttachment().FinalizeAttachment(LOCAL_GL_DEPTH_STENCIL_ATTACHMENT);
-
- FinalizeDrawAndReadBuffers(mContext->gl, ColorAttachment(0).IsDefined());
+ FinalizeDrawAndReadBuffers(gl, ColorAttachment(0).IsDefined());
}
inline void
ImplCycleCollectionUnlink(mozilla::WebGLFramebuffer::Attachment& aField)
{
aField.mTexturePtr = nullptr;
aField.mRenderbufferPtr = nullptr;
}
--- a/content/canvas/src/WebGLFramebuffer.h
+++ b/content/canvas/src/WebGLFramebuffer.h
@@ -36,35 +36,35 @@ public:
struct Attachment
{
// deleting a texture or renderbuffer immediately detaches it
WebGLRefPtr<WebGLTexture> mTexturePtr;
WebGLRefPtr<WebGLRenderbuffer> mRenderbufferPtr;
GLenum mAttachmentPoint;
GLenum mTexImageTarget;
GLint mTexImageLevel;
+ mutable bool mNeedsFinalize;
Attachment(GLenum aAttachmentPoint = LOCAL_GL_COLOR_ATTACHMENT0)
: mAttachmentPoint(aAttachmentPoint)
+ , mNeedsFinalize(false)
{}
bool IsDefined() const {
return Texture() || Renderbuffer();
}
bool IsDeleteRequested() const;
bool HasAlpha() const;
bool IsReadableFloat() const;
void SetTexImage(WebGLTexture* tex, GLenum target, GLint level);
- void SetRenderbuffer(WebGLRenderbuffer* rb) {
- mTexturePtr = nullptr;
- mRenderbufferPtr = rb;
- }
+ void SetRenderbuffer(WebGLRenderbuffer* rb);
+
const WebGLTexture* Texture() const {
return mTexturePtr;
}
WebGLTexture* Texture() {
return mTexturePtr;
}
const WebGLRenderbuffer* Renderbuffer() const {
return mRenderbufferPtr;
@@ -87,17 +87,17 @@ public:
mRenderbufferPtr = nullptr;
}
const WebGLRectangleObject& RectangleObject() const;
bool HasImage() const;
bool IsComplete() const;
- void FinalizeAttachment(GLenum attachmentLoc) const;
+ void FinalizeAttachment(gl::GLContext* gl, GLenum attachmentLoc) const;
};
void Delete();
bool HasEverBeenBound() { return mHasEverBeenBound; }
void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; }
GLuint GLName() { return mGLName; }