Changeset 65330 in webkit


Ignore:
Timestamp:
Aug 13, 2010 10:12:19 AM (14 years ago)
Author:
zmo@google.com
Message:

2010-08-11 Zhenyao Mo <zmo@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@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.
Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r65329 r65330  
     12010-08-11  Zhenyao Mo  <zmo@google.com>
     2
     3        Reviewed by Dimitri Glazkov.
     4
     5        Regression in linking of programs
     6        https://bugs.webkit.org/show_bug.cgi?id=43820
     7
     8        * 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.
     9        * fast/canvas/webgl/program-test.html: Ditto.
     10
    1112010-08-13  Steve Block  <steveblock@google.com>
    212
  • trunk/LayoutTests/fast/canvas/webgl/program-test-expected.txt

    r62396 r65330  
    1313PASS good fragment shader #2 should compile
    1414PASS bad fragment shader should fail to compile
    15 PASS should be no errors at this point
    16 PASS attaching a vertex shader should succeed
    17 PASS attaching an already attached vertex shader should generate INVALID_OPERATION
    18 PASS attaching a fragment shader should succeed
    19 PASS attaching an already attached fragment shader should generate INVALID_OPERATION
    20 PASS detaching a vertex shader should succeed
    21 PASS detaching a not already attached vertex shader should generate INVALID_OPERATION
    22 PASS detaching a fragment shader should succeed
    23 PASS detaching a not already attached fragment shader should generate INVALID_OPERATION
     15PASS getError was expected value: NO_ERROR : should be no errors at this point
     16PASS getError was expected value: NO_ERROR : attaching a vertex shader should succeed
     17PASS getError was expected value: INVALID_OPERATION : attaching an already attached vertex shader should generate INVALID_OPERATION
     18PASS getError was expected value: NO_ERROR : attaching a fragment shader should succeed
     19PASS getError was expected value: INVALID_OPERATION : attaching an already attached fragment shader should generate INVALID_OPERATION
     20PASS getError was expected value: INVALID_OPERATION : attaching shaders of the same type to a program should generate INVALID_OPERATION
     21PASS getError was expected value: INVALID_OPERATION : attaching shaders of the same type to a program should generate INVALID_OPERATION
     22PASS getError was expected value: NO_ERROR : detaching a vertex shader should succeed
     23PASS getError was expected value: INVALID_OPERATION : detaching a not already attached vertex shader should generate INVALID_OPERATION
     24PASS getError was expected value: NO_ERROR : detaching a fragment shader should succeed
     25PASS getError was expected value: INVALID_OPERATION : detaching a not already attached fragment shader should generate INVALID_OPERATION
    2426PASS getAttachedShaders should return an empty list by default
    2527PASS attaching a single shader should give the expected list
     
    3335PASS attaching shaders, including one that failed to compile, should still show the it in the list
    3436PASS valid program should link
    35 PASS using a valid program should succeed
     37PASS getError was expected value: NO_ERROR : using a valid program should succeed
    3638PASS valid program #2 should link
    37 PASS using a valid program should succeed
     39PASS getError was expected value: NO_ERROR : using a valid program should succeed
    3840PASS program with no fragment shader should fail to link
    39 PASS using an invalid program should generate INVALID_OPERATION
     41PASS getError was expected value: INVALID_OPERATION : using an invalid program should generate INVALID_OPERATION
    4042PASS program with no vertex shader should fail to link
    41 PASS using an invalid program should generate INVALID_OPERATION
     43PASS getError was expected value: INVALID_OPERATION : using an invalid program should generate INVALID_OPERATION
    4244PASS program with bad vertex shader should fail to link
    43 PASS using an invalid program should generate INVALID_OPERATION
     45PASS getError was expected value: INVALID_OPERATION : using an invalid program should generate INVALID_OPERATION
    4446PASS program with bad fragment shader should fail to link
    45 PASS using an invalid program should generate INVALID_OPERATION
     47PASS getError was expected value: INVALID_OPERATION : using an invalid program should generate INVALID_OPERATION
    4648PASS program with bad shaders should fail to link
    47 PASS using an invalid program should generate INVALID_OPERATION
    48 PASS using a valid program shouldn't generate a GL error
    49 PASS should be no errors at this point #2
    50 PASS drawing with a valid program shouldn't generate a GL error
    51 PASS using an invalid program should generate INVALID_OPERATION
    52 PASS drawing with an invalid program should generate some GL error XXX
     49PASS getError was expected value: INVALID_OPERATION : using an invalid program should generate INVALID_OPERATION
     50PASS getError was expected value: NO_ERROR : using a valid program shouldn't generate a GL error
     51PASS getError was expected value: NO_ERROR : should be no errors at this point #2
     52PASS getError was expected value: NO_ERROR : drawing with a valid program shouldn't generate a GL error
     53PASS getError was expected value: INVALID_OPERATION : using an invalid program should generate INVALID_OPERATION
     54PASS getError was expected value: NO_ERROR : Try to use an invalid program should not change the current rendering state
     55PASS getError was expected value: NO_ERROR : drawing with a valid program shouldn't generate a GL error
    5356PASS linking should fail with in-use formerly good program, with new bad shader attached
    54 PASS drawing with a valid when last used program shouldn't generate a GL error
     57PASS getError was expected value: NO_ERROR : drawing with a valid when last used program shouldn't generate a GL error
     58PASS delete shaders after attaching them and before linking program should not affect linkProgram
     59PASS getError was expected value: NO_ERROR : using a valid program should succeed
     60PASS getError was expected value: NO_ERROR : drawing with a valid when last used program shouldn't generate a GL error
     61PASS getError was expected value: NO_ERROR : delete the current program shouldn't change the current rendering state
     62PASS getError was expected value: NO_ERROR : The current program shouldn't be deleted
     63PASS good fragment shader should compile
     64PASS getError was expected value: INVALID_VALUE : an unattached shader should be deleted immediately
     65PASS good fragment shader should compile
     66PASS an attached shader shouldn't be deleted
     67PASS getError was expected value: INVALID_VALUE : a delete-marked program should be deleted once it's no longer the current program
     68PASS getError was expected value: INVALID_VALUE : a delete-marked shader should be deleted once all its attachments are removed
    5569PASS successfullyParsed is true
    5670
  • trunk/LayoutTests/fast/canvas/webgl/program-test.html

    r62396 r65330  
    7676              "bad fragment shader should fail to compile");
    7777
    78     assertMsg(gl.getError() == gl.NO_ERROR,
    79               "should be no errors at this point");
     78    glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors at this point");
    8079
    8180/////// Check attachShader() /////////////////////////////
     
    8887            assertMsg(false, "unexpected error in attachShader()");
    8988        gl.attachShader(prog, shader);
    90         assertMsg(gl.getError() == expected_error_code, errmsg);
     89        glErrorShouldBe(gl, expected_error_code, errmsg);
    9190    }
    9291
     
    9796    checkAttachShader([fs], fs, gl.INVALID_OPERATION,
    9897                      "attaching an already attached fragment shader should generate INVALID_OPERATION");
     98    checkAttachShader([vs], vs2, gl.INVALID_OPERATION,
     99                      "attaching shaders of the same type to a program should generate INVALID_OPERATION");
     100    checkAttachShader([fs], fs2, gl.INVALID_OPERATION,
     101                      "attaching shaders of the same type to a program should generate INVALID_OPERATION");
    99102
    100103/////// Check detachShader() /////////////////////////////
     
    107110            assertMsg(false, "unexpected error in attachShader()");
    108111        gl.detachShader(prog, shader);
    109         assertMsg(gl.getError() == expected_error_code, errmsg);
     112        glErrorShouldBe(gl, expected_error_code, errmsg);
    110113    }
    111114
     
    133136    checkGetAttachedShaders([], [], [], "getAttachedShaders should return an empty list by default");
    134137    checkGetAttachedShaders([fs], [], [fs], "attaching a single shader should give the expected list");
    135     checkGetAttachedShaders([fs, vs, fs2, vs2], [], [fs, vs, fs2, vs2],
     138    checkGetAttachedShaders([fs, vs], [], [fs, vs],
    136139        "attaching some shaders should give the expected list");
    137140    checkGetAttachedShaders([fs], [fs], [], "attaching a shader and detaching it shoud leave an empty list");
    138     checkGetAttachedShaders([fs, vs, fs2, vs2], [fs, vs, fs2, vs2], [],
     141    checkGetAttachedShaders([fs, vs], [fs, vs], [],
    139142        "attaching some shaders and detaching them in same order shoud leave an empty list");
    140     checkGetAttachedShaders([fs, vs, fs2, vs2], [fs, vs2, vs, fs2], [],
     143    checkGetAttachedShaders([fs, vs], [vs, fs], [],
    141144        "attaching some shaders and detaching them in random order shoud leave an empty list");
    142     checkGetAttachedShaders([fs, vs, fs2, vs2], [vs], [fs, fs2, vs2],
     145    checkGetAttachedShaders([fs, vs], [vs], [fs],
    143146        "attaching and detaching some shaders should leave the difference list");
    144     checkGetAttachedShaders([fs, vs, fs2, vs2], [fs, vs2], [vs, fs2],
     147    checkGetAttachedShaders([fs, vs], [fs], [vs],
    145148        "attaching and detaching some shaders should leave the difference list");
    146149    checkGetAttachedShaders([fsBad], [], [fsBad],
    147150        "attaching a shader that failed to compile should still show it in the list");
    148     checkGetAttachedShaders([fs, vsBad, fs2], [], [fs, vsBad, fs2],
     151    checkGetAttachedShaders([fs, vsBad], [], [fs, vsBad],
    149152        "attaching shaders, including one that failed to compile, should still show the it in the list");
    150153
    151154/////// Check linkProgram() and useProgram /////////////////////////////
    152155
    153     function checkLinkAndUse(shaders, expected_status, errmsg) {
    154         var prog = gl.createProgram();
    155         for (var i = 0; i < shaders.length; ++i)
     156    function checkLinkAndUse(shaders, deleteShaderAfterAttach, expected_status, errmsg) {
     157        var prog = gl.createProgram();
     158        for (var i = 0; i < shaders.length; ++i) {
    156159            gl.attachShader(prog, shaders[i]);
     160            if (deleteShaderAfterAttach)
     161                gl.deleteShader(shaders[i]);
     162        }
    157163        gl.bindAttribLocation(prog, 0, "aVertex");
    158164        gl.bindAttribLocation(prog, 1, "aColor");
     
    167173        gl.useProgram(prog);
    168174        if (expected_status == true)
    169             assertMsg(gl.getError() == gl.NO_ERROR, "using a valid program should succeed");
     175            glErrorShouldBe(gl, gl.NO_ERROR, "using a valid program should succeed");
    170176        if (expected_status == false)
    171             assertMsg(gl.getError() == gl.INVALID_OPERATION, "using an invalid program should generate INVALID_OPERATION");
     177            glErrorShouldBe(gl, gl.INVALID_OPERATION, "using an invalid program should generate INVALID_OPERATION");
    172178        return prog;
    173179    }
    174180
    175     var progGood1 = checkLinkAndUse([vs, fs], true, "valid program should link");
    176     var progGood2 = checkLinkAndUse([vs, fs2], true, "valid program #2 should link");
    177     var progBad1 = checkLinkAndUse([vs], false, "program with no fragment shader should fail to link");
    178     var progBad2 = checkLinkAndUse([fs], false, "program with no vertex shader should fail to link");
    179     var progBad3 = checkLinkAndUse([vsBad, fs], false, "program with bad vertex shader should fail to link");
    180     var progBad4 = checkLinkAndUse([vs, fsBad], false, "program with bad fragment shader should fail to link");
    181     var progBad5 = checkLinkAndUse([vsBad, fsBad], false, "program with bad shaders should fail to link");
    182 
    183     gl.useProgram(progGood1);
    184     assertMsg(gl.getError() == gl.NO_ERROR,
    185               "using a valid program shouldn't generate a GL error");
     181    var progGood1 = checkLinkAndUse([vs, fs], false, true, "valid program should link");
     182    var progGood2 = checkLinkAndUse([vs, fs2], false, true, "valid program #2 should link");
     183    var progBad1 = checkLinkAndUse([vs], false, false, "program with no fragment shader should fail to link");
     184    var progBad2 = checkLinkAndUse([fs], false, false, "program with no vertex shader should fail to link");
     185    var progBad3 = checkLinkAndUse([vsBad, fs], false, false, "program with bad vertex shader should fail to link");
     186    var progBad4 = checkLinkAndUse([vs, fsBad], false, false, "program with bad fragment shader should fail to link");
     187    var progBad5 = checkLinkAndUse([vsBad, fsBad], false, false, "program with bad shaders should fail to link");
     188
     189    gl.useProgram(progGood1);
     190    glErrorShouldBe(gl, gl.NO_ERROR, "using a valid program shouldn't generate a GL error");
    186191
    187192    var vbuf = gl.createBuffer();
     
    198203    gl.vertexAttrib3f(1, 1.0, 0.0, 0.0);
    199204
    200     assertMsg(gl.getError() == gl.NO_ERROR,
    201               "should be no errors at this point #2");
     205    glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors at this point #2");
    202206
    203207    gl.useProgram(progGood1);
    204208    gl.drawArrays(gl.TRIANGLES, 0, 3);
    205     assertMsg(gl.getError() == gl.NO_ERROR,
    206               "drawing with a valid program shouldn't generate a GL error");
     209    glErrorShouldBe(gl, gl.NO_ERROR, "drawing with a valid program shouldn't generate a GL error");
    207210
    208211    gl.useProgram(progBad1);
    209     assertMsg(gl.getError() == gl.INVALID_OPERATION,
    210               "using an invalid program should generate INVALID_OPERATION");
     212    glErrorShouldBe(gl, gl.INVALID_OPERATION, "using an invalid program should generate INVALID_OPERATION");
    211213    gl.drawArrays(gl.TRIANGLES, 0, 3);
    212     assertMsg(gl.getError() != gl.NO_ERROR,
    213               "drawing with an invalid program should generate some GL error XXX");
     214    glErrorShouldBe(gl, gl.NO_ERROR, "Try to use an invalid program should not change the current rendering state");
    214215
    215216    gl.useProgram(progGood2);
     217    gl.drawArrays(gl.TRIANGLES, 0, 3);
     218    glErrorShouldBe(gl, gl.NO_ERROR, "drawing with a valid program shouldn't generate a GL error");
     219    gl.detachShader(progGood2, fs2);
    216220    gl.attachShader(progGood2, fsBad);
    217221    gl.linkProgram(progGood2);
     
    221225    gl.useProgram(progGood1);
    222226    gl.drawArrays(gl.TRIANGLES, 0, 4);
    223     assertMsg(gl.getError() == gl.NO_ERROR,
    224               "drawing with a valid when last used program shouldn't generate a GL error");
     227    glErrorShouldBe(gl, gl.NO_ERROR, "drawing with a valid when last used program shouldn't generate a GL error");
     228
     229    var progGood1 = checkLinkAndUse([vs, fs], true, true, "delete shaders after attaching them and before linking program should not affect linkProgram");
     230    gl.useProgram(progGood1);
     231    gl.drawArrays(gl.TRIANGLES, 0, 4);
     232    glErrorShouldBe(gl, gl.NO_ERROR, "drawing with a valid when last used program shouldn't generate a GL error");
     233
     234/////// Check deleteProgram() and deleteShader() /////////////////////////////
     235
     236    gl.useProgram(progGood1);
     237    gl.deleteProgram(progGood1);
     238    gl.drawArrays(gl.TRIANGLES, 0, 4);
     239    glErrorShouldBe(gl, gl.NO_ERROR, "delete the current program shouldn't change the current rendering state");
     240
     241    gl.linkProgram(progGood1);
     242    glErrorShouldBe(gl, gl.NO_ERROR, "The current program shouldn't be deleted");
     243
     244    var fs3 = gl.createShader(gl.FRAGMENT_SHADER);
     245    gl.shaderSource(fs3, "#ifdef GL_ES\nprecision mediump float;\n#endif\n varying vec4 vColor; void main() { gl_FragColor = vColor; }");
     246    gl.compileShader(fs3);
     247
     248    assertMsg(gl.getShaderParameter(fs3, gl.COMPILE_STATUS) == true,
     249              "good fragment shader should compile");
     250
     251    gl.deleteShader(fs3);
     252    gl.compileShader(fs3);
     253    glErrorShouldBe(gl, gl.INVALID_VALUE, "an unattached shader should be deleted immediately");
     254
     255    fs3 = gl.createShader(gl.FRAGMENT_SHADER);
     256    gl.shaderSource(fs3, "#ifdef GL_ES\nprecision mediump float;\n#endif\n varying vec4 vColor; void main() { gl_FragColor = vColor; }");
     257    gl.compileShader(fs3);
     258
     259    assertMsg(gl.getShaderParameter(fs3, gl.COMPILE_STATUS) == true,
     260              "good fragment shader should compile");
     261
     262    gl.detachShader(progGood1, fs);
     263    gl.attachShader(progGood1, fs3);
     264
     265    gl.deleteShader(fs3);
     266    gl.compileShader(fs3);
     267    assertMsg(gl.getShaderParameter(fs3, gl.COMPILE_STATUS) == true,
     268              "an attached shader shouldn't be deleted");
     269
     270    gl.useProgram(null);
     271    gl.linkProgram(progGood1);
     272    glErrorShouldBe(gl, gl.INVALID_VALUE, "a delete-marked program should be deleted once it's no longer the current program");
     273
     274    gl.compileShader(fs3);
     275    glErrorShouldBe(gl, gl.INVALID_VALUE, "a delete-marked shader should be deleted once all its attachments are removed");
    225276}
    226277
    227278debug("");
     279go();
     280
    228281successfullyParsed = true;
    229 
    230 go();
    231282</script>
    232283<script src="../../js/resources/js-test-post.js"></script>
  • trunk/WebCore/ChangeLog

    r65329 r65330  
     12010-08-11  Zhenyao Mo  <zmo@google.com>
     2
     3        Reviewed by Dimitri Glazkov.
     4
     5        Regression in linking of programs
     6        https://bugs.webkit.org/show_bug.cgi?id=43820
     7
     8        Shaders and programs shouldn't be deleted until their attachments are removed, therefore, we need to track the attach/detach/useProgram.
     9
     10        * html/canvas/WebGLObject.cpp: Track the object attachment count and whether it should really be deleted.
     11        (WebCore::WebGLObject::WebGLObject):
     12        (WebCore::WebGLObject::setObject):
     13        (WebCore::WebGLObject::deleteObject):
     14        * html/canvas/WebGLObject.h: Track the object attachment count and whether it should really be deleted.
     15        (WebCore::WebGLObject::onAttached):
     16        (WebCore::WebGLObject::onDetached):
     17        (WebCore::WebGLObject::getAttachmentCount):
     18        * html/canvas/WebGLProgram.cpp: Track the attached shaders.
     19        (WebCore::WebGLProgram::WebGLProgram):
     20        (WebCore::WebGLProgram::deleteObjectImpl):
     21        (WebCore::WebGLProgram::getAttachedShader):
     22        (WebCore::WebGLProgram::attachShader):
     23        (WebCore::WebGLProgram::detachShader):
     24        * html/canvas/WebGLProgram.h: Track the attached shaders.
     25        * html/canvas/WebGLRenderingContext.cpp:
     26        (WebCore::WebGLRenderingContext::attachShader): Track the attachment of a shader to a program.
     27        (WebCore::WebGLRenderingContext::deleteProgram): Detach shaders.
     28        (WebCore::WebGLRenderingContext::detachShader): Track the attachment of a shader to a program.
     29        (WebCore::WebGLRenderingContext::validateWebGLObject): Also check if object == 0.
     30        (WebCore::WebGLRenderingContext::linkProgram): Using the cached attached shaders instead of query from driver.
     31        (WebCore::WebGLRenderingContext::useProgram): Track the attachment of a program to the current rendering pipeline.
     32
    1332010-08-13  Steve Block  <steveblock@google.com>
    234
  • trunk/WebCore/html/canvas/WebGLObject.cpp

    r64767 r65330  
    3636WebGLObject::WebGLObject(WebGLRenderingContext* context)
    3737    : m_object(0)
    38     , m_shouldDeleteObject(true)
    3938    , m_context(context)
     39    , m_attachmentCount(0)
     40    , m_deleted(false)
    4041{
    4142}
     
    4748}
    4849
    49 void WebGLObject::setObject(Platform3DObject object, bool shouldDeleteObject)
     50void WebGLObject::setObject(Platform3DObject object)
    5051{
    5152    if (object == m_object)
     
    5455    deleteObject();
    5556    m_object = object;
    56     m_shouldDeleteObject = shouldDeleteObject;
    5757}
    5858
     
    6060{
    6161    if (m_object) {
    62         if (m_shouldDeleteObject)
    63             if (m_context) {
    64                 m_context->graphicsContext3D()->makeContextCurrent();
    65                 deleteObjectImpl(m_object);
    66             }
    67         m_object = 0;
     62        if (m_context) {
     63            m_context->graphicsContext3D()->makeContextCurrent();
     64            deleteObjectImpl(m_object);
     65        }
     66        if (!m_attachmentCount)
     67            m_object = 0;
     68        m_deleted = true;
    6869    }
    69     m_shouldDeleteObject = true;
    7070}
    7171
  • trunk/WebCore/html/canvas/WebGLObject.h

    r64767 r65330  
    4141
    4242    Platform3DObject object() const { return m_object; }
    43     void setObject(Platform3DObject, bool shouldDeleteObject = true);
     43    void setObject(Platform3DObject);
    4444    void deleteObject();
    4545
     
    5959    virtual bool isTexture() const { return false; }
    6060
     61    void onAttached() { ++m_attachmentCount; }
     62    void onDetached()
     63    {
     64        if (m_attachmentCount)
     65            --m_attachmentCount;
     66        if (!m_attachmentCount && m_deleted)
     67            m_object = 0;
     68    }
     69    unsigned getAttachmentCount() { return m_attachmentCount; }
     70
    6171protected:
    6272    WebGLObject(WebGLRenderingContext*);
     
    6575private:
    6676    Platform3DObject m_object;
    67     // The shouldDeleteObject flag indicates whether this wrapper
    68     // owns the underlying resource and should delete it when the
    69     // wrapper is unreferenced for the last time and deleted. It
    70     // is only set to false for certain objects returned from get
    71     // queries. FIXME: should consider canonicalizing all of these
    72     // objects in the future.
    73     bool m_shouldDeleteObject;
    7477    WebGLRenderingContext* m_context;
     78    unsigned m_attachmentCount;
     79    bool m_deleted;
    7580};
    7681
  • trunk/WebCore/html/canvas/WebGLProgram.cpp

    r64767 r65330  
    4646}
    4747
    48 void WebGLProgram::deleteObjectImpl(Platform3DObject object)
     48void WebGLProgram::deleteObjectImpl(Platform3DObject obj)
    4949{
    50     context()->graphicsContext3D()->deleteProgram(object);
     50    context()->graphicsContext3D()->deleteProgram(obj);
     51    if (!object()) {
     52        if (m_vertexShader)
     53            m_vertexShader->onDetached();
     54        if (m_fragmentShader)
     55            m_fragmentShader->onDetached();
     56    }
    5157}
    5258
     
    95101}
    96102
     103WebGLShader* WebGLProgram::getAttachedShader(GraphicsContext3D::WebGLEnumType type)
     104{
     105    switch (type) {
     106    case GraphicsContext3D::VERTEX_SHADER:
     107        return m_vertexShader.get();
     108    case GraphicsContext3D::FRAGMENT_SHADER:
     109        return m_fragmentShader.get();
     110    default:
     111        return 0;
     112    }
     113}
     114
     115bool WebGLProgram::attachShader(WebGLShader* shader)
     116{
     117    if (!shader || !shader->object())
     118        return false;
     119    switch (shader->getType()) {
     120    case GraphicsContext3D::VERTEX_SHADER:
     121        if (m_vertexShader)
     122            return false;
     123        m_vertexShader = shader;
     124        return true;
     125    case GraphicsContext3D::FRAGMENT_SHADER:
     126        if (m_fragmentShader)
     127            return false;
     128        m_fragmentShader = shader;
     129        return true;
     130    default:
     131        return false;
     132    }
     133}
     134
     135bool WebGLProgram::detachShader(WebGLShader* shader)
     136{
     137    if (!shader || !shader->object())
     138        return false;
     139    switch (shader->getType()) {
     140    case GraphicsContext3D::VERTEX_SHADER:
     141        if (m_vertexShader != shader)
     142            return false;
     143        m_vertexShader = 0;
     144        return true;
     145    case GraphicsContext3D::FRAGMENT_SHADER:
     146        if (m_fragmentShader != shader)
     147            return false;
     148        m_fragmentShader = 0;
     149        return true;
     150    default:
     151        return false;
     152    }
     153}
     154
    97155}
    98156
  • trunk/WebCore/html/canvas/WebGLProgram.h

    r64767 r65330  
    2929#include "WebGLObject.h"
    3030
     31#include "WebGLShader.h"
     32
    3133#include <wtf/PassRefPtr.h>
    3234#include <wtf/RefCounted.h>
     
    5557    void setLinkFailureFlag(bool failed) { m_linkFailure = failed; }
    5658
     59    WebGLShader* getAttachedShader(GraphicsContext3D::WebGLEnumType);
     60    bool attachShader(WebGLShader*);
     61    bool detachShader(WebGLShader*);
     62
    5763protected:
    5864    WebGLProgram(WebGLRenderingContext*);
     
    6672
    6773    bool m_linkFailure;
     74
     75    RefPtr<WebGLShader> m_vertexShader;
     76    RefPtr<WebGLShader> m_fragmentShader;
    6877};
    6978
  • trunk/WebCore/html/canvas/WebGLRenderingContext.cpp

    r65279 r65330  
    218218    if (!validateWebGLObject(program) || !validateWebGLObject(shader))
    219219        return;
     220    if (!program->attachShader(shader)) {
     221        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
     222        return;
     223    }
    220224    m_context->attachShader(objectOrZero(program), objectOrZero(shader));
     225    shader->onAttached();
    221226    cleanupAfterGraphicsCall(false);
    222227}
     
    651656    if (!program)
    652657        return;
    653    
     658    if (program->context() != this) {
     659        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
     660        return;
     661    }
     662    if (!program->object())
     663        return;
    654664    program->deleteObject();
    655665}
     
    706716    if (!validateWebGLObject(program) || !validateWebGLObject(shader))
    707717        return;
     718    if (!program->detachShader(shader)) {
     719        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
     720        return;
     721    }
    708722    m_context->detachShader(objectOrZero(program), objectOrZero(shader));
     723    shader->onDetached();
    709724    cleanupAfterGraphicsCall(false);
    710725}
     
    893908bool WebGLRenderingContext::validateWebGLObject(WebGLObject* object)
    894909{
    895     if (!object) {
     910    if (!object || !object->object()) {
    896911        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
    897912        return false;
     
    18831898        return;
    18841899    if (!isGLES2Compliant()) {
    1885         Vector<WebGLShader*> shaders;
    1886         bool succeed = getAttachedShaders(program, shaders, ec);
    1887         if (succeed) {
    1888             bool vShader = false;
    1889             bool fShader = false;
    1890             for (size_t ii = 0; ii < shaders.size() && (!vShader || !fShader); ++ii) {
    1891                 if (shaders[ii]->getType() == GraphicsContext3D::VERTEX_SHADER)
    1892                     vShader = true;
    1893                 else if (shaders[ii]->getType() == GraphicsContext3D::FRAGMENT_SHADER)
    1894                     fShader = true;
    1895             }
    1896             if (!vShader || !fShader)
    1897                 succeed = false;
    1898         }
    1899         if (!succeed) {
     1900        if (!program->getAttachedShader(GraphicsContext3D::VERTEX_SHADER) || !program->getAttachedShader(GraphicsContext3D::FRAGMENT_SHADER)) {
    19001901            program->setLinkFailureFlag(true);
    19011902            return;
     
    27022703void WebGLRenderingContext::useProgram(WebGLProgram* program, ExceptionCode& ec)
    27032704{
    2704     UNUSED_PARAM(ec);
    27052705    if (program && program->context() != this) {
    27062706        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
    27072707        return;
    27082708    }
    2709     m_currentProgram = program;
    2710     m_context->useProgram(objectOrZero(program));
     2709    if (program && program->object() && !getProgramParameter(program, GraphicsContext3D::LINK_STATUS, ec).getBool()) {
     2710        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
     2711        cleanupAfterGraphicsCall(false);
     2712        return;
     2713    }
     2714    if (m_currentProgram != program) {
     2715        if (m_currentProgram)
     2716            m_currentProgram->onDetached();
     2717        m_currentProgram = program;
     2718        m_context->useProgram(objectOrZero(program));
     2719        if (program)
     2720            program->onAttached();
     2721    }
    27112722    cleanupAfterGraphicsCall(false);
    27122723}
Note: See TracChangeset for help on using the changeset viewer.