Remove rx::ShaderSh and move the shared code to the GL.

The GL layer can interact with the translator directly, to query all
the active shader variables and call ShCompile.

BUG=angleproject:1159

Change-Id: I334a9bef28f93cf85dd8cac0fb8542ac567cc3ec
Reviewed-on: https://chromium-review.googlesource.com/299877
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Tryjob-Request: Jamie Madill <jmadill@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index 7aeb1e1..d516762 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -289,7 +289,7 @@
 
 GLuint Context::createShader(GLenum type)
 {
-    return mResourceManager->createShader(getData(), type);
+    return mResourceManager->createShader(mRenderer->getRendererLimitations(), type);
 }
 
 GLuint Context::createTexture()
diff --git a/src/libANGLE/ResourceManager.cpp b/src/libANGLE/ResourceManager.cpp
index 1c6538b..bdfb0ce 100644
--- a/src/libANGLE/ResourceManager.cpp
+++ b/src/libANGLE/ResourceManager.cpp
@@ -88,13 +88,13 @@
 }
 
 // Returns an unused shader/program name
-GLuint ResourceManager::createShader(const gl::Data &data, GLenum type)
+GLuint ResourceManager::createShader(const gl::Limitations &rendererLimitations, GLenum type)
 {
     GLuint handle = mProgramShaderHandleAllocator.allocate();
 
     if (type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER)
     {
-        mShaderMap[handle] = new Shader(this, mFactory, type, handle);
+        mShaderMap[handle] = new Shader(this, mFactory, rendererLimitations, type, handle);
     }
     else UNREACHABLE();
 
diff --git a/src/libANGLE/ResourceManager.h b/src/libANGLE/ResourceManager.h
index 8e95e88..2073e9d 100644
--- a/src/libANGLE/ResourceManager.h
+++ b/src/libANGLE/ResourceManager.h
@@ -25,13 +25,14 @@
 namespace gl
 {
 class Buffer;
-class Shader;
+struct Data;
+class FenceSync;
+struct Limitations;
 class Program;
-class Texture;
 class Renderbuffer;
 class Sampler;
-class FenceSync;
-struct Data;
+class Shader;
+class Texture;
 
 class ResourceManager : angle::NonCopyable
 {
@@ -43,7 +44,7 @@
     void release();
 
     GLuint createBuffer();
-    GLuint createShader(const gl::Data &data, GLenum type);
+    GLuint createShader(const gl::Limitations &rendererLimitations, GLenum type);
     GLuint createProgram();
     GLuint createTexture();
     GLuint createRenderbuffer();
diff --git a/src/libANGLE/Shader.cpp b/src/libANGLE/Shader.cpp
index d0255a4..98fcdca 100644
--- a/src/libANGLE/Shader.cpp
+++ b/src/libANGLE/Shader.cpp
@@ -14,6 +14,7 @@
 
 #include "common/utilities.h"
 #include "GLSLANG/ShaderLang.h"
+#include "libANGLE/Compiler.h"
 #include "libANGLE/Constants.h"
 #include "libANGLE/renderer/Renderer.h"
 #include "libANGLE/renderer/ShaderImpl.h"
@@ -22,6 +23,55 @@
 namespace gl
 {
 
+namespace
+{
+template <typename VarT>
+std::vector<VarT> GetActiveShaderVariables(const std::vector<VarT> *variableList)
+{
+    ASSERT(variableList);
+    std::vector<VarT> result;
+    for (size_t varIndex = 0; varIndex < variableList->size(); varIndex++)
+    {
+        const VarT &var = variableList->at(varIndex);
+        if (var.staticUse)
+        {
+            result.push_back(var);
+        }
+    }
+    return result;
+}
+
+template <typename VarT>
+const std::vector<VarT> &GetShaderVariables(const std::vector<VarT> *variableList)
+{
+    ASSERT(variableList);
+    return *variableList;
+}
+
+// true if varying x has a higher priority in packing than y
+bool CompareVarying(const sh::Varying &x, const sh::Varying &y)
+{
+    if (x.type == y.type)
+    {
+        return x.arraySize > y.arraySize;
+    }
+
+    // Special case for handling structs: we sort these to the end of the list
+    if (x.type == GL_STRUCT_ANGLEX)
+    {
+        return false;
+    }
+
+    if (y.type == GL_STRUCT_ANGLEX)
+    {
+        return true;
+    }
+
+    return gl::VariableSortOrder(x.type) < gl::VariableSortOrder(y.type);
+}
+
+}  // anonymous namespace
+
 Shader::Data::Data(GLenum shaderType) : mShaderType(shaderType), mShaderVersion(100)
 {
 }
@@ -30,9 +80,14 @@
 {
 }
 
-Shader::Shader(ResourceManager *manager, rx::ImplFactory *implFactory, GLenum type, GLuint handle)
+Shader::Shader(ResourceManager *manager,
+               rx::ImplFactory *implFactory,
+               const gl::Limitations &rendererLimitations,
+               GLenum type,
+               GLuint handle)
     : mData(type),
-      mImplementation(implFactory->createShader(&mData)),
+      mImplementation(implFactory->createShader(mData)),
+      mRendererLimitations(rendererLimitations),
       mHandle(handle),
       mType(type),
       mRefCount(0),
@@ -69,17 +124,17 @@
         }
     }
 
-    mSource = stream.str();
+    mData.mSource = stream.str();
 }
 
 int Shader::getInfoLogLength() const
 {
-    if (mData.mInfoLog.empty())
+    if (mInfoLog.empty())
     {
         return 0;
     }
 
-    return (static_cast<int>(mData.mInfoLog.length()) + 1);
+    return (static_cast<int>(mInfoLog.length()) + 1);
 }
 
 void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const
@@ -88,8 +143,8 @@
 
     if (bufSize > 0)
     {
-        index = std::min(bufSize - 1, static_cast<GLsizei>(mData.mInfoLog.length()));
-        memcpy(infoLog, mData.mInfoLog.c_str(), index);
+        index = std::min(bufSize - 1, static_cast<GLsizei>(mInfoLog.length()));
+        memcpy(infoLog, mInfoLog.c_str(), index);
 
         infoLog[index] = '\0';
     }
@@ -102,7 +157,7 @@
 
 int Shader::getSourceLength() const
 {
-    return mSource.empty() ? 0 : (static_cast<int>(mSource.length()) + 1);
+    return mData.mSource.empty() ? 0 : (static_cast<int>(mData.mSource.length()) + 1);
 }
 
 int Shader::getTranslatedSourceLength() const
@@ -135,7 +190,7 @@
 
 void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer) const
 {
-    getSourceImpl(mSource, bufSize, length, buffer);
+    getSourceImpl(mData.mSource, bufSize, length, buffer);
 }
 
 void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) const
