Replace rx::Renderer with rx::ContextImpl.

Previously Context had no Impl class, but had a special relationship
with the instanced Renderer class. Having a ContextImpl backing every
Context will allow new designs to enable things like multithreading
(where each ContextImpl stores a Context-specific device) or non-
virtual Contexts on Android or other platforms where it is more
efficient.

A large refactoring patch that touches every back-end.

BUG=angleproject:1363

Change-Id: Icb73a7d37447f08a664eeb499a310ba05d71a57e
Reviewed-on: https://chromium-review.googlesource.com/342052
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/Buffer.cpp b/src/libANGLE/Buffer.cpp
index 589735c..3523b32 100644
--- a/src/libANGLE/Buffer.cpp
+++ b/src/libANGLE/Buffer.cpp
@@ -10,7 +10,6 @@
 
 #include "libANGLE/Buffer.h"
 #include "libANGLE/renderer/BufferImpl.h"
-#include "libANGLE/renderer/Renderer.h"
 
 namespace gl
 {
@@ -193,4 +192,4 @@
     return Error(GL_NO_ERROR);
 }
 
-}
+}  // namespace gl
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index 4330803..16ce699 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -32,7 +32,7 @@
 #include "libANGLE/formatutils.h"
 #include "libANGLE/validationES.h"
 #include "libANGLE/renderer/ContextImpl.h"
-#include "libANGLE/renderer/Renderer.h"
+#include "libANGLE/renderer/EGLImplFactory.h"
 
 namespace
 {
@@ -122,9 +122,9 @@
 namespace gl
 {
 
-Context::Context(const egl::Config *config,
+Context::Context(rx::EGLImplFactory *implFactory,
+                 const egl::Config *config,
                  const Context *shareContext,
-                 rx::Renderer *renderer,
                  const egl::AttributeMap &attribs)
     : ValidationContext(GetClientVersion(attribs),
                         mState,
@@ -134,9 +134,8 @@
                         nullptr,
                         mLimitations,
                         GetNoError(attribs)),
-      mImplementation(renderer->createContext(getData())),
+      mImplementation(implFactory->createContext(getData())),
       mCompiler(nullptr),
-      mRenderer(renderer),
       mClientVersion(GetClientVersion(attribs)),
       mConfig(config),
       mClientType(EGL_OPENGL_ES_API),
@@ -156,14 +155,14 @@
 
     mFenceNVHandleAllocator.setBaseHandle(0);
 
-    if (shareContext != NULL)
+    if (shareContext != nullptr)
     {
         mResourceManager = shareContext->mResourceManager;
         mResourceManager->addRef();
     }
     else
     {
-        mResourceManager = new ResourceManager(mRenderer);
+        mResourceManager = new ResourceManager(mImplementation.get());
     }
 
     mData.resourceManager = mResourceManager;
@@ -174,25 +173,26 @@
     // In order that access to these initial textures not be lost, they are treated as texture
     // objects all of whose names are 0.
 
-    Texture *zeroTexture2D = new Texture(mRenderer, 0, GL_TEXTURE_2D);
+    Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
     mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
 
-    Texture *zeroTextureCube = new Texture(mRenderer, 0, GL_TEXTURE_CUBE_MAP);
+    Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
     mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
 
     if (mClientVersion >= 3)
     {
         // TODO: These could also be enabled via extension
-        Texture *zeroTexture3D = new Texture(mRenderer, 0, GL_TEXTURE_3D);
+        Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
         mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
 
-        Texture *zeroTexture2DArray = new Texture(mRenderer, 0, GL_TEXTURE_2D_ARRAY);
+        Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
         mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
     }
 
     if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
     {
-        Texture *zeroTextureExternal = new Texture(mRenderer, 0, GL_TEXTURE_EXTERNAL_OES);
+        Texture *zeroTextureExternal =
+            new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
         mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
     }
 
@@ -224,7 +224,7 @@
         bindTransformFeedback(0);
     }
 
-    mCompiler = new Compiler(mRenderer, getData());
+    mCompiler = new Compiler(mImplementation.get(), getData());
 
     // Initialize dirty bit masks
     // TODO(jmadill): additional ES3 state
@@ -264,7 +264,7 @@
     mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
     mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
 
-    handleError(mImplementation->initialize(renderer));
+    handleError(mImplementation->initialize());
 }
 
 Context::~Context()
@@ -366,7 +366,7 @@
     }
 
     // Notify the renderer of a context switch
-    mRenderer->onMakeCurrent(getData());
+    mImplementation->onMakeCurrent(getData());
 }
 
 void Context::releaseSurface()
@@ -416,7 +416,7 @@
 
 GLuint Context::createShader(GLenum type)
 {
-    return mResourceManager->createShader(mRenderer->getRendererLimitations(), type);
+    return mResourceManager->createShader(mImplementation->getNativeLimitations(), type);
 }
 
 GLuint Context::createTexture()
@@ -469,7 +469,7 @@
 {
     GLuint handle = mFenceNVHandleAllocator.allocate();
 
-    mFenceNVMap[handle] = new FenceNV(mRenderer->createFenceNV());
+    mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
 
     return handle;
 }
@@ -951,7 +951,7 @@
     {
         if (!query->second && create)
         {
-            query->second = new Query(mRenderer->createQuery(type), handle);
+            query->second = new Query(mImplementation->createQuery(type), handle);
             query->second->addRef();
         }
         return query->second;
@@ -1109,7 +1109,7 @@
 
       // GL_EXT_disjoint_timer_query
       case GL_GPU_DISJOINT_EXT:
-          *params = mRenderer->getGPUDisjoint();
+          *params = mImplementation->getGPUDisjoint();
           break;
 
       default:
@@ -1142,7 +1142,7 @@
 
       // GL_EXT_disjoint_timer_query
       case GL_TIMESTAMP_EXT:
-          *params = mRenderer->getTimestamp();
+          *params = mImplementation->getTimestamp();
           break;
       default:
         UNREACHABLE();
@@ -1570,29 +1570,19 @@
 Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
 {
     syncRendererState();
-    Error error = mRenderer->drawArrays(getData(), mode, first, count);
-    if (error.isError())
-    {
-        return error;
-    }
-
+    ANGLE_TRY(mImplementation->drawArrays(mode, first, count));
     MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback());
 
-    return Error(GL_NO_ERROR);
+    return NoError();
 }
 
 Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
 {
     syncRendererState();
-    Error error = mRenderer->drawArraysInstanced(getData(), mode, first, count, instanceCount);
-    if (error.isError())
-    {
-        return error;
-    }
-
+    ANGLE_TRY(mImplementation->drawArraysInstanced(mode, first, count, instanceCount));
     MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback());
 
-    return Error(GL_NO_ERROR);
+    return NoError();
 }
 
 Error Context::drawElements(GLenum mode,
@@ -1602,7 +1592,7 @@
                             const IndexRange &indexRange)
 {
     syncRendererState();
-    return mRenderer->drawElements(getData(), mode, count, type, indices, indexRange);
+    return mImplementation->drawElements(mode, count, type, indices, indexRange);
 }
 
 Error Context::drawElementsInstanced(GLenum mode,
@@ -1613,8 +1603,8 @@
                                      const IndexRange &indexRange)
 {
     syncRendererState();
-    return mRenderer->drawElementsInstanced(getData(), mode, count, type, indices, instances,
-                                            indexRange);
+    return mImplementation->drawElementsInstanced(mode, count, type, indices, instances,
+                                                  indexRange);
 }
 
 Error Context::drawRangeElements(GLenum mode,
@@ -1626,36 +1616,35 @@
                                  const IndexRange &indexRange)
 {
     syncRendererState();
-    return mRenderer->drawRangeElements(getData(), mode, start, end, count, type, indices,
-                                        indexRange);
+    return mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange);
 }
 
 Error Context::flush()
 {
-    return mRenderer->flush();
+    return mImplementation->flush();
 }
 
 Error Context::finish()
 {
-    return mRenderer->finish();
+    return mImplementation->finish();
 }
 
 void Context::insertEventMarker(GLsizei length, const char *marker)
 {
-    ASSERT(mRenderer);
-    mRenderer->insertEventMarker(length, marker);
+    ASSERT(mImplementation);
+    mImplementation->insertEventMarker(length, marker);
 }
 
 void Context::pushGroupMarker(GLsizei length, const char *marker)
 {
-    ASSERT(mRenderer);
-    mRenderer->pushGroupMarker(length, marker);
+    ASSERT(mImplementation);
+    mImplementation->pushGroupMarker(length, marker);
 }
 
 void Context::popGroupMarker()
 {
-    ASSERT(mRenderer);
-    mRenderer->popGroupMarker();
+    ASSERT(mImplementation);
+    mImplementation->popGroupMarker();
 }
 
 void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
@@ -1704,9 +1693,9 @@
     {
         // mResetStatus will be set by the markContextLost callback
         // in the case a notification is sent
-        if (mRenderer->testDeviceLost())
+        if (mImplementation->testDeviceLost())
         {
-            mRenderer->notifyDeviceLost();
+            mImplementation->notifyDeviceLost();
         }
     }
 
