Interface design for user-defined name hashing.

1) We use BuiltInResources to pass the hash function to
   ANGLE, deciding whether we applies hash function or not.
2) We use 64 bits hashing function, because 64 bits is 16
   bytes using hex representation, plus the "webgl_" prefix,
   we can keep the names under 128 (WebGL allows 5 levels of
   nesting in structures).  If chooseing 128 bits, we will
   go beyond 128 characters, and some drivers can't handle
   that safely.

ANGLEBUG=315
Review URL: https://codereview.appspot.com/6822077

git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1466 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/build_angle.gypi b/src/build_angle.gypi
index 5ca5c08..e72aec6 100644
--- a/src/build_angle.gypi
+++ b/src/build_angle.gypi
@@ -79,6 +79,7 @@
         'compiler/glslang_lex.cpp',
         'compiler/glslang_tab.cpp',
         'compiler/glslang_tab.h',
+        'compiler/HashNames.h',
         'compiler/InfoSink.cpp',
         'compiler/InfoSink.h',
         'compiler/Initialize.cpp',
diff --git a/src/common/version.h b/src/common/version.h
index cd16882..536f6fb 100644
--- a/src/common/version.h
+++ b/src/common/version.h
@@ -1,7 +1,7 @@
 #define MAJOR_VERSION 1
 #define MINOR_VERSION 1
 #define BUILD_VERSION 0
-#define BUILD_REVISION 1382
+#define BUILD_REVISION 1384
 
 #define STRINGIFY(x) #x
 #define MACRO_STRINGIFY(x) STRINGIFY(x)
diff --git a/src/compiler/Compiler.cpp b/src/compiler/Compiler.cpp
index 9e7f75c..b067fed 100644
--- a/src/compiler/Compiler.cpp
+++ b/src/compiler/Compiler.cpp
@@ -124,6 +124,8 @@
         return false;
     InitExtensionBehavior(resources, extensionBehavior);
 
+    hashFunction = resources.HashFunction;
+
     return true;
 }
 
diff --git a/src/compiler/HashNames.h b/src/compiler/HashNames.h
new file mode 100644
index 0000000..d2141e2
--- /dev/null
+++ b/src/compiler/HashNames.h
@@ -0,0 +1,19 @@
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_HASH_NAMES_H_
+#define COMPILER_HASH_NAMES_H_
+
+#include <map>
+
+#include "compiler/intermediate.h"
+#include "GLSLANG/ShaderLang.h"
+
+#define HASHED_NAME_PREFIX "webgl_"
+
+typedef std::map<TPersistString, TPersistString> NameMap;
+
+#endif  // COMPILER_HASH_NAMES_H_
diff --git a/src/compiler/ShHandle.h b/src/compiler/ShHandle.h
index 6ba302a..0c77bb0 100644
--- a/src/compiler/ShHandle.h
+++ b/src/compiler/ShHandle.h
@@ -18,6 +18,7 @@
 
 #include "compiler/BuiltInFunctionEmulator.h"
 #include "compiler/ExtensionBehavior.h"
+#include "compiler/HashNames.h"
 #include "compiler/InfoSink.h"
 #include "compiler/SymbolTable.h"
 #include "compiler/VariableInfo.h"
@@ -68,6 +69,9 @@
     const TVariableInfoList& getUniforms() const { return uniforms; }
     int getMappedNameMaxLength() const;
 
+    ShHashFunction64 getHashFunction() const { return hashFunction; }
+    const NameMap& getNameMap() const { return nameMap; }
+
 protected:
     ShShaderType getShaderType() const { return shaderType; }
     ShShaderSpec getShaderSpec() const { return shaderSpec; }
@@ -124,6 +128,10 @@
 
     // Cached copy of the ref-counted singleton.
     LongNameMap* longNameMap;
+
+    // name hashing.
+    ShHashFunction64 hashFunction;
+    NameMap nameMap;
 };
 
 //
diff --git a/src/compiler/ShaderLang.cpp b/src/compiler/ShaderLang.cpp
index 56f5c7f..ab56538 100644
--- a/src/compiler/ShaderLang.cpp
+++ b/src/compiler/ShaderLang.cpp
@@ -125,6 +125,9 @@
     resources->OES_standard_derivatives = 0;
     resources->OES_EGL_image_external = 0;
     resources->ARB_texture_rectangle = 0;