@@ -152,7 +207,7 @@
 void Shader::compile(Compiler *compiler)
 {
     mData.mTranslatedSource.clear();
-    mData.mInfoLog.clear();
+    mInfoLog.clear();
     mData.mShaderVersion = 100;
     mData.mVaryings.clear();
     mData.mUniforms.clear();
@@ -160,7 +215,81 @@
     mData.mActiveAttributes.clear();
     mData.mActiveOutputVariables.clear();
 
-    mCompiled = mImplementation->compile(compiler, mSource, 0);
+    ShHandle compilerHandle = compiler->getCompilerHandle(mData.mShaderType);
+
+    std::stringstream sourceStream;
+
+    int additionalOptions = mImplementation->prepareSourceAndReturnOptions(&sourceStream);
+    int compileOptions    = (SH_OBJECT_CODE | SH_VARIABLES | additionalOptions);
+
+    // Some targets (eg D3D11 Feature Level 9_3 and below) do not support non-constant loop indexes
+    // in fragment shaders. Shader compilation will fail. To provide a better error message we can
+    // instruct the compiler to pre-validate.
+    if (mRendererLimitations.shadersRequireIndexedLoopValidation)
+    {
+        compileOptions |= SH_VALIDATE_LOOP_INDEXING;
+    }
+
+    std::string sourceString  = sourceStream.str();
+    const char *sourceCString = sourceString.c_str();
+    bool result               = ShCompile(compilerHandle, &sourceCString, 1, compileOptions);
+
+    if (!result)
+    {
+        mInfoLog = ShGetInfoLog(compilerHandle);
+        TRACE("\n%s", mInfoLog.c_str());
+        mCompiled = false;
+        return;
+    }
+
+    mData.mTranslatedSource = ShGetObjectCode(compilerHandle);
+
+#ifndef NDEBUG
+    // Prefix translated shader with commented out un-translated shader.
+    // Useful in diagnostics tools which capture the shader source.
+    std::ostringstream shaderStream;
+    shaderStream << "// GLSL\n";
+    shaderStream << "//\n";
+
+    size_t curPos = 0;
+    while (curPos != std::string::npos)
+    {
+        size_t nextLine = mData.mSource.find("\n", curPos);
+        size_t len      = (nextLine == std::string::npos) ? std::string::npos : (nextLine - curPos + 1);
+
+        shaderStream << "// " << mData.mSource.substr(curPos, len);
+
+        curPos = (nextLine == std::string::npos) ? std::string::npos : (nextLine + 1);
+    }
+    shaderStream << "\n\n";
+    shaderStream << mData.mTranslatedSource;
+    mData.mTranslatedSource = shaderStream.str();
+#endif
+
+    // Gather the shader information
+    mData.mShaderVersion = ShGetShaderVersion(compilerHandle);
+
+    mData.mVaryings        = GetShaderVariables(ShGetVaryings(compilerHandle));
+    mData.mUniforms        = GetShaderVariables(ShGetUniforms(compilerHandle));
+    mData.mInterfaceBlocks = GetShaderVariables(ShGetInterfaceBlocks(compilerHandle));
+
+    if (mData.mShaderType == GL_VERTEX_SHADER)
+    {
+        mData.mActiveAttributes = GetActiveShaderVariables(ShGetAttributes(compilerHandle));
+    }
+    else
+    {
+        ASSERT(mData.mShaderType == GL_FRAGMENT_SHADER);
+
+        // TODO(jmadill): Figure out why we only sort in the FS, and if we need to.
+        std::sort(mData.mVaryings.begin(), mData.mVaryings.end(), CompareVarying);
+        mData.mActiveOutputVariables =
+            GetActiveShaderVariables(ShGetOutputVariables(compilerHandle));
+    }
+
+    ASSERT(!mData.mTranslatedSource.empty());
+
+    mCompiled = mImplementation->postTranslateCompile(compiler, &mInfoLog);
 }
 
 void Shader::addRef()