@@ -1716,7 +1705,7 @@
     {
         ASSERT(mContextLost);
 
-        if (mRenderer->testDeviceResettable())
+        if (mImplementation->testDeviceResettable())
         {
             mResetStatus = GL_NO_ERROR;
         }
@@ -1763,7 +1752,8 @@
     VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
     if (!vertexArray)
     {
-        vertexArray                        = new VertexArray(mRenderer, vertexArrayHandle, MAX_VERTEX_ATTRIBS);
+        vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
+
         mVertexArrayMap[vertexArrayHandle] = vertexArray;
     }
 
@@ -1776,7 +1766,8 @@
     TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
     if (!transformFeedback)
     {
-        transformFeedback = new TransformFeedback(mRenderer, transformFeedbackHandle, mCaps);
+        transformFeedback =
+            new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
         transformFeedback->addRef();
         mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
     }
@@ -1791,7 +1782,7 @@
     bool neverCreated = framebufferIt == mFramebufferMap.end();
     if (neverCreated || framebufferIt->second == nullptr)
     {
-        Framebuffer *newFBO = new Framebuffer(mCaps, mRenderer, framebuffer);
+        Framebuffer *newFBO = new Framebuffer(mCaps, mImplementation.get(), framebuffer);
         if (neverCreated)
         {
             mFramebufferHandleAllocator.reserve(framebuffer);
@@ -2016,7 +2007,7 @@
 {
     std::ostringstream rendererString;
     rendererString << "ANGLE (";
-    rendererString << mRenderer->getRendererDescription();
+    rendererString << mImplementation->getRendererDescription();
     rendererString << ")";
 
     mRendererString = MakeStaticString(rendererString.str());
@@ -2074,11 +2065,11 @@
 
 void Context::initCaps(GLuint clientVersion)
 {
-    mCaps = mRenderer->getRendererCaps();
+    mCaps = mImplementation->getNativeCaps();
 
-    mExtensions = mRenderer->getRendererExtensions();
+    mExtensions = mImplementation->getNativeExtensions();
 
-    mLimitations = mRenderer->getRendererLimitations();
+    mLimitations = mImplementation->getNativeLimitations();
 
     if (clientVersion < 3)
     {
@@ -2108,7 +2099,7 @@
 
     mCaps.compressedTextureFormats.clear();
 
-    const TextureCapsMap &rendererFormats = mRenderer->getRendererTextureCaps();
+    const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
     for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
     {
         GLenum format = i->first;
@@ -2144,7 +2135,7 @@
 void Context::syncRendererState()
 {
     const State::DirtyBits &dirtyBits = mState.getDirtyBits();
-    mRenderer->syncState(mState, dirtyBits);
+    mImplementation->syncState(mState, dirtyBits);
     mState.clearDirtyBits();
     mState.syncDirtyObjects();
 }
@@ -2153,7 +2144,7 @@
                                 const State::DirtyObjects &objectMask)
 {
     const State::DirtyBits &dirtyBits = (mState.getDirtyBits() & bitMask);
-    mRenderer->syncState(mState, dirtyBits);
+    mImplementation->syncState(mState, dirtyBits);
     mState.clearDirtyBits(dirtyBits);
 
     mState.syncDirtyObjects(objectMask);
diff --git a/src/libANGLE/Context.h b/src/libANGLE/Context.h
index d9736e8..7c87ebc 100644
--- a/src/libANGLE/Context.h
+++ b/src/libANGLE/Context.h
@@ -27,7 +27,7 @@
 namespace rx
 {
 class ContextImpl;
-class Renderer;
+class EGLImplFactory;
 }
 
 namespace egl
@@ -58,9 +58,9 @@
 class Context final : public ValidationContext
 {
   public:
-    Context(const egl::Config *config,
+    Context(rx::EGLImplFactory *implFactory,
+            const egl::Config *config,
             const Context *shareContext,
-            rx::Renderer *renderer,
             const egl::AttributeMap &attribs);
 
     virtual ~Context();
@@ -405,9 +405,8 @@
     const std::string &getExtensionString(size_t idx) const;
     size_t getExtensionStringCount() const;
 
-    rx::Renderer *getRenderer() { return mRenderer; }
-
     State &getState() { return mState; }
+    rx::ContextImpl *getImplementation() const { return mImplementation.get(); }
 
   private:
     void syncRendererState();
@@ -444,7 +443,6 @@
     // Shader compiler
     Compiler *mCompiler;
 
-    rx::Renderer *const mRenderer;
     State mState;
 
     int mClientVersion;
diff --git a/src/libANGLE/Display.cpp b/src/libANGLE/Display.cpp
index 4cd5385..93dcba3 100644
--- a/src/libANGLE/Display.cpp
+++ b/src/libANGLE/Display.cpp
@@ -738,15 +738,10 @@
 
     if (mImplementation->testDeviceLost())
     {
-        Error error = restoreLostDevice();
-        if (error.isError())
-        {
-            return error;
-        }
+        ANGLE_TRY(restoreLostDevice());
     }
 
-    gl::Context *context = *outContext =
-        mImplementation->createContext(configuration, shareContext, attribs);
+    gl::Context *context = new gl::Context(mImplementation, configuration, shareContext, attribs);
 
     ASSERT(context != nullptr);
     mContextSet.insert(context);
diff --git a/src/libANGLE/Display.h b/src/libANGLE/Display.h
index 339fa59..a926ed6 100644
--- a/src/libANGLE/Display.h
+++ b/src/libANGLE/Display.h
@@ -18,7 +18,6 @@
 #include "libANGLE/Caps.h"
 #include "libANGLE/Config.h"
 #include "libANGLE/AttributeMap.h"
-#include "libANGLE/renderer/Renderer.h"
 
 namespace gl
 {
diff --git a/src/libANGLE/Fence.cpp b/src/libANGLE/Fence.cpp
index ff32f4b..e5f3ba6 100644
--- a/src/libANGLE/Fence.cpp
+++ b/src/libANGLE/Fence.cpp
@@ -9,12 +9,11 @@
 
 #include "libANGLE/Fence.h"
 
+#include "angle_gl.h"
+
+#include "common/utilities.h"
 #include "libANGLE/renderer/FenceNVImpl.h"
 #include "libANGLE/renderer/FenceSyncImpl.h"
-#include "libANGLE/renderer/Renderer.h"
-#include "common/utilities.h"
-
-#include "angle_gl.h"
 
 namespace gl
 {
diff --git a/src/libANGLE/Program.cpp b/src/libANGLE/Program.cpp
index b064abb..58b4711 100644
--- a/src/libANGLE/Program.cpp
+++ b/src/libANGLE/Program.cpp
@@ -20,9 +20,10 @@
 #include "libANGLE/ContextState.h"
 #include "libANGLE/ResourceManager.h"
 #include "libANGLE/features.h"
-#include "libANGLE/renderer/Renderer.h"
+#include "libANGLE/renderer/GLImplFactory.h"
 #include "libANGLE/renderer/ProgramImpl.h"
 #include "libANGLE/queryconversions.h"
+#include "libANGLE/Uniform.h"
 
 namespace gl
 {
diff --git a/src/libANGLE/ResourceManager.cpp b/src/libANGLE/ResourceManager.cpp
index 58c204a..5c5d907 100644
--- a/src/libANGLE/ResourceManager.cpp
+++ b/src/libANGLE/ResourceManager.cpp
@@ -10,13 +10,13 @@
 #include "libANGLE/ResourceManager.h"
 
 #include "libANGLE/Buffer.h"
+#include "libANGLE/Fence.h"
 #include "libANGLE/Program.h"
 #include "libANGLE/Renderbuffer.h"
+#include "libANGLE/Sampler.h"
 #include "libANGLE/Shader.h"
 #include "libANGLE/Texture.h"
-#include "libANGLE/Sampler.h"
-#include "libANGLE/Fence.h"
-#include "libANGLE/renderer/Renderer.h"
+#include "libANGLE/renderer/GLImplFactory.h"
 
 namespace gl
 {
diff --git a/src/libANGLE/Shader.cpp b/src/libANGLE/Shader.cpp
index b481002..bf0f742 100644
--- a/src/libANGLE/Shader.cpp
+++ b/src/libANGLE/Shader.cpp
@@ -14,9 +14,10 @@
 
 #include "common/utilities.h"
 #include "GLSLANG/ShaderLang.h"
+#include "libANGLE/Caps.h"
 #include "libANGLE/Compiler.h"
 #include "libANGLE/Constants.h"
-#include "libANGLE/renderer/Renderer.h"
+#include "libANGLE/renderer/GLImplFactory.h"
 #include "libANGLE/renderer/ShaderImpl.h"
 #include "libANGLE/ResourceManager.h"
 
diff --git a/src/libANGLE/formatutils.cpp b/src/libANGLE/formatutils.cpp
index 3a4df12..c9b2aba 100644
--- a/src/libANGLE/formatutils.cpp
+++ b/src/libANGLE/formatutils.cpp
@@ -10,7 +10,6 @@
 #include "libANGLE/formatutils.h"
 #include "libANGLE/Context.h"
 #include "libANGLE/Framebuffer.h"
-#include "libANGLE/renderer/Renderer.h"
 
 namespace gl
 {
diff --git a/src/libANGLE/renderer/ContextImpl.cpp b/src/libANGLE/renderer/ContextImpl.cpp
new file mode 100644
index 0000000..e02b5a7
--- /dev/null
+++ b/src/libANGLE/renderer/ContextImpl.cpp
@@ -0,0 +1,23 @@
+//
+// Copyright 2016 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.
+//
+// ContextImpl:
+//   Implementation-specific functionality associated with a GL Context.
+//
+
+#include "libANGLE/renderer/ContextImpl.h"
+
+namespace rx
+{
+
+ContextImpl::ContextImpl(const gl::ContextState &state) : mState(state)
+{
+}
+
+ContextImpl::~ContextImpl()
+{
+}
+
+}  // namespace rx
diff --git a/src/libANGLE/renderer/ContextImpl.h b/src/libANGLE/renderer/ContextImpl.h
index 4acb643..3d1f3cc 100644
--- a/src/libANGLE/renderer/ContextImpl.h
+++ b/src/libANGLE/renderer/ContextImpl.h
@@ -12,19 +12,19 @@
 
 #include "common/angleutils.h"
 #include "libANGLE/ContextState.h"
+#include "libANGLE/renderer/GLImplFactory.h"
 
 namespace rx
 {
-class Renderer;
-
-class ContextImpl : angle::NonCopyable
+class ContextImpl : public GLImplFactory
 {
   public:
-    ContextImpl(const gl::ContextState &state) : mState(state) {}
-    virtual ~ContextImpl() {}
+    ContextImpl(const gl::ContextState &state);
+    virtual ~ContextImpl();
 
-    virtual gl::Error initialize(Renderer *renderer) = 0;
+    virtual gl::Error initialize() = 0;
 
+    const gl::ContextState &getContextState() { return mState; }
     int getClientVersion() const { return mState.clientVersion; }
     const gl::State &getState() const { return *mState.state; }
     const gl::Caps &getCaps() const { return *mState.caps; }
@@ -32,7 +32,68 @@
     const gl::Extensions &getExtensions() const { return *mState.extensions; }
     const gl::Limitations &getLimitations() const { return *mState.limitations; }
 
-  private:
+    // Flush and finish.
+    virtual gl::Error flush() = 0;
+    virtual gl::Error finish() = 0;
+
+    // Drawing methods.
+    virtual gl::Error drawArrays(GLenum mode, GLint first, GLsizei count) = 0;
+    virtual gl::Error drawArraysInstanced(GLenum mode,
+                                          GLint first,
+                                          GLsizei count,
+                                          GLsizei instanceCount) = 0;
+
+    virtual gl::Error drawElements(GLenum mode,
+                                   GLsizei count,
+                                   GLenum type,
+                                   const GLvoid *indices,
+                                   const gl::IndexRange &indexRange) = 0;
+    virtual gl::Error drawElementsInstanced(GLenum mode,
+                                            GLsizei count,
+                                            GLenum type,
+                                            const GLvoid *indices,
+                                            GLsizei instances,
+                                            const gl::IndexRange &indexRange) = 0;
+    virtual gl::Error drawRangeElements(GLenum mode,
+                                        GLuint start,
+                                        GLuint end,
+                                        GLsizei count,
+                                        GLenum type,
+                                        const GLvoid *indices,
+                                        const gl::IndexRange &indexRange) = 0;
+
+    // TODO(jmadill): Investigate proper impl methods for this.
+    virtual void notifyDeviceLost() = 0;
+    virtual bool isDeviceLost() const = 0;
+    virtual bool testDeviceLost() = 0;
+    virtual bool testDeviceResettable() = 0;
+
+    // Vendor and description strings.
+    virtual std::string getVendorString() const = 0;
+    virtual std::string getRendererDescription() const = 0;
+
+    // Debug markers.
+    virtual void insertEventMarker(GLsizei length, const char *marker) = 0;
+    virtual void pushGroupMarker(GLsizei length, const char *marker) = 0;
+    virtual void popGroupMarker() = 0;
+
+    // State sync with dirty bits.
+    virtual void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits) = 0;
+
+    // Disjoint timer queries
+    virtual GLint getGPUDisjoint() = 0;
+    virtual GLint64 getTimestamp() = 0;
+
+    // Context switching
+    virtual void onMakeCurrent(const gl::ContextState &data) = 0;
+
+    // Native capabilities, unmodified by gl::Context.
+    virtual const gl::Caps &getNativeCaps() const = 0;
+    virtual const gl::TextureCapsMap &getNativeTextureCaps() const = 0;
+    virtual const gl::Extensions &getNativeExtensions() const = 0;
+    virtual const gl::Limitations &getNativeLimitations() const = 0;
+
+  protected:
     const gl::ContextState &mState;
 };
 
diff --git a/src/libANGLE/renderer/DisplayImpl.h b/src/libANGLE/renderer/DisplayImpl.h
index ddbeba2..8ef47ed 100644
--- a/src/libANGLE/renderer/DisplayImpl.h
+++ b/src/libANGLE/renderer/DisplayImpl.h
@@ -14,7 +14,6 @@
 #include "libANGLE/Config.h"
 #include "libANGLE/Error.h"
 #include "libANGLE/renderer/EGLImplFactory.h"
-#include "libANGLE/renderer/Renderer.h"
 #include "libANGLE/Stream.h"
 
 #include <set>
diff --git a/src/libANGLE/renderer/EGLImplFactory.h b/src/libANGLE/renderer/EGLImplFactory.h
index bf73cdd..15b139c 100644
--- a/src/libANGLE/renderer/EGLImplFactory.h
+++ b/src/libANGLE/renderer/EGLImplFactory.h
@@ -22,10 +22,12 @@
 namespace gl
 {
 class Context;
+struct ContextState;
 }
 
 namespace rx
 {
+class ContextImpl;
 class ImageImpl;
 class SurfaceImpl;
 
@@ -51,9 +53,7 @@
                                    egl::ImageSibling *buffer,
                                    const egl::AttributeMap &attribs) = 0;
 
-    virtual gl::Context *createContext(const egl::Config *config,
-                                       const gl::Context *shareContext,
-                                       const egl::AttributeMap &attribs) = 0;
+    virtual ContextImpl *createContext(const gl::ContextState &state) = 0;
 
     virtual StreamProducerImpl *createStreamProducerD3DTextureNV12(
         egl::Stream::ConsumerType consumerType,
diff --git a/src/libANGLE/renderer/GLImplFactory.h b/src/libANGLE/renderer/GLImplFactory.h
index 1321c2f..adf8e42 100644
--- a/src/libANGLE/renderer/GLImplFactory.h
+++ b/src/libANGLE/renderer/GLImplFactory.h
@@ -43,9 +43,6 @@
     GLImplFactory() {}
     virtual ~GLImplFactory() {}
 
-    // Context creation
-    virtual ContextImpl *createContext(const gl::ContextState &state) = 0;
-
     // Shader creation
     virtual CompilerImpl *createCompiler() = 0;
     virtual ShaderImpl *createShader(const gl::ShaderState &data) = 0;
diff --git a/src/libANGLE/renderer/ProgramImpl.h b/src/libANGLE/renderer/ProgramImpl.h
index ee78b1c..12c4a3c 100644
--- a/src/libANGLE/renderer/ProgramImpl.h
+++ b/src/libANGLE/renderer/ProgramImpl.h
@@ -14,10 +14,14 @@
 #include "libANGLE/Constants.h"
 #include "libANGLE/Program.h"
 #include "libANGLE/Shader.h"
-#include "libANGLE/renderer/Renderer.h"
 
 #include <map>
 
+namespace sh
+{
+struct BlockMemberInfo;
+}
+
 namespace rx
 {
 
diff --git a/src/libANGLE/renderer/Renderer.cpp b/src/libANGLE/renderer/Renderer.cpp
deleted file mode 100644
index f3f7f55..0000000
--- a/src/libANGLE/renderer/Renderer.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-//
-// Copyright (c) 2012-2014 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.
-//
-
-// Renderer.cpp: Implements EGL dependencies for creating and destroying Renderer instances.
-
-#include "common/utilities.h"
-#include "libANGLE/AttributeMap.h"
-#include "libANGLE/renderer/Renderer.h"
-
-#include <EGL/eglext.h>
-
-namespace rx
-{
-Renderer::Renderer() : mCapsInitialized(false)
-{
-}
-
-Renderer::~Renderer()
-{
-}
-
-void Renderer::ensureCapsInitialized() const
-{
-    if (!mCapsInitialized)
-    {
-        generateCaps(&mCaps, &mTextureCaps, &mExtensions, &mLimitations);
-        mCapsInitialized = true;
-    }
-}
-
-const gl::Caps &Renderer::getRendererCaps() const
-{
-    ensureCapsInitialized();
-
-    return mCaps;
-}
-
-const gl::TextureCapsMap &Renderer::getRendererTextureCaps() const
-{
-    ensureCapsInitialized();
-
-    return mTextureCaps;
-}
-
-const gl::Extensions &Renderer::getRendererExtensions() const
-{
-    ensureCapsInitialized();
-
-    return mExtensions;
-}
-
-const gl::Limitations &Renderer::getRendererLimitations() const
-{
-    ensureCapsInitialized();
-
-    return mLimitations;
-}
-
-}
diff --git a/src/libANGLE/renderer/Renderer.h b/src/libANGLE/renderer/Renderer.h
deleted file mode 100644
index 5f16ffd..0000000
--- a/src/libANGLE/renderer/Renderer.h
+++ /dev/null
@@ -1,124 +0,0 @@
-//
-// Copyright (c) 2012-2014 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.
-//
-
-// Renderer.h: Defines a back-end specific class that hides the details of the
-// implementation-specific renderer.
-
-#ifndef LIBANGLE_RENDERER_RENDERER_H_
-#define LIBANGLE_RENDERER_RENDERER_H_
-
-#include "libANGLE/Caps.h"
-#include "libANGLE/Error.h"
-#include "libANGLE/Framebuffer.h"
-#include "libANGLE/State.h"
-#include "libANGLE/Uniform.h"
-#include "libANGLE/angletypes.h"
-#include "libANGLE/renderer/GLImplFactory.h"
-#include "common/mathutil.h"
-
-#include <stdint.h>
-
-#include <EGL/egl.h>
-
-namespace egl
-{
-class AttributeMap;
-class Display;
-class Surface;
-}
-
-namespace rx
-{
-struct TranslatedIndexData;
-struct SourceIndexData;
-struct WorkaroundsD3D;
-class DisplayImpl;
-
-class Renderer : public GLImplFactory
-{
-  public:
-    Renderer();
-    virtual ~Renderer();
-
-    virtual gl::Error flush() = 0;
-    virtual gl::Error finish() = 0;
-
-    virtual gl::Error drawArrays(const gl::ContextState &data,
-                                 GLenum mode,
-                                 GLint first,
-                                 GLsizei count) = 0;
-    virtual gl::Error drawArraysInstanced(const gl::ContextState &data,
-                                          GLenum mode,
-                                          GLint first,
-                                          GLsizei count,
-                                          GLsizei instanceCount) = 0;
-
-    virtual gl::Error drawElements(const gl::ContextState &data,
-                                   GLenum mode,
-                                   GLsizei count,
-                                   GLenum type,
-                                   const GLvoid *indices,
-                                   const gl::IndexRange &indexRange) = 0;
-    virtual gl::Error drawElementsInstanced(const gl::ContextState &data,
-                                            GLenum mode,
-                                            GLsizei count,
-                                            GLenum type,
-                                            const GLvoid *indices,
-                                            GLsizei instances,
-                                            const gl::IndexRange &indexRange) = 0;
-    virtual gl::Error drawRangeElements(const gl::ContextState &data,
-                                        GLenum mode,
-                                        GLuint start,
-                                        GLuint end,
-                                        GLsizei count,
-                                        GLenum type,
-                                        const GLvoid *indices,
-                                        const gl::IndexRange &indexRange) = 0;
-
-    // lost device
-    //TODO(jmadill): investigate if this stuff is necessary in GL
-    virtual void notifyDeviceLost() = 0;
-    virtual bool isDeviceLost() const = 0;
-    virtual bool testDeviceLost() = 0;
-    virtual bool testDeviceResettable() = 0;
-
-    virtual std::string getVendorString() const = 0;
-    virtual std::string getRendererDescription() const = 0;
-
-    virtual void insertEventMarker(GLsizei length, const char *marker) = 0;
-    virtual void pushGroupMarker(GLsizei length, const char *marker) = 0;
-    virtual void popGroupMarker() = 0;
-
-    virtual void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits) = 0;
-
-    // Disjoint timer queries
-    virtual GLint getGPUDisjoint() = 0;
-    virtual GLint64 getTimestamp() = 0;
-
-    // Context switching
-    virtual void onMakeCurrent(const gl::ContextState &data) = 0;
-
-    // Renderer capabilities
-    const gl::Caps &getRendererCaps() const;
-    const gl::TextureCapsMap &getRendererTextureCaps() const;
-    const gl::Extensions &getRendererExtensions() const;
-    const gl::Limitations &getRendererLimitations() const;
-
-  private:
-    void ensureCapsInitialized() const;
-    virtual void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap* outTextureCaps,
-                              gl::Extensions *outExtensions,
-                              gl::Limitations *outLimitations) const = 0;
-
-    mutable bool mCapsInitialized;
-    mutable gl::Caps mCaps;
-    mutable gl::TextureCapsMap mTextureCaps;
-    mutable gl::Extensions mExtensions;
-    mutable gl::Limitations mLimitations;
-};
-
-}
-#endif // LIBANGLE_RENDERER_RENDERER_H_
diff --git a/src/libANGLE/renderer/SurfaceImpl.cpp b/src/libANGLE/renderer/SurfaceImpl.cpp
index 36f5fdc..586ee1d 100644
--- a/src/libANGLE/renderer/SurfaceImpl.cpp
+++ b/src/libANGLE/renderer/SurfaceImpl.cpp
@@ -19,4 +19,4 @@
 {
 }
 
-}
+}  // namespace rx
diff --git a/src/libANGLE/renderer/d3d/DisplayD3D.cpp b/src/libANGLE/renderer/d3d/DisplayD3D.cpp
index 77a0115..1f66e10 100644
--- a/src/libANGLE/renderer/d3d/DisplayD3D.cpp
+++ b/src/libANGLE/renderer/d3d/DisplayD3D.cpp
@@ -206,12 +206,10 @@
     return mRenderer->getEGLDevice(device);
 }
 
-gl::Context *DisplayD3D::createContext(const egl::Config *config,
-                                       const gl::Context *shareContext,
-                                       const egl::AttributeMap &attribs)
+ContextImpl *DisplayD3D::createContext(const gl::ContextState &state)
 {
     ASSERT(mRenderer != nullptr);
-    return new gl::Context(config, shareContext, mRenderer, attribs);
+    return mRenderer->createContext(state);
 }
 
 StreamProducerImpl *DisplayD3D::createStreamProducerD3DTextureNV12(
@@ -231,12 +229,7 @@
 {
     ASSERT(mRenderer == nullptr && display != nullptr);
     mDisplay = display;
-    egl::Error error = CreateRendererD3D(display, &mRenderer);
-    if (error.isError())
-    {
-        return error;
-    }
-
+    ANGLE_TRY(CreateRendererD3D(display, &mRenderer));
     return egl::Error(EGL_SUCCESS);
 }
 
@@ -322,7 +315,7 @@
     // Display must be initialized to generate caps
     ASSERT(mRenderer != nullptr);
 
-    outCaps->textureNPOT = mRenderer->getRendererExtensions().textureNPOT;
+    outCaps->textureNPOT = mRenderer->getNativeExtensions().textureNPOT;
 }
 
 egl::Error DisplayD3D::waitClient() const
@@ -338,4 +331,4 @@
     // Unimplemented as it is a noop on D3D
     return egl::Error(EGL_SUCCESS);
 }
-}
+}  // namespace rx
diff --git a/src/libANGLE/renderer/d3d/DisplayD3D.h b/src/libANGLE/renderer/d3d/DisplayD3D.h
index ada29a3..8379814 100644
--- a/src/libANGLE/renderer/d3d/DisplayD3D.h
+++ b/src/libANGLE/renderer/d3d/DisplayD3D.h
@@ -41,9 +41,7 @@
                            egl::ImageSibling *buffer,
                            const egl::AttributeMap &attribs) override;
 
-    gl::Context *createContext(const egl::Config *config,
-                               const gl::Context *shareContext,
-                               const egl::AttributeMap &attribs) override;
+    ContextImpl *createContext(const gl::ContextState &state) override;
 
     StreamProducerImpl *createStreamProducerD3DTextureNV12(
         egl::Stream::ConsumerType consumerType,
diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.cpp b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
index 216e0db..027f7b7 100644
--- a/src/libANGLE/renderer/d3d/ProgramD3D.cpp
+++ b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
@@ -13,6 +13,7 @@
 #include "libANGLE/Framebuffer.h"
 #include "libANGLE/FramebufferAttachment.h"
 #include "libANGLE/Program.h"
+#include "libANGLE/Uniform.h"
 #include "libANGLE/VertexArray.h"
 #include "libANGLE/features.h"
 #include "libANGLE/renderer/d3d/DynamicHLSL.h"
@@ -1359,7 +1360,7 @@
     vertexShaderD3D->generateWorkarounds(&mVertexWorkarounds);
     fragmentShaderD3D->generateWorkarounds(&mPixelWorkarounds);
 
-    if (mRenderer->getRendererLimitations().noFrontFacingSupport)
+    if (mRenderer->getNativeLimitations().noFrontFacingSupport)
     {
         if (fragmentShaderD3D->usesFrontFacing())
         {
diff --git a/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp b/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp
index 991801a..9ad447f 100644
--- a/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp
+++ b/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp
@@ -48,7 +48,7 @@
     // the specified storage.
     // Because ES 3.0 already knows the exact number of supported samples, it would already have been
     // validated and generated GL_INVALID_VALUE.
-    const gl::TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(creationFormat);
+    const gl::TextureCaps &formatCaps = mRenderer->getNativeTextureCaps().get(creationFormat);
     if (samples > formatCaps.getMaxSamples())
     {
         return gl::Error(GL_OUT_OF_MEMORY, "Renderbuffer format does not support %u samples, %u is the maximum.",
diff --git a/src/libANGLE/renderer/d3d/RendererD3D.cpp b/src/libANGLE/renderer/d3d/RendererD3D.cpp
index 88745ce..b98fb47 100644
--- a/src/libANGLE/renderer/d3d/RendererD3D.cpp
+++ b/src/libANGLE/renderer/d3d/RendererD3D.cpp
@@ -43,6 +43,7 @@
       mDeviceLost(false),
       mAnnotator(nullptr),
       mPresentPathFastEnabled(false),
+      mCapsInitialized(false),
       mScratchMemoryBufferResetCounter(0),
       mWorkaroundsInitialized(false),
       mDisjoint(false)
@@ -70,149 +71,6 @@
     }
 }
 
-SamplerImpl *RendererD3D::createSampler()
-{
-    return new SamplerD3D();
-}
-
-gl::Error RendererD3D::drawArrays(const gl::ContextState &data,
-                                  GLenum mode,
-                                  GLint first,
-                                  GLsizei count)
-{
-    return genericDrawArrays(data, mode, first, count, 0);
-}
-
-gl::Error RendererD3D::drawArraysInstanced(const gl::ContextState &data,
-                                           GLenum mode,
-                                           GLint first,
-                                           GLsizei count,
-                                           GLsizei instanceCount)
-{
-    return genericDrawArrays(data, mode, first, count, instanceCount);
-}
-
-gl::Error RendererD3D::drawElements(const gl::ContextState &data,
-                                    GLenum mode,
-                                    GLsizei count,
-                                    GLenum type,
-                                    const GLvoid *indices,
-                                    const gl::IndexRange &indexRange)
-{
-    return genericDrawElements(data, mode, count, type, indices, 0, indexRange);
-}
-
-gl::Error RendererD3D::drawElementsInstanced(const gl::ContextState &data,
-                                             GLenum mode,
-                                             GLsizei count,
-                                             GLenum type,
-                                             const GLvoid *indices,
-                                             GLsizei instances,
-                                             const gl::IndexRange &indexRange)
-{
-    return genericDrawElements(data, mode, count, type, indices, instances, indexRange);
-}
-
-gl::Error RendererD3D::drawRangeElements(const gl::ContextState &data,
-                                         GLenum mode,
-                                         GLuint start,
-                                         GLuint end,
-                                         GLsizei count,
-                                         GLenum type,
-                                         const GLvoid *indices,
-                                         const gl::IndexRange &indexRange)
-{
-    return genericDrawElements(data, mode, count, type, indices, 0, indexRange);
-}
-
-gl::Error RendererD3D::genericDrawElements(const gl::ContextState &data,
-                                           GLenum mode,
-                                           GLsizei count,
-                                           GLenum type,
-                                           const GLvoid *indices,
-                                           GLsizei instances,
-                                           const gl::IndexRange &indexRange)
-{
-    gl::Program *program = data.state->getProgram();
-    ASSERT(program != nullptr);
-    ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
-    bool usesPointSize     = programD3D->usesPointSize();
-
-    programD3D->updateSamplerMapping();
-
-    ANGLE_TRY(generateSwizzles(data));
-
-    if (!applyPrimitiveType(mode, count, usesPointSize))
-    {
-        return gl::NoError();
-    }
-
-    ANGLE_TRY(updateState(data, mode));
-
-    TranslatedIndexData indexInfo;
-    indexInfo.indexRange = indexRange;
-
-    ANGLE_TRY(applyIndexBuffer(data, indices, count, mode, type, &indexInfo));
-
-    applyTransformFeedbackBuffers(*data.state);
-    // Transform feedback is not allowed for DrawElements, this error should have been caught at the API validation
-    // layer.
-    ASSERT(!data.state->isTransformFeedbackActiveUnpaused());
-
-    size_t vertexCount = indexInfo.indexRange.vertexCount();
-    ANGLE_TRY(applyVertexBuffer(*data.state, mode, static_cast<GLsizei>(indexInfo.indexRange.start),
-                                static_cast<GLsizei>(vertexCount), instances, &indexInfo));
-    ANGLE_TRY(applyTextures(data));
-    ANGLE_TRY(applyShaders(data, mode));
-    ANGLE_TRY(programD3D->applyUniformBuffers(data));
-
-    if (!skipDraw(data, mode))
-    {
-        ANGLE_TRY(drawElementsImpl(data, indexInfo, mode, count, type, indices, instances));
-    }
-
-    return gl::NoError();
-}
-
-gl::Error RendererD3D::genericDrawArrays(const gl::ContextState &data,
-                                         GLenum mode,
-                                         GLint first,
-                                         GLsizei count,
-                                         GLsizei instances)
-{
-    gl::Program *program = data.state->getProgram();
-    ASSERT(program != nullptr);
-    ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
-    bool usesPointSize     = programD3D->usesPointSize();
-
-    programD3D->updateSamplerMapping();
-
-    ANGLE_TRY(generateSwizzles(data));
-    if (!applyPrimitiveType(mode, count, usesPointSize))
-    {
-        return gl::NoError();
-    }
-
-    ANGLE_TRY(updateState(data, mode));
-    ANGLE_TRY(applyTransformFeedbackBuffers(*data.state));
-    ANGLE_TRY(applyVertexBuffer(*data.state, mode, first, count, instances, nullptr));
-    ANGLE_TRY(applyTextures(data));
-    ANGLE_TRY(applyShaders(data, mode));
-    ANGLE_TRY(programD3D->applyUniformBuffers(data));
-
-    if (!skipDraw(data, mode))
-    {
-        ANGLE_TRY(drawArraysImpl(data, mode, first, count, instances));
-
-        if (data.state->isTransformFeedbackActiveUnpaused())
-        {
-            ANGLE_TRY(markTransformFeedbackUsage(data));
-        }
-    }
-
-    return gl::NoError();
-}
-
 gl::Error RendererD3D::generateSwizzles(const gl::ContextState &data, gl::SamplerType type)
 {
     ProgramD3D *programD3D = GetImplAs<ProgramD3D>(data.state->getProgram());
@@ -296,7 +154,8 @@
 // looks up the corresponding OpenGL texture image unit and texture type,
 // and sets the texture and its addressing/filtering state (or NULL when inactive).
 // Sampler mapping needs to be up-to-date on the program object before this is called.
-gl::Error RendererD3D::applyTextures(const gl::ContextState &data,
+gl::Error RendererD3D::applyTextures(GLImplFactory *implFactory,
+                                     const gl::ContextState &data,
                                      gl::SamplerType shaderType,
                                      const FramebufferTextureArray &framebufferTextures,
                                      size_t framebufferTextureCount)
@@ -331,7 +190,7 @@
             else
             {
                 // Texture is not sampler complete or it is in use by the framebuffer.  Bind the incomplete texture.
-                gl::Texture *incompleteTexture = getIncompleteTexture(textureType);
+                gl::Texture *incompleteTexture = getIncompleteTexture(implFactory, textureType);
 
                 ANGLE_TRY(setSamplerState(shaderType, samplerIndex, incompleteTexture,
                                           incompleteTexture->getSamplerState()));
@@ -353,13 +212,15 @@
     return gl::NoError();
 }
 
-gl::Error RendererD3D::applyTextures(const gl::ContextState &data)
+gl::Error RendererD3D::applyTextures(GLImplFactory *implFactory, const gl::ContextState &data)
 {
     FramebufferTextureArray framebufferTextures;
     size_t framebufferSerialCount = getBoundFramebufferTextures(data, &framebufferTextures);
 
-    ANGLE_TRY(applyTextures(data, gl::SAMPLER_VERTEX, framebufferTextures, framebufferSerialCount));
-    ANGLE_TRY(applyTextures(data, gl::SAMPLER_PIXEL, framebufferTextures, framebufferSerialCount));
+    ANGLE_TRY(applyTextures(implFactory, data, gl::SAMPLER_VERTEX, framebufferTextures,
+                            framebufferSerialCount));
+    ANGLE_TRY(applyTextures(implFactory, data, gl::SAMPLER_PIXEL, framebufferTextures,
+                            framebufferSerialCount));
     return gl::NoError();
 }
 
@@ -437,7 +298,7 @@
     return textureCount;
 }
 
-gl::Texture *RendererD3D::getIncompleteTexture(GLenum type)
+gl::Texture *RendererD3D::getIncompleteTexture(GLImplFactory *implFactory, GLenum type)
 {
     if (mIncompleteTextures.find(type) == mIncompleteTextures.end())
     {
@@ -450,7 +311,8 @@
         GLenum createType = (type == GL_TEXTURE_EXTERNAL_OES) ? GL_TEXTURE_2D : type;
 
         // Skip the API layer to avoid needing to pass the Context and mess with dirty bits.
-        gl::Texture *t = new gl::Texture(this, std::numeric_limits<GLuint>::max(), createType);
+        gl::Texture *t =
+            new gl::Texture(implFactory, std::numeric_limits<GLuint>::max(), createType);
         t->setStorage(createType, 1, GL_RGBA8, colorSize);
         if (type == GL_TEXTURE_CUBE_MAP)
         {
@@ -574,10 +436,6 @@
     return 0;
 }
 
-void RendererD3D::onMakeCurrent(const gl::ContextState &data)
-{
-}
-
 void RendererD3D::initializeDebugAnnotator()
 {
     createAnnotator();
@@ -590,4 +448,38 @@
     ASSERT(mAnnotator);
     return mAnnotator;
 }
+
+void RendererD3D::ensureCapsInitialized() const
+{
+    if (!mCapsInitialized)
+    {
+        generateCaps(&mNativeCaps, &mNativeTextureCaps, &mNativeExtensions, &mNativeLimitations);
+        mCapsInitialized = true;
+    }
+}
+
+const gl::Caps &RendererD3D::getNativeCaps() const
+{
+    ensureCapsInitialized();
+    return mNativeCaps;
+}
+
+const gl::TextureCapsMap &RendererD3D::getNativeTextureCaps() const
+{
+    ensureCapsInitialized();
+    return mNativeTextureCaps;
+}
+
+const gl::Extensions &RendererD3D::getNativeExtensions() const
+{
+    ensureCapsInitialized();
+    return mNativeExtensions;
+}
+
+const gl::Limitations &RendererD3D::getNativeLimitations() const
+{
+    ensureCapsInitialized();
+    return mNativeLimitations;
+}
+
 }  // namespace rx
diff --git a/src/libANGLE/renderer/d3d/RendererD3D.h b/src/libANGLE/renderer/d3d/RendererD3D.h
index a4a5210..c227e25 100644
--- a/src/libANGLE/renderer/d3d/RendererD3D.h
+++ b/src/libANGLE/renderer/d3d/RendererD3D.h
@@ -14,7 +14,6 @@
 #include "libANGLE/ContextState.h"
 #include "libANGLE/Device.h"
 #include "libANGLE/formatutils.h"
-#include "libANGLE/renderer/Renderer.h"
 #include "libANGLE/renderer/d3d/VertexDataManager.h"
 #include "libANGLE/renderer/d3d/formatutilsD3D.h"
 #include "libANGLE/renderer/d3d/WorkaroundsD3D.h"
@@ -30,6 +29,7 @@
 namespace gl
 {
 class DebugAnnotator;
+class FramebufferState;
 class InfoLog;
 class Texture;
 struct LinkedVarying;
@@ -37,10 +37,12 @@
 
 namespace rx
 {
+class ContextImpl;
 struct D3DUniform;
 struct D3DVarying;
 class DeviceD3D;
 class EGLImageD3D;
+class FramebufferImpl;
 class ImageD3D;
 class IndexBuffer;
 class NativeWindowD3D;
@@ -49,6 +51,7 @@
 class ShaderExecutableD3D;
 class SwapChainD3D;
 class TextureStorage;
+struct TranslatedIndexData;
 class UniformStorageD3D;
 class VertexBuffer;
 
@@ -76,7 +79,7 @@
 };
 
 // Useful for unit testing
-class BufferFactoryD3D
+class BufferFactoryD3D : angle::NonCopyable
 {
   public:
     BufferFactoryD3D() {}
@@ -96,7 +99,7 @@
 
 using AttribIndexArray = std::array<int, gl::MAX_VERTEX_ATTRIBS>;
 
-class RendererD3D : public Renderer, public BufferFactoryD3D
+class RendererD3D : public BufferFactoryD3D
 {
   public:
     explicit RendererD3D(egl::Display *display);
@@ -107,42 +110,11 @@
     virtual egl::ConfigSet generateConfigs() const = 0;
     virtual void generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const = 0;
 
-    gl::Error drawArrays(const gl::ContextState &data,
-                         GLenum mode,
-                         GLint first,
-                         GLsizei count) override;
-    gl::Error drawArraysInstanced(const gl::ContextState &data,
-                                  GLenum mode,
-                                  GLint first,
-                                  GLsizei count,
-                                  GLsizei instanceCount) override;
+    virtual ContextImpl *createContext(const gl::ContextState &state) = 0;
 
-    gl::Error drawElements(const gl::ContextState &data,
-                           GLenum mode,
-                           GLsizei count,
-                           GLenum type,
-                           const GLvoid *indices,
-                           const gl::IndexRange &indexRange) override;
-    gl::Error drawElementsInstanced(const gl::ContextState &data,
-                                    GLenum mode,
-                                    GLsizei count,
-                                    GLenum type,
-                                    const GLvoid *indices,
-                                    GLsizei instances,
-                                    const gl::IndexRange &indexRange) override;
-    gl::Error drawRangeElements(const gl::ContextState &data,
-                                GLenum mode,
-                                GLuint start,
-                                GLuint end,
-                                GLsizei count,
-                                GLenum type,
-                                const GLvoid *indices,
-                                const gl::IndexRange &indexRange) override;
-
-    bool isDeviceLost() const override;
-    std::string getVendorString() const override;
-
-    SamplerImpl *createSampler() override;
+    bool isDeviceLost() const;
+    virtual bool testDeviceLost() = 0;
+    std::string getVendorString() const;
 
     virtual int getMinorShaderModel() const = 0;
     virtual std::string getShaderModelSuffix() const = 0;
@@ -169,26 +141,9 @@
                                         const std::vector<GLint> &vertexUniformBuffers,
                                         const std::vector<GLint> &fragmentUniformBuffers) = 0;
 
-    virtual gl::Error updateState(const gl::ContextState &data, GLenum drawMode) = 0;
-
-    virtual gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) = 0;
     virtual gl::Error applyUniforms(const ProgramD3D &programD3D,
                                     GLenum drawMode,
                                     const std::vector<D3DUniform *> &uniformArray) = 0;
-    virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize) = 0;
-    virtual gl::Error applyVertexBuffer(const gl::State &state,
-                                        GLenum mode,
-                                        GLint first,
-                                        GLsizei count,
-                                        GLsizei instances,
-                                        TranslatedIndexData *indexInfo) = 0;
-    virtual gl::Error applyIndexBuffer(const gl::ContextState &data,
-                                       const GLvoid *indices,
-                                       GLsizei count,
-                                       GLenum mode,
-                                       GLenum type,
-                                       TranslatedIndexData *indexInfo) = 0;
-    virtual gl::Error applyTransformFeedbackBuffers(const gl::State &state) = 0;
 
     virtual unsigned int getReservedVertexUniformVectors() const = 0;
     virtual unsigned int getReservedFragmentUniformVectors() const = 0;
@@ -250,7 +205,7 @@
                                               GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) = 0;
 
     // Device lost
-    void notifyDeviceLost() override;
+    void notifyDeviceLost();
     virtual bool resetDevice() = 0;
     virtual RendererClass getRendererClass() const = 0;
     virtual void *getD3DDevice() = 0;
@@ -258,16 +213,14 @@
     gl::Error getScratchMemoryBuffer(size_t requestedSize, MemoryBuffer **bufferOut);
 
     // EXT_debug_marker
-    void insertEventMarker(GLsizei length, const char *marker) override;
-    void pushGroupMarker(GLsizei length, const char *marker) override;
-    void popGroupMarker() override;
+    void insertEventMarker(GLsizei length, const char *marker);
+    void pushGroupMarker(GLsizei length, const char *marker);
+    void popGroupMarker();
 
     void setGPUDisjoint();
 
-    GLint getGPUDisjoint() override;
-    GLint64 getTimestamp() override;
-
-    void onMakeCurrent(const gl::ContextState &data) override;
+    GLint getGPUDisjoint();
+    GLint64 getTimestamp();
 
     // In D3D11, faster than calling setTexture a jillion times
     virtual gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd) = 0;
@@ -281,9 +234,21 @@
         egl::Stream::ConsumerType consumerType,
         const egl::AttributeMap &attribs) = 0;
 
+    const gl::Caps &getNativeCaps() const;
+    const gl::TextureCapsMap &getNativeTextureCaps() const;
+    const gl::Extensions &getNativeExtensions() const;
+    const gl::Limitations &getNativeLimitations() const;
+
+    // Necessary hack for default framebuffers in D3D.
+    virtual FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) = 0;
+
   protected:
     virtual bool getLUID(LUID *adapterLuid) const = 0;
     virtual gl::Error applyShadersImpl(const gl::ContextState &data, GLenum drawMode) = 0;
+    virtual void generateCaps(gl::Caps *outCaps,
+                              gl::TextureCapsMap *outTextureCaps,
+                              gl::Extensions *outExtensions,
+                              gl::Limitations *outLimitations) const = 0;
 
     void cleanup();
 
@@ -292,6 +257,12 @@
     static unsigned int GetBlendSampleMask(const gl::ContextState &data, int samples);
     // dirtyPointer is a special value that will make the comparison with any valid pointer fail and force the renderer to re-apply the state.
 
+    gl::Error generateSwizzles(const gl::ContextState &data);
+    gl::Error applyShaders(const gl::ContextState &data, GLenum drawMode);
+    gl::Error applyTextures(GLImplFactory *implFactory, const gl::ContextState &data);
+    bool skipDraw(const gl::ContextState &data, GLenum drawMode);
+    gl::Error markTransformFeedbackUsage(const gl::ContextState &data);
+
     egl::Display *mDisplay;
     bool mDeviceLost;
 
@@ -301,19 +272,7 @@
     bool mPresentPathFastEnabled;
 
   private:
-    gl::Error genericDrawArrays(const gl::ContextState &data,
-                                GLenum mode,
-                                GLint first,
-                                GLsizei count,
-                                GLsizei instances);
-
-    gl::Error genericDrawElements(const gl::ContextState &data,
-                                  GLenum mode,
-                                  GLsizei count,
-                                  GLenum type,
-                                  const GLvoid *indices,
-                                  GLsizei instances,
-                                  const gl::IndexRange &indexRange);
+    void ensureCapsInitialized() const;
 
     virtual gl::Error drawArraysImpl(const gl::ContextState &data,
                                      GLenum mode,
@@ -328,31 +287,31 @@
                                        const GLvoid *indices,
                                        GLsizei instances) = 0;
 
-    //FIXME(jmadill): std::array is currently prohibited by Chromium style guide
     typedef std::array<gl::Texture*, gl::IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS> FramebufferTextureArray;
 
     gl::Error generateSwizzles(const gl::ContextState &data, gl::SamplerType type);
-    gl::Error generateSwizzles(const gl::ContextState &data);
 
     gl::Error applyState(const gl::ContextState &data, GLenum drawMode);
-    gl::Error applyShaders(const gl::ContextState &data, GLenum drawMode);
-    gl::Error applyTextures(const gl::ContextState &data,
+    gl::Error applyTextures(GLImplFactory *implFactory,
+                            const gl::ContextState &data,
                             gl::SamplerType shaderType,
                             const FramebufferTextureArray &framebufferTextures,
                             size_t framebufferTextureCount);
-    gl::Error applyTextures(const gl::ContextState &data);
-
-    bool skipDraw(const gl::ContextState &data, GLenum drawMode);
-    gl::Error markTransformFeedbackUsage(const gl::ContextState &data);
 
     size_t getBoundFramebufferTextures(const gl::ContextState &data,
                                        FramebufferTextureArray *outTextureArray);
-    gl::Texture *getIncompleteTexture(GLenum type);
+    gl::Texture *getIncompleteTexture(GLImplFactory *implFactory, GLenum type);
 
     gl::DebugAnnotator *getAnnotator();
 
     virtual WorkaroundsD3D generateWorkarounds() const = 0;
 
+    mutable bool mCapsInitialized;
+    mutable gl::Caps mNativeCaps;
+    mutable gl::TextureCapsMap mNativeTextureCaps;
+    mutable gl::Extensions mNativeExtensions;
+    mutable gl::Limitations mNativeLimitations;
+
     gl::TextureMap mIncompleteTextures;
     MemoryBuffer mScratchMemoryBuffer;
     unsigned int mScratchMemoryBufferResetCounter;
@@ -363,6 +322,6 @@
     bool mDisjoint;
 };
 
-}
+}  // namespace rx
 
 #endif // LIBANGLE_RENDERER_D3D_RENDERERD3D_H_
diff --git a/src/libANGLE/renderer/d3d/SurfaceD3D.cpp b/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
index 74b9cd7..e21d631 100644
--- a/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
+++ b/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
@@ -101,7 +101,7 @@
 
 FramebufferImpl *SurfaceD3D::createDefaultFramebuffer(const gl::FramebufferState &data)
 {
-    return mRenderer->createFramebuffer(data);
+    return mRenderer->createDefaultFramebuffer(data);
 }
 
 egl::Error SurfaceD3D::bindTexImage(gl::Texture *, EGLint)
diff --git a/src/libANGLE/renderer/d3d/TextureD3D.cpp b/src/libANGLE/renderer/d3d/TextureD3D.cpp
index 6925fb8..728bc9b 100644
--- a/src/libANGLE/renderer/d3d/TextureD3D.cpp
+++ b/src/libANGLE/renderer/d3d/TextureD3D.cpp
@@ -362,7 +362,8 @@
 
 GLint TextureD3D::creationLevels(GLsizei width, GLsizei height, GLsizei depth) const
 {
-    if ((gl::isPow2(width) && gl::isPow2(height) && gl::isPow2(depth)) || mRenderer->getRendererExtensions().textureNPOT)
+    if ((gl::isPow2(width) && gl::isPow2(height) && gl::isPow2(depth)) ||
+        mRenderer->getNativeExtensions().textureNPOT)
     {
         // Maximum number of levels
         return gl::log2(std::max(std::max(width, height), depth)) + 1;
diff --git a/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp b/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp
index 0598fb1..b908b98 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp
@@ -289,7 +289,7 @@
     vbDesc.ByteWidth =
         static_cast<unsigned int>(std::max(sizeof(d3d11::PositionLayerTexCoord3DVertex),
                                            sizeof(d3d11::PositionTexCoordVertex)) *
-                                  6 * mRenderer->getRendererCaps().max3DTextureSize);
+                                  6 * mRenderer->getNativeCaps().max3DTextureSize);
     vbDesc.Usage = D3D11_USAGE_DYNAMIC;
     vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
     vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
diff --git a/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp b/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp
index 0f1c1e7..c360383 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp
@@ -1070,7 +1070,7 @@
             bufferDesc->ByteWidth = roundUp(bufferDesc->ByteWidth, 16u);
             bufferDesc->ByteWidth =
                 std::min<UINT>(bufferDesc->ByteWidth,
-                               static_cast<UINT>(renderer->getRendererCaps().maxUniformBlockSize));
+                               static_cast<UINT>(renderer->getNativeCaps().maxUniformBlockSize));
             break;
 
         default:
diff --git a/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp b/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp
index 790b90b..369797a 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp
@@ -435,7 +435,7 @@
         // be a compatible clear type.
 
         // Bind all the render targets which need clearing
-        ASSERT(maskedClearRenderTargets.size() <= mRenderer->getRendererCaps().maxDrawBuffers);
+        ASSERT(maskedClearRenderTargets.size() <= mRenderer->getNativeCaps().maxDrawBuffers);
         std::vector<ID3D11RenderTargetView*> rtvs(maskedClearRenderTargets.size());
         for (unsigned int i = 0; i < maskedClearRenderTargets.size(); i++)
         {
diff --git a/src/libANGLE/renderer/d3d/d3d11/Context11.cpp b/src/libANGLE/renderer/d3d/d3d11/Context11.cpp
new file mode 100644
index 0000000..800eedf
--- /dev/null
+++ b/src/libANGLE/renderer/d3d/d3d11/Context11.cpp
@@ -0,0 +1,271 @@
+//
+// Copyright 2016 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.
+//
+// Context11:
+//   D3D11-specific functionality associated with a GL Context.
+//
+
+#include "libANGLE/renderer/d3d/d3d11/Context11.h"
+
+#include "libANGLE/renderer/d3d/CompilerD3D.h"
+#include "libANGLE/renderer/d3d/ShaderD3D.h"
+#include "libANGLE/renderer/d3d/ProgramD3D.h"
+#include "libANGLE/renderer/d3d/RenderbufferD3D.h"
+#include "libANGLE/renderer/d3d/SamplerD3D.h"
+#include "libANGLE/renderer/d3d/TextureD3D.h"
+#include "libANGLE/renderer/d3d/TransformFeedbackD3D.h"
+#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
+#include "libANGLE/renderer/d3d/d3d11/Fence11.h"
+#include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/StateManager11.h"
+#include "libANGLE/renderer/d3d/d3d11/VertexArray11.h"
+
+namespace rx
+{
+
+Context11::Context11(const gl::ContextState &state, Renderer11 *renderer)
+    : ContextImpl(state), mRenderer(renderer)
+{
+}
+
+Context11::~Context11()
+{
+}
+
+gl::Error Context11::initialize()
+{
+    return gl::NoError();
+}
+
+CompilerImpl *Context11::createCompiler()
+{
+    if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
+    {
+        return new CompilerD3D(SH_HLSL_4_0_FL9_3_OUTPUT);
+    }
+    else
+    {
+        return new CompilerD3D(SH_HLSL_4_1_OUTPUT);
+    }
+}
+
+ShaderImpl *Context11::createShader(const gl::ShaderState &data)
+{
+    return new ShaderD3D(data);
+}
+
+ProgramImpl *Context11::createProgram(const gl::ProgramState &data)
+{
+    return new ProgramD3D(data, mRenderer);
+}
+
+FramebufferImpl *Context11::createFramebuffer(const gl::FramebufferState &data)
+{
+    return new Framebuffer11(data, mRenderer);
+}
+
+TextureImpl *Context11::createTexture(const gl::TextureState &state)
+{
+    switch (state.target)
+    {
+        case GL_TEXTURE_2D:
+            return new TextureD3D_2D(state, mRenderer);
+        case GL_TEXTURE_CUBE_MAP:
+            return new TextureD3D_Cube(state, mRenderer);
+        case GL_TEXTURE_3D:
+            return new TextureD3D_3D(state, mRenderer);
+        case GL_TEXTURE_2D_ARRAY:
+            return new TextureD3D_2DArray(state, mRenderer);
+        case GL_TEXTURE_EXTERNAL_OES:
+            return new TextureD3D_External(state, mRenderer);
+        default:
+            UNREACHABLE();
+    }
+
+    return nullptr;
+}
+
+RenderbufferImpl *Context11::createRenderbuffer()
+{
+    return new RenderbufferD3D(mRenderer);
+}
+
+BufferImpl *Context11::createBuffer()
+{
+    Buffer11 *buffer = new Buffer11(mRenderer);
+    mRenderer->onBufferCreate(buffer);
+    return buffer;
+}
+
+VertexArrayImpl *Context11::createVertexArray(const gl::VertexArrayState &data)
+{
+    return new VertexArray11(data);
+}
+
+QueryImpl *Context11::createQuery(GLenum type)
+{
+    return new Query11(mRenderer, type);
+}
+
+FenceNVImpl *Context11::createFenceNV()
+{
+    return new FenceNV11(mRenderer);
+}
+
+FenceSyncImpl *Context11::createFenceSync()
+{
+    return new FenceSync11(mRenderer);
+}
+
+TransformFeedbackImpl *Context11::createTransformFeedback()
+{
+    return new TransformFeedbackD3D();
+}
+
+SamplerImpl *Context11::createSampler()
+{
+    return new SamplerD3D();
+}
+
+gl::Error Context11::flush()
+{
+    return mRenderer->flush();
+}
+
+gl::Error Context11::finish()
+{
+    return mRenderer->finish();
+}
+
+gl::Error Context11::drawArrays(GLenum mode, GLint first, GLsizei count)
+{
+    return mRenderer->genericDrawArrays(this, mode, first, count, 0);
+}
+
+gl::Error Context11::drawArraysInstanced(GLenum mode,
+                                         GLint first,
+                                         GLsizei count,
+                                         GLsizei instanceCount)
+{
+    return mRenderer->genericDrawArrays(this, mode, first, count, instanceCount);
+}
+
+gl::Error Context11::drawElements(GLenum mode,
+                                  GLsizei count,
+                                  GLenum type,
+                                  const GLvoid *indices,
+                                  const gl::IndexRange &indexRange)
+{
+    return mRenderer->genericDrawElements(this, mode, count, type, indices, 0, indexRange);
+}
+
+gl::Error Context11::drawElementsInstanced(GLenum mode,
+                                           GLsizei count,
+                                           GLenum type,
+                                           const GLvoid *indices,
+                                           GLsizei instances,
+                                           const gl::IndexRange &indexRange)
+{
+    return mRenderer->genericDrawElements(this, mode, count, type, indices, instances, indexRange);
+}
+
+gl::Error Context11::drawRangeElements(GLenum mode,
+                                       GLuint start,
+                                       GLuint end,
+                                       GLsizei count,
+                                       GLenum type,
+                                       const GLvoid *indices,
+                                       const gl::IndexRange &indexRange)
+{
+    return mRenderer->genericDrawElements(this, mode, count, type, indices, 0, indexRange);
+}
+
+void Context11::notifyDeviceLost()
+{
+    mRenderer->notifyDeviceLost();
+}
+
+bool Context11::isDeviceLost() const
+{
+    return mRenderer->isDeviceLost();
+}
+
+bool Context11::testDeviceLost()
+{
+    return mRenderer->testDeviceLost();
+}
+
+bool Context11::testDeviceResettable()
+{
+    return mRenderer->testDeviceResettable();
+}
+
+std::string Context11::getVendorString() const
+{
+    return mRenderer->getVendorString();
+}
+
+std::string Context11::getRendererDescription() const
+{
+    return mRenderer->getRendererDescription();
+}
+
+void Context11::insertEventMarker(GLsizei length, const char *marker)
+{
+    mRenderer->insertEventMarker(length, marker);
+}
+
+void Context11::pushGroupMarker(GLsizei length, const char *marker)
+{
+    mRenderer->pushGroupMarker(length, marker);
+}
+
+void Context11::popGroupMarker()
+{
+    mRenderer->popGroupMarker();
+}
+
+void Context11::syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits)
+{
+    mRenderer->getStateManager()->syncState(state, dirtyBits);
+}
+
+GLint Context11::getGPUDisjoint()
+{
+    return mRenderer->getGPUDisjoint();
+}
+
+GLint64 Context11::getTimestamp()
+{
+    return mRenderer->getTimestamp();
+}
+
+void Context11::onMakeCurrent(const gl::ContextState &data)
+{
+    mRenderer->getStateManager()->onMakeCurrent(data);
+}
+
+const gl::Caps &Context11::getNativeCaps() const
+{
+    return mRenderer->getNativeCaps();
+}
+
+const gl::TextureCapsMap &Context11::getNativeTextureCaps() const
+{
+    return mRenderer->getNativeTextureCaps();
+}
+
+const gl::Extensions &Context11::getNativeExtensions() const
+{
+    return mRenderer->getNativeExtensions();
+}
+
+const gl::Limitations &Context11::getNativeLimitations() const
+{
+    return mRenderer->getNativeLimitations();
+}
+
+}  // namespace rx
diff --git a/src/libANGLE/renderer/d3d/d3d11/Context11.h b/src/libANGLE/renderer/d3d/d3d11/Context11.h
index 141cf39..2ee3576 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Context11.h
+++ b/src/libANGLE/renderer/d3d/d3d11/Context11.h
@@ -14,14 +14,112 @@
 
 namespace rx
 {
+class Renderer11;
 
 class Context11 : public ContextImpl
 {
   public:
-    Context11(const gl::ContextState &state) : ContextImpl(state) {}
-    ~Context11() override {}
+    Context11(const gl::ContextState &state, Renderer11 *renderer);
+    ~Context11() override;
 
-    gl::Error initialize(Renderer *renderer) override { return gl::NoError(); }
+    gl::Error initialize() override;
+
+    // Shader creation
+    CompilerImpl *createCompiler() override;
+    ShaderImpl *createShader(const gl::ShaderState &data) override;
+    ProgramImpl *createProgram(const gl::ProgramState &data) override;
+
+    // Framebuffer creation
+    FramebufferImpl *createFramebuffer(const gl::FramebufferState &data) override;
+
+    // Texture creation
+    TextureImpl *createTexture(const gl::TextureState &state) override;
+
+    // Renderbuffer creation
+    RenderbufferImpl *createRenderbuffer() override;
+
+    // Buffer creation
+    BufferImpl *createBuffer() override;
+
+    // Vertex Array creation
+    VertexArrayImpl *createVertexArray(const gl::VertexArrayState &data) override;
+
+    // Query and Fence creation
+    QueryImpl *createQuery(GLenum type) override;
+    FenceNVImpl *createFenceNV() override;
+    FenceSyncImpl *createFenceSync() override;
+
+    // Transform Feedback creation
+    TransformFeedbackImpl *createTransformFeedback() override;
+
+    // Sampler object creation
+    SamplerImpl *createSampler() override;
+
+    // Flush and finish.
+    gl::Error flush() override;
+    gl::Error finish() override;
+
+    // Drawing methods.
+    gl::Error drawArrays(GLenum mode, GLint first, GLsizei count) override;
+    gl::Error drawArraysInstanced(GLenum mode,
+                                  GLint first,
+                                  GLsizei count,
+                                  GLsizei instanceCount) override;
+
+    gl::Error drawElements(GLenum mode,
+                           GLsizei count,
+                           GLenum type,
+                           const GLvoid *indices,
+                           const gl::IndexRange &indexRange) override;
+    gl::Error drawElementsInstanced(GLenum mode,
+                                    GLsizei count,
+                                    GLenum type,
+                                    const GLvoid *indices,
+                                    GLsizei instances,
+                                    const gl::IndexRange &indexRange) override;
+    gl::Error drawRangeElements(GLenum mode,
+                                GLuint start,
+                                GLuint end,
+                                GLsizei count,
+                                GLenum type,
+                                const GLvoid *indices,
+                                const gl::IndexRange &indexRange) override;
+
+    // TODO(jmadill): Investigate proper impl methods for this.
+    void notifyDeviceLost() override;
+    bool isDeviceLost() const override;
+    bool testDeviceLost() override;
+    bool testDeviceResettable() override;
+
+    // Vendor and description strings.
+    std::string getVendorString() const override;
+    std::string getRendererDescription() const override;
+
+    // Debug markers.
+    void insertEventMarker(GLsizei length, const char *marker) override;
+    void pushGroupMarker(GLsizei length, const char *marker) override;
+    void popGroupMarker() override;
+
+    // State sync with dirty bits.
+    void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits) override;
+
+    // Disjoint timer queries
+    GLint getGPUDisjoint() override;
+    GLint64 getTimestamp() override;
+
+    // Context switching
+    void onMakeCurrent(const gl::ContextState &data) override;
+
+    // Caps queries
+    const gl::Caps &getNativeCaps() const override;
+    const gl::TextureCapsMap &getNativeTextureCaps() const override;
+    const gl::Extensions &getNativeExtensions() const override;
+    const gl::Limitations &getNativeLimitations() const override;
+
+    Renderer11 *getRenderer() const { return mRenderer; }
+
+  private:
+    Renderer11 *mRenderer;
 };
 
 }  // namespace rx
diff --git a/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp b/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
index 02ae26d..89d5dc6 100644
--- a/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
@@ -13,6 +13,7 @@
 #include "common/utilities.h"
 #include "libANGLE/Program.h"
 #include "libANGLE/VertexAttribute.h"
+#include "libANGLE/VertexArray.h"
 #include "libANGLE/renderer/d3d/IndexDataManager.h"
 #include "libANGLE/renderer/d3d/ProgramD3D.h"
 #include "libANGLE/renderer/d3d/VertexDataManager.h"
diff --git a/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
index ff38f11..5b7988b 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
@@ -825,7 +825,7 @@
     ASSERT(!mPixelTransfer);
     mPixelTransfer = new PixelTransfer11(this);
 
-    const gl::Caps &rendererCaps = getRendererCaps();
+    const gl::Caps &rendererCaps = getNativeCaps();
 
     mStateManager.initialize(rendererCaps);
 
@@ -926,8 +926,8 @@
         GL_DEPTH_COMPONENT16,
     };
 
-    const gl::Caps &rendererCaps = getRendererCaps();
-    const gl::TextureCapsMap &rendererTextureCaps = getRendererTextureCaps();
+    const gl::Caps &rendererCaps                  = getNativeCaps();
+    const gl::TextureCapsMap &rendererTextureCaps = getNativeTextureCaps();
 
     const EGLint optimalSurfaceOrientation =
         mPresentPathFastEnabled ? 0 : EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE;
@@ -1144,23 +1144,6 @@
                            depthBufferFormat, orientation);
 }
 
-ContextImpl *Renderer11::createContext(const gl::ContextState &state)
-{
-    return new Context11(state);
-}
-
-CompilerImpl *Renderer11::createCompiler()
-{
-    if (mRenderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3)
-    {
-        return new CompilerD3D(SH_HLSL_4_0_FL9_3_OUTPUT);
-    }
-    else
-    {
-        return new CompilerD3D(SH_HLSL_4_1_OUTPUT);
-    }
-}
-
 void *Renderer11::getD3DDevice()
 {
     return reinterpret_cast<void*>(mDevice);
@@ -1222,7 +1205,7 @@
 
     if (type == gl::SAMPLER_PIXEL)
     {
-        ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxTextureImageUnits);
+        ASSERT(static_cast<unsigned int>(index) < getNativeCaps().maxTextureImageUnits);
 
         if (mForceSetPixelSamplerStates[index] ||
             memcmp(&samplerState, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0)
@@ -1246,7 +1229,7 @@
     }
     else if (type == gl::SAMPLER_VERTEX)
     {
-        ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxVertexTextureImageUnits);
+        ASSERT(static_cast<unsigned int>(index) < getNativeCaps().maxVertexTextureImageUnits);
 
         if (mForceSetVertexSamplerStates[index] ||
             memcmp(&samplerState, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0)
@@ -1305,8 +1288,10 @@
         textureImpl->resetDirty();
     }
 
-    ASSERT((type == gl::SAMPLER_PIXEL && static_cast<unsigned int>(index) < getRendererCaps().maxTextureImageUnits) ||
-           (type == gl::SAMPLER_VERTEX && static_cast<unsigned int>(index) < getRendererCaps().maxVertexTextureImageUnits));
+    ASSERT((type == gl::SAMPLER_PIXEL &&
+            static_cast<unsigned int>(index) < getNativeCaps().maxTextureImageUnits) ||
+           (type == gl::SAMPLER_VERTEX &&
+            static_cast<unsigned int>(index) < getNativeCaps().maxVertexTextureImageUnits));
 
     mStateManager.setShaderResource(type, index, textureSRV);
 
@@ -1515,11 +1500,6 @@
     return error;
 }
 
-void Renderer11::syncState(const gl::State &state, const gl::State::DirtyBits &bitmask)
-{
-    mStateManager.syncState(state, bitmask);
-}
-
 bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSize)
 {
     D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
@@ -2821,7 +2801,7 @@
 
     // We only currently support share handles with BGRA surfaces, because
     // chrome needs BGRA. Once chrome fixes this, we should always support them.
-    if (!getRendererExtensions().textureFormatBGRA8888)
+    if (!getNativeExtensions().textureFormatBGRA8888)
     {
         mSupportsShareHandles = false;
         return false;
@@ -3166,7 +3146,7 @@
 {
     const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(format, mRenderer11DeviceCaps);
 
-    const gl::TextureCaps &textureCaps = getRendererTextureCaps().get(format);
+    const gl::TextureCaps &textureCaps = getNativeTextureCaps().get(format);
     GLuint supportedSamples = textureCaps.getNearestSamples(samples);
 
     if (width > 0 && height > 0)
@@ -3357,21 +3337,6 @@
     return gl::Error(GL_NO_ERROR);
 }
 
-FramebufferImpl *Renderer11::createFramebuffer(const gl::FramebufferState &data)
-{
-    return new Framebuffer11(data, this);
-}
-
-ShaderImpl *Renderer11::createShader(const gl::ShaderState &data)
-{
-    return new ShaderD3D(data);
-}
-
-ProgramImpl *Renderer11::createProgram(const gl::ProgramState &data)
-{
-    return new ProgramD3D(data, this);
-}
-
 gl::Error Renderer11::loadExecutable(const void *function,
                                      size_t length,
                                      ShaderType type,
@@ -3568,38 +3533,6 @@
     return new IndexBuffer11(this);
 }
 
-BufferImpl *Renderer11::createBuffer()
-{
-    Buffer11 *buffer = new Buffer11(this);
-    mAliveBuffers.insert(buffer);
-    return buffer;
-}
-
-VertexArrayImpl *Renderer11::createVertexArray(const gl::VertexArrayState &data)
-{
-    return new VertexArray11(data);
-}
-
-QueryImpl *Renderer11::createQuery(GLenum type)
-{
-    return new Query11(this, type);
-}
-
-FenceNVImpl *Renderer11::createFenceNV()
-{
-    return new FenceNV11(this);
-}
-
-FenceSyncImpl *Renderer11::createFenceSync()
-{
-    return new FenceSync11(this);
-}
-
-TransformFeedbackImpl* Renderer11::createTransformFeedback()
-{
-    return new TransformFeedbackD3D();
-}
-
 StreamProducerImpl *Renderer11::createStreamProducerD3DTextureNV12(
     egl::Stream::ConsumerType consumerType,
     const egl::AttributeMap &attribs)
@@ -3609,7 +3542,7 @@
 
 bool Renderer11::supportsFastCopyBufferToTexture(GLenum internalFormat) const
 {
-    ASSERT(getRendererExtensions().pixelBufferObject);
+    ASSERT(getNativeExtensions().pixelBufferObject);
 
     const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat);
     const d3d11::TextureFormat &d3d11FormatInfo = d3d11::GetTextureFormatInfo(internalFormat, mRenderer11DeviceCaps);
@@ -3725,33 +3658,6 @@
     return new TextureStorage11_2DArray(this, internalformat, renderTarget, width, height, depth, levels);
 }
 
-TextureImpl *Renderer11::createTexture(const gl::TextureState &state)
-{
-    switch (state.target)
-    {
-        case GL_TEXTURE_2D:
-            return new TextureD3D_2D(state, this);
-        case GL_TEXTURE_CUBE_MAP:
-            return new TextureD3D_Cube(state, this);
-        case GL_TEXTURE_3D:
-            return new TextureD3D_3D(state, this);
-        case GL_TEXTURE_2D_ARRAY:
-            return new TextureD3D_2DArray(state, this);
-        case GL_TEXTURE_EXTERNAL_OES:
-            return new TextureD3D_External(state, this);
-        default:
-            UNREACHABLE();
-    }
-
-    return NULL;
-}
-
-RenderbufferImpl *Renderer11::createRenderbuffer()
-{
-    RenderbufferD3D *renderbuffer = new RenderbufferD3D(this);
-    return renderbuffer;
-}
-
 gl::Error Renderer11::readFromAttachment(const gl::FramebufferAttachment &srcAttachment,
                                          const gl::Rectangle &sourceArea,
                                          GLenum format,
@@ -4296,16 +4202,16 @@
     }
 }
 
+void Renderer11::onBufferCreate(const Buffer11 *created)
+{
+    mAliveBuffers.insert(created);
+}
+
 void Renderer11::onBufferDelete(const Buffer11 *deleted)
 {
     mAliveBuffers.erase(deleted);
 }
 
-void Renderer11::onMakeCurrent(const gl::ContextState &data)
-{
-    mStateManager.onMakeCurrent(data);
-}
-
 ID3D11Texture2D *Renderer11::resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource)
 {
     D3D11_TEXTURE2D_DESC textureDesc;
@@ -4461,4 +4367,105 @@
     return egl::Error(EGL_SUCCESS);
 }
 
