Title: [223180] branches/safari-604-branch

Diff

Modified: branches/safari-604-branch/LayoutTests/ChangeLog (223179 => 223180)


--- branches/safari-604-branch/LayoutTests/ChangeLog	2017-10-11 15:53:21 UTC (rev 223179)
+++ branches/safari-604-branch/LayoutTests/ChangeLog	2017-10-11 16:09:19 UTC (rev 223180)
@@ -1,5 +1,23 @@
 2017-10-10  Jason Marcell  <[email protected]>
 
+        Cherry-pick r221831. rdar://problem/34891283
+
+    2017-09-08  Dean Jackson  <[email protected]>
+
+            gl.detachShader breaks shader program
+            https://bugs.webkit.org/show_bug.cgi?id=137689
+            <rdar://problem/34025056>
+
+            Reviewed by Sam Weinig.
+
+            Test that detaches and deletes shaders after linking, but before
+            asking for uniform locations.
+
+            * fast/canvas/webgl/detachShader-before-accessing-uniform-expected.txt: Added.
+            * fast/canvas/webgl/detachShader-before-accessing-uniform.html: Added.
+
+2017-10-10  Jason Marcell  <[email protected]>
+
         Cherry-pick r222450. rdar://problem/34920294
 
     2017-09-25  Ryan Haddad  <[email protected]>

Added: branches/safari-604-branch/LayoutTests/fast/canvas/webgl/detachShader-before-accessing-uniform-expected.txt (0 => 223180)


--- branches/safari-604-branch/LayoutTests/fast/canvas/webgl/detachShader-before-accessing-uniform-expected.txt	                        (rev 0)
+++ branches/safari-604-branch/LayoutTests/fast/canvas/webgl/detachShader-before-accessing-uniform-expected.txt	2017-10-11 16:09:19 UTC (rev 223180)
@@ -0,0 +1,7 @@
+Vertex Shader compiled.
+Fragment Shader compiled.
+Program linked. Detaching and deleting shaders.
+Color uniform location was identified.
+Position attribute location was identified.
+Drawn.
+

Added: branches/safari-604-branch/LayoutTests/fast/canvas/webgl/detachShader-before-accessing-uniform.html (0 => 223180)