diff --git a/src/libANGLE/Shader.h b/src/libANGLE/Shader.h
index 76a5bc1..3508609 100644
--- a/src/libANGLE/Shader.h
+++ b/src/libANGLE/Shader.h
@@ -32,6 +32,7 @@
 namespace gl
 {
 class Compiler;
+struct Limitations;
 class ResourceManager;
 struct Data;
 
@@ -44,7 +45,7 @@
         Data(GLenum shaderType);
         ~Data();
 
-        const std::string &getInfoLog() const { return mInfoLog; }
+        const std::string &getSource() const { return mSource; }
         const std::string &getTranslatedSource() const { return mTranslatedSource; }
 
         GLenum getShaderType() const { return mShaderType; }
@@ -62,19 +63,13 @@
             return mActiveOutputVariables;
         }
 
-        // TODO(jmadill): Remove this.
-        std::string &getMutableInfoLog() { return mInfoLog; }
-
       private:
         friend class Shader;
 
-        // TODO(jmadill): Remove this.
-        friend class rx::ShaderSh;
-
         GLenum mShaderType;
         int mShaderVersion;
         std::string mTranslatedSource;
-        std::string mInfoLog;
+        std::string mSource;
 
         std::vector<sh::Varying> mVaryings;
         std::vector<sh::Uniform> mUniforms;
@@ -83,7 +78,11 @@
         std::vector<sh::OutputVariable> mActiveOutputVariables;
     };
 
-    Shader(ResourceManager *manager, rx::ImplFactory *implFactory, GLenum type, GLuint handle);
+    Shader(ResourceManager *manager,
+           rx::ImplFactory *implFactory,
+           const gl::Limitations &rendererLimitations,
+           GLenum type,
+           GLuint handle);
 
     virtual ~Shader();
 
@@ -127,12 +126,13 @@
 
     Data mData;
     rx::ShaderImpl *mImplementation;
+    const gl::Limitations &mRendererLimitations;
     const GLuint mHandle;
     const GLenum mType;
-    std::string mSource;
     unsigned int mRefCount;     // Number of program objects this shader is attached to
     bool mDeleteStatus;         // Flag to indicate that the shader can be deleted when no longer in use
     bool mCompiled;             // Indicates if this shader has been successfully compiled
+    std::string mInfoLog;
 
     ResourceManager *mResourceManager;
 };
diff --git a/src/libANGLE/renderer/ImplFactory.h b/src/libANGLE/renderer/ImplFactory.h
index 7cc730f..1a63213 100644
--- a/src/libANGLE/renderer/ImplFactory.h
+++ b/src/libANGLE/renderer/ImplFactory.h
@@ -38,8 +38,7 @@
 
     // Shader creation
     virtual CompilerImpl *createCompiler() = 0;
-    // TODO(jmadill): Make const.
-    virtual ShaderImpl *createShader(gl::Shader::Data *data) = 0;
+    virtual ShaderImpl *createShader(const gl::Shader::Data &data) = 0;
     virtual ProgramImpl *createProgram(const gl::Program::Data &data) = 0;
 
     // Framebuffer creation