+ContextImpl *Renderer11::createContext(const gl::ContextState &state)
+{
+    return new Context11(state, this);
+}
+
+gl::Error Renderer11::genericDrawElements(Context11 *context,
+                                          GLenum mode,
+                                          GLsizei count,
+                                          GLenum type,
+                                          const GLvoid *indices,
+                                          GLsizei instances,
+                                          const gl::IndexRange &indexRange)
+{
+    const auto &data     = context->getContextState();
+    gl::Program *program = context->getState().getProgram();
+    ASSERT(program != nullptr);
+    ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
+    bool usesPointSize     = programD3D->usesPointSize();
+
+    programD3D->updateSamplerMapping();
+
+    ANGLE_TRY(generateSwizzles(data));
+
+    if (!applyPrimitiveType(mode, count, usesPointSize))
+    {
+        return gl::NoError();
+    }
+
+    ANGLE_TRY(updateState(data, mode));
+
+    TranslatedIndexData indexInfo;
+    indexInfo.indexRange = indexRange;
+
+    ANGLE_TRY(applyIndexBuffer(data, indices, count, mode, type, &indexInfo));
+
+    applyTransformFeedbackBuffers(*data.state);
+    // Transform feedback is not allowed for DrawElements, this error should have been caught at the
+    // API validation
+    // layer.
+    ASSERT(!data.state->isTransformFeedbackActiveUnpaused());
+
+    size_t vertexCount = indexInfo.indexRange.vertexCount();
+    ANGLE_TRY(applyVertexBuffer(*data.state, mode, static_cast<GLsizei>(indexInfo.indexRange.start),
+                                static_cast<GLsizei>(vertexCount), instances, &indexInfo));
+    ANGLE_TRY(applyTextures(context, data));
+    ANGLE_TRY(applyShaders(data, mode));
+    ANGLE_TRY(programD3D->applyUniformBuffers(data));
+
+    if (!skipDraw(data, mode))
+    {
+        ANGLE_TRY(drawElementsImpl(data, indexInfo, mode, count, type, indices, instances));
+    }
+
+    return gl::NoError();
+}
+
+gl::Error Renderer11::genericDrawArrays(Context11 *context,
+                                        GLenum mode,
+                                        GLint first,
+                                        GLsizei count,
+                                        GLsizei instances)
+{
+    const auto &data     = context->getContextState();
+    gl::Program *program = context->getState().getProgram();
+    ASSERT(program != nullptr);
+    ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
+    bool usesPointSize     = programD3D->usesPointSize();
+
+    programD3D->updateSamplerMapping();
+
+    ANGLE_TRY(generateSwizzles(data));
+    if (!applyPrimitiveType(mode, count, usesPointSize))
+    {
+        return gl::NoError();
+    }
+
+    ANGLE_TRY(updateState(data, mode));
+    ANGLE_TRY(applyTransformFeedbackBuffers(*data.state));
+    ANGLE_TRY(applyVertexBuffer(*data.state, mode, first, count, instances, nullptr));
+    ANGLE_TRY(applyTextures(context, data));
+    ANGLE_TRY(applyShaders(data, mode));
+    ANGLE_TRY(programD3D->applyUniformBuffers(data));
+
+    if (!skipDraw(data, mode))
+    {
+        ANGLE_TRY(drawArraysImpl(data, mode, first, count, instances));
+
+        if (data.state->isTransformFeedbackActiveUnpaused())
+        {
+            ANGLE_TRY(markTransformFeedbackUsage(data));
+        }
+    }
+
+    return gl::NoError();
+}
+
+FramebufferImpl *Renderer11::createDefaultFramebuffer(const gl::FramebufferState &state)
+{
+    return new Framebuffer11(state, this);
+}
+
 }  // namespace rx
