Refactoring Buffers

BUG=angle:681
Change-Id: I6c3809e0b9468dfe38465c55759c2572c21485da
Reviewed-on: https://chromium-review.googlesource.com/204896
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Tested-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libGLESv2/Buffer.cpp b/src/libGLESv2/Buffer.cpp
index a449275..a47b8f4 100644
--- a/src/libGLESv2/Buffer.cpp
+++ b/src/libGLESv2/Buffer.cpp
@@ -10,77 +10,56 @@
 // [OpenGL ES 2.0.24] section 2.9 page 21.
 
 #include "libGLESv2/Buffer.h"
-
-#include "libGLESv2/renderer/d3d/VertexBuffer.h"
-#include "libGLESv2/renderer/d3d/IndexBuffer.h"
-#include "libGLESv2/renderer/BufferStorage.h"
+#include "libGLESv2/renderer/BufferImpl.h"
 #include "libGLESv2/renderer/Renderer.h"
 
 namespace gl
 {
 
-Buffer::Buffer(rx::Renderer *renderer, GLuint id)
+Buffer::Buffer(rx::BufferImpl *impl, GLuint id)
     : RefCountObject(id),
-      mRenderer(renderer),
+      mBuffer(impl),
       mUsage(GL_DYNAMIC_DRAW),
+      mSize(0),
       mAccessFlags(0),
       mMapped(GL_FALSE),
       mMapPointer(NULL),
       mMapOffset(0),
-      mMapLength(0),
-      mBufferStorage(NULL),
-      mStaticVertexBuffer(NULL),
-      mStaticIndexBuffer(NULL),
-      mUnmodifiedDataUse(0)
+      mMapLength(0)
 {
-    mBufferStorage = renderer->createBufferStorage();
 }
 
 Buffer::~Buffer()
 {
-    delete mBufferStorage;
-    delete mStaticVertexBuffer;
-    delete mStaticIndexBuffer;
+    delete mBuffer;
 }
 
 void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
 {
-    mBufferStorage->clear();
-    mIndexRangeCache.clear();
-    mBufferStorage->setData(data, size, 0);
-
     mUsage = usage;
-
-    invalidateStaticData();
-
-    if (usage == GL_STATIC_DRAW)
-    {
-        mStaticVertexBuffer = new rx::StaticVertexBufferInterface(mRenderer);
-        mStaticIndexBuffer = new rx::StaticIndexBufferInterface(mRenderer);
-    }
+    mSize = size;
+    mBuffer->setData(data, size, usage);
 }
 
 void Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset)
 {
-    mBufferStorage->setData(data, size, offset);
-    mIndexRangeCache.invalidateRange(offset, size);
-    invalidateStaticData();
+    mBuffer->setSubData(data, size, offset);
 }
 
 void Buffer::copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size)
 {
-    mBufferStorage->copyData(source->mBufferStorage, size, sourceOffset, destOffset);
-    invalidateStaticData();
+    mBuffer->copySubData(source->getImplementation(), size, sourceOffset, destOffset);
 }
 
 GLvoid *Buffer::mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access)
 {
     ASSERT(!mMapped);
+    ASSERT(offset + length <= mSize);
 
-    void *dataPointer = mBufferStorage->map(access);
+    void *dataPointer = mBuffer->map(offset, length, access);
 
     mMapped = GL_TRUE;
-    mMapPointer = static_cast<GLvoid*>(static_cast<GLubyte*>(dataPointer) + offset);
+    mMapPointer = static_cast<GLvoid*>(static_cast<GLubyte*>(dataPointer));
     mMapOffset = static_cast<GLint64>(offset);
     mMapLength = static_cast<GLint64>(length);
     mAccessFlags = static_cast<GLint>(access);
@@ -92,7 +71,7 @@
 {
     ASSERT(mMapped);
 
-    mBufferStorage->unmap();
+    mBuffer->unmap();
 
     mMapped = GL_FALSE;
     mMapPointer = NULL;
@@ -101,94 +80,10 @@
     mAccessFlags = 0;
 }
 
-rx::BufferStorage *Buffer::getStorage() const
-{
-    return mBufferStorage;
-}
-
-GLint64 Buffer::size() const
-{
-    return static_cast<GLint64>(mBufferStorage->getSize());
-}
-
-GLenum Buffer::usage() const
-{
-    return mUsage;
-}
-
-GLint Buffer::accessFlags() const
-{
-    return mAccessFlags;
-}
-
-GLboolean Buffer::mapped() const
-{
-    return mMapped;
-}
-
-GLvoid *Buffer::mapPointer() const
-{
-    return mMapPointer;
-}
-
-GLint64 Buffer::mapOffset() const
-{
-    return mMapOffset;
-}
-
-GLint64 Buffer::mapLength() const
-{
-    return mMapLength;
-}
-
 void Buffer::markTransformFeedbackUsage()
 {
-    mBufferStorage->markTransformFeedbackUsage();
-    invalidateStaticData();
-}
-
-rx::StaticVertexBufferInterface *Buffer::getStaticVertexBuffer()
-{
-    return mStaticVertexBuffer;
-}
-
-rx::StaticIndexBufferInterface *Buffer::getStaticIndexBuffer()
-{
-    return mStaticIndexBuffer;
-}
-
-void Buffer::invalidateStaticData()
-{
-    if ((mStaticVertexBuffer && mStaticVertexBuffer->getBufferSize() != 0) || (mStaticIndexBuffer && mStaticIndexBuffer->getBufferSize() != 0))
-    {
-        delete mStaticVertexBuffer;
-        mStaticVertexBuffer = NULL;
-
-        delete mStaticIndexBuffer;
-        mStaticIndexBuffer = NULL;
-    }
-
-    mUnmodifiedDataUse = 0;
-}
-
-// Creates static buffers if sufficient used data has been left unmodified
-void Buffer::promoteStaticUsage(int dataSize)
-{
-    if (!mStaticVertexBuffer && !mStaticIndexBuffer)
-    {
-        mUnmodifiedDataUse += dataSize;
-
-        if (mUnmodifiedDataUse > 3 * mBufferStorage->getSize())
-        {
-            mStaticVertexBuffer = new rx::StaticVertexBufferInterface(mRenderer);
-            mStaticIndexBuffer = new rx::StaticIndexBufferInterface(mRenderer);
-        }
-    }
-}
-
-rx::IndexRangeCache *Buffer::getIndexRangeCache()
-{
-    return &mIndexRangeCache;
+    // TODO: Only used by the DX11 backend. Refactor to a more appropriate place.
+    mBuffer->markTransformFeedbackUsage();
 }
 
 }
diff --git a/src/libGLESv2/Buffer.h b/src/libGLESv2/Buffer.h
index 55fbdeb..389c3d4 100644
--- a/src/libGLESv2/Buffer.h
+++ b/src/libGLESv2/Buffer.h
@@ -13,14 +13,11 @@
 
 #include "common/angleutils.h"
 #include "common/RefCountObject.h"
-#include "libGLESv2/renderer/IndexRangeCache.h"
 
 namespace rx
 {
 class Renderer;
-class BufferStorage;
-class StaticIndexBufferInterface;
-class StaticVertexBufferInterface;
+class BufferImpl;
 };
 
 namespace gl
@@ -29,7 +26,7 @@
 class Buffer : public RefCountObject
 {
   public:
-    Buffer(rx::Renderer *renderer, GLuint id);
+    Buffer(rx::BufferImpl *impl, GLuint id);
 
     virtual ~Buffer();
 
@@ -39,43 +36,30 @@
     GLvoid *mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access);
     void unmap();
 
-    GLenum usage() const;
-    GLint accessFlags() const;
-    GLboolean mapped() const;
-    GLvoid *mapPointer() const;
-    GLint64 mapOffset() const;
-    GLint64 mapLength() const;
+    GLenum  getUsage() const { return mUsage; }
+    GLint getAccessFlags() const {  return mAccessFlags; }
+    GLboolean isMapped() const { return mMapped; }
+    GLvoid *getMapPointer() const { return mMapPointer; }
+    GLint64 getMapOffset() const { return mMapOffset; }
+    GLint64 getMapLength() const { return mMapLength; }
+    GLint64 getSize() const { return mSize; }
 
-    rx::BufferStorage *getStorage() const;
-    GLint64 size() const;
+    rx::BufferImpl *getImplementation() const { return mBuffer; }
 
     void markTransformFeedbackUsage();
 
-    rx::StaticVertexBufferInterface *getStaticVertexBuffer();
-    rx::StaticIndexBufferInterface *getStaticIndexBuffer();
-    void invalidateStaticData();
-    void promoteStaticUsage(int dataSize);
-
-    rx::IndexRangeCache *getIndexRangeCache();
-
   private:
     DISALLOW_COPY_AND_ASSIGN(Buffer);
 
-    rx::Renderer *mRenderer;
+    rx::BufferImpl *mBuffer;
+
     GLenum mUsage;
+    GLsizeiptr mSize;
     GLint mAccessFlags;
     GLboolean mMapped;
     GLvoid *mMapPointer;
     GLint64 mMapOffset;
     GLint64 mMapLength;
