Skip to content

Commit

Permalink
webgl: Detach RBs and textures from the bound FBO on deletion.
Browse files Browse the repository at this point in the history
This is part of general GL behavior: when an object is deleted, look
through the currently bound objects and detach the deleted object from
them.  Detaching an object from an FBO causes it to need to be
re-checked for its status.
  • Loading branch information
anholt committed Oct 26, 2016
1 parent 6c10d5c commit dba7d5e
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 0 deletions.
44 changes: 44 additions & 0 deletions components/script/dom/webglframebuffer.rs
Expand Up @@ -231,6 +231,7 @@ impl WebGLFramebuffer {

_ => {
*binding.borrow_mut() = None;
self.update_status();
None
}
};
Expand All @@ -245,6 +246,49 @@ impl WebGLFramebuffer {
Ok(())
}

pub fn detach_renderbuffer(&self, rb: &WebGLRenderbuffer) {
let attachments = [&self.color,
&self.depth,
&self.stencil,
&self.depthstencil];

for attachment in &attachments {
let matched = {
match *attachment.borrow() {
Some(WebGLFramebufferAttachment::Renderbuffer(ref att_rb))
if rb.id() == att_rb.id() => true,
_ => false,
}
};

if matched {
*attachment.borrow_mut() = None;
self.update_status();
}
}
}

pub fn detach_texture(&self, texture: &WebGLTexture) {
let attachments = [&self.color,
&self.depth,
&self.stencil,
&self.depthstencil];

for attachment in &attachments {
let matched = {
match *attachment.borrow() {
Some(WebGLFramebufferAttachment::Texture(ref att_texture))
if texture.id() == att_texture.id() => true,
_ => false,
}
};

if matched {
*attachment.borrow_mut() = None;
}
}
}

pub fn target(&self) -> Option<u32> {
self.target.get()
}
Expand Down
26 changes: 26 additions & 0 deletions components/script/dom/webglrenderingcontext.rs
Expand Up @@ -1280,6 +1280,20 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
if let Some(renderbuffer) = renderbuffer {
handle_object_deletion!(self, self.bound_renderbuffer, renderbuffer,
Some(WebGLCommand::BindRenderbuffer(constants::RENDERBUFFER, None)));
// From the GLES 2.0.25 spec, page 113:
//
// "If a renderbuffer object is deleted while its
// image is attached to the currently bound
// framebuffer, then it is as if
// FramebufferRenderbuffer had been called, with a
// renderbuffer of 0, for each attachment point to
// which this image was attached in the currently
// bound framebuffer."
//
if let Some(fb) = self.bound_framebuffer.get() {
fb.detach_renderbuffer(renderbuffer);
}

renderbuffer.delete()
}
}
Expand All @@ -1291,6 +1305,18 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
Some(WebGLCommand::BindTexture(constants::TEXTURE_2D, None)));
handle_object_deletion!(self, self.bound_texture_cube_map, texture,
Some(WebGLCommand::BindTexture(constants::TEXTURE_CUBE_MAP, None)));

// From the GLES 2.0.25 spec, page 113:
//
// "If a texture object is deleted while its image is
// attached to the currently bound framebuffer, then
// it is as if FramebufferTexture2D had been called,
// with a texture of 0, for each attachment point to
// which this image was attached in the currently
// bound framebuffer."
if let Some(fb) = self.bound_framebuffer.get() {
fb.detach_texture(texture);
}
texture.delete()
}
}
Expand Down
Expand Up @@ -165,3 +165,81 @@
[WebGL test #227: at (0, 0) expected: 0,255,0,255 was 255,0,0,255]
expected: FAIL

[WebGL test #168: gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) should be [object WebGLRenderbuffer\]. Threw exception TypeError: gl.getFramebufferAttachmentParameter is not a function]
expected: FAIL

[WebGL test #170: gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) threw exception TypeError: gl.getFramebufferAttachmentParameter is not a function]
expected: FAIL

[WebGL test #171: gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) threw exception TypeError: gl.getFramebufferAttachmentParameter is not a function]
expected: FAIL

[WebGL test #187: gl.checkFramebufferStatus(gl.FRAMEBUFFER) should not be 36053.]
expected: FAIL

[WebGL test #196: gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) should be [object WebGLTexture\]. Threw exception TypeError: gl.getFramebufferAttachmentParameter is not a function]
expected: FAIL

[WebGL test #198: gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) threw exception TypeError: gl.getFramebufferAttachmentParameter is not a function]
expected: FAIL

[WebGL test #199: gl.checkFramebufferStatus(gl.FRAMEBUFFER) should not be 36053.]
expected: FAIL

[WebGL test #210: gl.getParameter(gl.ARRAY_BUFFER_BINDING) should be null. Was [object WebGLBuffer\].]
expected: FAIL

[WebGL test #219: gl.getParameter(gl.ARRAY_BUFFER_BINDING) should be null. Was [object WebGLBuffer\].]
expected: FAIL

[WebGL test #227: gl.getParameter(gl.ELEMENT_ARRAY_BUFFER_BINDING) should be null. Was [object WebGLBuffer\].]
expected: FAIL

[WebGL test #230: gl.bufferData(gl.ARRAY_BUFFER, 1, gl.STATIC_DRAW) threw exception TypeError: Value is not an object.]
expected: FAIL

[WebGL test #233: gl.bufferData(gl.ARRAY_BUFFER, 1, gl.STATIC_DRAW) threw exception TypeError: Value is not an object.]
expected: FAIL

[WebGL test #244: gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING) should be [object WebGLBuffer\]. Was null.]
expected: FAIL

[WebGL test #245: gl.getVertexAttrib(2, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING) should be [object WebGLBuffer\]. Was null.]
expected: FAIL

[WebGL test #246: gl.getVertexAttrib(3, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING) should be [object WebGLBuffer\]. Was null.]
expected: FAIL

[WebGL test #247: getError expected: NO_ERROR. Was INVALID_ENUM : after evaluating: gl.deleteBuffer(b2);]
expected: FAIL

[WebGL test #248: gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING) should be [object WebGLBuffer\]. Was null.]
expected: FAIL

[WebGL test #251: getError expected: NO_ERROR. Was INVALID_ENUM : after evaluating: gl.deleteBuffer(b1);]
expected: FAIL

[WebGL test #253: getError expected: NO_ERROR. Was INVALID_ENUM : after evaluating: gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)]
expected: FAIL

[WebGL test #281: at (0, 0) expected: 255,0,0,255 was 0,0,0,0]
expected: FAIL

[WebGL test #289: at (16, 0) expected: 0,255,0,255 was 0,0,0,0]
expected: FAIL

[WebGL test #292: at (0, 0) expected: 0,255,0,255 was 255,0,0,255]
expected: FAIL

[WebGL test #258: getError expected: NO_ERROR. Was INVALID_OPERATION : after evaluating: gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)]
expected: FAIL

[WebGL test #278: at (16, 16) expected: 0,0,0,0 was 9,0,0,0]
expected: FAIL

[WebGL test #281: at (0, 0) expected: 255,0,0,255 was 0,0,0,255]
expected: FAIL

[WebGL test #289: at (16, 0) expected: 0,255,0,255 was 0,0,0,14]
expected: FAIL

0 comments on commit dba7d5e

Please sign in to comment.