diff --git a/src/libANGLE/renderer/d3d/d3d11/Renderer11.h b/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
index 7387757..cb6443a 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
+++ b/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
@@ -31,17 +31,17 @@
 
 namespace rx
 {
-
-class VertexDataManager;
-class IndexDataManager;
-class StreamingIndexBufferInterface;
 class Blit11;
 class Buffer11;
 class Clear11;
+class Context11;
+class IndexDataManager;
+struct PackPixelsParams;
 class PixelTransfer11;
 class RenderTarget11;
+class StreamingIndexBufferInterface;
 class Trim11;
-struct PackPixelsParams;
+class VertexDataManager;
 
 struct Renderer11DeviceCaps
 {
@@ -110,8 +110,10 @@
     egl::ConfigSet generateConfigs() const override;
     void generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const override;
 
-    gl::Error flush() override;
-    gl::Error finish() override;
+    ContextImpl *createContext(const gl::ContextState &state) override;
+
+    gl::Error flush();
+    gl::Error finish();
 
     bool isValidNativeWindow(EGLNativeWindowType window) const override;
     NativeWindowD3D *createNativeWindow(EGLNativeWindowType window,
@@ -124,10 +126,6 @@
                                   GLenum depthBufferFormat,
                                   EGLint orientation) override;
 
-    ContextImpl *createContext(const gl::ContextState &state) override;
-
-    CompilerImpl *createCompiler() override;
-
     virtual gl::Error generateSwizzle(gl::Texture *texture);
     virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler);
     virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture);