-
-    rx::BufferStorage *mBufferStorage;
-
-    rx::IndexRangeCache mIndexRangeCache;
-
-    rx::StaticVertexBufferInterface *mStaticVertexBuffer;
-    rx::StaticIndexBufferInterface *mStaticIndexBuffer;
-    unsigned int mUnmodifiedDataUse;
 };
 
 }
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index b0425bd..34d6a24 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -3729,7 +3729,7 @@
         {
             const gl::VertexAttribute &vertexAttrib = getVertexAttribState(attribIndex);
             gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
-            if (vertexAttrib.enabled && boundBuffer && boundBuffer->mapped())
+            if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
             {
                 return true;
             }
@@ -3738,7 +3738,7 @@
     else if (target == GL_ELEMENT_ARRAY_BUFFER)
     {
         Buffer *elementBuffer = getElementArrayBuffer();
-        return (elementBuffer && elementBuffer->mapped());
+        return (elementBuffer && elementBuffer->isMapped());
     }
     else if (target == GL_TRANSFORM_FEEDBACK_BUFFER)
     {
diff --git a/src/libGLESv2/ProgramBinary.cpp b/src/libGLESv2/ProgramBinary.cpp
index 7faad64..b53a61f 100644
--- a/src/libGLESv2/ProgramBinary.cpp
+++ b/src/libGLESv2/ProgramBinary.cpp
@@ -984,7 +984,7 @@
 
         ASSERT(uniformBlock && uniformBuffer);
 
-        if (uniformBuffer->size() < uniformBlock->dataSize)
+        if (uniformBuffer->getSize() < uniformBlock->dataSize)
         {
             // undefined behaviour
             return false;
diff --git a/src/libGLESv2/ResourceManager.cpp b/src/libGLESv2/ResourceManager.cpp
index 4a4df65..660ba6b 100644
--- a/src/libGLESv2/ResourceManager.cpp
+++ b/src/libGLESv2/ResourceManager.cpp
@@ -17,6 +17,7 @@
 #include "libGLESv2/Texture.h"
 #include "libGLESv2/Sampler.h"
 #include "libGLESv2/Fence.h"
+#include "libGLESv2/renderer/Renderer.h"
 
 namespace gl
 {
@@ -362,7 +363,7 @@
 {
     if (buffer != 0 && !getBuffer(buffer))
     {
-        Buffer *bufferObject = new Buffer(mRenderer, buffer);
+        Buffer *bufferObject = new Buffer(mRenderer->createBuffer(), buffer);
         mBufferMap[buffer] = bufferObject;
         bufferObject->addRef();
     }
diff --git a/src/libGLESv2/Texture.cpp b/src/libGLESv2/Texture.cpp
index 9d37ad9..bac5217 100644
--- a/src/libGLESv2/Texture.cpp
+++ b/src/libGLESv2/Texture.cpp
@@ -21,7 +21,7 @@
 #include "libGLESv2/renderer/TextureStorage.h"
 #include "libEGL/Surface.h"
 #include "libGLESv2/Buffer.h"
-#include "libGLESv2/renderer/BufferStorage.h"
+#include "libGLESv2/renderer/BufferImpl.h"
 #include "libGLESv2/renderer/RenderTarget.h"
 
 namespace gl
@@ -309,7 +309,9 @@
         // Do a CPU readback here, if we have an unpack buffer bound and the fast GPU path is not supported
         Buffer *pixelBuffer = unpack.pixelBuffer.get();
         ptrdiff_t offset = reinterpret_cast<ptrdiff_t>(pixels);
-        const void *bufferData = pixelBuffer->getStorage()->getData();
+        // TODO: setImage/subImage is the only place outside of renderer that asks for a buffers raw data.
+        // This functionality should be moved into renderer and the getData method of BufferImpl removed.
+        const void *bufferData = pixelBuffer->getImplementation()->getData();
         pixelData = static_cast<const unsigned char *>(bufferData) + offset;
     }
 
@@ -361,7 +363,9 @@
     {
         Buffer *pixelBuffer = unpack.pixelBuffer.get();
         unsigned int offset = reinterpret_cast<unsigned int>(pixels);
-        const void *bufferData = pixelBuffer->getStorage()->getData();
+        // TODO: setImage/subImage is the only place outside of renderer that asks for a buffers raw data.
+        // This functionality should be moved into renderer and the getData method of BufferImpl removed.
+        const void *bufferData = pixelBuffer->getImplementation()->getData();
         pixelData = static_cast<const unsigned char *>(bufferData) + offset;
     }
 
diff --git a/src/libGLESv2/VertexArray.cpp b/src/libGLESv2/VertexArray.cpp
index 249ae19..16f75d6 100644
--- a/src/libGLESv2/VertexArray.cpp
+++ b/src/libGLESv2/VertexArray.cpp
@@ -19,10 +19,13 @@
       mVertexArray(impl),
       mVertexAttributes(maxAttribs)
 {
+    ASSERT(impl != NULL);
 }
 
 VertexArray::~VertexArray()
 {
+    SafeDelete(mVertexArray);
+
     for (size_t i = 0; i < getMaxAttribs(); i++)
     {
         mVertexAttributes[i].buffer.set(NULL);
diff --git a/src/libGLESv2/libGLESv2.cpp b/src/libGLESv2/libGLESv2.cpp
index 5bd564f..e7f2dc2 100644
--- a/src/libGLESv2/libGLESv2.cpp
+++ b/src/libGLESv2/libGLESv2.cpp
@@ -636,7 +636,7 @@
                 return gl::error(GL_INVALID_OPERATION);
             }
 
-            if (buffer->mapped())
+            if (buffer->isMapped())
             {
                 return gl::error(GL_INVALID_OPERATION);
             }
@@ -647,7 +647,7 @@
                 return gl::error(GL_OUT_OF_MEMORY);
             }
 
-            if (size + offset > buffer->size())
+            if (size + offset > buffer->getSize())
             {
                 return gl::error(GL_INVALID_VALUE);
             }
@@ -2419,22 +2419,22 @@
             switch (pname)
             {
               case GL_BUFFER_USAGE:
-                *params = static_cast<GLint>(buffer->usage());
+                *params = static_cast<GLint>(buffer->getUsage());
                 break;
               case GL_BUFFER_SIZE:
-                *params = gl::clampCast<GLint>(buffer->size());
+                *params = gl::clampCast<GLint>(buffer->getSize());
                 break;
               case GL_BUFFER_ACCESS_FLAGS:
-                *params = buffer->accessFlags();
+                *params = buffer->getAccessFlags();
                 break;
               case GL_BUFFER_MAPPED:
-                *params = static_cast<GLint>(buffer->mapped());
+                *params = static_cast<GLint>(buffer->isMapped());
                 break;
               case GL_BUFFER_MAP_OFFSET:
-                *params = gl::clampCast<GLint>(buffer->mapOffset());
+                *params = gl::clampCast<GLint>(buffer->getMapOffset());
                 break;
               case GL_BUFFER_MAP_LENGTH:
-                *params = gl::clampCast<GLint>(buffer->mapLength());
+                *params = gl::clampCast<GLint>(buffer->getMapLength());
                 break;
               default: UNREACHABLE(); break;
             }
@@ -8077,14 +8077,14 @@
                 return gl::error(GL_INVALID_OPERATION);
             }
 
-            if (readBuffer->mapped() || writeBuffer->mapped())
+            if (readBuffer->isMapped() || writeBuffer->isMapped())
             {
                 return gl::error(GL_INVALID_OPERATION);
             }
 
             if (readOffset < 0 || writeOffset < 0 || size < 0 ||
-                static_cast<unsigned int>(readOffset + size) > readBuffer->size() ||
-                static_cast<unsigned int>(writeOffset + size) > writeBuffer->size())
+                static_cast<unsigned int>(readOffset + size) > readBuffer->getSize() ||
+                static_cast<unsigned int>(writeOffset + size) > writeBuffer->getSize())
             {
                 return gl::error(GL_INVALID_VALUE);
             }
@@ -8869,22 +8869,22 @@
             switch (pname)
             {
               case GL_BUFFER_USAGE:
-                *params = static_cast<GLint64>(buffer->usage());
+                *params = static_cast<GLint64>(buffer->getUsage());
                 break;
               case GL_BUFFER_SIZE:
-                *params = buffer->size();
+                *params = buffer->getSize();
                 break;
               case GL_BUFFER_ACCESS_FLAGS:
-                *params = static_cast<GLint64>(buffer->accessFlags());
+                *params = static_cast<GLint64>(buffer->getAccessFlags());
                 break;
               case GL_BUFFER_MAPPED:
-                *params = static_cast<GLint64>(buffer->mapped());
+                *params = static_cast<GLint64>(buffer->isMapped());
                 break;
               case GL_BUFFER_MAP_OFFSET:
-                *params = buffer->mapOffset();
+                *params = buffer->getMapOffset();
                 break;
               case GL_BUFFER_MAP_LENGTH:
-                *params = buffer->mapLength();
+                *params = buffer->getMapLength();
                 break;
               default: UNREACHABLE(); break;
             }
@@ -9892,12 +9892,12 @@
 
             gl::Buffer *buffer = context->getTargetBuffer(target);
 
-            if (!buffer || !buffer->mapped())
+            if (!buffer || !buffer->isMapped())
             {
                 *params = NULL;
             }
 
-            *params = buffer->mapPointer();
+            *params = buffer->getMapPointer();
         }
     }
     catch (...)
@@ -9933,12 +9933,12 @@
                 return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLvoid*>(NULL));
             }
 
-            if (buffer->mapped())
+            if (buffer->isMapped())
             {
                 return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
             }
 
-            return buffer->mapRange(0, buffer->size(), GL_MAP_WRITE_BIT);
+            return buffer->mapRange(0, buffer->getSize(), GL_MAP_WRITE_BIT);
         }
     }
     catch (...)
@@ -9966,7 +9966,7 @@
 
             gl::Buffer *buffer = context->getTargetBuffer(target);
 
-            if (buffer == NULL || !buffer->mapped())
+            if (buffer == NULL || !buffer->isMapped())
             {
                 return gl::error(GL_INVALID_OPERATION, GL_FALSE);
             }
@@ -10019,7 +10019,7 @@
             size_t lengthSize = static_cast<size_t>(length);
 
             if (!rx::IsUnsignedAdditionSafe(offsetSize, lengthSize) ||
-                offsetSize + lengthSize > static_cast<size_t>(buffer->size()))
+                offsetSize + lengthSize > static_cast<size_t>(buffer->getSize()))
             {
                 return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLvoid*>(NULL));
             }
@@ -10037,7 +10037,7 @@
                 return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLvoid*>(NULL));
             }
 
-            if (length == 0 || buffer->mapped())
+            if (length == 0 || buffer->isMapped())
             {
                 return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
             }
@@ -10100,7 +10100,7 @@
                 return gl::error(GL_INVALID_OPERATION);
             }
 
-            if (!buffer->mapped() || (buffer->accessFlags() & GL_MAP_FLUSH_EXPLICIT_BIT) == 0)
+            if (!buffer->isMapped() || (buffer->getAccessFlags() & GL_MAP_FLUSH_EXPLICIT_BIT) == 0)
             {
                 return gl::error(GL_INVALID_OPERATION);
             }
@@ -10110,7 +10110,7 @@
             size_t lengthSize = static_cast<size_t>(length);
 
             if (!rx::IsUnsignedAdditionSafe(offsetSize, lengthSize) ||
-                offsetSize + lengthSize > static_cast<size_t>(buffer->mapLength()))
+                offsetSize + lengthSize > static_cast<size_t>(buffer->getMapLength()))
             {
                 return gl::error(GL_INVALID_VALUE);
             }