diff --git a/src/libANGLE/renderer/ShaderImpl.h b/src/libANGLE/renderer/ShaderImpl.h
index 499cd8f..ec164f3 100644
--- a/src/libANGLE/renderer/ShaderImpl.h
+++ b/src/libANGLE/renderer/ShaderImpl.h
@@ -18,17 +18,18 @@
 class ShaderImpl : angle::NonCopyable
 {
   public:
-    ShaderImpl(gl::Shader::Data *data) : mData(data) {}
+    ShaderImpl(const gl::Shader::Data &data) : mData(data) {}
     virtual ~ShaderImpl() { }
 
-    virtual bool compile(gl::Compiler *compiler,
-                         const std::string &source,
-                         int additionalOptions) = 0;
+    // Returns additional ShCompile options.
+    virtual int prepareSourceAndReturnOptions(std::stringstream *sourceStream) = 0;
+    // Returns success for compiling on the driver. Returns success.
+    virtual bool postTranslateCompile(gl::Compiler *compiler, std::string *infoLog) = 0;
+
     virtual std::string getDebugInfo() const = 0;
 
   protected:
-    // TODO(jmadill): Use a const reference when possible.
-    gl::Shader::Data *mData;
+    const gl::Shader::Data &mData;
 };
 
 }
diff --git a/src/libANGLE/renderer/ShaderSh.cpp b/src/libANGLE/renderer/ShaderSh.cpp
deleted file mode 100644
index 2bd21e6..0000000
--- a/src/libANGLE/renderer/ShaderSh.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-//
-// Copyright 2015 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.
-//
-// ShaderSh:
-//   Common class representing a shader compile with ANGLE's translator.
-//
-
-#include "libANGLE/renderer/ShaderSh.h"
-
-#include "common/utilities.h"
-#include "libANGLE/Caps.h"
-#include "libANGLE/Compiler.h"
-
-namespace rx
-{
-
-namespace
-{
-template <typename VarT>
-std::vector<VarT> GetActiveShaderVariables(const std::vector<VarT> *variableList)
-{
-    ASSERT(variableList);
-    std::vector<VarT> result;
-    for (size_t varIndex = 0; varIndex < variableList->size(); varIndex++)
-    {
-        const VarT &var = variableList->at(varIndex);
-        if (var.staticUse)
-        {
-            result.push_back(var);
-        }
-    }
-    return result;
-}
-
-template <typename VarT>
-const std::vector<VarT> &GetShaderVariables(const std::vector<VarT> *variableList)
-{
-    ASSERT(variableList);
-    return *variableList;
-}
-
-// true if varying x has a higher priority in packing than y
-bool CompareVarying(const sh::Varying &x, const sh::Varying &y)
-{
-    if (x.type == y.type)
-    {
-        return x.arraySize > y.arraySize;
-    }
-
-    // Special case for handling structs: we sort these to the end of the list
-    if (x.type == GL_STRUCT_ANGLEX)
-    {
-        return false;
-    }
-
-    if (y.type == GL_STRUCT_ANGLEX)
-    {
-        return true;
-    }
-
-    return gl::VariableSortOrder(x.type) < gl::VariableSortOrder(y.type);
-}
-
-}  // anonymous namespace
-
-ShaderSh::ShaderSh(gl::Shader::Data *data, const gl::Limitations &rendererLimitations)
-    : ShaderImpl(data), mRendererLimitations(rendererLimitations)
-{
-}
-
-ShaderSh::~ShaderSh()
-{
-}
-
-bool ShaderSh::compile(gl::Compiler *compiler, const std::string &source, int additionalOptions)
-{
-    ShHandle compilerHandle = compiler->getCompilerHandle(mData->getShaderType());
-
-    int compileOptions = (SH_OBJECT_CODE | SH_VARIABLES | additionalOptions);
-
-    // Some targets (eg D3D11 Feature Level 9_3 and below) do not support non-constant loop indexes
-    // in fragment shaders. Shader compilation will fail. To provide a better error message we can
-    // instruct the compiler to pre-validate.
-    if (mRendererLimitations.shadersRequireIndexedLoopValidation)
-    {
-        compileOptions |= SH_VALIDATE_LOOP_INDEXING;
-    }
-
-    const char *sourceCString = source.c_str();
-    bool result               = ShCompile(compilerHandle, &sourceCString, 1, compileOptions);
-
-    if (!result)
-    {
-        mData->mInfoLog = ShGetInfoLog(compilerHandle);
-        TRACE("\n%s", mData->mInfoLog.c_str());
-        return false;
-    }
-
-    mData->mTranslatedSource = ShGetObjectCode(compilerHandle);
-
-#ifndef NDEBUG
-    // Prefix translated shader with commented out un-translated shader.
-    // Useful in diagnostics tools which capture the shader source.
-    std::ostringstream shaderStream;
-    shaderStream << "// GLSL\n";
-    shaderStream << "//\n";
-
-    size_t curPos = 0;
-    while (curPos != std::string::npos)
-    {
-        size_t nextLine = source.find("\n", curPos);
-        size_t len      = (nextLine == std::string::npos) ? std::string::npos : (nextLine - curPos + 1);
-
-        shaderStream << "// " << source.substr(curPos, len);
-
-        curPos = (nextLine == std::string::npos) ? std::string::npos : (nextLine + 1);
-    }
-    shaderStream << "\n\n";
-    shaderStream << mData->mTranslatedSource;
-    mData->mTranslatedSource = shaderStream.str();
-#endif
-
-    // Gather the shader information
-    mData->mShaderVersion = ShGetShaderVersion(compilerHandle);
-
-    mData->mVaryings        = GetShaderVariables(ShGetVaryings(compilerHandle));
-    mData->mUniforms        = GetShaderVariables(ShGetUniforms(compilerHandle));
-    mData->mInterfaceBlocks = GetShaderVariables(ShGetInterfaceBlocks(compilerHandle));
-
-    if (mData->mShaderType == GL_VERTEX_SHADER)
-    {
-        mData->mActiveAttributes = GetActiveShaderVariables(ShGetAttributes(compilerHandle));
-    }
-    else
-    {
-        ASSERT(mData->mShaderType == GL_FRAGMENT_SHADER);
-
-        // TODO(jmadill): Figure out why we only sort in the FS, and if we need to.
-        std::sort(mData->mVaryings.begin(), mData->mVaryings.end(), CompareVarying);
-        mData->mActiveOutputVariables =
-            GetActiveShaderVariables(ShGetOutputVariables(compilerHandle));
-    }
-
-    ASSERT(!mData->mTranslatedSource.empty());
-    return true;
-}
-
-}  // namespace rx
diff --git a/src/libANGLE/renderer/ShaderSh.h b/src/libANGLE/renderer/ShaderSh.h
deleted file mode 100644
index 7e0f464..0000000
--- a/src/libANGLE/renderer/ShaderSh.h
+++ /dev/null
@@ -1,38 +0,0 @@
-//
-// Copyright 2015 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.
-//
-// ShaderSh:
-//   Common class representing a shader compile with ANGLE's translator.
-//   TODO(jmadill): Move this to the GL layer.
-//
-
-#ifndef LIBANGLE_RENDERER_SHADERSH_H_
-#define LIBANGLE_RENDERER_SHADERSH_H_
-
-#include "libANGLE/renderer/ShaderImpl.h"
-
-namespace gl
-{
-struct Limitations;
-}
-
-namespace rx
-{
-
-class ShaderSh : public ShaderImpl
-{
-  public:
-    ShaderSh(gl::Shader::Data *data, const gl::Limitations &rendererLimitations);
-    ~ShaderSh();
-
-    bool compile(gl::Compiler *compiler, const std::string &source, int additionalOptions) override;
-
-  protected:
-    const gl::Limitations &mRendererLimitations;
-};
-
-}  // namespace rx
-
-#endif  // LIBANGLE_RENDERER_SHADERSH_H_
diff --git a/src/libANGLE/renderer/d3d/ShaderD3D.cpp b/src/libANGLE/renderer/d3d/ShaderD3D.cpp
index 4bbd66b..07bd10d 100644
--- a/src/libANGLE/renderer/d3d/ShaderD3D.cpp
+++ b/src/libANGLE/renderer/d3d/ShaderD3D.cpp
@@ -39,8 +39,7 @@
 namespace rx
 {
 
-ShaderD3D::ShaderD3D(gl::Shader::Data *data, const gl::Limitations &limitations)
-    : ShaderSh(data, limitations)
+ShaderD3D::ShaderD3D(const gl::Shader::Data &data) : ShaderImpl(data)
 {
     uncompile();
 }
@@ -51,7 +50,7 @@
 
 std::string ShaderD3D::getDebugInfo() const
 {
-    return mDebugInfo + std::string("\n// ") + GetShaderTypeString(mData->getShaderType()) +
+    return mDebugInfo + std::string("\n// ") + GetShaderTypeString(mData.getShaderType()) +
            " SHADER END\n";
 }
 
@@ -118,39 +117,33 @@
     return mCompilerOutputType;
 }
 