--- branches/safari-604-branch/LayoutTests/fast/canvas/webgl/detachShader-before-accessing-uniform.html	                        (rev 0)
+++ branches/safari-604-branch/LayoutTests/fast/canvas/webgl/detachShader-before-accessing-uniform.html	2017-10-11 16:09:19 UTC (rev 223180)
@@ -0,0 +1,122 @@
+<style>
+canvas {
+    width: 200px;
+    height: 200px;
+}
+</style>
+</head>
+<script id="vertexShaderSource" type="text/glsl">
+attribute vec4 position;
+void main() {
+  gl_Position = position;
+}
+</script>
+<script id="fragmentShaderSource" type="text/glsl">
+precision mediump float;
+uniform vec4 color;
+void main() {
+  gl_FragColor = color;
+}
+</script>
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+
+function output(msg) {
+    let d = document.querySelector("div");
+    d.innerHTML += `${msg}<br>`;
+}
+
+function drawTriangle() {
+
+    let canvas = document.querySelector("canvas");
+    canvas.width = 200;
+    canvas.height = 200;
+    let gl = canvas.getContext("webgl");
+
+    let vertexShader = gl.createShader(gl.VERTEX_SHADER);
+    gl.shaderSource(vertexShader, document.getElementById("vertexShaderSource").textContent);
+    gl.compileShader(vertexShader);
+    if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
+        output("Vertex Shader failed to compile.");
+        console.log(gl.getShaderInfoLog(vertexShader));
+        return;
+    }
+    output("Vertex Shader compiled.");
+
+    let fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
+    gl.shaderSource(fragmentShader, document.getElementById("fragmentShaderSource").textContent);
+    gl.compileShader(fragmentShader);
+    if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
+        output("Fragment Shader failed to compile.");
+        console.log(gl.getShaderInfoLog(fragmentShader));
+        return;
+    }
+    output("Fragment Shader compiled.");
+
+    let program = gl.createProgram();
+    gl.attachShader(program, vertexShader);
+    gl.attachShader(program, fragmentShader);
+    gl.linkProgram(program);
+
+    if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
+        output("Unable to link shaders into program.");
+        return;
+    }
+    output("Program linked. Detaching and deleting shaders.");
+
+    gl.detachShader(program, vertexShader);
+    gl.detachShader(program, fragmentShader);
+    gl.deleteShader(vertexShader);
+    gl.deleteShader(fragmentShader);
+
+    gl.useProgram(program);
+
+    let colorUniform = gl.getUniformLocation(program, "color");
+    if (colorUniform)
+        output("Color uniform location was identified.");
+    else {
+        output("FAIL: Color uniform location was not found.");
+        return;
+    }
+
+    let positionAttribute = gl.getAttribLocation(program, "position");
+    if (positionAttribute >= 0)
+        output("Position attribute location was identified.");
+    else {
+        output("FAIL: Position attribute location was not found.");
+        return;
+    }
+
+    gl.enableVertexAttribArray(positionAttribute);
+
+    let vertices = new Float32Array([
+       -0.8, -0.3,
+       0.7, -0.8,
+       0.55, 0.75
+    ]);
+
+    let triangleBuffer = gl.createBuffer();
+
+    gl.bindBuffer(gl.ARRAY_BUFFER, triangleBuffer);
+    gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
+
+    gl.clearColor(0, 0, 0, 1);
+    gl.clear(gl.COLOR_BUFFER_BIT);
+
+    let now = Date.now();
+    gl.uniform4fv(colorUniform, [1.0, 0.0, 0.0, 1.0]);
+
+    gl.bindBuffer(gl.ARRAY_BUFFER, triangleBuffer);
+    gl.vertexAttribPointer(positionAttribute, 2, gl.FLOAT, false, 0, 0);
+
+    gl.drawArrays(gl.TRIANGLES, 0, 3);
+    output("Drawn.");
+}
+
+window.addEventListener("load", drawTriangle, false);
+</script>
+<body>
+    <canvas></canvas>
+    <div></div>
+</body>
\ No newline at end of file

Modified: branches/safari-604-branch/Source/WebCore/ChangeLog (223179 => 223180)


--- branches/safari-604-branch/Source/WebCore/ChangeLog	2017-10-11 15:53:21 UTC (rev 223179)
+++ branches/safari-604-branch/Source/WebCore/ChangeLog	2017-10-11 16:09:19 UTC (rev 223180)
@@ -1,5 +1,47 @@
 2017-10-10  Jason Marcell  <[email protected]>
 
+        Cherry-pick r221831. rdar://problem/34891283
+
+    2017-09-08  Dean Jackson  <[email protected]>
+
+            gl.detachShader breaks shader program
+            https://bugs.webkit.org/show_bug.cgi?id=137689
+            <rdar://problem/34025056>
+
+            Reviewed by Sam Weinig.
+
+            It should be possible to compile shaders, attach them to a program,
+            link the program, detach the shaders, delete the shaders, and then
+            ask for the uniform and attribute locations. That is, once you've
+            linked, the shaders can be thrown away.
+
+            We were using the attached shaders to look up uniform locations, so
+            we now keep around a separate map that remembers what shaders were
+            attached when the program links.
+
+            This fixes the bug, but the whole area is still a bit messy. For one,
+            we're keeping around all the shader information even after it is
+            no longer used.
+            See https://bugs.webkit.org/show_bug.cgi?id=98204
+
+            Test: fast/canvas/webgl/detachShader-before-accessing-uniform.html
+
+            * platform/graphics/GraphicsContext3D.h: Add another map to remember
+            what shaders were used when a program was linked.
+            * platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp:
+            (WebCore::GraphicsContext3D::mappedSymbolInShaderSourceMap): New helper
+            to look up a name in our source maps.
+            (WebCore::GraphicsContext3D::mappedSymbolName): Use the helper, and look
+            at linked shaders if there are no attached shaders.
+            (WebCore::GraphicsContext3D::originalSymbolInShaderSourceMap): Does the
+            reverse of the above.
+            (WebCore::GraphicsContext3D::originalSymbolName):
+            (WebCore::GraphicsContext3D::linkProgram): Add to the new map.
+            (WebCore::GraphicsContext3D::deleteProgram): Delete the program from
+            our shader entries.
+
+2017-10-10  Jason Marcell  <[email protected]>
+
         Cherry-pick r222478. rdar://problem/34771020
 
     2017-09-25  Youenn Fablet  <[email protected]>