@@ -136,38 +134,38 @@
                                 const std::vector<GLint> &vertexUniformBuffers,
                                 const std::vector<GLint> &fragmentUniformBuffers) override;
 
-    gl::Error updateState(const gl::ContextState &data, GLenum drawMode) override;
+    gl::Error updateState(const gl::ContextState &data, GLenum drawMode);
 
-    virtual bool applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSize);
-    gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) override;
+    bool applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSize);
+    gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer);
     gl::Error applyUniforms(const ProgramD3D &programD3D,
                             GLenum drawMode,
                             const std::vector<D3DUniform *> &uniformArray) override;
-    virtual gl::Error applyVertexBuffer(const gl::State &state,
-                                        GLenum mode,
-                                        GLint first,
-                                        GLsizei count,
-                                        GLsizei instances,
-                                        TranslatedIndexData *indexInfo);
+    gl::Error applyVertexBuffer(const gl::State &state,
+                                GLenum mode,
+                                GLint first,
+                                GLsizei count,
+                                GLsizei instances,
+                                TranslatedIndexData *indexInfo);
     gl::Error applyIndexBuffer(const gl::ContextState &data,
                                const GLvoid *indices,
                                GLsizei count,
                                GLenum mode,
                                GLenum type,
-                               TranslatedIndexData *indexInfo) override;
-    gl::Error applyTransformFeedbackBuffers(const gl::State &state) override;
+                               TranslatedIndexData *indexInfo);
+    gl::Error applyTransformFeedbackBuffers(const gl::State &state);
 
     // lost device
     bool testDeviceLost() override;
-    bool testDeviceResettable() override;
+    bool testDeviceResettable();
 
-    std::string getRendererDescription() const override;
+    std::string getRendererDescription() const;
     DeviceIdentifier getAdapterIdentifier() const override;
 
-    virtual unsigned int getReservedVertexUniformVectors() const;
-    virtual unsigned int getReservedFragmentUniformVectors() const;
-    virtual unsigned int getReservedVertexUniformBuffers() const;
-    virtual unsigned int getReservedFragmentUniformBuffers() const;
+    unsigned int getReservedVertexUniformVectors() const override;
+    unsigned int getReservedFragmentUniformVectors() const override;
+    unsigned int getReservedVertexUniformBuffers() const override;
+    unsigned int getReservedFragmentUniformBuffers() const override;
 
     bool getShareHandleSupport() const;
 
@@ -178,26 +176,40 @@
     std::string getShaderModelSuffix() const override;
 
     // Pixel operations
-    virtual gl::Error copyImage2D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
-                                  const gl::Offset &destOffset, TextureStorage *storage, GLint level);
-    virtual gl::Error copyImageCube(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
-                                    const gl::Offset &destOffset, TextureStorage *storage, GLenum target, GLint level);
-    virtual gl::Error copyImage3D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
-                                  const gl::Offset &destOffset, TextureStorage *storage, GLint level);
-    virtual gl::Error copyImage2DArray(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
-                                       const gl::Offset &destOffset, TextureStorage *storage, GLint level);
+    gl::Error copyImage2D(const gl::Framebuffer *framebuffer,
+                          const gl::Rectangle &sourceRect,
+                          GLenum destFormat,
+                          const gl::Offset &destOffset,
+                          TextureStorage *storage,
+                          GLint level) override;
+    gl::Error copyImageCube(const gl::Framebuffer *framebuffer,
+                            const gl::Rectangle &sourceRect,
+                            GLenum destFormat,
+                            const gl::Offset &destOffset,
+                            TextureStorage *storage,
+                            GLenum target,
+                            GLint level) override;
+    gl::Error copyImage3D(const gl::Framebuffer *framebuffer,
+                          const gl::Rectangle &sourceRect,
+                          GLenum destFormat,
+                          const gl::Offset &destOffset,
+                          TextureStorage *storage,
+                          GLint level) override;
+    gl::Error copyImage2DArray(const gl::Framebuffer *framebuffer,
+                               const gl::Rectangle &sourceRect,
+                               GLenum destFormat,
+                               const gl::Offset &destOffset,
+                               TextureStorage *storage,
+                               GLint level) override;
 
     // RenderTarget creation
-    virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT);
+    gl::Error createRenderTarget(int width,
+                                 int height,
+                                 GLenum format,
+                                 GLsizei samples,
+                                 RenderTargetD3D **outRT) override;
     gl::Error createRenderTargetCopy(RenderTargetD3D *source, RenderTargetD3D **outRT) override;
 
-    // Framebuffer creation
-    FramebufferImpl *createFramebuffer(const gl::FramebufferState &data) override;
-
-    // Shader creation
-    ShaderImpl *createShader(const gl::ShaderState &data) override;
-    ProgramImpl *createProgram(const gl::ProgramState &data) override;
-
     // Shader operations
     gl::Error loadExecutable(const void *function,
                              size_t length,
@@ -215,41 +227,41 @@
     UniformStorageD3D *createUniformStorage(size_t storageSize) override;
 
     // Image operations
-    virtual ImageD3D *createImage();
+    ImageD3D *createImage() override;
     gl::Error generateMipmap(ImageD3D *dest, ImageD3D *source) override;
     gl::Error generateMipmapsUsingD3D(TextureStorage *storage,
                                       const gl::TextureState &textureState) override;
-    virtual TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain);
+    TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain) override;
     TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage) override;
     TextureStorage *createTextureStorageExternal(
         egl::Stream *stream,
         const egl::Stream::GLTextureDescription &desc) override;
-    virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly);
-    virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly);
-    virtual TextureStorage *createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels);
-    virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels);
+    TextureStorage *createTextureStorage2D(GLenum internalformat,
+                                           bool renderTarget,
+                                           GLsizei width,
+                                           GLsizei height,
+                                           int levels,
+                                           bool hintLevelZeroOnly) override;
+    TextureStorage *createTextureStorageCube(GLenum internalformat,
+                                             bool renderTarget,
+                                             int size,
+                                             int levels,
+                                             bool hintLevelZeroOnly) override;
+    TextureStorage *createTextureStorage3D(GLenum internalformat,
+                                           bool renderTarget,
+                                           GLsizei width,
+                                           GLsizei height,
+                                           GLsizei depth,
+                                           int levels) override;
+    TextureStorage *createTextureStorage2DArray(GLenum internalformat,
+                                                bool renderTarget,
+                                                GLsizei width,
+                                                GLsizei height,
+                                                GLsizei depth,
+                                                int levels) override;
 
-    // Texture creation
-    TextureImpl *createTexture(const gl::TextureState &state) override;
-
-    // Renderbuffer creation
-    virtual RenderbufferImpl *createRenderbuffer();
-
-    // Buffer creation
-    virtual BufferImpl *createBuffer();
-    virtual VertexBuffer *createVertexBuffer();
-    virtual IndexBuffer *createIndexBuffer();
-
-    // Vertex Array creation
-    VertexArrayImpl *createVertexArray(const gl::VertexArrayState &data) override;
-
-    // Query and Fence creation
-    virtual QueryImpl *createQuery(GLenum type);
-    virtual FenceNVImpl *createFenceNV();
-    virtual FenceSyncImpl *createFenceSync();
-
-    // Transform Feedback creation
-    virtual TransformFeedbackImpl* createTransformFeedback();
+    VertexBuffer *createVertexBuffer() override;
+    IndexBuffer *createIndexBuffer() override;
 
     // Stream Creation
     StreamProducerImpl *createStreamProducerD3DTextureNV12(
@@ -305,18 +317,33 @@
     StateManager11 *getStateManager() { return &mStateManager; }
 
     void onSwap();
+    void onBufferCreate(const Buffer11 *created);
     void onBufferDelete(const Buffer11 *deleted);
-    void onMakeCurrent(const gl::ContextState &data) override;
 
     egl::Error getEGLDevice(DeviceImpl **device) override;
 
+    gl::Error genericDrawArrays(Context11 *context,
+                                GLenum mode,
+                                GLint first,
+                                GLsizei count,
+                                GLsizei instances);
+
+    gl::Error genericDrawElements(Context11 *context,
+                                  GLenum mode,
+                                  GLsizei count,
+                                  GLenum type,
+                                  const GLvoid *indices,
+                                  GLsizei instances,
+                                  const gl::IndexRange &indexRange);
+
+    // Necessary hack for default framebuffers in D3D.
+    FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) override;
+
   protected:
     void createAnnotator() override;
     gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd) override;
     gl::Error applyShadersImpl(const gl::ContextState &data, GLenum drawMode) override;
 
-    void syncState(const gl::State &state, const gl::State::DirtyBits &bitmask) override;
-
   private:
     gl::Error drawArraysImpl(const gl::ContextState &data,
                              GLenum mode,
diff --git a/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp b/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp
index 614d887..447ccfa 100644
--- a/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp
@@ -11,6 +11,7 @@
 #include "common/BitSetIterator.h"
 #include "common/utilities.h"
 #include "libANGLE/Query.h"
+#include "libANGLE/VertexArray.h"
 #include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h"
 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
 #include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
@@ -1084,7 +1085,7 @@
     }
 
     // TODO(jmadill): Use context caps?
-    UINT drawBuffers = mRenderer->getRendererCaps().maxDrawBuffers;
+    UINT drawBuffers = mRenderer->getNativeCaps().maxDrawBuffers;
 
     // Apply the render target and depth stencil
     mRenderer->getDeviceContext()->OMSetRenderTargets(drawBuffers, framebufferRTVs.data(),
diff --git a/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp b/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp
index 7a94835..2eaf7a7 100644
--- a/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp
@@ -16,7 +16,6 @@
 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
 #include "libANGLE/renderer/d3d/generatemip.h"
 #include "libANGLE/renderer/d3d/loadimage.h"
-#include "libANGLE/renderer/Renderer.h"
 
 namespace rx
 {
diff --git a/src/libANGLE/renderer/d3d/d3d9/Context9.cpp b/src/libANGLE/renderer/d3d/d3d9/Context9.cpp
new file mode 100644
index 0000000..a1e30d1
--- /dev/null
+++ b/src/libANGLE/renderer/d3d/d3d9/Context9.cpp
@@ -0,0 +1,257 @@
+//
+// Copyright 2016 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.
+//
+// Context9:
+//   D3D9-specific functionality associated with a GL Context.
+//
+
+#include "libANGLE/renderer/d3d/d3d9/Context9.h"
+
+#include "libANGLE/renderer/d3d/CompilerD3D.h"
+#include "libANGLE/renderer/d3d/ShaderD3D.h"
+#include "libANGLE/renderer/d3d/ProgramD3D.h"
+#include "libANGLE/renderer/d3d/RenderbufferD3D.h"
+#include "libANGLE/renderer/d3d/SamplerD3D.h"
+#include "libANGLE/renderer/d3d/TextureD3D.h"
+#include "libANGLE/renderer/d3d/TransformFeedbackD3D.h"
+#include "libANGLE/renderer/d3d/d3d9/Buffer9.h"
+#include "libANGLE/renderer/d3d/d3d9/Fence9.h"
+#include "libANGLE/renderer/d3d/d3d9/Framebuffer9.h"
+#include "libANGLE/renderer/d3d/d3d9/Query9.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
+#include "libANGLE/renderer/d3d/d3d9/StateManager9.h"
+#include "libANGLE/renderer/d3d/d3d9/VertexArray9.h"
+
+namespace rx
+{
+
+Context9::Context9(const gl::ContextState &state, Renderer9 *renderer)
+    : ContextImpl(state), mRenderer(renderer)
+{
+}
+
+Context9::~Context9()
+{
+}
+
+gl::Error Context9::initialize()
+{
+    return gl::NoError();
+}
+
+CompilerImpl *Context9::createCompiler()
+{
+    return new CompilerD3D(SH_HLSL_3_0_OUTPUT);
+}
+
+ShaderImpl *Context9::createShader(const gl::ShaderState &data)
+{
+    return new ShaderD3D(data);
+}
+
+ProgramImpl *Context9::createProgram(const gl::ProgramState &data)
+{
+    return new ProgramD3D(data, mRenderer);
+}
+
+FramebufferImpl *Context9::createFramebuffer(const gl::FramebufferState &data)
+{
+    return new Framebuffer9(data, mRenderer);
+}
+
+TextureImpl *Context9::createTexture(const gl::TextureState &state)
+{
+    switch (state.target)
+    {
+        case GL_TEXTURE_2D:
+            return new TextureD3D_2D(state, mRenderer);
+        case GL_TEXTURE_CUBE_MAP:
+            return new TextureD3D_Cube(state, mRenderer);
+        default:
+            UNREACHABLE();
+    }
+    return nullptr;
+}
+
+RenderbufferImpl *Context9::createRenderbuffer()
+{
+    return new RenderbufferD3D(mRenderer);
+}
+
+BufferImpl *Context9::createBuffer()
+{
+    return new Buffer9(mRenderer);
+}
+
+VertexArrayImpl *Context9::createVertexArray(const gl::VertexArrayState &data)
+{
+    return new VertexArray9(data);
+}
+
+QueryImpl *Context9::createQuery(GLenum type)
+{
+    return new Query9(mRenderer, type);
+}
+
+FenceNVImpl *Context9::createFenceNV()
+{
+    return new FenceNV9(mRenderer);
+}
+
+FenceSyncImpl *Context9::createFenceSync()
+{
+    // D3D9 doesn't support ES 3.0 and its sync objects.
+    UNREACHABLE();
+    return nullptr;
+}
+
+TransformFeedbackImpl *Context9::createTransformFeedback()
+{
+    return new TransformFeedbackD3D();
+}
+
+SamplerImpl *Context9::createSampler()
+{
+    return new SamplerD3D();
+}
+
+gl::Error Context9::flush()
+{
+    return mRenderer->flush();
+}
+
+gl::Error Context9::finish()
+{
+    return mRenderer->finish();
+}
+
+gl::Error Context9::drawArrays(GLenum mode, GLint first, GLsizei count)
+{
+    return mRenderer->genericDrawArrays(this, mode, first, count, 0);
+}
+
+gl::Error Context9::drawArraysInstanced(GLenum mode,
+                                        GLint first,
+                                        GLsizei count,
+                                        GLsizei instanceCount)
+{
+    return mRenderer->genericDrawArrays(this, mode, first, count, instanceCount);
+}
+
+gl::Error Context9::drawElements(GLenum mode,
+                                 GLsizei count,
+                                 GLenum type,
+                                 const GLvoid *indices,
+                                 const gl::IndexRange &indexRange)
+{
+    return mRenderer->genericDrawElements(this, mode, count, type, indices, 0, indexRange);
+}
+
+gl::Error Context9::drawElementsInstanced(GLenum mode,
+                                          GLsizei count,
+                                          GLenum type,
+                                          const GLvoid *indices,
+                                          GLsizei instances,
+                                          const gl::IndexRange &indexRange)
+{
+    return mRenderer->genericDrawElements(this, mode, count, type, indices, instances, indexRange);
+}
+
+gl::Error Context9::drawRangeElements(GLenum mode,
+                                      GLuint start,
+                                      GLuint end,
+                                      GLsizei count,
+                                      GLenum type,
+                                      const GLvoid *indices,
+                                      const gl::IndexRange &indexRange)
+{
+    return mRenderer->genericDrawElements(this, mode, count, type, indices, 0, indexRange);
+}
+
+void Context9::notifyDeviceLost()
+{
+    mRenderer->notifyDeviceLost();
+}
+
+bool Context9::isDeviceLost() const
+{
+    return mRenderer->isDeviceLost();
+}
+
+bool Context9::testDeviceLost()
+{
+    return mRenderer->testDeviceLost();
+}
+
+bool Context9::testDeviceResettable()
+{
+    return mRenderer->testDeviceResettable();
+}
+
+std::string Context9::getVendorString() const
+{
+    return mRenderer->getVendorString();
+}
+
+std::string Context9::getRendererDescription() const
+{
+    return mRenderer->getRendererDescription();
+}
+
+void Context9::insertEventMarker(GLsizei length, const char *marker)
+{
+    mRenderer->insertEventMarker(length, marker);
+}
+
+void Context9::pushGroupMarker(GLsizei length, const char *marker)
+{
+    mRenderer->pushGroupMarker(length, marker);
+}
+
+void Context9::popGroupMarker()
+{
+    mRenderer->popGroupMarker();
+}
+
+void Context9::syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits)
+{
+    mRenderer->getStateManager()->syncState(state, dirtyBits);
+}
+
+GLint Context9::getGPUDisjoint()
+{
+    return mRenderer->getGPUDisjoint();
+}
+
+GLint64 Context9::getTimestamp()
+{
+    return mRenderer->getTimestamp();
+}
+
+void Context9::onMakeCurrent(const gl::ContextState &data)
+{
+}
+
+const gl::Caps &Context9::getNativeCaps() const
+{
+    return mRenderer->getNativeCaps();
+}
+
+const gl::TextureCapsMap &Context9::getNativeTextureCaps() const
+{
+    return mRenderer->getNativeTextureCaps();
+}
+
+const gl::Extensions &Context9::getNativeExtensions() const
+{
+    return mRenderer->getNativeExtensions();
+}
+
+const gl::Limitations &Context9::getNativeLimitations() const
+{
+    return mRenderer->getNativeLimitations();
+}
+
+}  // namespace rx
diff --git a/src/libANGLE/renderer/d3d/d3d9/Context9.h b/src/libANGLE/renderer/d3d/d3d9/Context9.h
index 2e7b275..b450aea 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Context9.h
+++ b/src/libANGLE/renderer/d3d/d3d9/Context9.h
@@ -14,14 +14,110 @@
 
 namespace rx
 {
+class Renderer9;
 
 class Context9 : public ContextImpl
 {
   public:
-    Context9(const gl::ContextState &state) : ContextImpl(state) {}
-    ~Context9() override {}
+    Context9(const gl::ContextState &state, Renderer9 *renderer);
+    ~Context9() override;
 
-    gl::Error initialize(Renderer *renderer) override { return gl::NoError(); }
+    gl::Error initialize() override;
+
+    // Shader creation
+    CompilerImpl *createCompiler() override;
+    ShaderImpl *createShader(const gl::ShaderState &data) override;
+    ProgramImpl *createProgram(const gl::ProgramState &data) override;
+
+    // Framebuffer creation
+    FramebufferImpl *createFramebuffer(const gl::FramebufferState &data) override;
+
+    // Texture creation
+    TextureImpl *createTexture(const gl::TextureState &state) override;
+
+    // Renderbuffer creation
+    RenderbufferImpl *createRenderbuffer() override;
+
+    // Buffer creation
+    BufferImpl *createBuffer() override;
+
+    // Vertex Array creation
+    VertexArrayImpl *createVertexArray(const gl::VertexArrayState &data) override;
+
+    // Query and Fence creation
+    QueryImpl *createQuery(GLenum type) override;
+    FenceNVImpl *createFenceNV() override;
+    FenceSyncImpl *createFenceSync() override;
+
+    // Transform Feedback creation
+    TransformFeedbackImpl *createTransformFeedback() override;
+
+    // Sampler object creation
+    SamplerImpl *createSampler() override;
+
+    // Flush and finish.
+    gl::Error flush() override;
+    gl::Error finish() override;
+
+    // Drawing methods.
+    gl::Error drawArrays(GLenum mode, GLint first, GLsizei count) override;
+    gl::Error drawArraysInstanced(GLenum mode,
+                                  GLint first,
+                                  GLsizei count,
+                                  GLsizei instanceCount) override;
+
+    gl::Error drawElements(GLenum mode,
+                           GLsizei count,
+                           GLenum type,
+                           const GLvoid *indices,
+                           const gl::IndexRange &indexRange) override;
+    gl::Error drawElementsInstanced(GLenum mode,
+                                    GLsizei count,
+                                    GLenum type,
+                                    const GLvoid *indices,
+                                    GLsizei instances,
+                                    const gl::IndexRange &indexRange) override;
+    gl::Error drawRangeElements(GLenum mode,
+                                GLuint start,
+                                GLuint end,
+                                GLsizei count,
+                                GLenum type,
+                                const GLvoid *indices,
+                                const gl::IndexRange &indexRange) override;
+
+    // TODO(jmadill): Investigate proper impl methods for this.
+    void notifyDeviceLost() override;
+    bool isDeviceLost() const override;
+    bool testDeviceLost() override;
+    bool testDeviceResettable() override;
+
+    // Vendor and description strings.
+    std::string getVendorString() const override;
+    std::string getRendererDescription() const override;
+
+    // Debug markers.
+    void insertEventMarker(GLsizei length, const char *marker) override;
+    void pushGroupMarker(GLsizei length, const char *marker) override;
+    void popGroupMarker() override;
+
+    // State sync with dirty bits.
+    void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits) override;
+
+    // Disjoint timer queries
+    GLint getGPUDisjoint() override;
+    GLint64 getTimestamp() override;
+
+    // Context switching
+    void onMakeCurrent(const gl::ContextState &data) override;
+
+    // Caps queries
+    const gl::Caps &getNativeCaps() const override;
+    const gl::TextureCapsMap &getNativeTextureCaps() const override;
+    const gl::Extensions &getNativeExtensions() const override;
+    const gl::Limitations &getNativeLimitations() const override;
+
+  private:
+    Renderer9 *mRenderer;
 };
 
 }  // namespace rx