-bool ShaderD3D::compile(gl::Compiler *compiler, const std::string &source, int additionalOptionsIn)
+int ShaderD3D::prepareSourceAndReturnOptions(std::stringstream *shaderSourceStream)
 {
     uncompile();
 
-    ShHandle compilerHandle = compiler->getCompilerHandle(mData->getShaderType());
-
-    // TODO(jmadill): We shouldn't need to cache this.
-    mCompilerOutputType = ShGetShaderOutputType(compilerHandle);
-
-    int additionalOptions = additionalOptionsIn;
+    int additionalOptions = 0;
 
 #if !defined(ANGLE_ENABLE_WINDOWS_STORE)
-
-    std::stringstream sourceStream;
+    const std::string &source = mData.getSource();
 
     if (gl::DebugAnnotationsActive())
     {
         std::string sourcePath = getTempPath();
         writeFile(sourcePath.c_str(), source.c_str(), source.length());
         additionalOptions |= SH_LINE_DIRECTIVES | SH_SOURCE_PATH;
-        sourceStream << sourcePath;
+        *shaderSourceStream << sourcePath;
     }
 #endif
+    *shaderSourceStream << source;
+    return additionalOptions;
+}
 
-    sourceStream << source;
-    bool result = ShaderSh::compile(compiler, sourceStream.str(), additionalOptions);
+bool ShaderD3D::postTranslateCompile(gl::Compiler *compiler, std::string *infoLog)
+{
+    // TODO(jmadill): We shouldn't need to cache this.
+    mCompilerOutputType = compiler->getShaderOutputType();
 
-    if (!result)
-    {
-        return false;
-    }
-
-    const std::string &translatedSource = mData->getTranslatedSource();
+    const std::string &translatedSource = mData.getTranslatedSource();
 
     mUsesMultipleRenderTargets = translatedSource.find("GL_USES_MRT") != std::string::npos;
     mUsesFragColor             = translatedSource.find("GL_USES_FRAG_COLOR") != std::string::npos;
@@ -168,7 +161,9 @@
     mRequiresIEEEStrictCompiling =
         translatedSource.find("ANGLE_REQUIRES_IEEE_STRICT_COMPILING") != std::string::npos;
 
-    for (const sh::Uniform &uniform : mData->getUniforms())
+    ShHandle compilerHandle = compiler->getCompilerHandle(mData.getShaderType());
+
+    for (const sh::Uniform &uniform : mData.getUniforms())
     {
         if (uniform.staticUse && !uniform.isBuiltIn())
         {
@@ -182,7 +177,7 @@
         }
     }
 
-    for (const sh::InterfaceBlock &interfaceBlock : mData->getInterfaceBlocks())
+    for (const sh::InterfaceBlock &interfaceBlock : mData.getInterfaceBlocks())
     {
         if (interfaceBlock.staticUse)
         {
diff --git a/src/libANGLE/renderer/d3d/ShaderD3D.h b/src/libANGLE/renderer/d3d/ShaderD3D.h
index 9a2c136..f61917a 100644
--- a/src/libANGLE/renderer/d3d/ShaderD3D.h
+++ b/src/libANGLE/renderer/d3d/ShaderD3D.h
@@ -9,7 +9,7 @@
 #ifndef LIBANGLE_RENDERER_D3D_SHADERD3D_H_
 #define LIBANGLE_RENDERER_D3D_SHADERD3D_H_
 
-#include "libANGLE/renderer/ShaderSh.h"
+#include "libANGLE/renderer/ShaderImpl.h"
 
 #include <map>
 
@@ -19,16 +19,17 @@
 class RendererD3D;
 struct D3DCompilerWorkarounds;
 
-class ShaderD3D : public ShaderSh
+class ShaderD3D : public ShaderImpl
 {
     friend class DynamicHLSL;
 
   public:
-    ShaderD3D(gl::Shader::Data *data, const gl::Limitations &limitations);
+    ShaderD3D(const gl::Shader::Data &data);
     virtual ~ShaderD3D();
 
     // ShaderImpl implementation
-    bool compile(gl::Compiler *compiler, const std::string &source, int additionalOptions) override;
+    int prepareSourceAndReturnOptions(std::stringstream *sourceStream) override;
+    bool postTranslateCompile(gl::Compiler *compiler, std::string *infoLog) override;
     std::string getDebugInfo() const override;
 
     // D3D-specific methods
@@ -64,7 +65,6 @@
     std::string mDebugInfo;
     std::map<std::string, unsigned int> mUniformRegisterMap;
     std::map<std::string, unsigned int> mInterfaceBlockRegisterMap;
-    RendererD3D *mRenderer;
 };
 
 }
diff --git a/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
index 8941ecd..0f2f881 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
@@ -3003,9 +3003,9 @@
     return new Framebuffer11(data, this);
 }
 
-ShaderImpl *Renderer11::createShader(gl::Shader::Data *data)
+ShaderImpl *Renderer11::createShader(const gl::Shader::Data &data)
 {
-    return new ShaderD3D(data, getRendererLimitations());
+    return new ShaderD3D(data);
 }
 
 ProgramImpl *Renderer11::createProgram(const gl::Program::Data &data)
diff --git a/src/libANGLE/renderer/d3d/d3d11/Renderer11.h b/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
index 52e4433..97f3558 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
+++ b/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
@@ -182,7 +182,7 @@
     FramebufferImpl *createFramebuffer(const gl::Framebuffer::Data &data) override;
 
     // Shader creation
-    ShaderImpl *createShader(gl::Shader::Data *data) override;
+    ShaderImpl *createShader(const gl::Shader::Data &data) override;
     ProgramImpl *createProgram(const gl::Program::Data &data) override;
 
     // Shader operations
diff --git a/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp b/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
index 1556514..2657b9e 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
@@ -2713,9 +2713,9 @@
     return new Framebuffer9(data, this);
 }
 
