summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzmo@google.com <zmo@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>2011-12-19 23:03:02 (GMT)
committerzmo@google.com <zmo@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>2011-12-19 23:03:02 (GMT)
commit9def386340c74f2a745fb041b1cb11daa30d1a82 (patch)
treefa18d85656ef5d0b499ad9f216d678f9b9627123
parent9f8f78f71acb4370729a6cf70974a1628c6d40f7 (diff)
Postpone deleteRenderbuffer/deleteTexture until all framebuffer attachment points are removed.
https://bugs.webkit.org/show_bug.cgi?id=74741 Reviewed by Kenneth Russell. Source/WebCore: Use WebGLObject's attachment count mechanism to track if a renderbuffer/texture is still attached to framebuffers, and if its deletion should be delated or not. * html/canvas/WebGLFramebuffer.cpp: (WebCore::WebGLFramebuffer::setAttachmentForBoundFramebuffer): (WebCore::WebGLFramebuffer::getAttachment): (WebCore::WebGLFramebuffer::removeAttachmentFromBoundFramebuffer): (WebCore::WebGLFramebuffer::deleteObjectImpl): (WebCore::WebGLFramebuffer::isBound): * html/canvas/WebGLFramebuffer.h: LayoutTests: * fast/canvas/webgl/object-deletion-behaviour-expected.txt: * fast/canvas/webgl/object-deletion-behaviour.html: synced with khronos side. git-svn-id: http://svn.webkit.org/repository/webkit/trunk@103272 268f45cc-cd09-0410-ab3c-d52691b4dbfc
-rw-r--r--LayoutTests/ChangeLog10
-rw-r--r--LayoutTests/fast/canvas/webgl/object-deletion-behaviour-expected.txt232
-rw-r--r--LayoutTests/fast/canvas/webgl/object-deletion-behaviour.html291
-rw-r--r--Source/WebCore/ChangeLog18
-rw-r--r--Source/WebCore/html/canvas/WebGLFramebuffer.cpp108
-rw-r--r--Source/WebCore/html/canvas/WebGLFramebuffer.h13
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContext.cpp8
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContext.h1
8 files changed, 653 insertions, 28 deletions
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 8e6d34a..1956b6e 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,13 @@
+2011-12-16 Zhenyao Mo <zmo@google.com>
+
+ Postpone deleteRenderbuffer/deleteTexture until all framebuffer attachment points are removed.
+ https://bugs.webkit.org/show_bug.cgi?id=74741
+
+ Reviewed by Kenneth Russell.
+
+ * fast/canvas/webgl/object-deletion-behaviour-expected.txt:
+ * fast/canvas/webgl/object-deletion-behaviour.html: synced with khronos side.
+
2011-12-19 Adrienne Walker <enne@google.com>
[chromium] Rebaseline table-cell-collapsed-border after r103251.
diff --git a/LayoutTests/fast/canvas/webgl/object-deletion-behaviour-expected.txt b/LayoutTests/fast/canvas/webgl/object-deletion-behaviour-expected.txt
index a1f17a2..5452d3f 100644
--- a/LayoutTests/fast/canvas/webgl/object-deletion-behaviour-expected.txt
+++ b/LayoutTests/fast/canvas/webgl/object-deletion-behaviour-expected.txt
@@ -6,6 +6,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
shader and program deletion
PASS vertex shader loaded
PASS fragment shader loaded
+PASS program is non-null.
PASS gl.attachShader(program, vertexShader) was expected value: NO_ERROR.
PASS gl.attachShader(program, fragmentShader) was expected value: NO_ERROR.
PASS gl.linkProgram(program) was expected value: NO_ERROR.
@@ -27,11 +28,16 @@ PASS gl.isProgram(program) is false
PASS gl.isShader(fragmentShader) is false
texture deletion
+PASS fbo is non-null.
+PASS fbo2 is non-null.
+PASS fbo3 is non-null.
PASS gl.bindFramebuffer(gl.FRAMEBUFFER, fbo) was expected value: NO_ERROR.
+PASS tex is non-null.
PASS gl.bindTexture(gl.TEXTURE_2D, tex) was expected value: NO_ERROR.
PASS gl.getParameter(gl.TEXTURE_BINDING_2D) is tex
PASS gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0) was expected value: NO_ERROR.
PASS gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) is tex
+PASS gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) is gl.TEXTURE
PASS gl.deleteTexture(tex) was expected value: NO_ERROR.
PASS gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) is gl.NONE
PASS gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) was expected value: INVALID_ENUM.
@@ -39,6 +45,7 @@ PASS gl.isTexture(tex) is false
PASS gl.getParameter(gl.TEXTURE_BINDING_2D) is null
PASS gl.bindTexture(gl.TEXTURE_2D, tex) was expected value: NO_ERROR.
PASS gl.getParameter(gl.TEXTURE_BINDING_2D) is null
+PASS texCubeMap is non-null.
PASS gl.bindTexture(gl.TEXTURE_CUBE_MAP, texCubeMap) was expected value: NO_ERROR.
PASS gl.getParameter(gl.TEXTURE_BINDING_CUBE_MAP) is texCubeMap
PASS gl.deleteTexture(texCubeMap) was expected value: NO_ERROR.
@@ -46,8 +53,28 @@ PASS gl.isTexture(texCubeMap) is false
PASS gl.getParameter(gl.TEXTURE_BINDING_CUBE_MAP) is null
PASS gl.bindTexture(gl.TEXTURE_CUBE_MAP, texCubeMap) was expected value: NO_ERROR.
PASS gl.getParameter(gl.TEXTURE_BINDING_CUBE_MAP) is null
+PASS t is non-null.
+PASS gl.bindTexture(gl.TEXTURE_2D, t) was expected value: NO_ERROR.
+PASS gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE) was expected value: NO_ERROR.
+PASS gl.deleteTexture(t) was expected value: NO_ERROR.
+PASS gl.bindTexture(gl.TEXTURE_2D, t) was expected value: NO_ERROR.
+PASS gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE) was expected value: INVALID_OPERATION.
+PASS t2 is non-null.
+PASS gl.activeTexture(gl.TEXTURE0) was expected value: NO_ERROR.
+PASS gl.bindTexture(gl.TEXTURE_2D, t2) was expected value: NO_ERROR.
+PASS gl.getParameter(gl.TEXTURE_BINDING_2D) is t2
+PASS gl.activeTexture(gl.TEXTURE1) was expected value: NO_ERROR.
+PASS gl.bindTexture(gl.TEXTURE_2D, t2) was expected value: NO_ERROR.
+PASS gl.getParameter(gl.TEXTURE_BINDING_2D) is t2
+PASS gl.deleteTexture(t2) was expected value: NO_ERROR.
+PASS gl.getParameter(gl.TEXTURE_BINDING_2D) is null
+PASS gl.activeTexture(gl.TEXTURE0) was expected value: NO_ERROR.
+PASS gl.getParameter(gl.TEXTURE_BINDING_2D) is null
renderbuffer deletion
+PASS rbo is non-null.
+PASS rbo2 is non-null.
+PASS rbo3 is non-null.
PASS gl.bindRenderbuffer(gl.RENDERBUFFER, rbo) was expected value: NO_ERROR.
PASS gl.getParameter(gl.RENDERBUFFER_BINDING) is rbo
PASS gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo) was expected value: NO_ERROR.
@@ -59,8 +86,144 @@ PASS gl.isRenderbuffer(rbo) is false
PASS gl.getParameter(gl.RENDERBUFFER_BINDING) is null
PASS gl.bindRenderbuffer(gl.RENDERBUFFER, rbo) was expected value: NO_ERROR.
PASS gl.getParameter(gl.RENDERBUFFER_BINDING) is null
+PASS gl.bindRenderbuffer(gl.RENDERBUFFER, rbo2) was expected value: NO_ERROR.
+PASS gl.getParameter(gl.RENDERBUFFER_BINDING) is rbo2
+PASS gl.deleteRenderbuffer(rbo3) was expected value: NO_ERROR.
+PASS gl.getParameter(gl.RENDERBUFFER_BINDING) is rbo2
+
+using deleted renderbuffer
+PASS gl.bindRenderbuffer(gl.RENDERBUFFER, rbo) was expected value: NO_ERROR.
+PASS gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16) was expected value: NO_ERROR.
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, fbo) was expected value: NO_ERROR.
+PASS gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo) was expected value: NO_ERROR.
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, null) was expected value: NO_ERROR.
+PASS gl.clearColor(1,0,0,1) was expected value: NO_ERROR.
+PASS gl.clear(gl.COLOR_BUFFER_BIT) was expected value: NO_ERROR.
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, fbo) was expected value: NO_ERROR.
+PASS gl.clearColor(0,1,0,1) was expected value: NO_ERROR.
+PASS gl.clear(gl.COLOR_BUFFER_BIT) was expected value: NO_ERROR.
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, null) was expected value: NO_ERROR.
+PASS gl.deleteRenderbuffer(rbo) was expected value: NO_ERROR.
+PASS backbuffer should be red
+PASS wtu.checkCanvasRect(gl, 0, 0, 16, 16, [255,0,0,255], "backbuffer should be red") was expected value: NO_ERROR.
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, fbo) was expected value: NO_ERROR.
+PASS fbo should be green
+PASS wtu.checkCanvasRect(gl, 0, 0, 16, 16, [0,255,0,255], "fbo should be green") was expected value: NO_ERROR.
+PASS gl.clearColor(0,0,1,1) was expected value: NO_ERROR.
+PASS gl.clear(gl.COLOR_BUFFER_BIT) was expected value: NO_ERROR.
+PASS fbo should be blue
+PASS wtu.checkCanvasRect(gl, 0, 0, 16, 16, [0,0,255,255], "fbo should be blue") was expected value: NO_ERROR.
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, null) was expected value: NO_ERROR.
+PASS backbuffer should be red
+PASS wtu.checkCanvasRect(gl, 0, 0, 16, 16, [255,0,0,255], "backbuffer should be red") was expected value: NO_ERROR.
+
+renderbuffer attached twice to same framebuffer
+PASS gl.bindRenderbuffer(gl.RENDERBUFFER, rbo) was expected value: NO_ERROR.
+PASS gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16) was expected value: NO_ERROR.
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, fbo) was expected value: NO_ERROR.
+PASS gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo) was expected value: NO_ERROR.
+PASS gl.bindRenderbuffer(gl.RENDERBUFFER, rbo2) was expected value: NO_ERROR.
+PASS gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16) was expected value: NO_ERROR.
+PASS gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, rbo2) was expected value: NO_ERROR.
+PASS gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, rbo2) was expected value: NO_ERROR.
+PASS gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) is rbo2
+PASS gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) is rbo2
+PASS gl.checkFramebufferStatus(gl.FRAMEBUFFER) is not gl.FRAMEBUFFER_COMPLETE
+PASS gl.deleteRenderbuffer(rbo2) was expected value: NO_ERROR.
+PASS gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) is gl.NONE
+PASS gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) is gl.NONE
+PASS gl.checkFramebufferStatus(gl.FRAMEBUFFER) is gl.FRAMEBUFFER_COMPLETE
+PASS gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) is rbo
+PASS gl.deleteRenderbuffer(rbo) was expected value: NO_ERROR.
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, null) was expected value: NO_ERROR.
+
+using deleted texture
+PASS gl.bindTexture(gl.TEXTURE_2D, tex) was expected value: NO_ERROR.
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, fbo) was expected value: NO_ERROR.
+PASS gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0) was expected value: NO_ERROR.
+PASS gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null) was expected value: NO_ERROR.
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, fbo) was expected value: NO_ERROR.
+PASS gl.clearColor(0,1,0,1) was expected value: NO_ERROR.
+PASS gl.clear(gl.COLOR_BUFFER_BIT) was expected value: NO_ERROR.
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, null) was expected value: NO_ERROR.
+PASS gl.deleteTexture(tex) was expected value: NO_ERROR.
+PASS backbuffer should be red
+PASS wtu.checkCanvasRect(gl, 0, 0, 1, 1, [255,0,0,255], "backbuffer should be red") was expected value: NO_ERROR.
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, fbo) was expected value: NO_ERROR.
+PASS fbo should be green
+PASS wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0,255,0,255], "fbo should be green") was expected value: NO_ERROR.
+PASS gl.clearColor(0,0,1,1) was expected value: NO_ERROR.
+PASS gl.clear(gl.COLOR_BUFFER_BIT) was expected value: NO_ERROR.
+PASS fbo should be blue
+PASS wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0,0,255,255], "fbo should be blue") was expected value: NO_ERROR.
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, null) was expected value: NO_ERROR.
+PASS backbuffer should be red
+PASS wtu.checkCanvasRect(gl, 0, 0, 16, 16, [255,0,0,255], "backbuffer should be red") was expected value: NO_ERROR.
+
+using deleted renderbuffer
+PASS rbo is non-null.
+PASS gl.bindRenderbuffer(gl.RENDERBUFFER, rbo) was expected value: NO_ERROR.
+PASS gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16) was expected value: NO_ERROR.
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, fbo) was expected value: NO_ERROR.
+PASS gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo) was expected value: NO_ERROR.
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2) was expected value: NO_ERROR.
+PASS gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo) was expected value: NO_ERROR.
+PASS gl.checkFramebufferStatus(gl.FRAMEBUFFER) is gl.FRAMEBUFFER_COMPLETE
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, null) was expected value: NO_ERROR.
+PASS gl.clearColor(1,0,0,1) was expected value: NO_ERROR.
+PASS gl.clear(gl.COLOR_BUFFER_BIT) was expected value: NO_ERROR.
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, fbo) was expected value: NO_ERROR.
+PASS gl.clearColor(0,1,0,1) was expected value: NO_ERROR.
+PASS gl.clear(gl.COLOR_BUFFER_BIT) was expected value: NO_ERROR.
+PASS gl.deleteRenderbuffer(rbo) was expected value: NO_ERROR.
+PASS gl.checkFramebufferStatus(gl.FRAMEBUFFER) is not gl.FRAMEBUFFER_COMPLETE
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2) was expected value: NO_ERROR.
+PASS fbo should be green
+PASS wtu.checkCanvasRect(gl, 0, 0, 16, 16, [0,255,0,255], "fbo should be green") was expected value: NO_ERROR.
+PASS gl.clearColor(0,0,1,1) was expected value: NO_ERROR.
+PASS gl.clear(gl.COLOR_BUFFER_BIT) was expected value: NO_ERROR.
+PASS fbo should be blue
+PASS wtu.checkCanvasRect(gl, 0, 0, 16, 16, [0,0,255,255], "fbo should be blue") was expected value: NO_ERROR.
+PASS gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) is rbo
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, fbo) was expected value: NO_ERROR.
+PASS gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) was expected value: INVALID_ENUM.
+PASS gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) was expected value: NO_ERROR.
+PASS gl.checkFramebufferStatus(gl.FRAMEBUFFER) is not gl.FRAMEBUFFER_COMPLETE
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, null) was expected value: NO_ERROR.
+PASS backbuffer should be red
+PASS wtu.checkCanvasRect(gl, 0, 0, 16, 16, [255,0,0,255], "backbuffer should be red") was expected value: NO_ERROR.
+
+using deleted texture
+PASS tex is non-null.
+PASS gl.bindTexture(gl.TEXTURE_2D, tex) was expected value: NO_ERROR.
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, fbo) was expected value: NO_ERROR.
+PASS gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0) was expected value: NO_ERROR.
+PASS gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null) was expected value: NO_ERROR.
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2) was expected value: NO_ERROR.
+PASS gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0) was expected value: NO_ERROR.
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, fbo) was expected value: NO_ERROR.
+PASS gl.clearColor(0,1,0,1) was expected value: NO_ERROR.
+PASS gl.clear(gl.COLOR_BUFFER_BIT) was expected value: NO_ERROR.
+PASS gl.deleteTexture(tex) was expected value: NO_ERROR.
+PASS gl.checkFramebufferStatus(gl.FRAMEBUFFER) is not gl.FRAMEBUFFER_COMPLETE
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2) was expected value: NO_ERROR.
+PASS gl.checkFramebufferStatus(gl.FRAMEBUFFER) is gl.FRAMEBUFFER_COMPLETE
+PASS fbo should be green
+PASS wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0,255,0,255], "fbo should be green") was expected value: NO_ERROR.
+PASS gl.clearColor(0,0,1,1) was expected value: NO_ERROR.
+PASS gl.clear(gl.COLOR_BUFFER_BIT) was expected value: NO_ERROR.
+PASS fbo should be blue
+PASS wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0,0,255,255], "fbo should be blue") was expected value: NO_ERROR.
+PASS gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) is tex
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, fbo) was expected value: NO_ERROR.
+PASS gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) was expected value: INVALID_ENUM.
+PASS gl.checkFramebufferStatus(gl.FRAMEBUFFER) is not gl.FRAMEBUFFER_COMPLETE
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, null) was expected value: NO_ERROR.
+PASS backbuffer should be red
+PASS wtu.checkCanvasRect(gl, 0, 0, 16, 16, [255,0,0,255], "backbuffer should be red") was expected value: NO_ERROR.
buffer deletion
+PASS buffer is non-null.
PASS gl.bindBuffer(gl.ARRAY_BUFFER, buffer) was expected value: NO_ERROR.
PASS gl.getParameter(gl.ARRAY_BUFFER_BINDING) is buffer
PASS gl.deleteBuffer(buffer) was expected value: NO_ERROR.
@@ -68,6 +231,16 @@ PASS gl.isBuffer(buffer) is false
PASS gl.getParameter(gl.ARRAY_BUFFER_BINDING) is null
PASS gl.bindBuffer(gl.ARRAY_BUFFER, buffer) was expected value: NO_ERROR.
PASS gl.getParameter(gl.ARRAY_BUFFER_BINDING) is null
+PASS buffer2 is non-null.
+PASS gl.bindBuffer(gl.ARRAY_BUFFER, buffer2) was expected value: NO_ERROR.
+PASS gl.getParameter(gl.ARRAY_BUFFER_BINDING) is buffer2
+PASS gl.bindBuffer(gl.ARRAY_BUFFER, null) was expected value: NO_ERROR.
+PASS gl.getParameter(gl.ARRAY_BUFFER_BINDING) is null
+PASS gl.deleteBuffer(buffer2) was expected value: NO_ERROR.
+PASS gl.isBuffer(buffer2) is false
+PASS gl.bindBuffer(gl.ARRAY_BUFFER, buffer2) was expected value: NO_ERROR.
+PASS gl.getParameter(gl.ARRAY_BUFFER_BINDING) is null
+PASS bufferElement is non-null.
PASS gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufferElement) was expected value: NO_ERROR.
PASS gl.getParameter(gl.ELEMENT_ARRAY_BUFFER_BINDING) is bufferElement
PASS gl.deleteBuffer(bufferElement) was expected value: NO_ERROR.
@@ -75,6 +248,31 @@ PASS gl.isBuffer(bufferElement) is false
PASS gl.getParameter(gl.ELEMENT_ARRAY_BUFFER_BINDING) is null
PASS gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufferElement) was expected value: NO_ERROR.
PASS gl.getParameter(gl.ELEMENT_ARRAY_BUFFER_BINDING) is null
+PASS b is non-null.
+PASS gl.bindBuffer(gl.ARRAY_BUFFER, b) was expected value: NO_ERROR.
+PASS gl.bufferData(gl.ARRAY_BUFFER, 1, gl.STATIC_DRAW) was expected value: NO_ERROR.
+PASS gl.deleteBuffer(b) was expected value: NO_ERROR.
+PASS gl.bindBuffer(gl.ARRAY_BUFFER, b) was expected value: NO_ERROR.
+PASS gl.bufferData(gl.ARRAY_BUFFER, 1, gl.STATIC_DRAW) was expected value: INVALID_OPERATION.
+PASS b1 is non-null.
+PASS gl.bindBuffer(gl.ARRAY_BUFFER, b1); was expected value: NO_ERROR.
+PASS gl.enableVertexAttribArray(1); was expected value: NO_ERROR.
+PASS gl.vertexAttribPointer(1, 4, gl.FLOAT, false, 0, 0); was expected value: NO_ERROR.
+PASS b2 is non-null.
+PASS gl.bindBuffer(gl.ARRAY_BUFFER, b2); was expected value: NO_ERROR.
+PASS gl.enableVertexAttribArray(2); was expected value: NO_ERROR.
+PASS gl.vertexAttribPointer(2, 4, gl.FLOAT, false, 0, 0); was expected value: NO_ERROR.
+PASS gl.enableVertexAttribArray(3); was expected value: NO_ERROR.
+PASS gl.vertexAttribPointer(3, 4, gl.FLOAT, false, 0, 0); was expected value: NO_ERROR.
+PASS gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING) is b1
+PASS gl.getVertexAttrib(2, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING) is b2
+PASS gl.getVertexAttrib(3, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING) is b2
+PASS gl.deleteBuffer(b2); was expected value: NO_ERROR.
+PASS gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING) is b1
+PASS gl.getVertexAttrib(2, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING) is null
+PASS gl.getVertexAttrib(3, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING) is null
+PASS gl.deleteBuffer(b1); was expected value: NO_ERROR.
+PASS gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING) is null
framebuffer deletion
PASS gl.bindFramebuffer(gl.FRAMEBUFFER, fbo) was expected value: NO_ERROR.
@@ -84,6 +282,40 @@ PASS gl.isFramebuffer(fbo) is false
PASS gl.getParameter(gl.FRAMEBUFFER_BINDING) is null
PASS gl.bindFramebuffer(gl.FRAMEBUFFER, fbo) was expected value: NO_ERROR.
PASS gl.getParameter(gl.FRAMEBUFFER_BINDING) is null
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2) was expected value: NO_ERROR.
+PASS gl.getParameter(gl.FRAMEBUFFER_BINDING) is fbo2
+PASS gl.deleteFramebuffer(fbo3) was expected value: NO_ERROR.
+PASS gl.getParameter(gl.FRAMEBUFFER_BINDING) is fbo2
+PASS fbo is non-null.
+PASS rbo is non-null.
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, fbo) was expected value: NO_ERROR.
+PASS gl.bindRenderbuffer(gl.RENDERBUFFER, rbo) was expected value: NO_ERROR.
+PASS gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16) was expected value: NO_ERROR.
+PASS gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo) was expected value: NO_ERROR.
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, null) was expected value: NO_ERROR.
+PASS gl.clearColor(1,0,0,1) was expected value: NO_ERROR.
+PASS gl.clear(gl.COLOR_BUFFER_BIT) was expected value: NO_ERROR.
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, fbo) was expected value: NO_ERROR.
+PASS gl.clearColor(0,1,0,1) was expected value: NO_ERROR.
+PASS gl.clear(gl.COLOR_BUFFER_BIT) was expected value: NO_ERROR.
+PASS fbo should be green
+PASS wtu.checkCanvasRect(gl, 0, 0, 16, 16, [0,255,0,255], "fbo should be green") was expected value: NO_ERROR.
+PASS outside fbo should be black
+PASS wtu.checkCanvasRect(gl, 16, 16, 1, 1, [0,0,0,0], "outside fbo should be black") was expected value: NO_ERROR.
+PASS gl.deleteFramebuffer(fbo) was expected value: NO_ERROR.
+PASS backbuffer should be red
+PASS wtu.checkCanvasRect(gl, 0, 0, 300, 150, [255,0,0,255], "backbuffer should be red") was expected value: NO_ERROR.
+PASS outside backbuffer should be black
+PASS wtu.checkCanvasRect(gl, 300, 0, 300, 300, [0,0,0,0], "outside backbuffer should be black") was expected value: NO_ERROR.
+PASS outside backbuffer should be black
+PASS wtu.checkCanvasRect(gl, 0, 150, 300, 300, [0,0,0,0], "outside backbuffer should be black") was expected value: NO_ERROR.
+PASS gl.clearColor(0,1,0,1) was expected value: NO_ERROR.
+PASS gl.clear(gl.COLOR_BUFFER_BIT) was expected value: NO_ERROR.
+PASS fbo should be green
+PASS wtu.checkCanvasRect(gl, 0, 0, 300, 150, [0,255,0,255], "fbo should be green") was expected value: NO_ERROR.
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, null) was expected value: NO_ERROR.
+PASS fbo should be green
+PASS wtu.checkCanvasRect(gl, 0, 0, 300, 150, [0,255,0,255], "fbo should be green") was expected value: NO_ERROR.
PASS successfullyParsed is true
TEST COMPLETE
diff --git a/LayoutTests/fast/canvas/webgl/object-deletion-behaviour.html b/LayoutTests/fast/canvas/webgl/object-deletion-behaviour.html
index d721439..0c6b115 100644
--- a/LayoutTests/fast/canvas/webgl/object-deletion-behaviour.html
+++ b/LayoutTests/fast/canvas/webgl/object-deletion-behaviour.html
@@ -26,6 +26,7 @@ var fragmentShader = wtu.loadStandardFragmentShader(gl);
assertMsg(fragmentShader, "fragment shader loaded");
var program = gl.createProgram();
+shouldBeNonNull("program");
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.attachShader(program, vertexShader)");
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.attachShader(program, fragmentShader)");
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.linkProgram(program)");
@@ -49,14 +50,19 @@ shouldBeFalse("gl.isShader(fragmentShader)");
debug("");
debug("texture deletion");
-var fbo = gl.createFramebuffer();
+var fbo = gl.createFramebuffer(), fbo2 = gl.createFramebuffer(), fbo3 = gl.createFramebuffer();
+shouldBeNonNull("fbo");
+shouldBeNonNull("fbo2");
+shouldBeNonNull("fbo3");
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
var tex = gl.createTexture();
+shouldBeNonNull("tex");
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, tex)");
shouldBe("gl.getParameter(gl.TEXTURE_BINDING_2D)", "tex");
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0)");
shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "tex");
+shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)", "gl.TEXTURE");
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTexture(tex)");
// Deleting a texture bound to the currently-bound fbo is the same as
// detaching the textue from fbo first, then delete the texture.
@@ -68,6 +74,7 @@ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, tex)");
shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_2D)");
var texCubeMap = gl.createTexture();
+shouldBeNonNull("texCubeMap");
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_CUBE_MAP, texCubeMap)");
shouldBe("gl.getParameter(gl.TEXTURE_BINDING_CUBE_MAP)", "texCubeMap");
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTexture(texCubeMap)");
@@ -76,10 +83,34 @@ shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_CUBE_MAP)");
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_CUBE_MAP, texCubeMap)");
shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_CUBE_MAP)");
+var t = gl.createTexture();
+shouldBeNonNull("t");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, t)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTexture(t)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, t)");
+shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)");
+
+var t2 = gl.createTexture();
+shouldBeNonNull("t2");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.activeTexture(gl.TEXTURE0)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, t2)");
+shouldBe("gl.getParameter(gl.TEXTURE_BINDING_2D)", "t2");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.activeTexture(gl.TEXTURE1)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, t2)");
+shouldBe("gl.getParameter(gl.TEXTURE_BINDING_2D)", "t2");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTexture(t2)");
+shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_2D)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.activeTexture(gl.TEXTURE0)");
+shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_2D)");
+
debug("");
debug("renderbuffer deletion");
-var rbo = gl.createRenderbuffer();
+var rbo = gl.createRenderbuffer(), rbo2 = gl.createRenderbuffer(), rbo3 = gl.createRenderbuffer();
+shouldBeNonNull("rbo");
+shouldBeNonNull("rbo2");
+shouldBeNonNull("rbo3");
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)");
shouldBe("gl.getParameter(gl.RENDERBUFFER_BINDING)", "rbo");
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo)");
@@ -93,11 +124,184 @@ shouldBeFalse("gl.isRenderbuffer(rbo)");
shouldBeNull("gl.getParameter(gl.RENDERBUFFER_BINDING)");
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)");
shouldBeNull("gl.getParameter(gl.RENDERBUFFER_BINDING)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo2)");
+shouldBe("gl.getParameter(gl.RENDERBUFFER_BINDING)", "rbo2");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteRenderbuffer(rbo3)");
+shouldBe("gl.getParameter(gl.RENDERBUFFER_BINDING)", "rbo2");
+
+debug("");
+debug("using deleted renderbuffer");
+rbo = gl.createRenderbuffer();
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo)");
+if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
+ // make backbuffer red
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(1,0,0,1)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
+ // make fbo green
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,1,0,1)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
+ // Bind backbuffer.
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
+ // delete renderbuffer. It should still be attached to fbo though.
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteRenderbuffer(rbo)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [255,0,0,255], "backbuffer should be red")');
+ // Use fbo that has deleted rbo.
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [0,255,0,255], "fbo should be green")');
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,0,1,1)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [0,0,255,255], "fbo should be blue")');
+ // Bind backbuffer.
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [255,0,0,255], "backbuffer should be red")');
+}
+
+debug("");
+debug("renderbuffer attached twice to same framebuffer");
+rbo = gl.createRenderbuffer();
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo)");
+if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
+ rbo2 = gl.createRenderbuffer();
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo2)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16)");
+ // attach rbo2 at two attachment points incompatible with it
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, rbo2)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, rbo2)");
+ shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "rbo2");
+ shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "rbo2");
+ // fbo can't be complete as rbo2 is attached at incompatible attachment points
+ shouldNotBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
+ // now we delete rbo2, which detaches it from the two attachment points where it currently is attached
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteRenderbuffer(rbo2)");
+ shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)", "gl.NONE");
+ shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)", "gl.NONE");
+ // we should now be in the same state as before with only rbo attached, so fbo should be complete again
+ shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
+ shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "rbo");
+}
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteRenderbuffer(rbo)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
+
+
+
+debug("");
+debug("using deleted texture");
+tex = gl.createTexture();
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, tex)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null)");
+if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
+ // make fbo green
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,1,0,1)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
+ // Bind backbuffer.
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
+ // delete texture. It should still be attached to fbo though.
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTexture(tex)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 1, 1, [255,0,0,255], "backbuffer should be red")');
+ // Use fbo that has deleted texture.
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0,255,0,255], "fbo should be green")');
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,0,1,1)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0,0,255,255], "fbo should be blue")');
+ // Bind backbuffer.
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [255,0,0,255], "backbuffer should be red")');
+}
+
+debug("");
+debug("using deleted renderbuffer");
+rbo = gl.createRenderbuffer();
+shouldBeNonNull("rbo");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo)");
+if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo)");
+ shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
+ // make backbuffer red
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(1,0,0,1)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
+ // make fbo green
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,1,0,1)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
+ // delete renderbuffer. It should still be attached to fbo2 though.
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteRenderbuffer(rbo)");
+ // fbo has no attachments
+ shouldNotBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
+ // Use fbo2 that has deleted rbo.
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [0,255,0,255], "fbo should be green")');
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,0,1,1)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [0,0,255,255], "fbo should be blue")');
+ shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "rbo");
+
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
+ shouldGenerateGLError(gl, gl.INVALID_ENUM, "gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)");
+ shouldGenerateGLError(gl, gl.NONE, "gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)");
+ shouldNotBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
+ // Bind backbuffer.
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [255,0,0,255], "backbuffer should be red")');
+}
+
+debug("");
+debug("using deleted texture");
+tex = gl.createTexture();
+shouldBeNonNull("tex");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, tex)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null)");
+if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0)");
+ // make fbo green
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,1,0,1)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
+ // delete texture. It should still be attached to fbo2 though.
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTexture(tex)");
+ // fbo has no attachments
+ shouldNotBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
+ // Use fbo that has deleted texture.
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2)");
+ shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
+ shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0,255,0,255], "fbo should be green")');
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,0,1,1)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0,0,255,255], "fbo should be blue")');
+ shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "tex");
+
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
+ shouldGenerateGLError(gl, gl.INVALID_ENUM, "gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)");
+ shouldNotBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
+ // Bind backbuffer.
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [255,0,0,255], "backbuffer should be red")');
+}
debug("");
debug("buffer deletion");
var buffer = gl.createBuffer();
+shouldBeNonNull("buffer");
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, buffer)");
shouldBe("gl.getParameter(gl.ARRAY_BUFFER_BINDING)", "buffer");
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(buffer)");
@@ -106,7 +310,19 @@ shouldBeNull("gl.getParameter(gl.ARRAY_BUFFER_BINDING)");
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, buffer)");
shouldBeNull("gl.getParameter(gl.ARRAY_BUFFER_BINDING)");
+var buffer2 = gl.createBuffer();
+shouldBeNonNull("buffer2");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, buffer2)");
+shouldBe("gl.getParameter(gl.ARRAY_BUFFER_BINDING)", "buffer2");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, null)");
+shouldBeNull("gl.getParameter(gl.ARRAY_BUFFER_BINDING)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(buffer2)");
+shouldBeFalse("gl.isBuffer(buffer2)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, buffer2)");
+shouldBeNull("gl.getParameter(gl.ARRAY_BUFFER_BINDING)");
+
var bufferElement = gl.createBuffer();
+shouldBeNonNull("bufferElement");
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufferElement)");
shouldBe("gl.getParameter(gl.ELEMENT_ARRAY_BUFFER_BINDING)", "bufferElement");
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(bufferElement)");
@@ -115,6 +331,36 @@ shouldBeNull("gl.getParameter(gl.ELEMENT_ARRAY_BUFFER_BINDING)");
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufferElement)");
shouldBeNull("gl.getParameter(gl.ELEMENT_ARRAY_BUFFER_BINDING)");
+var b = gl.createBuffer();
+shouldBeNonNull("b");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, b)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bufferData(gl.ARRAY_BUFFER, 1, gl.STATIC_DRAW)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(b)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, b)");
+shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.bufferData(gl.ARRAY_BUFFER, 1, gl.STATIC_DRAW)");
+
+var b1 = gl.createBuffer();
+shouldBeNonNull("b1");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, b1);");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.enableVertexAttribArray(1);");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.vertexAttribPointer(1, 4, gl.FLOAT, false, 0, 0);");
+var b2 = gl.createBuffer();
+shouldBeNonNull("b2");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, b2);");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.enableVertexAttribArray(2);");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.vertexAttribPointer(2, 4, gl.FLOAT, false, 0, 0);");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.enableVertexAttribArray(3);");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.vertexAttribPointer(3, 4, gl.FLOAT, false, 0, 0);");
+shouldBe("gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)", "b1");
+shouldBe("gl.getVertexAttrib(2, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)", "b2");
+shouldBe("gl.getVertexAttrib(3, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)", "b2");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(b2);");
+shouldBe("gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)", "b1");
+shouldBeNull("gl.getVertexAttrib(2, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)");
+shouldBeNull("gl.getVertexAttrib(3, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(b1);");
+shouldBeNull("gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)");
+
debug("");
debug("framebuffer deletion");
@@ -125,6 +371,47 @@ shouldBeFalse("gl.isFramebuffer(fbo)");
shouldBeNull("gl.getParameter(gl.FRAMEBUFFER_BINDING)");
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
shouldBeNull("gl.getParameter(gl.FRAMEBUFFER_BINDING)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2)");
+shouldBe("gl.getParameter(gl.FRAMEBUFFER_BINDING)", "fbo2");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteFramebuffer(fbo3)");
+shouldBe("gl.getParameter(gl.FRAMEBUFFER_BINDING)", "fbo2");
+
+fbo = gl.createFramebuffer();
+rbo = gl.createRenderbuffer();
+shouldBeNonNull("fbo");
+shouldBeNonNull("rbo");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo)");
+if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
+ // set backbuffer to red
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(1,0,0,1)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
+ // set framebuffer to green
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,1,0,1)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
+ // check framebuffer
+ shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [0,255,0,255], "fbo should be green")');
+ shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 16, 16, 1, 1, [0,0,0,0], "outside fbo should be black")');
+ // delete framebuffer. because this was the bound fbo the backbuffer should be active now
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteFramebuffer(fbo)");
+ // check backbuffer
+ shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 300, 150, [255,0,0,255], "backbuffer should be red")');
+ shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 300, 0, 300, 300, [0,0,0,0], "outside backbuffer should be black")');
+ shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 150, 300, 300, [0,0,0,0], "outside backbuffer should be black")');
+ // check drawing to backbuffer
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,1,0,1)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
+ shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 300, 150, [0,255,0,255], "fbo should be green")');
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
+ // check again because many buggy implementations will have bound to the true backbuffer on deleteFramebuffer.
+ shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 300, 150, [0,255,0,255], "fbo should be green")');
+}
+
+successfullyParsed = true;
</script>
<script src="../../js/resources/js-test-post.js"></script>
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index b6478e5..9287b30 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,21 @@
+2011-12-16 Zhenyao Mo <zmo@google.com>
+
+ Postpone deleteRenderbuffer/deleteTexture until all framebuffer attachment points are removed.
+ https://bugs.webkit.org/show_bug.cgi?id=74741
+
+ Reviewed by Kenneth Russell.
+
+ Use WebGLObject's attachment count mechanism to track if a renderbuffer/texture
+ is still attached to framebuffers, and if its deletion should be delated or not.
+
+ * html/canvas/WebGLFramebuffer.cpp:
+ (WebCore::WebGLFramebuffer::setAttachmentForBoundFramebuffer):
+ (WebCore::WebGLFramebuffer::getAttachment):
+ (WebCore::WebGLFramebuffer::removeAttachmentFromBoundFramebuffer):
+ (WebCore::WebGLFramebuffer::deleteObjectImpl):
+ (WebCore::WebGLFramebuffer::isBound):
+ * html/canvas/WebGLFramebuffer.h:
+
2011-12-19 Iain Merrick <husky@google.com>
[chromium] Accelerated canvas broken in threaded compositing mode
diff --git a/Source/WebCore/html/canvas/WebGLFramebuffer.cpp b/Source/WebCore/html/canvas/WebGLFramebuffer.cpp
index 8d84c44..d1af518 100644
--- a/Source/WebCore/html/canvas/WebGLFramebuffer.cpp
+++ b/Source/WebCore/html/canvas/WebGLFramebuffer.cpp
@@ -117,10 +117,12 @@ WebGLFramebuffer::WebGLFramebuffer(WebGLRenderingContext* ctx)
setObject(context()->graphicsContext3D()->createFramebuffer());
}
-void WebGLFramebuffer::setAttachment(GC3Denum attachment, GC3Denum texTarget, WebGLTexture* texture, GC3Dint level)
+void WebGLFramebuffer::setAttachmentForBoundFramebuffer(GC3Denum attachment, GC3Denum texTarget, WebGLTexture* texture, GC3Dint level)
{
+ ASSERT(isBound());
if (!object())
return;
+ removeAttachmentFromBoundFramebuffer(attachment);
if (texture && !texture->object())
texture = 0;
switch (attachment) {
@@ -141,14 +143,19 @@ void WebGLFramebuffer::setAttachment(GC3Denum attachment, GC3Denum texTarget, We
m_depthStencilAttachment = texture;
break;
default:
- return;
+ ASSERT_NOT_REACHED();
+ break;
}
+ if (texture)
+ texture->onAttached();
}
-void WebGLFramebuffer::setAttachment(GC3Denum attachment, WebGLRenderbuffer* renderbuffer)
+void WebGLFramebuffer::setAttachmentForBoundFramebuffer(GC3Denum attachment, WebGLRenderbuffer* renderbuffer)
{
+ ASSERT(isBound());
if (!object())
return;
+ removeAttachmentFromBoundFramebuffer(attachment);
if (renderbuffer && !renderbuffer->object())
renderbuffer = 0;
switch (attachment) {
@@ -165,8 +172,11 @@ void WebGLFramebuffer::setAttachment(GC3Denum attachment, WebGLRenderbuffer* ren
m_depthStencilAttachment = renderbuffer;
break;
default:
- return;
+ ASSERT_NOT_REACHED();
+ break;
}
+ if (renderbuffer)
+ renderbuffer->onAttached();
}
WebGLObject* WebGLFramebuffer::getAttachment(GC3Denum attachment) const
@@ -183,24 +193,77 @@ WebGLObject* WebGLFramebuffer::getAttachment(GC3Denum attachment) const
case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
return m_depthStencilAttachment.get();
default:
+ ASSERT_NOT_REACHED();
return 0;
}
}
-void WebGLFramebuffer::removeAttachment(WebGLObject* attachment)
+void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(GC3Denum attachment)
{
+ ASSERT(isBound());
if (!object())
return;
- if (attachment == m_colorAttachment.get())
- m_colorAttachment = 0;
- else if (attachment == m_depthAttachment.get())
- m_depthAttachment = 0;
- else if (attachment == m_stencilAttachment.get())
- m_stencilAttachment = 0;
- else if (attachment == m_depthStencilAttachment.get())
- m_depthStencilAttachment = 0;
- else
+ switch (attachment) {
+ case GraphicsContext3D::COLOR_ATTACHMENT0:
+ if (m_colorAttachment) {
+ m_colorAttachment->onDetached();
+ m_colorAttachment = 0;
+ m_texTarget = 0;
+ m_texLevel = -1;
+ }
+ break;
+ case GraphicsContext3D::DEPTH_ATTACHMENT:
+ if (m_depthAttachment) {
+ m_depthAttachment->onDetached();
+ m_depthAttachment = 0;
+ }
+ break;
+ case GraphicsContext3D::STENCIL_ATTACHMENT:
+ if (m_stencilAttachment) {
+ m_stencilAttachment->onDetached();
+ m_stencilAttachment = 0;
+ }
+ break;
+ case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
+ if (m_depthStencilAttachment) {
+ m_depthStencilAttachment->onDetached();
+ m_depthStencilAttachment = 0;
+ }
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(WebGLObject* attachment)
+{
+ ASSERT(isBound());
+ if (!object())
return;
+ if (!attachment)
+ return;
+ GraphicsContext3D* gc3d = context()->graphicsContext3D();
+ if (attachment == m_colorAttachment.get()) {
+ if (attachment->isRenderbuffer())
+ gc3d->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::RENDERBUFFER, 0);
+ else
+ gc3d->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, m_texTarget, 0, m_texLevel);
+ removeAttachmentFromBoundFramebuffer(GraphicsContext3D::COLOR_ATTACHMENT0);
+ }
+ if (attachment == m_depthAttachment.get()) {
+ gc3d->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, 0);
+ removeAttachmentFromBoundFramebuffer(GraphicsContext3D::DEPTH_ATTACHMENT);
+ }
+ if (attachment == m_stencilAttachment.get()) {
+ gc3d->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::STENCIL_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, 0);
+ removeAttachmentFromBoundFramebuffer(GraphicsContext3D::STENCIL_ATTACHMENT);
+ }
+ if (attachment == m_depthStencilAttachment.get()) {
+ gc3d->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, 0);
+ gc3d->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::STENCIL_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, 0);
+ removeAttachmentFromBoundFramebuffer(GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT);
+ }
}
GC3Dsizei WebGLFramebuffer::getColorBufferWidth() const
@@ -317,11 +380,15 @@ bool WebGLFramebuffer::onAccess(bool needToInitializeRenderbuffers)
void WebGLFramebuffer::deleteObjectImpl(Platform3DObject object)
{
+ if (m_colorAttachment)
+ m_colorAttachment->onDetached();
+ if (m_depthAttachment)
+ m_depthAttachment->onDetached();
+ if (m_stencilAttachment)
+ m_stencilAttachment->onDetached();
+ if (m_depthStencilAttachment)
+ m_depthStencilAttachment->onDetached();
context()->graphicsContext3D()->deleteFramebuffer(object);
- m_colorAttachment = 0;
- m_depthAttachment = 0;
- m_stencilAttachment = 0;
- m_depthStencilAttachment = 0;
}
bool WebGLFramebuffer::initializeRenderbuffers()
@@ -420,6 +487,11 @@ bool WebGLFramebuffer::initializeRenderbuffers()
return true;
}
+bool WebGLFramebuffer::isBound() const
+{
+ return (context()->m_framebufferBinding.get() == this);
+}
+
}
#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLFramebuffer.h b/Source/WebCore/html/canvas/WebGLFramebuffer.h
index 9950bad..110f513 100644
--- a/Source/WebCore/html/canvas/WebGLFramebuffer.h
+++ b/Source/WebCore/html/canvas/WebGLFramebuffer.h
@@ -42,10 +42,12 @@ public:
static PassRefPtr<WebGLFramebuffer> create(WebGLRenderingContext*);
- void setAttachment(GC3Denum attachment, GC3Denum texTarget, WebGLTexture*, GC3Dint level);
- void setAttachment(GC3Denum attachment, WebGLRenderbuffer*);
- // If an object is attached to the framebuffer, remove it.
- void removeAttachment(WebGLObject*);
+ void setAttachmentForBoundFramebuffer(GC3Denum attachment, GC3Denum texTarget, WebGLTexture*, GC3Dint level);
+ void setAttachmentForBoundFramebuffer(GC3Denum attachment, WebGLRenderbuffer*);
+ // If an object is attached to the currently bound framebuffer, remove it.
+ void removeAttachmentFromBoundFramebuffer(WebGLObject*);
+ // If a given attachment point for the currently bound framebuffer is not null, remove the attached object.
+ void removeAttachmentFromBoundFramebuffer(GC3Denum);
WebGLObject* getAttachment(GC3Denum) const;
GC3Denum getColorBufferFormat() const;
@@ -81,6 +83,9 @@ private:
// Return false if framebuffer is incomplete.
bool initializeRenderbuffers();
+ // Check if the framebuffer is currently bound.
+ bool isBound() const;
+
bool isColorAttached() const { return (m_colorAttachment && m_colorAttachment->object()); }
bool isDepthAttached() const { return (m_depthAttachment && m_depthAttachment->object()); }
bool isStencilAttached() const { return (m_stencilAttachment && m_stencilAttachment->object()); }
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
index 2461ad4..5858574 100644
--- a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
+++ b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
@@ -1415,7 +1415,7 @@ void WebGLRenderingContext::deleteRenderbuffer(WebGLRenderbuffer* renderbuffer)
if (renderbuffer == m_renderbufferBinding)
m_renderbufferBinding = 0;
if (m_framebufferBinding)
- m_framebufferBinding->removeAttachment(renderbuffer);
+ m_framebufferBinding->removeAttachmentFromBoundFramebuffer(renderbuffer);
}
void WebGLRenderingContext::deleteShader(WebGLShader* shader)
@@ -1434,7 +1434,7 @@ void WebGLRenderingContext::deleteTexture(WebGLTexture* texture)
m_textureUnits[i].m_textureCubeMapBinding = 0;
}
if (m_framebufferBinding)
- m_framebufferBinding->removeAttachment(texture);
+ m_framebufferBinding->removeAttachmentFromBoundFramebuffer(texture);
}
void WebGLRenderingContext::depthFunc(GC3Denum func)
@@ -1918,7 +1918,7 @@ void WebGLRenderingContext::framebufferRenderbuffer(GC3Denum target, GC3Denum at
default:
m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, objectOrZero(buffer));
}
- m_framebufferBinding->setAttachment(attachment, buffer);
+ m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, buffer);
if (reattachDepth) {
Platform3DObject object = objectOrZero(m_framebufferBinding->getAttachment(GraphicsContext3D::DEPTH_ATTACHMENT));
if (object)
@@ -1963,7 +1963,7 @@ void WebGLRenderingContext::framebufferTexture2D(GC3Denum target, GC3Denum attac
return;
}
m_context->framebufferTexture2D(target, attachment, textarget, objectOrZero(texture), level);
- m_framebufferBinding->setAttachment(attachment, textarget, texture, level);
+ m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, textarget, texture, level);
cleanupAfterGraphicsCall(false);
}
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.h b/Source/WebCore/html/canvas/WebGLRenderingContext.h
index 4b3ca38..8baaf7f 100644
--- a/Source/WebCore/html/canvas/WebGLRenderingContext.h
+++ b/Source/WebCore/html/canvas/WebGLRenderingContext.h
@@ -309,6 +309,7 @@ public:
unsigned getMaxVertexAttribs() const { return m_maxVertexAttribs; }
private:
+ friend class WebGLFramebuffer;
friend class WebGLObject;
friend class OESVertexArrayObject;
friend class WebGLDebugShaders;