Refactor attempting shader compilation with different flags.

BUG=angle:648

Change-Id: Ie340eaa708820cc13be6d1f5ba04555b6c1918ea
Reviewed-on: https://chromium-review.googlesource.com/199310
Tested-by: Nicolas Capens <nicolascapens@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp b/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
index f45ba5b..d3ddd98 100644
--- a/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
+++ b/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
@@ -66,7 +66,7 @@
 }
 
 ShaderBlob *HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile,
-                                         unsigned int optimizationFlags, bool alternateFlags) const
+                                          const UINT optimizationFlags[], const char *flagNames[], int attempts) const
 {
     ASSERT(mD3DCompilerModule && mD3DCompileFunc);
 
@@ -75,54 +75,14 @@
         return NULL;
     }
 
-    HRESULT result = S_OK;
-    UINT flags = 0;
-    std::string sourceText;
-    if (gl::perfActive())
-    {
-        flags |= D3DCOMPILE_DEBUG;
-
-#ifdef NDEBUG
-        flags |= optimizationFlags;
-#else
-        flags |= D3DCOMPILE_SKIP_OPTIMIZATION;
-#endif
-
-        std::string sourcePath = getTempPath();
-        sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(hlsl);
-        writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size());
-    }
-    else
-    {
-        flags |= optimizationFlags;
-        sourceText = hlsl;
-    }
-
-    // Sometimes D3DCompile will fail with the default compilation flags for complicated shaders when it would otherwise pass with alternative options.
-    // Try the default flags first and if compilation fails, try some alternatives.
-    const static UINT extraFlags[] =
-    {
-        0,
-        D3DCOMPILE_AVOID_FLOW_CONTROL,
-        D3DCOMPILE_PREFER_FLOW_CONTROL
-    };
-
-    const static char * const extraFlagNames[] =
-    {
-        "default",
-        "avoid flow control",
-        "prefer flow control"
-    };
-
-    int attempts = alternateFlags ? ArraySize(extraFlags) : 1;
     pD3DCompile compileFunc = reinterpret_cast<pD3DCompile>(mD3DCompileFunc);
     for (int i = 0; i < attempts; ++i)
     {
         ID3DBlob *errorMessage = NULL;
         ID3DBlob *binary = NULL;
 
-        result = compileFunc(hlsl, strlen(hlsl), gl::g_fakepath, NULL, NULL,
-            "main", profile, flags | extraFlags[i], 0, &binary, &errorMessage);
+        HRESULT result = compileFunc(hlsl, strlen(hlsl), gl::g_fakepath, NULL, NULL, "main", profile, optimizationFlags[i], 0, &binary, &errorMessage);
+
         if (errorMessage)
         {
             const char *message = (const char*)errorMessage->GetBufferPointer();
@@ -146,12 +106,12 @@
             }
 
             infoLog.append("Warning: D3D shader compilation failed with ");
-            infoLog.append(extraFlagNames[i]);
+            infoLog.append(flagNames[i]);
             infoLog.append(" flags.");
             if (i + 1 < attempts)
             {
                 infoLog.append(" Retrying with ");
-                infoLog.append(extraFlagNames[i + 1]);
+                infoLog.append(flagNames[i + 1]);
                 infoLog.append(".\n");
             }
         }
diff --git a/src/libGLESv2/renderer/d3d/HLSLCompiler.h b/src/libGLESv2/renderer/d3d/HLSLCompiler.h
index cf8caf2..ab685f1 100644
--- a/src/libGLESv2/renderer/d3d/HLSLCompiler.h
+++ b/src/libGLESv2/renderer/d3d/HLSLCompiler.h
@@ -26,7 +26,7 @@
     void release();
 
     ShaderBlob *compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile,
-                                unsigned int optimizationFlags, bool alternateFlags) const;
+                                const UINT optimizationFlags[], const char *flagNames[], int attempts) const;
 
   private:
     DISALLOW_COPY_AND_ASSIGN(HLSLCompiler);
