Refactor Context dependency for resolveCompile

The context parameter of Shader::resolveCompile method causes a bad
impact that many methods in Shader, Program etc. have to have a same
context parameter. By removing it, these methods can be decoupled
from Context.

BUG=chromium:849576

Change-Id: Ia5545ee9dce45794550f6086bc0e6c4707e1276e
Reviewed-on: https://chromium-review.googlesource.com/1172202
Commit-Queue: Jie A Chen <jie.a.chen@intel.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index 3e1f2f5..55718fe 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -2503,7 +2503,7 @@
 {
     auto *programObject = getProgram(program);
 
-    programObject->pathFragmentInputGen(this, location, genMode, components, coeffs);
+    programObject->pathFragmentInputGen(location, genMode, components, coeffs);
 }
 
 GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
@@ -5355,7 +5355,7 @@
 {
     Shader *shaderObject = getShader(shader);
     ASSERT(shaderObject);
-    QueryShaderiv(this, shaderObject, pname, params);
+    QueryShaderiv(shaderObject, pname, params);
 }
 
 void Context::getShaderivRobust(GLuint shader,
@@ -5371,7 +5371,7 @@
 {
     Shader *shaderObject = getShader(shader);
     ASSERT(shaderObject);
-    shaderObject->getInfoLog(this, bufsize, length, infolog);
+    shaderObject->getInfoLog(bufsize, length, infolog);
 }
 
 void Context::getShaderPrecisionFormat(GLenum shadertype,
@@ -6633,7 +6633,7 @@
 {
     Shader *shaderObject = getShader(shader);
     ASSERT(shaderObject);
-    shaderObject->getTranslatedSourceWithDebugInfo(this, bufsize, length, source);
+    shaderObject->getTranslatedSourceWithDebugInfo(bufsize, length, source);
 }
 
 void Context::getnUniformfv(GLuint program, GLint location, GLsizei bufSize, GLfloat *params)
diff --git a/src/libANGLE/GLES1Renderer.cpp b/src/libANGLE/GLES1Renderer.cpp
index 75da6c5..c608679 100644
--- a/src/libANGLE/GLES1Renderer.cpp
+++ b/src/libANGLE/GLES1Renderer.cpp
@@ -496,11 +496,11 @@
 
     *shaderOut = shader;
 
-    if (!shaderObject->isCompiled(context))
+    if (!shaderObject->isCompiled())
     {
-        GLint infoLogLength = shaderObject->getInfoLogLength(context);
+        GLint infoLogLength = shaderObject->getInfoLogLength();
         std::vector<char> infoLog(infoLogLength, 0);
-        shaderObject->getInfoLog(context, infoLogLength - 1, nullptr, infoLog.data());
+        shaderObject->getInfoLog(infoLogLength - 1, nullptr, infoLog.data());
         fprintf(stderr, "GLES1Renderer::%s: Info log: %s\n", __func__, infoLog.data());
         return InternalError() << "GLES1Renderer shader compile failed. Source: " << src
                                << " Info log: " << infoLog.data();
diff --git a/src/libANGLE/Program.cpp b/src/libANGLE/Program.cpp
index f1cd2d4..86c2dfa 100644
--- a/src/libANGLE/Program.cpp
+++ b/src/libANGLE/Program.cpp
@@ -23,6 +23,7 @@
 #include "libANGLE/ResourceManager.h"
 #include "libANGLE/Uniform.h"
 #include "libANGLE/VaryingPacking.h"
+#include "libANGLE/Version.h"
 #include "libANGLE/features.h"
 #include "libANGLE/histogram_macros.h"
 #include "libANGLE/queryconversions.h"
@@ -337,30 +338,26 @@
     }
 }
 
-void InitUniformBlockLinker(const gl::Context *context,
-                            const ProgramState &state,
-                            UniformBlockLinker *blockLinker)
+void InitUniformBlockLinker(const ProgramState &state, UniformBlockLinker *blockLinker)
 {
     for (ShaderType shaderType : AllShaderTypes())
     {
         Shader *shader = state.getAttachedShader(shaderType);
         if (shader)
         {
-            blockLinker->addShaderBlocks(shaderType, &shader->getUniformBlocks(context));
+            blockLinker->addShaderBlocks(shaderType, &shader->getUniformBlocks());
         }
     }
 }
 
-void InitShaderStorageBlockLinker(const gl::Context *context,
-                                  const ProgramState &state,
-                                  ShaderStorageBlockLinker *blockLinker)
+void InitShaderStorageBlockLinker(const ProgramState &state, ShaderStorageBlockLinker *blockLinker)
 {
     for (ShaderType shaderType : AllShaderTypes())
     {
         Shader *shader = state.getAttachedShader(shaderType);
         if (shader != nullptr)
         {
-            blockLinker->addShaderBlocks(shaderType, &shader->getShaderStorageBlocks(context));
+            blockLinker->addShaderBlocks(shaderType, &shader->getShaderStorageBlocks());
         }
     }
 }
@@ -1011,7 +1008,7 @@
     mFragmentInputBindings.bindLocation(index, name);
 }
 
-BindingInfo Program::getFragmentInputBindingInfo(const Context *context, GLint index) const
+BindingInfo Program::getFragmentInputBindingInfo(GLint index) const
 {
     resolveLink();
     BindingInfo ret;
@@ -1022,7 +1019,7 @@
     ASSERT(fragmentShader);
 
     // Find the actual fragment shader varying we're interested in
-    const std::vector<sh::Varying> &inputs = fragmentShader->getInputVaryings(context);
+    const std::vector<sh::Varying> &inputs = fragmentShader->getInputVaryings();
 
     for (const auto &binding : mFragmentInputBindings)
     {
@@ -1064,8 +1061,7 @@
     return ret;
 }
 
-void Program::pathFragmentInputGen(const Context *context,
-                                   GLint index,
+void Program::pathFragmentInputGen(GLint index,
                                    GLenum genMode,
                                    GLint components,
                                    const GLfloat *coeffs)
@@ -1075,7 +1071,7 @@
     if (index == -1)
         return;
 
-    const auto &binding = getFragmentInputBindingInfo(context, index);
+    const auto &binding = getFragmentInputBindingInfo(index);
 
     // If the input doesn't exist then then the command is silently ignored
     // This could happen through optimization for example, the shader translator
@@ -1100,7 +1096,7 @@
     mInfoLog.reset();
 
     // Validate we have properly attached shaders before checking the cache.
-    if (!linkValidateShaders(context, mInfoLog))
+    if (!linkValidateShaders(mInfoLog))
     {
         return NoError();
     }
@@ -1126,7 +1122,7 @@
     unlink();
 
     // Re-link shaders after the unlink call.
-    ASSERT(linkValidateShaders(context, mInfoLog));
+    ASSERT(linkValidateShaders(mInfoLog));
 
     std::unique_ptr<ProgramLinkedResources> resources;
     if (mState.mAttachedShaders[ShaderType::Compute])
@@ -1139,14 +1135,16 @@
                                        {}});
 
         GLuint combinedImageUniforms = 0u;
-        if (!linkUniforms(context, mInfoLog, mUniformLocationBindings, &combinedImageUniforms,
-                          &resources->unusedUniforms))
+        if (!linkUniforms(context->getCaps(), mInfoLog, mUniformLocationBindings,
+                          &combinedImageUniforms, &resources->unusedUniforms))
         {
             return NoError();
         }
 
         GLuint combinedShaderStorageBlocks = 0u;
-        if (!linkInterfaceBlocks(context, mInfoLog, &combinedShaderStorageBlocks))
+        if (!linkInterfaceBlocks(context->getCaps(), context->getClientVersion(),
+                                 context->getExtensions().webglCompatibility, mInfoLog,
+                                 &combinedShaderStorageBlocks))
         {
             return NoError();
         }
@@ -1167,8 +1165,8 @@
             return NoError();
         }
 
-        InitUniformBlockLinker(context, mState, &resources->uniformBlockLinker);
-        InitShaderStorageBlockLinker(context, mState, &resources->shaderStorageBlockLinker);
+        InitUniformBlockLinker(mState, &resources->uniformBlockLinker);
+        InitShaderStorageBlockLinker(mState, &resources->shaderStorageBlockLinker);
     }
     else
     {
@@ -1192,48 +1190,52 @@
                                        {&mState.mAtomicCounterBuffers},
                                        {}});
 
-        if (!linkAttributes(context, mInfoLog))
+        if (!linkAttributes(context->getCaps(), mInfoLog))
         {
             return NoError();
         }
 
-        if (!linkVaryings(context, mInfoLog))
+        if (!linkVaryings(mInfoLog))
         {
             return NoError();
         }
 
         GLuint combinedImageUniforms = 0u;
-        if (!linkUniforms(context, mInfoLog, mUniformLocationBindings, &combinedImageUniforms,
-                          &resources->unusedUniforms))
+        if (!linkUniforms(context->getCaps(), mInfoLog, mUniformLocationBindings,
+                          &combinedImageUniforms, &resources->unusedUniforms))
         {
             return NoError();
         }
 
         GLuint combinedShaderStorageBlocks = 0u;
-        if (!linkInterfaceBlocks(context, mInfoLog, &combinedShaderStorageBlocks))
+        if (!linkInterfaceBlocks(context->getCaps(), context->getClientVersion(),
+                                 context->getExtensions().webglCompatibility, mInfoLog,
+                                 &combinedShaderStorageBlocks))
         {
             return NoError();
         }
 
-        if (!linkValidateGlobalNames(context, mInfoLog))
+        if (!linkValidateGlobalNames(mInfoLog))
         {
             return NoError();
         }
 
-        if (!linkOutputVariables(context, combinedImageUniforms, combinedShaderStorageBlocks))
+        if (!linkOutputVariables(context->getCaps(), context->getClientVersion(),
+                                 combinedImageUniforms, combinedShaderStorageBlocks))
         {
             return NoError();
         }
 
-        const auto &mergedVaryings = getMergedVaryings(context);
+        const auto &mergedVaryings = getMergedVaryings();
 
         ASSERT(mState.mAttachedShaders[ShaderType::Vertex]);
-        mState.mNumViews = mState.mAttachedShaders[ShaderType::Vertex]->getNumViews(context);
+        mState.mNumViews = mState.mAttachedShaders[ShaderType::Vertex]->getNumViews();
 
-        InitUniformBlockLinker(context, mState, &resources->uniformBlockLinker);
-        InitShaderStorageBlockLinker(context, mState, &resources->shaderStorageBlockLinker);
+        InitUniformBlockLinker(mState, &resources->uniformBlockLinker);
+        InitShaderStorageBlockLinker(mState, &resources->shaderStorageBlockLinker);
 
-        if (!linkValidateTransformFeedback(context, mInfoLog, mergedVaryings, context->getCaps()))
+        if (!linkValidateTransformFeedback(context->getClientVersion(), mInfoLog, mergedVaryings,
+                                           context->getCaps()))
         {
             return NoError();
         }
@@ -2542,7 +2544,7 @@
     return mState.mTransformFeedbackBufferMode;
 }
 
