Changes gl::RenderbufferStorage to rx::RenderbufferImpl

BUG=angle:782

Also eliminates Colorbuffer/DepthStencilBuffer and related friends
and adds the RenderbufferD3D implementation of RenderbufferImpl.

Change-Id: Ibe72c9589b3c238b952744e7cfd70d97ec898eb9
Reviewed-on: https://chromium-review.googlesource.com/222925
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Tested-by: Shannon Woods <shannonwoods@chromium.org>
diff --git a/src/libGLESv2.gypi b/src/libGLESv2.gypi
index 361e645..8f21ae4 100644
--- a/src/libGLESv2.gypi
+++ b/src/libGLESv2.gypi
@@ -104,9 +104,11 @@
             'libGLESv2/renderer/ProgramImpl.cpp',
             'libGLESv2/renderer/ProgramImpl.h',
             'libGLESv2/renderer/QueryImpl.h',
-            'libGLESv2/renderer/RenderTarget.h',
+            'libGLESv2/renderer/RenderbufferImpl.h',
+            'libGLESv2/renderer/RenderbufferImpl.cpp',
             'libGLESv2/renderer/Renderer.cpp',
             'libGLESv2/renderer/Renderer.h',
+            'libGLESv2/renderer/RenderTarget.h',
             'libGLESv2/renderer/ShaderExecutable.h',
             'libGLESv2/renderer/ShaderImpl.h',
             'libGLESv2/renderer/SwapChain.h',
@@ -169,6 +171,8 @@
             'libGLESv2/renderer/d3d/MemoryBuffer.h',
             'libGLESv2/renderer/d3d/ProgramD3D.cpp',
             'libGLESv2/renderer/d3d/ProgramD3D.h',
+            'libGLESv2/renderer/d3d/RenderbufferD3D.cpp',
+            'libGLESv2/renderer/d3d/RenderbufferD3D.h',
             'libGLESv2/renderer/d3d/ShaderD3D.cpp',
             'libGLESv2/renderer/d3d/ShaderD3D.h',
             'libGLESv2/renderer/d3d/TextureD3D.cpp',
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index b6b5472..e215696 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -192,8 +192,8 @@
     // Wrap the existing swapchain resources into GL objects and assign them to the '0' names
     rx::SwapChain *swapchain = surface->getSwapChain();
 
-    Colorbuffer *colorbufferZero = new Colorbuffer(mRenderer, swapchain);
-    DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(mRenderer, swapchain);
+    rx::RenderbufferImpl *colorbufferZero = mRenderer->createRenderbuffer(swapchain, false);
+    rx::RenderbufferImpl *depthStencilbufferZero = mRenderer->createRenderbuffer(swapchain, true);
     Framebuffer *framebufferZero = new DefaultFramebuffer(mRenderer, colorbufferZero, depthStencilbufferZero);
 
     setFramebufferZero(framebufferZero);
@@ -728,33 +728,6 @@
     mFramebufferMap[0] = buffer;
 }
 
-void Context::setRenderbufferStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples)
-{
-    ASSERT(getTextureCaps().get(internalformat).renderable);
-
-    RenderbufferStorage *renderbuffer = NULL;
-
-    const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
-    if (formatInfo.depthBits > 0 && formatInfo.stencilBits > 0)
-    {
-        renderbuffer = new gl::DepthStencilbuffer(mRenderer, width, height, samples);
-    }
-    else if (formatInfo.depthBits > 0)
-    {
-        renderbuffer = new gl::Depthbuffer(mRenderer, width, height, samples);
-    }
-    else if (formatInfo.stencilBits > 0)
-    {
-        renderbuffer = new gl::Stencilbuffer(mRenderer, width, height, samples);
-    }
-    else
-    {
-        renderbuffer = new gl::Colorbuffer(mRenderer, width, height, internalformat, samples);
-    }
-
-    mState.getCurrentRenderbuffer()->setStorage(renderbuffer);
-}
-
 Framebuffer *Context::getFramebuffer(unsigned int handle) const
 {
     FramebufferMap::const_iterator framebuffer = mFramebufferMap.find(handle);
diff --git a/src/libGLESv2/Context.h b/src/libGLESv2/Context.h
index 46364bd..eb81e1a 100644
--- a/src/libGLESv2/Context.h
+++ b/src/libGLESv2/Context.h
@@ -50,11 +50,6 @@
 class Texture2DArray;
 class Framebuffer;
 class Renderbuffer;
-class RenderbufferStorage;
-class Colorbuffer;
-class Depthbuffer;
-class Stencilbuffer;
-class DepthStencilbuffer;
 class FenceNV;
 class FenceSync;
 class Query;
@@ -139,8 +134,6 @@
 
     void setFramebufferZero(Framebuffer *framebuffer);
 
-    void setRenderbufferStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples);
-
     void setVertexAttribDivisor(GLuint index, GLuint divisor);
 
     void samplerParameteri(GLuint sampler, GLenum pname, GLint param);
