Revert "Store value types for FBO attachments."

In file included from ../../third_party/angle/src/libANGLE/Framebuffer.cpp:10:
In file included from ../../third_party/angle/src/libANGLE/Framebuffer.h:13:
In file included from /Applications/Xcode5.1.1.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.6.sdk/usr/include/c++/4.2.1/vector:68:
/Applications/Xcode5.1.1.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.6.sdk/usr/include/c++/4.2.1/bits/stl_construct.h:81:38: error: call to implicitly-deleted copy constructor of 'gl::FramebufferAttachment'
      ::new(static_cast<void*>(__p)) _T1(__value);
                                     ^   ~~~~~~~
This reverts commit 13773b26dfb29b963ea727e1ebf7bdabdc5892b1.

Change-Id: If79f2797fe46798cbe5b39d83c9bcb1a7e87026d
Reviewed-on: https://chromium-review.googlesource.com/266643
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/Framebuffer.cpp b/src/libANGLE/Framebuffer.cpp
index 3e005b3..78a06a8 100644
--- a/src/libANGLE/Framebuffer.cpp
+++ b/src/libANGLE/Framebuffer.cpp
@@ -27,19 +27,19 @@
 
 namespace
 {
-void DetachMatchingAttachment(FramebufferAttachment *attachment, GLenum matchType, GLuint matchId)
+void DeleteMatchingAttachment(FramebufferAttachment *&attachment, GLenum matchType, GLuint matchId)
 {
-    if (attachment->isAttached() &&
-        attachment->type() == matchType &&
-        attachment->id() == matchId)
+    if (attachment && attachment->type() == matchType && attachment->id() == matchId)
     {
-        attachment->detach();
+        SafeDelete(attachment);
     }
 }
 }
 
 Framebuffer::Data::Data(const Caps &caps)
