[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

zmo at google.com zmo at google.com
Wed Dec 22 12:04:48 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 0f9b8f57d90a8f683705c4e83c059b568f9062a9
Author: zmo at google.com <zmo at google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Aug 13 17:12:19 2010 +0000

    2010-08-11  Zhenyao Mo  <zmo at google.com>
    
            Reviewed by Dimitri Glazkov.
    
            Regression in linking of programs
            https://bugs.webkit.org/show_bug.cgi?id=43820
    
            Shaders and programs shouldn't be deleted until their attachments are removed, therefore, we need to track the attach/detach/useProgram.
    
            * html/canvas/WebGLObject.cpp: Track the object attachment count and whether it should really be deleted.
            (WebCore::WebGLObject::WebGLObject):
            (WebCore::WebGLObject::setObject):
            (WebCore::WebGLObject::deleteObject):
            * html/canvas/WebGLObject.h: Track the object attachment count and whether it should really be deleted.
            (WebCore::WebGLObject::onAttached):
            (WebCore::WebGLObject::onDetached):
            (WebCore::WebGLObject::getAttachmentCount):
            * html/canvas/WebGLProgram.cpp: Track the attached shaders.
            (WebCore::WebGLProgram::WebGLProgram):
            (WebCore::WebGLProgram::deleteObjectImpl):
            (WebCore::WebGLProgram::getAttachedShader):
            (WebCore::WebGLProgram::attachShader):
            (WebCore::WebGLProgram::detachShader):
            * html/canvas/WebGLProgram.h: Track the attached shaders.
            * html/canvas/WebGLRenderingContext.cpp:
            (WebCore::WebGLRenderingContext::attachShader): Track the attachment of a shader to a program.
            (WebCore::WebGLRenderingContext::deleteProgram): Detach shaders.
            (WebCore::WebGLRenderingContext::detachShader): Track the attachment of a shader to a program.
            (WebCore::WebGLRenderingContext::validateWebGLObject): Also check if object == 0.
            (WebCore::WebGLRenderingContext::linkProgram): Using the cached attached shaders instead of query from driver.
            (WebCore::WebGLRenderingContext::useProgram): Track the attachment of a program to the current rendering pipeline.
    2010-08-11  Zhenyao Mo  <zmo at google.com>
    
            Reviewed by Dimitri Glazkov.
    
            Regression in linking of programs
            https://bugs.webkit.org/show_bug.cgi?id=43820
    
            * fast/canvas/webgl/program-test-expected.txt: Fix the tests so a second shader of the same type attaching to a program will generate error; also, add tests for deleteShader/deleteProgram behavior.
            * fast/canvas/webgl/program-test.html: Ditto.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@65330 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 59c9f6f..3ed899d 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,13 @@
+2010-08-11  Zhenyao Mo  <zmo at google.com>
+
+        Reviewed by Dimitri Glazkov.
+
+        Regression in linking of programs
+        https://bugs.webkit.org/show_bug.cgi?id=43820
+
+        * fast/canvas/webgl/program-test-expected.txt: Fix the tests so a second shader of the same type attaching to a program will generate error; also, add tests for deleteShader/deleteProgram behavior.
+        * fast/canvas/webgl/program-test.html: Ditto.
+
 2010-08-13  Steve Block  <steveblock at google.com>
 
         Reviewed by Alexey Proskuryakov.
diff --git a/LayoutTests/fast/canvas/webgl/program-test-expected.txt b/LayoutTests/fast/canvas/webgl/program-test-expected.txt
index c98d2b2..fcdb05d 100644
--- a/LayoutTests/fast/canvas/webgl/program-test-expected.txt
+++ b/LayoutTests/fast/canvas/webgl/program-test-expected.txt
@@ -12,15 +12,17 @@ PASS bad vertex shader should fail to compile
 PASS good fragment shader should compile
 PASS good fragment shader #2 should compile
 PASS bad fragment shader should fail to compile
-PASS should be no errors at this point
-PASS attaching a vertex shader should succeed
-PASS attaching an already attached vertex shader should generate INVALID_OPERATION
-PASS attaching a fragment shader should succeed
-PASS attaching an already attached fragment shader should generate INVALID_OPERATION
-PASS detaching a vertex shader should succeed
-PASS detaching a not already attached vertex shader should generate INVALID_OPERATION
-PASS detaching a fragment shader should succeed
-PASS detaching a not already attached fragment shader should generate INVALID_OPERATION
+PASS getError was expected value: NO_ERROR : should be no errors at this point
+PASS getError was expected value: NO_ERROR : attaching a vertex shader should succeed
+PASS getError was expected value: INVALID_OPERATION : attaching an already attached vertex shader should generate INVALID_OPERATION
+PASS getError was expected value: NO_ERROR : attaching a fragment shader should succeed
+PASS getError was expected value: INVALID_OPERATION : attaching an already attached fragment shader should generate INVALID_OPERATION
+PASS getError was expected value: INVALID_OPERATION : attaching shaders of the same type to a program should generate INVALID_OPERATION
+PASS getError was expected value: INVALID_OPERATION : attaching shaders of the same type to a program should generate INVALID_OPERATION
+PASS getError was expected value: NO_ERROR : detaching a vertex shader should succeed
+PASS getError was expected value: INVALID_OPERATION : detaching a not already attached vertex shader should generate INVALID_OPERATION
+PASS getError was expected value: NO_ERROR : detaching a fragment shader should succeed
+PASS getError was expected value: INVALID_OPERATION : detaching a not already attached fragment shader should generate INVALID_OPERATION
 PASS getAttachedShaders should return an empty list by default
 PASS attaching a single shader should give the expected list
 PASS attaching some shaders should give the expected list
@@ -32,26 +34,38 @@ PASS attaching and detaching some shaders should leave the difference list
 PASS attaching a shader that failed to compile should still show it in the list
 PASS attaching shaders, including one that failed to compile, should still show the it in the list
 PASS valid program should link
-PASS using a valid program should succeed
+PASS getError was expected value: NO_ERROR : using a valid program should succeed
 PASS valid program #2 should link
-PASS using a valid program should succeed
+PASS getError was expected value: NO_ERROR : using a valid program should succeed
 PASS program with no fragment shader should fail to link
-PASS using an invalid program should generate INVALID_OPERATION
+PASS getError was expected value: INVALID_OPERATION : using an invalid program should generate INVALID_OPERATION
 PASS program with no vertex shader should fail to link
-PASS using an invalid program should generate INVALID_OPERATION
+PASS getError was expected value: INVALID_OPERATION : using an invalid program should generate INVALID_OPERATION
 PASS program with bad vertex shader should fail to link
-PASS using an invalid program should generate INVALID_OPERATION
+PASS getError was expected value: INVALID_OPERATION : using an invalid program should generate INVALID_OPERATION
 PASS program with bad fragment shader should fail to link
-PASS using an invalid program should generate INVALID_OPERATION
+PASS getError was expected value: INVALID_OPERATION : using an invalid program should generate INVALID_OPERATION
 PASS program with bad shaders should fail to link
-PASS using an invalid program should generate INVALID_OPERATION
-PASS using a valid program shouldn't generate a GL error
-PASS should be no errors at this point #2
-PASS drawing with a valid program shouldn't generate a GL error
-PASS using an invalid program should generate INVALID_OPERATION
-PASS drawing with an invalid program should generate some GL error XXX
+PASS getError was expected value: INVALID_OPERATION : using an invalid program should generate INVALID_OPERATION
+PASS getError was expected value: NO_ERROR : using a valid program shouldn't generate a GL error
+PASS getError was expected value: NO_ERROR : should be no errors at this point #2
+PASS getError was expected value: NO_ERROR : drawing with a valid program shouldn't generate a GL error
+PASS getError was expected value: INVALID_OPERATION : using an invalid program should generate INVALID_OPERATION
+PASS getError was expected value: NO_ERROR : Try to use an invalid program should not change the current rendering state
+PASS getError was expected value: NO_ERROR : drawing with a valid program shouldn't generate a GL error
 PASS linking should fail with in-use formerly good program, with new bad shader attached
-PASS drawing with a valid when last used program shouldn't generate a GL error
+PASS getError was expected value: NO_ERROR : drawing with a valid when last used program shouldn't generate a GL error
+PASS delete shaders after attaching them and before linking program should not affect linkProgram
+PASS getError was expected value: NO_ERROR : using a valid program should succeed
+PASS getError was expected value: NO_ERROR : drawing with a valid when last used program shouldn't generate a GL error
+PASS getError was expected value: NO_ERROR : delete the current program shouldn't change the current rendering state
+PASS getError was expected value: NO_ERROR : The current program shouldn't be deleted
+PASS good fragment shader should compile
+PASS getError was expected value: INVALID_VALUE : an unattached shader should be deleted immediately
+PASS good fragment shader should compile
+PASS an attached shader shouldn't be deleted
+PASS getError was expected value: INVALID_VALUE : a delete-marked program should be deleted once it's no longer the current program
+PASS getError was expected value: INVALID_VALUE : a delete-marked shader should be deleted once all its attachments are removed
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/LayoutTests/fast/canvas/webgl/program-test.html b/LayoutTests/fast/canvas/webgl/program-test.html
index e43c995..4d935bb 100644
--- a/LayoutTests/fast/canvas/webgl/program-test.html
+++ b/LayoutTests/fast/canvas/webgl/program-test.html
@@ -75,8 +75,7 @@ function go() {
     assertMsg(gl.getShaderParameter(fsBad, gl.COMPILE_STATUS) == false,
               "bad fragment shader should fail to compile");
 
-    assertMsg(gl.getError() == gl.NO_ERROR,
-              "should be no errors at this point");
+    glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors at this point");
 
 /////// Check attachShader() /////////////////////////////
 
@@ -87,7 +86,7 @@ function go() {
         if(gl.getError() != gl.NO_ERROR)
             assertMsg(false, "unexpected error in attachShader()");
         gl.attachShader(prog, shader);
-        assertMsg(gl.getError() == expected_error_code, errmsg);
+        glErrorShouldBe(gl, expected_error_code, errmsg);
     }
 
     checkAttachShader([], vs, gl.NO_ERROR, "attaching a vertex shader should succeed");
@@ -96,6 +95,10 @@ function go() {
     checkAttachShader([], fs, gl.NO_ERROR, "attaching a fragment shader should succeed");
     checkAttachShader([fs], fs, gl.INVALID_OPERATION,
                       "attaching an already attached fragment shader should generate INVALID_OPERATION");
+    checkAttachShader([vs], vs2, gl.INVALID_OPERATION,
+                      "attaching shaders of the same type to a program should generate INVALID_OPERATION");
+    checkAttachShader([fs], fs2, gl.INVALID_OPERATION,
+                      "attaching shaders of the same type to a program should generate INVALID_OPERATION");
 
 /////// Check detachShader() /////////////////////////////
 
@@ -106,7 +109,7 @@ function go() {
         if(gl.getError() != gl.NO_ERROR)
             assertMsg(false, "unexpected error in attachShader()");
         gl.detachShader(prog, shader);
-        assertMsg(gl.getError() == expected_error_code, errmsg);
+        glErrorShouldBe(gl, expected_error_code, errmsg);
     }
 
     checkDetachShader([vs], vs, gl.NO_ERROR, "detaching a vertex shader should succeed");
@@ -132,28 +135,31 @@ function go() {
     }
     checkGetAttachedShaders([], [], [], "getAttachedShaders should return an empty list by default");
     checkGetAttachedShaders([fs], [], [fs], "attaching a single shader should give the expected list");
-    checkGetAttachedShaders([fs, vs, fs2, vs2], [], [fs, vs, fs2, vs2],
+    checkGetAttachedShaders([fs, vs], [], [fs, vs],
         "attaching some shaders should give the expected list");
     checkGetAttachedShaders([fs], [fs], [], "attaching a shader and detaching it shoud leave an empty list");
-    checkGetAttachedShaders([fs, vs, fs2, vs2], [fs, vs, fs2, vs2], [],
+    checkGetAttachedShaders([fs, vs], [fs, vs], [],
         "attaching some shaders and detaching them in same order shoud leave an empty list");
-    checkGetAttachedShaders([fs, vs, fs2, vs2], [fs, vs2, vs, fs2], [],
+    checkGetAttachedShaders([fs, vs], [vs, fs], [],
         "attaching some shaders and detaching them in random order shoud leave an empty list");
-    checkGetAttachedShaders([fs, vs, fs2, vs2], [vs], [fs, fs2, vs2],
+    checkGetAttachedShaders([fs, vs], [vs], [fs],
         "attaching and detaching some shaders should leave the difference list");
-    checkGetAttachedShaders([fs, vs, fs2, vs2], [fs, vs2], [vs, fs2],
+    checkGetAttachedShaders([fs, vs], [fs], [vs],
         "attaching and detaching some shaders should leave the difference list");
     checkGetAttachedShaders([fsBad], [], [fsBad],
         "attaching a shader that failed to compile should still show it in the list");
-    checkGetAttachedShaders([fs, vsBad, fs2], [], [fs, vsBad, fs2],
+    checkGetAttachedShaders([fs, vsBad], [], [fs, vsBad],
         "attaching shaders, including one that failed to compile, should still show the it in the list");
 
 /////// Check linkProgram() and useProgram /////////////////////////////
 
-    function checkLinkAndUse(shaders, expected_status, errmsg) {
+    function checkLinkAndUse(shaders, deleteShaderAfterAttach, expected_status, errmsg) {
         var prog = gl.createProgram();
-        for (var i = 0; i < shaders.length; ++i)
+        for (var i = 0; i < shaders.length; ++i) {
             gl.attachShader(prog, shaders[i]);
+            if (deleteShaderAfterAttach)
+                gl.deleteShader(shaders[i]);
+        }
         gl.bindAttribLocation(prog, 0, "aVertex");
         gl.bindAttribLocation(prog, 1, "aColor");
         gl.linkProgram(prog);
@@ -166,23 +172,22 @@ function go() {
             assertMsg(false, "unexpected error in getProgramParameter()");
         gl.useProgram(prog);
         if (expected_status == true)
-            assertMsg(gl.getError() == gl.NO_ERROR, "using a valid program should succeed");
+            glErrorShouldBe(gl, gl.NO_ERROR, "using a valid program should succeed");
         if (expected_status == false)
-            assertMsg(gl.getError() == gl.INVALID_OPERATION, "using an invalid program should generate INVALID_OPERATION");
+            glErrorShouldBe(gl, gl.INVALID_OPERATION, "using an invalid program should generate INVALID_OPERATION");
         return prog;
     }
 
-    var progGood1 = checkLinkAndUse([vs, fs], true, "valid program should link");
-    var progGood2 = checkLinkAndUse([vs, fs2], true, "valid program #2 should link");
-    var progBad1 = checkLinkAndUse([vs], false, "program with no fragment shader should fail to link");
-    var progBad2 = checkLinkAndUse([fs], false, "program with no vertex shader should fail to link");
-    var progBad3 = checkLinkAndUse([vsBad, fs], false, "program with bad vertex shader should fail to link");
-    var progBad4 = checkLinkAndUse([vs, fsBad], false, "program with bad fragment shader should fail to link");
-    var progBad5 = checkLinkAndUse([vsBad, fsBad], false, "program with bad shaders should fail to link");
+    var progGood1 = checkLinkAndUse([vs, fs], false, true, "valid program should link");
+    var progGood2 = checkLinkAndUse([vs, fs2], false, true, "valid program #2 should link");
+    var progBad1 = checkLinkAndUse([vs], false, false, "program with no fragment shader should fail to link");
+    var progBad2 = checkLinkAndUse([fs], false, false, "program with no vertex shader should fail to link");
+    var progBad3 = checkLinkAndUse([vsBad, fs], false, false, "program with bad vertex shader should fail to link");
+    var progBad4 = checkLinkAndUse([vs, fsBad], false, false, "program with bad fragment shader should fail to link");
+    var progBad5 = checkLinkAndUse([vsBad, fsBad], false, false, "program with bad shaders should fail to link");
 
     gl.useProgram(progGood1);
-    assertMsg(gl.getError() == gl.NO_ERROR,
-              "using a valid program shouldn't generate a GL error");
+    glErrorShouldBe(gl, gl.NO_ERROR, "using a valid program shouldn't generate a GL error");
 
     var vbuf = gl.createBuffer();
     gl.bindBuffer(gl.ARRAY_BUFFER, vbuf);
@@ -197,22 +202,21 @@ function go() {
     gl.enableVertexAttribArray(0);
     gl.vertexAttrib3f(1, 1.0, 0.0, 0.0);
 
-    assertMsg(gl.getError() == gl.NO_ERROR,
-              "should be no errors at this point #2");
+    glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors at this point #2");
 
     gl.useProgram(progGood1);
     gl.drawArrays(gl.TRIANGLES, 0, 3);
-    assertMsg(gl.getError() == gl.NO_ERROR,
-              "drawing with a valid program shouldn't generate a GL error");
+    glErrorShouldBe(gl, gl.NO_ERROR, "drawing with a valid program shouldn't generate a GL error");
 
     gl.useProgram(progBad1);
-    assertMsg(gl.getError() == gl.INVALID_OPERATION,
-              "using an invalid program should generate INVALID_OPERATION");
+    glErrorShouldBe(gl, gl.INVALID_OPERATION, "using an invalid program should generate INVALID_OPERATION");
     gl.drawArrays(gl.TRIANGLES, 0, 3);
-    assertMsg(gl.getError() != gl.NO_ERROR,
-              "drawing with an invalid program should generate some GL error XXX");
+    glErrorShouldBe(gl, gl.NO_ERROR, "Try to use an invalid program should not change the current rendering state");
 
     gl.useProgram(progGood2);
+    gl.drawArrays(gl.TRIANGLES, 0, 3);
+    glErrorShouldBe(gl, gl.NO_ERROR, "drawing with a valid program shouldn't generate a GL error");
+    gl.detachShader(progGood2, fs2);
     gl.attachShader(progGood2, fsBad);
     gl.linkProgram(progGood2);
     assertMsg(gl.getProgramParameter(progGood2, gl.LINK_STATUS) == false,
@@ -220,14 +224,61 @@ function go() {
 
     gl.useProgram(progGood1);
     gl.drawArrays(gl.TRIANGLES, 0, 4);
-    assertMsg(gl.getError() == gl.NO_ERROR,
-              "drawing with a valid when last used program shouldn't generate a GL error");
+    glErrorShouldBe(gl, gl.NO_ERROR, "drawing with a valid when last used program shouldn't generate a GL error");
+
+    var progGood1 = checkLinkAndUse([vs, fs], true, true, "delete shaders after attaching them and before linking program should not affect linkProgram");
+    gl.useProgram(progGood1);
+    gl.drawArrays(gl.TRIANGLES, 0, 4);
+    glErrorShouldBe(gl, gl.NO_ERROR, "drawing with a valid when last used program shouldn't generate a GL error");
+
+/////// Check deleteProgram() and deleteShader() /////////////////////////////
+
+    gl.useProgram(progGood1);
+    gl.deleteProgram(progGood1);
+    gl.drawArrays(gl.TRIANGLES, 0, 4);
+    glErrorShouldBe(gl, gl.NO_ERROR, "delete the current program shouldn't change the current rendering state");
+
+    gl.linkProgram(progGood1);
+    glErrorShouldBe(gl, gl.NO_ERROR, "The current program shouldn't be deleted");
+
+    var fs3 = gl.createShader(gl.FRAGMENT_SHADER);
+    gl.shaderSource(fs3, "#ifdef GL_ES\nprecision mediump float;\n#endif\n varying vec4 vColor; void main() { gl_FragColor = vColor; }");
+    gl.compileShader(fs3);
+
+    assertMsg(gl.getShaderParameter(fs3, gl.COMPILE_STATUS) == true,
+              "good fragment shader should compile");
+
+    gl.deleteShader(fs3);
+    gl.compileShader(fs3);
+    glErrorShouldBe(gl, gl.INVALID_VALUE, "an unattached shader should be deleted immediately");
+
+    fs3 = gl.createShader(gl.FRAGMENT_SHADER);
+    gl.shaderSource(fs3, "#ifdef GL_ES\nprecision mediump float;\n#endif\n varying vec4 vColor; void main() { gl_FragColor = vColor; }");
+    gl.compileShader(fs3);
+
+    assertMsg(gl.getShaderParameter(fs3, gl.COMPILE_STATUS) == true,
+              "good fragment shader should compile");
+
+    gl.detachShader(progGood1, fs);
+    gl.attachShader(progGood1, fs3);
+
+    gl.deleteShader(fs3);
+    gl.compileShader(fs3);
+    assertMsg(gl.getShaderParameter(fs3, gl.COMPILE_STATUS) == true,
+              "an attached shader shouldn't be deleted");
+
+    gl.useProgram(null);
+    gl.linkProgram(progGood1);
+    glErrorShouldBe(gl, gl.INVALID_VALUE, "a delete-marked program should be deleted once it's no longer the current program");
+
+    gl.compileShader(fs3);
+    glErrorShouldBe(gl, gl.INVALID_VALUE, "a delete-marked shader should be deleted once all its attachments are removed");
 }
 
 debug("");
-successfullyParsed = true;
-
 go();
+
+successfullyParsed = true;
 </script>
 <script src="../../js/resources/js-test-post.js"></script>
 
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 931918d..5a46aa2 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,35 @@
+2010-08-11  Zhenyao Mo  <zmo at google.com>
+
+        Reviewed by Dimitri Glazkov.
+
+        Regression in linking of programs
+        https://bugs.webkit.org/show_bug.cgi?id=43820
+
+        Shaders and programs shouldn't be deleted until their attachments are removed, therefore, we need to track the attach/detach/useProgram.
+
+        * html/canvas/WebGLObject.cpp: Track the object attachment count and whether it should really be deleted.
+        (WebCore::WebGLObject::WebGLObject):
+        (WebCore::WebGLObject::setObject):
+        (WebCore::WebGLObject::deleteObject):
+        * html/canvas/WebGLObject.h: Track the object attachment count and whether it should really be deleted.
+        (WebCore::WebGLObject::onAttached):
+        (WebCore::WebGLObject::onDetached):
+        (WebCore::WebGLObject::getAttachmentCount):
+        * html/canvas/WebGLProgram.cpp: Track the attached shaders.
+        (WebCore::WebGLProgram::WebGLProgram):
+        (WebCore::WebGLProgram::deleteObjectImpl):
+        (WebCore::WebGLProgram::getAttachedShader):
+        (WebCore::WebGLProgram::attachShader):
+        (WebCore::WebGLProgram::detachShader):
+        * html/canvas/WebGLProgram.h: Track the attached shaders.
+        * html/canvas/WebGLRenderingContext.cpp:
+        (WebCore::WebGLRenderingContext::attachShader): Track the attachment of a shader to a program.
+        (WebCore::WebGLRenderingContext::deleteProgram): Detach shaders.
+        (WebCore::WebGLRenderingContext::detachShader): Track the attachment of a shader to a program.
+        (WebCore::WebGLRenderingContext::validateWebGLObject): Also check if object == 0.
+        (WebCore::WebGLRenderingContext::linkProgram): Using the cached attached shaders instead of query from driver.
+        (WebCore::WebGLRenderingContext::useProgram): Track the attachment of a program to the current rendering pipeline.
+
 2010-08-13  Steve Block  <steveblock at google.com>
 
         Reviewed by Alexey Proskuryakov.
diff --git a/WebCore/html/canvas/WebGLObject.cpp b/WebCore/html/canvas/WebGLObject.cpp
index 6a34269..5fd5534 100644
--- a/WebCore/html/canvas/WebGLObject.cpp
+++ b/WebCore/html/canvas/WebGLObject.cpp
@@ -35,8 +35,9 @@ namespace WebCore {
     
 WebGLObject::WebGLObject(WebGLRenderingContext* context)
     : m_object(0)
-    , m_shouldDeleteObject(true)
     , m_context(context)
+    , m_attachmentCount(0)
+    , m_deleted(false)
 {
 }
 
@@ -46,27 +47,26 @@ WebGLObject::~WebGLObject()
         m_context->removeObject(this);
 }
 
-void WebGLObject::setObject(Platform3DObject object, bool shouldDeleteObject)
+void WebGLObject::setObject(Platform3DObject object)
 {
     if (object == m_object)
         return;
         
     deleteObject();
     m_object = object;
-    m_shouldDeleteObject = shouldDeleteObject;
 }
 
 void WebGLObject::deleteObject()
 {
     if (m_object) {
-        if (m_shouldDeleteObject)
-            if (m_context) {
-                m_context->graphicsContext3D()->makeContextCurrent();
-                deleteObjectImpl(m_object);
-            }
-        m_object = 0;
+        if (m_context) {
+            m_context->graphicsContext3D()->makeContextCurrent();
+            deleteObjectImpl(m_object);
+        }
+        if (!m_attachmentCount)
+            m_object = 0;
+        m_deleted = true;
     }
-    m_shouldDeleteObject = true;
 }
 
 }
diff --git a/WebCore/html/canvas/WebGLObject.h b/WebCore/html/canvas/WebGLObject.h
index b66311f..18d4cf9 100644
--- a/WebCore/html/canvas/WebGLObject.h
+++ b/WebCore/html/canvas/WebGLObject.h
@@ -40,7 +40,7 @@ public:
     virtual ~WebGLObject();
 
     Platform3DObject object() const { return m_object; }
-    void setObject(Platform3DObject, bool shouldDeleteObject = true);
+    void setObject(Platform3DObject);
     void deleteObject();
 
     void detachContext()
@@ -58,20 +58,25 @@ public:
     virtual bool isShader() const { return false; }
     virtual bool isTexture() const { return false; }
 
+    void onAttached() { ++m_attachmentCount; }
+    void onDetached()
+    {
+        if (m_attachmentCount)
+            --m_attachmentCount;
+        if (!m_attachmentCount && m_deleted)
+            m_object = 0;
+    }
+    unsigned getAttachmentCount() { return m_attachmentCount; }
+
 protected:
     WebGLObject(WebGLRenderingContext*);
     virtual void deleteObjectImpl(Platform3DObject) = 0;
 
 private:
     Platform3DObject m_object;
-    // The shouldDeleteObject flag indicates whether this wrapper
-    // owns the underlying resource and should delete it when the
-    // wrapper is unreferenced for the last time and deleted. It
-    // is only set to false for certain objects returned from get
-    // queries. FIXME: should consider canonicalizing all of these
-    // objects in the future.
-    bool m_shouldDeleteObject;
     WebGLRenderingContext* m_context;
+    unsigned m_attachmentCount;
+    bool m_deleted;
 };
 
 } // namespace WebCore
diff --git a/WebCore/html/canvas/WebGLProgram.cpp b/WebCore/html/canvas/WebGLProgram.cpp
index 846b171..8cf3c42 100644
--- a/WebCore/html/canvas/WebGLProgram.cpp
+++ b/WebCore/html/canvas/WebGLProgram.cpp
@@ -45,9 +45,15 @@ WebGLProgram::WebGLProgram(WebGLRenderingContext* ctx)
     setObject(context()->graphicsContext3D()->createProgram());
 }
 
-void WebGLProgram::deleteObjectImpl(Platform3DObject object)
+void WebGLProgram::deleteObjectImpl(Platform3DObject obj)
 {
-    context()->graphicsContext3D()->deleteProgram(object);
+    context()->graphicsContext3D()->deleteProgram(obj);
+    if (!object()) {
+        if (m_vertexShader)
+            m_vertexShader->onDetached();
+        if (m_fragmentShader)
+            m_fragmentShader->onDetached();
+    }
 }
 
 bool WebGLProgram::cacheActiveAttribLocations()
@@ -94,6 +100,58 @@ bool WebGLProgram::isUsingVertexAttrib0() const
     return false;
 }
 
+WebGLShader* WebGLProgram::getAttachedShader(GraphicsContext3D::WebGLEnumType type)
+{
+    switch (type) {
+    case GraphicsContext3D::VERTEX_SHADER:
+        return m_vertexShader.get();
+    case GraphicsContext3D::FRAGMENT_SHADER:
+        return m_fragmentShader.get();
+    default:
+        return 0;
+    }
+}
+
+bool WebGLProgram::attachShader(WebGLShader* shader)
+{
+    if (!shader || !shader->object())
+        return false;
+    switch (shader->getType()) {
+    case GraphicsContext3D::VERTEX_SHADER:
+        if (m_vertexShader)
+            return false;
+        m_vertexShader = shader;
+        return true;
+    case GraphicsContext3D::FRAGMENT_SHADER:
+        if (m_fragmentShader)
+            return false;
+        m_fragmentShader = shader;
+        return true;
+    default:
+        return false;
+    }
+}
+
+bool WebGLProgram::detachShader(WebGLShader* shader)
+{
+    if (!shader || !shader->object())
+        return false;
+    switch (shader->getType()) {
+    case GraphicsContext3D::VERTEX_SHADER:
+        if (m_vertexShader != shader)
+            return false;
+        m_vertexShader = 0;
+        return true;
+    case GraphicsContext3D::FRAGMENT_SHADER:
+        if (m_fragmentShader != shader)
+            return false;
+        m_fragmentShader = 0;
+        return true;
+    default:
+        return false;
+    }
+}
+
 }
 
 #endif // ENABLE(3D_CANVAS)
diff --git a/WebCore/html/canvas/WebGLProgram.h b/WebCore/html/canvas/WebGLProgram.h
index 0156938..e5548eb 100644
--- a/WebCore/html/canvas/WebGLProgram.h
+++ b/WebCore/html/canvas/WebGLProgram.h
@@ -28,6 +28,8 @@
 
 #include "WebGLObject.h"
 
+#include "WebGLShader.h"
+
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefCounted.h>
 #include <wtf/Vector.h>
@@ -54,6 +56,10 @@ public:
     bool isLinkFailureFlagSet() const { return m_linkFailure; }
     void setLinkFailureFlag(bool failed) { m_linkFailure = failed; }
 
+    WebGLShader* getAttachedShader(GraphicsContext3D::WebGLEnumType);
+    bool attachShader(WebGLShader*);
+    bool detachShader(WebGLShader*);
+
 protected:
     WebGLProgram(WebGLRenderingContext*);
 
@@ -65,6 +71,9 @@ private:
     Vector<int> m_activeAttribLocations;
 
     bool m_linkFailure;
+
+    RefPtr<WebGLShader> m_vertexShader;
+    RefPtr<WebGLShader> m_fragmentShader;
 };
 
 } // namespace WebCore
diff --git a/WebCore/html/canvas/WebGLRenderingContext.cpp b/WebCore/html/canvas/WebGLRenderingContext.cpp
index a553b77..b4ea464 100644
--- a/WebCore/html/canvas/WebGLRenderingContext.cpp
+++ b/WebCore/html/canvas/WebGLRenderingContext.cpp
@@ -217,7 +217,12 @@ void WebGLRenderingContext::attachShader(WebGLProgram* program, WebGLShader* sha
     UNUSED_PARAM(ec);
     if (!validateWebGLObject(program) || !validateWebGLObject(shader))
         return;
+    if (!program->attachShader(shader)) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+        return;
+    }
     m_context->attachShader(objectOrZero(program), objectOrZero(shader));
+    shader->onAttached();
     cleanupAfterGraphicsCall(false);
 }
 
@@ -650,7 +655,12 @@ void WebGLRenderingContext::deleteProgram(WebGLProgram* program)
 {
     if (!program)
         return;
-    
+    if (program->context() != this) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+        return;
+    }
+    if (!program->object())
+        return;
     program->deleteObject();
 }
 
@@ -705,7 +715,12 @@ void WebGLRenderingContext::detachShader(WebGLProgram* program, WebGLShader* sha
     UNUSED_PARAM(ec);
     if (!validateWebGLObject(program) || !validateWebGLObject(shader))
         return;
+    if (!program->detachShader(shader)) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+        return;
+    }
     m_context->detachShader(objectOrZero(program), objectOrZero(shader));
+    shader->onDetached();
     cleanupAfterGraphicsCall(false);
 }
 
@@ -892,7 +907,7 @@ bool WebGLRenderingContext::validateRenderingState(long numElementsRequired)
 
 bool WebGLRenderingContext::validateWebGLObject(WebGLObject* object)
 {
-    if (!object) {
+    if (!object || !object->object()) {
         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return false;
     }
@@ -1882,21 +1897,7 @@ void WebGLRenderingContext::linkProgram(WebGLProgram* program, ExceptionCode& ec
     if (!validateWebGLObject(program))
         return;
     if (!isGLES2Compliant()) {
-        Vector<WebGLShader*> shaders;
-        bool succeed = getAttachedShaders(program, shaders, ec);
-        if (succeed) {
-            bool vShader = false;
-            bool fShader = false;
-            for (size_t ii = 0; ii < shaders.size() && (!vShader || !fShader); ++ii) {
-                if (shaders[ii]->getType() == GraphicsContext3D::VERTEX_SHADER)
-                    vShader = true;
-                else if (shaders[ii]->getType() == GraphicsContext3D::FRAGMENT_SHADER)
-                    fShader = true;
-            }
-            if (!vShader || !fShader)
-                succeed = false;
-        }
-        if (!succeed) {
+        if (!program->getAttachedShader(GraphicsContext3D::VERTEX_SHADER) || !program->getAttachedShader(GraphicsContext3D::FRAGMENT_SHADER)) {
             program->setLinkFailureFlag(true);
             return;
         }
@@ -2701,13 +2702,23 @@ void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* locatio
 
 void WebGLRenderingContext::useProgram(WebGLProgram* program, ExceptionCode& ec)
 {
-    UNUSED_PARAM(ec);
     if (program && program->context() != this) {
         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    m_currentProgram = program;
-    m_context->useProgram(objectOrZero(program));
+    if (program && program->object() && !getProgramParameter(program, GraphicsContext3D::LINK_STATUS, ec).getBool()) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+        cleanupAfterGraphicsCall(false);
+        return;
+    }
+    if (m_currentProgram != program) {
+        if (m_currentProgram)
+            m_currentProgram->onDetached();
+        m_currentProgram = program;
+        m_context->useProgram(objectOrZero(program));
+        if (program)
+            program->onAttached();
+    }
     cleanupAfterGraphicsCall(false);
 }
 

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list