diff --git a/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp b/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp
index 8055e12..d7662fb 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp
@@ -59,7 +59,8 @@
     const gl::FramebufferAttachment *colorAttachment        = mState.getColorAttachment(0);
     const gl::FramebufferAttachment *depthStencilAttachment = mState.getDepthOrStencilAttachment();
 
-    gl::Error error = mRenderer->applyRenderTarget(colorAttachment, depthStencilAttachment);
+    gl::Error error =
+        mRenderer->applyRenderTarget(context, colorAttachment, depthStencilAttachment);
     if (error.isError())
     {
         return error;
diff --git a/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp b/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp
index 97c7f72..40152df 100644
--- a/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp
@@ -40,7 +40,7 @@
         }
         else if (indexType == GL_UNSIGNED_INT)
         {
-            ASSERT(mRenderer->getRendererExtensions().elementIndexUint);
+            ASSERT(mRenderer->getNativeExtensions().elementIndexUint);
             format = D3DFMT_INDEX32;
         }
         else UNREACHABLE();
diff --git a/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp b/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
index 55eaafb..3295359 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
@@ -348,7 +348,7 @@
         mDevice->SetRenderState(D3DRS_POINTSIZE_MAX, 0x3F800000);   // 1.0f
     }
 
-    const gl::Caps &rendererCaps = getRendererCaps();
+    const gl::Caps &rendererCaps = getNativeCaps();
 
     mCurVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits);
     mCurPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits);
@@ -368,7 +368,7 @@
     mVertexDataManager = new VertexDataManager(this);
     mIndexDataManager = new IndexDataManager(this, getRendererClass());
 
-    mTranslatedAttribCache.resize(getRendererCaps().maxVertexAttributes);
+    mTranslatedAttribCache.resize(getNativeCaps().maxVertexAttributes);
 
     mStateManager.initialize();
 }
@@ -414,8 +414,8 @@
         GL_DEPTH_COMPONENT16,
     };
 
-    const gl::Caps &rendererCaps = getRendererCaps();
-    const gl::TextureCapsMap &rendererTextureCaps = getRendererTextureCaps();
+    const gl::Caps &rendererCaps                  = getNativeCaps();
+    const gl::TextureCapsMap &rendererTextureCaps = getNativeTextureCaps();
 
     D3DDISPLAYMODE currentDisplayMode;
     mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
@@ -683,12 +683,7 @@
 
 ContextImpl *Renderer9::createContext(const gl::ContextState &state)
 {
-    return new Context9(state);
-}
-
-CompilerImpl *Renderer9::createCompiler()
-{
-    return new CompilerD3D(SH_HLSL_3_0_OUTPUT);
+    return new Context9(state, this);
 }
 
 void *Renderer9::getD3DDevice()
@@ -760,38 +755,6 @@
     return new IndexBuffer9(this);
 }
 
-BufferImpl *Renderer9::createBuffer()
-{
-    return new Buffer9(this);
-}
-
-VertexArrayImpl *Renderer9::createVertexArray(const gl::VertexArrayState &data)
-{
-    return new VertexArray9(data);
-}
-
-QueryImpl *Renderer9::createQuery(GLenum type)
-{
-    return new Query9(this, type);
-}
-
-FenceNVImpl *Renderer9::createFenceNV()
-{
-    return new FenceNV9(this);
-}
-
-FenceSyncImpl *Renderer9::createFenceSync()
-{
-    // Renderer9 doesn't support ES 3.0 and its sync objects.
-    UNREACHABLE();
-    return NULL;
-}
-
-TransformFeedbackImpl* Renderer9::createTransformFeedback()
-{
-    return new TransformFeedbackD3D();
-}
-
 StreamProducerImpl *Renderer9::createStreamProducerD3DTextureNV12(
     egl::Stream::ConsumerType consumerType,
     const egl::AttributeMap &attribs)
@@ -861,7 +824,7 @@
         mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter);
         mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXMIPLEVEL, baseLevel);
         mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPMAPLODBIAS, static_cast<DWORD>(lodBias));
-        if (getRendererExtensions().textureFilterAnisotropic)
+        if (getNativeExtensions().textureFilterAnisotropic)
         {
             mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXANISOTROPY, (DWORD)samplerState.maxAnisotropy);
         }
@@ -930,23 +893,16 @@
     return gl::Error(GL_NO_ERROR);
 }
 
-void Renderer9::syncState(const gl::State &state, const gl::State::DirtyBits &bitmask)
+gl::Error Renderer9::updateState(Context9 *context, GLenum drawMode)
 {
-    mStateManager.syncState(state, bitmask);
-}
+    const auto &data = context->getContextState();
 
-gl::Error Renderer9::updateState(const gl::ContextState &data, GLenum drawMode)
-{
     // Applies the render target surface, depth stencil surface, viewport rectangle and
     // scissor rectangle to the renderer
     const gl::Framebuffer *framebufferObject = data.state->getDrawFramebuffer();
     ASSERT(framebufferObject && framebufferObject->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE);
 
-    gl::Error error = applyRenderTarget(framebufferObject);
-    if (error.isError())
-    {
-        return error;
-    }
+    ANGLE_TRY(applyRenderTarget(context, framebufferObject));
 
     // Setting viewport state
     setViewport(data.state->getViewport(), data.state->getNearPlane(), data.state->getFarPlane(),
@@ -962,16 +918,11 @@
     rasterizer.multiSample         = (samples != 0);
 
     unsigned int mask = GetBlendSampleMask(data, samples);
-    error             = setBlendDepthRasterStates(data, mask);
-
-    if (error.isError())
-    {
-        return error;
-    }
+    ANGLE_TRY(setBlendDepthRasterStates(data, mask));
 
     mStateManager.resetDirtyBits();
 
-    return error;
+    return gl::NoError();
 }
 
 void Renderer9::setScissorRectangle(const gl::Rectangle &scissor, bool enabled)
@@ -1040,8 +991,9 @@
     return mPrimitiveCount > 0;
 }
 
-
-gl::Error Renderer9::getNullColorbuffer(const gl::FramebufferAttachment *depthbuffer, const gl::FramebufferAttachment **outColorBuffer)
+gl::Error Renderer9::getNullColorbuffer(GLImplFactory *implFactory,
+                                        const gl::FramebufferAttachment *depthbuffer,
+                                        const gl::FramebufferAttachment **outColorBuffer)
 {
     ASSERT(depthbuffer);
 
@@ -1060,7 +1012,7 @@
         }
     }
 
-    gl::Renderbuffer *nullRenderbuffer = new gl::Renderbuffer(createRenderbuffer(), 0);
+    gl::Renderbuffer *nullRenderbuffer = new gl::Renderbuffer(implFactory->createRenderbuffer(), 0);
     gl::Error error = nullRenderbuffer->setStorage(GL_NONE, size.width, size.height);
     if (error.isError())
     {
@@ -1090,7 +1042,8 @@
     return gl::Error(GL_NO_ERROR);
 }
 
-gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorAttachment,
+gl::Error Renderer9::applyRenderTarget(GLImplFactory *implFactory,
+                                       const gl::FramebufferAttachment *colorAttachment,
                                        const gl::FramebufferAttachment *depthStencilAttachment)
 {
     const gl::FramebufferAttachment *renderAttachment = colorAttachment;
@@ -1100,7 +1053,7 @@
     // to keep the D3D runtime happy.  This should only be possible if depth texturing.
     if (renderAttachment == nullptr)
     {
-        error = getNullColorbuffer(depthStencilAttachment, &renderAttachment);
+        error = getNullColorbuffer(implFactory, depthStencilAttachment, &renderAttachment);
         if (error.isError())
         {
             return error;
@@ -1194,9 +1147,11 @@
     return gl::Error(GL_NO_ERROR);
 }
 
-gl::Error Renderer9::applyRenderTarget(const gl::Framebuffer *framebuffer)
+gl::Error Renderer9::applyRenderTarget(GLImplFactory *implFactory,
+                                       const gl::Framebuffer *framebuffer)
 {
-    return applyRenderTarget(framebuffer->getColorbuffer(0), framebuffer->getDepthOrStencilbuffer());
+    return applyRenderTarget(implFactory, framebuffer->getColorbuffer(0),
+                             framebuffer->getDepthOrStencilbuffer());
 }
 
 gl::Error Renderer9::applyVertexBuffer(const gl::State &state,
@@ -1352,7 +1307,7 @@
 
     unsigned int startIndex = 0;
 
-    if (getRendererExtensions().elementIndexUint)
+    if (getNativeExtensions().elementIndexUint)
     {
         if (!mLineLoopIB)
         {
@@ -1596,7 +1551,7 @@
             }
         }
     }
-    else if (getRendererExtensions().elementIndexUint)
+    else if (getNativeExtensions().elementIndexUint)
     {
         const unsigned int spaceNeeded = static_cast<unsigned int>(count) * sizeof(unsigned int);
 
@@ -2388,7 +2343,7 @@
 {
     const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(format);
 
-    const gl::TextureCaps &textureCaps = getRendererTextureCaps().get(format);
+    const gl::TextureCaps &textureCaps = getNativeTextureCaps().get(format);
     GLuint supportedSamples = textureCaps.getNearestSamples(samples);
 
     IDirect3DTexture9 *texture      = nullptr;
@@ -2477,21 +2432,6 @@
     return gl::Error(GL_NO_ERROR);
 }
 
-FramebufferImpl *Renderer9::createFramebuffer(const gl::FramebufferState &data)
-{
-    return new Framebuffer9(data, this);
-}
-
-ShaderImpl *Renderer9::createShader(const gl::ShaderState &data)
-{
-    return new ShaderD3D(data);
-}
-
-ProgramImpl *Renderer9::createProgram(const gl::ProgramState &data)
-{
-    return new ProgramD3D(data, this);
-}
-
 gl::Error Renderer9::loadExecutable(const void *function,
                                     size_t length,
                                     ShaderType type,
@@ -2749,27 +2689,6 @@
     return NULL;
 }
 
-TextureImpl *Renderer9::createTexture(const gl::TextureState &state)
-{
-    switch (state.target)
-    {
-        case GL_TEXTURE_2D:
-            return new TextureD3D_2D(state, this);
-        case GL_TEXTURE_CUBE_MAP:
-            return new TextureD3D_Cube(state, this);
-        default:
-            UNREACHABLE();
-    }
-
-    return NULL;
-}
-
-RenderbufferImpl *Renderer9::createRenderbuffer()
-{
-    RenderbufferD3D *renderbuffer = new RenderbufferD3D(this);
-    return renderbuffer;
-}
-
 bool Renderer9::getLUID(LUID *adapterLuid) const
 {
     adapterLuid->HighPart = 0;
@@ -2887,4 +2806,100 @@
 {
 }
 
+gl::Error Renderer9::genericDrawElements(Context9 *context,
+                                         GLenum mode,
+                                         GLsizei count,
+                                         GLenum type,
+                                         const GLvoid *indices,
+                                         GLsizei instances,
+                                         const gl::IndexRange &indexRange)
+{
+    const auto &data     = context->getContextState();
+    gl::Program *program = context->getState().getProgram();
+    ASSERT(program != nullptr);
+    ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
+    bool usesPointSize     = programD3D->usesPointSize();
+
+    programD3D->updateSamplerMapping();
+
+    ANGLE_TRY(generateSwizzles(data));
+
+    if (!applyPrimitiveType(mode, count, usesPointSize))
+    {
+        return gl::NoError();
+    }
+
+    ANGLE_TRY(updateState(context, mode));
+
+    TranslatedIndexData indexInfo;
+    indexInfo.indexRange = indexRange;
+
+    ANGLE_TRY(applyIndexBuffer(data, indices, count, mode, type, &indexInfo));
+
+    applyTransformFeedbackBuffers(*data.state);
+    // Transform feedback is not allowed for DrawElements, this error should have been caught at the
+    // API validation
+    // layer.
+    ASSERT(!data.state->isTransformFeedbackActiveUnpaused());
+
+    size_t vertexCount = indexInfo.indexRange.vertexCount();
+    ANGLE_TRY(applyVertexBuffer(*data.state, mode, static_cast<GLsizei>(indexInfo.indexRange.start),
+                                static_cast<GLsizei>(vertexCount), instances, &indexInfo));
+    ANGLE_TRY(applyTextures(context, data));
+    ANGLE_TRY(applyShaders(data, mode));
+    ANGLE_TRY(programD3D->applyUniformBuffers(data));
+
+    if (!skipDraw(data, mode))
+    {
+        ANGLE_TRY(drawElementsImpl(data, indexInfo, mode, count, type, indices, instances));
+    }
+
+    return gl::NoError();
 }
+
+gl::Error Renderer9::genericDrawArrays(Context9 *context,
+                                       GLenum mode,
+                                       GLint first,
+                                       GLsizei count,
+                                       GLsizei instances)
+{
+    const auto &data     = context->getContextState();
+    gl::Program *program = context->getState().getProgram();
+    ASSERT(program != nullptr);
+    ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
+    bool usesPointSize     = programD3D->usesPointSize();
+
+    programD3D->updateSamplerMapping();
+
+    ANGLE_TRY(generateSwizzles(data));
+    if (!applyPrimitiveType(mode, count, usesPointSize))
+    {
+        return gl::NoError();
+    }
+
+    ANGLE_TRY(updateState(context, mode));
+    ANGLE_TRY(applyTransformFeedbackBuffers(*data.state));
+    ANGLE_TRY(applyVertexBuffer(*data.state, mode, first, count, instances, nullptr));
+    ANGLE_TRY(applyTextures(context, data));
+    ANGLE_TRY(applyShaders(data, mode));
+    ANGLE_TRY(programD3D->applyUniformBuffers(data));
+
+    if (!skipDraw(data, mode))
+    {
+        ANGLE_TRY(drawArraysImpl(data, mode, first, count, instances));
+
+        if (data.state->isTransformFeedbackActiveUnpaused())
+        {
+            ANGLE_TRY(markTransformFeedbackUsage(data));
+        }
+    }
+
+    return gl::NoError();
+}
+
+FramebufferImpl *Renderer9::createDefaultFramebuffer(const gl::FramebufferState &state)
+{
+    return new Framebuffer9(state, this);
+}
+
+}  // namespace rx
diff --git a/src/libANGLE/renderer/d3d/d3d9/Renderer9.h b/src/libANGLE/renderer/d3d/d3d9/Renderer9.h
index 4a138be..2b7f9aa 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Renderer9.h
+++ b/src/libANGLE/renderer/d3d/d3d9/Renderer9.h
@@ -32,6 +32,7 @@
 namespace rx
 {
 class Blit9;
+class Context9;
 class IndexDataManager;
 class ProgramD3D;
 class StreamingIndexBufferInterface;
@@ -76,8 +77,8 @@
     void startScene();
     void endScene();
 
-    gl::Error flush() override;
-    gl::Error finish() override;
+    gl::Error flush();
+    gl::Error finish();
 
     bool isValidNativeWindow(EGLNativeWindowType window) const override;
     NativeWindowD3D *createNativeWindow(EGLNativeWindowType window,
@@ -92,8 +93,6 @@
 
     ContextImpl *createContext(const gl::ContextState &state) override;
 
-    CompilerImpl *createCompiler() override;
-
     gl::Error allocateEventQuery(IDirect3DQuery9 **outQuery);
     void freeEventQuery(IDirect3DQuery9* query);
 
@@ -110,7 +109,7 @@
                                 const std::vector<GLint> &vertexUniformBuffers,
                                 const std::vector<GLint> &fragmentUniformBuffers) override;
 
-    gl::Error updateState(const gl::ContextState &data, GLenum drawMode) override;
+    gl::Error updateState(Context9 *context, GLenum drawMode);
 
     void setScissorRectangle(const gl::Rectangle &scissor, bool enabled);
     void setViewport(const gl::Rectangle &viewport,
@@ -120,27 +119,28 @@
                      GLenum frontFace,
                      bool ignoreViewport);
 
-    gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) override;
-    gl::Error applyRenderTarget(const gl::FramebufferAttachment *colorAttachment,
+    gl::Error applyRenderTarget(GLImplFactory *implFactory, const gl::Framebuffer *frameBuffer);
+    gl::Error applyRenderTarget(GLImplFactory *implFactory,
+                                const gl::FramebufferAttachment *colorAttachment,
                                 const gl::FramebufferAttachment *depthStencilAttachment);
     gl::Error applyUniforms(const ProgramD3D &programD3D,
                             GLenum drawMode,
                             const std::vector<D3DUniform *> &uniformArray) override;
-    virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize);
-    virtual gl::Error applyVertexBuffer(const gl::State &state,
-                                        GLenum mode,
-                                        GLint first,
-                                        GLsizei count,
-                                        GLsizei instances,
-                                        TranslatedIndexData *indexInfo);
+    bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize);
+    gl::Error applyVertexBuffer(const gl::State &state,
+                                GLenum mode,
+                                GLint first,
+                                GLsizei count,
+                                GLsizei instances,
+                                TranslatedIndexData *indexInfo);
     gl::Error applyIndexBuffer(const gl::ContextState &data,
                                const GLvoid *indices,
                                GLsizei count,
                                GLenum mode,
                                GLenum type,
-                               TranslatedIndexData *indexInfo) override;
+                               TranslatedIndexData *indexInfo);
 
-    gl::Error applyTransformFeedbackBuffers(const gl::State &state) override;
+    gl::Error applyTransformFeedbackBuffers(const gl::State &state);
 
     gl::Error clear(const ClearParameters &clearParams,
                     const gl::FramebufferAttachment *colorBuffer,
@@ -150,19 +150,19 @@
 
     // lost device
     bool testDeviceLost() override;
-    bool testDeviceResettable() override;
+    bool testDeviceResettable();
 
     VendorID getVendorId() const;
-    std::string getRendererDescription() const override;
+    std::string getRendererDescription() const;
     DeviceIdentifier getAdapterIdentifier() const override;
 
     IDirect3DDevice9 *getDevice() { return mDevice; }
     void *getD3DDevice() override;
 
-    virtual unsigned int getReservedVertexUniformVectors() const;
-    virtual unsigned int getReservedFragmentUniformVectors() const;
-    virtual unsigned int getReservedVertexUniformBuffers() const;
-    virtual unsigned int getReservedFragmentUniformBuffers() const;
+    unsigned int getReservedVertexUniformVectors() const override;
+    unsigned int getReservedFragmentUniformVectors() const override;
+    unsigned int getReservedVertexUniformBuffers() const override;
+    unsigned int getReservedFragmentUniformBuffers() const override;
 
     bool getShareHandleSupport() const;
 
@@ -173,26 +173,40 @@
     DWORD getCapsDeclTypes() const;
 
     // Pixel operations
-    virtual gl::Error copyImage2D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
-                                  const gl::Offset &destOffset, TextureStorage *storage, GLint level);
-    virtual gl::Error copyImageCube(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
-                                    const gl::Offset &destOffset, TextureStorage *storage, GLenum target, GLint level);
-    virtual gl::Error copyImage3D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
-                                  const gl::Offset &destOffset, TextureStorage *storage, GLint level);
-    virtual gl::Error copyImage2DArray(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
-                                       const gl::Offset &destOffset, TextureStorage *storage, GLint level);
+    gl::Error copyImage2D(const gl::Framebuffer *framebuffer,
+                          const gl::Rectangle &sourceRect,
+                          GLenum destFormat,
+                          const gl::Offset &destOffset,
+                          TextureStorage *storage,
+                          GLint level) override;
+    gl::Error copyImageCube(const gl::Framebuffer *framebuffer,
+                            const gl::Rectangle &sourceRect,
+                            GLenum destFormat,
+                            const gl::Offset &destOffset,
+                            TextureStorage *storage,
+                            GLenum target,
+                            GLint level) override;
+    gl::Error copyImage3D(const gl::Framebuffer *framebuffer,
+                          const gl::Rectangle &sourceRect,
+                          GLenum destFormat,
+                          const gl::Offset &destOffset,
+                          TextureStorage *storage,
+                          GLint level) override;
+    gl::Error copyImage2DArray(const gl::Framebuffer *framebuffer,
+                               const gl::Rectangle &sourceRect,
+                               GLenum destFormat,
+                               const gl::Offset &destOffset,
+                               TextureStorage *storage,
+                               GLint level) override;
 
     // RenderTarget creation
-    virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT);
+    gl::Error createRenderTarget(int width,
+                                 int height,
+                                 GLenum format,
+                                 GLsizei samples,
+                                 RenderTargetD3D **outRT) override;
     gl::Error createRenderTargetCopy(RenderTargetD3D *source, RenderTargetD3D **outRT) override;
 