-ShaderImpl *Renderer9::createShader(gl::Shader::Data *data)
+ShaderImpl *Renderer9::createShader(const gl::Shader::Data &data)
 {
-    return new ShaderD3D(data, getRendererLimitations());
+    return new ShaderD3D(data);
 }
 
 ProgramImpl *Renderer9::createProgram(const gl::Program::Data &data)
diff --git a/src/libANGLE/renderer/d3d/d3d9/Renderer9.h b/src/libANGLE/renderer/d3d/d3d9/Renderer9.h
index 39f3d51..e6d3a44 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Renderer9.h
+++ b/src/libANGLE/renderer/d3d/d3d9/Renderer9.h
@@ -169,7 +169,7 @@
     FramebufferImpl *createFramebuffer(const gl::Framebuffer::Data &data) override;
 
     // Shader creation
-    ShaderImpl *createShader(gl::Shader::Data *data) override;
+    ShaderImpl *createShader(const gl::Shader::Data &data) override;
     ProgramImpl *createProgram(const gl::Program::Data &data) override;
 
     // Shader operations
diff --git a/src/libANGLE/renderer/gl/RendererGL.cpp b/src/libANGLE/renderer/gl/RendererGL.cpp
index bbbb01d..e1fbf24 100644
--- a/src/libANGLE/renderer/gl/RendererGL.cpp
+++ b/src/libANGLE/renderer/gl/RendererGL.cpp
@@ -242,9 +242,9 @@
     return new CompilerGL(mFunctions);
 }
 