Modified: branches/safari-604-branch/Source/WebCore/platform/graphics/GraphicsContext3D.h (223179 => 223180)


--- branches/safari-604-branch/Source/WebCore/platform/graphics/GraphicsContext3D.h	2017-10-11 15:53:21 UTC (rev 223179)
+++ branches/safari-604-branch/Source/WebCore/platform/graphics/GraphicsContext3D.h	2017-10-11 16:09:19 UTC (rev 223180)
@@ -1340,9 +1340,14 @@
         }
     };
 
+    // FIXME: Shaders are never removed from this map, even if they and their program are deleted.
+    // This is bad, and it also relies on the fact we never reuse Platform3DObject numbers.
     typedef HashMap<Platform3DObject, ShaderSourceEntry> ShaderSourceMap;
     ShaderSourceMap m_shaderSourceMap;
 
+    typedef HashMap<Platform3DObject, std::pair<Platform3DObject, Platform3DObject>> LinkedShaderMap;
+    LinkedShaderMap m_linkedShaderMap;
+
     struct ActiveShaderSymbolCounts {
         Vector<GC3Dint> filteredToActualAttributeIndexMap;
         Vector<GC3Dint> filteredToActualUniformIndexMap;
@@ -1369,6 +1374,8 @@
     String mappedSymbolName(Platform3DObject program, ANGLEShaderSymbolType, const String& name);
     String mappedSymbolName(Platform3DObject shaders[2], size_t count, const String& name);
     String originalSymbolName(Platform3DObject program, ANGLEShaderSymbolType, const String& name);
+    std::optional<String> mappedSymbolInShaderSourceMap(Platform3DObject shader, ANGLEShaderSymbolType, const String& name);
+    std::optional<String> originalSymbolInShaderSourceMap(Platform3DObject shader, ANGLEShaderSymbolType, const String& name);
 
     std::unique_ptr<ShaderNameHash> nameHashMapForShaders;
 

Modified: branches/safari-604-branch/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp (223179 => 223180)


--- branches/safari-604-branch/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp	2017-10-11 15:53:21 UTC (rev 223179)
+++ branches/safari-604-branch/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp	2017-10-11 16:09:19 UTC (rev 223180)
@@ -922,6 +922,21 @@
     return builder.toString();
 }
 
