Title: [130417] trunk
Revision
130417
Author
[email protected]
Date
2012-10-04 12:31:10 -0700 (Thu, 04 Oct 2012)

Log Message

Attribute and Uniform variable names need translation in shader
https://bugs.webkit.org/show_bug.cgi?id=70989

Reviewed by Tim Horton (and Darin Adler).

Source/WebCore:

WebGL specifies some maximum lengths for variable names (attributes
and uniforms). Also, some GL drivers have issues with long names. For
that reason, ANGLE has an option to rewrite the shader, translating
long names into short names. Turning this on helps shaders compile,
but we need to keep a mapping between the original names and the
translated names, so that we bind to the right location from user code
(which won't ever see the translated source).

This provided an opportunity to clean up some other bits of code:
CSS Filters examined the uniform names after a compilation; It can
now use the variable name map. I also added a typedef for the
HashMaps that keep the shader, the source code and the variable name
mappings.

I also opened a followup bug to make sure these tables are deleted
when the associated shaders (or linked programs) go away:
https://bugs.webkit.org/show_bug.cgi?id=98204

Covered by existing tests (with some enhancements):
- fast/canvas/webgl/attrib-location-length-limits.html:
- fast/canvas/webgl/uniform-location-length-limits.html:

* platform/graphics/ANGLEWebKitBridge.cpp:
(WebCore::getSymbolInfo): Extracts all the information on symbols (either attributes
or uniforms) from the newly compiled shader.
(WebCore):
(WebCore::ANGLEWebKitBridge::compileShaderSource): New method name.
* platform/graphics/ANGLEWebKitBridge.h:
(WebCore::getUniforms): Deleted this method.
(WebCore::ANGLEShaderSymbol::isSampler): Make sure the symbol is a uniform.
(ANGLEWebKitBridge):
* platform/graphics/GraphicsContext3D.h:
(WebCore::GraphicsContext3D::SymbolInfo::SymbolInfo): A new object that
holds the size, type and translated name of a symbol from a WebGL shader.
(ShaderSourceEntry):
(WebCore::GraphicsContext3D::ShaderSourceEntry::ShaderSourceEntry): Now keeps track
of the translated source code and symbol mappings.
(WebCore::GraphicsContext3D::ShaderSourceEntry::symbolMap): Helper function to
get the member variable corresponding to the type of symbol you're asking fo.
* platform/graphics/filters/CustomFilterValidatedProgram.cpp:
(WebCore::CustomFilterValidatedProgram::CustomFilterValidatedProgram): Calls new method
name which also produces a set of symbols to examine.
* platform/graphics/opengl/Extensions3DOpenGLCommon.cpp:
(WebCore::Extensions3DOpenGLCommon::getTranslatedShaderSourceANGLE): We now can pass
in some extra compile options to do translation of long symbol names. Also fill the
map of translated symbol names.
* platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp:
(WebCore::GraphicsContext3D::compileShader):
(WebCore::GraphicsContext3D::mappedSymbolName): Returns the mapped name for
a shader symbol if it was translated during compilation.
(WebCore):
(WebCore::GraphicsContext3D::getAttribLocation):
(WebCore::GraphicsContext3D::getShaderiv):
(WebCore::GraphicsContext3D::getShaderInfoLog):
(WebCore::GraphicsContext3D::getShaderSource):
(WebCore::GraphicsContext3D::getUniformLocation):

LayoutTests:

Added subtests to exercise variables that are well under the limits but
not long enough to produce an error. This way we now test all three options:
under the limit, at the limit, over the limit.

Also, the tests are unskipped on Mac.

* fast/canvas/webgl/attrib-location-length-limits-expected.txt:
* fast/canvas/webgl/attrib-location-length-limits.html:
* fast/canvas/webgl/uniform-location-length-limits-expected.txt:
* fast/canvas/webgl/uniform-location-length-limits.html:
* platform/mac/TestExpectations:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (130416 => 130417)


--- trunk/LayoutTests/ChangeLog	2012-10-04 19:10:18 UTC (rev 130416)
+++ trunk/LayoutTests/ChangeLog	2012-10-04 19:31:10 UTC (rev 130417)
@@ -1,3 +1,22 @@
+2012-10-04  Dean Jackson  <[email protected]>
+
+        Attribute and Uniform variable names need translation in shader
+        https://bugs.webkit.org/show_bug.cgi?id=70989
+
+        Reviewed by Tim Horton (and Darin Adler).
+
+        Added subtests to exercise variables that are well under the limits but
+        not long enough to produce an error. This way we now test all three options:
+        under the limit, at the limit, over the limit.
+
+        Also, the tests are unskipped on Mac.
+
+        * fast/canvas/webgl/attrib-location-length-limits-expected.txt:
+        * fast/canvas/webgl/attrib-location-length-limits.html:
+        * fast/canvas/webgl/uniform-location-length-limits-expected.txt:
+        * fast/canvas/webgl/uniform-location-length-limits.html:
+        * platform/mac/TestExpectations:
+
 2012-10-03  Benjamin Poulain  <[email protected]>
 
         [WK2] Support all attributes of GeolocationPosition

Modified: trunk/LayoutTests/fast/canvas/webgl/attrib-location-length-limits-expected.txt (130416 => 130417)


--- trunk/LayoutTests/fast/canvas/webgl/attrib-location-length-limits-expected.txt	2012-10-04 19:10:18 UTC (rev 130416)
+++ trunk/LayoutTests/fast/canvas/webgl/attrib-location-length-limits-expected.txt	2012-10-04 19:31:10 UTC (rev 130417)
@@ -3,6 +3,10 @@
 PASS gl.getProgramParameter(program, gl.LINK_STATUS) is true
 PASS attrib location should not be -1
 PASS getError was expected value: NO_ERROR : 
+Test attrib location exactly at the length limit
+PASS gl.getProgramParameter(program, gl.LINK_STATUS) is true
+PASS attrib location should not be -1
+PASS getError was expected value: NO_ERROR : 
 Test attrib location over the length limit
 Shader compilation should fail
 PASS wtu.loadShaderFromScript(gl, "badVertexShader", gl.VERTEX_SHADER, function (err) {}) is null

Modified: trunk/LayoutTests/fast/canvas/webgl/attrib-location-length-limits.html (130416 => 130417)


--- trunk/LayoutTests/fast/canvas/webgl/attrib-location-length-limits.html	2012-10-04 19:10:18 UTC (rev 130416)
+++ trunk/LayoutTests/fast/canvas/webgl/attrib-location-length-limits.html	2012-10-04 19:31:10 UTC (rev 130417)
@@ -13,7 +13,16 @@
 </canvas>
 <div id="description">Verify limits on the lengths of attrib locations.</div>
 <div id="console"></div>
-<script id="goodVertexShader" type="x-shader/x-vertex">
+<script id="goodVertexShader1" type="x-shader/x-vertex">
+// A vertex shader where the needed attrib location is long, but not over the limit.
+attribute vec4 vPosition01234567890123456789012345678901234567890123456789012345678901234567890;
+
+void main()
+{
+    gl_Position = vPosition01234567890123456789012345678901234567890123456789012345678901234567890;
+}
+</script>
+<script id="goodVertexShader2" type="x-shader/x-vertex">
 // A vertex shader where the needed attrib location is exactly 256 characters.
 attribute vec4 vPosition0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456;
 
@@ -47,8 +56,19 @@
 var gl = wtu.create3DContext(document.getElementById("example"));
 
 debug("Test attrib location underneath the length limit");
-var program = wtu.loadProgramFromScript(gl, "goodVertexShader", "fragmentShader");
+var program = wtu.loadProgramFromScript(gl, "goodVertexShader1", "fragmentShader");
 shouldBe('gl.getProgramParameter(program, gl.LINK_STATUS)', 'true');
+var attribLoc = gl.getAttribLocation(program, "vPosition01234567890123456789012345678901234567890123456789012345678901234567890");
+if (attribLoc == -1) {
+    testFailed("attrib location was -1, should not be");
+} else {
+    testPassed("attrib location should not be -1");
+}
+wtu.glErrorShouldBe(gl, gl.NONE);
+
+debug("Test attrib location exactly at the length limit");
+var program = wtu.loadProgramFromScript(gl, "goodVertexShader2", "fragmentShader");
+shouldBe('gl.getProgramParameter(program, gl.LINK_STATUS)', 'true');
 var attribLoc = gl.getAttribLocation(program, "vPosition0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456");
 if (attribLoc == -1) {
     testFailed("attrib location was -1, should not be");

Modified: trunk/LayoutTests/fast/canvas/webgl/uniform-location-length-limits-expected.txt (130416 => 130417)


--- trunk/LayoutTests/fast/canvas/webgl/uniform-location-length-limits-expected.txt	2012-10-04 19:10:18 UTC (rev 130416)
+++ trunk/LayoutTests/fast/canvas/webgl/uniform-location-length-limits-expected.txt	2012-10-04 19:31:10 UTC (rev 130417)
@@ -3,6 +3,10 @@
 PASS gl.getProgramParameter(program, gl.LINK_STATUS) is true
 PASS uniformLoc is non-null.
 PASS getError was expected value: NO_ERROR : 
+Test uniform location exactly at the length limit
+PASS gl.getProgramParameter(program, gl.LINK_STATUS) is true
+PASS uniformLoc is non-null.
+PASS getError was expected value: NO_ERROR : 
 Test uniform location over the length limit
 PASS getError was expected value: NO_ERROR : 
 PASS gl.getProgramParameter(program, gl.LINK_STATUS) is true

Modified: trunk/LayoutTests/fast/canvas/webgl/uniform-location-length-limits.html (130416 => 130417)


--- trunk/LayoutTests/fast/canvas/webgl/uniform-location-length-limits.html	2012-10-04 19:10:18 UTC (rev 130416)
+++ trunk/LayoutTests/fast/canvas/webgl/uniform-location-length-limits.html	2012-10-04 19:31:10 UTC (rev 130417)
@@ -13,7 +13,23 @@
 </canvas>
 <div id="description">Verify limits on the lengths of uniform locations.</div>
 <div id="console"></div>
-<script id="goodVertexShader" type="x-shader/x-vertex">
+<script id="goodVertexShader1" type="x-shader/x-vertex">
+// A vertex shader where the uniform name is long, but well below the limit.
+struct Nesting2 {
+    vec4 identifier62CharactersLong_01234567890123456789012345678901234;
+};
+
+struct Nesting1 {
+    Nesting2 identifier64CharactersLong_0123456789012345678901234567890123456;
+};
+
+uniform Nesting1 identifier70CharactersLong_01234567890123456789012345678901234567890;
+
+void main() {
+    gl_Position = identifier70CharactersLong_01234567890123456789012345678901234567890.identifier64CharactersLong_0123456789012345678901234567890123456.identifier62CharactersLong_01234567890123456789012345678901234;
+}
+</script>
+<script id="goodVertexShader2" type="x-shader/x-vertex">
 // A vertex shader where the needed uniform location is exactly 256 characters.
 struct Nesting2 {
     vec4 identifier62CharactersLong_01234567890123456789012345678901234;
@@ -62,8 +78,15 @@
 var gl = wtu.create3DContext(document.getElementById("example"));
 
 debug("Test uniform location underneath the length limit");
-var program = wtu.loadProgramFromScript(gl, "goodVertexShader", "fragmentShader");
+var program = wtu.loadProgramFromScript(gl, "goodVertexShader1", "fragmentShader");
 shouldBe('gl.getProgramParameter(program, gl.LINK_STATUS)', 'true');
+var uniformLoc = gl.getUniformLocation(program, "identifier70CharactersLong_01234567890123456789012345678901234567890.identifier64CharactersLong_0123456789012345678901234567890123456.identifier62CharactersLong_01234567890123456789012345678901234");
+shouldBeNonNull('uniformLoc');
+wtu.glErrorShouldBe(gl, gl.NONE);
+
+debug("Test uniform location exactly at the length limit");
+var program = wtu.loadProgramFromScript(gl, "goodVertexShader2", "fragmentShader");
+shouldBe('gl.getProgramParameter(program, gl.LINK_STATUS)', 'true');
 var uniformLoc = gl.getUniformLocation(program, "identifier128CharactersLong_0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789.identifier64CharactersLong_0123456789012345678901234567890123456.identifier62CharactersLong_01234567890123456789012345678901234");
 shouldBeNonNull('uniformLoc');
 wtu.glErrorShouldBe(gl, gl.NONE);

Modified: trunk/LayoutTests/platform/mac/TestExpectations (130416 => 130417)


--- trunk/LayoutTests/platform/mac/TestExpectations	2012-10-04 19:10:18 UTC (rev 130416)
+++ trunk/LayoutTests/platform/mac/TestExpectations	2012-10-04 19:31:10 UTC (rev 130417)
@@ -479,10 +479,6 @@
 fast/events/platform-wheelevent-paging-y-in-scrolling-div.html
 fast/events/platform-wheelevent-paging-y-in-scrolling-page.html
 
-# https://bugs.webkit.org/show_bug.cgi?id=70989
-fast/canvas/webgl/attrib-location-length-limits.html
-fast/canvas/webgl/uniform-location-length-limits.html
-
 # Web Intents is not yet enabled.
 webintents/
 

Modified: trunk/Source/WebCore/ChangeLog (130416 => 130417)


--- trunk/Source/WebCore/ChangeLog	2012-10-04 19:10:18 UTC (rev 130416)
+++ trunk/Source/WebCore/ChangeLog	2012-10-04 19:31:10 UTC (rev 130417)
@@ -1,3 +1,67 @@
+2012-10-04  Dean Jackson  <[email protected]>
+
+        Attribute and Uniform variable names need translation in shader
+        https://bugs.webkit.org/show_bug.cgi?id=70989
+
+        Reviewed by Tim Horton (and Darin Adler).
+
+        WebGL specifies some maximum lengths for variable names (attributes
+        and uniforms). Also, some GL drivers have issues with long names. For
+        that reason, ANGLE has an option to rewrite the shader, translating
+        long names into short names. Turning this on helps shaders compile,
+        but we need to keep a mapping between the original names and the
+        translated names, so that we bind to the right location from user code
+        (which won't ever see the translated source).
+
+        This provided an opportunity to clean up some other bits of code:
+        CSS Filters examined the uniform names after a compilation; It can
+        now use the variable name map. I also added a typedef for the
+        HashMaps that keep the shader, the source code and the variable name
+        mappings.
+
+        I also opened a followup bug to make sure these tables are deleted
+        when the associated shaders (or linked programs) go away:
+        https://bugs.webkit.org/show_bug.cgi?id=98204
+
+        Covered by existing tests (with some enhancements):
+        - fast/canvas/webgl/attrib-location-length-limits.html:
+        - fast/canvas/webgl/uniform-location-length-limits.html:
+
+        * platform/graphics/ANGLEWebKitBridge.cpp:
+        (WebCore::getSymbolInfo): Extracts all the information on symbols (either attributes
+        or uniforms) from the newly compiled shader.
+        (WebCore):
+        (WebCore::ANGLEWebKitBridge::compileShaderSource): New method name.
+        * platform/graphics/ANGLEWebKitBridge.h:
+        (WebCore::getUniforms): Deleted this method.
+        (WebCore::ANGLEShaderSymbol::isSampler): Make sure the symbol is a uniform.
+        (ANGLEWebKitBridge):
+        * platform/graphics/GraphicsContext3D.h:
+        (WebCore::GraphicsContext3D::SymbolInfo::SymbolInfo): A new object that
+        holds the size, type and translated name of a symbol from a WebGL shader.
+        (ShaderSourceEntry):
+        (WebCore::GraphicsContext3D::ShaderSourceEntry::ShaderSourceEntry): Now keeps track
+        of the translated source code and symbol mappings.
+        (WebCore::GraphicsContext3D::ShaderSourceEntry::symbolMap): Helper function to
+        get the member variable corresponding to the type of symbol you're asking fo.
+        * platform/graphics/filters/CustomFilterValidatedProgram.cpp:
+        (WebCore::CustomFilterValidatedProgram::CustomFilterValidatedProgram): Calls new method
+        name which also produces a set of symbols to examine.
+        * platform/graphics/opengl/Extensions3DOpenGLCommon.cpp:
+        (WebCore::Extensions3DOpenGLCommon::getTranslatedShaderSourceANGLE): We now can pass
+        in some extra compile options to do translation of long symbol names. Also fill the
+        map of translated symbol names.
+        * platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp:
+        (WebCore::GraphicsContext3D::compileShader):
+        (WebCore::GraphicsContext3D::mappedSymbolName): Returns the mapped name for
+        a shader symbol if it was translated during compilation.
+        (WebCore):
+        (WebCore::GraphicsContext3D::getAttribLocation):
+        (WebCore::GraphicsContext3D::getShaderiv):
+        (WebCore::GraphicsContext3D::getShaderInfoLog):
+        (WebCore::GraphicsContext3D::getShaderSource):
+        (WebCore::GraphicsContext3D::getUniformLocation):
+
 2012-10-04  Alpha Lam  <[email protected]>
 
         [skia] Drawing a subrect of bitmap image is misaligned

Modified: trunk/Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp (130416 => 130417)


--- trunk/Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp	2012-10-04 19:10:18 UTC (rev 130416)
+++ trunk/Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp	2012-10-04 19:31:10 UTC (rev 130417)
@@ -39,6 +39,68 @@
     return value;
 }
 
+static bool getSymbolInfo(ShHandle compiler, ShShaderInfo symbolType, Vector<ANGLEShaderSymbol>& symbols)
+{
+    ShShaderInfo symbolMaxNameLengthType;
+
+    switch (symbolType) {
+    case SH_ACTIVE_ATTRIBUTES:
+        symbolMaxNameLengthType = SH_ACTIVE_ATTRIBUTE_MAX_LENGTH;
+        break;
+    case SH_ACTIVE_UNIFORMS:
+        symbolMaxNameLengthType = SH_ACTIVE_UNIFORM_MAX_LENGTH;
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+        return false;
+    }
+
+    int numSymbols = getValidationResultValue(compiler, symbolType);
+    if (numSymbols < 0)
+        return false;
+
+    int maxNameLength = getValidationResultValue(compiler, symbolMaxNameLengthType);
+    if (maxNameLength <= 1)
+        return false;
+
+    int maxMappedNameLength = getValidationResultValue(compiler, SH_MAPPED_NAME_MAX_LENGTH);
+    if (maxMappedNameLength <= 1)
+        return false;
+
+    // The maximum allowed symbol name length is 256 characters.
+    Vector<char, 256> nameBuffer(maxNameLength);
+    Vector<char, 256> mappedNameBuffer(maxMappedNameLength);
+    
+    for (int i = 0; i < numSymbols; ++i) {
+        ANGLEShaderSymbol symbol;
+        int nameLength = -1;
+        switch (symbolType) {
+        case SH_ACTIVE_ATTRIBUTES:
+            symbol.symbolType = SHADER_SYMBOL_TYPE_ATTRIBUTE;
+            ShGetActiveAttrib(compiler, i, &nameLength, &symbol.size, &symbol.dataType, nameBuffer.data(), mappedNameBuffer.data());
+            break;
+        case SH_ACTIVE_UNIFORMS:
+            symbol.symbolType = SHADER_SYMBOL_TYPE_UNIFORM;
+            ShGetActiveUniform(compiler, i, &nameLength, &symbol.size, &symbol.dataType, nameBuffer.data(), mappedNameBuffer.data());
+            break;
+        default:
+            ASSERT_NOT_REACHED();
+            return false;
+        }
+        if (nameLength <= 0)
+            return false;
+        
+        // The ShGetActive* calls above are guaranteed to produce null-terminated strings for
+        // nameBuffer and mappedNameBuffer. Also, the character set for symbol names
+        // is a subset of Latin-1 as specified by the OpenGL ES Shading Language, Section 3.1 and
+        // WebGL, Section "Characters Outside the GLSL Source Character Set".
+        symbol.name = String(nameBuffer.data());
+        symbol.mappedName = String(mappedNameBuffer.data());
+        symbols.append(symbol);
+    }
+    return true;
+}
+
 ANGLEWebKitBridge::ANGLEWebKitBridge(ShShaderOutput shaderOutput, ShShaderSpec shaderSpec)
     : builtCompilers(false)
     , m_fragmentCompiler(0)
@@ -75,7 +137,7 @@
     m_resources = resources;
 }
 
-bool ANGLEWebKitBridge::validateShaderSource(const char* shaderSource, ANGLEShaderType shaderType, String& translatedShaderSource, String& shaderValidationLog, int extraCompileOptions)
+bool ANGLEWebKitBridge::compileShaderSource(const char* shaderSource, ANGLEShaderType shaderType, String& translatedShaderSource, String& shaderValidationLog, Vector<ANGLEShaderSymbol>& symbols, int extraCompileOptions)
 {
     if (!builtCompilers) {
         m_fragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, m_shaderSpec, m_shaderOutput, &m_resources);
@@ -97,7 +159,7 @@
 
     const char* const shaderSourceStrings[] = { shaderSource };
 
-    bool validateSuccess = ShCompile(compiler, shaderSourceStrings, 1, SH_OBJECT_CODE | extraCompileOptions);
+    bool validateSuccess = ShCompile(compiler, shaderSourceStrings, 1, SH_OBJECT_CODE | SH_ATTRIBUTES_UNIFORMS | extraCompileOptions);
     if (!validateSuccess) {
         int logSize = getValidationResultValue(compiler, SH_INFO_LOG_LENGTH);
         if (logSize > 1) {
@@ -118,36 +180,12 @@
         ShGetObjectCode(compiler, translationBuffer.get());
         translatedShaderSource = translationBuffer.get();
     }
-
-    return true;
-}
-
-bool ANGLEWebKitBridge::getUniforms(ShShaderType shaderType, Vector<ANGLEShaderSymbol> &symbols)
-{
-    const ShHandle compiler = (shaderType == SH_VERTEX_SHADER ? m_vertexCompiler : m_fragmentCompiler);
-
-    int numUniforms = getValidationResultValue(compiler, SH_ACTIVE_UNIFORMS);
-    if (numUniforms < 0)
+    
+    if (!getSymbolInfo(compiler, SH_ACTIVE_ATTRIBUTES, symbols))
         return false;
-    if (!numUniforms)
-        return true;
-
-    int maxNameLength = getValidationResultValue(compiler, SH_ACTIVE_UNIFORM_MAX_LENGTH);
-    if (maxNameLength <= 1)
+    if (!getSymbolInfo(compiler, SH_ACTIVE_UNIFORMS, symbols))
         return false;
-    OwnArrayPtr<char> nameBuffer = adoptArrayPtr(new char[maxNameLength]);
 
-    for (int i = 0; i < numUniforms; ++i) {
-        ANGLEShaderSymbol symbol;
-        symbol.symbolType = SHADER_SYMBOL_TYPE_UNIFORM;
-        int nameLength = -1;
-        ShGetActiveUniform(compiler, i, &nameLength, &symbol.size, &symbol.dataType, nameBuffer.get(), 0);
-        if (nameLength <= 0)
-            return false;
-        symbol.name = String::fromUTF8(nameBuffer.get(), nameLength);
-        symbols.append(symbol);
-    }
-
     return true;
 }
 

Modified: trunk/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h (130416 => 130417)


--- trunk/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h	2012-10-04 19:10:18 UTC (rev 130416)
+++ trunk/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h	2012-10-04 19:31:10 UTC (rev 130417)
@@ -50,15 +50,17 @@
 struct ANGLEShaderSymbol {
     ANGLEShaderSymbolType symbolType;
     String name;
+    String mappedName;
     ShDataType dataType;
     int size;
 
     bool isSampler()
     {
-        return dataType == SH_SAMPLER_2D
+        return symbolType == SHADER_SYMBOL_TYPE_UNIFORM
+            && (dataType == SH_SAMPLER_2D
             || dataType == SH_SAMPLER_CUBE
             || dataType == SH_SAMPLER_2D_RECT_ARB
-            || dataType == SH_SAMPLER_EXTERNAL_OES;
+            || dataType == SH_SAMPLER_EXTERNAL_OES);
     }
 };
 
@@ -71,13 +73,8 @@
     ShBuiltInResources getResources() { return m_resources; }
     void setResources(ShBuiltInResources);
     
-    bool validateShaderSource(const char* shaderSource, ANGLEShaderType, String& translatedShaderSource, String& shaderValidationLog, int extraCompileOptions = 0);
+    bool compileShaderSource(const char* shaderSource, ANGLEShaderType, String& translatedShaderSource, String& shaderValidationLog, Vector<ANGLEShaderSymbol>& symbols, int extraCompileOptions = 0);
 
-    // Get the uniforms for the last validated shader of type ShShaderType.
-    // For this function to work, you must use the SH_ATTRIBUTES_UNIFORMS compile option during validation.
-    // Returns false if an unexpected error occurred in ANGLE.
-    bool getUniforms(ShShaderType, Vector<ANGLEShaderSymbol> &symbols);
-
 private:
 
     void cleanupCompilers();

Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h (130416 => 130417)


--- trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h	2012-10-04 19:10:18 UTC (rev 130416)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h	2012-10-04 19:31:10 UTC (rev 130417)
@@ -964,17 +964,60 @@
 #endif
 
 #if PLATFORM(MAC) || PLATFORM(GTK) || PLATFORM(QT) || PLATFORM(EFL) || PLATFORM(BLACKBERRY)
+    struct SymbolInfo {
+        SymbolInfo()
+            : type(0)
+            , size(0)
+        {
+        }
+
+        SymbolInfo(GC3Denum type, int size, const String& mappedName)
+            : type(type)
+            , size(size)
+            , mappedName(mappedName)
+        {
+        }
+
+        bool operator==(SymbolInfo& other) const
+        {
+            return type == other.type && size == other.size && mappedName == other.mappedName;
+        }
+
+        GC3Denum type;
+        int size;
+        String mappedName;
+    };
+
+    typedef HashMap<String, SymbolInfo> ShaderSymbolMap;
+
     struct ShaderSourceEntry {
+        GC3Denum type;
         String source;
+        String translatedSource;
         String log;
         bool isValid;
+        ShaderSymbolMap attributeMap;
+        ShaderSymbolMap uniformMap;
         ShaderSourceEntry()
-            : isValid(0)
+            : type(VERTEX_SHADER)
+            , isValid(false)
         {
         }
+        
+        ShaderSymbolMap& symbolMap(ANGLEShaderSymbolType symbolType)
+        {
+            ASSERT(symbolType == SHADER_SYMBOL_TYPE_ATTRIBUTE || symbolType == SHADER_SYMBOL_TYPE_UNIFORM);
+            if (symbolType == SHADER_SYMBOL_TYPE_ATTRIBUTE)
+                return attributeMap;
+            return uniformMap;
+        }
     };
-    HashMap<Platform3DObject, ShaderSourceEntry> m_shaderSourceMap;
 
+    typedef HashMap<Platform3DObject, ShaderSourceEntry> ShaderSourceMap;
+    ShaderSourceMap m_shaderSourceMap;
+
+    String mappedSymbolName(Platform3DObject program, ANGLEShaderSymbolType, const String& name);
+
     ANGLEWebKitBridge m_compiler;
 #endif
 

Modified: trunk/Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.cpp (130416 => 130417)


--- trunk/Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.cpp	2012-10-04 19:10:18 UTC (rev 130416)
+++ trunk/Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.cpp	2012-10-04 19:31:10 UTC (rev 130417)
@@ -85,8 +85,9 @@
     // Shaders referenced from the CSS mix function use a different validator than regular WebGL shaders. See CustomFilterGlobalContext.h for more details.
     ANGLEWebKitBridge* validator = programInfo.mixSettings().enabled ? m_globalContext->mixShaderValidator() : m_globalContext->webglShaderValidator();
     String vertexShaderLog, fragmentShaderLog;
-    bool vertexShaderValid = validator->validateShaderSource(originalVertexShader.utf8().data(), SHADER_TYPE_VERTEX, m_validatedVertexShader, vertexShaderLog, SH_ATTRIBUTES_UNIFORMS);
-    bool fragmentShaderValid = validator->validateShaderSource(originalFragmentShader.utf8().data(), SHADER_TYPE_FRAGMENT, m_validatedFragmentShader, fragmentShaderLog, SH_ATTRIBUTES_UNIFORMS);
+    Vector<ANGLEShaderSymbol> symbols;
+    bool vertexShaderValid = validator->compileShaderSource(originalVertexShader.utf8().data(), SHADER_TYPE_VERTEX, m_validatedVertexShader, vertexShaderLog, symbols);
+    bool fragmentShaderValid = validator->compileShaderSource(originalFragmentShader.utf8().data(), SHADER_TYPE_FRAGMENT, m_validatedFragmentShader, fragmentShaderLog, symbols);
     if (!vertexShaderValid || !fragmentShaderValid) {
         // FIXME: Report the validation errors.
         // https://bugs.webkit.org/show_bug.cgi?id=74416
@@ -94,12 +95,7 @@
     }
 
     // Validate the author's samplers.
-    Vector<ANGLEShaderSymbol> uniforms;
-    if (!validator->getUniforms(SH_VERTEX_SHADER, uniforms))
-        return;
-    if (!validator->getUniforms(SH_FRAGMENT_SHADER, uniforms))
-        return;
-    for (Vector<ANGLEShaderSymbol>::iterator it = uniforms.begin(); it != uniforms.end(); ++it) {
+    for (Vector<ANGLEShaderSymbol>::iterator it = symbols.begin(); it != symbols.end(); ++it) {
         if (it->isSampler()) {
             // FIXME: For now, we restrict shaders with any sampler defined.
             // When we implement texture parameters, we will allow shaders whose samplers are bound to valid textures.

Modified: trunk/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp (130416 => 130417)


--- trunk/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp	2012-10-04 19:10:18 UTC (rev 130416)
+++ trunk/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp	2012-10-04 19:31:10 UTC (rev 130417)
@@ -161,16 +161,24 @@
 
     String translatedShaderSource;
     String shaderInfoLog;
-    int extraCompileOptions = 0;
+    int extraCompileOptions = SH_MAP_LONG_VARIABLE_NAMES;
 
     if (m_requiresBuiltInFunctionEmulation)
         extraCompileOptions |= SH_EMULATE_BUILT_IN_FUNCTIONS;
 
-    bool isValid = compiler.validateShaderSource(entry.source.utf8().data(), shaderType, translatedShaderSource, shaderInfoLog, extraCompileOptions);
+    Vector<ANGLEShaderSymbol> symbols;
+    bool isValid = compiler.compileShaderSource(entry.source.utf8().data(), shaderType, translatedShaderSource, shaderInfoLog, symbols, extraCompileOptions);
 
     entry.log = shaderInfoLog;
     entry.isValid = isValid;
 
+    size_t numSymbols = symbols.size();
+    for (size_t i = 0; i < numSymbols; ++i) {
+        ANGLEShaderSymbol shaderSymbol = symbols[i];
+        GraphicsContext3D::SymbolInfo symbolInfo(shaderSymbol.dataType, shaderSymbol.size, shaderSymbol.mappedName);
+        entry.symbolMap(shaderSymbol.symbolType).set(shaderSymbol.name, symbolInfo);
+    }
+
     if (!isValid)
         return "";
 

Modified: trunk/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp (130416 => 130417)


--- trunk/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp	2012-10-04 19:10:18 UTC (rev 130416)
+++ trunk/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp	2012-10-04 19:31:10 UTC (rev 130417)
@@ -465,7 +465,7 @@
     ::glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
 
     if (length) {
-        HashMap<Platform3DObject, GraphicsContext3D::ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader);
+        ShaderSourceMap::iterator result = m_shaderSourceMap.find(shader);
         GraphicsContext3D::ShaderSourceEntry& entry = result->second;
 
         GLsizei size = 0;
@@ -671,13 +671,38 @@
     ::glGetAttachedShaders(program, maxCount, count, shaders);
 }
 
+String GraphicsContext3D::mappedSymbolName(Platform3DObject program, ANGLEShaderSymbolType symbolType, const String& name)
+{
+    GC3Dsizei count;
+    Platform3DObject shaders[2];
+    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->second.symbolMap(symbolType);
+        ShaderSymbolMap::const_iterator symbolEntry = symbolMap.find(name);
+        if (symbolEntry != symbolMap.end())
+            return symbolEntry->second.mappedName;
+    }
+    return name;
+}
+
 int GraphicsContext3D::getAttribLocation(Platform3DObject program, const String& name)
 {
     if (!program)
         return -1;
 
     makeContextCurrent();
-    return ::glGetAttribLocation(program, name.utf8().data());
+
+    // The attribute name may have been translated during ANGLE compilation.
+    // Look through the corresponding ShaderSourceMap to make sure we
+    // reference the mapped name rather than the external name.
+    String mappedName = mappedSymbolName(program, SHADER_SYMBOL_TYPE_ATTRIBUTE, name);
+
+    return ::glGetAttribLocation(program, mappedName.utf8().data());
 }
 
 GraphicsContext3D::Attributes GraphicsContext3D::getContextAttributes()
@@ -1126,7 +1151,7 @@
 
     makeContextCurrent();
 
-    HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader);
+    ShaderSourceMap::iterator result = m_shaderSourceMap.find(shader);
     
     switch (pname) {
     case DELETE_STATUS:
@@ -1161,7 +1186,7 @@
 
     makeContextCurrent();
 
-    HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader);
+    ShaderSourceMap::iterator result = m_shaderSourceMap.find(shader);
     if (result == m_shaderSourceMap.end())
         return String(); 
 
@@ -1187,7 +1212,7 @@
 
     makeContextCurrent();
 
-    HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader);
+    ShaderSourceMap::iterator result = m_shaderSourceMap.find(shader);
     if (result == m_shaderSourceMap.end())
         return String(); 
 
@@ -1224,7 +1249,13 @@
     ASSERT(program);
 
     makeContextCurrent();
-    return ::glGetUniformLocation(program, name.utf8().data());
+
+    // The uniform name may have been translated during ANGLE compilation.
+    // Look through the corresponding ShaderSourceMap to make sure we
+    // reference the mapped name rather than the external name.
+    String mappedName = mappedSymbolName(program, SHADER_SYMBOL_TYPE_UNIFORM, name);
+
+    return ::glGetUniformLocation(program, mappedName.utf8().data());
 }
 
 void GraphicsContext3D::getVertexAttribfv(GC3Duint index, GC3Denum pname, GC3Dfloat* value)
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to