diff --git a/src/libGLESv2/renderer/BufferImpl.h b/src/libGLESv2/renderer/BufferImpl.h
new file mode 100644
index 0000000..1253414
--- /dev/null
+++ b/src/libGLESv2/renderer/BufferImpl.h
@@ -0,0 +1,32 @@
+//
+// Copyright 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.
+//
+
+// BufferImpl.h: Defines the abstract rx::BufferImpl class.
+
+#ifndef LIBGLESV2_RENDERER_BUFFERIMPL_H_
+#define LIBGLESV2_RENDERER_BUFFERIMPL_H_
+
+#include "common/angleutils.h"
+#include "libGLESv2/Buffer.h"
+
+namespace rx
+{
+
+class BufferImpl
+{
+  public:
+    virtual void setData(const void* data, size_t size, GLenum usage) = 0;
+    virtual void *getData() = 0;
+    virtual void setSubData(const void* data, size_t size, size_t offset) = 0;
+    virtual void copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) = 0;
+    virtual GLvoid* map(size_t offset, size_t length, GLbitfield access) = 0;
+    virtual void unmap() = 0;
+    virtual void markTransformFeedbackUsage() = 0;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_BUFFERIMPL_H_
diff --git a/src/libGLESv2/renderer/BufferStorage.cpp b/src/libGLESv2/renderer/BufferStorage.cpp
deleted file mode 100644
index 4d245f8..0000000
--- a/src/libGLESv2/renderer/BufferStorage.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-#include "precompiled.h"
-//
-// Copyright (c) 2013 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.
-//
-
-// BufferStorage.cpp Defines the abstract BufferStorage class.
-
-#include "libGLESv2/renderer/BufferStorage.h"
-
-namespace rx
-{
-
-unsigned int BufferStorage::mNextSerial = 1;
-
-BufferStorage::BufferStorage()
-{
-    updateSerial();
-}
-
-BufferStorage::~BufferStorage()
-{
-}
-
-unsigned int BufferStorage::getSerial() const
-{
-    return mSerial;
-}
-
-void BufferStorage::updateSerial()
-{
-    mSerial = mNextSerial++;
-}
-
-}
diff --git a/src/libGLESv2/renderer/BufferStorage.h b/src/libGLESv2/renderer/BufferStorage.h
deleted file mode 100644
index a5f95d1..0000000
--- a/src/libGLESv2/renderer/BufferStorage.h
+++ /dev/null
@@ -1,49 +0,0 @@
-//
-// Copyright (c) 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.
-//
-
-// BufferStorage.h Defines the abstract BufferStorage class.
-
-#ifndef LIBGLESV2_RENDERER_BUFFERSTORAGE_H_
-#define LIBGLESV2_RENDERER_BUFFERSTORAGE_H_
-
-#include "common/angleutils.h"
-
-namespace rx
-{
-
-class BufferStorage
-{
-  public:
-    BufferStorage();
-    virtual ~BufferStorage();
-
-    // The data returned is only guaranteed valid until next non-const method.
-    virtual void *getData() = 0;
-    virtual void setData(const void* data, size_t size, size_t offset) = 0;
-    virtual void copyData(BufferStorage* sourceStorage, size_t size, size_t sourceOffset, size_t destOffset) = 0;
-    virtual void clear() = 0;
-    virtual void markTransformFeedbackUsage() = 0;
-    virtual size_t getSize() const = 0;
-    virtual bool supportsDirectBinding() const = 0;
-    unsigned int getSerial() const;
-
-    virtual bool isMapped() const = 0;
-    virtual void *map(GLbitfield access) = 0;
-    virtual void unmap() = 0;
-
-  protected:
-    void updateSerial();
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(BufferStorage);
-
-    unsigned int mSerial;
-    static unsigned int mNextSerial;
-};
-
-}
-
-#endif // LIBGLESV2_RENDERER_BUFFERSTORAGE_H_
diff --git a/src/libGLESv2/renderer/Renderer.h b/src/libGLESv2/renderer/Renderer.h
index b50513c..818fddd 100644
--- a/src/libGLESv2/renderer/Renderer.h
+++ b/src/libGLESv2/renderer/Renderer.h
@@ -47,6 +47,7 @@
 class IndexBuffer;
 class QueryImpl;
 class FenceImpl;
+class BufferImpl;
 class VertexArrayImpl;
 class BufferStorage;
 struct TranslatedIndexData;
@@ -231,9 +232,9 @@
     virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0;
 
     // Buffer creation
+    virtual BufferImpl *createBuffer() = 0;
     virtual VertexBuffer *createVertexBuffer() = 0;
     virtual IndexBuffer *createIndexBuffer() = 0;
-    virtual BufferStorage *createBufferStorage() = 0;
 
     // Vertex Array creation
     virtual VertexArrayImpl *createVertexArray() = 0;
diff --git a/src/libGLESv2/renderer/d3d/BufferD3D.cpp b/src/libGLESv2/renderer/d3d/BufferD3D.cpp
new file mode 100644
index 0000000..08457af
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/BufferD3D.cpp
@@ -0,0 +1,83 @@
+#include "precompiled.h"
+//
+// Copyright 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.
+//
+
+// BufferD3D.cpp Defines common functionality between the Buffer9 and Buffer11 classes.
+
+#include "libGLESv2/renderer/d3d/BufferD3D.h"
+#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/d3d/VertexBuffer.h"
+#include "libGLESv2/renderer/d3d/IndexBuffer.h"
+#include "libGLESv2/main.h"
+
+namespace rx
+{
+
+unsigned int BufferD3D::mNextSerial = 1;
+
+BufferD3D::BufferD3D()
+    : BufferImpl(),
+      mStaticVertexBuffer(NULL),
+      mStaticIndexBuffer(NULL)
+{
+    updateSerial();
+}
+
+BufferD3D::~BufferD3D()
+{
+    SafeDelete(mStaticVertexBuffer);
+    SafeDelete(mStaticIndexBuffer);
+}
+
+BufferD3D *BufferD3D::makeBufferD3D(BufferImpl *buffer)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(BufferD3D*, buffer));
+    return static_cast<BufferD3D*>(buffer);
+}
+
+void BufferD3D::updateSerial()
+{
+    mSerial = mNextSerial++;
+}
+
+void BufferD3D::initializeStaticData()
+{
+    if (!mStaticVertexBuffer)
+    {
+        mStaticVertexBuffer = new rx::StaticVertexBufferInterface(getRenderer());
+    }
+    if (!mStaticIndexBuffer)
+    {
+        mStaticIndexBuffer = new rx::StaticIndexBufferInterface(getRenderer());
+    }
+}
+
+void BufferD3D::invalidateStaticData()
+{
+    if ((mStaticVertexBuffer && mStaticVertexBuffer->getBufferSize() != 0) || (mStaticIndexBuffer && mStaticIndexBuffer->getBufferSize() != 0))
+    {
+        SafeDelete(mStaticVertexBuffer);
+        SafeDelete(mStaticIndexBuffer);
+    }
+
+    mUnmodifiedDataUse = 0;
+}
+
+// Creates static buffers if sufficient used data has been left unmodified
+void BufferD3D::promoteStaticUsage(int dataSize)
+{
+    if (!mStaticVertexBuffer && !mStaticIndexBuffer)
+    {
+        mUnmodifiedDataUse += dataSize;
+
+        if (mUnmodifiedDataUse > 3 * getSize())
+        {
+            initializeStaticData();
+        }
+    }
+}
+
+}
\ No newline at end of file
diff --git a/src/libGLESv2/renderer/d3d/BufferD3D.h b/src/libGLESv2/renderer/d3d/BufferD3D.h
new file mode 100644
index 0000000..8e204b9
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/BufferD3D.h
@@ -0,0 +1,60 @@
+//
+// Copyright 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.
+//
+
+// BufferImpl.h: Defines the abstract rx::BufferImpl class.
+
+#ifndef LIBGLESV2_RENDERER_BUFFERD3D_H_
+#define LIBGLESV2_RENDERER_BUFFERD3D_H_
+
+#include "libGLESv2/renderer/BufferImpl.h"
+#include "libGLESv2/angletypes.h"
+#include "libGLESv2/renderer/IndexRangeCache.h"
+
+namespace rx
+{
+
+class Renderer;
+class StaticIndexBufferInterface;
+class StaticVertexBufferInterface;
+
+class BufferD3D : public BufferImpl
+{
+  public:
+    BufferD3D();
+    virtual ~BufferD3D();
+
+    static BufferD3D *makeBufferD3D(BufferImpl *buffer);
+
+    unsigned int getSerial() const { return mSerial; }
+
+    virtual size_t getSize() const = 0;
+    virtual void clear() = 0;
+    virtual bool supportsDirectBinding() const = 0;
+    virtual Renderer* getRenderer() = 0;
+
+    rx::StaticVertexBufferInterface *getStaticVertexBuffer() { return mStaticVertexBuffer; }
+    rx::StaticIndexBufferInterface *getStaticIndexBuffer() { return mStaticIndexBuffer; }
+    rx::IndexRangeCache *getIndexRangeCache() { return &mIndexRangeCache; }
+
+    void initializeStaticData();
+    void invalidateStaticData();
+    void promoteStaticUsage(int dataSize);
+
+  protected:
+    unsigned int mSerial;
+    static unsigned int mNextSerial;
+
+    void updateSerial();
+
+    rx::StaticVertexBufferInterface *mStaticVertexBuffer;
+    rx::StaticIndexBufferInterface *mStaticIndexBuffer;
+    rx::IndexRangeCache mIndexRangeCache;
+    unsigned int mUnmodifiedDataUse;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_BUFFERIMPLD3D_H_
diff --git a/src/libGLESv2/renderer/d3d/IndexDataManager.cpp b/src/libGLESv2/renderer/d3d/IndexDataManager.cpp
index ad28335..932524c 100644
--- a/src/libGLESv2/renderer/d3d/IndexDataManager.cpp
+++ b/src/libGLESv2/renderer/d3d/IndexDataManager.cpp
@@ -9,7 +9,7 @@
 // runs the Buffer translation process for index buffers.
 
 #include "libGLESv2/renderer/d3d/IndexDataManager.h"
-#include "libGLESv2/renderer/BufferStorage.h"
+#include "libGLESv2/renderer/d3d/BufferD3D.h"
 
 #include "libGLESv2/Buffer.h"
 #include "libGLESv2/main.h"
@@ -118,7 +118,7 @@
     unsigned int offset = 0;
     bool alignedOffset = false;
 
-    BufferStorage *storage = NULL;
+    BufferD3D *storage = NULL;
 
     if (buffer != NULL)
     {
@@ -128,7 +128,7 @@
         }
         offset = static_cast<unsigned int>(reinterpret_cast<uintptr_t>(indices));
 
-        storage = buffer->getStorage();
+        storage = BufferD3D::makeBufferD3D(buffer->getImplementation());
 
         switch (type)
         {
@@ -157,7 +157,7 @@
 
     StreamingIndexBufferInterface *streamingBuffer = (type == GL_UNSIGNED_INT) ? mStreamingBufferInt : mStreamingBufferShort;
 
-    StaticIndexBufferInterface *staticBuffer = buffer ? buffer->getStaticIndexBuffer() : NULL;
+    StaticIndexBufferInterface *staticBuffer = storage ? storage->getStaticIndexBuffer() : NULL;
     IndexBufferInterface *indexBuffer = streamingBuffer;
     bool directStorage = alignedOffset && storage && storage->supportsDirectBinding() &&
                          destinationIndexType == type;
@@ -168,11 +168,11 @@
         indexBuffer = streamingBuffer;
         streamOffset = offset;
 
-        if (!buffer->getIndexRangeCache()->findRange(type, offset, count, &translated->minIndex,
+        if (!storage->getIndexRangeCache()->findRange(type, offset, count, &translated->minIndex,
                                                      &translated->maxIndex, NULL))
         {
             computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
-            buffer->getIndexRangeCache()->addRange(type, offset, count, translated->minIndex,
+            storage->getIndexRangeCache()->addRange(type, offset, count, translated->minIndex,
                                                    translated->maxIndex, offset);
         }
     }
@@ -202,7 +202,7 @@
             }
             else
             {
-                buffer->invalidateStaticData();
+                storage->invalidateStaticData();
                 staticBuffer = NULL;
             }
         }
@@ -258,9 +258,9 @@
     translated->startIndex = streamOffset / gl::GetTypeBytes(destinationIndexType);
     translated->startOffset = streamOffset;
 
-    if (buffer)
+    if (storage)
     {
-        buffer->promoteStaticUsage(count * gl::GetTypeBytes(type));
+        storage->promoteStaticUsage(count * gl::GetTypeBytes(type));
     }
 
     return GL_NO_ERROR;
diff --git a/src/libGLESv2/renderer/d3d/IndexDataManager.h b/src/libGLESv2/renderer/d3d/IndexDataManager.h
index 0e77c81..8f98193 100644
--- a/src/libGLESv2/renderer/d3d/IndexDataManager.h
+++ b/src/libGLESv2/renderer/d3d/IndexDataManager.h
@@ -27,7 +27,7 @@
 class StaticIndexBufferInterface;
 class StreamingIndexBufferInterface;
 class IndexBuffer;
-class BufferStorage;
+class BufferD3D;
 class Renderer;
 
 struct TranslatedIndexData
@@ -38,7 +38,7 @@
     unsigned int startOffset;   // In bytes
 
     IndexBuffer *indexBuffer;
-    BufferStorage *storage;
+    BufferD3D *storage;
     unsigned int serial;
 };
 
diff --git a/src/libGLESv2/renderer/d3d/VertexBuffer.cpp b/src/libGLESv2/renderer/d3d/VertexBuffer.cpp
index 2395a4d..901ca19 100644
--- a/src/libGLESv2/renderer/d3d/VertexBuffer.cpp
+++ b/src/libGLESv2/renderer/d3d/VertexBuffer.cpp
@@ -11,7 +11,7 @@
 #include "libGLESv2/renderer/d3d/VertexBuffer.h"
 #include "libGLESv2/renderer/Renderer.h"
 #include "libGLESv2/VertexAttribute.h"
-#include "libGLESv2/renderer/BufferStorage.h"
+#include "libGLESv2/renderer/d3d/BufferD3D.h"
 #include "common/mathutil.h"
 
 namespace rx
@@ -158,7 +158,7 @@
                                                   const gl::VertexAttribCurrentValueData &currentValue) const
 {
     gl::Buffer *buffer = attrib.buffer.get();
-    BufferStorage *storage = buffer ? buffer->getStorage() : NULL;
+    BufferD3D *storage = buffer ? BufferD3D::makeBufferD3D(buffer->getImplementation()) : NULL;
 
     if (!storage || !storage->supportsDirectBinding())
     {
diff --git a/src/libGLESv2/renderer/d3d/VertexDataManager.cpp b/src/libGLESv2/renderer/d3d/VertexDataManager.cpp
index 33296c5..9ba12d1 100644
--- a/src/libGLESv2/renderer/d3d/VertexDataManager.cpp
+++ b/src/libGLESv2/renderer/d3d/VertexDataManager.cpp
@@ -9,7 +9,7 @@
 // runs the Buffer translation process.
 
 #include "libGLESv2/renderer/d3d/VertexDataManager.h"
-#include "libGLESv2/renderer/BufferStorage.h"
+#include "libGLESv2/renderer/d3d/BufferD3D.h"
 
 #include "libGLESv2/Buffer.h"
 #include "libGLESv2/ProgramBinary.h"
@@ -103,12 +103,17 @@
         if (translated[i].active && attribs[i].enabled)
         {
             gl::Buffer *buffer = attribs[i].buffer.get();
-            StaticVertexBufferInterface *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL;
 
-            if (staticBuffer && staticBuffer->getBufferSize() > 0 && !staticBuffer->lookupAttribute(attribs[i], NULL) &&
-                !staticBuffer->directStoragePossible(attribs[i], currentValues[i]))
+            if (buffer)
             {
-                buffer->invalidateStaticData();
+                BufferD3D *bufferImpl = BufferD3D::makeBufferD3D(buffer->getImplementation());
+                StaticVertexBufferInterface *staticBuffer = bufferImpl->getStaticVertexBuffer();
+
+                if (staticBuffer && staticBuffer->getBufferSize() > 0 && !staticBuffer->lookupAttribute(attribs[i], NULL) &&
+                    !staticBuffer->directStoragePossible(attribs[i], currentValues[i]))
+                {
+                    bufferImpl->invalidateStaticData();
+                }
             }
         }
     }
@@ -119,38 +124,42 @@
         if (translated[i].active && attribs[i].enabled)
         {
             gl::Buffer *buffer = attribs[i].buffer.get();
-            StaticVertexBufferInterface *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL;
-            VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer);
-
-            if (!vertexBuffer->directStoragePossible(attribs[i], currentValues[i]))
+            if (buffer)
             {
-                if (staticBuffer)
+                BufferD3D *bufferImpl = BufferD3D::makeBufferD3D(buffer->getImplementation());
+                StaticVertexBufferInterface *staticBuffer = bufferImpl->getStaticVertexBuffer();
+                VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer);
+
+                if (!vertexBuffer->directStoragePossible(attribs[i], currentValues[i]))
                 {
-                    if (staticBuffer->getBufferSize() == 0)
+                    if (staticBuffer)
                     {
-                        int totalCount = ElementsInBuffer(attribs[i], buffer->size());
-                        if (!staticBuffer->reserveVertexSpace(attribs[i], totalCount, 0))
+                        if (staticBuffer->getBufferSize() == 0)
+                        {
+                            int totalCount = ElementsInBuffer(attribs[i], bufferImpl->getSize());
+                            if (!staticBuffer->reserveVertexSpace(attribs[i], totalCount, 0))
+                            {
+                                return GL_OUT_OF_MEMORY;
+                            }
+                        }
+                    }
+                    else
+                    {
+                        int totalCount = StreamingBufferElementCount(attribs[i], count, instances);
+
+                        // [OpenGL ES 3.0.2] section 2.9.4 page 40:
+                        // We can return INVALID_OPERATION if our vertex attribute does not have enough backing data.
+                        if (bufferImpl && ElementsInBuffer(attribs[i], bufferImpl->getSize()) < totalCount)
+                        {
+                            return GL_INVALID_OPERATION;
+                        }
+
+                        if (!mStreamingBuffer->reserveVertexSpace(attribs[i], totalCount, instances))
                         {
                             return GL_OUT_OF_MEMORY;
                         }
                     }
                 }
-                else
-                {
-                    int totalCount = StreamingBufferElementCount(attribs[i], count, instances);
-
-                    // [OpenGL ES 3.0.2] section 2.9.4 page 40:
-                    // We can return INVALID_OPERATION if our vertex attribute does not have enough backing data.
-                    if (buffer && ElementsInBuffer(attribs[i], buffer->size()) < totalCount)
-                    {
-                        return GL_INVALID_OPERATION;
-                    }
-
-                    if (!mStreamingBuffer->reserveVertexSpace(attribs[i], totalCount, instances))
-                    {
-                        return GL_OUT_OF_MEMORY;
-                    }
-                }
             }
         }
     }
@@ -171,10 +180,9 @@
                     return GL_INVALID_OPERATION;
                 }
 
-                StaticVertexBufferInterface *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL;
+                BufferD3D *storage = buffer ? BufferD3D::makeBufferD3D(buffer->getImplementation()) : NULL;
+                StaticVertexBufferInterface *staticBuffer = storage ? storage->getStaticVertexBuffer() : NULL;
                 VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer);
-
-                BufferStorage *storage = buffer ? buffer->getStorage() : NULL;
                 bool directStorage = vertexBuffer->directStoragePossible(attribs[i], currentValues[i]);
 
                 unsigned int streamOffset = 0;
@@ -282,7 +290,8 @@
 
             if (buffer)
             {
-                buffer->promoteStaticUsage(count * ComputeVertexAttributeTypeSize(attribs[i]));
+                BufferD3D *bufferImpl = BufferD3D::makeBufferD3D(buffer->getImplementation());
+                bufferImpl->promoteStaticUsage(count * ComputeVertexAttributeTypeSize(attribs[i]));
             }
         }
     }
diff --git a/src/libGLESv2/renderer/d3d/VertexDataManager.h b/src/libGLESv2/renderer/d3d/VertexDataManager.h
index 2ce8f7f..4164fbe 100644
--- a/src/libGLESv2/renderer/d3d/VertexDataManager.h
+++ b/src/libGLESv2/renderer/d3d/VertexDataManager.h
@@ -23,7 +23,7 @@
 
 namespace rx
 {
-class BufferStorage;
+class BufferD3D;
 class StreamingVertexBufferInterface;
 class VertexBuffer;
 class Renderer;
@@ -38,7 +38,7 @@
     unsigned int stride;   // 0 means not to advance the read pointer at all
 
     VertexBuffer *vertexBuffer;
-    BufferStorage *storage;
+    BufferD3D *storage;
     unsigned int serial;
     unsigned int divisor;
 };
diff --git a/src/libGLESv2/renderer/d3d/d3d11/BufferStorage11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp
similarity index 78%
rename from src/libGLESv2/renderer/d3d/d3d11/BufferStorage11.cpp
rename to src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp
index c23b03c..facd709 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/BufferStorage11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp
@@ -1,17 +1,16 @@
 #include "precompiled.h"
 //
-// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
+// Copyright 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.
 //
 
-// BufferStorage11.cpp Defines the BufferStorage11 class.
+// Buffer11.cpp Defines the Buffer11 class.
 
-#include "libGLESv2/renderer/d3d/d3d11/BufferStorage11.h"
+#include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
 #include "libGLESv2/main.h"
 #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
 #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
-#include "libGLESv2/Buffer.h"
 
 namespace rx
 {
@@ -69,15 +68,15 @@
 
 }
 
-// Each instance of BufferStorageD3DBuffer11 is specialized for a class of D3D binding points
+// Each instance of Buffer11::BufferStorage11 is specialized for a class of D3D binding points
 // - vertex/transform feedback buffers
 // - index buffers
 // - pixel unpack buffers
 // - uniform buffers
