InputLayoutCache only hashes input layout keys up to last used element.

R=geofflang@chromium.org

Review URL: https://codereview.appspot.com/12676043
diff --git a/src/common/version.h b/src/common/version.h
index 6733700..4893762 100644
--- a/src/common/version.h
+++ b/src/common/version.h
@@ -1,7 +1,7 @@
 #define MAJOR_VERSION 1
 #define MINOR_VERSION 2
 #define BUILD_VERSION 0
-#define BUILD_REVISION 2437
+#define BUILD_REVISION 2438
 
 #define STRINGIFY(x) #x
 #define MACRO_STRINGIFY(x) STRINGIFY(x)
diff --git a/src/libEGL/libEGL.vcxproj b/src/libEGL/libEGL.vcxproj
index b6bc1ef..631a4c6 100644
--- a/src/libEGL/libEGL.vcxproj
+++ b/src/libEGL/libEGL.vcxproj
@@ -91,7 +91,7 @@
       <WarningLevel>Level4</WarningLevel>

       <TreatWarningAsError>true</TreatWarningAsError>

       <DebugInformationFormat>EditAndContinue</DebugInformationFormat>

-      <DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4512;4702;%(DisableSpecificWarnings)</DisableSpecificWarnings>

+      <DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4512;4702;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>

     </ClCompile>

     <Link>

       <AdditionalDependencies>d3d9.lib;%(AdditionalDependencies)</AdditionalDependencies>

@@ -124,7 +124,7 @@
       <WarningLevel>Level4</WarningLevel>

       <TreatWarningAsError>true</TreatWarningAsError>

       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>

-      <DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4512;4702;%(DisableSpecificWarnings)</DisableSpecificWarnings>

+      <DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4512;4702;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>

     </ClCompile>

     <Link>

       <AdditionalDependencies>d3d9.lib;%(AdditionalDependencies)</AdditionalDependencies>

@@ -161,7 +161,7 @@
       <PrecompiledHeader>

       </PrecompiledHeader>

       <WarningLevel>Level4</WarningLevel>

-      <DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4512;4702;%(DisableSpecificWarnings)</DisableSpecificWarnings>

+      <DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4512;4702;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>

       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>

       <TreatWarningAsError>true</TreatWarningAsError>

     </ClCompile>

@@ -197,7 +197,7 @@
       <PrecompiledHeader>

       </PrecompiledHeader>

       <WarningLevel>Level4</WarningLevel>

-      <DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4512;4702;%(DisableSpecificWarnings)</DisableSpecificWarnings>

+      <DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4512;4702;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>

       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>

       <TreatWarningAsError>true</TreatWarningAsError>

     </ClCompile>

diff --git a/src/libGLESv2/libGLESv2.vcxproj b/src/libGLESv2/libGLESv2.vcxproj
index 7dddcd3..f841de2 100644
--- a/src/libGLESv2/libGLESv2.vcxproj
+++ b/src/libGLESv2/libGLESv2.vcxproj
@@ -93,7 +93,7 @@
       <WarningLevel>Level4</WarningLevel>
       <TreatWarningAsError>true</TreatWarningAsError>
       <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4512;4702;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4512;4702;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
       <PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile>
       <AdditionalOptions>$(ExternalCompilerOptions) %(AdditionalOptions)</AdditionalOptions>
     </ClCompile>
@@ -126,7 +126,7 @@
       <WarningLevel>Level4</WarningLevel>
       <TreatWarningAsError>true</TreatWarningAsError>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4512;4702;4718;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4512;4702;4718;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
       <PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile>
       <AdditionalOptions>$(ExternalCompilerOptions) %(AdditionalOptions)</AdditionalOptions>
     </ClCompile>
@@ -164,7 +164,7 @@
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <PrecompiledHeader>Use</PrecompiledHeader>
       <WarningLevel>Level4</WarningLevel>
-      <DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4512;4702;4718;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4512;4702;4718;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <TreatWarningAsError>true</TreatWarningAsError>
       <PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile>
@@ -200,7 +200,7 @@
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <PrecompiledHeader>Use</PrecompiledHeader>
       <WarningLevel>Level4</WarningLevel>
-      <DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4512;4702;4718;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <DisableSpecificWarnings>4100;4127;4189;4239;4244;4245;4512;4702;4718;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <TreatWarningAsError>true</TreatWarningAsError>
       <PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile>
diff --git a/src/libGLESv2/renderer/InputLayoutCache.cpp b/src/libGLESv2/renderer/InputLayoutCache.cpp
index fcc6f7c..1552f3a 100644
--- a/src/libGLESv2/renderer/InputLayoutCache.cpp
+++ b/src/libGLESv2/renderer/InputLayoutCache.cpp
@@ -103,15 +103,15 @@
             // Record the type of the associated vertex shader vector in our key
             // This will prevent mismatched vertex shaders from using the same input layout
             GLint attributeSize;