+
+    // Disable name hashing by default.
+    resources->HashFunction = NULL;
 }
 
 //
@@ -224,6 +227,22 @@
         // handle array and struct dereferences.
         *params = 1 + MAX_SYMBOL_NAME_LEN;
         break;
+    case SH_NAME_MAX_LENGTH:
+        *params = 1 + MAX_SYMBOL_NAME_LEN;
+        break;
+    case SH_HASHED_NAME_MAX_LENGTH:
+        if (compiler->getHashFunction() == NULL) {
+            *params = 0;
+        } else {
+            // 64 bits hashing output requires 16 bytes for hex 
+            // representation.
+            const char HashedNamePrefix[] = HASHED_NAME_PREFIX;
+            *params = 16 + sizeof(HashedNamePrefix);
+        }
+        break;
+    case SH_HASHED_NAMES_COUNT:
+        *params = compiler->getNameMap().size();
+        break;
     default: UNREACHABLE();
     }
 }
@@ -283,3 +302,46 @@
     getVariableInfo(SH_ACTIVE_UNIFORMS,
                     handle, index, length, size, type, name, mappedName);
 }
+
+void ShGetNameHashingEntry(const ShHandle handle,
+                           int index,
+                           char* name,
+                           char* hashedName)
+{
+    if (!handle || !name || !hashedName || index < 0)
+        return;
+
+    TShHandleBase* base = static_cast<TShHandleBase*>(handle);
+    TCompiler* compiler = base->getAsCompiler();
+    if (!compiler) return;
+
+    const NameMap& nameMap = compiler->getNameMap();
+    if (index >= static_cast<int>(nameMap.size()))
+        return;
+
+    NameMap::const_iterator it = nameMap.begin();
+    for (int i = 0; i < index; ++i)
+        ++it;
+
+    size_t len = it->first.length() + 1;
+    int max_len = 0;
+    ShGetInfo(handle, SH_NAME_MAX_LENGTH, &max_len);
+    if (static_cast<int>(len) > max_len) {
+        ASSERT(false);
+        len = max_len;
+    }
+    strncpy(name, it->first.c_str(), len);
+    // To be on the safe side in case the source is longer than expected.
+    name[len] = '\0';
+
+    len = it->second.length() + 1;
+    max_len = 0;
+    ShGetInfo(handle, SH_HASHED_NAME_MAX_LENGTH, &max_len);
+    if (static_cast<int>(len) > max_len) {
+        ASSERT(false);
+        len = max_len;
+    }
+    strncpy(hashedName, it->second.c_str(), len);
+    // To be on the safe side in case the source is longer than expected.
+    hashedName[len] = '\0';
+}
diff --git a/src/compiler/translator_common.vcxproj b/src/compiler/translator_common.vcxproj
index 6d8d530..0f383db 100644
--- a/src/compiler/translator_common.vcxproj
+++ b/src/compiler/translator_common.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>

+<?xml version="1.0" encoding="utf-8"?>

 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

   <ItemGroup Label="ProjectConfigurations">

     <ProjectConfiguration Include="Debug|Win32">

@@ -234,6 +234,7 @@
     <ClInclude Include="Diagnostics.h" />

     <ClInclude Include="DirectiveHandler.h" />

     <ClInclude Include="ForLoopUnroll.h" />

+    <ClInclude Include="HashNames.h" />

     <ClInclude Include="InfoSink.h" />

     <ClInclude Include="Initialize.h" />

     <ClInclude Include="InitializeDll.h" />

diff --git a/src/compiler/translator_common.vcxproj.filters b/src/compiler/translator_common.vcxproj.filters
index b460cfa..2de9243 100644
--- a/src/compiler/translator_common.vcxproj.filters
+++ b/src/compiler/translator_common.vcxproj.filters
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>

+<?xml version="1.0" encoding="utf-8"?>

 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

   <ItemGroup>

     <Filter Include="Source Files">

@@ -253,6 +253,9 @@
     <ClInclude Include="depgraph\DependencyGraphOutput.h">

       <Filter>Header Files\depgraph</Filter>

     </ClInclude>

+    <ClInclude Include="HashNames.h">

+      <Filter>Header Files</Filter>

+    </ClInclude>

   </ItemGroup>

   <ItemGroup>

     <CustomBuild Include="glslang.l">