-    // Framebuffer creation
-    FramebufferImpl *createFramebuffer(const gl::FramebufferState &data) override;
-
-    // Shader creation
-    ShaderImpl *createShader(const gl::ShaderState &data) override;
-    ProgramImpl *createProgram(const gl::ProgramState &data) override;
-
     // Shader operations
     gl::Error loadExecutable(const void *function,
                              size_t length,
@@ -210,7 +224,7 @@
     UniformStorageD3D *createUniformStorage(size_t storageSize) override;
 
     // Image operations
-    virtual ImageD3D *createImage();
+    ImageD3D *createImage() override;
     gl::Error generateMipmap(ImageD3D *dest, ImageD3D *source) override;
     gl::Error generateMipmapsUsingD3D(TextureStorage *storage,
                                       const gl::TextureState &textureState) override;
@@ -219,32 +233,33 @@
     TextureStorage *createTextureStorageExternal(
         egl::Stream *stream,
         const egl::Stream::GLTextureDescription &desc) override;
-    virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly);
-    virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly);
-    virtual TextureStorage *createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels);
-    virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels);
-
-    // Texture creation
-    TextureImpl *createTexture(const gl::TextureState &state) override;
-
-    // Renderbuffer creation
-    virtual RenderbufferImpl *createRenderbuffer();
+    TextureStorage *createTextureStorage2D(GLenum internalformat,
+                                           bool renderTarget,
+                                           GLsizei width,
+                                           GLsizei height,
+                                           int levels,
+                                           bool hintLevelZeroOnly) override;
+    TextureStorage *createTextureStorageCube(GLenum internalformat,
+                                             bool renderTarget,
+                                             int size,
+                                             int levels,
+                                             bool hintLevelZeroOnly) override;
+    TextureStorage *createTextureStorage3D(GLenum internalformat,
+                                           bool renderTarget,
+                                           GLsizei width,
+                                           GLsizei height,
+                                           GLsizei depth,
+                                           int levels) override;
+    TextureStorage *createTextureStorage2DArray(GLenum internalformat,
+                                                bool renderTarget,
+                                                GLsizei width,
+                                                GLsizei height,
+                                                GLsizei depth,
+                                                int levels) override;
 
     // Buffer creation
-    virtual BufferImpl *createBuffer();
-    virtual VertexBuffer *createVertexBuffer();
-    virtual IndexBuffer *createIndexBuffer();
-
-    // Vertex Array creation
-    VertexArrayImpl *createVertexArray(const gl::VertexArrayState &data) override;
-
-    // Query and Fence creation
-    virtual QueryImpl *createQuery(GLenum type);
-    virtual FenceNVImpl *createFenceNV();
-    virtual FenceSyncImpl *createFenceSync();
-
-    // Transform Feedback creation
-    virtual TransformFeedbackImpl* createTransformFeedback();
+    VertexBuffer *createVertexBuffer() override;
+    IndexBuffer *createIndexBuffer() override;
 
     // Stream Creation
     StreamProducerImpl *createStreamProducerD3DTextureNV12(
@@ -256,8 +271,6 @@
     virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget,
                                               GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea);
 
-    void syncState(const gl::State &state, const gl::State::DirtyBits &bitmask) override;
-
     // D3D9-renderer specific methods
     gl::Error boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest);
 
@@ -278,6 +291,25 @@
 
     egl::Error getEGLDevice(DeviceImpl **device) override;
 
+    StateManager9 *getStateManager() { return &mStateManager; }
+
+    gl::Error genericDrawArrays(Context9 *context,
+                                GLenum mode,
+                                GLint first,
+                                GLsizei count,
+                                GLsizei instances);
+
+    gl::Error genericDrawElements(Context9 *context,
+                                  GLenum mode,
+                                  GLsizei count,
+                                  GLenum type,
+                                  const GLvoid *indices,
+                                  GLsizei instances,
+                                  const gl::IndexRange &indexRange);
+
+    // Necessary hack for default framebuffers in D3D.
+    FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) override;
+
   protected:
     void createAnnotator() override;
     gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd) override;
@@ -316,7 +348,9 @@
 
     gl::Error getCountingIB(size_t count, StaticIndexBufferInterface **outIB);
 
-    gl::Error getNullColorbuffer(const gl::FramebufferAttachment *depthbuffer, const gl::FramebufferAttachment **outColorBuffer);
+    gl::Error getNullColorbuffer(GLImplFactory *implFactory,
+                                 const gl::FramebufferAttachment *depthbuffer,
+                                 const gl::FramebufferAttachment **outColorBuffer);
 
     D3DPOOL getBufferPool(DWORD usage) const;
 
@@ -411,5 +445,6 @@
     std::vector<TranslatedAttribute> mTranslatedAttribCache;
 };
 
-}
+}  // namespace rx
+
 #endif // LIBANGLE_RENDERER_D3D_D3D9_RENDERER9_H_
diff --git a/src/libANGLE/renderer/gl/ContextGL.cpp b/src/libANGLE/renderer/gl/ContextGL.cpp
new file mode 100644
index 0000000..ded0eca
--- /dev/null
+++ b/src/libANGLE/renderer/gl/ContextGL.cpp
@@ -0,0 +1,268 @@
+//
+// Copyright 2016 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.
+//
+// ContextGL:
+//   OpenGL-specific functionality associated with a GL Context.
+//
+
+#include "libANGLE/renderer/gl/ContextGL.h"
+
+#include "libANGLE/renderer/gl/BufferGL.h"
+#include "libANGLE/renderer/gl/CompilerGL.h"
+#include "libANGLE/renderer/gl/FenceNVGL.h"
+#include "libANGLE/renderer/gl/FenceSyncGL.h"
+#include "libANGLE/renderer/gl/FramebufferGL.h"
+#include "libANGLE/renderer/gl/ProgramGL.h"
+#include "libANGLE/renderer/gl/QueryGL.h"
+#include "libANGLE/renderer/gl/RenderbufferGL.h"
+#include "libANGLE/renderer/gl/RendererGL.h"
+#include "libANGLE/renderer/gl/SamplerGL.h"
+#include "libANGLE/renderer/gl/ShaderGL.h"
+#include "libANGLE/renderer/gl/StateManagerGL.h"
+#include "libANGLE/renderer/gl/TextureGL.h"
+#include "libANGLE/renderer/gl/TransformFeedbackGL.h"
+#include "libANGLE/renderer/gl/VertexArrayGL.h"
+
+namespace rx
+{
+
+ContextGL::ContextGL(const gl::ContextState &state, RendererGL *renderer)
+    : ContextImpl(state), mRenderer(renderer)
+{
+}
+
+ContextGL::~ContextGL()
+{
+}
+
+gl::Error ContextGL::initialize()
+{
+    return gl::NoError();
+}
+
+CompilerImpl *ContextGL::createCompiler()
+{
+    return new CompilerGL(getFunctions());
+}
+
+ShaderImpl *ContextGL::createShader(const gl::ShaderState &data)
+{
+    return new ShaderGL(data, getFunctions(), getWorkaroundsGL());
+}
+
+ProgramImpl *ContextGL::createProgram(const gl::ProgramState &data)
+{
+    return new ProgramGL(data, getFunctions(), getWorkaroundsGL(), getStateManager());
+}
+
+FramebufferImpl *ContextGL::createFramebuffer(const gl::FramebufferState &data)
+{
+    return new FramebufferGL(data, getFunctions(), getStateManager(), getWorkaroundsGL(), false);
+}
+
+TextureImpl *ContextGL::createTexture(const gl::TextureState &state)
+{
+    return new TextureGL(state, getFunctions(), getWorkaroundsGL(), getStateManager(),
+                         mRenderer->getBlitter());
+}
+
+RenderbufferImpl *ContextGL::createRenderbuffer()
+{
+    return new RenderbufferGL(getFunctions(), getWorkaroundsGL(), getStateManager(),
+                              getNativeTextureCaps());
+}
+
+BufferImpl *ContextGL::createBuffer()
+{
+    return new BufferGL(getFunctions(), getStateManager());
+}
+
+VertexArrayImpl *ContextGL::createVertexArray(const gl::VertexArrayState &data)
+{
+    return new VertexArrayGL(data, getFunctions(), getStateManager());
+}
+
+QueryImpl *ContextGL::createQuery(GLenum type)
+{
+    return new QueryGL(type, getFunctions(), getStateManager());
+}
+
+FenceNVImpl *ContextGL::createFenceNV()
+{
+    return new FenceNVGL(getFunctions());
+}
+
+FenceSyncImpl *ContextGL::createFenceSync()
+{
+    return new FenceSyncGL(getFunctions());
+}
+
+TransformFeedbackImpl *ContextGL::createTransformFeedback()
+{
+    return new TransformFeedbackGL(getFunctions(), getStateManager(),
+                                   getNativeCaps().maxTransformFeedbackSeparateComponents);
+}
+
+SamplerImpl *ContextGL::createSampler()
+{
+    return new SamplerGL(getFunctions(), getStateManager());
+}
+
+gl::Error ContextGL::flush()
+{
+    return mRenderer->flush();
+}
+
+gl::Error ContextGL::finish()
+{
+    return mRenderer->finish();
+}
+
+gl::Error ContextGL::drawArrays(GLenum mode, GLint first, GLsizei count)
+{
+    return mRenderer->drawArrays(mState, mode, first, count);
+}
+
+gl::Error ContextGL::drawArraysInstanced(GLenum mode,
+                                         GLint first,
+                                         GLsizei count,
+                                         GLsizei instanceCount)
+{
+    return mRenderer->drawArraysInstanced(mState, mode, first, count, instanceCount);
+}
+
+gl::Error ContextGL::drawElements(GLenum mode,
+                                  GLsizei count,
+                                  GLenum type,
+                                  const GLvoid *indices,
+                                  const gl::IndexRange &indexRange)
+{
+    return mRenderer->drawElements(mState, mode, count, type, indices, indexRange);
+}
+
+gl::Error ContextGL::drawElementsInstanced(GLenum mode,
+                                           GLsizei count,
+                                           GLenum type,
+                                           const GLvoid *indices,
+                                           GLsizei instances,
+                                           const gl::IndexRange &indexRange)
+{
+    return mRenderer->drawElementsInstanced(mState, mode, count, type, indices, instances,
+                                            indexRange);
+}
+
+gl::Error ContextGL::drawRangeElements(GLenum mode,
+                                       GLuint start,
+                                       GLuint end,
+                                       GLsizei count,
+                                       GLenum type,
+                                       const GLvoid *indices,
+                                       const gl::IndexRange &indexRange)
+{
+    return mRenderer->drawRangeElements(mState, mode, start, end, count, type, indices, indexRange);
+}
+
+void ContextGL::notifyDeviceLost()
+{
+    mRenderer->notifyDeviceLost();
+}
+
+bool ContextGL::isDeviceLost() const
+{
+    return mRenderer->isDeviceLost();
+}
+
+bool ContextGL::testDeviceLost()
+{
+    return mRenderer->testDeviceLost();
+}
+
+bool ContextGL::testDeviceResettable()
+{
+    return mRenderer->testDeviceResettable();
+}
+
+std::string ContextGL::getVendorString() const
+{
+    return mRenderer->getVendorString();
+}
+
+std::string ContextGL::getRendererDescription() const
+{
+    return mRenderer->getRendererDescription();
+}
+
+void ContextGL::insertEventMarker(GLsizei length, const char *marker)
+{
+    mRenderer->insertEventMarker(length, marker);
+}
+
+void ContextGL::pushGroupMarker(GLsizei length, const char *marker)
+{
+    mRenderer->pushGroupMarker(length, marker);
+}
+
+void ContextGL::popGroupMarker()
+{
+    mRenderer->popGroupMarker();
+}
+
+void ContextGL::syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits)
+{
+    mRenderer->getStateManager()->syncState(state, dirtyBits);
+}
+
+GLint ContextGL::getGPUDisjoint()
+{
+    return mRenderer->getGPUDisjoint();
+}
+
+GLint64 ContextGL::getTimestamp()
+{
+    return mRenderer->getTimestamp();
+}
+
+void ContextGL::onMakeCurrent(const gl::ContextState &data)
+{
+    // Queries need to be paused/resumed on context switches
+    mRenderer->getStateManager()->onMakeCurrent(data);
+}
+
+const gl::Caps &ContextGL::getNativeCaps() const
+{
+    return mRenderer->getNativeCaps();
+}
+
+const gl::TextureCapsMap &ContextGL::getNativeTextureCaps() const
+{
+    return mRenderer->getNativeTextureCaps();
+}
+
+const gl::Extensions &ContextGL::getNativeExtensions() const
+{
+    return mRenderer->getNativeExtensions();
+}
+
+const gl::Limitations &ContextGL::getNativeLimitations() const
+{
+    return mRenderer->getNativeLimitations();
+}
+
+const FunctionsGL *ContextGL::getFunctions() const
+{
+    return mRenderer->getFunctions();
+}
+
+StateManagerGL *ContextGL::getStateManager()
+{
+    return mRenderer->getStateManager();
+}
+
+const WorkaroundsGL &ContextGL::getWorkaroundsGL()
+{
+    return mRenderer->getWorkarounds();
+}
+
+}  // namespace rx
diff --git a/src/libANGLE/renderer/gl/ContextGL.h b/src/libANGLE/renderer/gl/ContextGL.h
index a20dd75..5dd73b9 100644
--- a/src/libANGLE/renderer/gl/ContextGL.h
+++ b/src/libANGLE/renderer/gl/ContextGL.h
@@ -12,16 +12,125 @@
 
 #include "libANGLE/renderer/ContextImpl.h"
 
+namespace sh
+{
+struct BlockMemberInfo;
+}
+
 namespace rx
 {
+class FunctionsGL;
+class RendererGL;
+class StateManagerGL;
+struct WorkaroundsGL;
 
 class ContextGL : public ContextImpl
 {
   public:
-    ContextGL(const gl::ContextState &state) : ContextImpl(state) {}
-    ~ContextGL() override {}
+    ContextGL(const gl::ContextState &state, RendererGL *renderer);
+    ~ContextGL() override;
 
-    gl::Error initialize(Renderer *renderer) override { return gl::NoError(); }
+    gl::Error initialize() override;
+
+    // Shader creation
+    CompilerImpl *createCompiler() override;
+    ShaderImpl *createShader(const gl::ShaderState &data) override;
+    ProgramImpl *createProgram(const gl::ProgramState &data) override;
+
+    // Framebuffer creation
+    FramebufferImpl *createFramebuffer(const gl::FramebufferState &data) override;
+
+    // Texture creation
+    TextureImpl *createTexture(const gl::TextureState &state) override;
+
+    // Renderbuffer creation
+    RenderbufferImpl *createRenderbuffer() override;
+
+    // Buffer creation
+    BufferImpl *createBuffer() override;
+
+    // Vertex Array creation
+    VertexArrayImpl *createVertexArray(const gl::VertexArrayState &data) override;
+
+    // Query and Fence creation
+    QueryImpl *createQuery(GLenum type) override;
+    FenceNVImpl *createFenceNV() override;
+    FenceSyncImpl *createFenceSync() override;
+
+    // Transform Feedback creation
+    TransformFeedbackImpl *createTransformFeedback() override;
+
+    // Sampler object creation
+    SamplerImpl *createSampler() override;
+
+    // Flush and finish.
+    gl::Error flush() override;
+    gl::Error finish() override;
+
+    // Drawing methods.
+    gl::Error drawArrays(GLenum mode, GLint first, GLsizei count) override;
+    gl::Error drawArraysInstanced(GLenum mode,
+                                  GLint first,
+                                  GLsizei count,
+                                  GLsizei instanceCount) override;
+
+    gl::Error drawElements(GLenum mode,
+                           GLsizei count,
+                           GLenum type,
+                           const GLvoid *indices,
+                           const gl::IndexRange &indexRange) override;
+    gl::Error drawElementsInstanced(GLenum mode,
+                                    GLsizei count,
+                                    GLenum type,
+                                    const GLvoid *indices,
+                                    GLsizei instances,
+                                    const gl::IndexRange &indexRange) override;
+    gl::Error drawRangeElements(GLenum mode,
+                                GLuint start,
+                                GLuint end,
+                                GLsizei count,
+                                GLenum type,
+                                const GLvoid *indices,
+                                const gl::IndexRange &indexRange) override;
+
+    // TODO(jmadill): Investigate proper impl methods for this.
+    void notifyDeviceLost() override;
+    bool isDeviceLost() const override;
+    bool testDeviceLost() override;
+    bool testDeviceResettable() override;
+
+    // Vendor and description strings.
+    std::string getVendorString() const override;
+    std::string getRendererDescription() const override;
+
+    // Debug markers.
+    void insertEventMarker(GLsizei length, const char *marker) override;
+    void pushGroupMarker(GLsizei length, const char *marker) override;
+    void popGroupMarker() override;
+
+    // State sync with dirty bits.
+    void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits) override;
+
+    // Disjoint timer queries
+    GLint getGPUDisjoint() override;
+    GLint64 getTimestamp() override;
+
+    // Context switching
+    void onMakeCurrent(const gl::ContextState &data) override;
+
+    // Caps queries
+    const gl::Caps &getNativeCaps() const override;
+    const gl::TextureCapsMap &getNativeTextureCaps() const override;
+    const gl::Extensions &getNativeExtensions() const override;
+    const gl::Limitations &getNativeLimitations() const override;
+
+    // Handle helpers
+    const FunctionsGL *getFunctions() const;
+    StateManagerGL *getStateManager();
+    const WorkaroundsGL &getWorkaroundsGL();
+
+  private:
+    RendererGL *mRenderer;
 };
 
 }  // namespace rx
diff --git a/src/libANGLE/renderer/gl/DisplayGL.cpp b/src/libANGLE/renderer/gl/DisplayGL.cpp
index 57de7fb..fa443ca 100644
--- a/src/libANGLE/renderer/gl/DisplayGL.cpp
+++ b/src/libANGLE/renderer/gl/DisplayGL.cpp
@@ -9,9 +9,9 @@
 #include "libANGLE/renderer/gl/DisplayGL.h"
 
 #include "libANGLE/AttributeMap.h"
-#include "libANGLE/Context.h"
 #include "libANGLE/Display.h"
 #include "libANGLE/Surface.h"
+#include "libANGLE/renderer/gl/ContextGL.h"
 #include "libANGLE/renderer/gl/RendererGL.h"
 #include "libANGLE/renderer/gl/SurfaceGL.h"
 
@@ -55,12 +55,10 @@
     return nullptr;
 }
 
-gl::Context *DisplayGL::createContext(const egl::Config *config,
-                                      const gl::Context *shareContext,
-                                      const egl::AttributeMap &attribs)
+ContextImpl *DisplayGL::createContext(const gl::ContextState &state)
 {
     ASSERT(mRenderer != nullptr);
-    return new gl::Context(config, shareContext, mRenderer, attribs);
+    return new ContextGL(state, mRenderer);
 }
 
 StreamProducerImpl *DisplayGL::createStreamProducerD3DTextureNV12(
diff --git a/src/libANGLE/renderer/gl/DisplayGL.h b/src/libANGLE/renderer/gl/DisplayGL.h
index 2670b7a..9a300c1 100644
--- a/src/libANGLE/renderer/gl/DisplayGL.h
+++ b/src/libANGLE/renderer/gl/DisplayGL.h
@@ -30,9 +30,7 @@
                            egl::ImageSibling *buffer,
                            const egl::AttributeMap &attribs) override;
 