-            programBinary->getActiveAttribute(ilKey.elementCount, 0, NULL, &attributeSize, &ilKey.glslElementType[ilKey.elementCount], NULL);
+            programBinary->getActiveAttribute(ilKey.elementCount, 0, NULL, &attributeSize, &ilKey.elements[ilKey.elementCount].glslElementType, NULL);
 
-            ilKey.elements[ilKey.elementCount].SemanticName = semanticName;
-            ilKey.elements[ilKey.elementCount].SemanticIndex = sortedSemanticIndices[i];
-            ilKey.elements[ilKey.elementCount].Format = attributes[i].attribute->mArrayEnabled ? vertexBuffer->getDXGIFormat(*attributes[i].attribute) : DXGI_FORMAT_R32G32B32A32_FLOAT;
-            ilKey.elements[ilKey.elementCount].InputSlot = i;
-            ilKey.elements[ilKey.elementCount].AlignedByteOffset = 0;
-            ilKey.elements[ilKey.elementCount].InputSlotClass = inputClass;
-            ilKey.elements[ilKey.elementCount].InstanceDataStepRate = attributes[i].divisor;
+            ilKey.elements[ilKey.elementCount].desc.SemanticName = semanticName;
+            ilKey.elements[ilKey.elementCount].desc.SemanticIndex = sortedSemanticIndices[i];
+            ilKey.elements[ilKey.elementCount].desc.Format = attributes[i].attribute->mArrayEnabled ? vertexBuffer->getDXGIFormat(*attributes[i].attribute) : DXGI_FORMAT_R32G32B32A32_FLOAT;
+            ilKey.elements[ilKey.elementCount].desc.InputSlot = i;
+            ilKey.elements[ilKey.elementCount].desc.AlignedByteOffset = 0;
+            ilKey.elements[ilKey.elementCount].desc.InputSlotClass = inputClass;
+            ilKey.elements[ilKey.elementCount].desc.InstanceDataStepRate = attributes[i].divisor;
             ilKey.elementCount++;
 
             vertexBuffers[i] = bufferStorage ? bufferStorage->getBuffer() : vertexBuffer->getBuffer();
@@ -133,7 +133,13 @@
     {
         ShaderExecutable11 *shader = ShaderExecutable11::makeShaderExecutable11(programBinary->getVertexExecutable());
 
-        HRESULT result = mDevice->CreateInputLayout(ilKey.elements, ilKey.elementCount, shader->getFunction(), shader->getLength(), &inputLayout);
+        D3D11_INPUT_ELEMENT_DESC descs[gl::MAX_VERTEX_ATTRIBS];
+        for (unsigned int j = 0; j < ilKey.elementCount; ++j)
+        {
+            descs[j] = ilKey.elements[j].desc;
+        }
+
+        HRESULT result = mDevice->CreateInputLayout(descs, ilKey.elementCount, shader->getFunction(), shader->getLength(), &inputLayout);
         if (FAILED(result))
         {
             ERR("Failed to crate input layout, result: 0x%08x", result);
@@ -190,13 +196,18 @@
     static const unsigned int seed = 0xDEADBEEF;
 
     std::size_t hash = 0;
-    MurmurHash3_x86_32(&inputLayout, sizeof(InputLayoutKey), seed, &hash);
+    MurmurHash3_x86_32(inputLayout.begin(), inputLayout.end() - inputLayout.begin(), seed, &hash);
     return hash;
 }
 
 bool InputLayoutCache::compareInputLayouts(const InputLayoutKey &a, const InputLayoutKey &b)
 {
-    return memcmp(&a, &b, sizeof(InputLayoutKey)) == 0;
+    if (a.elementCount != b.elementCount)
+    {
+        return false;
+    }
+
+    return std::equal(a.begin(), a.end(), b.begin());
 }
 
 }
diff --git a/src/libGLESv2/renderer/InputLayoutCache.h b/src/libGLESv2/renderer/InputLayoutCache.h
index 797853d..bb1a8ee 100644
--- a/src/libGLESv2/renderer/InputLayoutCache.h
+++ b/src/libGLESv2/renderer/InputLayoutCache.h
@@ -38,11 +38,26 @@
   private:
     DISALLOW_COPY_AND_ASSIGN(InputLayoutCache);
 
+    struct InputLayoutElement
+    {
+        D3D11_INPUT_ELEMENT_DESC desc;
+        GLenum glslElementType;
+    };
+
     struct InputLayoutKey
     {
         unsigned int elementCount;
-        D3D11_INPUT_ELEMENT_DESC elements[gl::MAX_VERTEX_ATTRIBS];
-        GLenum glslElementType[gl::MAX_VERTEX_ATTRIBS];
+        InputLayoutElement elements[gl::MAX_VERTEX_ATTRIBS];
+
+        const char *begin() const
+        {
+            return reinterpret_cast<const char*>(&elementCount);
+        }
+
+        const char *end() const
+        {
+            return reinterpret_cast<const char*>(&elements[elementCount]);
+        }
     };
 
     struct InputLayoutCounterPair