diff --git a/src/libGLESv2/Framebuffer.cpp b/src/libGLESv2/Framebuffer.cpp
index 9cd9e25..4587f2b 100644
--- a/src/libGLESv2/Framebuffer.cpp
+++ b/src/libGLESv2/Framebuffer.cpp
@@ -16,13 +16,17 @@
 #include "libGLESv2/FramebufferAttachment.h"
 #include "libGLESv2/renderer/Renderer.h"
 #include "libGLESv2/renderer/RenderTarget.h"
+#include "libGLESv2/renderer/RenderbufferImpl.h"
 #include "libGLESv2/renderer/Workarounds.h"
 #include "libGLESv2/renderer/d3d/TextureD3D.h"
+#include "libGLESv2/renderer/d3d/RenderbufferD3D.h"
 
 #include "common/utilities.h"
 
 namespace rx
 {
+// TODO: Move these functions, and the D3D-specific header inclusions above,
+//       to FramebufferD3D.
 gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget **outRT)
 {
     if (attachment->isTexture())
@@ -38,9 +42,8 @@
     {
         gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
         ASSERT(renderbuffer);
-
-        // TODO: cast to RenderbufferD3D
-        *outRT = renderbuffer->getStorage()->getRenderTarget();
+        RenderbufferD3D *renderbufferD3D = RenderbufferD3D::makeRenderbufferD3D(renderbuffer->getImpl());
+        *outRT = renderbufferD3D->getRenderTarget();
         return gl::Error(GL_NO_ERROR);
     }
 }
@@ -60,9 +63,8 @@
 
     gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
     ASSERT(renderbuffer);
-
-    // TODO: cast to RenderbufferD3D
-    return renderbuffer->getStorage()->getSerial();
+    RenderbufferD3D *renderbufferD3D = RenderbufferD3D::makeRenderbufferD3D(renderbuffer->getImpl());
+    return renderbufferD3D->getSerial();
 }
 
 }
@@ -638,13 +640,13 @@
     return Error(GL_NO_ERROR);
 }
 
-DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
+DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, rx::RenderbufferImpl *colorbuffer, rx::RenderbufferImpl *depthStencil)
     : Framebuffer(renderer, 0)
 {
-    Renderbuffer *colorRenderbuffer = new Renderbuffer(0, colorbuffer);
+    Renderbuffer *colorRenderbuffer = new Renderbuffer(colorbuffer, 0);
     mColorbuffers[0] = new RenderbufferAttachment(GL_BACK, colorRenderbuffer);
 
-    Renderbuffer *depthStencilBuffer = new Renderbuffer(0, depthStencil);
+    Renderbuffer *depthStencilBuffer = new Renderbuffer(depthStencil, 0);
 
     // Make a new attachment objects to ensure we do not double-delete
     // See angle issue 686
diff --git a/src/libGLESv2/Framebuffer.h b/src/libGLESv2/Framebuffer.h
index 1f55b43..c528ce7 100644
--- a/src/libGLESv2/Framebuffer.h
+++ b/src/libGLESv2/Framebuffer.h
@@ -21,15 +21,12 @@
 namespace rx
 {
 class Renderer;
+class RenderbufferImpl;
 }
 
 namespace gl
 {
 class FramebufferAttachment;
-class Colorbuffer;
-class Depthbuffer;
-class Stencilbuffer;
-class DepthStencilbuffer;
 struct Caps;
 
 typedef std::vector<FramebufferAttachment *> ColorbufferInfo;
@@ -103,7 +100,7 @@
 class DefaultFramebuffer : public Framebuffer
 {
   public:
-    DefaultFramebuffer(rx::Renderer *Renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil);
+    DefaultFramebuffer(rx::Renderer *Renderer, rx::RenderbufferImpl *colorbuffer, rx::RenderbufferImpl *depthStencil);
 
     virtual GLenum completeness() const;
     virtual FramebufferAttachment *getAttachment(GLenum attachment) const;
diff --git a/src/libGLESv2/FramebufferAttachment.cpp b/src/libGLESv2/FramebufferAttachment.cpp
index 540ede1..894884a 100644
--- a/src/libGLESv2/FramebufferAttachment.cpp
+++ b/src/libGLESv2/FramebufferAttachment.cpp
@@ -187,7 +187,7 @@
 
 GLsizei RenderbufferAttachment::getSamples() const
 {
-    return mRenderbuffer->getStorage()->getSamples();
+    return mRenderbuffer->getSamples();
 }
 
 GLuint RenderbufferAttachment::id() const
diff --git a/src/libGLESv2/Renderbuffer.cpp b/src/libGLESv2/Renderbuffer.cpp
index 9406fce..2931a0b 100644
--- a/src/libGLESv2/Renderbuffer.cpp
+++ b/src/libGLESv2/Renderbuffer.cpp
@@ -4,9 +4,9 @@
 // found in the LICENSE file.
 //
 
-// Renderbuffer.cpp: the gl::Renderbuffer class and its derived classes
-// Colorbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
-// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
+// Renderbuffer.cpp: Implements the renderer-agnostic gl::Renderbuffer class,
+// GL renderbuffer objects and related functionality.
+// [OpenGL ES 2.0.24] section 4.4.3 page 108.
 
 #include "libGLESv2/Renderbuffer.h"
 #include "libGLESv2/Texture.h"
@@ -14,67 +14,70 @@
 #include "libGLESv2/FramebufferAttachment.h"
 #include "libGLESv2/renderer/Renderer.h"
 #include "libGLESv2/renderer/RenderTarget.h"
+#include "libGLESv2/renderer/RenderbufferImpl.h"
 
 #include "common/utilities.h"
 
 namespace gl
 {
-unsigned int RenderbufferStorage::mCurrentSerial = 1;
-
-Renderbuffer::Renderbuffer(GLuint id, RenderbufferStorage *newStorage)
+Renderbuffer::Renderbuffer(rx::RenderbufferImpl *impl, GLuint id)
   : RefCountObject(id),
-    mStorage(newStorage)
+    mRenderbuffer(impl)
 {
-    ASSERT(mStorage);
+    ASSERT(mRenderbuffer);
+
+    mWidth = mRenderbuffer->getWidth();
+    mHeight = mRenderbuffer->getHeight();
+    mInternalFormat = mRenderbuffer->getInternalFormat();
+    mActualFormat = mRenderbuffer->getActualFormat();
+    mSamples = mRenderbuffer->getSamples();
 }
 
 Renderbuffer::~Renderbuffer()
 {
-    SafeDelete(mStorage);
+    SafeDelete(mRenderbuffer);
 }
 
-void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
+void Renderbuffer::setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples)
 {
-    ASSERT(newStorage);
+    mWidth = width;
+    mHeight = height;
+    mInternalFormat = internalformat;
+    mSamples = samples;
 
-    SafeDelete(mStorage);
-    mStorage = newStorage;
+    mRenderbuffer->setStorage(width, height, internalformat, samples);
+    mActualFormat = mRenderbuffer->getActualFormat();
 }
 
-RenderbufferStorage *Renderbuffer::getStorage()
+rx::RenderbufferImpl *Renderbuffer::getImpl()
 {
-    ASSERT(mStorage);
-    return mStorage;
+    ASSERT(mRenderbuffer);
+    return mRenderbuffer;
 }
 
 GLsizei Renderbuffer::getWidth() const
 {
-    ASSERT(mStorage);
-    return mStorage->getWidth();
+    return mWidth;
 }
 
 GLsizei Renderbuffer::getHeight() const
 {
-    ASSERT(mStorage);
-    return mStorage->getHeight();
+    return mHeight;
 }
 
 GLenum Renderbuffer::getInternalFormat() const
 {
-    ASSERT(mStorage);
-    return mStorage->getInternalFormat();
+    return mInternalFormat;
 }
 
 GLenum Renderbuffer::getActualFormat() const
 {
-    ASSERT(mStorage);
-    return mStorage->getActualFormat();
+    return mActualFormat;
 }
 
 GLsizei Renderbuffer::getSamples() const
 {
-    ASSERT(mStorage);
-    return mStorage->getSamples();
+    return mSamples;
 }
 
 GLuint Renderbuffer::getRedSize() const
@@ -107,176 +110,4 @@
     return GetInternalFormatInfo(getActualFormat()).stencilBits;
 }
 
-RenderbufferStorage::RenderbufferStorage() : mSerial(issueSerials(1))
-{
-    mWidth = 0;
-    mHeight = 0;
-    mInternalFormat = GL_RGBA4;
-    mActualFormat = GL_RGBA8_OES;
-    mSamples = 0;
-}
-
-RenderbufferStorage::~RenderbufferStorage()
-{
-}
-
-rx::RenderTarget *RenderbufferStorage::getRenderTarget()
-{
-    return NULL;
-}
-
-GLsizei RenderbufferStorage::getWidth() const
-{
-    return mWidth;
-}
-
-GLsizei RenderbufferStorage::getHeight() const
-{
-    return mHeight;
-}
-
-GLenum RenderbufferStorage::getInternalFormat() const
-{
-    return mInternalFormat;
-}
-
-GLenum RenderbufferStorage::getActualFormat() const
-{
-    return mActualFormat;
-}
-
-GLsizei RenderbufferStorage::getSamples() const
-{
-    return mSamples;
-}
-
-unsigned int RenderbufferStorage::getSerial() const
-{
-    return mSerial;
-}
-
-unsigned int RenderbufferStorage::issueSerials(unsigned int count)
-{
-    unsigned int firstSerial = mCurrentSerial;
-    mCurrentSerial += count;
-    return firstSerial;
-}
-
-bool RenderbufferStorage::isTexture() const
-{
-    return false;
-}
-
-unsigned int RenderbufferStorage::getTextureSerial() const
-{
-    return -1;
-}
-
-Colorbuffer::Colorbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain)
-{
-    mRenderTarget = renderer->createRenderTarget(swapChain, false); 
-
-    if (mRenderTarget)
-    {
-        mWidth = mRenderTarget->getWidth();
-        mHeight = mRenderTarget->getHeight();
-        mInternalFormat = mRenderTarget->getInternalFormat();
-        mActualFormat = mRenderTarget->getActualFormat();
-        mSamples = mRenderTarget->getSamples();
-    }
-}
-
-Colorbuffer::Colorbuffer(rx::Renderer *renderer, int width, int height, GLenum format, GLsizei samples) : mRenderTarget(NULL)
-{
-    mRenderTarget = renderer->createRenderTarget(width, height, format, samples);
-
-    if (mRenderTarget)
-    {
-        mWidth = width;
-        mHeight = height;
-        mInternalFormat = format;
-        mActualFormat = mRenderTarget->getActualFormat();
-        mSamples = mRenderTarget->getSamples();
-    }
-}
-
-Colorbuffer::~Colorbuffer()
-{
-    if (mRenderTarget)
-    {
-        delete mRenderTarget;
-    }
-}
-
-rx::RenderTarget *Colorbuffer::getRenderTarget()
-{
-    return mRenderTarget;
-}
-
-DepthStencilbuffer::DepthStencilbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain)
-{
-    mDepthStencil = renderer->createRenderTarget(swapChain, true);
-    if (mDepthStencil)
-    {
-        mWidth = mDepthStencil->getWidth();
-        mHeight = mDepthStencil->getHeight();
-        mInternalFormat = mDepthStencil->getInternalFormat();
-        mSamples = mDepthStencil->getSamples();
-        mActualFormat = mDepthStencil->getActualFormat();
-    }
-}
-
-DepthStencilbuffer::DepthStencilbuffer(rx::Renderer *renderer, int width, int height, GLsizei samples)
-{
-
-    mDepthStencil = renderer->createRenderTarget(width, height, GL_DEPTH24_STENCIL8_OES, samples);
-
-    mWidth = mDepthStencil->getWidth();
-    mHeight = mDepthStencil->getHeight();
-    mInternalFormat = GL_DEPTH24_STENCIL8_OES;
-    mActualFormat = mDepthStencil->getActualFormat();
-    mSamples = mDepthStencil->getSamples();
-}
-
-DepthStencilbuffer::~DepthStencilbuffer()
-{
-    if (mDepthStencil)
-    {
-        delete mDepthStencil;
-    }
-}
-
-rx::RenderTarget *DepthStencilbuffer::getRenderTarget()
-{
-    return mDepthStencil;
-}
-
-Depthbuffer::Depthbuffer(rx::Renderer *renderer, int width, int height, GLsizei samples) : DepthStencilbuffer(renderer, width, height, samples)
-{
-    if (mDepthStencil)
-    {
-        mInternalFormat = GL_DEPTH_COMPONENT16;   // If the renderbuffer parameters are queried, the calling function
-                                                  // will expect one of the valid renderbuffer formats for use in 
-                                                  // glRenderbufferStorage
-    }
-}
-
-Depthbuffer::~Depthbuffer()
-{
-}
-
-Stencilbuffer::Stencilbuffer(rx::Renderer *renderer, int width, int height, GLsizei samples) : DepthStencilbuffer(renderer, width, height, samples)
-{
-    if (mDepthStencil)
-    {
-        mInternalFormat = GL_STENCIL_INDEX8;   // If the renderbuffer parameters are queried, the calling function
-                                               // will expect one of the valid renderbuffer formats for use in 
-                                               // glRenderbufferStorage
-    }
-}
-
-Stencilbuffer::~Stencilbuffer()
-{
-}
-
 }
diff --git a/src/libGLESv2/Renderbuffer.h b/src/libGLESv2/Renderbuffer.h
index 71bcb0e..fd1ffa4 100644
--- a/src/libGLESv2/Renderbuffer.h
+++ b/src/libGLESv2/Renderbuffer.h
@@ -4,10 +4,9 @@
 // found in the LICENSE file.
 //
 
-// Renderbuffer.h: Defines the wrapper class gl::Renderbuffer, as well as the
-// class hierarchy used to store its contents: RenderbufferStorage, Colorbuffer,
-// DepthStencilbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
-// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
+// Renderbuffer.h: Defines the renderer-agnostic container class gl::Renderbuffer.
+// Implements GL renderbuffer objects and related functionality.
+// [OpenGL ES 2.0.24] section 4.4.3 page 108.
 
 #ifndef LIBGLESV2_RENDERBUFFER_H_
 #define LIBGLESV2_RENDERBUFFER_H_
@@ -19,15 +18,11 @@
 
 namespace rx
 {
-class Renderer;
-class SwapChain;
-class RenderTarget;
-class TextureStorage;
+class RenderbufferImpl;
 }
 
 namespace gl
 {
-class RenderbufferStorage;
 class FramebufferAttachment;
 
 // A GL renderbuffer object is usually used as a depth or stencil buffer attachment
@@ -38,11 +33,12 @@
 class Renderbuffer : public RefCountObject
 {
   public:
-    Renderbuffer(GLuint id, RenderbufferStorage *newStorage);
+    Renderbuffer(rx::RenderbufferImpl *impl, GLuint id);
     virtual ~Renderbuffer();
 
-    void setStorage(RenderbufferStorage *newStorage);
-    RenderbufferStorage *getStorage();
+    void setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples);
+
+    rx::RenderbufferImpl *getImpl();
 
     GLsizei getWidth() const;
     GLsizei getHeight() const;
@@ -57,102 +53,15 @@
     GLuint getStencilSize() const;
 
   private:
-    RenderbufferStorage *mStorage;
-};
+    DISALLOW_COPY_AND_ASSIGN(Renderbuffer);
 
-// A class derived from RenderbufferStorage is created whenever glRenderbufferStorage
-// is called. The specific concrete type depends on whether the internal format is
-// colour depth, stencil or packed depth/stencil.
-class RenderbufferStorage
-{
-  public:
-    RenderbufferStorage();
+    rx::RenderbufferImpl *mRenderbuffer;
 
-    virtual ~RenderbufferStorage() = 0;
-
-    virtual rx::RenderTarget *getRenderTarget();
-
-    virtual GLsizei getWidth() const;
-    virtual GLsizei getHeight() const;
-    virtual GLenum getInternalFormat() const;
-    virtual GLenum getActualFormat() const;
-    virtual GLsizei getSamples() const;
-
-    virtual unsigned int getSerial() const;
-
-    virtual bool isTexture() const;
-    virtual unsigned int getTextureSerial() const;
-
-    static unsigned int issueSerials(unsigned int count);
-
-  protected:
     GLsizei mWidth;
     GLsizei mHeight;
     GLenum mInternalFormat;
     GLenum mActualFormat;
     GLsizei mSamples;
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(RenderbufferStorage);
-
-    const unsigned int mSerial;
-
-    static unsigned int mCurrentSerial;
-};
-
-class Colorbuffer : public RenderbufferStorage
-{
-  public:
-    Colorbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain);
-    Colorbuffer(rx::Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples);
-
-    virtual ~Colorbuffer();
-
-    virtual rx::RenderTarget *getRenderTarget();
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(Colorbuffer);
-
-    rx::RenderTarget *mRenderTarget;
-};
-
-class DepthStencilbuffer : public RenderbufferStorage
-{
-  public:
-    DepthStencilbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain);
-    DepthStencilbuffer(rx::Renderer *renderer, GLsizei width, GLsizei height, GLsizei samples);
-
-    ~DepthStencilbuffer();
-
-    virtual rx::RenderTarget *getRenderTarget();
-
-  protected:
-    rx::RenderTarget  *mDepthStencil;
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(DepthStencilbuffer);
-};
-
-class Depthbuffer : public DepthStencilbuffer
-{
-  public:
-    Depthbuffer(rx::Renderer *renderer, GLsizei width, GLsizei height, GLsizei samples);
-
-    virtual ~Depthbuffer();
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(Depthbuffer);
-};
-
-class Stencilbuffer : public DepthStencilbuffer
-{
-  public:
-    Stencilbuffer(rx::Renderer *renderer, GLsizei width, GLsizei height, GLsizei samples);
-
-    virtual ~Stencilbuffer();
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(Stencilbuffer);
 };
 
 }
diff --git a/src/libGLESv2/ResourceManager.cpp b/src/libGLESv2/ResourceManager.cpp
index 04fa841..35f8783 100644
--- a/src/libGLESv2/ResourceManager.cpp
+++ b/src/libGLESv2/ResourceManager.cpp
@@ -403,7 +403,7 @@
 {
     if (renderbuffer != 0 && !getRenderbuffer(renderbuffer))
     {
-        Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(mRenderer, 0, 0, GL_RGBA4, 0));
+        Renderbuffer *renderbufferObject = new Renderbuffer(mRenderer->createRenderbuffer(), renderbuffer);
         mRenderbufferMap[renderbuffer] = renderbufferObject;
         renderbufferObject->addRef();
     }
diff --git a/src/libGLESv2/libGLESv2.cpp b/src/libGLESv2/libGLESv2.cpp
index bc1b589..4a31f2c 100644
--- a/src/libGLESv2/libGLESv2.cpp
+++ b/src/libGLESv2/libGLESv2.cpp
@@ -3876,7 +3876,8 @@
             return;
         }
 
-        context->setRenderbufferStorage(width, height, internalformat, samples);
+        gl::Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer();
+        renderbuffer->setStorage(width, height, internalformat, samples);
     }
 }
 
@@ -5821,7 +5822,8 @@
             return;
         }
 
-        context->setRenderbufferStorage(width, height, internalformat, samples);
+        gl::Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer();
+        renderbuffer->setStorage(width, height, internalformat, samples);
     }
 }
 
diff --git a/src/libGLESv2/renderer/RenderbufferImpl.cpp b/src/libGLESv2/renderer/RenderbufferImpl.cpp
new file mode 100644
index 0000000..770ae8e
--- /dev/null
+++ b/src/libGLESv2/renderer/RenderbufferImpl.cpp
@@ -0,0 +1,21 @@
+//
+// 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.
+//
+
+// RenderbufferImpl.h: Implements the shared methods of the abstract class gl::RenderbufferImpl
+
+#include "libGLESv2/renderer/RenderbufferImpl.h"
+
+namespace rx
+{
+RenderbufferImpl::RenderbufferImpl()
+{
+}
+
+RenderbufferImpl::~RenderbufferImpl()
+{
+}
+
+}
diff --git a/src/libGLESv2/renderer/RenderbufferImpl.h b/src/libGLESv2/renderer/RenderbufferImpl.h
new file mode 100644
index 0000000..5f24e80
--- /dev/null
+++ b/src/libGLESv2/renderer/RenderbufferImpl.h
@@ -0,0 +1,39 @@
+//
+// 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.
+//
+
+// RenderbufferImpl.h: Defines the abstract class gl::RenderbufferImpl
+
+#ifndef LIBGLESV2_RENDERER_RENDERBUFFERIMPL_H_
+#define LIBGLESV2_RENDERER_RENDERBUFFERIMPL_H_
+
+#include "angle_gl.h"
+
+#include "common/angleutils.h"
+
+namespace rx
+{
+
+class RenderbufferImpl
+{
+  public:
+    RenderbufferImpl();
+    virtual ~RenderbufferImpl() = 0;
+
+    virtual void setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples) = 0;
+
+    virtual GLsizei getWidth() const = 0;
+    virtual GLsizei getHeight() const = 0;
+    virtual GLenum getInternalFormat() const = 0;
+    virtual GLenum getActualFormat() const = 0;
+    virtual GLsizei getSamples() const = 0;
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(RenderbufferImpl);
+};
+
+}
+
+#endif   // LIBGLESV2_RENDERER_RENDERBUFFERIMPL_H_
diff --git a/src/libGLESv2/renderer/Renderer.h b/src/libGLESv2/renderer/Renderer.h
index 6ef8d64..90251e2 100644
--- a/src/libGLESv2/renderer/Renderer.h
+++ b/src/libGLESv2/renderer/Renderer.h
@@ -66,6 +66,7 @@
 class UniformStorage;
 class TextureImpl;
 class TransformFeedbackImpl;
+class RenderbufferImpl;
 
 struct ConfigDesc
 {
@@ -218,6 +219,10 @@
     // Texture creation
     virtual TextureImpl *createTexture(GLenum target) = 0;
 
+    // Renderbuffer creation
+    virtual RenderbufferImpl *createRenderbuffer() = 0;
+    virtual RenderbufferImpl *createRenderbuffer(SwapChain *swapChain, bool depth) = 0;
+
     // Buffer creation
     virtual BufferImpl *createBuffer() = 0;
     virtual VertexBuffer *createVertexBuffer() = 0;
diff --git a/src/libGLESv2/renderer/d3d/RenderbufferD3D.cpp b/src/libGLESv2/renderer/d3d/RenderbufferD3D.cpp
new file mode 100644
index 0000000..897ceed
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/RenderbufferD3D.cpp
@@ -0,0 +1,101 @@
+//
+// 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.
+//
+
+// RenderbufferD3d.cpp: Implements the RenderbufferD3D class, a specialization of RenderbufferImpl
+
+
+#include "libGLESv2/renderer/d3d/RenderbufferD3D.h"
+
+#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/RenderTarget.h"
+
+namespace rx
+{
+unsigned int RenderbufferD3D::mCurrentSerial = 1;
+
+RenderbufferD3D::RenderbufferD3D(Renderer *renderer) : mSerial(issueSerials(1)), mRenderer(renderer)
+{
+    mRenderTarget = NULL;
+}
+
+RenderbufferD3D::~RenderbufferD3D()
+{
+    SafeDelete(mRenderTarget);
+}
+
+RenderbufferD3D *RenderbufferD3D::makeRenderbufferD3D(RenderbufferImpl *renderbuffer)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(RenderbufferD3D*, renderbuffer));
+    return static_cast<RenderbufferD3D*>(renderbuffer);
+}
+
+void RenderbufferD3D::setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples)
+{
+    // If the renderbuffer parameters are queried, the calling function
+    // will expect one of the valid renderbuffer formats for use in
+    // glRenderbufferStorage, but we should create depth and stencil buffers
+    // as DEPTH24_STENCIL8
+    GLenum creationFormat = internalformat;
+    if (internalformat == GL_DEPTH_COMPONENT16 || internalformat == GL_STENCIL_INDEX8)
+    {
+        creationFormat = GL_DEPTH24_STENCIL8_OES;
+    }
+
+    RenderTarget *newRT = mRenderer->createRenderTarget(width, height, creationFormat, samples);
+    SafeDelete(mRenderTarget);
+    mRenderTarget = newRT;
+}
+
+void RenderbufferD3D::setStorage(SwapChain *swapChain, bool depth)
+{
+    RenderTarget *newRT = mRenderer->createRenderTarget(swapChain, depth);
+    SafeDelete(mRenderTarget);
+    mRenderTarget = newRT;
+}
+
+GLsizei RenderbufferD3D::getWidth() const
+{
+    return (mRenderTarget ? mRenderTarget->getWidth() : 0);
+}
+
+GLsizei RenderbufferD3D::getHeight() const
+{
+    return (mRenderTarget ? mRenderTarget->getHeight() : 0);
+}
+
+GLenum RenderbufferD3D::getInternalFormat() const
+{
+    return (mRenderTarget ? mRenderTarget->getInternalFormat() : GL_RGBA4);
+}
+
+GLenum RenderbufferD3D::getActualFormat() const
+{
+    return (mRenderTarget ? mRenderTarget->getActualFormat() : GL_RGBA4);
+}
+
+GLsizei RenderbufferD3D::getSamples() const
+{
+    return (mRenderTarget ? mRenderTarget->getSamples() : 0);
+}
+
+RenderTarget *RenderbufferD3D::getRenderTarget()
+{
+    return mRenderTarget;
+}
+
+unsigned int RenderbufferD3D::getSerial() const
+{
+    return mSerial;
+}
+
+unsigned int RenderbufferD3D::issueSerials(unsigned int count)
+{
+    unsigned int firstSerial = mCurrentSerial;
+    mCurrentSerial += count;
+    return firstSerial;
+}
+
+}
diff --git a/src/libGLESv2/renderer/d3d/RenderbufferD3D.h b/src/libGLESv2/renderer/d3d/RenderbufferD3D.h
new file mode 100644
index 0000000..42dab4f
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/RenderbufferD3D.h
@@ -0,0 +1,55 @@
+//
+// 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.
+//
+
+// RenderbufferD3d.h: Defines the RenderbufferD3D class which implements RenderbufferImpl.
+
+#ifndef LIBGLESV2_RENDERER_RENDERBUFFERD3D_H_
+#define LIBGLESV2_RENDERER_RENDERBUFFERD3D_H_
+
+#include "angle_gl.h"
+
+#include "common/angleutils.h"
+#include "libGLESv2/renderer/RenderbufferImpl.h"
+
+namespace rx
+{
+class Renderer;
+class RenderTarget;
+class SwapChain;
+
+class RenderbufferD3D : public RenderbufferImpl
+{
+  public:
+    RenderbufferD3D(Renderer *renderer);
+    virtual ~RenderbufferD3D();
+
+    static RenderbufferD3D *makeRenderbufferD3D(RenderbufferImpl *texture);
+
+    virtual void setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples);
+    virtual void setStorage(SwapChain *swapChain, bool depth);
+
+    virtual GLsizei getWidth() const;
+    virtual GLsizei getHeight() const;
+    virtual GLenum getInternalFormat() const;
+    virtual GLenum getActualFormat() const;
+    virtual GLsizei getSamples() const;
+
+    virtual rx::RenderTarget *getRenderTarget();
+    virtual unsigned int getSerial() const;
+    static unsigned int issueSerials(unsigned int count);
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(RenderbufferD3D);
+
+    Renderer *mRenderer;
+    RenderTarget *mRenderTarget;
+    const unsigned int mSerial;
+
+    static unsigned int mCurrentSerial;
+};
+}
+
+#endif // LIBGLESV2_RENDERER_RENDERBUFFERD3D_H_
diff --git a/src/libGLESv2/renderer/d3d/TextureStorage.cpp b/src/libGLESv2/renderer/d3d/TextureStorage.cpp
index d2a6d24..09f5bd0 100644
--- a/src/libGLESv2/renderer/d3d/TextureStorage.cpp
+++ b/src/libGLESv2/renderer/d3d/TextureStorage.cpp
@@ -8,6 +8,7 @@
 
 #include "libGLESv2/renderer/d3d/TextureStorage.h"
 #include "libGLESv2/renderer/d3d/TextureD3D.h"