diff --git a/src/libGLESv2/renderer/d3d11/Renderer11.cpp b/src/libGLESv2/renderer/d3d11/Renderer11.cpp
index 224de35..0b26cda 100644
--- a/src/libGLESv2/renderer/d3d11/Renderer11.cpp
+++ b/src/libGLESv2/renderer/d3d11/Renderer11.cpp
@@ -3045,7 +3045,36 @@
     char profile[32];
     snprintf(profile, ArraySize(profile), "%s_%s", profileType, profileVersion);
 
-    ID3DBlob *binary = (ID3DBlob*)mCompiler.compileToBinary(infoLog, shaderHLSL, profile, D3DCOMPILE_OPTIMIZATION_LEVEL0, false);
+    UINT flags = D3DCOMPILE_OPTIMIZATION_LEVEL0;
+
+    if (gl::perfActive())
+    {
+#ifndef NDEBUG
+        flags = D3DCOMPILE_SKIP_OPTIMIZATION;
+#endif
+
+        flags |= D3DCOMPILE_DEBUG;
+
+        std::string sourcePath = getTempPath();
+        std::string sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(shaderHLSL);
+        writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size());
+    }
+
+    // Sometimes D3DCompile will fail with the default compilation flags for complicated shaders when it would otherwise pass with alternative options.
+    // Try the default flags first and if compilation fails, try some alternatives.
+    const UINT extraFlags[] =
+    {
+        flags
+    };
+
+    const static char *extraFlagNames[] =
+    {
+        "default"
+    };
+
+    int attempts = ArraySize(extraFlags);
+
+    ID3DBlob *binary = (ID3DBlob*)mCompiler.compileToBinary(infoLog, shaderHLSL, profile, extraFlags, extraFlagNames, attempts);
     if (!binary)
     {
         return NULL;
diff --git a/src/libGLESv2/renderer/d3d9/Renderer9.cpp b/src/libGLESv2/renderer/d3d9/Renderer9.cpp
index c5ad862..bfb3bbf 100644
--- a/src/libGLESv2/renderer/d3d9/Renderer9.cpp
+++ b/src/libGLESv2/renderer/d3d9/Renderer9.cpp
@@ -3380,19 +3380,50 @@
         return NULL;
     }
 
-    UINT optimizationFlags = ANGLE_COMPILE_OPTIMIZATION_LEVEL;
+    UINT flags = ANGLE_COMPILE_OPTIMIZATION_LEVEL;
 
     if (workaround == ANGLE_D3D_WORKAROUND_SKIP_OPTIMIZATION)
     {
-        optimizationFlags = D3DCOMPILE_SKIP_OPTIMIZATION;
+        flags = D3DCOMPILE_SKIP_OPTIMIZATION;
     }
     else if (workaround == ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION)
     {
-        optimizationFlags = D3DCOMPILE_OPTIMIZATION_LEVEL3;
+        flags = D3DCOMPILE_OPTIMIZATION_LEVEL3;
     }
     else ASSERT(workaround == ANGLE_D3D_WORKAROUND_NONE);
 
-    ID3DBlob *binary = (ID3DBlob*)mCompiler.compileToBinary(infoLog, shaderHLSL, profile, optimizationFlags, true);
+    if (gl::perfActive())
+    {
+#ifndef NDEBUG
+        flags = D3DCOMPILE_SKIP_OPTIMIZATION;
+#endif
+
+        flags |= D3DCOMPILE_DEBUG;
+
+        std::string sourcePath = getTempPath();
+        std::string sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(shaderHLSL);
+        writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size());
+    }
+
+    // Sometimes D3DCompile will fail with the default compilation flags for complicated shaders when it would otherwise pass with alternative options.
+    // Try the default flags first and if compilation fails, try some alternatives.
+    const UINT extraFlags[] =
+    {
+        flags,
+        flags | D3DCOMPILE_AVOID_FLOW_CONTROL,
+        flags | D3DCOMPILE_PREFER_FLOW_CONTROL
+    };
+
+    const static char *extraFlagNames[] =
+    {
+        "default",
+        "avoid flow control",
+        "prefer flow control"
+    };
+
+    int attempts = ArraySize(extraFlags);
+
+    ID3DBlob *binary = (ID3DBlob*)mCompiler.compileToBinary(infoLog, shaderHLSL, profile, extraFlags, extraFlagNames, attempts);
     if (!binary)
     {
         return NULL;