-ShaderImpl *RendererGL::createShader(gl::Shader::Data *data)
+ShaderImpl *RendererGL::createShader(const gl::Shader::Data &data)
 {
-    return new ShaderGL(data, getRendererLimitations(), mFunctions);
+    return new ShaderGL(data, mFunctions);
 }
 
 ProgramImpl *RendererGL::createProgram(const gl::Program::Data &data)
diff --git a/src/libANGLE/renderer/gl/RendererGL.h b/src/libANGLE/renderer/gl/RendererGL.h
index 8fc3251..f493296 100644
--- a/src/libANGLE/renderer/gl/RendererGL.h
+++ b/src/libANGLE/renderer/gl/RendererGL.h
@@ -59,7 +59,7 @@
 
     // Shader creation
     CompilerImpl *createCompiler() override;
-    ShaderImpl *createShader(gl::Shader::Data *data) override;
+    ShaderImpl *createShader(const gl::Shader::Data &data) override;
     ProgramImpl *createProgram(const gl::Program::Data &data) override;
 
     // Framebuffer creation
diff --git a/src/libANGLE/renderer/gl/ShaderGL.cpp b/src/libANGLE/renderer/gl/ShaderGL.cpp
index 6c9aa13..7c8fd76 100644
--- a/src/libANGLE/renderer/gl/ShaderGL.cpp
+++ b/src/libANGLE/renderer/gl/ShaderGL.cpp
@@ -16,10 +16,8 @@
 namespace rx
 {
 
-ShaderGL::ShaderGL(gl::Shader::Data *data,
-                   const gl::Limitations &rendererLimitations,
-                   const FunctionsGL *functions)
-    : ShaderSh(data, rendererLimitations), mFunctions(functions), mShaderID(0)
+ShaderGL::ShaderGL(const gl::Shader::Data &data, const FunctionsGL *functions)
+    : ShaderImpl(data), mFunctions(functions), mShaderID(0)
 {
     ASSERT(mFunctions);
 }
@@ -33,7 +31,7 @@
     }
 }
 