-    : mColorAttachments(caps.maxColorAttachments),
+    : mColorAttachments(caps.maxColorAttachments, nullptr),
+      mDepthAttachment(nullptr),
+      mStencilAttachment(nullptr),
       mDrawBufferStates(caps.maxDrawBuffers, GL_NONE),
       mReadBufferState(GL_COLOR_ATTACHMENT0_EXT)
 {
@@ -48,6 +48,12 @@
 
 Framebuffer::Data::~Data()
 {
+    for (auto &colorAttachment : mColorAttachments)
+    {
+        SafeDelete(colorAttachment);
+    }
+    SafeDelete(mDepthAttachment);
+    SafeDelete(mStencilAttachment);
 }
 
 const FramebufferAttachment *Framebuffer::Data::getReadAttachment() const
@@ -55,16 +61,16 @@
     ASSERT(mReadBufferState == GL_BACK || (mReadBufferState >= GL_COLOR_ATTACHMENT0 && mReadBufferState <= GL_COLOR_ATTACHMENT15));
     size_t readIndex = (mReadBufferState == GL_BACK ? 0 : static_cast<size_t>(mReadBufferState - GL_COLOR_ATTACHMENT0));
     ASSERT(readIndex < mColorAttachments.size());
-    return mColorAttachments[readIndex].isAttached() ? &mColorAttachments[readIndex] : nullptr;
+    return mColorAttachments[readIndex];
 }
 
 const FramebufferAttachment *Framebuffer::Data::getFirstColorAttachment() const
 {
-    for (const FramebufferAttachment &colorAttachment : mColorAttachments)
+    for (FramebufferAttachment *colorAttachment : mColorAttachments)
     {
-        if (colorAttachment.isAttached())
+        if (colorAttachment != nullptr)
         {
-            return &colorAttachment;
+            return colorAttachment;
         }
     }
 
@@ -73,23 +79,13 @@
 
 const FramebufferAttachment *Framebuffer::Data::getDepthOrStencilAttachment() const
 {
-    if (mDepthAttachment.isAttached())
-    {
-        return &mDepthAttachment;
-    }
-    if (mStencilAttachment.isAttached())
-    {
-        return &mStencilAttachment;
-    }
-    return nullptr;
+    return (mDepthAttachment != nullptr ? mDepthAttachment : mStencilAttachment);
 }
 
 FramebufferAttachment *Framebuffer::Data::getColorAttachment(unsigned int colorAttachment)
 {
     ASSERT(colorAttachment < mColorAttachments.size());
-    return mColorAttachments[colorAttachment].isAttached() ?
-           &mColorAttachments[colorAttachment] :
-           nullptr;
+    return mColorAttachments[colorAttachment];
 }
 
 const FramebufferAttachment *Framebuffer::Data::getColorAttachment(unsigned int colorAttachment) const
@@ -99,7 +95,7 @@
 
 FramebufferAttachment *Framebuffer::Data::getDepthAttachment()
 {
-    return mDepthAttachment.isAttached() ? &mDepthAttachment : nullptr;
+    return mDepthAttachment;
 }
 
 const FramebufferAttachment *Framebuffer::Data::getDepthAttachment() const
@@ -109,7 +105,7 @@
 
 FramebufferAttachment *Framebuffer::Data::getStencilAttachment()
 {
-    return mStencilAttachment.isAttached() ? &mStencilAttachment : nullptr;
+    return mStencilAttachment;
 }
 
 const FramebufferAttachment *Framebuffer::Data::getStencilAttachment() const
@@ -121,11 +117,11 @@
 {
     // A valid depth-stencil attachment has the same resource bound to both the
     // depth and stencil attachment points.
-    if (mDepthAttachment.isAttached() && mStencilAttachment.isAttached() &&
-        mDepthAttachment.type() == mStencilAttachment.type() &&
-        mDepthAttachment.id() == mStencilAttachment.id())
+    if (mDepthAttachment && mStencilAttachment &&
+        mDepthAttachment->type() == mStencilAttachment->type() &&
+        mDepthAttachment->id() == mStencilAttachment->id())
     {
-        return &mDepthAttachment;
+        return mDepthAttachment;
     }
 
     return nullptr;
@@ -171,11 +167,11 @@
 {
     for (auto &colorAttachment : mData.mColorAttachments)
     {
-        DetachMatchingAttachment(&colorAttachment, resourceType, resourceId);
+        DeleteMatchingAttachment(colorAttachment, resourceType, resourceId);
     }
 
-    DetachMatchingAttachment(&mData.mDepthAttachment, resourceType, resourceId);
-    DetachMatchingAttachment(&mData.mStencilAttachment, resourceType, resourceId);
+    DeleteMatchingAttachment(mData.mDepthAttachment, resourceType, resourceId);
+    DeleteMatchingAttachment(mData.mStencilAttachment, resourceType, resourceId);
 }
 
 FramebufferAttachment *Framebuffer::getColorbuffer(unsigned int colorAttachment)
@@ -239,7 +235,7 @@
     return mData.getFirstColorAttachment();
 }
 
-const FramebufferAttachment *Framebuffer::getAttachment(GLenum attachment) const
+FramebufferAttachment *Framebuffer::getAttachment(GLenum attachment)
 {
     if (attachment >= GL_COLOR_ATTACHMENT0 && attachment <= GL_COLOR_ATTACHMENT15)
     {
@@ -268,6 +264,11 @@
     }
 }
 
+const FramebufferAttachment *Framebuffer::getAttachment(GLenum attachment) const
+{
+    return const_cast<Framebuffer*>(this)->getAttachment(attachment);
+}
+
 GLenum Framebuffer::getDrawBufferState(unsigned int colorAttachment) const
 {
     ASSERT(colorAttachment < mData.mDrawBufferStates.size());
@@ -301,7 +302,7 @@
 bool Framebuffer::isEnabledColorAttachment(unsigned int colorAttachment) const
 {
     ASSERT(colorAttachment < mData.mColorAttachments.size());
-    return (mData.mColorAttachments[colorAttachment].isAttached() &&
+    return (mData.mColorAttachments[colorAttachment] &&
             mData.mDrawBufferStates[colorAttachment] != GL_NONE);
 }
 
@@ -320,7 +321,7 @@
 
 bool Framebuffer::hasStencil() const
 {
-    return (mData.mStencilAttachment.isAttached() && mData.mStencilAttachment.getStencilSize() > 0);
+    return (mData.mStencilAttachment && mData.mStencilAttachment->getStencilSize() > 0);
 }
 
 bool Framebuffer::usingExtendedDrawBuffers() const
@@ -351,19 +352,19 @@
     int samples = -1;
     bool missingAttachment = true;
 
-    for (const FramebufferAttachment &colorAttachment : mData.mColorAttachments)
+    for (const FramebufferAttachment *colorAttachment : mData.mColorAttachments)
     {
-        if (colorAttachment.isAttached())
+        if (colorAttachment != nullptr)
         {
-            if (colorAttachment.getWidth() == 0 || colorAttachment.getHeight() == 0)
+            if (colorAttachment->getWidth() == 0 || colorAttachment->getHeight() == 0)
             {
                 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
             }
 
-            GLenum internalformat = colorAttachment.getInternalFormat();
+            GLenum internalformat = colorAttachment->getInternalFormat();
             const TextureCaps &formatCaps = data.textureCaps->get(internalformat);
             const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
-            if (colorAttachment.type() == GL_TEXTURE)
+            if (colorAttachment->type() == GL_TEXTURE)
             {
                 if (!formatCaps.renderable)
                 {
@@ -375,7 +376,7 @@
                     return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
                 }
             }
-            else if (colorAttachment.type() == GL_RENDERBUFFER)
+            else if (colorAttachment->type() == GL_RENDERBUFFER)
             {
                 if (!formatCaps.renderable || formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
                 {
@@ -386,14 +387,14 @@
             if (!missingAttachment)
             {
                 // all color attachments must have the same width and height
-                if (colorAttachment.getWidth() != width || colorAttachment.getHeight() != height)
+                if (colorAttachment->getWidth() != width || colorAttachment->getHeight() != height)
                 {
                     return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
                 }
 
                 // APPLE_framebuffer_multisample, which EXT_draw_buffers refers to, requires that
                 // all color attachments have the same number of samples for the FBO to be complete.
-                if (colorAttachment.getSamples() != samples)
+                if (colorAttachment->getSamples() != samples)
                 {
                     return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT;
                 }
@@ -410,27 +411,27 @@
             }
             else
             {
-                width = colorAttachment.getWidth();
-                height = colorAttachment.getHeight();
-                samples = colorAttachment.getSamples();
+                width = colorAttachment->getWidth();
+                height = colorAttachment->getHeight();
+                samples = colorAttachment->getSamples();
                 colorbufferSize = formatInfo.pixelBytes;
                 missingAttachment = false;
             }
         }
     }
 
-    const FramebufferAttachment &depthAttachment = mData.mDepthAttachment;
-    if (depthAttachment.isAttached())
+    const FramebufferAttachment *depthAttachment = mData.mDepthAttachment;
+    if (depthAttachment != nullptr)
     {
-        if (depthAttachment.getWidth() == 0 || depthAttachment.getHeight() == 0)
+        if (depthAttachment->getWidth() == 0 || depthAttachment->getHeight() == 0)
         {
             return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
         }
 
-        GLenum internalformat = depthAttachment.getInternalFormat();
+        GLenum internalformat = depthAttachment->getInternalFormat();
         const TextureCaps &formatCaps = data.textureCaps->get(internalformat);
         const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
-        if (depthAttachment.type() == GL_TEXTURE)
+        if (depthAttachment->type() == GL_TEXTURE)
         {
             // depth texture attachments require OES/ANGLE_depth_texture
             if (!data.extensions->depthTextures)
@@ -448,7 +449,7 @@
                 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
             }
         }
-        else if (depthAttachment.type() == GL_RENDERBUFFER)
+        else if (depthAttachment->type() == GL_RENDERBUFFER)
         {
             if (!formatCaps.renderable || formatInfo.depthBits == 0)
             {
@@ -458,33 +459,33 @@
 
         if (missingAttachment)
         {
-            width = depthAttachment.getWidth();
-            height = depthAttachment.getHeight();
-            samples = depthAttachment.getSamples();
+            width = depthAttachment->getWidth();
+            height = depthAttachment->getHeight();
+            samples = depthAttachment->getSamples();
             missingAttachment = false;
         }
-        else if (width != depthAttachment.getWidth() || height != depthAttachment.getHeight())
+        else if (width != depthAttachment->getWidth() || height != depthAttachment->getHeight())
         {
             return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
         }
-        else if (samples != depthAttachment.getSamples())
+        else if (samples != depthAttachment->getSamples())
         {
             return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
         }
     }
 
-    const FramebufferAttachment &stencilAttachment = mData.mStencilAttachment;
-    if (stencilAttachment.isAttached())
+    const FramebufferAttachment *stencilAttachment = mData.mStencilAttachment;
+    if (stencilAttachment)
     {
-        if (stencilAttachment.getWidth() == 0 || stencilAttachment.getHeight() == 0)
+        if (stencilAttachment->getWidth() == 0 || stencilAttachment->getHeight() == 0)
         {
             return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
         }
 
-        GLenum internalformat = stencilAttachment.getInternalFormat();
+        GLenum internalformat = stencilAttachment->getInternalFormat();
         const TextureCaps &formatCaps = data.textureCaps->get(internalformat);
         const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
-        if (stencilAttachment.type() == GL_TEXTURE)
+        if (stencilAttachment->type() == GL_TEXTURE)
         {
             // texture stencil attachments come along as part
             // of OES_packed_depth_stencil + OES/ANGLE_depth_texture
@@ -503,7 +504,7 @@
                 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
             }
         }
-        else if (stencilAttachment.type() == GL_RENDERBUFFER)
+        else if (stencilAttachment->type() == GL_RENDERBUFFER)
         {
             if (!formatCaps.renderable || formatInfo.stencilBits == 0)
             {
@@ -513,16 +514,16 @@
 
         if (missingAttachment)
         {
-            width = stencilAttachment.getWidth();
-            height = stencilAttachment.getHeight();
-            samples = stencilAttachment.getSamples();
+            width = stencilAttachment->getWidth();
+            height = stencilAttachment->getHeight();
+            samples = stencilAttachment->getSamples();
             missingAttachment = false;
         }
-        else if (width != stencilAttachment.getWidth() || height != stencilAttachment.getHeight())
+        else if (width != stencilAttachment->getWidth() || height != stencilAttachment->getHeight())
         {
             return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
         }
-        else if (samples != stencilAttachment.getSamples())
+        else if (samples != stencilAttachment->getSamples())
         {
             return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
         }
@@ -530,7 +531,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 (depthAttachment.isAttached() && stencilAttachment.isAttached() && !hasValidDepthStencil())
+    if (depthAttachment && stencilAttachment && !hasValidDepthStencil())
     {
         return GL_FRAMEBUFFER_UNSUPPORTED;
     }
@@ -606,11 +607,11 @@
     {
         // for a complete framebuffer, all attachments must have the same sample count
         // in this case return the first nonzero sample size
-        for (const FramebufferAttachment &colorAttachment : mData.mColorAttachments)
+        for (const FramebufferAttachment *colorAttachment : mData.mColorAttachments)
         {
-            if (colorAttachment.isAttached())
+            if (colorAttachment != nullptr)
             {
-                return colorAttachment.getSamples();
+                return colorAttachment->getSamples();
             }
         }
     }
@@ -623,84 +624,103 @@
     return mData.getDepthStencilAttachment() != nullptr;
 }
 
-void Framebuffer::setAttachment(GLenum type,
-                                GLenum binding,
-                                const ImageIndex &textureIndex,
-                                FramebufferAttachmentObject *resource)
+void Framebuffer::setTextureAttachment(GLenum attachment, Texture *texture, const ImageIndex &imageIndex)
 {
-    if (binding == GL_DEPTH_STENCIL || binding == GL_DEPTH_STENCIL_ATTACHMENT)
+    setAttachment(attachment, new FramebufferAttachment(GL_TEXTURE, attachment, imageIndex, texture));
+}
+
+void Framebuffer::setRenderbufferAttachment(GLenum attachment, Renderbuffer *renderbuffer)
+{
+    setAttachment(attachment, new FramebufferAttachment(GL_RENDERBUFFER, attachment, ImageIndex::MakeInvalid(), renderbuffer));
+}
+
+void Framebuffer::setNULLAttachment(GLenum attachment)
+{
+    setAttachment(attachment, NULL);
+}
+
+void Framebuffer::setAttachment(GLenum attachment, FramebufferAttachment *attachmentObj)
+{
+    if (attachment >= GL_COLOR_ATTACHMENT0 && attachment < (GL_COLOR_ATTACHMENT0 + mData.mColorAttachments.size()))
     {
+        size_t colorAttachment = attachment - GL_COLOR_ATTACHMENT0;
+        SafeDelete(mData.mColorAttachments[colorAttachment]);
+        mData.mColorAttachments[colorAttachment] = attachmentObj;
+        mImpl->setColorAttachment(colorAttachment, attachmentObj);
+    }
+    else if (attachment == GL_BACK)
+    {
+        SafeDelete(mData.mColorAttachments[0]);
+        mData.mColorAttachments[0] = attachmentObj;
+        mImpl->setColorAttachment(0, attachmentObj);
+    }
+    else if (attachment == GL_DEPTH_ATTACHMENT || attachment == GL_DEPTH)
+    {
+        SafeDelete(mData.mDepthAttachment);
+        mData.mDepthAttachment = attachmentObj;
+        mImpl->setDepthAttachment(attachmentObj);
+    }
+    else if (attachment == GL_STENCIL_ATTACHMENT || attachment == GL_STENCIL)
+    {
+        SafeDelete(mData.mStencilAttachment);
+        mData.mStencilAttachment = attachmentObj;
+        mImpl->setStencilAttachment(attachmentObj);
+    }
+    else if (attachment == GL_DEPTH_STENCIL_ATTACHMENT || attachment == GL_DEPTH_STENCIL)
+    {
+        SafeDelete(mData.mDepthAttachment);
+        SafeDelete(mData.mStencilAttachment);
+
         // ensure this is a legitimate depth+stencil format
-        FramebufferAttachment::Target target(binding, textureIndex);
-        GLenum internalFormat = resource->getAttachmentInternalFormat(target);
-        const InternalFormat &formatInfo = GetInternalFormatInfo(internalFormat);
-        if (resource && formatInfo.depthBits > 0 && formatInfo.stencilBits > 0)
+        if (attachmentObj && attachmentObj->getDepthSize() > 0 && attachmentObj->getStencilSize() > 0)
         {
-            mData.mDepthAttachment.attach(type, binding, textureIndex, resource);
-            mData.mStencilAttachment.attach(type, binding, textureIndex, resource);
+            mData.mDepthAttachment = attachmentObj;
+            mImpl->setDepthAttachment(attachmentObj);
+
+            // Make a new attachment object to ensure we do not double-delete
+            // See angle issue 686
+            if (attachmentObj->type() == GL_TEXTURE)
+            {
+                mData.mStencilAttachment = new FramebufferAttachment(GL_TEXTURE,
+                                                                     GL_DEPTH_STENCIL_ATTACHMENT,
+                                                                     attachmentObj->getTextureImageIndex(),
+                                                                     attachmentObj->getTexture());
+                mImpl->setStencilAttachment(mData.mStencilAttachment);
+            }
+            else if (attachmentObj->type() == GL_RENDERBUFFER)
+            {
+                mData.mStencilAttachment = new FramebufferAttachment(GL_RENDERBUFFER,
+                                                                     GL_DEPTH_STENCIL_ATTACHMENT,
+                                                                     ImageIndex::MakeInvalid(),
+                                                                     attachmentObj->getRenderbuffer());
+                mImpl->setStencilAttachment(mData.mStencilAttachment);
+            }
+            else
+            {
+                UNREACHABLE();
+            }
         }
-        else
-        {
-            mData.mDepthAttachment.detach();
-            mData.mStencilAttachment.detach();
-        }
-        mImpl->setDepthStencilAttachment(&mData.mDepthAttachment);
     }
     else
     {
-        FramebufferAttachment *attachment = nullptr;
-
-        switch (binding)
-        {
-          case GL_DEPTH:
-          case GL_DEPTH_ATTACHMENT:
-            attachment = &mData.mDepthAttachment;
-            attachment->attach(type, binding, textureIndex, resource);
-            mImpl->setDepthAttachment(attachment);
-            break;
-          case GL_STENCIL:
-          case GL_STENCIL_ATTACHMENT:
-            attachment = &mData.mStencilAttachment;
-            attachment->attach(type, binding, textureIndex, resource);
-            mImpl->setStencilAttachment(attachment);
-            break;
-          case GL_BACK:
-            attachment = &mData.mColorAttachments[0];
-            attachment->attach(type, binding, textureIndex, resource);
-            mImpl->setColorAttachment(0, attachment);
-            break;
-          default:
-            {
-                size_t colorIndex = binding - GL_COLOR_ATTACHMENT0;
-                ASSERT(colorIndex < mData.mColorAttachments.size());
-                attachment = &mData.mColorAttachments[colorIndex];
-                attachment->attach(type, binding, textureIndex, resource);
-                mImpl->setColorAttachment(colorIndex, attachment);
-            }
-            break;
-        }
+        UNREACHABLE();
     }
 }
 
-void Framebuffer::resetAttachment(GLenum binding)
-{
-    setAttachment(GL_NONE, binding, ImageIndex::MakeInvalid(), nullptr);
-}
-
 DefaultFramebuffer::DefaultFramebuffer(const Caps &caps, rx::ImplFactory *factory, egl::Surface *surface)
     : Framebuffer(caps, factory, 0)
 {
     const egl::Config *config = surface->getConfig();
 
-    setAttachment(GL_FRAMEBUFFER_DEFAULT, GL_BACK, ImageIndex::MakeInvalid(), surface);
+    setAttachment(GL_BACK, new FramebufferAttachment(GL_FRAMEBUFFER_DEFAULT, GL_BACK, ImageIndex::MakeInvalid(), surface));
 
     if (config->depthSize > 0)
     {
-        setAttachment(GL_FRAMEBUFFER_DEFAULT, GL_DEPTH, ImageIndex::MakeInvalid(), surface);
+        setAttachment(GL_DEPTH, new FramebufferAttachment(GL_FRAMEBUFFER_DEFAULT, GL_DEPTH, ImageIndex::MakeInvalid(), surface));
     }
     if (config->stencilSize > 0)
     {
-        setAttachment(GL_FRAMEBUFFER_DEFAULT, GL_STENCIL, ImageIndex::MakeInvalid(), surface);
+        setAttachment(GL_STENCIL, new FramebufferAttachment(GL_FRAMEBUFFER_DEFAULT, GL_STENCIL, ImageIndex::MakeInvalid(), surface));
     }
 
     GLenum drawBufferState = GL_BACK;