Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
gl.detachShader breaks shader program
https://bugs.webkit.org/show_bug.cgi?id=137689 <rdar://problem/34025056> Reviewed by Sam Weinig. Source/WebCore: 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. LayoutTests: 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. Canonical link: https://commits.webkit.org/193180@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@221831 268f45cc-cd09-0410-ab3c-d52691b4dbfc
- Loading branch information
Showing
with
257 additions
and 20 deletions.
- +14 −0 LayoutTests/ChangeLog
- +7 −0 LayoutTests/fast/canvas/webgl/detachShader-before-accessing-uniform-expected.txt
- +122 −0 LayoutTests/fast/canvas/webgl/detachShader-before-accessing-uniform.html
- +38 −0 Source/WebCore/ChangeLog
- +7 −0 Source/WebCore/platform/graphics/GraphicsContext3D.h
- +69 −20 Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -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. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters