Remove obsolete Renderbuffer types.

RenderbufferProxySet and FramebufferTextureBindingPointer aren't
necessary any more with our refactored renderbuffer classes and
ownership of attachments by the Framebuffer.

We can also consolidate the FramebufferAttachment and implementation
to a single class, and no longer need to store ref counted objects
in the Framebuffer class directly.

BUG=angle:660

Change-Id: Idcc06dfb42b47242b33494e797a0ba06d6669511
Reviewed-on: https://chromium-review.googlesource.com/201838
Tested-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/common/RefCountObject.h b/src/common/RefCountObject.h
index 88b6393..4e475d8 100644
--- a/src/common/RefCountObject.h
+++ b/src/common/RefCountObject.h
@@ -63,33 +63,6 @@
 };
 
 template <class ObjectType>
-class FramebufferTextureBindingPointer : public RefCountObjectBindingPointer
-{
-public:
-    FramebufferTextureBindingPointer() : mType(GL_NONE), mMipLevel(0), mLayer(0) { }
-
-    void set(ObjectType *newObject, GLenum type, GLint mipLevel, GLint layer)
-    {
-        RefCountObjectBindingPointer::set(newObject);
-        mType = type;
-        mMipLevel = mipLevel;
-        mLayer = layer;
-    }
-
-    ObjectType *get() const { return static_cast<ObjectType*>(RefCountObjectBindingPointer::get()); }
-    ObjectType *operator->() const { return get(); }
-
-    GLenum type() const { return mType; }
-    GLint mipLevel() const { return mMipLevel; }
-    GLint layer() const { return mLayer; }
-
-private:
-    GLenum mType;
-    GLint mMipLevel;
-    GLint mLayer;
-};
-
-template <class ObjectType>
 class OffsetBindingPointer : public RefCountObjectBindingPointer
 {
   public:
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index 22fa252..5df651f 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -16,6 +16,7 @@
 #include "libGLESv2/Buffer.h"
 #include "libGLESv2/Fence.h"
 #include "libGLESv2/Framebuffer.h"
+#include "libGLESv2/FramebufferAttachment.h"
 #include "libGLESv2/Renderbuffer.h"
 #include "libGLESv2/Program.h"
 #include "libGLESv2/ProgramBinary.h"
diff --git a/src/libGLESv2/Framebuffer.cpp b/src/libGLESv2/Framebuffer.cpp
index 806c9a0..5fc8232 100644
--- a/src/libGLESv2/Framebuffer.cpp
+++ b/src/libGLESv2/Framebuffer.cpp
@@ -17,32 +17,36 @@
 #include "libGLESv2/Context.h"
 #include "libGLESv2/renderer/Renderer.h"
 #include "libGLESv2/Renderbuffer.h"
+#include "libGLESv2/FramebufferAttachment.h"
 
 namespace gl
 {
 
 Framebuffer::Framebuffer(rx::Renderer *renderer)
-    : mRenderer(renderer)
+    : mRenderer(renderer),
+      mReadBufferState(GL_COLOR_ATTACHMENT0_EXT),
+      mDepthbuffer(NULL),
+      mStencilbuffer(NULL)
 {
     for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
     {
+        mColorbuffers[colorAttachment] = NULL;
         mDrawBufferStates[colorAttachment] = GL_NONE;
     }
     mDrawBufferStates[0] = GL_COLOR_ATTACHMENT0_EXT;
-    mReadBufferState = GL_COLOR_ATTACHMENT0_EXT;
 }
 
 Framebuffer::~Framebuffer()
 {
     for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
     {
-        mColorbuffers[colorAttachment].set(NULL, GL_NONE, 0, 0);
+        SafeDelete(mColorbuffers[colorAttachment]);
     }
-    mDepthbuffer.set(NULL, GL_NONE, 0, 0);
-    mStencilbuffer.set(NULL, GL_NONE, 0, 0);
+    SafeDelete(mDepthbuffer);
+    SafeDelete(mStencilbuffer);
 }
 
-FramebufferAttachmentImpl *Framebuffer::createAttachmentImpl(GLenum type, GLuint handle, GLint level, GLint layer) const
+FramebufferAttachment *Framebuffer::createAttachment(GLenum type, GLuint handle, GLint level, GLint layer) const
 {
     if (handle == 0)
     {
@@ -129,173 +133,112 @@
 void Framebuffer::setColorbuffer(unsigned int colorAttachment, GLenum type, GLuint colorbuffer, GLint level, GLint layer)
 {
     ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
-    FramebufferAttachmentImpl *attachmentImpl = createAttachmentImpl(type, colorbuffer, level, layer);
-    if (attachmentImpl)
-    {
-        FramebufferAttachment *newAttachment = new FramebufferAttachment(colorbuffer, attachmentImpl);
-        mColorbuffers[colorAttachment].set(newAttachment, type, level, layer);
-    }
-    else
-    {
-        mColorbuffers[colorAttachment].set(NULL, GL_NONE, 0, 0);
-    }
+    SafeDelete(mColorbuffers[colorAttachment]);
+    mColorbuffers[colorAttachment] = createAttachment(type, colorbuffer, level, layer);
 }
 
 void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer)
 {
-    FramebufferAttachmentImpl *attachmentImpl = createAttachmentImpl(type, depthbuffer, level, layer);
-    if (attachmentImpl)
-    {
-        FramebufferAttachment *newAttachment = new FramebufferAttachment(depthbuffer, attachmentImpl);
-        mDepthbuffer.set(newAttachment, type, level, layer);
-    }
-    else
-    {
-        mDepthbuffer.set(NULL, GL_NONE, 0, 0);
-    }
+    SafeDelete(mDepthbuffer);
+    mDepthbuffer = createAttachment(type, depthbuffer, level, layer);
 }
 
 void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer)
 {
-    FramebufferAttachmentImpl *attachmentImpl = createAttachmentImpl(type, stencilbuffer, level, layer);
-    if (attachmentImpl)
-    {
-        FramebufferAttachment *newAttachment = new FramebufferAttachment(stencilbuffer, attachmentImpl);
-        mStencilbuffer.set(newAttachment, type, level, layer);
-    }
-    else
-    {
-        mStencilbuffer.set(NULL, GL_NONE, 0, 0);
-    }
+    SafeDelete(mStencilbuffer);
+    mStencilbuffer = createAttachment(type, stencilbuffer, level, layer);
 }
 
 void Framebuffer::setDepthStencilBuffer(GLenum type, GLuint depthStencilBuffer, GLint level, GLint layer)
 {
-    mDepthbuffer.set(NULL, GL_NONE, 0, 0);
-    mStencilbuffer.set(NULL, GL_NONE, 0, 0);
+    FramebufferAttachment *attachment = createAttachment(type, depthStencilBuffer, level, layer);
 
-    FramebufferAttachmentImpl *attachmentImpl = createAttachmentImpl(type, depthStencilBuffer, level, layer);
-    if (attachmentImpl)
+    SafeDelete(mDepthbuffer);
+    SafeDelete(mStencilbuffer);
+
+    // ensure this is a legitimate depth+stencil format
+    int clientVersion = mRenderer->getCurrentClientVersion();
+    if (attachment && attachment->getDepthSize(clientVersion) > 0 && attachment->getStencilSize(clientVersion) > 0)
     {
-        FramebufferAttachment *newAttachment = new FramebufferAttachment(depthStencilBuffer, attachmentImpl);
-        int clientVersion = mRenderer->getCurrentClientVersion();
-        if (newAttachment->getDepthSize(clientVersion) > 0 && newAttachment->getStencilSize(clientVersion) > 0)
-        {
-            mDepthbuffer.set(newAttachment, type, level, layer);
-            mStencilbuffer.set(newAttachment, type, level, layer);
-        }
+        mDepthbuffer = attachment;
+        mStencilbuffer = attachment;
     }
 }
 
-void Framebuffer::detachTexture(GLuint texture)
+void Framebuffer::detachTexture(GLuint textureId)
 {
     for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
     {
-        if (mColorbuffers[colorAttachment].id() == texture &&
-            IsInternalTextureTarget(mColorbuffers[colorAttachment].type(), mRenderer->getCurrentClientVersion()))
+        FramebufferAttachment *attachment = mColorbuffers[colorAttachment];
+
+        if (attachment && attachment->isTextureWithId(textureId))
         {
-            mColorbuffers[colorAttachment].set(NULL, GL_NONE, 0, 0);
+            SafeDelete(mColorbuffers[colorAttachment]);
         }
     }
 
-    if (mDepthbuffer.id() == texture && IsInternalTextureTarget(mDepthbuffer.type(), mRenderer->getCurrentClientVersion()))
+    if (mDepthbuffer && mDepthbuffer->isTextureWithId(textureId))
     {
-        mDepthbuffer.set(NULL, GL_NONE, 0, 0);
+        SafeDelete(mDepthbuffer);
     }
 
-    if (mStencilbuffer.id() == texture && IsInternalTextureTarget(mStencilbuffer.type(), mRenderer->getCurrentClientVersion()))
+    if (mStencilbuffer && mStencilbuffer->isTextureWithId(textureId))
     {
-        mStencilbuffer.set(NULL, GL_NONE, 0, 0);
+        SafeDelete(mStencilbuffer);
     }
 }
 
-void Framebuffer::detachRenderbuffer(GLuint renderbuffer)
+void Framebuffer::detachRenderbuffer(GLuint renderbufferId)
 {
     for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
     {
-        if (mColorbuffers[colorAttachment].id() == renderbuffer && mColorbuffers[colorAttachment].type() == GL_RENDERBUFFER)
+        FramebufferAttachment *attachment = mColorbuffers[colorAttachment];
+
+        if (attachment && attachment->isRenderbufferWithId(renderbufferId))
         {
-            mColorbuffers[colorAttachment].set(NULL, GL_NONE, 0, 0);
+            SafeDelete(mColorbuffers[colorAttachment]);
         }
     }
 
-    if (mDepthbuffer.id() == renderbuffer && mDepthbuffer.type() == GL_RENDERBUFFER)
+    if (mDepthbuffer && mDepthbuffer->isRenderbufferWithId(renderbufferId))
     {
-        mDepthbuffer.set(NULL, GL_NONE, 0, 0);
+        SafeDelete(mDepthbuffer);
     }
 
-    if (mStencilbuffer.id() == renderbuffer && mStencilbuffer.type() == GL_RENDERBUFFER)
+    if (mStencilbuffer && mStencilbuffer->isRenderbufferWithId(renderbufferId))
     {
-        mStencilbuffer.set(NULL, GL_NONE, 0, 0);
+        SafeDelete(mStencilbuffer);
     }
 }
 
-unsigned int Framebuffer::getRenderTargetSerial(unsigned int colorAttachment) const
-{
-    ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
-
-    FramebufferAttachment *colorbuffer = mColorbuffers[colorAttachment].get();
-
-    if (colorbuffer)
-    {
-        return colorbuffer->getSerial();
-    }
-
-    return 0;
-}
-
-unsigned int Framebuffer::getDepthbufferSerial() const
-{
-    FramebufferAttachment *depthbuffer = mDepthbuffer.get();
-
-    if (depthbuffer)
-    {
-        return depthbuffer->getSerial();
-    }
-
-    return 0;
-}
-
-unsigned int Framebuffer::getStencilbufferSerial() const
-{
-    FramebufferAttachment *stencilbuffer = mStencilbuffer.get();
-
-    if (stencilbuffer)
-    {
-        return stencilbuffer->getSerial();
-    }
-
-    return 0;
-}
-
 FramebufferAttachment *Framebuffer::getColorbuffer(unsigned int colorAttachment) const
 {
     ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
-    return mColorbuffers[colorAttachment].get();
+    return mColorbuffers[colorAttachment];
 }
 
 FramebufferAttachment *Framebuffer::getDepthbuffer() const
 {
-    return mDepthbuffer.get();
+    return mDepthbuffer;
 }
 
 FramebufferAttachment *Framebuffer::getStencilbuffer() const
 {
-    return mStencilbuffer.get();
+    return mStencilbuffer;
 }
 
 FramebufferAttachment *Framebuffer::getDepthStencilBuffer() const
 {
-    return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.get() : NULL;
+    return (hasValidDepthStencil() ? mDepthbuffer : NULL);
 }
 
 FramebufferAttachment *Framebuffer::getDepthOrStencilbuffer() const
 {
-    FramebufferAttachment *depthstencilbuffer = mDepthbuffer.get();
+    FramebufferAttachment *depthstencilbuffer = mDepthbuffer;
     
     if (!depthstencilbuffer)
     {
-        depthstencilbuffer = mStencilbuffer.get();
+        depthstencilbuffer = mStencilbuffer;
     }
 
     return depthstencilbuffer;
@@ -304,22 +247,22 @@
 FramebufferAttachment *Framebuffer::getReadColorbuffer() const
 {
     // Will require more logic if glReadBuffers is supported
-    return mColorbuffers[0].get();
+    return mColorbuffers[0];
 }
 
 GLenum Framebuffer::getReadColorbufferType() const
 {
     // Will require more logic if glReadBuffers is supported
-    return mColorbuffers[0].type();
+    return (mColorbuffers[0] ? mColorbuffers[0]->type() : GL_NONE);
 }
 
 FramebufferAttachment *Framebuffer::getFirstColorbuffer() const
 {
     for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
     {
-        if (mColorbuffers[colorAttachment].type() != GL_NONE)
+        if (mColorbuffers[colorAttachment])
         {
-            return mColorbuffers[colorAttachment].get();
+            return mColorbuffers[colorAttachment];
         }
     }
 
@@ -329,85 +272,85 @@
 GLenum Framebuffer::getColorbufferType(unsigned int colorAttachment) const
 {
     ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
-    return mColorbuffers[colorAttachment].type();
+    return (mColorbuffers[colorAttachment] ? mColorbuffers[colorAttachment]->type() : GL_NONE);
 }
 
 GLenum Framebuffer::getDepthbufferType() const
 {
-    return mDepthbuffer.type();
+    return (mDepthbuffer ? mDepthbuffer->type() : GL_NONE);
 }
 
 GLenum Framebuffer::getStencilbufferType() const
 {
-    return mStencilbuffer.type();
+    return (mStencilbuffer ? mStencilbuffer->type() : GL_NONE);
 }
 
 GLenum Framebuffer::getDepthStencilbufferType() const
 {
-    return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.type() : GL_NONE;
+    return (hasValidDepthStencil() ? mDepthbuffer->type() : GL_NONE);
 }
 
 GLuint Framebuffer::getColorbufferHandle(unsigned int colorAttachment) const
 {
     ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
-    return mColorbuffers[colorAttachment].id();
+    return (mColorbuffers[colorAttachment] ? mColorbuffers[colorAttachment]->id() : 0);
 }
 
 GLuint Framebuffer::getDepthbufferHandle() const
 {
-    return mDepthbuffer.id();
+    return (mDepthbuffer ? mDepthbuffer->id() : 0);
 }
 
 GLuint Framebuffer::getStencilbufferHandle() const
 {
-    return mStencilbuffer.id();
+    return (mStencilbuffer ? mStencilbuffer->id() : 0);
 }
 
-GLenum Framebuffer::getDepthStencilbufferHandle() const
+GLuint Framebuffer::getDepthStencilbufferHandle() const
 {
-    return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.id() : 0;
+    return (hasValidDepthStencil() ? mDepthbuffer->id() : 0);
 }
 
-GLenum Framebuffer::getColorbufferMipLevel(unsigned int colorAttachment) const
+GLint Framebuffer::getColorbufferMipLevel(unsigned int colorAttachment) const
 {
     ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
-    return mColorbuffers[colorAttachment].mipLevel();
+    return (mColorbuffers[colorAttachment] ? mColorbuffers[colorAttachment]->mipLevel() : 0);
 }
 
-GLenum Framebuffer::getDepthbufferMipLevel() const
+GLint Framebuffer::getDepthbufferMipLevel() const
 {
-    return mDepthbuffer.mipLevel();
+    return (mDepthbuffer ? mDepthbuffer->mipLevel() : 0);
 }
 
-GLenum Framebuffer::getStencilbufferMipLevel() const
+GLint Framebuffer::getStencilbufferMipLevel() const
 {
-    return mStencilbuffer.mipLevel();
+    return (mStencilbuffer ? mStencilbuffer->mipLevel() : 0);
 }
 
-GLenum Framebuffer::getDepthStencilbufferMipLevel() const
+GLint Framebuffer::getDepthStencilbufferMipLevel() const
 {
-    return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.mipLevel() : 0;
+    return (hasValidDepthStencil() ? mDepthbuffer->mipLevel() : 0);
 }
 
-GLenum Framebuffer::getColorbufferLayer(unsigned int colorAttachment) const
+GLint Framebuffer::getColorbufferLayer(unsigned int colorAttachment) const
 {
     ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
-    return mColorbuffers[colorAttachment].layer();
+    return (mColorbuffers[colorAttachment] ? mColorbuffers[colorAttachment]->layer() : 0);
 }
 
-GLenum Framebuffer::getDepthbufferLayer() const
+GLint Framebuffer::getDepthbufferLayer() const
 {
-    return mDepthbuffer.layer();
+    return (mDepthbuffer ? mDepthbuffer->layer() : 0);
 }
 
-GLenum Framebuffer::getStencilbufferLayer() const
+GLint Framebuffer::getStencilbufferLayer() const
 {
-    return mStencilbuffer.layer();
+    return (mStencilbuffer ? mStencilbuffer->layer() : 0);
 }
 
-GLenum Framebuffer::getDepthStencilbufferLayer() const
+GLint Framebuffer::getDepthStencilbufferLayer() const
 {
-    return (mDepthbuffer.id() == mStencilbuffer.id()) ? mDepthbuffer.layer() : 0;
+    return (hasValidDepthStencil() ? mDepthbuffer->layer() : 0);
 }
 
 GLenum Framebuffer::getDrawBufferState(unsigned int colorAttachment) const
@@ -422,7 +365,7 @@
 
 bool Framebuffer::isEnabledColorAttachment(unsigned int colorAttachment) const
 {
-    return (mColorbuffers[colorAttachment].type() != GL_NONE && mDrawBufferStates[colorAttachment] != GL_NONE);
+    return (mColorbuffers[colorAttachment] && mDrawBufferStates[colorAttachment] != GL_NONE);
 }
 
 bool Framebuffer::hasEnabledColorAttachment() const
@@ -440,15 +383,10 @@
 
 bool Framebuffer::hasStencil() const
 {
-    if (mStencilbuffer.type() != GL_NONE)
+    if (mStencilbuffer)
     {
-        const FramebufferAttachment *stencilbufferObject = getStencilbuffer();
-
-        if (stencilbufferObject)
-        {
-            int clientVersion = mRenderer->getCurrentClientVersion();
-            return stencilbufferObject->getStencilSize(clientVersion) > 0;
-        }
+        int clientVersion = mRenderer->getCurrentClientVersion();
+        return (mStencilbuffer->getStencilSize(clientVersion) > 0);
     }
 
     return false;
@@ -478,11 +416,11 @@
 
     for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
     {
-        if (mColorbuffers[colorAttachment].type() != GL_NONE)
+        if (mColorbuffers[colorAttachment])
         {
-            const FramebufferAttachment *colorbuffer = getColorbuffer(colorAttachment);
+            const FramebufferAttachment *colorbuffer = mColorbuffers[colorAttachment];
 
-            if (!colorbuffer)
+            if (colorbuffer->type() == GL_NONE)
             {
                 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
             }
@@ -494,14 +432,14 @@
 
             GLenum internalformat = colorbuffer->getInternalFormat();
             const TextureCaps &formatCaps = mRenderer->getCaps().textureCaps.get(internalformat);
-            if (mColorbuffers[colorAttachment].type() == GL_RENDERBUFFER)
+            if (colorbuffer->type() == GL_RENDERBUFFER)
             {
                 if (!formatCaps.colorRendering)
                 {
                     return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
                 }
             }
-            else if (IsInternalTextureTarget(mColorbuffers[colorAttachment].type(), mRenderer->getCurrentClientVersion()))
+            else if (IsInternalTextureTarget(colorbuffer->type(), mRenderer->getCurrentClientVersion()))
             {
                 if (!formatCaps.colorRendering)
                 {
@@ -548,7 +486,8 @@
                 // D3D11 does not allow for overlapping RenderTargetViews, so ensure uniqueness
                 for (unsigned int previousColorAttachment = 0; previousColorAttachment < colorAttachment; previousColorAttachment++)
                 {
-                    if (mColorbuffers[colorAttachment].get() == mColorbuffers[previousColorAttachment].get())
+                    if (colorbuffer->id() == getColorbufferHandle(previousColorAttachment) &&
+                        colorbuffer->type() == getColorbufferType(previousColorAttachment))
                     {
                         return GL_FRAMEBUFFER_UNSUPPORTED;
                     }
@@ -565,34 +504,26 @@
         }
     }
 
-    const FramebufferAttachment *depthbuffer = NULL;
-    const FramebufferAttachment *stencilbuffer = NULL;
-
-    if (mDepthbuffer.type() != GL_NONE)
+    if (mDepthbuffer)
     {
-        depthbuffer = getDepthbuffer();
-
-        if (!depthbuffer)
+        if (mDepthbuffer->getWidth() == 0 || mDepthbuffer->getHeight() == 0)
         {
             return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
         }
 
-        if (depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0)
-        {
-            return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
-        }
-
-        GLenum internalformat = depthbuffer->getInternalFormat();
+        GLenum internalformat = mDepthbuffer->getInternalFormat();
         const TextureCaps &formatCaps = mRenderer->getCaps().textureCaps.get(internalformat);
-        if (mDepthbuffer.type() == GL_RENDERBUFFER)
+        if (mDepthbuffer->type() == GL_RENDERBUFFER)
         {
             if (!formatCaps.depthRendering)
             {
                 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
             }
         }
-        else if (IsInternalTextureTarget(mDepthbuffer.type(), mRenderer->getCurrentClientVersion()))
+        else if (IsInternalTextureTarget(mDepthbuffer->type(), mRenderer->getCurrentClientVersion()))
         {
+            GLenum internalformat = mDepthbuffer->getInternalFormat();
+
             // depth texture attachments require OES/ANGLE_depth_texture
             if (!mRenderer->getCaps().extensions.depthTextures)
             {
@@ -617,46 +548,41 @@
 
         if (missingAttachment)
         {
-            width = depthbuffer->getWidth();
-            height = depthbuffer->getHeight();
-            samples = depthbuffer->getSamples();
+            width = mDepthbuffer->getWidth();
+            height = mDepthbuffer->getHeight();
+            samples = mDepthbuffer->getSamples();
             missingAttachment = false;
         }
-        else if (width != depthbuffer->getWidth() || height != depthbuffer->getHeight())
+        else if (width != mDepthbuffer->getWidth() || height != mDepthbuffer->getHeight())
         {
             return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
         }
-        else if (samples != depthbuffer->getSamples())
+        else if (samples != mDepthbuffer->getSamples())
         {
             return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
         }
     }
 
-    if (mStencilbuffer.type() != GL_NONE)
+    if (mStencilbuffer)
     {
-        stencilbuffer = getStencilbuffer();
-
-        if (!stencilbuffer)
+        if (mStencilbuffer->getWidth() == 0 || mStencilbuffer->getHeight() == 0)
         {
             return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
         }
 
-        if (stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0)
-        {
-            return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
-        }
-
-        GLenum internalformat = stencilbuffer->getInternalFormat();
+        GLenum internalformat = mStencilbuffer->getInternalFormat();
         const TextureCaps &formatCaps = mRenderer->getCaps().textureCaps.get(internalformat);
-        if (mStencilbuffer.type() == GL_RENDERBUFFER)
+        if (mStencilbuffer->type() == GL_RENDERBUFFER)
         {
             if (!formatCaps.stencilRendering)
             {
                 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
             }
         }
-        else if (IsInternalTextureTarget(mStencilbuffer.type(), mRenderer->getCurrentClientVersion()))
+        else if (IsInternalTextureTarget(mStencilbuffer->type(), mRenderer->getCurrentClientVersion()))
         {
+            GLenum internalformat = mStencilbuffer->getInternalFormat();
+
             // texture stencil attachments come along as part
             // of OES_packed_depth_stencil + OES/ANGLE_depth_texture
             if (!mRenderer->getCaps().extensions.depthTextures)
@@ -682,16 +608,16 @@
 
         if (missingAttachment)
         {
-            width = stencilbuffer->getWidth();
-            height = stencilbuffer->getHeight();
-            samples = stencilbuffer->getSamples();
+            width = mStencilbuffer->getWidth();
+            height = mStencilbuffer->getHeight();
+            samples = mStencilbuffer->getSamples();
             missingAttachment = false;
         }
-        else if (width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight())
+        else if (width != mStencilbuffer->getWidth() || height != mStencilbuffer->getHeight())
         {
             return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
         }
-        else if (samples != stencilbuffer->getSamples())
+        else if (samples != mStencilbuffer->getSamples())
         {
             return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
         }
@@ -699,9 +625,7 @@
 
     // if we have both a depth and stencil buffer, they must refer to the same object
     // since we only support packed_depth_stencil and not separate depth and stencil
-    if (depthbuffer && stencilbuffer &&
-        !(depthbuffer->id() == stencilbuffer->id() &&
-          depthbuffer->isTexture() == stencilbuffer->isTexture()))
+    if (mDepthbuffer && mStencilbuffer && !hasValidDepthStencil())
     {
         return GL_FRAMEBUFFER_UNSUPPORTED;
     }
@@ -719,13 +643,12 @@
     : Framebuffer(renderer)
 {
     Renderbuffer *colorRenderbuffer = new Renderbuffer(mRenderer, 0, colorbuffer);
-    FramebufferAttachment *colorAttachment = new FramebufferAttachment(0, new RenderbufferAttachment(colorRenderbuffer));
-    mColorbuffers[0].set(colorAttachment, GL_RENDERBUFFER, 0, 0);
+    mColorbuffers[0] = new RenderbufferAttachment(colorRenderbuffer);
 
     Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(mRenderer, 0, depthStencil);
-    FramebufferAttachment *depthStencilAttachment = new FramebufferAttachment(0, new RenderbufferAttachment(depthStencilRenderbuffer));
-    mDepthbuffer.set(depthStencilAttachment, (depthStencilRenderbuffer->getDepthSize() != 0) ? GL_RENDERBUFFER : GL_NONE, 0, 0);
-    mStencilbuffer.set(depthStencilAttachment, (depthStencilRenderbuffer->getStencilSize() != 0) ? GL_RENDERBUFFER : GL_NONE, 0, 0);
+    FramebufferAttachment *depthStencilAttachment = new RenderbufferAttachment(depthStencilRenderbuffer);
+    mDepthbuffer = (depthStencilRenderbuffer->getDepthSize() != 0 ? depthStencilAttachment : NULL);
+    mStencilbuffer = (depthStencilRenderbuffer->getStencilSize() != 0 ? depthStencilAttachment : NULL);
 
     mDrawBufferStates[0] = GL_BACK;
     mReadBufferState = GL_BACK;
@@ -739,9 +662,9 @@
         // in this case return the first nonzero sample size
         for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
         {
-            if (mColorbuffers[colorAttachment].type() != GL_NONE)
+            if (mColorbuffers[colorAttachment])
             {
-                return getColorbuffer(colorAttachment)->getSamples();
+                return mColorbuffers[colorAttachment]->getSamples();
             }
         }
     }
@@ -749,6 +672,15 @@
     return 0;
 }
 
+bool Framebuffer::hasValidDepthStencil() const
+{
+    // A valid depth-stencil attachment has the same resource bound to both the
+    // depth and stencil attachment points.
+    return (mDepthbuffer && mStencilbuffer &&
+            mDepthbuffer->type() == mStencilbuffer->type() &&
+            mDepthbuffer->id() == mStencilbuffer->id());
+}
+
 GLenum DefaultFramebuffer::completeness() const
 {
     // The default framebuffer *must* always be complete, though it may not be
diff --git a/src/libGLESv2/Framebuffer.h b/src/libGLESv2/Framebuffer.h
index 0c5a8d7..56eb6d9 100644
--- a/src/libGLESv2/Framebuffer.h
+++ b/src/libGLESv2/Framebuffer.h
@@ -22,7 +22,6 @@
 namespace gl
 {
 class FramebufferAttachment;
-class FramebufferAttachmentImpl;
 class Colorbuffer;
 class Depthbuffer;
 class Stencilbuffer;
@@ -43,10 +42,6 @@
     void detachTexture(GLuint texture);
     void detachRenderbuffer(GLuint renderbuffer);
 
-    unsigned int getRenderTargetSerial(unsigned int colorAttachment) const;
-    unsigned int getDepthbufferSerial() const;
-    unsigned int getStencilbufferSerial() const;
-
     FramebufferAttachment *getColorbuffer(unsigned int colorAttachment) const;
     FramebufferAttachment *getDepthbuffer() const;
     FramebufferAttachment *getStencilbuffer() const;
@@ -64,17 +59,17 @@
     GLuint getColorbufferHandle(unsigned int colorAttachment) const;
     GLuint getDepthbufferHandle() const;
     GLuint getStencilbufferHandle() const;
-    GLenum getDepthStencilbufferHandle() const;
+    GLuint getDepthStencilbufferHandle() const;
 
-    GLenum getColorbufferMipLevel(unsigned int colorAttachment) const;
-    GLenum getDepthbufferMipLevel() const;
-    GLenum getStencilbufferMipLevel() const;
-    GLenum getDepthStencilbufferMipLevel() const;
+    GLint getColorbufferMipLevel(unsigned int colorAttachment) const;
+    GLint getDepthbufferMipLevel() const;
+    GLint getStencilbufferMipLevel() const;
+    GLint getDepthStencilbufferMipLevel() const;
 
-    GLenum getColorbufferLayer(unsigned int colorAttachment) const;
-    GLenum getDepthbufferLayer() const;
-    GLenum getStencilbufferLayer() const;
-    GLenum getDepthStencilbufferLayer() const;
+    GLint getColorbufferLayer(unsigned int colorAttachment) const;
+    GLint getDepthbufferLayer() const;
+    GLint getStencilbufferLayer() const;
+    GLint getDepthStencilbufferLayer() const;
 
     GLenum getDrawBufferState(unsigned int colorAttachment) const;
     void setDrawBufferState(unsigned int colorAttachment, GLenum drawBuffer);
@@ -88,19 +83,21 @@
     virtual GLenum completeness() const;
 
   protected:
-    FramebufferTextureBindingPointer<FramebufferAttachment> mColorbuffers[IMPLEMENTATION_MAX_DRAW_BUFFERS];
+    rx::Renderer *mRenderer;
+
+    FramebufferAttachment *mColorbuffers[IMPLEMENTATION_MAX_DRAW_BUFFERS];
     GLenum mDrawBufferStates[IMPLEMENTATION_MAX_DRAW_BUFFERS];
     GLenum mReadBufferState;
 
-    FramebufferTextureBindingPointer<FramebufferAttachment> mDepthbuffer;
-    FramebufferTextureBindingPointer<FramebufferAttachment> mStencilbuffer;
+    FramebufferAttachment *mDepthbuffer;
+    FramebufferAttachment *mStencilbuffer;
 
-    rx::Renderer *mRenderer;
+    bool hasValidDepthStencil() const;
 
-  private:
+private:
     DISALLOW_COPY_AND_ASSIGN(Framebuffer);
 
-    FramebufferAttachmentImpl *createAttachmentImpl(GLenum type, GLuint handle, GLint level, GLint layer) const;
+    FramebufferAttachment *createAttachment(GLenum type, GLuint handle, GLint level, GLint layer) const;
 };
 
 class DefaultFramebuffer : public Framebuffer
diff --git a/src/libGLESv2/FramebufferAttachment.cpp b/src/libGLESv2/FramebufferAttachment.cpp
index ee26f19..c26f07d 100644
--- a/src/libGLESv2/FramebufferAttachment.cpp
+++ b/src/libGLESv2/FramebufferAttachment.cpp
@@ -21,461 +21,14 @@
 namespace gl
 {
 
-FramebufferAttachmentImpl::FramebufferAttachmentImpl()
-{
-}
-
-// The default case for classes inherited from FramebufferAttachmentImpl is not to
-// need to do anything upon the reference count to the parent FramebufferAttachment incrementing
-// or decrementing.
-void FramebufferAttachmentImpl::addProxyRef(const FramebufferAttachment *proxy)
-{
-}
-
-void FramebufferAttachmentImpl::releaseProxy(const FramebufferAttachment *proxy)
-{
-}
-
-///// Texture2DAttachment Implementation ////////
-
-Texture2DAttachment::Texture2DAttachment(Texture2D *texture, GLint level) : mLevel(level)
-{
-    mTexture2D.set(texture);
-}
-
-Texture2DAttachment::~Texture2DAttachment()
-{
-    mTexture2D.set(NULL);
-}
-
-// Textures need to maintain their own reference count for references via
-// Renderbuffers acting as proxies. Here, we notify the texture of a reference.
-void Texture2DAttachment::addProxyRef(const FramebufferAttachment *proxy)
-{
-    mTexture2D->addProxyRef(proxy);
-}
-
-void Texture2DAttachment::releaseProxy(const FramebufferAttachment *proxy)
-{
-    mTexture2D->releaseProxy(proxy);
-}
-
-rx::RenderTarget *Texture2DAttachment::getRenderTarget()
-{
-    return mTexture2D->getRenderTarget(mLevel);
-}
-
-rx::RenderTarget *Texture2DAttachment::getDepthStencil()
-{
-    return mTexture2D->getDepthSencil(mLevel);
-}
-
-rx::TextureStorage *Texture2DAttachment::getTextureStorage()
-{
-    return mTexture2D->getNativeTexture()->getStorageInstance();
-}
-
-GLsizei Texture2DAttachment::getWidth() const
-{
-    return mTexture2D->getWidth(mLevel);
-}
-
-GLsizei Texture2DAttachment::getHeight() const
-{
-    return mTexture2D->getHeight(mLevel);
-}
-
-GLenum Texture2DAttachment::getInternalFormat() const
-{
-    return mTexture2D->getInternalFormat(mLevel);
-}
-
-GLenum Texture2DAttachment::getActualFormat() const
-{
-    return mTexture2D->getActualFormat(mLevel);
-}
-
-GLsizei Texture2DAttachment::getSamples() const
-{
-    return 0;
-}
-
-unsigned int Texture2DAttachment::getSerial() const
-{
-    return mTexture2D->getRenderTargetSerial(mLevel);
-}
-
-GLuint Texture2DAttachment::id() const
-{
-    return mTexture2D->id();
-}
-
-GLenum Texture2DAttachment::type() const
-{
-    return GL_TEXTURE_2D;
-}
-
-GLint Texture2DAttachment::mipLevel() const
-{
-    return mLevel;
-}
-
-GLint Texture2DAttachment::layer() const
-{
-    return 0;
-}
-
-unsigned int Texture2DAttachment::getTextureSerial() const
-{
-    return mTexture2D->getTextureSerial();
-}
-
-///// TextureCubeMapAttachment Implementation ////////
-
-TextureCubeMapAttachment::TextureCubeMapAttachment(TextureCubeMap *texture, GLenum faceTarget, GLint level)
-    : mFaceTarget(faceTarget), mLevel(level)
-{
-    mTextureCubeMap.set(texture);
-}
-
-TextureCubeMapAttachment::~TextureCubeMapAttachment()
-{
-    mTextureCubeMap.set(NULL);
-}
-
-// Textures need to maintain their own reference count for references via
-// Renderbuffers acting as proxies. Here, we notify the texture of a reference.
-void TextureCubeMapAttachment::addProxyRef(const FramebufferAttachment *proxy)
-{
-    mTextureCubeMap->addProxyRef(proxy);
-}
-
-void TextureCubeMapAttachment::releaseProxy(const FramebufferAttachment *proxy)
-{
-    mTextureCubeMap->releaseProxy(proxy);
-}
-
-rx::RenderTarget *TextureCubeMapAttachment::getRenderTarget()
-{
-    return mTextureCubeMap->getRenderTarget(mFaceTarget, mLevel);
-}
-
-rx::RenderTarget *TextureCubeMapAttachment::getDepthStencil()
-{
-    return mTextureCubeMap->getDepthStencil(mFaceTarget, mLevel);
-}
-
-rx::TextureStorage *TextureCubeMapAttachment::getTextureStorage()
-{
-    return mTextureCubeMap->getNativeTexture()->getStorageInstance();
-}
-
-GLsizei TextureCubeMapAttachment::getWidth() const
-{
-    return mTextureCubeMap->getWidth(mFaceTarget, mLevel);
-}
-
-GLsizei TextureCubeMapAttachment::getHeight() const
-{
-    return mTextureCubeMap->getHeight(mFaceTarget, mLevel);
-}
-
-GLenum TextureCubeMapAttachment::getInternalFormat() const
-{
-    return mTextureCubeMap->getInternalFormat(mFaceTarget, mLevel);
-}
-
-GLenum TextureCubeMapAttachment::getActualFormat() const
-{
-    return mTextureCubeMap->getActualFormat(mFaceTarget, mLevel);
-}
-
-GLsizei TextureCubeMapAttachment::getSamples() const
-{
-    return 0;
-}
-
-unsigned int TextureCubeMapAttachment::getSerial() const
-{
-    return mTextureCubeMap->getRenderTargetSerial(mFaceTarget, mLevel);
-}
-
-GLuint TextureCubeMapAttachment::id() const
-{
-    return mTextureCubeMap->id();
-}
-
-GLenum TextureCubeMapAttachment::type() const
-{
-    return mFaceTarget;
-}
-
-GLint TextureCubeMapAttachment::mipLevel() const
-{
-    return mLevel;
-}
-
-GLint TextureCubeMapAttachment::layer() const
-{
-    return 0;
-}
-
-unsigned int TextureCubeMapAttachment::getTextureSerial() const
-{
-    return mTextureCubeMap->getTextureSerial();
-}
-
-///// Texture3DAttachment Implementation ////////
-
-Texture3DAttachment::Texture3DAttachment(Texture3D *texture, GLint level, GLint layer)
-    : mLevel(level), mLayer(layer)
-{
-    mTexture3D.set(texture);
-}
-
-Texture3DAttachment::~Texture3DAttachment()
-{
-    mTexture3D.set(NULL);
-}
-
-// Textures need to maintain their own reference count for references via
-// Renderbuffers acting as proxies. Here, we notify the texture of a reference.
-void Texture3DAttachment::addProxyRef(const FramebufferAttachment *proxy)
-{
-    mTexture3D->addProxyRef(proxy);
-}
-
-void Texture3DAttachment::releaseProxy(const FramebufferAttachment *proxy)
-{
-    mTexture3D->releaseProxy(proxy);
-}
-
-rx::RenderTarget *Texture3DAttachment::getRenderTarget()
-{
-    return mTexture3D->getRenderTarget(mLevel, mLayer);
-}
-
-rx::RenderTarget *Texture3DAttachment::getDepthStencil()
-{
-    return mTexture3D->getDepthStencil(mLevel, mLayer);
-}
-
-rx::TextureStorage *Texture3DAttachment::getTextureStorage()
-{
-    return mTexture3D->getNativeTexture()->getStorageInstance();
-}
-
-GLsizei Texture3DAttachment::getWidth() const
-{
-    return mTexture3D->getWidth(mLevel);
-}
-
-GLsizei Texture3DAttachment::getHeight() const
-{
-    return mTexture3D->getHeight(mLevel);
-}
-
-GLenum Texture3DAttachment::getInternalFormat() const
-{
-    return mTexture3D->getInternalFormat(mLevel);
-}
-
-GLenum Texture3DAttachment::getActualFormat() const
-{
-    return mTexture3D->getActualFormat(mLevel);
-}
-
-GLsizei Texture3DAttachment::getSamples() const
-{
-    return 0;
-}
-
-unsigned int Texture3DAttachment::getSerial() const
-{
-    return mTexture3D->getRenderTargetSerial(mLevel, mLayer);
-}
-
-GLuint Texture3DAttachment::id() const
-{
-    return mTexture3D->id();
-}
-
-GLenum Texture3DAttachment::type() const
-{
-    return GL_TEXTURE_3D;
-}
-
-GLint Texture3DAttachment::mipLevel() const
-{
-    return mLevel;
-}
-
-GLint Texture3DAttachment::layer() const
-{
-    return mLayer;
-}
-
-unsigned int Texture3DAttachment::getTextureSerial() const
-{
-    return mTexture3D->getTextureSerial();
-}
-
-////// Texture2DArrayAttachment Implementation //////
-
-Texture2DArrayAttachment::Texture2DArrayAttachment(Texture2DArray *texture, GLint level, GLint layer)
-    : mLevel(level), mLayer(layer)
-{
-    mTexture2DArray.set(texture);
-}
-
-Texture2DArrayAttachment::~Texture2DArrayAttachment()
-{
-    mTexture2DArray.set(NULL);
-}
-
-void Texture2DArrayAttachment::addProxyRef(const FramebufferAttachment *proxy)
-{
-    mTexture2DArray->addProxyRef(proxy);
-}
-
-void Texture2DArrayAttachment::releaseProxy(const FramebufferAttachment *proxy)
-{
-    mTexture2DArray->releaseProxy(proxy);
-}
-
-rx::RenderTarget *Texture2DArrayAttachment::getRenderTarget()
-{
-    return mTexture2DArray->getRenderTarget(mLevel, mLayer);
-}
-
-rx::RenderTarget *Texture2DArrayAttachment::getDepthStencil()
-{
-    return mTexture2DArray->getDepthStencil(mLevel, mLayer);
-}
-
-rx::TextureStorage *Texture2DArrayAttachment::getTextureStorage()
-{
-    return mTexture2DArray->getNativeTexture()->getStorageInstance();
-}
-
-GLsizei Texture2DArrayAttachment::getWidth() const
-{
-    return mTexture2DArray->getWidth(mLevel);
-}
-
-GLsizei Texture2DArrayAttachment::getHeight() const
-{
-    return mTexture2DArray->getHeight(mLevel);
-}
-
-GLenum Texture2DArrayAttachment::getInternalFormat() const
-{
-    return mTexture2DArray->getInternalFormat(mLevel);
-}
-
-GLenum Texture2DArrayAttachment::getActualFormat() const
-{
-    return mTexture2DArray->getActualFormat(mLevel);
-}
-
-GLsizei Texture2DArrayAttachment::getSamples() const
-{
-    return 0;
-}
-
-unsigned int Texture2DArrayAttachment::getSerial() const
-{
-    return mTexture2DArray->getRenderTargetSerial(mLevel, mLayer);
-}
-
-GLuint Texture2DArrayAttachment::id() const
-{
-    return mTexture2DArray->id();
-}
-
-GLenum Texture2DArrayAttachment::type() const
-{
-    return GL_TEXTURE_2D_ARRAY;
-}
-
-GLint Texture2DArrayAttachment::mipLevel() const
-{
-    return mLevel;
-}
-
-GLint Texture2DArrayAttachment::layer() const
-{
-    return mLayer;
-}
-
-unsigned int Texture2DArrayAttachment::getTextureSerial() const
-{
-    return mTexture2DArray->getTextureSerial();
-}
-
 ////// FramebufferAttachment Implementation //////
 
-FramebufferAttachment::FramebufferAttachment(GLuint id, FramebufferAttachmentImpl *instance)
-  : RefCountObject(id),
-    mImpl(instance)
+FramebufferAttachment::FramebufferAttachment()
 {
-    ASSERT(mImpl != NULL);
 }
 
 FramebufferAttachment::~FramebufferAttachment()
 {
-    SafeDelete(mImpl);
-}
-
-// The FramebufferAttachmentImpl contained in this FramebufferAttachment may need to maintain
-// its own reference count, so we pass it on here.
-void FramebufferAttachment::addRef() const
-{
-    mImpl->addProxyRef(this);
-
-    RefCountObject::addRef();
-}
-
-void FramebufferAttachment::release() const
-{
-    mImpl->releaseProxy(this);
-
-    RefCountObject::release();
-}
-
-rx::RenderTarget *FramebufferAttachment::getRenderTarget()
-{
-    return mImpl->getRenderTarget();
-}
-
-rx::RenderTarget *FramebufferAttachment::getDepthStencil()
-{
-    return mImpl->getDepthStencil();
-}
-
-rx::TextureStorage *FramebufferAttachment::getTextureStorage()
-{
-    return mImpl->getTextureStorage();
-}
-
-GLsizei FramebufferAttachment::getWidth() const
-{
-    return mImpl->getWidth();
-}
-
-GLsizei FramebufferAttachment::getHeight() const
-{
-    return mImpl->getHeight();
-}
-
-GLenum FramebufferAttachment::getInternalFormat() const
-{
-    return mImpl->getInternalFormat();
-}
-
-GLenum FramebufferAttachment::getActualFormat() const
-{
-    return mImpl->getActualFormat();
 }
 
 GLuint FramebufferAttachment::getRedSize(int clientVersion) const
@@ -565,49 +118,339 @@
     return (type() != GL_RENDERBUFFER);
 }
 
-GLsizei FramebufferAttachment::getSamples() const
+///// Texture2DAttachment Implementation ////////
+
+Texture2DAttachment::Texture2DAttachment(Texture2D *texture, GLint level) : mLevel(level)
 {
-    return mImpl->getSamples();
+    mTexture2D.set(texture);
 }
 
-unsigned int FramebufferAttachment::getSerial() const
+Texture2DAttachment::~Texture2DAttachment()
 {
-    return mImpl->getSerial();
+    mTexture2D.set(NULL);
 }
 
-GLuint FramebufferAttachment::id() const
+rx::RenderTarget *Texture2DAttachment::getRenderTarget()
 {
-    return mImpl->id();
+    return mTexture2D->getRenderTarget(mLevel);
 }
 
-GLuint FramebufferAttachment::type() const
+rx::RenderTarget *Texture2DAttachment::getDepthStencil()
 {
-    return mImpl->type();
+    return mTexture2D->getDepthSencil(mLevel);
 }
 
-GLint FramebufferAttachment::mipLevel() const
+rx::TextureStorage *Texture2DAttachment::getTextureStorage()
 {
-    return mImpl->mipLevel();
+    return mTexture2D->getNativeTexture()->getStorageInstance();
 }
 
-GLint FramebufferAttachment::layer() const
+GLsizei Texture2DAttachment::getWidth() const
 {
-    return mImpl->layer();
+    return mTexture2D->getWidth(mLevel);
 }
 
-unsigned int FramebufferAttachment::getTextureSerial() const
+GLsizei Texture2DAttachment::getHeight() const
 {
-    return mImpl->getTextureSerial();
+    return mTexture2D->getHeight(mLevel);
 }
 
-void FramebufferAttachment::setImplementation(FramebufferAttachmentImpl *newImpl)
+GLenum Texture2DAttachment::getInternalFormat() const
 {
-    ASSERT(newImpl != NULL);
-
-    delete mImpl;
-    mImpl = newImpl;
+    return mTexture2D->getInternalFormat(mLevel);
 }
 
+GLenum Texture2DAttachment::getActualFormat() const
+{
+    return mTexture2D->getActualFormat(mLevel);
+}
+
+GLsizei Texture2DAttachment::getSamples() const
+{
+    return 0;
+}
+
+unsigned int Texture2DAttachment::getSerial() const
+{
+    return mTexture2D->getRenderTargetSerial(mLevel);
+}
+
+GLuint Texture2DAttachment::id() const
+{
+    return mTexture2D->id();
+}
+
+GLenum Texture2DAttachment::type() const
+{
+    return GL_TEXTURE_2D;
+}
+
+GLint Texture2DAttachment::mipLevel() const
+{
+    return mLevel;
+}
+
+GLint Texture2DAttachment::layer() const
+{
+    return 0;
+}
+
+unsigned int Texture2DAttachment::getTextureSerial() const
+{
+    return mTexture2D->getTextureSerial();
+}
+
+///// TextureCubeMapAttachment Implementation ////////
+
+TextureCubeMapAttachment::TextureCubeMapAttachment(TextureCubeMap *texture, GLenum faceTarget, GLint level)
+    : mFaceTarget(faceTarget), mLevel(level)
+{
+    mTextureCubeMap.set(texture);
+}
+
+TextureCubeMapAttachment::~TextureCubeMapAttachment()
+{
+    mTextureCubeMap.set(NULL);
+}
+
+rx::RenderTarget *TextureCubeMapAttachment::getRenderTarget()
+{
+    return mTextureCubeMap->getRenderTarget(mFaceTarget, mLevel);
+}
+
+rx::RenderTarget *TextureCubeMapAttachment::getDepthStencil()
+{
+    return mTextureCubeMap->getDepthStencil(mFaceTarget, mLevel);
+}
+
+rx::TextureStorage *TextureCubeMapAttachment::getTextureStorage()
+{
+    return mTextureCubeMap->getNativeTexture()->getStorageInstance();
+}
+
+GLsizei TextureCubeMapAttachment::getWidth() const
+{
+    return mTextureCubeMap->getWidth(mFaceTarget, mLevel);
+}
+
+GLsizei TextureCubeMapAttachment::getHeight() const
+{
+    return mTextureCubeMap->getHeight(mFaceTarget, mLevel);
+}
+
+GLenum TextureCubeMapAttachment::getInternalFormat() const
+{
+    return mTextureCubeMap->getInternalFormat(mFaceTarget, mLevel);
+}
+
+GLenum TextureCubeMapAttachment::getActualFormat() const
+{
+    return mTextureCubeMap->getActualFormat(mFaceTarget, mLevel);
+}
+
+GLsizei TextureCubeMapAttachment::getSamples() const
+{
+    return 0;
+}
+
+unsigned int TextureCubeMapAttachment::getSerial() const
+{
+    return mTextureCubeMap->getRenderTargetSerial(mFaceTarget, mLevel);
+}
+
+GLuint TextureCubeMapAttachment::id() const
+{
+    return mTextureCubeMap->id();
+}
+
+GLenum TextureCubeMapAttachment::type() const
+{
+    return mFaceTarget;
+}
+
+GLint TextureCubeMapAttachment::mipLevel() const
+{
+    return mLevel;
+}
+
+GLint TextureCubeMapAttachment::layer() const
+{
+    return 0;
+}
+
+unsigned int TextureCubeMapAttachment::getTextureSerial() const
+{
+    return mTextureCubeMap->getTextureSerial();
+}
+
+///// Texture3DAttachment Implementation ////////
+
+Texture3DAttachment::Texture3DAttachment(Texture3D *texture, GLint level, GLint layer)
+    : mLevel(level), mLayer(layer)
+{
+    mTexture3D.set(texture);
+}
+
+Texture3DAttachment::~Texture3DAttachment()
+{
+    mTexture3D.set(NULL);
+}
+
+rx::RenderTarget *Texture3DAttachment::getRenderTarget()
+{
+    return mTexture3D->getRenderTarget(mLevel, mLayer);
+}
+
+rx::RenderTarget *Texture3DAttachment::getDepthStencil()
+{
+    return mTexture3D->getDepthStencil(mLevel, mLayer);
+}
+
+rx::TextureStorage *Texture3DAttachment::getTextureStorage()
+{
+    return mTexture3D->getNativeTexture()->getStorageInstance();
+}
+
+GLsizei Texture3DAttachment::getWidth() const
+{
+    return mTexture3D->getWidth(mLevel);
+}
+
+GLsizei Texture3DAttachment::getHeight() const
+{
+    return mTexture3D->getHeight(mLevel);
+}
+
+GLenum Texture3DAttachment::getInternalFormat() const
+{
+    return mTexture3D->getInternalFormat(mLevel);
+}
+
+GLenum Texture3DAttachment::getActualFormat() const
+{
+    return mTexture3D->getActualFormat(mLevel);
+}
+
+GLsizei Texture3DAttachment::getSamples() const
+{
+    return 0;
+}
+
+unsigned int Texture3DAttachment::getSerial() const
+{
+    return mTexture3D->getRenderTargetSerial(mLevel, mLayer);
+}
+
+GLuint Texture3DAttachment::id() const
+{
+    return mTexture3D->id();
+}
+
+GLenum Texture3DAttachment::type() const
+{
+    return GL_TEXTURE_3D;
+}
+
+GLint Texture3DAttachment::mipLevel() const
+{
+    return mLevel;
+}
+
+GLint Texture3DAttachment::layer() const
+{
+    return mLayer;
+}
+
+unsigned int Texture3DAttachment::getTextureSerial() const
+{
+    return mTexture3D->getTextureSerial();
+}
+
+////// Texture2DArrayAttachment Implementation //////
+
+Texture2DArrayAttachment::Texture2DArrayAttachment(Texture2DArray *texture, GLint level, GLint layer)
+    : mLevel(level), mLayer(layer)
+{
+    mTexture2DArray.set(texture);
+}
+
+Texture2DArrayAttachment::~Texture2DArrayAttachment()
+{
+    mTexture2DArray.set(NULL);
+}
+
+rx::RenderTarget *Texture2DArrayAttachment::getRenderTarget()
+{
+    return mTexture2DArray->getRenderTarget(mLevel, mLayer);
+}
+
+rx::RenderTarget *Texture2DArrayAttachment::getDepthStencil()
+{
+    return mTexture2DArray->getDepthStencil(mLevel, mLayer);
+}
+
+rx::TextureStorage *Texture2DArrayAttachment::getTextureStorage()
+{
+    return mTexture2DArray->getNativeTexture()->getStorageInstance();
+}
+
+GLsizei Texture2DArrayAttachment::getWidth() const
+{
+    return mTexture2DArray->getWidth(mLevel);
+}
+
+GLsizei Texture2DArrayAttachment::getHeight() const
+{
+    return mTexture2DArray->getHeight(mLevel);
+}
+
+GLenum Texture2DArrayAttachment::getInternalFormat() const
+{
+    return mTexture2DArray->getInternalFormat(mLevel);
+}
+
+GLenum Texture2DArrayAttachment::getActualFormat() const
+{
+    return mTexture2DArray->getActualFormat(mLevel);
+}
+
+GLsizei Texture2DArrayAttachment::getSamples() const
+{
+    return 0;
+}
+
+unsigned int Texture2DArrayAttachment::getSerial() const
+{
+    return mTexture2DArray->getRenderTargetSerial(mLevel, mLayer);
+}
+
+GLuint Texture2DArrayAttachment::id() const
+{
+    return mTexture2DArray->id();
+}
+
+GLenum Texture2DArrayAttachment::type() const
+{
+    return GL_TEXTURE_2D_ARRAY;
+}
+
+GLint Texture2DArrayAttachment::mipLevel() const
+{
+    return mLevel;
+}
+
+GLint Texture2DArrayAttachment::layer() const
+{
+    return mLayer;
+}
+
+unsigned int Texture2DArrayAttachment::getTextureSerial() const
+{
+    return mTexture2DArray->getTextureSerial();
+}
+
+////// RenderbufferAttachment Implementation //////
+
 RenderbufferAttachment::RenderbufferAttachment(Renderbuffer *renderbuffer)
 {
     ASSERT(renderbuffer);
diff --git a/src/libGLESv2/FramebufferAttachment.h b/src/libGLESv2/FramebufferAttachment.h
index 62d9aad..d08d800 100644
--- a/src/libGLESv2/FramebufferAttachment.h
+++ b/src/libGLESv2/FramebufferAttachment.h
@@ -29,38 +29,21 @@
 class TextureCubeMap;
 class Texture3D;
 class Texture2DArray;
-class FramebufferAttachmentImpl;
 class Renderbuffer;
 
 // FramebufferAttachment implements a GL framebuffer attachment.
 // Attachments are "light" containers, which store pointers to ref-counted GL objects.
 // We support GL texture (2D/3D/Cube/2D array) and renderbuffer object attachments.
-// Note: Renderbuffers are specialized storage for depth and stencil buffes. Our old
-// naming scheme used the term "Renderbuffer" for both GL renderbuffers and for
+// Note: Our old naming scheme used the term "Renderbuffer" for both GL renderbuffers and for
 // framebuffer attachments, which confused their usage.
 
-class FramebufferAttachment : public RefCountObject
+class FramebufferAttachment
 {
   public:
-    FramebufferAttachment(GLuint id, FramebufferAttachmentImpl *storage);
-
+    FramebufferAttachment();
     virtual ~FramebufferAttachment();
 
-    // These functions from RefCountObject are overloaded here because
-    // Textures need to maintain their own count of references to them via
-    // Renderbuffers/RenderbufferTextures. These functions invoke those
-    // reference counting functions on the FramebufferAttachmentImpl.
-    void addRef() const;
-    void release() const;
-
-    rx::RenderTarget *getRenderTarget();
-    rx::RenderTarget *getDepthStencil();
-    rx::TextureStorage *getTextureStorage();
-
-    GLsizei getWidth() const;
-    GLsizei getHeight() const;
-    GLenum getInternalFormat() const;
-    GLenum getActualFormat() const;
+    // Helper methods
     GLuint getRedSize(int clientVersion) const;
     GLuint getGreenSize(int clientVersion) const;
     GLuint getBlueSize(int clientVersion) const;
@@ -69,35 +52,12 @@
     GLuint getStencilSize(int clientVersion) const;
     GLenum getComponentType(int clientVersion) const;
     GLenum getColorEncoding(int clientVersion) const;
-    GLsizei getSamples() const;
     bool isTexture() const;
 
-    unsigned int getSerial() const;
+    bool isTextureWithId(GLuint textureId) const { return isTexture() && id() == textureId; }
+    bool isRenderbufferWithId(GLuint renderbufferId) const { return !isTexture() && id() == renderbufferId; }
 
-    GLuint id() const;
-    GLenum type() const;
-    GLint mipLevel() const;
-    GLint layer() const;
-    unsigned int getTextureSerial() const;
-
-    void setImplementation(FramebufferAttachmentImpl *newImpl);
-
-  private:
-    DISALLOW_COPY_AND_ASSIGN(FramebufferAttachment);
-
-    FramebufferAttachmentImpl *mImpl;
-};
-
-class FramebufferAttachmentImpl
-{
-  public:
-    FramebufferAttachmentImpl();
-
-    virtual ~FramebufferAttachmentImpl() {};
-
-    virtual void addProxyRef(const FramebufferAttachment *proxy);
-    virtual void releaseProxy(const FramebufferAttachment *proxy);
-
+    // Child class interface
     virtual rx::RenderTarget *getRenderTarget() = 0;
     virtual rx::RenderTarget *getDepthStencil() = 0;
     virtual rx::TextureStorage *getTextureStorage() = 0;
@@ -117,19 +77,16 @@
     virtual unsigned int getTextureSerial() const = 0;
 
   private:
-    DISALLOW_COPY_AND_ASSIGN(FramebufferAttachmentImpl);
+    DISALLOW_COPY_AND_ASSIGN(FramebufferAttachment);
 };
 
-class Texture2DAttachment : public FramebufferAttachmentImpl
+class Texture2DAttachment : public FramebufferAttachment
 {
   public:
     Texture2DAttachment(Texture2D *texture, GLint level);
 
     virtual ~Texture2DAttachment();
 
-    void addProxyRef(const FramebufferAttachment *proxy);
-    void releaseProxy(const FramebufferAttachment *proxy);
-
     rx::RenderTarget *getRenderTarget();
     rx::RenderTarget *getDepthStencil();
     rx::TextureStorage *getTextureStorage();
@@ -151,20 +108,17 @@
   private:
     DISALLOW_COPY_AND_ASSIGN(Texture2DAttachment);
 
-    BindingPointer <Texture2D> mTexture2D;
+    BindingPointer<Texture2D> mTexture2D;
     const GLint mLevel;
 };
 
-class TextureCubeMapAttachment : public FramebufferAttachmentImpl
+class TextureCubeMapAttachment : public FramebufferAttachment
 {
   public:
     TextureCubeMapAttachment(TextureCubeMap *texture, GLenum faceTarget, GLint level);
 
     virtual ~TextureCubeMapAttachment();
 
-    void addProxyRef(const FramebufferAttachment *proxy);
-    void releaseProxy(const FramebufferAttachment *proxy);
-
     rx::RenderTarget *getRenderTarget();
     rx::RenderTarget *getDepthStencil();
     rx::TextureStorage *getTextureStorage();
@@ -186,21 +140,18 @@
   private:
     DISALLOW_COPY_AND_ASSIGN(TextureCubeMapAttachment);
 
-    BindingPointer <TextureCubeMap> mTextureCubeMap;
+    BindingPointer<TextureCubeMap> mTextureCubeMap;
     const GLint mLevel;
     const GLenum mFaceTarget;
 };
 
-class Texture3DAttachment : public FramebufferAttachmentImpl
+class Texture3DAttachment : public FramebufferAttachment
 {
   public:
     Texture3DAttachment(Texture3D *texture, GLint level, GLint layer);
 
     virtual ~Texture3DAttachment();
 
-    void addProxyRef(const FramebufferAttachment *proxy);
-    void releaseProxy(const FramebufferAttachment *proxy);
-
     rx::RenderTarget *getRenderTarget();
     rx::RenderTarget *getDepthStencil();
     rx::TextureStorage *getTextureStorage();
@@ -227,16 +178,13 @@
     const GLint mLayer;
 };
 
-class Texture2DArrayAttachment : public FramebufferAttachmentImpl
+class Texture2DArrayAttachment : public FramebufferAttachment
 {
   public:
     Texture2DArrayAttachment(Texture2DArray *texture, GLint level, GLint layer);
 
     virtual ~Texture2DArrayAttachment();
 
-    void addProxyRef(const FramebufferAttachment *proxy);
-    void releaseProxy(const FramebufferAttachment *proxy);
-
     rx::RenderTarget *getRenderTarget();
     rx::RenderTarget *getDepthStencil();
     rx::TextureStorage *getTextureStorage();
@@ -263,7 +211,7 @@
     const GLint mLayer;
 };
 
-class RenderbufferAttachment : public FramebufferAttachmentImpl
+class RenderbufferAttachment : public FramebufferAttachment
 {
   public:
     RenderbufferAttachment(Renderbuffer *renderbuffer);
diff --git a/src/libGLESv2/ProgramBinary.cpp b/src/libGLESv2/ProgramBinary.cpp
index 0f77bd9..dcb312c 100644
--- a/src/libGLESv2/ProgramBinary.cpp
+++ b/src/libGLESv2/ProgramBinary.cpp
@@ -197,17 +197,16 @@
 rx::ShaderExecutable *ProgramBinary::getPixelExecutableForFramebuffer(const Framebuffer *fbo)
 {
     std::vector<GLenum> outputs(IMPLEMENTATION_MAX_DRAW_BUFFERS);
-    for (size_t i = 0; i < IMPLEMENTATION_MAX_DRAW_BUFFERS; i++)
+    for (size_t outputIndex = 0; outputIndex < IMPLEMENTATION_MAX_DRAW_BUFFERS; outputIndex++)
     {
-        FramebufferAttachment *attachment = fbo->getColorbuffer(i);
-        if (attachment)
+        if (fbo->getColorbufferType(outputIndex) != GL_NONE)
         {
             // Always output floats for now
-            outputs[i] = GL_FLOAT;
+            outputs[outputIndex] = GL_FLOAT;
         }
         else
         {
-            outputs[i] = GL_NONE;
+            outputs[outputIndex] = GL_NONE;
         }
     }
 
diff --git a/src/libGLESv2/Renderbuffer.cpp b/src/libGLESv2/Renderbuffer.cpp
index 266084c..cae1eb8 100644
--- a/src/libGLESv2/Renderbuffer.cpp
+++ b/src/libGLESv2/Renderbuffer.cpp
@@ -17,6 +17,7 @@
 #include "libGLESv2/renderer/TextureStorage.h"
 #include "common/utilities.h"
 #include "libGLESv2/formatutils.h"
+#include "libGLESv2/FramebufferAttachment.h"
 
 namespace gl
 {
diff --git a/src/libGLESv2/Renderbuffer.h b/src/libGLESv2/Renderbuffer.h
index ef7989e..51c1eeb 100644
--- a/src/libGLESv2/Renderbuffer.h
+++ b/src/libGLESv2/Renderbuffer.h
@@ -17,7 +17,6 @@
 
 #include "common/angleutils.h"
 #include "common/RefCountObject.h"
-#include "libGLESv2/FramebufferAttachment.h"
 
 namespace rx
 {
@@ -30,6 +29,7 @@
 namespace gl
 {
 class RenderbufferStorage;
+class FramebufferAttachment;
 
 // A GL renderbuffer object is usually used as a depth or stencil buffer attachment
 // for a framebuffer object. The renderbuffer itself is a distinct GL object, see
diff --git a/src/libGLESv2/RenderbufferProxySet.cpp b/src/libGLESv2/RenderbufferProxySet.cpp
deleted file mode 100644
index f4fbe51..0000000
--- a/src/libGLESv2/RenderbufferProxySet.cpp
+++ /dev/null
@@ -1,87 +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.
-//
-
-// RenderbufferProxySet.cpp: Implements the gl::RenderbufferProxySet, a class for
-// maintaining a Texture's weak references to the Renderbuffers that represent it.
-
-#include "libGLESv2/RenderbufferProxySet.h"
-#include "common/debug.h"
-
-namespace gl
-{
-
-void RenderbufferProxySet::addRef(const FramebufferAttachment *proxy)
-{
-    RefCountMap::iterator i = mRefCountMap.find(proxy);
-    if (i != mRefCountMap.end())
-    {
-        i->second++;
-    }
-}
-
-void RenderbufferProxySet::release(const FramebufferAttachment *proxy)
-{
-    RefCountMap::iterator i = mRefCountMap.find(proxy);
-    if (i != mRefCountMap.end())
-    {
-        if (i->second > 0)
-        {
-            i->second--;
-        }
-
-        if (i->second == 0)
-        {
-            // Clear the buffer map of references to this FramebufferAttachment
-            BufferMap::iterator j = mBufferMap.begin();
-            while (j != mBufferMap.end())
-            {
-                if (j->second == proxy)
-                {
-                    j = mBufferMap.erase(j);
-                }
-                else
-                {
-                    ++j;
-                }
-            }
-
-            mRefCountMap.erase(i);
-        }
-    }
-}
-
-void RenderbufferProxySet::add(unsigned int mipLevel, unsigned int layer, FramebufferAttachment *renderBuffer)
-{
-    if (mRefCountMap.find(renderBuffer) == mRefCountMap.end())
-    {
-        mRefCountMap.insert(std::make_pair(renderBuffer, 0));
-    }
-
-    RenderbufferKey key;
-    key.mipLevel = mipLevel;
-    key.layer = layer;
-    if (mBufferMap.find(key) == mBufferMap.end())
-    {
-        mBufferMap.insert(std::make_pair(key, renderBuffer));
-    }
-}
-
-FramebufferAttachment *RenderbufferProxySet::get(unsigned int mipLevel, unsigned int layer) const
-{
-    RenderbufferKey key;
-    key.mipLevel = mipLevel;
-    key.layer = layer;
-    BufferMap::const_iterator i = mBufferMap.find(key);
-    return (i != mBufferMap.end()) ? i->second : NULL;
-}
-
-bool RenderbufferProxySet::RenderbufferKey::operator<(const RenderbufferKey &other) const
-{
-    return (mipLevel != other.mipLevel) ? mipLevel < other.mipLevel : layer < other.layer;
-}
-
-}
diff --git a/src/libGLESv2/RenderbufferProxySet.h b/src/libGLESv2/RenderbufferProxySet.h
deleted file mode 100644
index f151151..0000000
--- a/src/libGLESv2/RenderbufferProxySet.h
+++ /dev/null
@@ -1,46 +0,0 @@
-//
-// 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.
-//
-
-// RenderbufferProxySet.h: Defines the gl::RenderbufferProxySet, a class for
-// maintaining a Texture's weak references to the Renderbuffers that represent it.
-
-#ifndef LIBGLESV2_RENDERBUFFERPROXYSET_H_
-#define LIBGLESV2_RENDERBUFFERPROXYSET_H_
-
-#include <map>
-
-namespace gl
-{
-class FramebufferAttachment;
-
-class RenderbufferProxySet
-{
-  public:
-    void addRef(const FramebufferAttachment *proxy);
-    void release(const FramebufferAttachment *proxy);
-
-    void add(unsigned int mipLevel, unsigned int layer, FramebufferAttachment *renderBuffer);
-    FramebufferAttachment *get(unsigned int mipLevel, unsigned int layer) const;
-
-  private:
-    struct RenderbufferKey
-    {
-        unsigned int mipLevel;
-        unsigned int layer;
-
-        bool operator<(const RenderbufferKey &other) const;
-    };
-
-    typedef std::map<RenderbufferKey, FramebufferAttachment*> BufferMap;
-    BufferMap mBufferMap;
-
-    typedef std::map<const FramebufferAttachment*, unsigned int> RefCountMap;
-    RefCountMap mRefCountMap;
-};
-
-}
-
-#endif // LIBGLESV2_RENDERBUFFERPROXYSET_H_
diff --git a/src/libGLESv2/Texture.cpp b/src/libGLESv2/Texture.cpp
index 2a2f673..e6744a8 100644
--- a/src/libGLESv2/Texture.cpp
+++ b/src/libGLESv2/Texture.cpp
@@ -87,16 +87,6 @@
     return mTarget;
 }
 
-void Texture::addProxyRef(const FramebufferAttachment *proxy)
-{
-    mRenderbufferProxies.addRef(proxy);
-}
-
-void Texture::releaseProxy(const FramebufferAttachment *proxy)
-{
-    mRenderbufferProxies.release(proxy);
-}
-
 void Texture::setMinFilter(GLenum filter)
 {
     mSamplerState.minFilter = filter;
@@ -1027,18 +1017,6 @@
     return mTexStorage;
 }
 
-FramebufferAttachment *Texture2D::getAttachment(GLint level)
-{
-    FramebufferAttachment *attachment = mRenderbufferProxies.get(level, 0);
-    if (!attachment)
-    {
-        attachment = new FramebufferAttachment(id(), new Texture2DAttachment(this, level));
-        mRenderbufferProxies.add(level, 0, attachment);
-    }
-
-    return attachment;
-}
-
 unsigned int Texture2D::getRenderTargetSerial(GLint level)
 {
     return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(level) : 0);
@@ -1662,21 +1640,6 @@
     return mTexStorage;
 }
 
-FramebufferAttachment *TextureCubeMap::getAttachment(GLenum target, GLint level)
-{
-    ASSERT(!IsCubemapTextureTarget(target));
-    int faceIndex = targetToIndex(target);
-
-    FramebufferAttachment *attachment = mRenderbufferProxies.get(level, faceIndex);
-    if (!attachment)
-    {
-        attachment = new FramebufferAttachment(id(), new TextureCubeMapAttachment(this, target, level));
-        mRenderbufferProxies.add(level, faceIndex, attachment);
-    }
-
-    return attachment;
-}
-
 unsigned int TextureCubeMap::getRenderTargetSerial(GLenum target, GLint level)
 {
     return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(target, level) : 0);
@@ -2042,18 +2005,6 @@
     return true;
 }
 
-FramebufferAttachment *Texture3D::getAttachment(GLint level, GLint layer)
-{
-    FramebufferAttachment *attachment = mRenderbufferProxies.get(level, layer);
-    if (!attachment)
-    {
-        attachment = new FramebufferAttachment(id(), new Texture3DAttachment(this, level, layer));
-        mRenderbufferProxies.add(level, 0, attachment);
-    }
-
-    return attachment;
-}
-
 unsigned int Texture3D::getRenderTargetSerial(GLint level, GLint layer)
 {
     return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(level, layer) : 0);
@@ -2593,18 +2544,6 @@
     return true;
 }
 
-FramebufferAttachment *Texture2DArray::getAttachment(GLint level, GLint layer)
-{
-    FramebufferAttachment *attachment = mRenderbufferProxies.get(level, layer);
-    if (!attachment)
-    {
-        attachment = new FramebufferAttachment(id(), new Texture2DArrayAttachment(this, level, layer));
-        mRenderbufferProxies.add(level, 0, attachment);
-    }
-
-    return attachment;
-}
-
 unsigned int Texture2DArray::getRenderTargetSerial(GLint level, GLint layer)
 {
     return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(level, layer) : 0);
diff --git a/src/libGLESv2/Texture.h b/src/libGLESv2/Texture.h
index 84ca289..8a92a5e 100644
--- a/src/libGLESv2/Texture.h
+++ b/src/libGLESv2/Texture.h
@@ -19,7 +19,6 @@
 #include "common/debug.h"
 #include "common/RefCountObject.h"
 #include "libGLESv2/angletypes.h"
-#include "libGLESv2/RenderbufferProxySet.h"
 
 namespace egl
 {
@@ -65,9 +64,6 @@
 
     virtual ~Texture();
 
-    void addProxyRef(const FramebufferAttachment *proxy);
-    void releaseProxy(const FramebufferAttachment *proxy);
-
     GLenum getTarget() const;
 
     void setMinFilter(GLenum filter);
@@ -157,13 +153,6 @@
 
     GLenum mTarget;
 
-    // A specific internal reference count is kept for colorbuffer proxy references,
-    // because, as the renderbuffer acting as proxy will maintain a binding pointer
-    // back to this texture, there would be a circular reference if we used a binding
-    // pointer here. This reference count will cause the pointer to be set to NULL if
-    // the count drops to zero, but will not cause deletion of the FramebufferAttachment.
-    RenderbufferProxySet mRenderbufferProxies;
-
   private:
     DISALLOW_COPY_AND_ASSIGN(Texture);
 
@@ -199,7 +188,6 @@
 
     virtual void generateMipmaps();
 
-    FramebufferAttachment *getAttachment(GLint level);
     unsigned int getRenderTargetSerial(GLint level);
 
   protected:
@@ -267,7 +255,6 @@
 
     virtual void generateMipmaps();
 
-    FramebufferAttachment *getAttachment(GLenum target, GLint level);
     unsigned int getRenderTargetSerial(GLenum target, GLint level);
 
     static int targetToIndex(GLenum target);
@@ -330,7 +317,6 @@
     virtual bool isSamplerComplete(const SamplerState &samplerState) const;
     virtual bool isMipmapComplete() const;
 
-    FramebufferAttachment *getAttachment(GLint level, GLint layer);
     unsigned int getRenderTargetSerial(GLint level, GLint layer);
 
   protected:
@@ -391,7 +377,6 @@
     virtual bool isSamplerComplete(const SamplerState &samplerState) const;
     virtual bool isMipmapComplete() const;
 
-    FramebufferAttachment *getAttachment(GLint level, GLint layer);
     unsigned int getRenderTargetSerial(GLint level, GLint layer);
 
   protected:
diff --git a/src/libGLESv2/libGLESv2.cpp b/src/libGLESv2/libGLESv2.cpp
index d8f8de8..6be355a 100644
--- a/src/libGLESv2/libGLESv2.cpp
+++ b/src/libGLESv2/libGLESv2.cpp
@@ -24,6 +24,7 @@
 #include "libGLESv2/VertexArray.h"
 #include "libGLESv2/VertexAttribute.h"
 #include "libGLESv2/TransformFeedback.h"
+#include "libGLESv2/FramebufferAttachment.h"
 
 #include "libGLESv2/validationES.h"
 #include "libGLESv2/validationES2.h"
@@ -2617,7 +2618,7 @@
             GLuint attachmentHandle;
             GLuint attachmentLevel;
             GLuint attachmentLayer;
-            gl::FramebufferAttachment *attachmentObject;
+            const gl::FramebufferAttachment *attachmentObject;
 
             if (framebufferHandle == 0)
             {
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp
index 59e07e2..37eb1b1 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp
@@ -14,7 +14,7 @@
 
 #include "libGLESv2/formatutils.h"
 #include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/Renderbuffer.h"
+#include "libGLESv2/FramebufferAttachment.h"
 
 #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearfloat11vs.h"
 #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps.h"
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp
index b4b5632..a159c36 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp
@@ -12,7 +12,7 @@
 #include "libGLESv2/renderer/d3d/d3d11/Image11.h"
 #include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h"
 #include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/Renderbuffer.h"
+#include "libGLESv2/FramebufferAttachment.h"
 
 #include "libGLESv2/main.h"
 #include "common/utilities.h"
diff --git a/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp b/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp
index 7bdd6b0..7b6ad78 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp
@@ -12,7 +12,7 @@
 #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
 #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
 #include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/Renderbuffer.h"
+#include "libGLESv2/FramebufferAttachment.h"
 
 #include "common/debug.h"
 #include "third_party/murmurhash/MurmurHash3.h"
@@ -95,7 +95,7 @@
     key.blendState = blendState;
     for (unsigned int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
     {
-        gl::FramebufferAttachment *attachment = framebuffer->getColorbuffer(i);
+        const gl::FramebufferAttachment *attachment = framebuffer->getColorbuffer(i);
         if (attachment)
         {
             if (i > 0)
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
index 7d1ac26..b26a8ae 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
@@ -10,9 +10,9 @@
 #include "libGLESv2/main.h"
 #include "common/utilities.h"
 #include "libGLESv2/Buffer.h"
+#include "libGLESv2/FramebufferAttachment.h"
 #include "libGLESv2/ProgramBinary.h"
 #include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/RenderBuffer.h"
 #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
 #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
 #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp b/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp
index c9fabba..b723fed 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp
@@ -16,7 +16,7 @@
 #include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h"
 #include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
 #include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/Renderbuffer.h"
+#include "libGLESv2/FramebufferAttachment.h"
 
 namespace
 {
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp b/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp
index 759df06..d241c92 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp
@@ -1,3 +1,4 @@
+
 #include "precompiled.h"
 //
 // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
@@ -12,6 +13,7 @@
 
 #include "libGLESv2/main.h"
 #include "libGLESv2/Framebuffer.h"
+#include "libGLESv2/FramebufferAttachment.h"
 #include "libGLESv2/Renderbuffer.h"
 #include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
 #include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h"
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
index 54d2c60..0f64e58 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
@@ -13,6 +13,7 @@
 #include "libGLESv2/Buffer.h"
 #include "libGLESv2/Texture.h"
 #include "libGLESv2/Framebuffer.h"
+#include "libGLESv2/FramebufferAttachment.h"
 #include "libGLESv2/Renderbuffer.h"
 #include "libGLESv2/ProgramBinary.h"
 #include "libGLESv2/renderer/d3d/IndexDataManager.h"
@@ -1126,7 +1127,7 @@
     }
 
     gl::Renderbuffer *nullRenderbuffer = new gl::Renderbuffer(this, 0, new gl::Colorbuffer(this, width, height, GL_NONE, 0));
-    gl::FramebufferAttachment *nullbuffer = new gl::FramebufferAttachment(0, new gl::RenderbufferAttachment(nullRenderbuffer));
+    gl::RenderbufferAttachment *nullbuffer = new gl::RenderbufferAttachment(nullRenderbuffer);
 
     // add nullbuffer to the cache
     NullColorbufferCacheEntry *oldest = &mNullColorbufferCache[0];
diff --git a/src/libGLESv2/validationES.cpp b/src/libGLESv2/validationES.cpp
index 5afe273..34e6396 100644
--- a/src/libGLESv2/validationES.cpp
+++ b/src/libGLESv2/validationES.cpp
@@ -13,7 +13,7 @@
 #include "libGLESv2/Context.h"
 #include "libGLESv2/Texture.h"
 #include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/Renderbuffer.h"
+#include "libGLESv2/FramebufferAttachment.h"
 #include "libGLESv2/formatutils.h"
 #include "libGLESv2/main.h"
 #include "libGLESv2/Query.h"
diff --git a/src/libGLESv2/validationES2.cpp b/src/libGLESv2/validationES2.cpp
index f2ba5da..5136575 100644
--- a/src/libGLESv2/validationES2.cpp
+++ b/src/libGLESv2/validationES2.cpp
@@ -15,6 +15,7 @@
 #include "libGLESv2/Renderbuffer.h"
 #include "libGLESv2/formatutils.h"
 #include "libGLESv2/main.h"
+#include "libGLESv2/FramebufferAttachment.h"
 
 #include "common/mathutil.h"
 #include "common/utilities.h"
diff --git a/src/libGLESv2/validationES3.cpp b/src/libGLESv2/validationES3.cpp
index e55e86d..e865fba 100644
--- a/src/libGLESv2/validationES3.cpp
+++ b/src/libGLESv2/validationES3.cpp
@@ -15,6 +15,7 @@
 #include "libGLESv2/Renderbuffer.h"
 #include "libGLESv2/formatutils.h"
 #include "libGLESv2/main.h"
+#include "libGLESv2/FramebufferAttachment.h"
 
 #include "common/mathutil.h"