+#include "libGLESv2/renderer/d3d/RenderbufferD3D.h"
 #include "libGLESv2/renderer/Renderer.h"
 #include "libGLESv2/Renderbuffer.h"
 #include "libGLESv2/Texture.h"
@@ -25,7 +26,7 @@
 
 void TextureStorage::initializeSerials(unsigned int rtSerialsToReserve, unsigned int rtSerialsLayerStride)
 {
-    mFirstRenderTargetSerial = gl::RenderbufferStorage::issueSerials(rtSerialsToReserve);
+    mFirstRenderTargetSerial = RenderbufferD3D::issueSerials(rtSerialsToReserve);
     mRenderTargetSerialsLayerStride = rtSerialsLayerStride;
 }
 
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
index e5c4d12..3a15432 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
@@ -36,6 +36,7 @@
 #include "libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h"
 #include "libGLESv2/renderer/d3d/d3d11/VertexArray11.h"
 #include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
+#include "libGLESv2/renderer/d3d/RenderbufferD3D.h"
 
 #include "libEGL/Display.h"
 
@@ -2707,6 +2708,19 @@
     return NULL;
 }
 
+RenderbufferImpl *Renderer11::createRenderbuffer()
+{
+    RenderbufferD3D *renderbuffer = new RenderbufferD3D(this);
+    return renderbuffer;
+}
+
+RenderbufferImpl *Renderer11::createRenderbuffer(SwapChain *swapChain, bool depth)
+{
+    RenderbufferD3D *renderbuffer = new RenderbufferD3D(this);
+    renderbuffer->setStorage(swapChain, depth);
+    return renderbuffer;
+}
+
 gl::Error Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format,
                                       GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels)
 {
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
index 6087e8c..7b59d9c 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
+++ b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
@@ -162,6 +162,10 @@
     // Texture creation
     virtual TextureImpl *createTexture(GLenum target);
 
+    // Renderbuffer creation
+    virtual RenderbufferImpl *createRenderbuffer();
+    virtual RenderbufferImpl *createRenderbuffer(SwapChain *swapChain, bool depth);
+
     // Buffer creation
     virtual BufferImpl *createBuffer();
     virtual VertexBuffer *createVertexBuffer();
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
index 32d3400..4ce8b88 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
@@ -26,6 +26,7 @@
 #include "libGLESv2/renderer/d3d/ShaderD3D.h"
 #include "libGLESv2/renderer/d3d/TextureD3D.h"
 #include "libGLESv2/renderer/d3d/TransformFeedbackD3D.h"
+#include "libGLESv2/renderer/d3d/RenderbufferD3D.h"
 #include "libGLESv2/main.h"
 #include "libGLESv2/Buffer.h"
 #include "libGLESv2/Texture.h"
@@ -1172,7 +1173,7 @@
         }
     }
 
-    gl::Renderbuffer *nullRenderbuffer = new gl::Renderbuffer(0, new gl::Colorbuffer(this, width, height, GL_NONE, 0));
+    gl::Renderbuffer *nullRenderbuffer = new gl::Renderbuffer(createRenderbuffer(), 0);
     gl::RenderbufferAttachment *nullbuffer = new gl::RenderbufferAttachment(GL_NONE, nullRenderbuffer);
 
     // add nullbuffer to the cache
@@ -3088,6 +3089,19 @@
     return NULL;
 }
 
+RenderbufferImpl *Renderer9::createRenderbuffer()
+{
+    RenderbufferD3D *renderbuffer = new RenderbufferD3D(this);
+    return renderbuffer;
+}
+
+RenderbufferImpl *Renderer9::createRenderbuffer(SwapChain *swapChain, bool depth)
+{
+    RenderbufferD3D *renderbuffer = new RenderbufferD3D(this);
+    renderbuffer->setStorage(swapChain, depth);
+    return renderbuffer;
+}
+
 bool Renderer9::getLUID(LUID *adapterLuid) const
 {
     adapterLuid->HighPart = 0;
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h
index 7cf0b1e..2c4d469 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h
+++ b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h
@@ -164,6 +164,10 @@
     // Texture creation
     virtual TextureImpl *createTexture(GLenum target);
 
+    // Renderbuffer creation
+    virtual RenderbufferImpl *createRenderbuffer();
+    virtual RenderbufferImpl *createRenderbuffer(SwapChain *swapChain, bool depth);
+
     // Buffer creation
     virtual BufferImpl *createBuffer();
     virtual VertexBuffer *createVertexBuffer();