Don't reallocate default FBO on makeCurrent.

We can use the flat FBO attachment types to update our data
instead of reallocating it. This also lets us delete the
DefaultFramebuffer class.

BUG=angleproject:963,angleproject:840

Change-Id: Ib8f20d8212d073fb5e248756321cb2e6b4e086dc
Reviewed-on: https://chromium-review.googlesource.com/263492
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index d944f8b..545284a 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -49,7 +49,6 @@
 
     mConfigID = config->configID;
     mClientType = EGL_OPENGL_ES_API;
-    mRenderBuffer = EGL_NONE;
 
     mFenceNVHandleAllocator.setBaseHandle(0);
 
@@ -89,6 +88,9 @@
 
     mState.initializeZeroTextures(mZeroTextures);
 
+    // Allocate default FBO
+    mFramebufferMap[0] = new Framebuffer(mCaps, mRenderer, 0);
+
     bindVertexArray(0);
     bindArrayBuffer(0);
     bindElementArrayBuffer(0);
@@ -184,16 +186,50 @@
         mHasBeenCurrent = true;
     }
 
-    // TODO(jmadill): do not allocate new pointers here
-    Framebuffer *framebufferZero = new DefaultFramebuffer(mCaps, mRenderer, surface);
-    setFramebufferZero(framebufferZero);
-    mRenderBuffer = surface->getRenderBuffer();
+    // Update default framebuffer
+    Framebuffer *defaultFBO = mFramebufferMap[0];
+
+    GLenum drawBufferState = GL_BACK;
+    defaultFBO->setDrawBuffers(1, &drawBufferState);
+    defaultFBO->setReadBuffer(GL_BACK);
+
+    const FramebufferAttachment *backAttachment = defaultFBO->getAttachment(GL_BACK);
+
+    if (backAttachment && backAttachment->getSurface() == surface)
+    {
+        // FBO already initialized to the surface.
+        return;
+    }
+
+    const egl::Config *config = surface->getConfig();
+
+    defaultFBO->setAttachment(GL_FRAMEBUFFER_DEFAULT, GL_BACK, ImageIndex::MakeInvalid(), surface);
+
+    if (config->depthSize > 0)
+    {
+        defaultFBO->setAttachment(GL_FRAMEBUFFER_DEFAULT, GL_DEPTH, ImageIndex::MakeInvalid(), surface);
+    }
+    else
+    {
+        defaultFBO->resetAttachment(GL_DEPTH);
+    }
+
+    if (config->stencilSize > 0)
+    {
+        defaultFBO->setAttachment(GL_FRAMEBUFFER_DEFAULT, GL_STENCIL, ImageIndex::MakeInvalid(), surface);
+    }
+    else
+    {
+        defaultFBO->resetAttachment(GL_STENCIL);
+    }
 }
 
 void Context::releaseSurface()
 {
-    setFramebufferZero(nullptr);
-    mRenderBuffer = EGL_NONE;
+    Framebuffer *defaultFBO = mFramebufferMap[0];
+    defaultFBO->resetAttachment(GL_BACK);
+    defaultFBO->resetAttachment(GL_DEPTH);
+    defaultFBO->resetAttachment(GL_STENCIL);
 }
 
 // NOTE: this function should not assume that this context is current!
@@ -664,27 +700,6 @@
     return error;
 }
 
-void Context::setFramebufferZero(Framebuffer *buffer)
-{
-    // First, check to see if the old default framebuffer
-    // was set for draw or read framebuffer, and change
-    // the bindings to point to the new one before deleting it.
-    if (mState.getDrawFramebuffer() == nullptr ||
-        mState.getDrawFramebuffer()->id() == 0)
-    {
-        mState.setDrawFramebufferBinding(buffer);
-    }
-
-    if (mState.getReadFramebuffer() == nullptr ||
-        mState.getReadFramebuffer()->id() == 0)
-    {
-        mState.setReadFramebufferBinding(buffer);
-    }
-
-    SafeDelete(mFramebufferMap[0]);
-    mFramebufferMap[0] = buffer;
-}
-
 Framebuffer *Context::getFramebuffer(unsigned int handle) const
 {
     FramebufferMap::const_iterator framebuffer = mFramebufferMap.find(handle);
@@ -1298,7 +1313,10 @@
 
 EGLenum Context::getRenderBuffer() const
 {
-    return mRenderBuffer;
+    ASSERT(mFramebufferMap.count(0) > 0);
+    const Framebuffer *framebuffer = mFramebufferMap.find(0)->second;
+    const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
+    return backAttachment ? backAttachment->getSurface()->getRenderBuffer() : EGL_NONE;
 }
 
 const Caps &Context::getCaps() const