-bool Program::linkValidateShaders(const Context *context, InfoLog &infoLog)
+bool Program::linkValidateShaders(InfoLog &infoLog)
 {
     Shader *vertexShader   = mState.mAttachedShaders[ShaderType::Vertex];
     Shader *fragmentShader = mState.mAttachedShaders[ShaderType::Fragment];
@@ -2563,14 +2565,14 @@
 
     if (computeShader)
     {
-        if (!computeShader->isCompiled(context))
+        if (!computeShader->isCompiled())
         {
             infoLog << "Attached compute shader is not compiled.";
             return false;
         }
         ASSERT(computeShader->getType() == ShaderType::Compute);
 
-        mState.mComputeShaderLocalSize = computeShader->getWorkGroupSize(context);
+        mState.mComputeShaderLocalSize = computeShader->getWorkGroupSize();
 
         // GLSL ES 3.10, 4.4.1.1 Compute Shader Inputs
         // If the work group size is not specified, a link time error should occur.
@@ -2582,22 +2584,22 @@
     }
     else
     {
-        if (!fragmentShader || !fragmentShader->isCompiled(context))
+        if (!fragmentShader || !fragmentShader->isCompiled())
         {
             infoLog << "No compiled fragment shader when at least one graphics shader is attached.";
             return false;
         }
         ASSERT(fragmentShader->getType() == ShaderType::Fragment);
 
-        if (!vertexShader || !vertexShader->isCompiled(context))
+        if (!vertexShader || !vertexShader->isCompiled())
         {
             infoLog << "No compiled vertex shader when at least one graphics shader is attached.";
             return false;
         }
         ASSERT(vertexShader->getType() == ShaderType::Vertex);
 
-        int vertexShaderVersion = vertexShader->getShaderVersion(context);
-        if (fragmentShader->getShaderVersion(context) != vertexShaderVersion)
+        int vertexShaderVersion = vertexShader->getShaderVersion();
+        if (fragmentShader->getShaderVersion() != vertexShaderVersion)
         {
             infoLog << "Fragment shader version does not match vertex shader version.";
             return false;
@@ -2615,13 +2617,13 @@
             //   - <program> is not separable and contains no objects to form a vertex shader; or
             //   - the input primitive type, output primitive type, or maximum output vertex count
             //     is not specified in the compiled geometry shader object.
-            if (!geometryShader->isCompiled(context))
+            if (!geometryShader->isCompiled())
             {
                 infoLog << "The attached geometry shader isn't compiled.";
                 return false;
             }
 
-            if (geometryShader->getShaderVersion(context) != vertexShaderVersion)
+            if (geometryShader->getShaderVersion() != vertexShaderVersion)
             {
                 mInfoLog << "Geometry shader version does not match vertex shader version.";
                 return false;
@@ -2629,7 +2631,7 @@
             ASSERT(geometryShader->getType() == ShaderType::Geometry);
 
             Optional<PrimitiveMode> inputPrimitive =
-                geometryShader->getGeometryShaderInputPrimitiveType(context);
+                geometryShader->getGeometryShaderInputPrimitiveType();
             if (!inputPrimitive.valid())
             {
                 mInfoLog << "Input primitive type is not specified in the geometry shader.";
@@ -2637,14 +2639,14 @@
             }
 
             Optional<PrimitiveMode> outputPrimitive =
-                geometryShader->getGeometryShaderOutputPrimitiveType(context);
+                geometryShader->getGeometryShaderOutputPrimitiveType();
             if (!outputPrimitive.valid())
             {
                 mInfoLog << "Output primitive type is not specified in the geometry shader.";
                 return false;
             }
 
-            Optional<GLint> maxVertices = geometryShader->getGeometryShaderMaxVertices(context);
+            Optional<GLint> maxVertices = geometryShader->getGeometryShaderMaxVertices();
             if (!maxVertices.valid())
             {
                 mInfoLog << "'max_vertices' is not specified in the geometry shader.";
@@ -2654,8 +2656,7 @@
             mState.mGeometryShaderInputPrimitiveType  = inputPrimitive.value();
             mState.mGeometryShaderOutputPrimitiveType = outputPrimitive.value();
             mState.mGeometryShaderMaxVertices         = maxVertices.value();
-            mState.mGeometryShaderInvocations =
-                geometryShader->getGeometryShaderInvocations(context);
+            mState.mGeometryShaderInvocations = geometryShader->getGeometryShaderInvocations();
         }
     }
 
@@ -2683,7 +2684,7 @@
     return mState.mLinkedTransformFeedbackVaryings[index];
 }
 
-bool Program::linkVaryings(const Context *context, InfoLog &infoLog) const
+bool Program::linkVaryings(InfoLog &infoLog) const
 {
     Shader *previousShader = nullptr;
     for (ShaderType shaderType : kAllGraphicsShaderTypes)
@@ -2696,8 +2697,7 @@
 
         if (previousShader)
         {
-            if (!linkValidateShaderInterfaceMatching(context, previousShader, currentShader,
-                                                     infoLog))
+            if (!linkValidateShaderInterfaceMatching(previousShader, currentShader, infoLog))
             {
                 return false;
             }
@@ -2705,12 +2705,12 @@
         previousShader = currentShader;
     }
 
-    if (!linkValidateBuiltInVaryings(context, infoLog))
+    if (!linkValidateBuiltInVaryings(infoLog))
     {
         return false;
     }
 
-    if (!linkValidateFragmentInputBindings(context, infoLog))
+    if (!linkValidateFragmentInputBindings(infoLog))
     {
         return false;
     }
@@ -2720,16 +2720,14 @@
 
 // [OpenGL ES 3.1] Chapter 7.4.1 "Shader Interface Matchining" Page 91
 // TODO(jiawei.shao@intel.com): add validation on input/output blocks matching
-bool Program::linkValidateShaderInterfaceMatching(const Context *context,
-                                                  gl::Shader *generatingShader,
+bool Program::linkValidateShaderInterfaceMatching(gl::Shader *generatingShader,
                                                   gl::Shader *consumingShader,
                                                   gl::InfoLog &infoLog) const
 {
-    ASSERT(generatingShader->getShaderVersion(context) ==
-           consumingShader->getShaderVersion(context));
+    ASSERT(generatingShader->getShaderVersion() == consumingShader->getShaderVersion());
 
-    const std::vector<sh::Varying> &outputVaryings = generatingShader->getOutputVaryings(context);
-    const std::vector<sh::Varying> &inputVaryings  = consumingShader->getInputVaryings(context);
+    const std::vector<sh::Varying> &outputVaryings = generatingShader->getOutputVaryings();
+    const std::vector<sh::Varying> &inputVaryings  = consumingShader->getInputVaryings();
 
     bool validateGeometryShaderInputs = consumingShader->getType() == ShaderType::Geometry;
 
@@ -2751,7 +2749,7 @@
 
                 std::string mismatchedStructFieldName;
                 LinkMismatchError linkError =
-                    LinkValidateVaryings(output, input, generatingShader->getShaderVersion(context),
+                    LinkValidateVaryings(output, input, generatingShader->getShaderVersion(),
                                          validateGeometryShaderInputs, &mismatchedStructFieldName);
                 if (linkError != LinkMismatchError::NO_MISMATCH)
                 {
@@ -2783,14 +2781,14 @@
     return true;
 }
 
-bool Program::linkValidateFragmentInputBindings(const Context *context, gl::InfoLog &infoLog) const
+bool Program::linkValidateFragmentInputBindings(gl::InfoLog &infoLog) const
 {
     ASSERT(mState.mAttachedShaders[ShaderType::Fragment]);
 
     std::map<GLuint, std::string> staticFragmentInputLocations;
 
     const std::vector<sh::Varying> &fragmentInputVaryings =
-        mState.mAttachedShaders[ShaderType::Fragment]->getInputVaryings(context);
+        mState.mAttachedShaders[ShaderType::Fragment]->getInputVaryings();
     for (const sh::Varying &input : fragmentInputVaryings)
     {
         if (input.isBuiltIn() || !input.staticUse)
@@ -2818,14 +2816,14 @@
     return true;
 }
 
-bool Program::linkUniforms(const Context *context,
+bool Program::linkUniforms(const Caps &caps,
                            InfoLog &infoLog,
                            const ProgramBindings &uniformLocationBindings,
                            GLuint *combinedImageUniformsCount,
                            std::vector<UnusedUniform> *unusedUniforms)
 {
     UniformLinker linker(mState);
-    if (!linker.link(context, infoLog, uniformLocationBindings))
+    if (!linker.link(caps, infoLog, uniformLocationBindings))
     {
         return false;
     }
@@ -2951,26 +2949,25 @@
 }
 
 // Assigns locations to all attributes from the bindings and program locations.
-bool Program::linkAttributes(const Context *context, InfoLog &infoLog)
+bool Program::linkAttributes(const Caps &caps, InfoLog &infoLog)
 {
-    const ContextState &data = context->getContextState();
     Shader *vertexShader     = mState.getAttachedShader(ShaderType::Vertex);
 
-    int shaderVersion = vertexShader->getShaderVersion(context);
+    int shaderVersion = vertexShader->getShaderVersion();
 
     unsigned int usedLocations = 0;
     if (shaderVersion >= 300)
     {
         // In GLSL ES 3.00.6, aliasing checks should be done with all declared attributes - see GLSL
         // ES 3.00.6 section 12.46. Inactive attributes will be pruned after aliasing checks.
-        mState.mAttributes = vertexShader->getAllAttributes(context);
+        mState.mAttributes = vertexShader->getAllAttributes();
     }
     else
     {
         // In GLSL ES 1.00.17 we only do aliasing checks for active attributes.
-        mState.mAttributes = vertexShader->getActiveAttributes(context);
+        mState.mAttributes = vertexShader->getActiveAttributes();
     }
-    GLuint maxAttribs = data.getCaps().maxVertexAttributes;
+    GLuint maxAttribs = caps.maxVertexAttributes;
 
     // TODO(jmadill): handle aliasing robustly
     if (mState.mAttributes.size() > maxAttribs)
@@ -3102,14 +3099,14 @@
     return true;
 }
 
-bool Program::linkInterfaceBlocks(const Context *context,
+bool Program::linkInterfaceBlocks(const Caps &caps,
+                                  const Version &version,
+                                  bool webglCompatibility,
                                   InfoLog &infoLog,
                                   GLuint *combinedShaderStorageBlocksCount)
 {
     ASSERT(combinedShaderStorageBlocksCount);
 
-    const auto &caps = context->getCaps();
-
     GLuint combinedUniformBlocksCount                                         = 0u;
     GLuint numShadersHasUniformBlocks                                         = 0u;
     ShaderMap<const std::vector<sh::InterfaceBlock> *> allShaderUniformBlocks = {};
@@ -3121,7 +3118,7 @@
             continue;
         }
 
-        const auto &uniformBlocks = shader->getUniformBlocks(context);
+        const auto &uniformBlocks = shader->getUniformBlocks();
         if (!uniformBlocks.empty())
         {
             if (!ValidateInterfaceBlocksCount(
@@ -3144,14 +3141,13 @@
         return false;
     }
 
-    bool webglCompatibility = context->getExtensions().webglCompatibility;
     if (!ValidateInterfaceBlocksMatch(numShadersHasUniformBlocks, allShaderUniformBlocks, infoLog,
                                       webglCompatibility))
     {
         return false;
     }
 
-    if (context->getClientVersion() >= Version(3, 1))
+    if (version >= Version(3, 1))
     {
         *combinedShaderStorageBlocksCount                                         = 0u;
         GLuint numShadersHasShaderStorageBlocks                                   = 0u;
@@ -3164,7 +3160,7 @@
                 continue;
             }
 
-            const auto &shaderStorageBlocks = shader->getShaderStorageBlocks(context);
+            const auto &shaderStorageBlocks = shader->getShaderStorageBlocks();
             if (!shaderStorageBlocks.empty())
             {
                 if (!ValidateInterfaceBlocksCount(
@@ -3296,13 +3292,13 @@
     return LinkMismatchError::NO_MISMATCH;
 }
 
-bool Program::linkValidateBuiltInVaryings(const Context *context, InfoLog &infoLog) const
+bool Program::linkValidateBuiltInVaryings(InfoLog &infoLog) const
 {
     Shader *vertexShader         = mState.mAttachedShaders[ShaderType::Vertex];
     Shader *fragmentShader       = mState.mAttachedShaders[ShaderType::Fragment];
-    const auto &vertexVaryings   = vertexShader->getOutputVaryings(context);
-    const auto &fragmentVaryings = fragmentShader->getInputVaryings(context);
-    int shaderVersion            = vertexShader->getShaderVersion(context);
+    const auto &vertexVaryings   = vertexShader->getOutputVaryings();
+    const auto &fragmentVaryings = fragmentShader->getInputVaryings();
+    int shaderVersion            = vertexShader->getShaderVersion();
 
     if (shaderVersion != 100)
     {
@@ -3367,7 +3363,7 @@
     return true;
 }
 
-bool Program::linkValidateTransformFeedback(const gl::Context *context,
+bool Program::linkValidateTransformFeedback(const Version &version,
                                             InfoLog &infoLog,
                                             const ProgramMergedVaryings &varyings,
                                             const Caps &caps) const
@@ -3377,13 +3373,12 @@
     std::set<std::string> uniqueNames;
     for (const std::string &tfVaryingName : mState.mTransformFeedbackVaryingNames)
     {
-        if (context->getClientVersion() < Version(3, 1) &&
-            tfVaryingName.find('[') != std::string::npos)
+        if (version < Version(3, 1) && tfVaryingName.find('[') != std::string::npos)
         {
             infoLog << "Capture of array elements is undefined and not supported.";
             return false;
         }
-        if (context->getClientVersion() >= Version(3, 1))
+        if (version >= Version(3, 1))
         {
             if (IncludeSameArrayElement(uniqueNames, tfVaryingName))
             {
@@ -3431,7 +3426,7 @@
 
         if (var->isArray())
         {
-            if (context->getClientVersion() < Version(3, 1))
+            if (version < Version(3, 1))
             {
                 infoLog << "Capture of arrays is undefined and not supported.";
                 return false;
@@ -3482,10 +3477,10 @@
     return true;
 }
 
-bool Program::linkValidateGlobalNames(const Context *context, InfoLog &infoLog) const
+bool Program::linkValidateGlobalNames(InfoLog &infoLog) const
 {
     const std::vector<sh::Attribute> &attributes =
-        mState.mAttachedShaders[ShaderType::Vertex]->getActiveAttributes(context);
+        mState.mAttachedShaders[ShaderType::Vertex]->getActiveAttributes();
 
     for (const auto &attrib : attributes)
     {
@@ -3497,7 +3492,7 @@
                 continue;
             }
 
-            const std::vector<sh::Uniform> &uniforms = shader->getUniforms(context);
+            const std::vector<sh::Uniform> &uniforms = shader->getUniforms();
             for (const auto &uniform : uniforms)
             {
                 if (uniform.name == attrib.name)
@@ -3548,18 +3543,18 @@
     mState.updateTransformFeedbackStrides();
 }
 
-ProgramMergedVaryings Program::getMergedVaryings(const Context *context) const
+ProgramMergedVaryings Program::getMergedVaryings() const
 {
     ProgramMergedVaryings merged;
 
     for (const sh::Varying &varying :
-         mState.mAttachedShaders[ShaderType::Vertex]->getOutputVaryings(context))
+         mState.mAttachedShaders[ShaderType::Vertex]->getOutputVaryings())
     {
         merged[varying.name].vertex = &varying;
     }
 
     for (const sh::Varying &varying :
-         mState.mAttachedShaders[ShaderType::Fragment]->getInputVaryings(context))
+         mState.mAttachedShaders[ShaderType::Fragment]->getInputVaryings())
     {
         merged[varying.name].fragment = &varying;
     }
@@ -3567,7 +3562,8 @@
     return merged;
 }
 
-bool Program::linkOutputVariables(const Context *context,
+bool Program::linkOutputVariables(const Caps &caps,
+                                  const Version &version,
                                   GLuint combinedImageUniformsCount,
                                   GLuint combinedShaderStorageBlocksCount)
 {
@@ -3578,7 +3574,7 @@
     ASSERT(mState.mActiveOutputVariables.none());
     ASSERT(mState.mDrawBufferTypeMask.none());
 
-    const auto &outputVariables = fragmentShader->getActiveOutputVariables(context);
+    const auto &outputVariables = fragmentShader->getActiveOutputVariables();
     // Gather output variable types
     for (const auto &outputVariable : outputVariables)
     {
@@ -3609,7 +3605,7 @@
         }
     }
 
-    if (context->getClientVersion() >= ES_3_1)
+    if (version >= ES_3_1)
     {
         // [OpenGL ES 3.1] Chapter 8.22 Page 203:
         // A link error will be generated if the sum of the number of active image uniforms used in
@@ -3618,19 +3614,19 @@
         // MAX_COMBINED_SHADER_OUTPUT_RESOURCES.
         if (combinedImageUniformsCount + combinedShaderStorageBlocksCount +
                 mState.mActiveOutputVariables.count() >
-            context->getCaps().maxCombinedShaderOutputResources)
+            caps.maxCombinedShaderOutputResources)
         {
             mInfoLog
                 << "The sum of the number of active image uniforms, active shader storage blocks "
                    "and active fragment shader outputs exceeds "
                    "MAX_COMBINED_SHADER_OUTPUT_RESOURCES ("
-                << context->getCaps().maxCombinedShaderOutputResources << ")";
+                << caps.maxCombinedShaderOutputResources << ")";
             return false;
         }
     }
 
     // Skip this step for GLES2 shaders.
-    if (fragmentShader->getShaderVersion(context) == 100)
+    if (fragmentShader->getShaderVersion() == 100)
         return true;
 
     mState.mOutputVariables = outputVariables;
diff --git a/src/libANGLE/Program.h b/src/libANGLE/Program.h
index 195867b..8b245ad 100644
--- a/src/libANGLE/Program.h
+++ b/src/libANGLE/Program.h
@@ -50,6 +50,7 @@
 class InfoLog;
 class Buffer;
 class Framebuffer;
+struct Version;
 
 extern const char *const g_fakepath;
 
@@ -488,13 +489,9 @@
     void bindUniformLocation(GLuint index, const char *name);
 
     // CHROMIUM_path_rendering
-    BindingInfo getFragmentInputBindingInfo(const Context *context, GLint index) const;
+    BindingInfo getFragmentInputBindingInfo(GLint index) const;
     void bindFragmentInputLocation(GLint index, const char *name);
-    void pathFragmentInputGen(const Context *context,
-                              GLint index,
-                              GLenum genMode,
-                              GLint components,
-                              const GLfloat *coeffs);
+    void pathFragmentInputGen(GLint index, GLenum genMode, GLint components, const GLfloat *coeffs);
 
     // KHR_parallel_shader_compile
     // Try to link the program asynchrously. As a result, background threads may be launched to
@@ -751,14 +748,16 @@
 
     void unlink();
 
-    bool linkValidateShaders(const Context *context, InfoLog &infoLog);
-    bool linkAttributes(const Context *context, InfoLog &infoLog);
-    bool linkInterfaceBlocks(const Context *context,
+    bool linkValidateShaders(InfoLog &infoLog);
+    bool linkAttributes(const Caps &caps, InfoLog &infoLog);
+    bool linkInterfaceBlocks(const Caps &caps,
+                             const Version &version,
+                             bool webglCompatibility,
                              InfoLog &infoLog,
                              GLuint *combinedShaderStorageBlocksCount);
-    bool linkVaryings(const Context *context, InfoLog &infoLog) const;
+    bool linkVaryings(InfoLog &infoLog) const;
 
-    bool linkUniforms(const Context *context,
+    bool linkUniforms(const Caps &caps,
                       InfoLog &infoLog,
                       const ProgramBindings &uniformLocationBindings,
                       GLuint *combinedImageUniformsCount,
@@ -774,26 +773,26 @@
                                                   bool validateGeometryShaderInputVarying,
                                                   std::string *mismatchedStructFieldName);
 
-    bool linkValidateShaderInterfaceMatching(const Context *context,
-                                             Shader *generatingShader,
+    bool linkValidateShaderInterfaceMatching(Shader *generatingShader,
                                              Shader *consumingShader,
                                              InfoLog &infoLog) const;
 
     // Check for aliased path rendering input bindings (if any).
     // If more than one binding refer statically to the same location the link must fail.
-    bool linkValidateFragmentInputBindings(const Context *context, InfoLog &infoLog) const;
+    bool linkValidateFragmentInputBindings(InfoLog &infoLog) const;
 
-    bool linkValidateBuiltInVaryings(const Context *context, InfoLog &infoLog) const;
-    bool linkValidateTransformFeedback(const Context *context,
+    bool linkValidateBuiltInVaryings(InfoLog &infoLog) const;
+    bool linkValidateTransformFeedback(const Version &version,
                                        InfoLog &infoLog,
                                        const ProgramMergedVaryings &linkedVaryings,
                                        const Caps &caps) const;
-    bool linkValidateGlobalNames(const Context *context, InfoLog &infoLog) const;
+    bool linkValidateGlobalNames(InfoLog &infoLog) const;
 
     void gatherTransformFeedbackVaryings(const ProgramMergedVaryings &varyings);
 
-    ProgramMergedVaryings getMergedVaryings(const Context *context) const;
-    bool linkOutputVariables(const Context *context,
+    ProgramMergedVaryings getMergedVaryings() const;
+    bool linkOutputVariables(const Caps &caps,
+                             const Version &version,
                              GLuint combinedImageUniformsCount,
                              GLuint combinedShaderStorageBlocksCount);
 
diff --git a/src/libANGLE/ProgramLinkedResources.cpp b/src/libANGLE/ProgramLinkedResources.cpp
index 605d1bd..8b3e4d3 100644
--- a/src/libANGLE/ProgramLinkedResources.cpp
+++ b/src/libANGLE/ProgramLinkedResources.cpp
@@ -101,15 +101,14 @@
 
 using ShaderUniform = std::pair<ShaderType, const sh::Uniform *>;
 
-bool ValidateGraphicsUniformsPerShader(const Context *context,
-                                       Shader *shaderToLink,
+bool ValidateGraphicsUniformsPerShader(Shader *shaderToLink,
                                        bool extendLinkedUniforms,
                                        std::map<std::string, ShaderUniform> *linkedUniforms,
                                        InfoLog &infoLog)
 {
-    ASSERT(context && shaderToLink && linkedUniforms);
+    ASSERT(shaderToLink && linkedUniforms);
 
-    for (const sh::Uniform &uniform : shaderToLink->getUniforms(context))
+    for (const sh::Uniform &uniform : shaderToLink->getUniforms())
     {
         const auto &entry = linkedUniforms->find(uniform.name);
         if (entry != linkedUniforms->end())
@@ -261,7 +260,7 @@
     uniformLocations->swap(mUniformLocations);
 }
 
-bool UniformLinker::link(const Context *context,
+bool UniformLinker::link(const Caps &caps,
                          InfoLog &infoLog,
                          const ProgramBindings &uniformLocationBindings)
 {
@@ -269,7 +268,7 @@
         mState.getAttachedShader(ShaderType::Fragment))
     {
         ASSERT(mState.getAttachedShader(ShaderType::Compute) == nullptr);
-        if (!validateGraphicsUniforms(context, infoLog))
+        if (!validateGraphicsUniforms(infoLog))
         {
             return false;
         }
@@ -277,12 +276,12 @@
 
     // Flatten the uniforms list (nested fields) into a simple list (no nesting).
     // Also check the maximum uniform vector and sampler counts.
-    if (!flattenUniformsAndCheckCaps(context, infoLog))
+    if (!flattenUniformsAndCheckCaps(caps, infoLog))
     {
         return false;
     }
 
-    if (!checkMaxCombinedAtomicCounters(context->getCaps(), infoLog))
+    if (!checkMaxCombinedAtomicCounters(caps, infoLog))
     {
         return false;
     }
@@ -295,7 +294,7 @@
     return true;
 }
 
-bool UniformLinker::validateGraphicsUniforms(const Context *context, InfoLog &infoLog) const
+bool UniformLinker::validateGraphicsUniforms(InfoLog &infoLog) const
 {
     // Check that uniforms defined in the graphics shaders are identical
     std::map<std::string, ShaderUniform> linkedUniforms;
@@ -307,7 +306,7 @@
         {
             if (shaderType == ShaderType::Vertex)
             {
-                for (const sh::Uniform &vertexUniform : currentShader->getUniforms(context))
+                for (const sh::Uniform &vertexUniform : currentShader->getUniforms())
                 {
                     linkedUniforms[vertexUniform.name] =
                         std::make_pair(ShaderType::Vertex, &vertexUniform);
@@ -316,7 +315,7 @@
             else
             {
                 bool isLastShader = (shaderType == ShaderType::Fragment);
-                if (!ValidateGraphicsUniformsPerShader(context, currentShader, !isLastShader,
+                if (!ValidateGraphicsUniformsPerShader(currentShader, !isLastShader,
                                                        &linkedUniforms, infoLog))
                 {
                     return false;
@@ -510,7 +509,6 @@
 }
 
 bool UniformLinker::flattenUniformsAndCheckCapsForShader(
-    const Context *context,
     Shader *shader,
     const Caps &caps,
     std::vector<LinkedUniform> &samplerUniforms,
@@ -520,7 +518,7 @@
     InfoLog &infoLog)
 {
     ShaderUniformCount shaderUniformCount;
-    for (const sh::Uniform &uniform : shader->getUniforms(context))
+    for (const sh::Uniform &uniform : shader->getUniforms())
     {
         shaderUniformCount +=
             flattenUniform(uniform, &samplerUniforms, &imageUniforms, &atomicCounterUniforms,
@@ -573,14 +571,13 @@
     return true;
 }
 
-bool UniformLinker::flattenUniformsAndCheckCaps(const Context *context, InfoLog &infoLog)
+bool UniformLinker::flattenUniformsAndCheckCaps(const Caps &caps, InfoLog &infoLog)
 {
     std::vector<LinkedUniform> samplerUniforms;
     std::vector<LinkedUniform> imageUniforms;
     std::vector<LinkedUniform> atomicCounterUniforms;
     std::vector<UnusedUniform> unusedUniforms;
 
-    const Caps &caps = context->getCaps();
     for (ShaderType shaderType : AllShaderTypes())
     {
         Shader *shader = mState.getAttachedShader(shaderType);
@@ -589,9 +586,8 @@
             continue;
         }
 
-        if (!flattenUniformsAndCheckCapsForShader(context, shader, caps, samplerUniforms,
-                                                  imageUniforms, atomicCounterUniforms,
-                                                  unusedUniforms, infoLog))
+        if (!flattenUniformsAndCheckCapsForShader(shader, caps, samplerUniforms, imageUniforms,
+                                                  atomicCounterUniforms, unusedUniforms, infoLog))
         {
             return false;
         }
diff --git a/src/libANGLE/ProgramLinkedResources.h b/src/libANGLE/ProgramLinkedResources.h
index c23da64..57e0a92 100644
--- a/src/libANGLE/ProgramLinkedResources.h
+++ b/src/libANGLE/ProgramLinkedResources.h
@@ -50,9 +50,7 @@
     UniformLinker(const ProgramState &state);
     ~UniformLinker();
 
-    bool link(const Context *context,
-              InfoLog &infoLog,
-              const ProgramBindings &uniformLocationBindings);
+    bool link(const Caps &caps, InfoLog &infoLog, const ProgramBindings &uniformLocationBindings);
 
     void getResults(std::vector<LinkedUniform> *uniforms,
                     std::vector<UnusedUniform> *unusedUniforms,
@@ -82,10 +80,9 @@
         unsigned int atomicCounterCount;
     };
 
-    bool validateGraphicsUniforms(const Context *context, InfoLog &infoLog) const;
+    bool validateGraphicsUniforms(InfoLog &infoLog) const;
 
-    bool flattenUniformsAndCheckCapsForShader(const Context *context,
-                                              Shader *shader,
+    bool flattenUniformsAndCheckCapsForShader(Shader *shader,
                                               const Caps &caps,
                                               std::vector<LinkedUniform> &samplerUniforms,
                                               std::vector<LinkedUniform> &imageUniforms,
@@ -93,7 +90,7 @@
                                               std::vector<UnusedUniform> &unusedUniforms,
                                               InfoLog &infoLog);
 
-    bool flattenUniformsAndCheckCaps(const Context *context, InfoLog &infoLog);
+    bool flattenUniformsAndCheckCaps(const Caps &caps, InfoLog &infoLog);
     bool checkMaxCombinedAtomicCounters(const Caps &caps, InfoLog &infoLog);
 
     ShaderUniformCount flattenUniform(const sh::Uniform &uniform,
diff --git a/src/libANGLE/Shader.cpp b/src/libANGLE/Shader.cpp
index 9eb2d5b..a2697da 100644
--- a/src/libANGLE/Shader.cpp
+++ b/src/libANGLE/Shader.cpp
@@ -123,14 +123,15 @@
       mType(type),
       mRefCount(0),
       mDeleteStatus(false),
-      mResourceManager(manager)
+      mResourceManager(manager),
+      mCurrentMaxComputeWorkGroupInvocations(0u)
 {
     ASSERT(mImplementation);
 }
 
 void Shader::onDestroy(const gl::Context *context)
 {
-    mImplementation->destroy(context);
+    mImplementation->destroy();
     mBoundCompiler.set(context, nullptr);
     mImplementation.reset(nullptr);
     delete this;
@@ -175,9 +176,9 @@
     mState.mSource = stream.str();
 }
 
-int Shader::getInfoLogLength(const Context *context)
+int Shader::getInfoLogLength()
 {
-    resolveCompile(context);
+    resolveCompile();
     if (mInfoLog.empty())
     {
         return 0;
@@ -186,9 +187,9 @@
     return (static_cast<int>(mInfoLog.length()) + 1);
 }
 
-void Shader::getInfoLog(const Context *context, GLsizei bufSize, GLsizei *length, char *infoLog)
+void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog)
 {
-    resolveCompile(context);
+    resolveCompile();
 
     int index = 0;
 
@@ -211,9 +212,9 @@
     return mState.mSource.empty() ? 0 : (static_cast<int>(mState.mSource.length()) + 1);
 }
 
-int Shader::getTranslatedSourceLength(const Context *context)
+int Shader::getTranslatedSourceLength()
 {
-    resolveCompile(context);
+    resolveCompile();
 
     if (mState.mTranslatedSource.empty())
     {
@@ -223,11 +224,11 @@
     return (static_cast<int>(mState.mTranslatedSource.length()) + 1);
 }
 
-int Shader::getTranslatedSourceWithDebugInfoLength(const Context *context)
+int Shader::getTranslatedSourceWithDebugInfoLength()
 {
-    resolveCompile(context);
+    resolveCompile();
 
-    const std::string &debugInfo = mImplementation->getDebugInfo(context);
+    const std::string &debugInfo = mImplementation->getDebugInfo();
     if (debugInfo.empty())
     {
         return 0;
@@ -263,27 +264,21 @@
     GetSourceImpl(mState.mSource, bufSize, length, buffer);
 }
 
-void Shader::getTranslatedSource(const Context *context,
-                                 GLsizei bufSize,
-                                 GLsizei *length,
-                                 char *buffer)
+void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer)
 {
-    GetSourceImpl(getTranslatedSource(context), bufSize, length, buffer);
+    GetSourceImpl(getTranslatedSource(), bufSize, length, buffer);
 }
 
-const std::string &Shader::getTranslatedSource(const Context *context)
+const std::string &Shader::getTranslatedSource()
 {
-    resolveCompile(context);
+    resolveCompile();
     return mState.mTranslatedSource;
 }
 
-void Shader::getTranslatedSourceWithDebugInfo(const Context *context,
-                                              GLsizei bufSize,
-                                              GLsizei *length,
-                                              char *buffer)
+void Shader::getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length, char *buffer)
 {
-    resolveCompile(context);
-    const std::string &debugInfo = mImplementation->getDebugInfo(context);
+    resolveCompile();
+    const std::string &debugInfo = mImplementation->getDebugInfo();
     GetSourceImpl(debugInfo, bufSize, length, buffer);
 }
 
@@ -334,9 +329,11 @@
     {
         mLastCompileOptions |= SH_VALIDATE_LOOP_INDEXING;
     }
+
+    mCurrentMaxComputeWorkGroupInvocations = context->getCaps().maxComputeWorkGroupInvocations;
 }
 
-void Shader::resolveCompile(const Context *context)
+void Shader::resolveCompile()
 {
     if (!mState.compilePending())
     {
@@ -413,7 +410,7 @@
                     return;
                 }
                 if (checked_local_size_product.ValueOrDie() >
-                    context->getCaps().maxComputeWorkGroupInvocations)
+                    mCurrentMaxComputeWorkGroupInvocations)
                 {
                     WARN() << std::endl
                            << "The total number of invocations within a work group exceeds "
@@ -472,7 +469,7 @@
 
     ASSERT(!mState.mTranslatedSource.empty());
 
-    bool success = mImplementation->postTranslateCompile(context, mBoundCompiler.get(), &mInfoLog);
+    bool success          = mImplementation->postTranslateCompile(mBoundCompiler.get(), &mInfoLog);
     mState.mCompileStatus = success ? CompileStatus::COMPILED : CompileStatus::NOT_COMPILED;
 }
 
@@ -506,72 +503,71 @@
     mDeleteStatus = true;
 }
 
-bool Shader::isCompiled(const Context *context)
+bool Shader::isCompiled()
 {
-    resolveCompile(context);
+    resolveCompile();
     return mState.mCompileStatus == CompileStatus::COMPILED;
 }
 
-int Shader::getShaderVersion(const Context *context)
+int Shader::getShaderVersion()
 {
-    resolveCompile(context);
+    resolveCompile();
     return mState.mShaderVersion;
 }
 
-const std::vector<sh::Varying> &Shader::getInputVaryings(const Context *context)
+const std::vector<sh::Varying> &Shader::getInputVaryings()
 {
-    resolveCompile(context);
+    resolveCompile();
     return mState.getInputVaryings();
 }
 
-const std::vector<sh::Varying> &Shader::getOutputVaryings(const Context *context)
+const std::vector<sh::Varying> &Shader::getOutputVaryings()
 {
-    resolveCompile(context);
+    resolveCompile();
     return mState.getOutputVaryings();
 }
 
-const std::vector<sh::Uniform> &Shader::getUniforms(const Context *context)
+const std::vector<sh::Uniform> &Shader::getUniforms()
 {
-    resolveCompile(context);
+    resolveCompile();
     return mState.getUniforms();
 }
 
-const std::vector<sh::InterfaceBlock> &Shader::getUniformBlocks(const Context *context)
+const std::vector<sh::InterfaceBlock> &Shader::getUniformBlocks()
 {
-    resolveCompile(context);
+    resolveCompile();
     return mState.getUniformBlocks();
 }
 
-const std::vector<sh::InterfaceBlock> &Shader::getShaderStorageBlocks(const Context *context)
+const std::vector<sh::InterfaceBlock> &Shader::getShaderStorageBlocks()
 {
-    resolveCompile(context);
+    resolveCompile();
     return mState.getShaderStorageBlocks();
 }
 
-const std::vector<sh::Attribute> &Shader::getActiveAttributes(const Context *context)
+const std::vector<sh::Attribute> &Shader::getActiveAttributes()
 {
-    resolveCompile(context);
+    resolveCompile();
     return mState.getActiveAttributes();
 }
 
-const std::vector<sh::Attribute> &Shader::getAllAttributes(const Context *context)
+const std::vector<sh::Attribute> &Shader::getAllAttributes()
 {
-    resolveCompile(context);
+    resolveCompile();
     return mState.getAllAttributes();
 }
 
-const std::vector<sh::OutputVariable> &Shader::getActiveOutputVariables(const Context *context)
+const std::vector<sh::OutputVariable> &Shader::getActiveOutputVariables()
 {
-    resolveCompile(context);
+    resolveCompile();
     return mState.getActiveOutputVariables();
 }
 
-std::string Shader::getTransformFeedbackVaryingMappedName(const std::string &tfVaryingName,
-                                                          const Context *context)
+std::string Shader::getTransformFeedbackVaryingMappedName(const std::string &tfVaryingName)
 {
     // TODO(jiawei.shao@intel.com): support transform feedback on geometry shader.
     ASSERT(mState.getShaderType() == ShaderType::Vertex);
-    const auto &varyings = getOutputVaryings(context);
+    const auto &varyings = getOutputVaryings();
     auto bracketPos      = tfVaryingName.find("[");
     if (bracketPos != std::string::npos)
     {
@@ -606,39 +602,39 @@
     return std::string();
 }
 
-const sh::WorkGroupSize &Shader::getWorkGroupSize(const Context *context)
+const sh::WorkGroupSize &Shader::getWorkGroupSize()
 {
-    resolveCompile(context);
+    resolveCompile();
     return mState.mLocalSize;
 }
 
-int Shader::getNumViews(const Context *context)
+int Shader::getNumViews()
 {
-    resolveCompile(context);
+    resolveCompile();
     return mState.mNumViews;
 }
 
-Optional<PrimitiveMode> Shader::getGeometryShaderInputPrimitiveType(const Context *context)
+Optional<PrimitiveMode> Shader::getGeometryShaderInputPrimitiveType()
 {
-    resolveCompile(context);
+    resolveCompile();
     return mState.mGeometryShaderInputPrimitiveType;
 }
 
-Optional<PrimitiveMode> Shader::getGeometryShaderOutputPrimitiveType(const Context *context)
+Optional<PrimitiveMode> Shader::getGeometryShaderOutputPrimitiveType()
 {
-    resolveCompile(context);
+    resolveCompile();
     return mState.mGeometryShaderOutputPrimitiveType;
 }
 
-int Shader::getGeometryShaderInvocations(const Context *context)
+int Shader::getGeometryShaderInvocations()
 {
-    resolveCompile(context);
+    resolveCompile();
     return mState.mGeometryShaderInvocations;
 }
 
-Optional<GLint> Shader::getGeometryShaderMaxVertices(const Context *context)
+Optional<GLint> Shader::getGeometryShaderMaxVertices()
 {
-    resolveCompile(context);
+    resolveCompile();
     return mState.mGeometryShaderMaxVertices;
 }
 
diff --git a/src/libANGLE/Shader.h b/src/libANGLE/Shader.h
index cf30368..ec46d66 100644
--- a/src/libANGLE/Shader.h
+++ b/src/libANGLE/Shader.h
@@ -133,25 +133,19 @@
     rx::ShaderImpl *getImplementation() const { return mImplementation.get(); }
 
     void setSource(GLsizei count, const char *const *string, const GLint *length);
-    int getInfoLogLength(const Context *context);
-    void getInfoLog(const Context *context, GLsizei bufSize, GLsizei *length, char *infoLog);
+    int getInfoLogLength();
+    void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog);
     int getSourceLength() const;
     const std::string &getSourceString() const { return mState.getSource(); }
     void getSource(GLsizei bufSize, GLsizei *length, char *buffer) const;
-    int getTranslatedSourceLength(const Context *context);
-    int getTranslatedSourceWithDebugInfoLength(const Context *context);
-    const std::string &getTranslatedSource(const Context *context);
-    void getTranslatedSource(const Context *context,
-                             GLsizei bufSize,
-                             GLsizei *length,
-                             char *buffer);
-    void getTranslatedSourceWithDebugInfo(const Context *context,
-                                          GLsizei bufSize,
-                                          GLsizei *length,
-                                          char *buffer);
+    int getTranslatedSourceLength();
+    int getTranslatedSourceWithDebugInfoLength();
+    const std::string &getTranslatedSource();
+    void getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer);
+    void getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length, char *buffer);
 
     void compile(const Context *context);
-    bool isCompiled(const Context *context);
+    bool isCompiled();
 
     void addRef();
     void release(const Context *context);
@@ -159,31 +153,30 @@
     bool isFlaggedForDeletion() const;
     void flagForDeletion();
 
-    int getShaderVersion(const Context *context);
+    int getShaderVersion();
 
-    const std::vector<sh::Varying> &getInputVaryings(const Context *context);
-    const std::vector<sh::Varying> &getOutputVaryings(const Context *context);
-    const std::vector<sh::Uniform> &getUniforms(const Context *context);
-    const std::vector<sh::InterfaceBlock> &getUniformBlocks(const Context *context);
-    const std::vector<sh::InterfaceBlock> &getShaderStorageBlocks(const Context *context);
-    const std::vector<sh::Attribute> &getActiveAttributes(const Context *context);
-    const std::vector<sh::Attribute> &getAllAttributes(const Context *context);
-    const std::vector<sh::OutputVariable> &getActiveOutputVariables(const Context *context);
+    const std::vector<sh::Varying> &getInputVaryings();
+    const std::vector<sh::Varying> &getOutputVaryings();
+    const std::vector<sh::Uniform> &getUniforms();
+    const std::vector<sh::InterfaceBlock> &getUniformBlocks();
+    const std::vector<sh::InterfaceBlock> &getShaderStorageBlocks();
+    const std::vector<sh::Attribute> &getActiveAttributes();
+    const std::vector<sh::Attribute> &getAllAttributes();
+    const std::vector<sh::OutputVariable> &getActiveOutputVariables();
 
     // Returns mapped name of a transform feedback varying. The original name may contain array
     // brackets with an index inside, which will get copied to the mapped name. The varying must be
     // known to be declared in the shader.
-    std::string getTransformFeedbackVaryingMappedName(const std::string &tfVaryingName,
-                                                      const Context *context);
+    std::string getTransformFeedbackVaryingMappedName(const std::string &tfVaryingName);
 
-    const sh::WorkGroupSize &getWorkGroupSize(const Context *context);
+    const sh::WorkGroupSize &getWorkGroupSize();
 
-    int getNumViews(const Context *context);
+    int getNumViews();
 
-    Optional<PrimitiveMode> getGeometryShaderInputPrimitiveType(const Context *context);
-    Optional<PrimitiveMode> getGeometryShaderOutputPrimitiveType(const Context *context);
-    int getGeometryShaderInvocations(const Context *context);
-    Optional<GLint> getGeometryShaderMaxVertices(const Context *context);
+    Optional<PrimitiveMode> getGeometryShaderInputPrimitiveType();
+    Optional<PrimitiveMode> getGeometryShaderOutputPrimitiveType();
+    int getGeometryShaderInvocations();
+    Optional<GLint> getGeometryShaderMaxVertices();
 
     const std::string &getCompilerResourcesString() const;
 
@@ -194,7 +187,7 @@
                               GLsizei *length,
                               char *buffer);
 
-    void resolveCompile(const Context *context);
+    void resolveCompile();
 
     ShaderState mState;
     std::string mLastCompiledSource;
@@ -212,6 +205,8 @@
     BindingPointer<Compiler> mBoundCompiler;
 
     ShaderProgramManager *mResourceManager;
+
+    GLuint mCurrentMaxComputeWorkGroupInvocations;
 };
 
 bool CompareShaderVar(const sh::ShaderVariable &x, const sh::ShaderVariable &y);
diff --git a/src/libANGLE/queryutils.cpp b/src/libANGLE/queryutils.cpp
index 0b09f7a..45b3cd4 100644
--- a/src/libANGLE/queryutils.cpp
+++ b/src/libANGLE/queryutils.cpp
@@ -1150,7 +1150,7 @@
     }
 }
 
-void QueryShaderiv(const Context *context, Shader *shader, GLenum pname, GLint *params)
+void QueryShaderiv(Shader *shader, GLenum pname, GLint *params)
 {
     ASSERT(shader != nullptr);
 
@@ -1163,21 +1163,21 @@
             *params = shader->isFlaggedForDeletion();
             return;
         case GL_COMPILE_STATUS:
-            *params = shader->isCompiled(context) ? GL_TRUE : GL_FALSE;
+            *params = shader->isCompiled() ? GL_TRUE : GL_FALSE;
             return;
         case GL_COMPLETION_STATUS_KHR:
             // TODO(jie.a.chen@intel.com): Parallelize shader compilation.
             // http://crbug.com/849576
-            *params = shader->isCompiled(context) ? GL_TRUE : GL_FALSE;
+            *params = shader->isCompiled() ? GL_TRUE : GL_FALSE;
             return;
         case GL_INFO_LOG_LENGTH:
-            *params = shader->getInfoLogLength(context);
+            *params = shader->getInfoLogLength();
             return;
         case GL_SHADER_SOURCE_LENGTH:
             *params = shader->getSourceLength();
             return;
         case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
-            *params = shader->getTranslatedSourceWithDebugInfoLength(context);
+            *params = shader->getTranslatedSourceWithDebugInfoLength();
             return;
         default:
             UNREACHABLE();
diff --git a/src/libANGLE/queryutils.h b/src/libANGLE/queryutils.h
index 48819cb..2b0edf5 100644
--- a/src/libANGLE/queryutils.h
+++ b/src/libANGLE/queryutils.h
@@ -47,7 +47,7 @@
                          const Renderbuffer *renderbuffer,
                          GLenum pname,
                          GLint *params);
-void QueryShaderiv(const Context *context, Shader *shader, GLenum pname, GLint *params);
+void QueryShaderiv(Shader *shader, GLenum pname, GLint *params);
 void QueryTexLevelParameterfv(const Texture *texture,
                               TextureTarget target,
                               GLint level,
diff --git a/src/libANGLE/renderer/ShaderImpl.h b/src/libANGLE/renderer/ShaderImpl.h
index 8da34c8..2b5c404 100644
--- a/src/libANGLE/renderer/ShaderImpl.h
+++ b/src/libANGLE/renderer/ShaderImpl.h
@@ -21,18 +21,16 @@
     ShaderImpl(const gl::ShaderState &data) : mData(data) {}
     virtual ~ShaderImpl() { }
 
-    virtual void destroy(const gl::Context *context) {}
+    virtual void destroy() {}
 
     // Returns additional sh::Compile options.
     virtual ShCompileOptions prepareSourceAndReturnOptions(const gl::Context *context,
                                                            std::stringstream *sourceStream,
                                                            std::string *sourcePath) = 0;
     // Returns success for compiling on the driver. Returns success.
-    virtual bool postTranslateCompile(const gl::Context *context,
-                                      gl::Compiler *compiler,
-                                      std::string *infoLog) = 0;
+    virtual bool postTranslateCompile(gl::Compiler *compiler, std::string *infoLog) = 0;
 
-    virtual std::string getDebugInfo(const gl::Context *context) const = 0;
+    virtual std::string getDebugInfo() const = 0;
 
     const gl::ShaderState &getData() const { return mData; }
 
diff --git a/src/libANGLE/renderer/d3d/DynamicHLSL.cpp b/src/libANGLE/renderer/d3d/DynamicHLSL.cpp
index 4b48577..0dfea5f 100644
--- a/src/libANGLE/renderer/d3d/DynamicHLSL.cpp
+++ b/src/libANGLE/renderer/d3d/DynamicHLSL.cpp
@@ -457,7 +457,7 @@
     hlslStream << "};\n";
 }
 
-void DynamicHLSL::generateShaderLinkHLSL(const gl::Context *context,
+void DynamicHLSL::generateShaderLinkHLSL(const gl::Caps &caps,
                                          const gl::ProgramState &programData,
                                          const ProgramD3DMetadata &programMetadata,
                                          const VaryingPacking &varyingPacking,
@@ -468,7 +468,6 @@
     ASSERT((*shaderHLSL)[gl::ShaderType::Vertex].empty() &&
            (*shaderHLSL)[gl::ShaderType::Fragment].empty());
 
-    const auto &data                   = context->getContextState();
     gl::Shader *vertexShaderGL         = programData.getAttachedShader(ShaderType::Vertex);
     gl::Shader *fragmentShaderGL       = programData.getAttachedShader(ShaderType::Fragment);
     const ShaderD3D *fragmentShader    = GetImplAs<ShaderD3D>(fragmentShaderGL);
@@ -494,10 +493,10 @@
     // GeometryShader HLSL. These include pointsize clamp values.
     if (useInstancedPointSpriteEmulation)
     {
-        vertexStream << "static float minPointSize = "
-                     << static_cast<int>(data.getCaps().minAliasedPointSize) << ".0f;\n"
-                     << "static float maxPointSize = "
-                     << static_cast<int>(data.getCaps().maxAliasedPointSize) << ".0f;\n";
+        vertexStream << "static float minPointSize = " << static_cast<int>(caps.minAliasedPointSize)
+                     << ".0f;\n"
+                     << "static float maxPointSize = " << static_cast<int>(caps.maxAliasedPointSize)
+                     << ".0f;\n";
     }
 
     std::ostringstream vertexGenerateOutput;
@@ -664,7 +663,7 @@
                          << "    return output;\n"
                          << "}";
 
-    std::string vertexSource = vertexShaderGL->getTranslatedSource(context);
+    std::string vertexSource = vertexShaderGL->getTranslatedSource();
     angle::ReplaceSubstring(&vertexSource, std::string(MAIN_PROLOGUE_STUB_STRING),
                             "    initAttributes(input);\n");
     angle::ReplaceSubstring(&vertexSource, std::string(VERTEX_OUTPUT_STUB_STRING),
@@ -833,7 +832,7 @@
         pixelPrologue << ";\n";
     }
 
-    std::string pixelSource = fragmentShaderGL->getTranslatedSource(context);
+    std::string pixelSource = fragmentShaderGL->getTranslatedSource();
 
     if (fragmentShader->usesFrontFacing())
     {
@@ -955,7 +954,7 @@
     return preambleStream.str();
 }
 
-std::string DynamicHLSL::generateGeometryShaderHLSL(const gl::Context *context,
+std::string DynamicHLSL::generateGeometryShaderHLSL(const gl::Caps &caps,
                                                     gl::PrimitiveMode primitiveType,
                                                     const gl::ProgramState &programData,
                                                     const bool useViewScale,
@@ -1063,10 +1062,10 @@
                         "};\n"
                         "\n"
                         "static float minPointSize = "
-                     << static_cast<int>(context->getCaps().minAliasedPointSize)
+                     << static_cast<int>(caps.minAliasedPointSize)
                      << ".0f;\n"
                         "static float maxPointSize = "
-                     << static_cast<int>(context->getCaps().maxAliasedPointSize) << ".0f;\n"
+                     << static_cast<int>(caps.maxAliasedPointSize) << ".0f;\n"
                      << "\n";
     }
 
diff --git a/src/libANGLE/renderer/d3d/DynamicHLSL.h b/src/libANGLE/renderer/d3d/DynamicHLSL.h
index d9c1d61..d138c82 100644
--- a/src/libANGLE/renderer/d3d/DynamicHLSL.h
+++ b/src/libANGLE/renderer/d3d/DynamicHLSL.h
@@ -128,7 +128,7 @@
         const std::vector<PixelShaderOutputVariable> &outputVariables,
         bool usesFragDepth,
         const std::vector<GLenum> &outputLayout) const;
-    void generateShaderLinkHLSL(const gl::Context *context,
+    void generateShaderLinkHLSL(const gl::Caps &caps,
                                 const gl::ProgramState &programData,
                                 const ProgramD3DMetadata &programMetadata,
                                 const gl::VaryingPacking &varyingPacking,
@@ -140,7 +140,7 @@
                                                const bool hasANGLEMultiviewEnabled,
                                                const bool selectViewInVS) const;
 
-    std::string generateGeometryShaderHLSL(const gl::Context *context,
+    std::string generateGeometryShaderHLSL(const gl::Caps &caps,
                                            gl::PrimitiveMode primitiveType,
                                            const gl::ProgramState &programData,
                                            const bool useViewScale,
diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.cpp b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
index ef3264d..0f179ae 100644
--- a/src/libANGLE/renderer/d3d/ProgramD3D.cpp
+++ b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
@@ -36,13 +36,11 @@
 namespace
 {
 
-void GetDefaultInputLayoutFromShader(const gl::Context *context,
-                                     gl::Shader *vertexShader,
-                                     gl::InputLayout *inputLayoutOut)
+void GetDefaultInputLayoutFromShader(gl::Shader *vertexShader, gl::InputLayout *inputLayoutOut)
 {
     inputLayoutOut->clear();
 
-    for (const sh::Attribute &shaderAttr : vertexShader->getActiveAttributes(context))
+    for (const sh::Attribute &shaderAttr : vertexShader->getActiveAttributes())
     {
         if (shaderAttr.type != GL_NONE)
         {
@@ -119,29 +117,26 @@
     return false;
 }
 
-bool FindFlatInterpolationVaryingPerShader(const gl::Context *context, gl::Shader *shader)
+bool FindFlatInterpolationVaryingPerShader(gl::Shader *shader)
 {
-    ASSERT(context && shader);
+    ASSERT(shader);
     switch (shader->getType())
     {
         case gl::ShaderType::Vertex:
-            return HasFlatInterpolationVarying(shader->getOutputVaryings(context));
+            return HasFlatInterpolationVarying(shader->getOutputVaryings());
         case gl::ShaderType::Fragment:
-            return HasFlatInterpolationVarying(shader->getInputVaryings(context));
+            return HasFlatInterpolationVarying(shader->getInputVaryings());
         case gl::ShaderType::Geometry:
-            return HasFlatInterpolationVarying(shader->getInputVaryings(context)) ||
-                   HasFlatInterpolationVarying(shader->getOutputVaryings(context));
+            return HasFlatInterpolationVarying(shader->getInputVaryings()) ||
+                   HasFlatInterpolationVarying(shader->getOutputVaryings());
         default:
             UNREACHABLE();
             return false;
     }
 }
 
-bool FindFlatInterpolationVarying(const gl::Context *context,
-                                  const gl::ShaderMap<gl::Shader *> &shaders)
+bool FindFlatInterpolationVarying(const gl::ShaderMap<gl::Shader *> &shaders)
 {
-    ASSERT(context);
-
     for (gl::ShaderType shaderType : gl::kAllGraphicsShaderTypes)
     {
         gl::Shader *shader = shaders[shaderType];
@@ -150,7 +145,7 @@
             continue;
         }
 
-        if (FindFlatInterpolationVaryingPerShader(context, shader))
+        if (FindFlatInterpolationVaryingPerShader(shader))
         {
             return true;
         }
@@ -164,7 +159,7 @@
   public:
     UniformBlockInfo() {}
 
-    void getShaderBlockInfo(const gl::Context *context, gl::Shader *shader);
+    void getShaderBlockInfo(gl::Shader *shader);
 
     bool getBlockSize(const std::string &name, const std::string &mappedName, size_t *sizeOut);
     bool getBlockMemberInfo(const std::string &name,
@@ -178,9 +173,9 @@
     sh::BlockLayoutMap mBlockLayout;
 };
 
-void UniformBlockInfo::getShaderBlockInfo(const gl::Context *context, gl::Shader *shader)
+void UniformBlockInfo::getShaderBlockInfo(gl::Shader *shader)
 {
-    for (const sh::InterfaceBlock &interfaceBlock : shader->getUniformBlocks(context))
+    for (const sh::InterfaceBlock &interfaceBlock : shader->getUniformBlocks())
     {
         if (!interfaceBlock.active && interfaceBlock.layout == sh::BLOCKLAYOUT_PACKED)
             continue;
@@ -1306,7 +1301,7 @@
     }
 
     std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL(
-        context, geometryShaderType, mState, mRenderer->presentPathFastEnabled(),
+        context->getCaps(), geometryShaderType, mState, mRenderer->presentPathFastEnabled(),
         mHasANGLEMultiviewEnabled, mRenderer->canSelectViewInVertexShader(),
         usesGeometryShaderForPointSpriteEmulation(), mGeometryShaderPreamble);
 
@@ -1374,7 +1369,7 @@
     }
     angle::Result run() override
     {
-        mProgram->updateCachedInputLayoutFromShader(mContext);
+        mProgram->updateCachedInputLayoutFromShader();
 
         ANGLE_TRY(
             mProgram->getVertexExecutableForCachedInputLayout(mContext, &mExecutable, &mInfoLog));
@@ -1383,9 +1378,9 @@
     }
 };
 
-void ProgramD3D::updateCachedInputLayoutFromShader(const gl::Context *context)
+void ProgramD3D::updateCachedInputLayoutFromShader()
 {
-    GetDefaultInputLayoutFromShader(context, mState.getAttachedShader(gl::ShaderType::Vertex),
+    GetDefaultInputLayoutFromShader(mState.getAttachedShader(gl::ShaderType::Vertex),
                                     &mCachedInputLayout);
     VertexExecutable::getSignature(mRenderer, mCachedInputLayout, &mCachedVertexSignature);
     updateCachedVertexExecutableIndex();
@@ -1586,7 +1581,7 @@
 
     gl::Shader *computeShaderGL = mState.getAttachedShader(gl::ShaderType::Compute);
     ASSERT(computeShaderGL);
-    std::string computeShader = computeShaderGL->getTranslatedSource(context);
+    std::string computeShader = computeShaderGL->getTranslatedSource();
 
     ShaderExecutableD3D *computeExecutable = nullptr;
     ANGLE_TRY(mRenderer->compileToExecutable(
@@ -1626,9 +1621,9 @@
         mReadonlyImagesCS.resize(data.getCaps().maxImageUnits);
 
         mShaderUniformsDirty.set(gl::ShaderType::Compute);
-        defineUniformsAndAssignRegisters(context);
+        defineUniformsAndAssignRegisters();
 
-        linkResources(context, resources);
+        linkResources(resources);
 
         gl::LinkResult result = compileComputeExecutable(context, infoLog);
         if (result.isError())
@@ -1671,8 +1666,8 @@
         ProgramD3DMetadata metadata(mRenderer, shadersD3D);
         BuiltinVaryingsD3D builtins(metadata, resources.varyingPacking);
 
-        mDynamicHLSL->generateShaderLinkHLSL(context, mState, metadata, resources.varyingPacking,
-                                             builtins, &mShaderHLSL);
+        mDynamicHLSL->generateShaderLinkHLSL(context->getCaps(), mState, metadata,
+                                             resources.varyingPacking, builtins, &mShaderHLSL);
 
         mUsesPointSize = shadersD3D[gl::ShaderType::Vertex]->usesPointSize();
         mDynamicHLSL->getPixelShaderOutputKey(data, mState, metadata, &mPixelShaderKey);
@@ -1681,7 +1676,7 @@
         mHasANGLEMultiviewEnabled = metadata.hasANGLEMultiviewEnabled();
 
         // Cache if we use flat shading
-        mUsesFlatInterpolation = FindFlatInterpolationVarying(context, mState.getAttachedShaders());
+        mUsesFlatInterpolation = FindFlatInterpolationVarying(mState.getAttachedShaders());
 
         if (mRenderer->getMajorShaderModel() >= 4)
         {
@@ -1690,13 +1685,13 @@
                 metadata.canSelectViewInVertexShader());
         }
 
-        initAttribLocationsToD3DSemantic(context);
+        initAttribLocationsToD3DSemantic();
 
-        defineUniformsAndAssignRegisters(context);
+        defineUniformsAndAssignRegisters();
 
         gatherTransformFeedbackVaryings(resources.varyingPacking, builtins[gl::ShaderType::Vertex]);
 
-        linkResources(context, resources);
+        linkResources(resources);
 
         return compileProgramExecutables(context, infoLog);
     }
@@ -1994,7 +1989,7 @@
     mRenderer->onDirtyUniformBlockBinding(uniformBlockIndex);
 }
 
-void ProgramD3D::defineUniformsAndAssignRegisters(const gl::Context *context)
+void ProgramD3D::defineUniformsAndAssignRegisters()
 {
     D3DUniformMap uniformMap;
 
@@ -2004,7 +1999,7 @@
         gl::Shader *shader = mState.getAttachedShader(shaderType);
         if (shader)
         {
-            for (const sh::Uniform &uniform : shader->getUniforms(context))
+            for (const sh::Uniform &uniform : shader->getUniforms())
             {
                 if (uniform.active)
                 {
@@ -2571,14 +2566,14 @@
     return mCurrentSerial++;
 }
 
-void ProgramD3D::initAttribLocationsToD3DSemantic(const gl::Context *context)
+void ProgramD3D::initAttribLocationsToD3DSemantic()
 {
     gl::Shader *vertexShader = mState.getAttachedShader(gl::ShaderType::Vertex);
     ASSERT(vertexShader != nullptr);
 
     // Init semantic index
     int semanticIndex = 0;
-    for (const sh::Attribute &attribute : vertexShader->getActiveAttributes(context))
+    for (const sh::Attribute &attribute : vertexShader->getActiveAttributes())
     {
         int regCount    = gl::VariableRegisterCount(attribute.type);
         GLuint location = mState.getAttributeLocation(attribute.name);
@@ -2811,8 +2806,7 @@
     }
 }
 
-void ProgramD3D::linkResources(const gl::Context *context,
-                               const gl::ProgramLinkedResources &resources)
+void ProgramD3D::linkResources(const gl::ProgramLinkedResources &resources)
 {
     UniformBlockInfo uniformBlockInfo;
     for (gl::ShaderType shaderType : gl::AllShaderTypes())
@@ -2820,7 +2814,7 @@
         gl::Shader *shader = mState.getAttachedShader(shaderType);
         if (shader)
         {
-            uniformBlockInfo.getShaderBlockInfo(context, shader);
+            uniformBlockInfo.getShaderBlockInfo(shader);
         }
     }
 
diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.h b/src/libANGLE/renderer/d3d/ProgramD3D.h
index 7be9d41..326d710 100644
--- a/src/libANGLE/renderer/d3d/ProgramD3D.h
+++ b/src/libANGLE/renderer/d3d/ProgramD3D.h
@@ -387,7 +387,7 @@
 
     void initializeUniformStorage(const gl::ShaderBitSet &availableShaderStages);
 
-    void defineUniformsAndAssignRegisters(const gl::Context *context);
+    void defineUniformsAndAssignRegisters();
     void defineUniformBase(const gl::Shader *shader,
                            const sh::Uniform &uniform,
                            D3DUniformMap *uniformMap);
@@ -462,17 +462,17 @@
     D3DUniform *getD3DUniformFromLocation(GLint location);
     const D3DUniform *getD3DUniformFromLocation(GLint location) const;
 
-    void initAttribLocationsToD3DSemantic(const gl::Context *context);
+    void initAttribLocationsToD3DSemantic();
 
     void reset();
     void initializeUniformBlocks();
 
-    void updateCachedInputLayoutFromShader(const gl::Context *context);
+    void updateCachedInputLayoutFromShader();
     void updateCachedOutputLayoutFromShader();
     void updateCachedVertexExecutableIndex();
     void updateCachedPixelExecutableIndex();
 
-    void linkResources(const gl::Context *context, const gl::ProgramLinkedResources &resources);
+    void linkResources(const gl::ProgramLinkedResources &resources);
 
     RendererD3D *mRenderer;
     DynamicHLSL *mDynamicHLSL;
diff --git a/src/libANGLE/renderer/d3d/ShaderD3D.cpp b/src/libANGLE/renderer/d3d/ShaderD3D.cpp
index 8798cb8..0d27f78 100644
--- a/src/libANGLE/renderer/d3d/ShaderD3D.cpp
+++ b/src/libANGLE/renderer/d3d/ShaderD3D.cpp
@@ -62,7 +62,7 @@
 {
 }
 
-std::string ShaderD3D::getDebugInfo(const gl::Context *context) const
+std::string ShaderD3D::getDebugInfo() const
 {
     if (mDebugInfo.empty())
     {
@@ -174,9 +174,7 @@
     return *uniformRegisterMap;
 }
 
-bool ShaderD3D::postTranslateCompile(const gl::Context *context,
-                                     gl::Compiler *compiler,
-                                     std::string *infoLog)
+bool ShaderD3D::postTranslateCompile(gl::Compiler *compiler, std::string *infoLog)
 {
     // TODO(jmadill): We shouldn't need to cache this.
     mCompilerOutputType = compiler->getShaderOutputType();
diff --git a/src/libANGLE/renderer/d3d/ShaderD3D.h b/src/libANGLE/renderer/d3d/ShaderD3D.h
index a6a7fb4..9239df7 100644
--- a/src/libANGLE/renderer/d3d/ShaderD3D.h
+++ b/src/libANGLE/renderer/d3d/ShaderD3D.h
@@ -42,10 +42,8 @@
     ShCompileOptions prepareSourceAndReturnOptions(const gl::Context *context,
                                                    std::stringstream *sourceStream,
                                                    std::string *sourcePath) override;
-    bool postTranslateCompile(const gl::Context *context,
-                              gl::Compiler *compiler,
-                              std::string *infoLog) override;
-    std::string getDebugInfo(const gl::Context *context) const override;
+    bool postTranslateCompile(gl::Compiler *compiler, std::string *infoLog) override;
+    std::string getDebugInfo() const override;
 
     // D3D-specific methods
     void uncompile();
diff --git a/src/libANGLE/renderer/gl/ContextGL.cpp b/src/libANGLE/renderer/gl/ContextGL.cpp
index c2ec78f..0ffc85f 100644
--- a/src/libANGLE/renderer/gl/ContextGL.cpp
+++ b/src/libANGLE/renderer/gl/ContextGL.cpp
@@ -55,7 +55,7 @@
     const FunctionsGL *functions = getFunctions();
     GLuint shader                = functions->createShader(ToGLenum(data.getShaderType()));
 
-    return new ShaderGL(data, shader, mRenderer->getMultiviewImplementationType());
+    return new ShaderGL(data, shader, mRenderer->getMultiviewImplementationType(), functions);
 }
 
 ProgramImpl *ContextGL::createProgram(const gl::ProgramState &data)
diff --git a/src/libANGLE/renderer/gl/ProgramGL.cpp b/src/libANGLE/renderer/gl/ProgramGL.cpp
index 3c6fd40..e3789c3 100644
--- a/src/libANGLE/renderer/gl/ProgramGL.cpp
+++ b/src/libANGLE/renderer/gl/ProgramGL.cpp
@@ -160,7 +160,7 @@
         {
             std::string tfVaryingMappedName =
                 mState.getAttachedShader(gl::ShaderType::Vertex)
-                    ->getTransformFeedbackVaryingMappedName(tfVarying, context);
+                    ->getTransformFeedbackVaryingMappedName(tfVarying);
             transformFeedbackVaryingMappedNames.push_back(tfVaryingMappedName);
         }
 
diff --git a/src/libANGLE/renderer/gl/ShaderGL.cpp b/src/libANGLE/renderer/gl/ShaderGL.cpp
index dc3fc8d..fa053ab 100644
--- a/src/libANGLE/renderer/gl/ShaderGL.cpp
+++ b/src/libANGLE/renderer/gl/ShaderGL.cpp
@@ -22,10 +22,12 @@
 
 ShaderGL::ShaderGL(const gl::ShaderState &data,
                    GLuint shaderID,
-                   MultiviewImplementationTypeGL multiviewImplementationType)
+                   MultiviewImplementationTypeGL multiviewImplementationType,
+                   const FunctionsGL *functions)
     : ShaderImpl(data),
       mShaderID(shaderID),
-      mMultiviewImplementationType(multiviewImplementationType)
+      mMultiviewImplementationType(multiviewImplementationType),
+      mFunctions(functions)
 {
 }
 
@@ -34,10 +36,9 @@
     ASSERT(mShaderID == 0);
 }
 
-void ShaderGL::destroy(const gl::Context *context)
+void ShaderGL::destroy()
 {
-    const FunctionsGL *functions = GetFunctionsGL(context);
-    functions->deleteShader(mShaderID);
+    mFunctions->deleteShader(mShaderID);
     mShaderID = 0;
 }
 
@@ -141,33 +142,30 @@
     return options;
 }
 
-bool ShaderGL::postTranslateCompile(const gl::Context *context,
-                                    gl::Compiler *compiler,
-                                    std::string *infoLog)
+bool ShaderGL::postTranslateCompile(gl::Compiler *compiler, std::string *infoLog)
 {
     // Translate the ESSL into GLSL
     const char *translatedSourceCString = mData.getTranslatedSource().c_str();
 
     // Set the source
-    const FunctionsGL *functions = GetFunctionsGL(context);
-    functions->shaderSource(mShaderID, 1, &translatedSourceCString, nullptr);
-    functions->compileShader(mShaderID);
+    mFunctions->shaderSource(mShaderID, 1, &translatedSourceCString, nullptr);
+    mFunctions->compileShader(mShaderID);
 
     // Check for compile errors from the native driver
     GLint compileStatus = GL_FALSE;
-    functions->getShaderiv(mShaderID, GL_COMPILE_STATUS, &compileStatus);
+    mFunctions->getShaderiv(mShaderID, GL_COMPILE_STATUS, &compileStatus);
     if (compileStatus == GL_FALSE)
     {
         // Compilation failed, put the error into the info log
         GLint infoLogLength = 0;
-        functions->getShaderiv(mShaderID, GL_INFO_LOG_LENGTH, &infoLogLength);
+        mFunctions->getShaderiv(mShaderID, GL_INFO_LOG_LENGTH, &infoLogLength);
 
         // Info log length includes the null terminator, so 1 means that the info log is an empty
         // string.
         if (infoLogLength > 1)
         {
             std::vector<char> buf(infoLogLength);
-            functions->getShaderInfoLog(mShaderID, infoLogLength, nullptr, &buf[0]);
+            mFunctions->getShaderInfoLog(mShaderID, infoLogLength, nullptr, &buf[0]);
 
             *infoLog = &buf[0];
             WARN() << std::endl << *infoLog;
@@ -182,7 +180,7 @@
     return true;
 }
 
-std::string ShaderGL::getDebugInfo(const gl::Context *context) const
+std::string ShaderGL::getDebugInfo() const
 {
     return mData.getTranslatedSource();
 }
diff --git a/src/libANGLE/renderer/gl/ShaderGL.h b/src/libANGLE/renderer/gl/ShaderGL.h
index 3023fb5..0ba8843 100644
--- a/src/libANGLE/renderer/gl/ShaderGL.h
+++ b/src/libANGLE/renderer/gl/ShaderGL.h
@@ -22,25 +22,25 @@
   public:
     ShaderGL(const gl::ShaderState &data,
              GLuint shaderID,
-             MultiviewImplementationTypeGL multiviewImplementationType);
+             MultiviewImplementationTypeGL multiviewImplementationType,
+             const FunctionsGL *functions);
     ~ShaderGL() override;
 
-    void destroy(const gl::Context *context) override;
+    void destroy() override;
 
     // ShaderImpl implementation
     ShCompileOptions prepareSourceAndReturnOptions(const gl::Context *context,
                                                    std::stringstream *sourceStream,
                                                    std::string *sourcePath) override;
-    bool postTranslateCompile(const gl::Context *context,
-                              gl::Compiler *compiler,
-                              std::string *infoLog) override;
-    std::string getDebugInfo(const gl::Context *context) const override;
+    bool postTranslateCompile(gl::Compiler *compiler, std::string *infoLog) override;
+    std::string getDebugInfo() const override;
 
     GLuint getShaderID() const;
 
   private:
     GLuint mShaderID;
     MultiviewImplementationTypeGL mMultiviewImplementationType;
+    const FunctionsGL *mFunctions;
 };
 
 }
diff --git a/src/libANGLE/renderer/null/ShaderNULL.cpp b/src/libANGLE/renderer/null/ShaderNULL.cpp
index 59ae007..4e3b9e7 100644
--- a/src/libANGLE/renderer/null/ShaderNULL.cpp
+++ b/src/libANGLE/renderer/null/ShaderNULL.cpp
@@ -30,14 +30,12 @@
     return 0;
 }
 
-bool ShaderNULL::postTranslateCompile(const gl::Context *context,
-                                      gl::Compiler *compiler,
-                                      std::string *infoLog)
+bool ShaderNULL::postTranslateCompile(gl::Compiler *compiler, std::string *infoLog)
 {
     return true;
 }
 
-std::string ShaderNULL::getDebugInfo(const gl::Context *context) const
+std::string ShaderNULL::getDebugInfo() const
 {
     return "";
 }
diff --git a/src/libANGLE/renderer/null/ShaderNULL.h b/src/libANGLE/renderer/null/ShaderNULL.h
index 0a415f3..04a58c0 100644
--- a/src/libANGLE/renderer/null/ShaderNULL.h
+++ b/src/libANGLE/renderer/null/ShaderNULL.h
@@ -26,11 +26,9 @@
                                                    std::stringstream *sourceStream,
                                                    std::string *sourcePath) override;
     // Returns success for compiling on the driver. Returns success.
-    bool postTranslateCompile(const gl::Context *context,
-                              gl::Compiler *compiler,
-                              std::string *infoLog) override;
+    bool postTranslateCompile(gl::Compiler *compiler, std::string *infoLog) override;
 
-    std::string getDebugInfo(const gl::Context *context) const override;
+    std::string getDebugInfo() const override;
 };
 
 }  // namespace rx
diff --git a/src/libANGLE/renderer/vulkan/GlslangWrapper.cpp b/src/libANGLE/renderer/vulkan/GlslangWrapper.cpp
index 7b6f350..2356a85 100644
--- a/src/libANGLE/renderer/vulkan/GlslangWrapper.cpp
+++ b/src/libANGLE/renderer/vulkan/GlslangWrapper.cpp
@@ -135,8 +135,7 @@
 }
 
 // static
-void GlslangWrapper::GetShaderSource(const gl::Context *glContext,
-                                     const gl::ProgramState &programState,
+void GlslangWrapper::GetShaderSource(const gl::ProgramState &programState,
                                      const gl::ProgramLinkedResources &resources,
                                      std::string *vertexSourceOut,
                                      std::string *fragmentSourceOut)
@@ -144,8 +143,8 @@
     gl::Shader *glVertexShader   = programState.getAttachedShader(gl::ShaderType::Vertex);
     gl::Shader *glFragmentShader = programState.getAttachedShader(gl::ShaderType::Fragment);
 
-    std::string vertexSource   = glVertexShader->getTranslatedSource(glContext);
-    std::string fragmentSource = glFragmentShader->getTranslatedSource(glContext);
+    std::string vertexSource   = glVertexShader->getTranslatedSource();
+    std::string fragmentSource = glFragmentShader->getTranslatedSource();
 
     // Parse attribute locations and replace them in the vertex shader.
     // See corresponding code in OutputVulkanGLSL.cpp.
@@ -164,7 +163,7 @@
     // The attributes in the programState could have been filled with active attributes only
     // depending on the shader version. If there is inactive attributes left, we have to remove
     // their @@ QUALIFIER and @@ LAYOUT markers.
-    for (const sh::Attribute &attribute : glVertexShader->getAllAttributes(glContext))
+    for (const sh::Attribute &attribute : glVertexShader->getAllAttributes())
     {
         if (attribute.active)
         {
diff --git a/src/libANGLE/renderer/vulkan/GlslangWrapper.h b/src/libANGLE/renderer/vulkan/GlslangWrapper.h
index 4db938c..aff6747 100644
--- a/src/libANGLE/renderer/vulkan/GlslangWrapper.h
+++ b/src/libANGLE/renderer/vulkan/GlslangWrapper.h
@@ -22,8 +22,7 @@
     static void Initialize();
     static void Release();
 
-    static void GetShaderSource(const gl::Context *glContext,
-                                const gl::ProgramState &programState,
+    static void GetShaderSource(const gl::ProgramState &programState,
                                 const gl::ProgramLinkedResources &resources,
                                 std::string *vertexSourceOut,
                                 std::string *fragmentSourceOut);
diff --git a/src/libANGLE/renderer/vulkan/ProgramVk.cpp b/src/libANGLE/renderer/vulkan/ProgramVk.cpp
index 5fdaa8b..f27e92d 100644
--- a/src/libANGLE/renderer/vulkan/ProgramVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ProgramVk.cpp
@@ -268,7 +268,7 @@
 
     ANGLE_TRY(reset(contextVk));
 
-    GlslangWrapper::GetShaderSource(glContext, mState, resources, &mVertexSource, &mFragmentSource);
+    GlslangWrapper::GetShaderSource(mState, resources, &mVertexSource, &mFragmentSource);
 
     ANGLE_TRY(initDefaultUniformBlocks(glContext));
 
@@ -355,7 +355,7 @@
     {
         gl::ShaderType glShaderType = static_cast<gl::ShaderType>(shaderType);
         gl::Shader *shader                       = mState.getAttachedShader(glShaderType);
-        const std::vector<sh::Uniform> &uniforms = shader->getUniforms(glContext);
+        const std::vector<sh::Uniform> &uniforms = shader->getUniforms();
         InitDefaultUniformBlock(uniforms, shader, &layoutMap[shaderType],
                                 &requiredBufferSize[shaderType]);
     }
diff --git a/src/libANGLE/renderer/vulkan/ShaderVk.cpp b/src/libANGLE/renderer/vulkan/ShaderVk.cpp
index b840c2d..c1e21b6 100644
--- a/src/libANGLE/renderer/vulkan/ShaderVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ShaderVk.cpp
@@ -30,15 +30,13 @@
     return SH_INITIALIZE_UNINITIALIZED_LOCALS;
 }
 
-bool ShaderVk::postTranslateCompile(const gl::Context *context,
-                                    gl::Compiler *compiler,
-                                    std::string *infoLog)
+bool ShaderVk::postTranslateCompile(gl::Compiler *compiler, std::string *infoLog)
 {
     // No work to do here.
     return true;
 }
 
-std::string ShaderVk::getDebugInfo(const gl::Context *context) const
+std::string ShaderVk::getDebugInfo() const
 {
     return std::string();
 }
diff --git a/src/libANGLE/renderer/vulkan/ShaderVk.h b/src/libANGLE/renderer/vulkan/ShaderVk.h
index 202f4d3..5e42907 100644
--- a/src/libANGLE/renderer/vulkan/ShaderVk.h
+++ b/src/libANGLE/renderer/vulkan/ShaderVk.h
@@ -26,11 +26,9 @@
                                                    std::stringstream *sourceStream,
                                                    std::string *sourcePath) override;
     // Returns success for compiling on the driver. Returns success.
-    bool postTranslateCompile(const gl::Context *context,
-                              gl::Compiler *compiler,
-                              std::string *infoLog) override;
+    bool postTranslateCompile(gl::Compiler *compiler, std::string *infoLog) override;
 
-    std::string getDebugInfo(const gl::Context *context) const override;
+    std::string getDebugInfo() const override;
 };
 
 }  // namespace rx
diff --git a/src/libANGLE/validationES2.cpp b/src/libANGLE/validationES2.cpp
index 6d3fd58..88d775f 100644
--- a/src/libANGLE/validationES2.cpp
+++ b/src/libANGLE/validationES2.cpp
@@ -3849,7 +3849,7 @@
     if (location == -1)
         return true;
 
-    const auto &binding = programObject->getFragmentInputBindingInfo(context, location);
+    const auto &binding = programObject->getFragmentInputBindingInfo(location);
 
     if (!binding.valid)
     {