-class BufferStorage11::TypedBufferStorage11
+class Buffer11::BufferStorage11
 {
   public:
-    virtual ~TypedBufferStorage11() {}
+    virtual ~BufferStorage11() {}
 
     DataRevision getDataRevision() const { return mRevision; }
     BufferUsage getUsage() const { return mUsage; }
@@ -86,15 +85,15 @@
 
     void setDataRevision(DataRevision rev) { mRevision = rev; }
 
-    virtual bool copyFromStorage(TypedBufferStorage11 *source, size_t sourceOffset,
+    virtual bool copyFromStorage(BufferStorage11 *source, size_t sourceOffset,
                                  size_t size, size_t destOffset) = 0;
     virtual bool resize(size_t size, bool preserveData) = 0;
 
-    virtual void *map(GLbitfield access) = 0;
+    virtual void *map(size_t offset, size_t length, GLbitfield access) = 0;
     virtual void unmap() = 0;
 
   protected:
-    TypedBufferStorage11(Renderer11 *renderer, BufferUsage usage);
+    BufferStorage11(Renderer11 *renderer, BufferUsage usage);
 
     Renderer11 *mRenderer;
     DataRevision mRevision;
@@ -104,7 +103,7 @@
 
 // A native buffer storage represents an underlying D3D11 buffer for a particular
 // type of storage.
-class BufferStorage11::NativeBuffer11 : public BufferStorage11::TypedBufferStorage11
+class Buffer11::NativeBuffer11 : public Buffer11::BufferStorage11
 {
   public:
     NativeBuffer11(Renderer11 *renderer, BufferUsage usage);
@@ -112,11 +111,11 @@
 
     ID3D11Buffer *getNativeBuffer() const { return mNativeBuffer; }
 
-    virtual bool copyFromStorage(TypedBufferStorage11 *source, size_t sourceOffset,
+    virtual bool copyFromStorage(BufferStorage11 *source, size_t sourceOffset,
                                  size_t size, size_t destOffset);
     virtual bool resize(size_t size, bool preserveData);
 
-    virtual void *map(GLbitfield access);
+    virtual void *map(size_t offset, size_t length, GLbitfield access);
     virtual void unmap();
 
   private:
@@ -127,17 +126,17 @@
 
 // Pack storage represents internal storage for pack buffers. We implement pack buffers
 // as CPU memory, tied to a staging texture, for asynchronous texture readback.
-class BufferStorage11::PackStorage11 : public BufferStorage11::TypedBufferStorage11
+class Buffer11::PackStorage11 : public Buffer11::BufferStorage11
 {
   public:
     PackStorage11(Renderer11 *renderer);
     ~PackStorage11();
 
-    virtual bool copyFromStorage(TypedBufferStorage11 *source, size_t sourceOffset,
+    virtual bool copyFromStorage(BufferStorage11 *source, size_t sourceOffset,
                                  size_t size, size_t destOffset);
     virtual bool resize(size_t size, bool preserveData);
 
-    virtual void *map(GLbitfield access);
+    virtual void *map(size_t offset, size_t length, GLbitfield access);
     virtual void unmap();
 
     void packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams &params);
@@ -155,27 +154,54 @@
     bool mDataModified;
 };
 
-BufferStorage11::BufferStorage11(Renderer11 *renderer)
-    : mRenderer(renderer),
+
+Buffer11::Buffer11(Renderer11 *renderer)
+    : BufferD3D(),
+      mRenderer(renderer),
+      mSize(0),
       mMappedStorage(NULL),
       mResolvedDataRevision(0),
-      mReadUsageCount(0),
-      mSize(0)
+      mReadUsageCount(0)
 {
 }
 
-BufferStorage11::~BufferStorage11()
+Buffer11::~Buffer11()
 {
     clear();
 }
 
-BufferStorage11 *BufferStorage11::makeBufferStorage11(BufferStorage *bufferStorage)
+Buffer11 *Buffer11::makeBuffer11(BufferImpl *buffer)
 {
-    ASSERT(HAS_DYNAMIC_TYPE(BufferStorage11*, bufferStorage));
-    return static_cast<BufferStorage11*>(bufferStorage);
+    ASSERT(HAS_DYNAMIC_TYPE(Buffer11*, buffer));
+    return static_cast<Buffer11*>(buffer);
 }
 
-void *BufferStorage11::getData()
+void Buffer11::clear()
+{
+    for (auto it = mBufferStorages.begin(); it != mBufferStorages.end(); it++)
+    {
+        SafeDelete(it->second);
+    }
+
+    mBufferStorages.clear();
+
+    mSize = 0;
+    mResolvedDataRevision = 0;
+}
+
+void Buffer11::setData(const void* data, size_t size, GLenum usage)
+{
+    mIndexRangeCache.clear();
+
+    setSubData(data, size, 0);
+
+    if (usage == GL_STATIC_DRAW)
+    {
+        initializeStaticData();
+    }
+}
+
+void *Buffer11::getData()
 {
     NativeBuffer11 *stagingBuffer = getStagingBuffer();
 
@@ -213,11 +239,14 @@
     return mResolvedData.data();
 }
 
-void BufferStorage11::setData(const void* data, size_t size, size_t offset)
+void Buffer11::setSubData(const void* data, size_t size, size_t offset)
 {
     size_t requiredSize = size + offset;
     mSize = std::max(mSize, requiredSize);
 
+    mIndexRangeCache.invalidateRange(offset, size);
+    invalidateStaticData();
+
     if (data && size > 0)
     {
         NativeBuffer11 *stagingBuffer = getStagingBuffer();
@@ -258,25 +287,25 @@
     }
 }
 
-void BufferStorage11::copyData(BufferStorage* sourceStorage, size_t size, size_t sourceOffset, size_t destOffset)
+void Buffer11::copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size)
 {
-    BufferStorage11* sourceStorage11 = makeBufferStorage11(sourceStorage);
-    if (sourceStorage11)
+    Buffer11 *sourceBuffer = makeBuffer11(source);
+    if (sourceBuffer)
     {
-        TypedBufferStorage11 *dest = getLatestStorage();
+        BufferStorage11 *dest = getLatestBufferStorage();
         if (!dest)
         {
             dest = getStagingBuffer();
         }
 
-        TypedBufferStorage11 *source = sourceStorage11->getLatestStorage();
+        BufferStorage11 *source = sourceBuffer->getLatestBufferStorage();
         if (source && dest)
         {
             // If copying to/from a pixel pack buffer, we must have a staging or
             // pack buffer partner, because other native buffers can't be mapped
             if (dest->getUsage() == BUFFER_USAGE_PIXEL_PACK && !source->isMappable())
             {
-                source = sourceStorage11->getStagingBuffer();
+                source = sourceBuffer->getStagingBuffer();
             }
             else if (source->getUsage() == BUFFER_USAGE_PIXEL_PACK && !dest->isMappable())
             {
@@ -289,42 +318,64 @@
 
         mSize = std::max<size_t>(mSize, destOffset + size);
     }
+
+    invalidateStaticData();
 }
 
-void BufferStorage11::clear()
+GLvoid *Buffer11::map(size_t offset, size_t length, GLbitfield access)
 {
-    for (auto it = mTypedBuffers.begin(); it != mTypedBuffers.end(); it++)
+    ASSERT(!mMappedStorage);
+
+    BufferStorage11 *latestStorage = getLatestBufferStorage();
+    if (latestStorage &&
+        (latestStorage->getUsage() == BUFFER_USAGE_PIXEL_PACK ||
+         latestStorage->getUsage() == BUFFER_USAGE_STAGING))
     {
-        SafeDelete(it->second);
+        // Latest storage is mappable.
+        mMappedStorage = latestStorage;
+    }
+    else
+    {
+        // Fall back to using the staging buffer if the latest storage does
+        // not exist or is not CPU-accessible.
+        mMappedStorage = getStagingBuffer();
     }
 
-    mTypedBuffers.clear();
+    if (!mMappedStorage)
+    {
+        // Out-of-memory
+        return NULL;
+    }
 
-    mSize = 0;
-    mResolvedDataRevision = 0;
+    if ((access & GL_MAP_WRITE_BIT) > 0)
+    {
+        // Update the data revision immediately, since the data might be changed at any time
+        mMappedStorage->setDataRevision(mMappedStorage->getDataRevision() + 1);
+    }
+
+    return mMappedStorage->map(offset, length, access);
 }
 
-void BufferStorage11::markTransformFeedbackUsage()
+void Buffer11::unmap()
 {
-    TypedBufferStorage11 *transformFeedbackStorage = getStorage(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
+    ASSERT(mMappedStorage);
+    mMappedStorage->unmap();
+    mMappedStorage = NULL;
+}
+
+void Buffer11::markTransformFeedbackUsage()
+{
+    BufferStorage11 *transformFeedbackStorage = getBufferStorage(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
 
     if (transformFeedbackStorage)
     {
         transformFeedbackStorage->setDataRevision(transformFeedbackStorage->getDataRevision() + 1);
     }
+
+    invalidateStaticData();
 }
 
-size_t BufferStorage11::getSize() const
-{
-    return mSize;
-}
-
-bool BufferStorage11::supportsDirectBinding() const
-{
-    return true;
-}
-
-void BufferStorage11::markBufferUsage()
+void Buffer11::markBufferUsage()
 {
     mReadUsageCount++;
 
@@ -337,26 +388,31 @@
     }
 }
 
-ID3D11Buffer *BufferStorage11::getBuffer(BufferUsage usage)
+Renderer* Buffer11::getRenderer()
+{
+    return mRenderer;
+}
+
+ID3D11Buffer *Buffer11::getBuffer(BufferUsage usage)
 {
     markBufferUsage();
 
-    TypedBufferStorage11 *typedBuffer = getStorage(usage);
+    BufferStorage11 *bufferStorage = getBufferStorage(usage);
 
-    if (!typedBuffer)
+    if (!bufferStorage)
     {
         // Storage out-of-memory
         return NULL;
     }
 
-    ASSERT(HAS_DYNAMIC_TYPE(NativeBuffer11*, typedBuffer));
+    ASSERT(HAS_DYNAMIC_TYPE(NativeBuffer11*, bufferStorage));
 
-    return static_cast<NativeBuffer11*>(typedBuffer)->getNativeBuffer();
+    return static_cast<NativeBuffer11*>(bufferStorage)->getNativeBuffer();
 }
 
-ID3D11ShaderResourceView *BufferStorage11::getSRV(DXGI_FORMAT srvFormat)
+ID3D11ShaderResourceView *Buffer11::getSRV(DXGI_FORMAT srvFormat)
 {
-    TypedBufferStorage11 *storage = getStorage(BUFFER_USAGE_PIXEL_UNPACK);
+    BufferStorage11 *storage = getBufferStorage(BUFFER_USAGE_PIXEL_UNPACK);
 
     if (!storage)
     {
@@ -400,11 +456,11 @@
     return bufferSRV;
 }
 
-void BufferStorage11::packPixels(ID3D11Texture2D *srcTexture, UINT srcSubresource, const PackPixelsParams &params)
+void Buffer11::packPixels(ID3D11Texture2D *srcTexture, UINT srcSubresource, const PackPixelsParams &params)
 {
     PackStorage11 *packStorage = getPackStorage();
 
-    TypedBufferStorage11 *latestStorage = getLatestStorage();
+    BufferStorage11 *latestStorage = getLatestBufferStorage();
 
     if (packStorage)
     {
@@ -413,11 +469,11 @@
     }
 }
 
-BufferStorage11::TypedBufferStorage11 *BufferStorage11::getStorage(BufferUsage usage)
+Buffer11::BufferStorage11 *Buffer11::getBufferStorage(BufferUsage usage)
 {
-    TypedBufferStorage11 *directBuffer = NULL;
-    auto directBufferIt = mTypedBuffers.find(usage);
-    if (directBufferIt != mTypedBuffers.end())
+    BufferStorage11 *directBuffer = NULL;
+    auto directBufferIt = mBufferStorages.find(usage);
+    if (directBufferIt != mBufferStorages.end())
     {
         directBuffer = directBufferIt->second;
     }
@@ -434,7 +490,7 @@
             directBuffer = new NativeBuffer11(mRenderer, usage);
         }
 
-        mTypedBuffers.insert(std::make_pair(usage, directBuffer));
+        mBufferStorages.insert(std::make_pair(usage, directBuffer));
     }
 
     // resize buffer
@@ -447,7 +503,7 @@
         }
     }
 
-    TypedBufferStorage11 *latestBuffer = getLatestStorage();
+    BufferStorage11 *latestBuffer = getLatestBufferStorage();
     if (latestBuffer && latestBuffer->getDataRevision() > directBuffer->getDataRevision())
     {
         // if copying from a pack buffer to a non-staging native buffer, we must first
@@ -474,15 +530,15 @@
     return directBuffer;
 }
 
-BufferStorage11::TypedBufferStorage11 *BufferStorage11::getLatestStorage() const
+Buffer11::BufferStorage11 *Buffer11::getLatestBufferStorage() const
 {
     // Even though we iterate over all the direct buffers, it is expected that only
     // 1 or 2 will be present.
-    TypedBufferStorage11 *latestStorage = NULL;
+    BufferStorage11 *latestStorage = NULL;
     DataRevision latestRevision = 0;
-    for (auto it = mTypedBuffers.begin(); it != mTypedBuffers.end(); it++)
+    for (auto it = mBufferStorages.begin(); it != mBufferStorages.end(); it++)
     {
-        TypedBufferStorage11 *storage = it->second;
+        BufferStorage11 *storage = it->second;
         if (!latestStorage || storage->getDataRevision() > latestRevision)
         {
             latestStorage = storage;
@@ -493,55 +549,9 @@
     return latestStorage;
 }
 
-bool BufferStorage11::isMapped() const
+Buffer11::NativeBuffer11 *Buffer11::getStagingBuffer()
 {
-    return mMappedStorage != NULL;
-}
-
-void *BufferStorage11::map(GLbitfield access)
-{
-    ASSERT(!mMappedStorage);
-
-    TypedBufferStorage11 *latestStorage = getLatestStorage();
-    if (latestStorage &&
-        (latestStorage->getUsage() == BUFFER_USAGE_PIXEL_PACK ||
-         latestStorage->getUsage() == BUFFER_USAGE_STAGING))
-    {
-        // Latest storage is mappable.
-        mMappedStorage = latestStorage;
-    }
-    else
-    {
-        // Fall back to using the staging buffer if the latest storage does
-        // not exist or is not CPU-accessible.
-        mMappedStorage = getStagingBuffer();
-    }
-
-    if (!mMappedStorage)
-    {
-        // Out-of-memory
-        return NULL;
-    }
-
-    if ((access & GL_MAP_WRITE_BIT) > 0)
-    {
-        // Update the data revision immediately, since the data might be changed at any time
-        mMappedStorage->setDataRevision(mMappedStorage->getDataRevision() + 1);
-    }
-
-    return mMappedStorage->map(access);
-}
-
-void BufferStorage11::unmap()
-{
-    ASSERT(mMappedStorage);
-    mMappedStorage->unmap();
-    mMappedStorage = NULL;
-}
-
-BufferStorage11::NativeBuffer11 *BufferStorage11::getStagingBuffer()
-{
-    TypedBufferStorage11 *stagingStorage = getStorage(BUFFER_USAGE_STAGING);
+    BufferStorage11 *stagingStorage = getBufferStorage(BUFFER_USAGE_STAGING);
 
     if (!stagingStorage)
     {
@@ -553,9 +563,9 @@
     return static_cast<NativeBuffer11*>(stagingStorage);
 }
 
-BufferStorage11::PackStorage11 *BufferStorage11::getPackStorage()
+Buffer11::PackStorage11 *Buffer11::getPackStorage()
 {
-    TypedBufferStorage11 *packStorage = getStorage(BUFFER_USAGE_PIXEL_PACK);
+    BufferStorage11 *packStorage = getBufferStorage(BUFFER_USAGE_PIXEL_PACK);
 
     if (!packStorage)
     {
@@ -567,7 +577,7 @@
     return static_cast<PackStorage11*>(packStorage);
 }
 
-BufferStorage11::TypedBufferStorage11::TypedBufferStorage11(Renderer11 *renderer, BufferUsage usage)
+Buffer11::BufferStorage11::BufferStorage11(Renderer11 *renderer, BufferUsage usage)
     : mRenderer(renderer),
       mUsage(usage),
       mRevision(0),
@@ -575,19 +585,19 @@
 {
 }
 
-BufferStorage11::NativeBuffer11::NativeBuffer11(Renderer11 *renderer, BufferUsage usage)
-    : TypedBufferStorage11(renderer, usage),
+Buffer11::NativeBuffer11::NativeBuffer11(Renderer11 *renderer, BufferUsage usage)
+    : BufferStorage11(renderer, usage),
       mNativeBuffer(NULL)
 {
 }
 
-BufferStorage11::NativeBuffer11::~NativeBuffer11()
+Buffer11::NativeBuffer11::~NativeBuffer11()
 {
     SafeRelease(mNativeBuffer);
 }
 
 // Returns true if it recreates the direct buffer
-bool BufferStorage11::NativeBuffer11::copyFromStorage(TypedBufferStorage11 *source, size_t sourceOffset,
+bool Buffer11::NativeBuffer11::copyFromStorage(BufferStorage11 *source, size_t sourceOffset,
                                                       size_t size, size_t destOffset)
 {
     ID3D11DeviceContext *context = mRenderer->getDeviceContext();
@@ -606,7 +616,7 @@
     {
         ASSERT(HAS_DYNAMIC_TYPE(PackStorage11*, source));
 
-        unsigned char *sourcePointer = static_cast<unsigned char *>(source->map(GL_MAP_READ_BIT)) + sourceOffset;
+        void *sourcePointer = source->map(sourceOffset, size, GL_MAP_READ_BIT);
 
         D3D11_MAPPED_SUBRESOURCE mappedResource;
         HRESULT hr = context->Map(mNativeBuffer, 0, D3D11_MAP_WRITE, 0, &mappedResource);
@@ -640,7 +650,7 @@
     return createBuffer;
 }
 
-bool BufferStorage11::NativeBuffer11::resize(size_t size, bool preserveData)
+bool Buffer11::NativeBuffer11::resize(size_t size, bool preserveData)
 {
     ID3D11Device *device = mRenderer->getDevice();
     ID3D11DeviceContext *context = mRenderer->getDeviceContext();
@@ -681,7 +691,7 @@
     return true;
 }
 
-void BufferStorage11::NativeBuffer11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer *renderer,
+void Buffer11::NativeBuffer11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer *renderer,
                                                      BufferUsage usage, unsigned int bufferSize)
 {
     bufferDesc->ByteWidth = bufferSize;
@@ -730,7 +740,7 @@
     }
 }
 
-void *BufferStorage11::NativeBuffer11::map(GLbitfield access)
+void *Buffer11::NativeBuffer11::map(size_t offset, size_t length, GLbitfield access)
 {
     ASSERT(mUsage == BUFFER_USAGE_STAGING);
 
@@ -743,18 +753,18 @@
     UNUSED_ASSERTION_VARIABLE(result);
     ASSERT(SUCCEEDED(result));
 
-    return mappedResource.pData;
+    return static_cast<GLubyte*>(mappedResource.pData) + offset;
 }
 
-void BufferStorage11::NativeBuffer11::unmap()
+void Buffer11::NativeBuffer11::unmap()
 {
     ASSERT(mUsage == BUFFER_USAGE_STAGING);
     ID3D11DeviceContext *context = mRenderer->getDeviceContext();
     context->Unmap(mNativeBuffer, 0);
 }
 
-BufferStorage11::PackStorage11::PackStorage11(Renderer11 *renderer)
-    : TypedBufferStorage11(renderer, BUFFER_USAGE_PIXEL_PACK),
+Buffer11::PackStorage11::PackStorage11(Renderer11 *renderer)
+    : BufferStorage11(renderer, BUFFER_USAGE_PIXEL_PACK),
       mStagingTexture(NULL),
       mTextureFormat(DXGI_FORMAT_UNKNOWN),
       mQueuedPackCommand(NULL),
@@ -762,20 +772,20 @@
 {
 }
 
-BufferStorage11::PackStorage11::~PackStorage11()
+Buffer11::PackStorage11::~PackStorage11()
 {
     SafeRelease(mStagingTexture);
     SafeDelete(mQueuedPackCommand);
 }
 
-bool BufferStorage11::PackStorage11::copyFromStorage(TypedBufferStorage11 *source, size_t sourceOffset,
+bool Buffer11::PackStorage11::copyFromStorage(BufferStorage11 *source, size_t sourceOffset,
                                                      size_t size, size_t destOffset)
 {
     UNIMPLEMENTED();
     return false;
 }
 
-bool BufferStorage11::PackStorage11::resize(size_t size, bool preserveData)
+bool Buffer11::PackStorage11::resize(size_t size, bool preserveData)
 {
     if (size != mBufferSize)
     {
@@ -786,8 +796,9 @@
     return true;
 }
 
-void *BufferStorage11::PackStorage11::map(GLbitfield access)
+void *Buffer11::PackStorage11::map(size_t offset, size_t length, GLbitfield access)
 {
+    ASSERT(offset + length <= getSize());
     // TODO: fast path
     //  We might be able to optimize out one or more memcpy calls by detecting when
     //  and if D3D packs the staging texture memory identically to how we would fill
@@ -796,15 +807,15 @@
     flushQueuedPackCommand();
     mDataModified = (mDataModified || (access & GL_MAP_WRITE_BIT) != 0);
 
-    return &mMemoryBuffer[0];
+    return &mMemoryBuffer[0] + offset;
 }
 
-void BufferStorage11::PackStorage11::unmap()
+void Buffer11::PackStorage11::unmap()
 {
     // No-op
 }
 
-void BufferStorage11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams &params)
+void Buffer11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams &params)
 {
     flushQueuedPackCommand();
     mQueuedPackCommand = new PackPixelsParams(params);
@@ -867,7 +878,7 @@
     immediateContext->CopySubresourceRegion(mStagingTexture, 0, 0, 0, 0, srcTexure, srcSubresource, &srcBox);
 }
 
-void BufferStorage11::PackStorage11::flushQueuedPackCommand()
+void Buffer11::PackStorage11::flushQueuedPackCommand()
 {
     ASSERT(!mMemoryBuffer.empty());
 
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h b/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h
new file mode 100644
index 0000000..43f95c3
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h
@@ -0,0 +1,105 @@
+//
+// Copyright 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.
+//
+
+// Buffer11.h: Defines the rx::Buffer11 class which implements rx::BufferImpl via rx::BufferD3D.
+
+#ifndef LIBGLESV2_RENDERER_BUFFER11_H_
+#define LIBGLESV2_RENDERER_BUFFER11_H_
+
+#include "libGLESv2/renderer/d3d/BufferD3D.h"
+#include "libGLESv2/angletypes.h"
+
+namespace rx
+{
+class Renderer11;
+
+enum BufferUsage
+{
+    BUFFER_USAGE_STAGING,
+    BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK,
+    BUFFER_USAGE_INDEX,
+    BUFFER_USAGE_PIXEL_UNPACK,
+    BUFFER_USAGE_PIXEL_PACK,
+    BUFFER_USAGE_UNIFORM,
+};
+
+struct PackPixelsParams
+{
+    PackPixelsParams();
+    PackPixelsParams(const gl::Rectangle &area, GLenum format, GLenum type, GLuint outputPitch,
+                     const gl::PixelPackState &pack, ptrdiff_t offset);
+
+    gl::Rectangle area;
+    GLenum format;
+    GLenum type;
+    GLuint outputPitch;
+    gl::Buffer *packBuffer;
+    gl::PixelPackState pack;
+    ptrdiff_t offset;
+};
+
+typedef size_t DataRevision;
+
+class Buffer11 : public BufferD3D
+{
+  public:
+    Buffer11(rx::Renderer11 *renderer);
+    virtual ~Buffer11();
+
+    static Buffer11 *makeBuffer11(BufferImpl *buffer);
+
+    ID3D11Buffer *getBuffer(BufferUsage usage);
+    ID3D11ShaderResourceView *getSRV(DXGI_FORMAT srvFormat);
+    bool isMapped() const { return mMappedStorage != NULL; }
+    void packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams &params);
+
+    // BufferD3D implementation
+    virtual size_t getSize() const { return mSize; }
+    virtual void clear();
+    virtual bool supportsDirectBinding() const { return true; }
+    virtual Renderer* getRenderer();
+
+    // BufferImpl implementation
+    virtual void setData(const void* data, size_t size, GLenum usage);
+    virtual void *getData();
+    virtual void setSubData(const void* data, size_t size, size_t offset);
+    virtual void copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size);
+    virtual GLvoid* map(size_t offset, size_t length, GLbitfield access);
+    virtual void unmap();
+    virtual void markTransformFeedbackUsage();
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(Buffer11);
+
+    class BufferStorage11;
+    class NativeBuffer11;
+    class PackStorage11;
+
+    rx::Renderer11 *mRenderer;
+    size_t mSize;
+
+    BufferStorage11 *mMappedStorage;
+
+    std::map<BufferUsage, BufferStorage11*> mBufferStorages;
+
+    typedef std::pair<ID3D11Buffer *, ID3D11ShaderResourceView *> BufferSRVPair;
+    std::map<DXGI_FORMAT, BufferSRVPair> mBufferResourceViews;
+
+    std::vector<unsigned char> mResolvedData;
+    DataRevision mResolvedDataRevision;
+    unsigned int mReadUsageCount;
+
+    void markBufferUsage();
+    NativeBuffer11 *getStagingBuffer();
+    PackStorage11 *getPackStorage();
+
+    BufferStorage11 *getBufferStorage(BufferUsage usage);
+    BufferStorage11 *getLatestBufferStorage() const;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_BUFFER11_H_
diff --git a/src/libGLESv2/renderer/d3d/d3d11/BufferStorage11.h b/src/libGLESv2/renderer/d3d/d3d11/BufferStorage11.h
deleted file mode 100644
index 7934de1..0000000
--- a/src/libGLESv2/renderer/d3d/d3d11/BufferStorage11.h
+++ /dev/null
@@ -1,100 +0,0 @@
-//
-// Copyright (c) 2013-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.
-//
-
-// BufferStorage11.h Defines the BufferStorage11 class.
-
-#ifndef LIBGLESV2_RENDERER_BUFFERSTORAGE11_H_
-#define LIBGLESV2_RENDERER_BUFFERSTORAGE11_H_
-
-#include "libGLESv2/renderer/BufferStorage.h"
-#include "libGLESv2/angletypes.h"
-
-namespace rx
-{
-class Renderer;
-class Renderer11;
-
-enum BufferUsage
-{
-    BUFFER_USAGE_STAGING,
-    BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK,
-    BUFFER_USAGE_INDEX,
-    BUFFER_USAGE_PIXEL_UNPACK,
-    BUFFER_USAGE_PIXEL_PACK,
-    BUFFER_USAGE_UNIFORM,
-};
-
-struct PackPixelsParams
-{
-    PackPixelsParams();
-    PackPixelsParams(const gl::Rectangle &area, GLenum format, GLenum type, GLuint outputPitch,
-                     const gl::PixelPackState &pack, ptrdiff_t offset);
-
-    gl::Rectangle area;
-    GLenum format;
-    GLenum type;
-    GLuint outputPitch;
-    gl::Buffer *packBuffer;
-    gl::PixelPackState pack;
-    ptrdiff_t offset;
-};
-
-typedef size_t DataRevision;
-
-class BufferStorage11 : public BufferStorage
-{
-  public:
-    explicit BufferStorage11(Renderer11 *renderer);
-    virtual ~BufferStorage11();
-
-    static BufferStorage11 *makeBufferStorage11(BufferStorage *bufferStorage);
-
-    virtual void *getData();
-    virtual void setData(const void* data, size_t size, size_t offset);
-    virtual void copyData(BufferStorage* sourceStorage, size_t size, size_t sourceOffset, size_t destOffset);
-    virtual void clear();
-    virtual void markTransformFeedbackUsage();
-    virtual size_t getSize() const;
-    virtual bool supportsDirectBinding() const;
-
-    ID3D11Buffer *getBuffer(BufferUsage usage);
-    ID3D11ShaderResourceView *getSRV(DXGI_FORMAT srvFormat);
-    void packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams &params);
-
-    virtual bool isMapped() const;
-    virtual void *map(GLbitfield access);
-    virtual void unmap();
-
-  private:
-    class TypedBufferStorage11;
-    class NativeBuffer11;
-    class PackStorage11;
-
-    Renderer11 *mRenderer;
-    TypedBufferStorage11 *mMappedStorage;
-
-    std::map<BufferUsage, TypedBufferStorage11*> mTypedBuffers;
-
-    typedef std::pair<ID3D11Buffer *, ID3D11ShaderResourceView *> BufferSRVPair;
-    std::map<DXGI_FORMAT, BufferSRVPair> mBufferResourceViews;
-
-    std::vector<unsigned char> mResolvedData;
-    DataRevision mResolvedDataRevision;
-    unsigned int mReadUsageCount;
-
-    size_t mSize;
-
-    void markBufferUsage();
-    NativeBuffer11 *getStagingBuffer();
-    PackStorage11 *getPackStorage();
-
-    TypedBufferStorage11 *getStorage(BufferUsage usage);
-    TypedBufferStorage11 *getLatestStorage() const;
-};
-
-}
-
-#endif // LIBGLESV2_RENDERER_BUFFERSTORAGE11_H_
diff --git a/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp b/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp
index a5ec58a..a10f64e 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp
@@ -10,7 +10,7 @@
 
 #include "libGLESv2/renderer/d3d/d3d11/InputLayoutCache.h"
 #include "libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h"
-#include "libGLESv2/renderer/d3d/d3d11/BufferStorage11.h"
+#include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
 #include "libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.h"
 #include "libGLESv2/ProgramBinary.h"
 #include "libGLESv2/VertexAttribute.h"
@@ -194,7 +194,7 @@
         if (attributes[i].active)
         {
             VertexBuffer11 *vertexBuffer = VertexBuffer11::makeVertexBuffer11(attributes[i].vertexBuffer);
-            BufferStorage11 *bufferStorage = attributes[i].storage ? BufferStorage11::makeBufferStorage11(attributes[i].storage) : NULL;
+            Buffer11 *bufferStorage = attributes[i].storage ? Buffer11::makeBuffer11(attributes[i].storage) : NULL;
 
             buffer = bufferStorage ? bufferStorage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK)
                                    : vertexBuffer->getBuffer();
diff --git a/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp b/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp
index 566ec26..1ca456c 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp
@@ -17,7 +17,7 @@
 #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
 #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
 #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
-#include "libGLESv2/renderer/d3d/d3d11/BufferStorage11.h"
+#include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
 #include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h"
 #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
 #include "libGLESv2/Context.h"
@@ -162,7 +162,7 @@
 
     DXGI_FORMAT srvFormat = gl_d3d11::GetSRVFormat(sourceFormat);
     ASSERT(srvFormat != DXGI_FORMAT_UNKNOWN);
-    BufferStorage11 *bufferStorage11 = BufferStorage11::makeBufferStorage11(sourceBuffer.getStorage());
+    Buffer11 *bufferStorage11 = Buffer11::makeBuffer11(sourceBuffer.getImplementation());
     ID3D11ShaderResourceView *bufferSRV = bufferStorage11->getSRV(srvFormat);
     ASSERT(bufferSRV != NULL);
 
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
index 092a028..ddb6236 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
@@ -22,7 +22,7 @@
 #include "libGLESv2/renderer/d3d/d3d11/Image11.h"
 #include "libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h"
 #include "libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h"
-#include "libGLESv2/renderer/d3d/d3d11/BufferStorage11.h"
+#include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
 #include "libGLESv2/renderer/d3d/VertexDataManager.h"
 #include "libGLESv2/renderer/d3d/IndexDataManager.h"
 #include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h"
@@ -32,6 +32,7 @@
 #include "libGLESv2/renderer/d3d/d3d11/Clear11.h"
 #include "libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h"
 #include "libGLESv2/renderer/d3d/d3d11/VertexArray11.h"
+#include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
 #include "libEGL/Display.h"
 
 // Enable ANGLE_SKIP_DXGI_1_2_CHECK if there is not a possibility of using cross-process
@@ -540,7 +541,7 @@
         const gl::Buffer *uniformBuffer = vertexUniformBuffers[uniformBufferIndex];
         if (uniformBuffer)
         {
-            BufferStorage11 *bufferStorage = BufferStorage11::makeBufferStorage11(uniformBuffer->getStorage());
+            Buffer11 *bufferStorage = Buffer11::makeBuffer11(uniformBuffer->getImplementation());
             ID3D11Buffer *constantBuffer = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM);
 
             if (!constantBuffer)
@@ -562,7 +563,7 @@
         const gl::Buffer *uniformBuffer = fragmentUniformBuffers[uniformBufferIndex];
         if (uniformBuffer)
         {
-            BufferStorage11 *bufferStorage = BufferStorage11::makeBufferStorage11(uniformBuffer->getStorage());
+            Buffer11 *bufferStorage = Buffer11::makeBuffer11(uniformBuffer->getImplementation());
             ID3D11Buffer *constantBuffer = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM);
 
             if (!constantBuffer)
@@ -987,7 +988,7 @@
 
         if (indexInfo->storage)
         {
-            BufferStorage11 *storage = BufferStorage11::makeBufferStorage11(indexInfo->storage);
+            Buffer11 *storage = Buffer11::makeBuffer11(indexInfo->storage);
             buffer = storage->getBuffer(BUFFER_USAGE_INDEX);
         }
         else
@@ -1017,7 +1018,7 @@
     {
         if (transformFeedbackBuffers[i])
         {
-            BufferStorage11 *storage = BufferStorage11::makeBufferStorage11(transformFeedbackBuffers[i]->getStorage());
+            Buffer11 *storage = Buffer11::makeBuffer11(transformFeedbackBuffers[i]->getImplementation());
             ID3D11Buffer *buffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
 
             d3dBuffers[i] = buffer;
@@ -1125,7 +1126,7 @@
     if (type != GL_NONE && elementArrayBuffer)
     {
         gl::Buffer *indexBuffer = elementArrayBuffer;
-        BufferStorage *storage = indexBuffer->getStorage();
+        BufferImpl *storage = indexBuffer->getImplementation();
         intptr_t offset = reinterpret_cast<intptr_t>(indices);
         indices = static_cast<const GLubyte*>(storage->getData()) + offset;
     }
@@ -1230,7 +1231,7 @@
     if (type != GL_NONE && elementArrayBuffer)
     {
         gl::Buffer *indexBuffer = elementArrayBuffer;
-        BufferStorage *storage = indexBuffer->getStorage();
+        BufferImpl *storage = indexBuffer->getImplementation();
         intptr_t offset = reinterpret_cast<intptr_t>(indices);
         indices = static_cast<const GLubyte*>(storage->getData()) + offset;
     }
@@ -2778,9 +2779,9 @@
     return new IndexBuffer11(this);
 }
 
-BufferStorage *Renderer11::createBufferStorage()
+BufferImpl *Renderer11::createBuffer()
 {
-    return new BufferStorage11(this);
+    return new Buffer11(this);
 }
 
 VertexArrayImpl *Renderer11::createVertexArray()
@@ -2960,7 +2961,7 @@
 
         if (pack.pixelBuffer.get() != NULL)
         {
-            rx::BufferStorage11 *packBufferStorage = BufferStorage11::makeBufferStorage11(pack.pixelBuffer.get()->getStorage());
+            rx::Buffer11 *packBufferStorage = Buffer11::makeBuffer11(pack.pixelBuffer.get()->getImplementation());
             PackPixelsParams packParams(area, format, type, outputPitch, pack, reinterpret_cast<ptrdiff_t>(pixels));
             packBufferStorage->packPixels(colorBufferTexture, subresourceIndex, packParams);
         }
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
index 0c02837..b490d14 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
+++ b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
@@ -186,9 +186,9 @@
     virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels);
 
     // Buffer creation
+    virtual BufferImpl *createBuffer();
     virtual VertexBuffer *createVertexBuffer();
     virtual IndexBuffer *createIndexBuffer();
-    virtual BufferStorage *createBufferStorage();
 
     // Vertex Array creation
     virtual VertexArrayImpl *createVertexArray();
diff --git a/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp b/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp
index c5d63e6..2f47ec0 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp
@@ -8,7 +8,7 @@
 // VertexBuffer11.cpp: Defines the D3D11 VertexBuffer implementation.
 
 #include "libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h"
-#include "libGLESv2/renderer/BufferStorage.h"
+#include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
 
 #include "libGLESv2/Buffer.h"
 #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
@@ -90,7 +90,7 @@
         {
             if (buffer)
             {
-                BufferStorage *storage = buffer->getStorage();
+                Buffer11 *storage = Buffer11::makeBuffer11(buffer->getImplementation());
                 input = static_cast<const char*>(storage->getData()) + static_cast<int>(attrib.offset);
             }
             else
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp b/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp
new file mode 100644
index 0000000..c86fe13
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp
@@ -0,0 +1,120 @@
+#include "precompiled.h"
+//
+// Copyright 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.
+//
+
+// Buffer9.cpp Defines the Buffer9 class.
+
+#include "libGLESv2/renderer/d3d/d3d9/Buffer9.h"
+#include "libGLESv2/main.h"
+#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
+
+namespace rx
+{
+
+Buffer9::Buffer9(rx::Renderer9 *renderer)
+    : BufferD3D(),
+      mRenderer(renderer),
+      mSize(0)
+{
+
+}
+
+Buffer9::~Buffer9()
+{
+
+}
+
+Buffer9 *Buffer9::makeBuffer9(BufferImpl *buffer)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(Buffer9*, buffer));
+    return static_cast<Buffer9*>(buffer);
+}
+
+void Buffer9::clear()
+{
+    mSize = 0;
+}
+
+void Buffer9::setData(const void* data, size_t size, GLenum usage)
+{
+    if (size > mMemory.size())
+    {
+        mMemory.resize(size);
+    }
+
+    mSize = size;
+    if (data)
+    {
+        memcpy(mMemory.data(), data, size);
+    }
+
+    mIndexRangeCache.clear();
+
+    invalidateStaticData();
+
+    if (usage == GL_STATIC_DRAW)
+    {
+        initializeStaticData();
+    }
+}
+
+void *Buffer9::getData()
+{
+    return mMemory.data();
+}
+
+void Buffer9::setSubData(const void* data, size_t size, size_t offset)
+{
+    if (offset + size > mMemory.size())
+    {
+        mMemory.resize(offset + size);
+    }
+
+    mSize = std::max(mSize, offset + size);
+    if (data)
+    {
+        memcpy(mMemory.data() + offset, data, size);
+    }
+
+    mIndexRangeCache.invalidateRange(offset, size);
+
+    invalidateStaticData();
+}
+
+void Buffer9::copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size)
+{
+    Buffer9* sourceBuffer = makeBuffer9(source);
+    if (sourceBuffer)
+    {
+        memcpy(mMemory.data() + destOffset, sourceBuffer->mMemory.data() + sourceOffset, size);
+    }
+
+    invalidateStaticData();
+}
+
+// We do not suppot buffer mapping in D3D9
+GLvoid* Buffer9::map(size_t offset, size_t length, GLbitfield access)
+{
+    UNREACHABLE();
+    return NULL;
+}
+
+void Buffer9::unmap()
+{
+    UNREACHABLE();
+}
+
+void Buffer9::markTransformFeedbackUsage()
+{
+    UNREACHABLE();
+}
+
+Renderer* Buffer9::getRenderer()
+{
+    return mRenderer;
+}
+
+}
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h b/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h
new file mode 100644
index 0000000..0f80d07
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h
@@ -0,0 +1,52 @@
+//
+// Copyright 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.
+//
+
+// Buffer9.h: Defines the rx::Buffer9 class which implements rx::BufferImpl via rx::BufferD3D.
+
+#ifndef LIBGLESV2_RENDERER_BUFFER9_H_
+#define LIBGLESV2_RENDERER_BUFFER9_H_
+
+#include "libGLESv2/renderer/d3d/BufferD3D.h"
+#include "libGLESv2/angletypes.h"
+
+namespace rx
+{
+class Renderer9;
+
+class Buffer9 : public BufferD3D
+{
+  public:
+    Buffer9(rx::Renderer9 *renderer);
+    virtual ~Buffer9();
+
+    static Buffer9 *makeBuffer9(BufferImpl *buffer);
+
+    // BufferD3D implementation
+    virtual size_t getSize() const { return mSize; }
+    virtual void clear();
+    virtual bool supportsDirectBinding() const { return false; }
+    virtual Renderer* getRenderer();
+
+    // BufferImpl implementation
+    virtual void setData(const void* data, size_t size, GLenum usage);
+    virtual void *getData();
+    virtual void setSubData(const void* data, size_t size, size_t offset);
+    virtual void copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size);
+    virtual GLvoid* map(size_t offset, size_t length, GLbitfield access);
+    virtual void unmap();
+    virtual void markTransformFeedbackUsage();
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(Buffer9);
+
+    rx::Renderer9 *mRenderer;
+    std::vector<char> mMemory;
+    size_t mSize;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_BUFFER9_H_
diff --git a/src/libGLESv2/renderer/d3d/d3d9/BufferStorage9.cpp b/src/libGLESv2/renderer/d3d/d3d9/BufferStorage9.cpp
deleted file mode 100644
index a225680..0000000
--- a/src/libGLESv2/renderer/d3d/d3d9/BufferStorage9.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-#include "precompiled.h"
-//
-// Copyright (c) 2013-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.
-//
-
-// BufferStorage9.cpp Defines the BufferStorage9 class.
-
-#include "libGLESv2/renderer/d3d/d3d9/BufferStorage9.h"
-#include "common/debug.h"
-#include "libGLESv2/main.h"
-
-namespace rx
-{
-
-BufferStorage9::BufferStorage9()
-    : mSize(0)
-{
-}
-
-BufferStorage9::~BufferStorage9()
-{
-}
-
-BufferStorage9 *BufferStorage9::makeBufferStorage9(BufferStorage *bufferStorage)
-{
-    ASSERT(HAS_DYNAMIC_TYPE(BufferStorage9*, bufferStorage));
-    return static_cast<BufferStorage9*>(bufferStorage);
-}
-
-void *BufferStorage9::getData()
-{
-    return mMemory.data();
-}
-
-void BufferStorage9::setData(const void* data, size_t size, size_t offset)
-{
-    if (offset + size > mMemory.size())
-    {
-        mMemory.resize(offset + size);
-    }
-
-    mSize = std::max(mSize, offset + size);
-    if (data)
-    {
-        memcpy(mMemory.data() + offset, data, size);
-    }
-}
-
-void BufferStorage9::copyData(BufferStorage* sourceStorage, size_t size, size_t sourceOffset, size_t destOffset)
-{
-    BufferStorage9* source = makeBufferStorage9(sourceStorage);
-    if (source)
-    {
-        memcpy(mMemory.data() + destOffset, source->mMemory.data() + sourceOffset, size);
-    }
-}
-
-void BufferStorage9::clear()
-{
-    mSize = 0;
-}
-
-void BufferStorage9::markTransformFeedbackUsage()
-{
-    UNREACHABLE();
-}
-
-size_t BufferStorage9::getSize() const
-{
-    return mSize;
-}
-
-bool BufferStorage9::supportsDirectBinding() const
-{
-    return false;
-}
-
-// We do not suppot buffer mapping facility in D3D9
-bool BufferStorage9::isMapped() const
-{
-    UNREACHABLE();
-    return false;
-}
-
-void *BufferStorage9::map(GLbitfield access)
-{
-    UNREACHABLE();
-    return NULL;
-}
-
-void BufferStorage9::unmap()
-{
-    UNREACHABLE();
-}
-
-}
diff --git a/src/libGLESv2/renderer/d3d/d3d9/BufferStorage9.h b/src/libGLESv2/renderer/d3d/d3d9/BufferStorage9.h
deleted file mode 100644
index dd61624..0000000
--- a/src/libGLESv2/renderer/d3d/d3d9/BufferStorage9.h
+++ /dev/null
@@ -1,46 +0,0 @@
-//
-// Copyright (c) 2013-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.
-//
-
-// BufferStorage9.h Defines the BufferStorage9 class.
-
-#ifndef LIBGLESV2_RENDERER_BUFFERSTORAGE9_H_
-#define LIBGLESV2_RENDERER_BUFFERSTORAGE9_H_
-
-#include "libGLESv2/renderer/BufferStorage.h"
-
-namespace rx
-{
-
-class BufferStorage9 : public BufferStorage
-{
-  public:
-    BufferStorage9();
-    virtual ~BufferStorage9();
-
-    static BufferStorage9 *makeBufferStorage9(BufferStorage *bufferStorage);
-
-    virtual void *getData();
-    virtual void setData(const void* data, size_t size, size_t offset);
-    virtual void copyData(BufferStorage* sourceStorage, size_t size, size_t sourceOffset, size_t destOffset);
-    virtual void clear();
-    virtual void markTransformFeedbackUsage();
-    virtual size_t getSize() const;
-    virtual bool supportsDirectBinding() const;
-
-    virtual bool isMapped() const;
-    virtual void *map(GLbitfield access);
-    virtual void unmap();
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(BufferStorage9);
-
-    std::vector<char> mMemory;
-    size_t mSize;
-};
-
-}
-
-#endif // LIBGLESV2_RENDERER_BUFFERSTORAGE9_H_
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
index 49f5b3b..02ceae2 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
@@ -28,7 +28,7 @@
 #include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h"
 #include "libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h"
 #include "libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h"
-#include "libGLESv2/renderer/d3d/d3d9/BufferStorage9.h"
+#include "libGLESv2/renderer/d3d/d3d9/Buffer9.h"
 #include "libGLESv2/renderer/d3d/d3d9/Query9.h"
 #include "libGLESv2/renderer/d3d/d3d9/Fence9.h"
 #include "libGLESv2/renderer/d3d/d3d9/VertexArray9.h"
@@ -608,9 +608,9 @@
     return new IndexBuffer9(this);
 }
 
-BufferStorage *Renderer9::createBufferStorage()
+BufferImpl *Renderer9::createBuffer()
 {
-    return new BufferStorage9();
+    return new Buffer9(this);
 }
 
 VertexArrayImpl *Renderer9::createVertexArray()
@@ -1394,7 +1394,7 @@
     if (type != GL_NONE && elementArrayBuffer)
     {
         gl::Buffer *indexBuffer = elementArrayBuffer;
-        BufferStorage *storage = indexBuffer->getStorage();
+        BufferImpl *storage = indexBuffer->getImplementation();
         intptr_t offset = reinterpret_cast<intptr_t>(indices);
         indices = static_cast<const GLubyte*>(storage->getData()) + offset;
     }
@@ -1592,7 +1592,7 @@
 
     if (elementArrayBuffer)
     {
-        BufferStorage *storage = elementArrayBuffer->getStorage();
+        BufferImpl *storage = elementArrayBuffer->getImplementation();
         intptr_t offset = reinterpret_cast<intptr_t>(indices);
         indices = static_cast<const GLubyte*>(storage->getData()) + offset;
     }
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h
index ecaf832..c7b0018 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h
+++ b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h
@@ -188,9 +188,9 @@
     virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels);
 
     // Buffer creation
+    virtual BufferImpl *createBuffer();
     virtual VertexBuffer *createVertexBuffer();
     virtual IndexBuffer *createIndexBuffer();
-    virtual BufferStorage *createBufferStorage();
 
     // Vertex Array creation
     virtual VertexArrayImpl *createVertexArray();
diff --git a/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp b/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp
index fd442a9..d260640 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp
@@ -9,7 +9,7 @@
 
 #include "libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h"
 #include "libGLESv2/renderer/vertexconversion.h"
-#include "libGLESv2/renderer/BufferStorage.h"
+#include "libGLESv2/renderer/BufferImpl.h"
 #include "libGLESv2/VertexAttribute.h"
 #include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
 #include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
@@ -98,7 +98,7 @@
         {
             if (buffer)
             {
-                BufferStorage *storage = buffer->getStorage();
+                BufferImpl *storage = buffer->getImplementation();
                 input = static_cast<const char*>(storage->getData()) + static_cast<int>(attrib.offset);
             }
             else
diff --git a/src/libGLESv2/validationES3.cpp b/src/libGLESv2/validationES3.cpp
index 27c226d..e16c9a2 100644
--- a/src/libGLESv2/validationES3.cpp
+++ b/src/libGLESv2/validationES3.cpp
@@ -277,7 +277,7 @@
         size_t offset = reinterpret_cast<size_t>(pixels);
 
         if (!rx::IsUnsignedAdditionSafe(offset, copyBytes) ||
-            ((offset + copyBytes) > static_cast<size_t>(pixelUnpackBuffer->size())))
+            ((offset + copyBytes) > static_cast<size_t>(pixelUnpackBuffer->getSize())))
         {
             // Overflow past the end of the buffer
             return gl::error(GL_INVALID_OPERATION, false);
@@ -293,7 +293,7 @@
         }
 
         // ...the buffer object's data store is currently mapped.
-        if (pixelUnpackBuffer->mapped())
+        if (pixelUnpackBuffer->isMapped())
         {
             return gl::error(GL_INVALID_OPERATION, false);
         }