aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2016-09-18 13:17:41 +0100
committerEric Anholt <eric@anholt.net>2016-10-25 22:19:26 -0700
commitdba7d5eb51b5eb433f47a948f66df77920b06191 (patch)
treefabceedf764f49742c3cf7b8779604e52fc2b407
parent6c10d5ca75d8d6064fa36c3ec3309fdd54e5f1c7 (diff)
downloadservo-dba7d5eb51b5eb433f47a948f66df77920b06191.tar.gz
servo-dba7d5eb51b5eb433f47a948f66df77920b06191.zip
webgl: Detach RBs and textures from the bound FBO on deletion.
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.
-rw-r--r--components/script/dom/webglframebuffer.rs44
-rw-r--r--components/script/dom/webglrenderingcontext.rs26
-rw-r--r--tests/wpt/metadata/webgl/conformance-1.0.3/conformance/misc/object-deletion-behaviour.html.ini78
3 files changed, 148 insertions, 0 deletions
diff --git a/components/script/dom/webglframebuffer.rs b/components/script/dom/webglframebuffer.rs
index 4dddfb047a0..0211a0bc31f 100644
--- a/components/script/dom/webglframebuffer.rs
+++ b/components/script/dom/webglframebuffer.rs
@@ -231,6 +231,7 @@ impl WebGLFramebuffer {
_ => {
*binding.borrow_mut() = None;
+ self.update_status();
None
}
};
@@ -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()
}
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs
index 59f27aa3139..b67f524825f 100644
--- a/components/script/dom/webglrenderingcontext.rs
+++ b/components/script/dom/webglrenderingcontext.rs
@@ -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()
}
}
@@ -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()
}
}
diff --git a/tests/wpt/metadata/webgl/conformance-1.0.3/conformance/misc/object-deletion-behaviour.html.ini b/tests/wpt/metadata/webgl/conformance-1.0.3/conformance/misc/object-deletion-behaviour.html.ini
index 70c044382d1..8e2be3e1863 100644
--- a/tests/wpt/metadata/webgl/conformance-1.0.3/conformance/misc/object-deletion-behaviour.html.ini
+++ b/tests/wpt/metadata/webgl/conformance-1.0.3/conformance/misc/object-deletion-behaviour.html.ini
@@ -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
+