-    gl::Context *createContext(const egl::Config *config,
-                               const gl::Context *shareContext,
-                               const egl::AttributeMap &attribs) override;
+    ContextImpl *createContext(const gl::ContextState &state) override;
 
     StreamProducerImpl *createStreamProducerD3DTextureNV12(
         egl::Stream::ConsumerType consumerType,
diff --git a/src/libANGLE/renderer/gl/ProgramGL.cpp b/src/libANGLE/renderer/gl/ProgramGL.cpp
index fcd5cfa..a13aa56 100644
--- a/src/libANGLE/renderer/gl/ProgramGL.cpp
+++ b/src/libANGLE/renderer/gl/ProgramGL.cpp
@@ -14,6 +14,7 @@
 #include "libANGLE/renderer/gl/ShaderGL.h"
 #include "libANGLE/renderer/gl/StateManagerGL.h"
 #include "libANGLE/renderer/gl/WorkaroundsGL.h"
+#include "libANGLE/Uniform.h"
 #include "platform/Platform.h"
 
 namespace rx
diff --git a/src/libANGLE/renderer/gl/RendererGL.cpp b/src/libANGLE/renderer/gl/RendererGL.cpp
index 70cc363..8fbdca9 100644
--- a/src/libANGLE/renderer/gl/RendererGL.cpp
+++ b/src/libANGLE/renderer/gl/RendererGL.cpp
@@ -82,16 +82,16 @@
 {
 
 RendererGL::RendererGL(const FunctionsGL *functions, const egl::AttributeMap &attribMap)
-    : Renderer(),
-      mMaxSupportedESVersion(0, 0),
+    : mMaxSupportedESVersion(0, 0),
       mFunctions(functions),
       mStateManager(nullptr),
       mBlitter(nullptr),
       mHasDebugOutput(false),
-      mSkipDrawCalls(false)
+      mSkipDrawCalls(false),
+      mCapsInitialized(false)
 {
     ASSERT(mFunctions);
-    mStateManager = new StateManagerGL(mFunctions, getRendererCaps());
+    mStateManager = new StateManagerGL(mFunctions, getNativeCaps());
     nativegl_gl::GenerateWorkarounds(mFunctions, &mWorkarounds);
     mBlitter = new BlitGL(functions, mWorkarounds, mStateManager);
 
@@ -157,18 +157,14 @@
                                  GLint first,
                                  GLsizei count)
 {
-    gl::Error error = mStateManager->setDrawArraysState(data, first, count, 0);
-    if (error.isError())
-    {
-        return error;
-    }
+    ANGLE_TRY(mStateManager->setDrawArraysState(data, first, count, 0));
 
     if (!mSkipDrawCalls)
     {
         mFunctions->drawArrays(mode, first, count);
     }
 
-    return gl::Error(GL_NO_ERROR);
+    return gl::NoError();
 }
 
 gl::Error RendererGL::drawArraysInstanced(const gl::ContextState &data,
@@ -177,18 +173,14 @@
                                           GLsizei count,
                                           GLsizei instanceCount)
 {
-    gl::Error error = mStateManager->setDrawArraysState(data, first, count, instanceCount);
-    if (error.isError())
-    {
-        return error;
-    }
+    ANGLE_TRY(mStateManager->setDrawArraysState(data, first, count, instanceCount));
 
     if (!mSkipDrawCalls)
     {
         mFunctions->drawArraysInstanced(mode, first, count, instanceCount);
     }
 
-    return gl::Error(GL_NO_ERROR);
+    return gl::NoError();
 }
 
 gl::Error RendererGL::drawElements(const gl::ContextState &data,
@@ -198,20 +190,15 @@
                                    const GLvoid *indices,
                                    const gl::IndexRange &indexRange)
 {
-    const GLvoid *drawIndexPointer = nullptr;
-    gl::Error error =
-        mStateManager->setDrawElementsState(data, count, type, indices, 0, &drawIndexPointer);
-    if (error.isError())
-    {
-        return error;
-    }
+    const GLvoid *drawIndexPtr = nullptr;
+    ANGLE_TRY(mStateManager->setDrawElementsState(data, count, type, indices, 0, &drawIndexPtr));
 
     if (!mSkipDrawCalls)
     {
-        mFunctions->drawElements(mode, count, type, drawIndexPointer);
+        mFunctions->drawElements(mode, count, type, drawIndexPtr);
     }
 
-    return gl::Error(GL_NO_ERROR);
+    return gl::NoError();
 }
 
 gl::Error RendererGL::drawElementsInstanced(const gl::ContextState &data,
@@ -223,19 +210,15 @@
                                             const gl::IndexRange &indexRange)
 {
     const GLvoid *drawIndexPointer = nullptr;
-    gl::Error error = mStateManager->setDrawElementsState(data, count, type, indices, instances,
-                                                          &drawIndexPointer);
-    if (error.isError())
-    {
-        return error;
-    }
+    ANGLE_TRY(mStateManager->setDrawElementsState(data, count, type, indices, instances,
+                                                  &drawIndexPointer));
 
     if (!mSkipDrawCalls)
     {
         mFunctions->drawElementsInstanced(mode, count, type, drawIndexPointer, instances);
     }
 
-    return gl::Error(GL_NO_ERROR);
+    return gl::NoError();
 }
 
 gl::Error RendererGL::drawRangeElements(const gl::ContextState &data,
@@ -248,12 +231,8 @@
                                         const gl::IndexRange &indexRange)
 {
     const GLvoid *drawIndexPointer = nullptr;
-    gl::Error error =
-        mStateManager->setDrawElementsState(data, count, type, indices, 0, &drawIndexPointer);
-    if (error.isError())
-    {
-        return error;
-    }
+    ANGLE_TRY(
+        mStateManager->setDrawElementsState(data, count, type, indices, 0, &drawIndexPointer));
 
     if (!mSkipDrawCalls)
     {
@@ -265,73 +244,7 @@
 
 ContextImpl *RendererGL::createContext(const gl::ContextState &state)
 {
-    return new ContextGL(state);
-}
-
-CompilerImpl *RendererGL::createCompiler()
-{
-    return new CompilerGL(mFunctions);
-}
-
-ShaderImpl *RendererGL::createShader(const gl::ShaderState &data)
-{
-    return new ShaderGL(data, mFunctions, mWorkarounds);
-}
-
-ProgramImpl *RendererGL::createProgram(const gl::ProgramState &data)
-{
-    return new ProgramGL(data, mFunctions, mWorkarounds, mStateManager);
-}
-
-FramebufferImpl *RendererGL::createFramebuffer(const gl::FramebufferState &data)
-{
-    return new FramebufferGL(data, mFunctions, mStateManager, mWorkarounds, false);
-}
-
-TextureImpl *RendererGL::createTexture(const gl::TextureState &state)
-{
-    return new TextureGL(state, mFunctions, mWorkarounds, mStateManager, mBlitter);
-}
-
-RenderbufferImpl *RendererGL::createRenderbuffer()
-{
-    return new RenderbufferGL(mFunctions, mWorkarounds, mStateManager, getRendererTextureCaps());
-}
-
-BufferImpl *RendererGL::createBuffer()
-{
-    return new BufferGL(mFunctions, mStateManager);
-}
-
-VertexArrayImpl *RendererGL::createVertexArray(const gl::VertexArrayState &data)
-{
-    return new VertexArrayGL(data, mFunctions, mStateManager);
-}
-
-QueryImpl *RendererGL::createQuery(GLenum type)
-{
-    return new QueryGL(type, mFunctions, mStateManager);
-}
-
-FenceNVImpl *RendererGL::createFenceNV()
-{
-    return new FenceNVGL(mFunctions);
-}
-
-FenceSyncImpl *RendererGL::createFenceSync()
-{
-    return new FenceSyncGL(mFunctions);
-}
-
-TransformFeedbackImpl *RendererGL::createTransformFeedback()
-{
-    return new TransformFeedbackGL(mFunctions, mStateManager,
-                                   getRendererCaps().maxTransformFeedbackSeparateComponents);
-}
-
-SamplerImpl *RendererGL::createSampler()
-{
-    return new SamplerGL(mFunctions, mStateManager);
+    return new ContextGL(state, this);
 }
 
 void RendererGL::insertEventMarker(GLsizei length, const char *marker)
@@ -410,7 +323,7 @@
 const gl::Version &RendererGL::getMaxSupportedESVersion() const
 {
     // Force generation of caps
-    getRendererCaps();
+    getNativeCaps();
 
     return mMaxSupportedESVersion;
 }
@@ -422,11 +335,6 @@
     nativegl_gl::GenerateCaps(mFunctions, outCaps, outTextureCaps, outExtensions, &mMaxSupportedESVersion);
 }
 
-void RendererGL::syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits)
-{
-    mStateManager->syncState(state, dirtyBits);
-}
-
 GLint RendererGL::getGPUDisjoint()
 {
     // TODO(ewell): On GLES backends we should find a way to reliably query disjoint events
@@ -440,9 +348,37 @@
     return result;
 }
 
-void RendererGL::onMakeCurrent(const gl::ContextState &data)
+void RendererGL::ensureCapsInitialized() const
 {
-    // Queries need to be paused/resumed on context switches
-    mStateManager->onMakeCurrent(data);
+    if (!mCapsInitialized)
+    {
+        generateCaps(&mNativeCaps, &mNativeTextureCaps, &mNativeExtensions, &mNativeLimitations);
+        mCapsInitialized = true;
+    }
 }
+
+const gl::Caps &RendererGL::getNativeCaps() const
+{
+    ensureCapsInitialized();
+    return mNativeCaps;
 }
+
+const gl::TextureCapsMap &RendererGL::getNativeTextureCaps() const
+{
+    ensureCapsInitialized();
+    return mNativeTextureCaps;
+}
+
+const gl::Extensions &RendererGL::getNativeExtensions() const
+{
+    ensureCapsInitialized();
+    return mNativeExtensions;
+}
+
+const gl::Limitations &RendererGL::getNativeLimitations() const
+{
+    ensureCapsInitialized();
+    return mNativeLimitations;
+}
+
+}  // namespace rx
diff --git a/src/libANGLE/renderer/gl/RendererGL.h b/src/libANGLE/renderer/gl/RendererGL.h
index 7925665..be010df 100644
--- a/src/libANGLE/renderer/gl/RendererGL.h
+++ b/src/libANGLE/renderer/gl/RendererGL.h
@@ -9,48 +9,65 @@
 #ifndef LIBANGLE_RENDERER_GL_RENDERERGL_H_
 #define LIBANGLE_RENDERER_GL_RENDERERGL_H_
 
+#include "libANGLE/Caps.h"
+#include "libANGLE/Error.h"
 #include "libANGLE/Version.h"
-#include "libANGLE/renderer/Renderer.h"
 #include "libANGLE/renderer/gl/WorkaroundsGL.h"
 
+namespace gl
+{
+struct ContextState;
+struct IndexRange;
+}
+
+namespace egl
+{
+class AttributeMap;
+}
+
+namespace sh
+{
+struct BlockMemberInfo;
+}
+
 namespace rx
 {
 class BlitGL;
+class ContextImpl;
 class FunctionsGL;
 class StateManagerGL;
 
-class RendererGL : public Renderer
+class RendererGL : angle::NonCopyable
 {
   public:
     RendererGL(const FunctionsGL *functions, const egl::AttributeMap &attribMap);
-    ~RendererGL() override;
+    ~RendererGL();
 
-    gl::Error flush() override;
-    gl::Error finish() override;
+    ContextImpl *createContext(const gl::ContextState &state);
 
-    gl::Error drawArrays(const gl::ContextState &data,
-                         GLenum mode,
-                         GLint first,
-                         GLsizei count) override;
+    gl::Error flush();
+    gl::Error finish();
+
+    gl::Error drawArrays(const gl::ContextState &data, GLenum mode, GLint first, GLsizei count);
     gl::Error drawArraysInstanced(const gl::ContextState &data,
                                   GLenum mode,
                                   GLint first,
                                   GLsizei count,
-                                  GLsizei instanceCount) override;
+                                  GLsizei instanceCount);
 
     gl::Error drawElements(const gl::ContextState &data,
                            GLenum mode,
                            GLsizei count,
                            GLenum type,
                            const GLvoid *indices,
-                           const gl::IndexRange &indexRange) override;
+                           const gl::IndexRange &indexRange);
     gl::Error drawElementsInstanced(const gl::ContextState &data,
                                     GLenum mode,
                                     GLsizei count,
                                     GLenum type,
                                     const GLvoid *indices,
                                     GLsizei instances,
-                                    const gl::IndexRange &indexRange) override;
+                                    const gl::IndexRange &indexRange);
     gl::Error drawRangeElements(const gl::ContextState &data,
                                 GLenum mode,
                                 GLuint start,
@@ -58,71 +75,42 @@
                                 GLsizei count,
                                 GLenum type,
                                 const GLvoid *indices,
-                                const gl::IndexRange &indexRange) override;
-
-    ContextImpl *createContext(const gl::ContextState &state) override;
-
-    // Shader creation
-    CompilerImpl *createCompiler() override;
-    ShaderImpl *createShader(const gl::ShaderState &data) override;
-    ProgramImpl *createProgram(const gl::ProgramState &data) override;
-
-    // Framebuffer creation
-    FramebufferImpl *createFramebuffer(const gl::FramebufferState &data) override;
-
-    // Texture creation
-    TextureImpl *createTexture(const gl::TextureState &state) override;
-
-    // Renderbuffer creation
-    RenderbufferImpl *createRenderbuffer() override;
-
-    // Buffer creation
-    BufferImpl *createBuffer() override;
-
-    // Vertex Array creation
-    VertexArrayImpl *createVertexArray(const gl::VertexArrayState &data) override;
-
-    // Query and Fence creation
-    QueryImpl *createQuery(GLenum type) override;
-    FenceNVImpl *createFenceNV() override;
-    FenceSyncImpl *createFenceSync() override;
-
-    // Transform Feedback creation
-    TransformFeedbackImpl *createTransformFeedback() override;
-
-    // Sampler object creation
-    SamplerImpl *createSampler() override;
+                                const gl::IndexRange &indexRange);
 
     // EXT_debug_marker
-    void insertEventMarker(GLsizei length, const char *marker) override;
-    void pushGroupMarker(GLsizei length, const char *marker) override;
-    void popGroupMarker() override;
+    void insertEventMarker(GLsizei length, const char *marker);
+    void pushGroupMarker(GLsizei length, const char *marker);
+    void popGroupMarker();
 
     // lost device
-    void notifyDeviceLost() override;
-    bool isDeviceLost() const override;
-    bool testDeviceLost() override;
-    bool testDeviceResettable() override;
+    void notifyDeviceLost();
+    bool isDeviceLost() const;
+    bool testDeviceLost();
+    bool testDeviceResettable();
 
-    std::string getVendorString() const override;
-    std::string getRendererDescription() const override;
+    std::string getVendorString() const;
+    std::string getRendererDescription() const;
 
-    void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits) override;
-
-    GLint getGPUDisjoint() override;
-    GLint64 getTimestamp() override;
-
-    void onMakeCurrent(const gl::ContextState &data) override;
+    GLint getGPUDisjoint();
+    GLint64 getTimestamp();
 
     const gl::Version &getMaxSupportedESVersion() const;
     const FunctionsGL *getFunctions() const { return mFunctions; }
     StateManagerGL *getStateManager() const { return mStateManager; }
     const WorkaroundsGL &getWorkarounds() const { return mWorkarounds; }
+    BlitGL *getBlitter() const { return mBlitter; }
+
+    const gl::Caps &getNativeCaps() const;
+    const gl::TextureCapsMap &getNativeTextureCaps() const;
+    const gl::Extensions &getNativeExtensions() const;
+    const gl::Limitations &getNativeLimitations() const;
 
   private:
-    void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap* outTextureCaps,
+    void ensureCapsInitialized() const;
+    void generateCaps(gl::Caps *outCaps,
+                      gl::TextureCapsMap *outTextureCaps,
                       gl::Extensions *outExtensions,
-                      gl::Limitations *outLimitations) const override;
+                      gl::Limitations *outLimitations) const;
 
     mutable gl::Version mMaxSupportedESVersion;
 
@@ -137,8 +125,14 @@
 
     // For performance debugging
     bool mSkipDrawCalls;
+
+    mutable bool mCapsInitialized;
+    mutable gl::Caps mNativeCaps;
+    mutable gl::TextureCapsMap mNativeTextureCaps;
+    mutable gl::Extensions mNativeExtensions;
+    mutable gl::Limitations mNativeLimitations;
 };
 
-}
+}  // namespace rx
 
 #endif // LIBANGLE_RENDERER_GL_RENDERERGL_H_
diff --git a/src/libGLESv2.gypi b/src/libGLESv2.gypi
index 4559f0c..008e408 100644
--- a/src/libGLESv2.gypi
+++ b/src/libGLESv2.gypi
@@ -137,6 +137,7 @@
             'libANGLE/queryconversions.h',
             'libANGLE/renderer/BufferImpl.h',
             'libANGLE/renderer/CompilerImpl.h',
+            'libANGLE/renderer/ContextImpl.cpp',
             'libANGLE/renderer/ContextImpl.h',
             'libANGLE/renderer/DeviceImpl.cpp',
             'libANGLE/renderer/DeviceImpl.h',
@@ -151,8 +152,6 @@
             'libANGLE/renderer/ProgramImpl.h',
             'libANGLE/renderer/QueryImpl.h',
             'libANGLE/renderer/RenderbufferImpl.h',
-            'libANGLE/renderer/Renderer.cpp',
-            'libANGLE/renderer/Renderer.h',
             'libANGLE/renderer/SamplerImpl.h',
             'libANGLE/renderer/ShaderImpl.h',
             'libANGLE/renderer/StreamProducerImpl.h',
@@ -247,6 +246,7 @@
             'libANGLE/renderer/d3d/d3d9/Blit9.h',
             'libANGLE/renderer/d3d/d3d9/Buffer9.cpp',
             'libANGLE/renderer/d3d/d3d9/Buffer9.h',
+            'libANGLE/renderer/d3d/d3d9/Context9.cpp',
             'libANGLE/renderer/d3d/d3d9/Context9.h',
             'libANGLE/renderer/d3d/d3d9/DebugAnnotator9.cpp',
             'libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h',
@@ -299,6 +299,7 @@
             'libANGLE/renderer/d3d/d3d11/Buffer11.h',
             'libANGLE/renderer/d3d/d3d11/Clear11.cpp',
             'libANGLE/renderer/d3d/d3d11/Clear11.h',
+            'libANGLE/renderer/d3d/d3d11/Context11.cpp',
             'libANGLE/renderer/d3d/d3d11/Context11.h',
             'libANGLE/renderer/d3d/d3d11/copyvertex.h',
             'libANGLE/renderer/d3d/d3d11/copyvertex.inl',
@@ -431,6 +432,7 @@
             'libANGLE/renderer/gl/BufferGL.h',
             'libANGLE/renderer/gl/CompilerGL.cpp',
             'libANGLE/renderer/gl/CompilerGL.h',
+            'libANGLE/renderer/gl/ContextGL.cpp',
             'libANGLE/renderer/gl/ContextGL.h',
             'libANGLE/renderer/gl/DisplayGL.cpp',
             'libANGLE/renderer/gl/DisplayGL.h',
diff --git a/src/tests/angle_unittests_utils.h b/src/tests/angle_unittests_utils.h
index ab13126..9ece611 100644
--- a/src/tests/angle_unittests_utils.h
+++ b/src/tests/angle_unittests_utils.h
@@ -94,10 +94,7 @@
     MOCK_METHOD3(createPixmapSurface,
                  SurfaceImpl *(const egl::Config *, NativePixmapType, const egl::AttributeMap &));
     MOCK_METHOD3(createImage, ImageImpl *(EGLenum, egl::ImageSibling *, const egl::AttributeMap &));
-    MOCK_METHOD3(createContext,
-                 gl::Context *(const egl::Config *,
-                               const gl::Context *,
-                               const egl::AttributeMap &));
+    MOCK_METHOD1(createContext, ContextImpl *(const gl::ContextState &));
     MOCK_METHOD2(createStreamProducerD3DTextureNV12,
                  StreamProducerImpl *(egl::Stream::ConsumerType, const egl::AttributeMap &));
 };
diff --git a/src/tests/gl_tests/D3D11EmulatedIndexedBufferTest.cpp b/src/tests/gl_tests/D3D11EmulatedIndexedBufferTest.cpp
index 01c9832..5cdcb96 100644
--- a/src/tests/gl_tests/D3D11EmulatedIndexedBufferTest.cpp
+++ b/src/tests/gl_tests/D3D11EmulatedIndexedBufferTest.cpp
@@ -10,8 +10,9 @@
 
 #include "libANGLE/angletypes.h"
 #include "libANGLE/Context.h"
-#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
 #include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
+#include "libANGLE/renderer/d3d/d3d11/Context11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
 #include "libANGLE/renderer/d3d/IndexDataManager.h"
 #include "test_utils/ANGLETest.h"
 #include "test_utils/angle_test_instantiate.h"
@@ -31,7 +32,8 @@
         ASSERT_EQ(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, GetParam().getRenderer());
 
         gl::Context *context = reinterpret_cast<gl::Context *>(getEGLWindow()->getContext());
-        mRenderer = rx::GetAs<rx::Renderer11>(context->getRenderer());
+        rx::Context11 *context11 = rx::GetImplAs<rx::Context11>(context);
+        mRenderer                = context11->getRenderer();
 
         mSourceBuffer = new rx::Buffer11(mRenderer);
         GLfloat testData[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f };
diff --git a/src/tests/gl_tests/D3D11FormatTablesTest.cpp b/src/tests/gl_tests/D3D11FormatTablesTest.cpp
index 1c1826e..9aa6cce 100644
--- a/src/tests/gl_tests/D3D11FormatTablesTest.cpp
+++ b/src/tests/gl_tests/D3D11FormatTablesTest.cpp
@@ -10,6 +10,7 @@
 #include "libANGLE/angletypes.h"
 #include "libANGLE/Context.h"
 #include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/d3d/d3d11/Context11.h"
 #include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
 #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
@@ -38,8 +39,9 @@
 
     // Hack the angle!
     gl::Context *context = reinterpret_cast<gl::Context *>(getEGLWindow()->getContext());
-    rx::Renderer11 *renderer = rx::GetAs<rx::Renderer11>(context->getRenderer());
-    const auto &textureCaps = renderer->getRendererTextureCaps();
+    rx::Context11 *context11 = rx::GetImplAs<rx::Context11>(context);
+    rx::Renderer11 *renderer = context11->getRenderer();
+    const auto &textureCaps  = renderer->getNativeTextureCaps();
 
     ID3D11Device *device = renderer->getDevice();
 
diff --git a/src/tests/gl_tests/D3D11InputLayoutCacheTest.cpp b/src/tests/gl_tests/D3D11InputLayoutCacheTest.cpp
index 546399c..7f182d2 100644
--- a/src/tests/gl_tests/D3D11InputLayoutCacheTest.cpp
+++ b/src/tests/gl_tests/D3D11InputLayoutCacheTest.cpp
@@ -10,6 +10,7 @@
 #include <sstream>
 
 #include "libANGLE/Context.h"
+#include "libANGLE/renderer/d3d/d3d11/Context11.h"
 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
 #include "test_utils/ANGLETest.h"
 #include "test_utils/angle_test_instantiate.h"
@@ -65,7 +66,8 @@
 {
     // Hack the ANGLE!
     gl::Context *context = reinterpret_cast<gl::Context *>(getEGLWindow()->getContext());
-    rx::Renderer11 *renderer11 = rx::GetAs<rx::Renderer11>(context->getRenderer());
+    rx::Context11 *context11               = rx::GetImplAs<rx::Context11>(context);
+    rx::Renderer11 *renderer11             = context11->getRenderer();
     rx::InputLayoutCache *inputLayoutCache = renderer11->getInputLayoutCache();
 
     // Clamp the cache size to something tiny