+std::optional<String> GraphicsContext3D::mappedSymbolInShaderSourceMap(Platform3DObject shader, ANGLEShaderSymbolType symbolType, const String& name)
+{
+    auto result = m_shaderSourceMap.find(shader);
+    if (result == m_shaderSourceMap.end())
+        return std::nullopt;
+
+    const auto& symbolMap = result->value.symbolMap(symbolType);
+    auto symbolEntry = symbolMap.find(name);
+    if (symbolEntry == symbolMap.end())
+        return std::nullopt;
+
+    auto& mappedName = symbolEntry->value.mappedName;
+    return String(mappedName.c_str(), mappedName.length());
+}
+
 String GraphicsContext3D::mappedSymbolName(Platform3DObject program, ANGLEShaderSymbolType symbolType, const String& name)
 {
     GC3Dsizei count = 0;
@@ -929,16 +944,21 @@
     getAttachedShaders(program, 2, &count, shaders);
 
     for (GC3Dsizei i = 0; i < count; ++i) {
-        ShaderSourceMap::iterator result = m_shaderSourceMap.find(shaders[i]);
-        if (result == m_shaderSourceMap.end())
-            continue;
+        auto mappedName = mappedSymbolInShaderSourceMap(shaders[i], symbolType, name);
+        if (mappedName)
+            return mappedName.value();
+    }
 
-        const ShaderSymbolMap& symbolMap = result->value.symbolMap(symbolType);
-        ShaderSymbolMap::const_iterator symbolEntry = symbolMap.find(name);
-        if (symbolEntry != symbolMap.end()) {
-            const std::string& mappedName = symbolEntry->value.mappedName;
-            return String(mappedName.c_str(), mappedName.length());
-        }
+    // We might have detached or deleted the shaders after linking.
+    auto result = m_linkedShaderMap.find(program);
+    if (result != m_linkedShaderMap.end()) {
+        auto linkedShaders = result->value;
+        auto mappedName = mappedSymbolInShaderSourceMap(linkedShaders.first, symbolType, name);
+        if (mappedName)
+            return mappedName.value();
+        mappedName = mappedSymbolInShaderSourceMap(linkedShaders.second, symbolType, name);
+        if (mappedName)
+            return mappedName.value();
     }
 
     if (symbolType == SHADER_SYMBOL_TYPE_ATTRIBUTE && !name.isEmpty()) {
@@ -948,7 +968,7 @@
             nameHashMapForShaders = std::make_unique<ShaderNameHash>();
         setCurrentNameHashMapForShader(nameHashMapForShaders.get());
 
-        String generatedName = generateHashedName(name);
+        auto generatedName = generateHashedName(name);
 
         setCurrentNameHashMapForShader(nullptr);
 
@@ -959,7 +979,21 @@
 
     return name;
 }
-    
+
+std::optional<String> GraphicsContext3D::originalSymbolInShaderSourceMap(Platform3DObject shader, ANGLEShaderSymbolType symbolType, const String& name)
+{
+    auto result = m_shaderSourceMap.find(shader);
+    if (result == m_shaderSourceMap.end())
+        return std::nullopt;
+
+    const auto& symbolMap = result->value.symbolMap(symbolType);
+    for (const auto& symbolEntry : symbolMap) {
+        if (name == symbolEntry.value.mappedName.c_str())
+            return symbolEntry.key;
+    }
+    return std::nullopt;
+}
+
 String GraphicsContext3D::originalSymbolName(Platform3DObject program, ANGLEShaderSymbolType symbolType, const String& name)
 {
     GC3Dsizei count;
@@ -967,17 +1001,23 @@
     getAttachedShaders(program, 2, &count, shaders);
     
     for (GC3Dsizei i = 0; i < count; ++i) {
-        ShaderSourceMap::iterator result = m_shaderSourceMap.find(shaders[i]);
-        if (result == m_shaderSourceMap.end())
-            continue;
-        
-        const ShaderSymbolMap& symbolMap = result->value.symbolMap(symbolType);
-        for (const auto& symbolEntry : symbolMap) {
-            if (name == symbolEntry.value.mappedName.c_str())
-                return symbolEntry.key;
-        }
+        auto originalName = originalSymbolInShaderSourceMap(shaders[i], symbolType, name);
+        if (originalName)
+            return originalName.value();
     }
 
+    // We might have detached or deleted the shaders after linking.
+    auto result = m_linkedShaderMap.find(program);
+    if (result != m_linkedShaderMap.end()) {
+        auto linkedShaders = result->value;
+        auto originalName = originalSymbolInShaderSourceMap(linkedShaders.first, symbolType, name);
+        if (originalName)
+            return originalName.value();
+        originalName = originalSymbolInShaderSourceMap(linkedShaders.second, symbolType, name);
+        if (originalName)
+            return originalName.value();
+    }
+
     if (symbolType == SHADER_SYMBOL_TYPE_ATTRIBUTE && !name.isEmpty()) {
         // Attributes are a special case: they may be requested before any shaders have been compiled,
         // and aren't even required to be used in any shader program.
@@ -1140,6 +1180,14 @@
 {
     ASSERT(program);
     makeContextCurrent();
+
+    GC3Dsizei count = 0;
+    Platform3DObject shaders[2] = { };
+    getAttachedShaders(program, 2, &count, shaders);
+
+    if (count == 2)
+        m_linkedShaderMap.set(program, std::make_pair(shaders[0], shaders[1]));
+
     ::glLinkProgram(program);
 }
 
@@ -1845,6 +1893,7 @@
 void GraphicsContext3D::deleteProgram(Platform3DObject program)
 {
     makeContextCurrent();
+    m_shaderProgramSymbolCountMap.remove(program);
     glDeleteProgram(program);
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to