-bool ShaderGL::compile(gl::Compiler *compiler, const std::string &source, int additionalOptionsIn)
+int ShaderGL::prepareSourceAndReturnOptions(std::stringstream *sourceStream)
 {
     // Reset the previous state
     if (mShaderID != 0)
@@ -42,17 +40,18 @@
         mShaderID = 0;
     }
 
-    int additionalOptions = (additionalOptionsIn | SH_INIT_GL_POSITION);
-    if (!ShaderSh::compile(compiler, source, additionalOptions))
-    {
-        return false;
-    }
+    *sourceStream << mData.getSource();
 
+    return SH_INIT_GL_POSITION;
+}
+
+bool ShaderGL::postTranslateCompile(gl::Compiler *compiler, std::string *infoLog)
+{
     // Translate the ESSL into GLSL
-    const char *translatedSourceCString = mData->getTranslatedSource().c_str();
+    const char *translatedSourceCString = mData.getTranslatedSource().c_str();
 
     // Generate a shader object and set the source
-    mShaderID = mFunctions->createShader(mData->getShaderType());
+    mShaderID = mFunctions->createShader(mData.getShaderType());
     mFunctions->shaderSource(mShaderID, 1, &translatedSourceCString, nullptr);
     mFunctions->compileShader(mShaderID);
 
@@ -72,9 +71,8 @@
         mFunctions->deleteShader(mShaderID);
         mShaderID = 0;
 
-        // TODO(jmadill): possibly pass in info log?
-        mData->getMutableInfoLog() = &buf[0];
-        TRACE("\n%s", mData->getMutableInfoLog().c_str());
+        *infoLog = &buf[0];
+        TRACE("\n%s", infoLog->c_str());
         return false;
     }
 
diff --git a/src/libANGLE/renderer/gl/ShaderGL.h b/src/libANGLE/renderer/gl/ShaderGL.h
index ffc17b0..1a032ab 100644
--- a/src/libANGLE/renderer/gl/ShaderGL.h
+++ b/src/libANGLE/renderer/gl/ShaderGL.h
@@ -9,22 +9,21 @@
 #ifndef LIBANGLE_RENDERER_GL_SHADERGL_H_
 #define LIBANGLE_RENDERER_GL_SHADERGL_H_
 
-#include "libANGLE/renderer/ShaderSh.h"
+#include "libANGLE/renderer/ShaderImpl.h"
 
 namespace rx
 {
 class FunctionsGL;
-class RendererGL;
 
-class ShaderGL : public ShaderSh
+class ShaderGL : public ShaderImpl
 {
   public:
-    ShaderGL(gl::Shader::Data *data,
-             const gl::Limitations &rendererLimitations,
-             const FunctionsGL *functions);
+    ShaderGL(const gl::Shader::Data &data, const FunctionsGL *functions);
     ~ShaderGL() override;
 
-    bool compile(gl::Compiler *compiler, const std::string &source, int additionalOptions) override;
+    // ShaderImpl implementation
+    int prepareSourceAndReturnOptions(std::stringstream *sourceStream) override;
+    bool postTranslateCompile(gl::Compiler *compiler, std::string *infoLog) override;
     std::string getDebugInfo() const override;
 
     GLuint getShaderID() const;
diff --git a/src/libGLESv2.gypi b/src/libGLESv2.gypi
index 23bfe4d..646e0c0 100644
--- a/src/libGLESv2.gypi
+++ b/src/libGLESv2.gypi
@@ -147,8 +147,6 @@
             'libANGLE/renderer/Renderer.cpp',
             'libANGLE/renderer/Renderer.h',
             'libANGLE/renderer/ShaderImpl.h',
-            'libANGLE/renderer/ShaderSh.cpp',
-            'libANGLE/renderer/ShaderSh.h',
             'libANGLE/renderer/SurfaceImpl.cpp',
             'libANGLE/renderer/SurfaceImpl.h',
             'libANGLE/renderer/TextureImpl.h',
diff --git a/src/tests/angle_unittests_utils.h b/src/tests/angle_unittests_utils.h
index 45a28a0..fa2a63d 100644
--- a/src/tests/angle_unittests_utils.h
+++ b/src/tests/angle_unittests_utils.h
@@ -22,7 +22,7 @@
 
     // Shader creation
     CompilerImpl *createCompiler() override { return nullptr; }
-    ShaderImpl *createShader(gl::Shader::Data *data) override { return nullptr; }
+    ShaderImpl *createShader(const gl::Shader::Data &data) override { return nullptr; }
     ProgramImpl *createProgram(const gl::Program::Data &data) override { return nullptr; }
 
     // Framebuffer creation