Create a DefaultAttachment type and an implementation for it.

This allows for dynamically sized default attachments instead of calling
Context::makeCurrent each time the surface changes size.

BUG=angle:824

Change-Id: Ic39c0d7dc4269db53a34c01c4d915cb1a3cfbd08
Reviewed-on: https://chromium-review.googlesource.com/228180
Tested-by: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/projects/src/libANGLE.vcxproj b/projects/src/libANGLE.vcxproj
index a01298e..69435f2 100644
--- a/projects/src/libANGLE.vcxproj
+++ b/projects/src/libANGLE.vcxproj
@@ -287,6 +287,7 @@
     <ClInclude Include="..\..\src\libGLESv2\queryconversions.h"/>
     <ClInclude Include="..\..\src\libGLESv2\renderer\BufferImpl.h"/>
     <ClInclude Include="..\..\src\libGLESv2\renderer\FenceImpl.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\FramebufferImpl.h"/>
     <ClInclude Include="..\..\src\libGLESv2\renderer\Image.h"/>
     <ClInclude Include="..\..\src\libGLESv2\renderer\IndexRangeCache.h"/>
     <ClInclude Include="..\..\src\libGLESv2\renderer\ProgramImpl.h"/>
@@ -315,6 +316,7 @@
     <ClInclude Include="..\..\src\third_party\systeminfo\SystemInfo.h"/>
     <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\BufferD3D.h"/>
     <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\DynamicHLSL.h"/>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\FramebufferD3D.h"/>
     <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\HLSLCompiler.h"/>
     <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\ImageD3D.h"/>
     <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\IndexBuffer.h"/>
@@ -476,6 +478,7 @@
     <ClCompile Include="..\..\src\third_party\systeminfo\SystemInfo.cpp"/>
     <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\BufferD3D.cpp"/>
     <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\DynamicHLSL.cpp"/>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\FramebufferD3D.cpp"/>
     <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\HLSLCompiler.cpp"/>
     <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\ImageD3D.cpp"/>
     <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\IndexBuffer.cpp"/>
diff --git a/projects/src/libANGLE.vcxproj.filters b/projects/src/libANGLE.vcxproj.filters
index b381be6..c70ea7c 100644
--- a/projects/src/libANGLE.vcxproj.filters
+++ b/projects/src/libANGLE.vcxproj.filters
@@ -859,6 +859,15 @@
     <Filter Include="src\libGLESv2">
       <UniqueIdentifier>{A62A9415-2E9D-A6D2-631D-1F25A5CD626F}</UniqueIdentifier>
     </Filter>
+    <Filter Include="src\libGLESv2\renderer">
+      <UniqueIdentifier>{AC4EF684-2900-10EA-3D11-A6DF0901358C}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src">
+      <UniqueIdentifier>{8CDEE807-BC53-E450-C8B8-4DEBB66742D4}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\libGLESv2">
+      <UniqueIdentifier>{A62A9415-2E9D-A6D2-631D-1F25A5CD626F}</UniqueIdentifier>
+    </Filter>
     <Filter Include="src">
       <UniqueIdentifier>{8CDEE807-BC53-E450-C8B8-4DEBB66742D4}</UniqueIdentifier>
     </Filter>
@@ -1327,6 +1336,30 @@
     <Filter Include="src\libGLESv2\renderer\d3d">
       <UniqueIdentifier>{3AC19AE3-A12C-4021-D645-4CEA5BC956DB}</UniqueIdentifier>
     </Filter>
+    <Filter Include="src">
+      <UniqueIdentifier>{8CDEE807-BC53-E450-C8B8-4DEBB66742D4}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\libGLESv2">
+      <UniqueIdentifier>{A62A9415-2E9D-A6D2-631D-1F25A5CD626F}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\libGLESv2\renderer">
+      <UniqueIdentifier>{AC4EF684-2900-10EA-3D11-A6DF0901358C}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\libGLESv2\renderer\d3d">
+      <UniqueIdentifier>{3AC19AE3-A12C-4021-D645-4CEA5BC956DB}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src">
+      <UniqueIdentifier>{8CDEE807-BC53-E450-C8B8-4DEBB66742D4}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\libGLESv2">
+      <UniqueIdentifier>{A62A9415-2E9D-A6D2-631D-1F25A5CD626F}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\libGLESv2\renderer">
+      <UniqueIdentifier>{AC4EF684-2900-10EA-3D11-A6DF0901358C}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\libGLESv2\renderer\d3d">
+      <UniqueIdentifier>{3AC19AE3-A12C-4021-D645-4CEA5BC956DB}</UniqueIdentifier>
+    </Filter>
     <Filter Include="src\libGLESv2\renderer\d3d\d3d9">
       <UniqueIdentifier>{8BB193D2-4A8B-A094-A81E-D5E262AB1F92}</UniqueIdentifier>
     </Filter>
@@ -3852,6 +3885,9 @@
     <ClInclude Include="..\..\src\libGLESv2\renderer\FenceImpl.h">
       <Filter>src\libGLESv2\renderer</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\FramebufferImpl.h">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </ClInclude>
     <ClCompile Include="..\..\src\libGLESv2\renderer\Image.cpp">
       <Filter>src\libGLESv2\renderer</Filter>
     </ClCompile>
@@ -3996,6 +4032,12 @@
     <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\DynamicHLSL.h">
       <Filter>src\libGLESv2\renderer\d3d</Filter>
     </ClInclude>
+    <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\FramebufferD3D.cpp">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\src\libGLESv2\renderer\d3d\FramebufferD3D.h">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClInclude>
     <ClCompile Include="..\..\src\libGLESv2\renderer\d3d\HLSLCompiler.cpp">
       <Filter>src\libGLESv2\renderer\d3d</Filter>
     </ClCompile>
diff --git a/projects/winrt/windows/src/libANGLE.vcxproj b/projects/winrt/windows/src/libANGLE.vcxproj
index b7d95fe..e420bfa 100644
--- a/projects/winrt/windows/src/libANGLE.vcxproj
+++ b/projects/winrt/windows/src/libANGLE.vcxproj
@@ -400,6 +400,7 @@
     <ClInclude Include="..\..\..\..\src\libGLESv2\queryconversions.h"/>
     <ClInclude Include="..\..\..\..\src\libGLESv2\renderer\BufferImpl.h"/>
     <ClInclude Include="..\..\..\..\src\libGLESv2\renderer\FenceImpl.h"/>
+    <ClInclude Include="..\..\..\..\src\libGLESv2\renderer\FramebufferImpl.h"/>
     <ClInclude Include="..\..\..\..\src\libGLESv2\renderer\Image.h"/>
     <ClInclude Include="..\..\..\..\src\libGLESv2\renderer\IndexRangeCache.h"/>
     <ClInclude Include="..\..\..\..\src\libGLESv2\renderer\ProgramImpl.h"/>
@@ -428,6 +429,7 @@
     <ClInclude Include="..\..\..\..\src\third_party\systeminfo\SystemInfo.h"/>
     <ClInclude Include="..\..\..\..\src\libGLESv2\renderer\d3d\BufferD3D.h"/>
     <ClInclude Include="..\..\..\..\src\libGLESv2\renderer\d3d\DynamicHLSL.h"/>
+    <ClInclude Include="..\..\..\..\src\libGLESv2\renderer\d3d\FramebufferD3D.h"/>
     <ClInclude Include="..\..\..\..\src\libGLESv2\renderer\d3d\HLSLCompiler.h"/>
     <ClInclude Include="..\..\..\..\src\libGLESv2\renderer\d3d\ImageD3D.h"/>
     <ClInclude Include="..\..\..\..\src\libGLESv2\renderer\d3d\IndexBuffer.h"/>
@@ -571,6 +573,7 @@
     <ClCompile Include="..\..\..\..\src\third_party\systeminfo\SystemInfo.cpp"/>
     <ClCompile Include="..\..\..\..\src\libGLESv2\renderer\d3d\BufferD3D.cpp"/>
     <ClCompile Include="..\..\..\..\src\libGLESv2\renderer\d3d\DynamicHLSL.cpp"/>
+    <ClCompile Include="..\..\..\..\src\libGLESv2\renderer\d3d\FramebufferD3D.cpp"/>
     <ClCompile Include="..\..\..\..\src\libGLESv2\renderer\d3d\HLSLCompiler.cpp"/>
     <ClCompile Include="..\..\..\..\src\libGLESv2\renderer\d3d\ImageD3D.cpp"/>
     <ClCompile Include="..\..\..\..\src\libGLESv2\renderer\d3d\IndexBuffer.cpp"/>
diff --git a/projects/winrt/windows/src/libANGLE.vcxproj.filters b/projects/winrt/windows/src/libANGLE.vcxproj.filters
index 94a06e1..f0bfd3d 100644
--- a/projects/winrt/windows/src/libANGLE.vcxproj.filters
+++ b/projects/winrt/windows/src/libANGLE.vcxproj.filters
@@ -859,6 +859,15 @@
     <Filter Include="src\libGLESv2">
       <UniqueIdentifier>{A62A9415-2E9D-A6D2-631D-1F25A5CD626F}</UniqueIdentifier>
     </Filter>
+    <Filter Include="src\libGLESv2\renderer">
+      <UniqueIdentifier>{AC4EF684-2900-10EA-3D11-A6DF0901358C}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src">
+      <UniqueIdentifier>{8CDEE807-BC53-E450-C8B8-4DEBB66742D4}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\libGLESv2">
+      <UniqueIdentifier>{A62A9415-2E9D-A6D2-631D-1F25A5CD626F}</UniqueIdentifier>
+    </Filter>
     <Filter Include="src">
       <UniqueIdentifier>{8CDEE807-BC53-E450-C8B8-4DEBB66742D4}</UniqueIdentifier>
     </Filter>
@@ -1327,6 +1336,30 @@
     <Filter Include="src\libGLESv2\renderer\d3d">
       <UniqueIdentifier>{3AC19AE3-A12C-4021-D645-4CEA5BC956DB}</UniqueIdentifier>
     </Filter>
+    <Filter Include="src">
+      <UniqueIdentifier>{8CDEE807-BC53-E450-C8B8-4DEBB66742D4}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\libGLESv2">
+      <UniqueIdentifier>{A62A9415-2E9D-A6D2-631D-1F25A5CD626F}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\libGLESv2\renderer">
+      <UniqueIdentifier>{AC4EF684-2900-10EA-3D11-A6DF0901358C}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\libGLESv2\renderer\d3d">
+      <UniqueIdentifier>{3AC19AE3-A12C-4021-D645-4CEA5BC956DB}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src">
+      <UniqueIdentifier>{8CDEE807-BC53-E450-C8B8-4DEBB66742D4}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\libGLESv2">
+      <UniqueIdentifier>{A62A9415-2E9D-A6D2-631D-1F25A5CD626F}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\libGLESv2\renderer">
+      <UniqueIdentifier>{AC4EF684-2900-10EA-3D11-A6DF0901358C}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\libGLESv2\renderer\d3d">
+      <UniqueIdentifier>{3AC19AE3-A12C-4021-D645-4CEA5BC956DB}</UniqueIdentifier>
+    </Filter>
     <Filter Include="src\libGLESv2\renderer\d3d\d3d11">
       <UniqueIdentifier>{10FB1414-88D2-B512-6D76-522749905268}</UniqueIdentifier>
     </Filter>
@@ -3327,6 +3360,9 @@
     <ClInclude Include="..\..\..\..\src\libGLESv2\renderer\FenceImpl.h">
       <Filter>src\libGLESv2\renderer</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\..\..\src\libGLESv2\renderer\FramebufferImpl.h">
+      <Filter>src\libGLESv2\renderer</Filter>
+    </ClInclude>
     <ClCompile Include="..\..\..\..\src\libGLESv2\renderer\Image.cpp">
       <Filter>src\libGLESv2\renderer</Filter>
     </ClCompile>
@@ -3471,6 +3507,12 @@
     <ClInclude Include="..\..\..\..\src\libGLESv2\renderer\d3d\DynamicHLSL.h">
       <Filter>src\libGLESv2\renderer\d3d</Filter>
     </ClInclude>
+    <ClCompile Include="..\..\..\..\src\libGLESv2\renderer\d3d\FramebufferD3D.cpp">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClCompile>
+    <ClInclude Include="..\..\..\..\src\libGLESv2\renderer\d3d\FramebufferD3D.h">
+      <Filter>src\libGLESv2\renderer\d3d</Filter>
+    </ClInclude>
     <ClCompile Include="..\..\..\..\src\libGLESv2\renderer\d3d\HLSLCompiler.cpp">
       <Filter>src\libGLESv2\renderer\d3d</Filter>
     </ClCompile>
diff --git a/src/libEGL/Surface.cpp b/src/libEGL/Surface.cpp
index 3414656..3693162 100644
--- a/src/libEGL/Surface.cpp
+++ b/src/libEGL/Surface.cpp
@@ -363,17 +363,7 @@
         resizeSwapChain(clientWidth, clientHeight);
     }
 
-    if (wasDirty)
-    {
-        if (static_cast<egl::Surface*>(getCurrentDrawSurface()) == this)
-        {
-            glMakeCurrent(glGetCurrentContext(), static_cast<egl::Display*>(getCurrentDisplay()), this);
-        }
-
-        return true;
-    }
-
-    return false;
+    return wasDirty;
 }
 
 Error Surface::swap()
diff --git a/src/libGLESv2.gypi b/src/libGLESv2.gypi
index 8a7fd02..cb6ac94 100644
--- a/src/libGLESv2.gypi
+++ b/src/libGLESv2.gypi
@@ -100,6 +100,7 @@
             'libGLESv2/queryconversions.h',
             'libGLESv2/renderer/BufferImpl.h',
             'libGLESv2/renderer/FenceImpl.h',
+            'libGLESv2/renderer/FramebufferImpl.h',
             'libGLESv2/renderer/Image.cpp',
             'libGLESv2/renderer/Image.h',
             'libGLESv2/renderer/IndexRangeCache.cpp',
@@ -165,6 +166,8 @@
             'libGLESv2/renderer/d3d/BufferD3D.h',
             'libGLESv2/renderer/d3d/DynamicHLSL.cpp',
             'libGLESv2/renderer/d3d/DynamicHLSL.h',
+            'libGLESv2/renderer/d3d/FramebufferD3D.cpp',
+            'libGLESv2/renderer/d3d/FramebufferD3D.h',
             'libGLESv2/renderer/d3d/HLSLCompiler.cpp',
             'libGLESv2/renderer/d3d/HLSLCompiler.h',
             'libGLESv2/renderer/d3d/ImageD3D.cpp',
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index fe9b1a2..b0c5bc5 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -193,12 +193,9 @@
         mHasBeenCurrent = true;
     }
 
-    // Wrap the existing swapchain resources into GL objects and assign them to the '0' names
-    rx::SwapChain *swapchain = surface->getSwapChain();
-
-    rx::RenderbufferImpl *colorbufferZero = mRenderer->createRenderbuffer(swapchain, false);
-    rx::RenderbufferImpl *depthStencilbufferZero = mRenderer->createRenderbuffer(swapchain, true);
-    Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);
+    Framebuffer *framebufferZero = new DefaultFramebuffer(mRenderer->createDefaultAttachment(GL_BACK, surface),
+                                                          mRenderer->createDefaultAttachment(GL_DEPTH, surface),
+                                                          mRenderer->createDefaultAttachment(GL_STENCIL, surface));
 
     setFramebufferZero(framebufferZero);
 }
diff --git a/src/libGLESv2/Framebuffer.cpp b/src/libGLESv2/Framebuffer.cpp
index 9b97830..27fc3cf 100644
--- a/src/libGLESv2/Framebuffer.cpp
+++ b/src/libGLESv2/Framebuffer.cpp
@@ -20,6 +20,7 @@
 #include "libGLESv2/renderer/Workarounds.h"
 #include "libGLESv2/renderer/d3d/TextureD3D.h"
 #include "libGLESv2/renderer/d3d/RenderbufferD3D.h"
+#include "libGLESv2/renderer/d3d/FramebufferD3D.h"
 
 #include "common/utilities.h"
 
@@ -29,7 +30,7 @@
 //       to FramebufferD3D.
 gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget **outRT)
 {
-    if (attachment->isTexture())
+    if (attachment->type() == GL_TEXTURE)
     {
         gl::Texture *texture = attachment->getTexture();
         ASSERT(texture);
@@ -38,7 +39,7 @@
         ASSERT(index);
         return textureD3D->getRenderTarget(*index, outRT);
     }
-    else
+    else if (attachment->type() == GL_RENDERBUFFER)
     {
         gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
         ASSERT(renderbuffer);
@@ -46,12 +47,26 @@
         *outRT = renderbufferD3D->getRenderTarget();
         return gl::Error(GL_NO_ERROR);
     }
+    else if (attachment->type() == GL_FRAMEBUFFER_DEFAULT)
+    {
+        gl::DefaultAttachment *defaultAttachment = static_cast<gl::DefaultAttachment *>(attachment);
+        DefaultAttachmentD3D *defaultAttachmentD3D = DefaultAttachmentD3D::makeDefaultAttachmentD3D(defaultAttachment->getImplementation());
+        ASSERT(defaultAttachmentD3D);
+
+        *outRT = defaultAttachmentD3D->getRenderTarget();
+        return gl::Error(GL_NO_ERROR);
+    }
+    else
+    {
+        UNREACHABLE();
+        return gl::Error(GL_INVALID_OPERATION);
+    }
 }
 
 // Note: RenderTarget serials should ideally be in the RenderTargets themselves.
 unsigned int GetAttachmentSerial(gl::FramebufferAttachment *attachment)
 {
-    if (attachment->isTexture())
+    if (attachment->type() == GL_TEXTURE)
     {
         gl::Texture *texture = attachment->getTexture();
         ASSERT(texture);
@@ -60,11 +75,25 @@
         ASSERT(index);
         return textureD3D->getRenderTargetSerial(*index);
     }
-
-    gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
-    ASSERT(renderbuffer);
-    RenderbufferD3D *renderbufferD3D = RenderbufferD3D::makeRenderbufferD3D(renderbuffer->getImplementation());
-    return renderbufferD3D->getRenderTargetSerial();
+    else if (attachment->type() == GL_RENDERBUFFER)
+    {
+        gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
+        ASSERT(renderbuffer);
+        RenderbufferD3D *renderbufferD3D = RenderbufferD3D::makeRenderbufferD3D(renderbuffer->getImplementation());
+        return renderbufferD3D->getRenderTargetSerial();
+    }
+    else if (attachment->type() == GL_FRAMEBUFFER_DEFAULT)
+    {
+        gl::DefaultAttachment *defaultAttachment = static_cast<gl::DefaultAttachment *>(attachment);
+        DefaultAttachmentD3D *defaultAttachmentD3D = DefaultAttachmentD3D::makeDefaultAttachmentD3D(defaultAttachment->getImplementation());
+        ASSERT(defaultAttachmentD3D);
+        return defaultAttachmentD3D->getRenderTarget()->getSerial();
+    }
+    else
+    {
+        UNREACHABLE();
+        return 0;
+    }
 }
 
 }
@@ -291,7 +320,7 @@
             GLenum internalformat = colorbuffer->getInternalFormat();
             const TextureCaps &formatCaps = data.textureCaps->get(internalformat);
             const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
-            if (colorbuffer->isTexture())
+            if (colorbuffer->type() == GL_TEXTURE)
             {
                 if (!formatCaps.renderable)
                 {
@@ -303,7 +332,7 @@
                     return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
                 }
             }
-            else
+            else if (colorbuffer->type() == GL_RENDERBUFFER)
             {
                 if (!formatCaps.renderable || formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
                 {
@@ -370,7 +399,7 @@
         GLenum internalformat = mDepthbuffer->getInternalFormat();
         const TextureCaps &formatCaps = data.textureCaps->get(internalformat);
         const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
-        if (mDepthbuffer->isTexture())
+        if (mDepthbuffer->type() == GL_TEXTURE)
         {
             // depth texture attachments require OES/ANGLE_depth_texture
             if (!data.extensions->depthTextures)
@@ -388,7 +417,7 @@
                 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
             }
         }
-        else
+        else if (mDepthbuffer->type() == GL_RENDERBUFFER)
         {
             if (!formatCaps.renderable || formatInfo.depthBits == 0)
             {
@@ -423,7 +452,7 @@
         GLenum internalformat = mStencilbuffer->getInternalFormat();
         const TextureCaps &formatCaps = data.textureCaps->get(internalformat);
         const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
-        if (mStencilbuffer->isTexture())
+        if (mStencilbuffer->type() == GL_TEXTURE)
         {
             // texture stencil attachments come along as part
             // of OES_packed_depth_stencil + OES/ANGLE_depth_texture
@@ -442,7 +471,7 @@
                 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
             }
         }
-        else
+        else if (mStencilbuffer->type() == GL_RENDERBUFFER)
         {
             if (!formatCaps.renderable || formatInfo.stencilBits == 0)
             {
@@ -514,23 +543,20 @@
     return Error(GL_NO_ERROR);
 }
 
-DefaultFramebuffer::DefaultFramebuffer(rx::RenderbufferImpl *colorbuffer, rx::RenderbufferImpl *depthStencil)
+DefaultFramebuffer::DefaultFramebuffer(rx::DefaultAttachmentImpl *colorAttachment, rx::DefaultAttachmentImpl *depthAttachment,
+                                       rx::DefaultAttachmentImpl *stencilAttachment)
     : Framebuffer(0)
 {
-    Renderbuffer *colorRenderbuffer = new Renderbuffer(colorbuffer, 0);
-    mColorbuffers[0] = new RenderbufferAttachment(GL_BACK, colorRenderbuffer);
+    ASSERT(colorAttachment);
+    mColorbuffers[0] = new DefaultAttachment(GL_BACK, colorAttachment);
 
-    GLenum depthStencilActualFormat = depthStencil->getActualFormat();
-    const InternalFormat &depthStencilFormatInfo = GetInternalFormatInfo(depthStencilActualFormat);
-
-    if (depthStencilFormatInfo.depthBits != 0 || depthStencilFormatInfo.stencilBits != 0)
+    if (depthAttachment)
     {
-        Renderbuffer *depthStencilBuffer = new Renderbuffer(depthStencil, 0);
-
-        // Make a new attachment objects to ensure we do not double-delete
-        // See angle issue 686
-        mDepthbuffer = (depthStencilFormatInfo.depthBits != 0 ? new RenderbufferAttachment(GL_DEPTH_ATTACHMENT, depthStencilBuffer) : NULL);
-        mStencilbuffer = (depthStencilFormatInfo.stencilBits != 0 ? new RenderbufferAttachment(GL_STENCIL_ATTACHMENT, depthStencilBuffer) : NULL);
+        mDepthbuffer = new DefaultAttachment(GL_DEPTH, depthAttachment);
+    }
+    if (stencilAttachment)
+    {
+        mStencilbuffer = new DefaultAttachment(GL_STENCIL, stencilAttachment);
     }
 
     mDrawBufferStates[0] = GL_BACK;
@@ -632,15 +658,19 @@
 
             // Make a new attachment object to ensure we do not double-delete
             // See angle issue 686
-            if (attachmentObj->isTexture())
+            if (attachmentObj->type() == GL_TEXTURE)
             {
                 mStencilbuffer = new TextureAttachment(GL_DEPTH_STENCIL_ATTACHMENT, attachmentObj->getTexture(),
                                                        *attachmentObj->getTextureImageIndex());
             }
-            else
+            else if (attachmentObj->type() == GL_RENDERBUFFER)
             {
                 mStencilbuffer = new RenderbufferAttachment(GL_DEPTH_STENCIL_ATTACHMENT, attachmentObj->getRenderbuffer());
             }
+            else
+            {
+                UNREACHABLE();
+            }
         }
     }
     else
diff --git a/src/libGLESv2/Framebuffer.h b/src/libGLESv2/Framebuffer.h
index d0fe893..68a8df9 100644
--- a/src/libGLESv2/Framebuffer.h
+++ b/src/libGLESv2/Framebuffer.h
@@ -22,6 +22,7 @@
 {
 class RenderbufferImpl;
 struct Workarounds;
+class DefaultAttachmentImpl;
 }
 
 namespace gl
@@ -102,7 +103,8 @@
 class DefaultFramebuffer : public Framebuffer
 {
   public:
-    DefaultFramebuffer(rx::RenderbufferImpl *colorbuffer, rx::RenderbufferImpl *depthStencil);
+    DefaultFramebuffer(rx::DefaultAttachmentImpl *colorAttachment, rx::DefaultAttachmentImpl *depthAttachment,
+                       rx::DefaultAttachmentImpl *stencilAttachment);
 
     GLenum completeness(const gl::Data &data) const override;
     virtual FramebufferAttachment *getAttachment(GLenum attachment) const;
diff --git a/src/libGLESv2/FramebufferAttachment.cpp b/src/libGLESv2/FramebufferAttachment.cpp
index 894884a..6d3b788 100644
--- a/src/libGLESv2/FramebufferAttachment.cpp
+++ b/src/libGLESv2/FramebufferAttachment.cpp
@@ -11,6 +11,7 @@
 #include "libGLESv2/Texture.h"
 #include "libGLESv2/formatutils.h"
 #include "libGLESv2/Renderbuffer.h"
+#include "libGLESv2/renderer/FramebufferImpl.h"
 #include "libGLESv2/renderer/RenderTarget.h"
 #include "libGLESv2/renderer/Renderer.h"
 #include "libGLESv2/renderer/d3d/TextureStorage.h"
@@ -71,11 +72,6 @@
     return GetInternalFormatInfo(getActualFormat()).colorEncoding;
 }
 
-bool FramebufferAttachment::isTexture() const
-{
-    return (type() != GL_RENDERBUFFER);
-}
-
 ///// TextureAttachment Implementation ////////
 
 TextureAttachment::TextureAttachment(GLenum binding, Texture *texture, const ImageIndex &index)
@@ -122,7 +118,7 @@
 
 GLenum TextureAttachment::type() const
 {
-    return mIndex.type;
+    return GL_TEXTURE;
 }
 
 GLint TextureAttachment::mipLevel() const
@@ -130,6 +126,11 @@
     return mIndex.mipIndex;
 }
 
+GLenum TextureAttachment::cubeMapFace() const
+{
+    return IsCubemapTextureTarget(mIndex.type) ? mIndex.type : GL_NONE;
+}
+
 GLint TextureAttachment::layer() const
 {
     return mIndex.layerIndex;
@@ -205,6 +206,11 @@
     return 0;
 }
 
+GLenum RenderbufferAttachment::cubeMapFace() const
+{
+    return GL_NONE;
+}
+
 GLint RenderbufferAttachment::layer() const
 {
     return 0;
@@ -227,4 +233,90 @@
     return mRenderbuffer.get();
 }
 
+
+DefaultAttachment::DefaultAttachment(GLenum binding, rx::DefaultAttachmentImpl *impl)
+    : FramebufferAttachment(binding),
+      mImpl(impl)
+{
+    ASSERT(mImpl);
+}
+
+DefaultAttachment::~DefaultAttachment()
+{
+    SafeDelete(mImpl);
+}
+
+GLsizei DefaultAttachment::getWidth() const
+{
+    return mImpl->getWidth();
+}
+
+GLsizei DefaultAttachment::getHeight() const
+{
+    return mImpl->getHeight();
+}
+
+GLenum DefaultAttachment::getInternalFormat() const
+{
+    return mImpl->getInternalFormat();
+}
+
+GLenum DefaultAttachment::getActualFormat() const
+{
+    return mImpl->getActualFormat();
+}
+
+GLsizei DefaultAttachment::getSamples() const
+{
+    return mImpl->getSamples();
+}
+
+GLuint DefaultAttachment::id() const
+{
+    return 0;
+}
+
+GLenum DefaultAttachment::type() const
+{
+    return GL_FRAMEBUFFER_DEFAULT;
+}
+
+GLint DefaultAttachment::mipLevel() const
+{
+    return 0;
+}
+
+GLenum DefaultAttachment::cubeMapFace() const
+{
+    return GL_NONE;
+}
+
+GLint DefaultAttachment::layer() const
+{
+    return 0;
+}
+
+Texture *DefaultAttachment::getTexture()
+{
+    UNREACHABLE();
+    return NULL;
+}
+
+const ImageIndex *DefaultAttachment::getTextureImageIndex() const
+{
+    UNREACHABLE();
+    return NULL;
+}
+
+Renderbuffer *DefaultAttachment::getRenderbuffer()
+{
+    UNREACHABLE();
+    return NULL;
+}
+
+rx::DefaultAttachmentImpl *DefaultAttachment::getImplementation() const
+{
+    return mImpl;
+}
+
 }
diff --git a/src/libGLESv2/FramebufferAttachment.h b/src/libGLESv2/FramebufferAttachment.h
index 8d2dafa..0d28793 100644
--- a/src/libGLESv2/FramebufferAttachment.h
+++ b/src/libGLESv2/FramebufferAttachment.h
@@ -10,12 +10,18 @@
 #ifndef LIBGLESV2_FRAMEBUFFERATTACHMENT_H_
 #define LIBGLESV2_FRAMEBUFFERATTACHMENT_H_
 
+#include "libGLESv2/Texture.h"
+
 #include "common/angleutils.h"
 #include "common/RefCountObject.h"
-#include "Texture.h"
 
 #include "angle_gl.h"
 
+namespace rx
+{
+class DefaultAttachmentImpl;
+}
+
 namespace gl
 {
 class Renderbuffer;
@@ -41,10 +47,9 @@
     GLuint getStencilSize() const;
     GLenum getComponentType() const;
     GLenum getColorEncoding() const;
-    bool isTexture() const;
 
-    bool isTextureWithId(GLuint textureId) const { return isTexture() && id() == textureId; }
-    bool isRenderbufferWithId(GLuint renderbufferId) const { return !isTexture() && id() == renderbufferId; }
+    bool isTextureWithId(GLuint textureId) const { return type() == GL_TEXTURE && id() == textureId; }
+    bool isRenderbufferWithId(GLuint renderbufferId) const { return type() == GL_RENDERBUFFER && id() == renderbufferId; }
 
     GLenum getBinding() const { return mBinding; }
 
@@ -58,6 +63,7 @@
     virtual GLuint id() const = 0;
     virtual GLenum type() const = 0;
     virtual GLint mipLevel() const = 0;
+    virtual GLenum cubeMapFace() const = 0;
     virtual GLint layer() const = 0;
 
     virtual Texture *getTexture() = 0;
@@ -86,6 +92,7 @@
 
     virtual GLenum type() const;
     virtual GLint mipLevel() const;
+    virtual GLenum cubeMapFace() const;
     virtual GLint layer() const;
 
     virtual Texture *getTexture();
@@ -115,6 +122,7 @@
     virtual GLuint id() const;
     virtual GLenum type() const;
     virtual GLint mipLevel() const;
+    virtual GLenum cubeMapFace() const;
     virtual GLint layer() const;
 
     virtual Texture *getTexture();
@@ -127,6 +135,37 @@
     BindingPointer<Renderbuffer> mRenderbuffer;
 };
 
+class DefaultAttachment : public FramebufferAttachment
+{
+  public:
+    DefaultAttachment(GLenum binding, rx::DefaultAttachmentImpl *impl);
+
+    virtual ~DefaultAttachment();
+
+    virtual GLsizei getWidth() const;
+    virtual GLsizei getHeight() const;
+    virtual GLenum getInternalFormat() const;
+    virtual GLenum getActualFormat() const;
+    virtual GLsizei getSamples() const;
+
+    virtual GLuint id() const;
+    virtual GLenum type() const;
+    virtual GLint mipLevel() const;
+    virtual GLenum cubeMapFace() const;
+    virtual GLint layer() const;
+
+    virtual Texture *getTexture();
+    virtual const ImageIndex *getTextureImageIndex() const;
+    virtual Renderbuffer *getRenderbuffer();
+
+    rx::DefaultAttachmentImpl *getImplementation() const;
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(DefaultAttachment);
+
+    rx::DefaultAttachmentImpl *mImpl;
+};
+
 }
 
 #endif // LIBGLESV2_FRAMEBUFFERATTACHMENT_H_
diff --git a/src/libGLESv2/Renderbuffer.cpp b/src/libGLESv2/Renderbuffer.cpp
index 911a389..74ce2fa 100644
--- a/src/libGLESv2/Renderbuffer.cpp
+++ b/src/libGLESv2/Renderbuffer.cpp
@@ -22,15 +22,14 @@
 {
 Renderbuffer::Renderbuffer(rx::RenderbufferImpl *impl, GLuint id)
   : RefCountObject(id),
-    mRenderbuffer(impl)
+    mRenderbuffer(impl),
+    mWidth(0),
+    mHeight(0),
+    mInternalFormat(GL_RGBA4),
+    mActualFormat(GL_RGBA4),
+    mSamples(0)
 {
     ASSERT(mRenderbuffer);
-
-    mWidth = mRenderbuffer->getWidth();
-    mHeight = mRenderbuffer->getHeight();
-    mInternalFormat = mRenderbuffer->getInternalFormat();
-    mActualFormat = mRenderbuffer->getActualFormat();
-    mSamples = mRenderbuffer->getSamples();
 }
 
 Renderbuffer::~Renderbuffer()
diff --git a/src/libGLESv2/libGLESv2.cpp b/src/libGLESv2/libGLESv2.cpp
index b15c445..c059268 100644
--- a/src/libGLESv2/libGLESv2.cpp
+++ b/src/libGLESv2/libGLESv2.cpp
@@ -2263,11 +2263,10 @@
             break;
         }
 
-        GLuint framebufferHandle = context->getState().getTargetFramebuffer(target)->id();
-        gl::Framebuffer *framebuffer = context->getFramebuffer(framebufferHandle);
+        gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
         ASSERT(framebuffer);
 
-        if (framebufferHandle == 0)
+        if (framebuffer->id() == 0)
         {
             if (clientVersion < 3)
             {
@@ -2316,114 +2315,44 @@
             }
         }
 
-        GLenum attachmentType = GL_NONE;
-        GLuint attachmentHandle = 0;
-        GLuint attachmentLevel = 0;
-        GLuint attachmentLayer = 0;
-
         const gl::FramebufferAttachment *attachmentObject = framebuffer->getAttachment(attachment);
-
         if (attachmentObject)
         {
-            attachmentType = attachmentObject->type();
-            attachmentHandle = attachmentObject->id();
-            attachmentLevel = attachmentObject->mipLevel();
-            attachmentLayer = attachmentObject->layer();
-        }
-
-        GLenum attachmentObjectType;   // Type category
-        if (framebufferHandle == 0)
-        {
-            attachmentObjectType = GL_FRAMEBUFFER_DEFAULT;
-        }
-        else if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
-        {
-            attachmentObjectType = attachmentType;
-        }
-        else if (gl::ValidTexture2DDestinationTarget(context, attachmentType))
-        {
-            attachmentObjectType = GL_TEXTURE;
-        }
-        else
-        {
-            UNREACHABLE();
-            return;
-        }
-
-        if (attachmentObjectType == GL_NONE)
-        {
-            // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
-            // is NONE, then querying any other pname will generate INVALID_ENUM.
-
-            // ES 3.0.2 spec pg 235 states that if the attachment type is none,
-            // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
-            // INVALID_OPERATION for all other pnames
+            ASSERT(attachmentObject->type() == GL_RENDERBUFFER ||
+                   attachmentObject->type() == GL_TEXTURE ||
+                   attachmentObject->type() == GL_FRAMEBUFFER_DEFAULT);
 
             switch (pname)
             {
               case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
-                *params = attachmentObjectType;
+                *params = attachmentObject->type();
                 break;
 
               case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
-                if (clientVersion < 3)
+                if (attachmentObject->type() != GL_RENDERBUFFER && attachmentObject->type() != GL_TEXTURE)
                 {
                     context->recordError(gl::Error(GL_INVALID_ENUM));
                     return;
                 }
-                *params = 0;
-                break;
-
-              default:
-                if (clientVersion < 3)
-                {
-                    context->recordError(gl::Error(GL_INVALID_ENUM));
-                    return;
-                }
-                else
-                {
-                    context->recordError(gl::Error(GL_INVALID_OPERATION));
-                    return;
-                }
-            }
-        }
-        else
-        {
-            ASSERT(attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE ||
-                   attachmentObjectType == GL_FRAMEBUFFER_DEFAULT);
-            ASSERT(attachmentObject != NULL);
-
-            switch (pname)
-            {
-              case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
-                *params = attachmentObjectType;
-                break;
-
-              case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
-                if (attachmentObjectType != GL_RENDERBUFFER && attachmentObjectType != GL_TEXTURE)
-                {
-                    context->recordError(gl::Error(GL_INVALID_ENUM));
-                    return;
-                }
-                *params = attachmentHandle;
+                *params = attachmentObject->id();
                 break;
 
               case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
-                if (attachmentObjectType != GL_TEXTURE)
+                if (attachmentObject->type() != GL_TEXTURE)
                 {
                     context->recordError(gl::Error(GL_INVALID_ENUM));
                     return;
                 }
-                *params = attachmentLevel;
+                *params = attachmentObject->mipLevel();
                 break;
 
               case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
-                if (attachmentObjectType != GL_TEXTURE)
+                if (attachmentObject->type() != GL_TEXTURE)
                 {
                     context->recordError(gl::Error(GL_INVALID_ENUM));
                     return;
                 }
-                *params = gl::IsCubemapTextureTarget(attachmentType) ? attachmentType : 0;
+                *params = attachmentObject->cubeMapFace();
                 break;
 
               case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
@@ -2464,12 +2393,12 @@
                 break;
 
               case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
-                if (attachmentObjectType != GL_TEXTURE)
+                if (attachmentObject->type() != GL_TEXTURE)
                 {
                     context->recordError(gl::Error(GL_INVALID_ENUM));
                     return;
                 }
-                *params = attachmentLayer;
+                *params = attachmentObject->layer();
                 break;
 
               default:
@@ -2477,6 +2406,43 @@
                 break;
             }
         }
+        else
+        {
+            // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
+            // is NONE, then querying any other pname will generate INVALID_ENUM.
+
+            // ES 3.0.2 spec pg 235 states that if the attachment type is none,
+            // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
+            // INVALID_OPERATION for all other pnames
+
+            switch (pname)
+            {
+              case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+                *params = GL_NONE;
+                break;
+
+              case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+                if (clientVersion < 3)
+                {
+                    context->recordError(gl::Error(GL_INVALID_ENUM));
+                    return;
+                }
+                *params = 0;
+                break;
+
+              default:
+                if (clientVersion < 3)
+                {
+                    context->recordError(gl::Error(GL_INVALID_ENUM));
+                    return;
+                }
+                else
+                {
+                    context->recordError(gl::Error(GL_INVALID_OPERATION));
+                    return;
+                }
+            }
+        }
     }
 }
 
diff --git a/src/libGLESv2/renderer/FramebufferImpl.h b/src/libGLESv2/renderer/FramebufferImpl.h
new file mode 100644
index 0000000..372da6e
--- /dev/null
+++ b/src/libGLESv2/renderer/FramebufferImpl.h
@@ -0,0 +1,31 @@
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// FramebufferImpl.h: Defines the abstract rx::DefaultAttachmentImpl class.
+
+#ifndef LIBGLESV2_RENDERER_FRAMBUFFERIMPL_H_
+#define LIBGLESV2_RENDERER_FRAMBUFFERIMPL_H_
+
+#include "angle_gl.h"
+
+namespace rx
+{
+
+class DefaultAttachmentImpl
+{
+  public:
+    virtual ~DefaultAttachmentImpl() {};
+
+    virtual GLsizei getWidth() const = 0;
+    virtual GLsizei getHeight() const = 0;
+    virtual GLenum getInternalFormat() const = 0;
+    virtual GLenum getActualFormat() const = 0;
+    virtual GLsizei getSamples() const = 0;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_FRAMBUFFERIMPL_H_
diff --git a/src/libGLESv2/renderer/RenderbufferImpl.h b/src/libGLESv2/renderer/RenderbufferImpl.h
index 52e070f..9f217d7 100644
--- a/src/libGLESv2/renderer/RenderbufferImpl.h
+++ b/src/libGLESv2/renderer/RenderbufferImpl.h
@@ -26,11 +26,7 @@
 
     virtual gl::Error setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples) = 0;
 
-    virtual GLsizei getWidth() const = 0;
-    virtual GLsizei getHeight() const = 0;
-    virtual GLenum getInternalFormat() const = 0;
     virtual GLenum getActualFormat() const = 0;
-    virtual GLsizei getSamples() const = 0;
 
   private:
     DISALLOW_COPY_AND_ASSIGN(RenderbufferImpl);
diff --git a/src/libGLESv2/renderer/Renderer.h b/src/libGLESv2/renderer/Renderer.h
index 9e6b9e4..dc2c29b 100644
--- a/src/libGLESv2/renderer/Renderer.h
+++ b/src/libGLESv2/renderer/Renderer.h
@@ -31,6 +31,7 @@
 namespace egl
 {
 class Display;
+class Surface;
 }
 
 namespace gl
@@ -52,6 +53,7 @@
 class TextureImpl;
 class TransformFeedbackImpl;
 class RenderbufferImpl;
+class DefaultAttachmentImpl;
 struct TranslatedIndexData;
 struct Workarounds;
 class SwapChain;
@@ -111,12 +113,14 @@
     // Shader operations
     virtual void releaseShaderCompiler() = 0;
 
+    // Framebuffer creation
+    virtual DefaultAttachmentImpl *createDefaultAttachment(GLenum type, egl::Surface *surface) = 0;
+
     // Texture creation
     virtual TextureImpl *createTexture(GLenum target) = 0;
 
     // Renderbuffer creation
     virtual RenderbufferImpl *createRenderbuffer() = 0;
-    virtual RenderbufferImpl *createRenderbuffer(SwapChain *swapChain, bool depth) = 0;
 
     // Buffer creation
     virtual BufferImpl *createBuffer() = 0;
diff --git a/src/libGLESv2/renderer/d3d/FramebufferD3D.cpp b/src/libGLESv2/renderer/d3d/FramebufferD3D.cpp
new file mode 100644
index 0000000..03a3029
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/FramebufferD3D.cpp
@@ -0,0 +1,62 @@
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Framebuffer11.h: Implements the DefaultAttachment11 class.
+
+#include "libGLESv2/renderer/d3d/FramebufferD3D.h"
+#include "libGLESv2/renderer/RenderTarget.h"
+
+namespace rx
+{
+
+DefaultAttachmentD3D::DefaultAttachmentD3D(RenderTarget *renderTarget)
+    : mRenderTarget(renderTarget)
+{
+    ASSERT(mRenderTarget);
+}
+
+DefaultAttachmentD3D::~DefaultAttachmentD3D()
+{
+    SafeDelete(mRenderTarget);
+}
+
+DefaultAttachmentD3D *DefaultAttachmentD3D::makeDefaultAttachmentD3D(DefaultAttachmentImpl* impl)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(DefaultAttachmentD3D*, impl));
+    return static_cast<DefaultAttachmentD3D*>(impl);
+}
+
+GLsizei DefaultAttachmentD3D::getWidth() const
+{
+    return mRenderTarget->getWidth();
+}
+
+GLsizei DefaultAttachmentD3D::getHeight() const
+{
+    return mRenderTarget->getHeight();
+}
+
+GLenum DefaultAttachmentD3D::getInternalFormat() const
+{
+    return mRenderTarget->getInternalFormat();
+}
+
+GLenum DefaultAttachmentD3D::getActualFormat() const
+{
+    return mRenderTarget->getActualFormat();
+}
+
+GLsizei DefaultAttachmentD3D::getSamples() const
+{
+    return mRenderTarget->getSamples();
+}
+
+RenderTarget *DefaultAttachmentD3D::getRenderTarget() const
+{
+    return mRenderTarget;
+}
+
+}
diff --git a/src/libGLESv2/renderer/d3d/FramebufferD3D.h b/src/libGLESv2/renderer/d3d/FramebufferD3D.h
new file mode 100644
index 0000000..0034e07
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/FramebufferD3D.h
@@ -0,0 +1,40 @@
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// FramebufferD3D.h: Defines the DefaultAttachmentD3D class.
+
+#ifndef LIBGLESV2_RENDERER_FRAMBUFFERD3D_H_
+#define LIBGLESV2_RENDERER_FRAMBUFFERD3D_H_
+
+#include "libGLESv2/renderer/FramebufferImpl.h"
+
+namespace rx
+{
+class RenderTarget;
+
+class DefaultAttachmentD3D : public DefaultAttachmentImpl
+{
+  public:
+    DefaultAttachmentD3D(RenderTarget *renderTarget);
+    virtual ~DefaultAttachmentD3D();
+
+    static DefaultAttachmentD3D *makeDefaultAttachmentD3D(DefaultAttachmentImpl* impl);
+
+    virtual GLsizei getWidth() const override;
+    virtual GLsizei getHeight() const override;
+    virtual GLenum getInternalFormat() const override;
+    virtual GLenum getActualFormat() const override;
+    virtual GLsizei getSamples() const override;
+
+    RenderTarget *getRenderTarget() const;
+
+  private:
+    RenderTarget *mRenderTarget;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_FRAMBUFFERD3D_H_
diff --git a/src/libGLESv2/renderer/d3d/RenderbufferD3D.cpp b/src/libGLESv2/renderer/d3d/RenderbufferD3D.cpp
index cb4af36..6859a79 100644
--- a/src/libGLESv2/renderer/d3d/RenderbufferD3D.cpp
+++ b/src/libGLESv2/renderer/d3d/RenderbufferD3D.cpp
@@ -55,46 +55,11 @@
     return gl::Error(GL_NO_ERROR);
 }
 
-gl::Error RenderbufferD3D::setStorage(SwapChain *swapChain, bool depth)
-{
-    RenderTarget *newRT = NULL;
-    gl::Error error = mRenderer->createRenderTarget(swapChain, depth, &newRT);
-    if (error.isError())
-    {
-        return error;
-    }
-
-    SafeDelete(mRenderTarget);
-    mRenderTarget = newRT;
-
-    return gl::Error(GL_NO_ERROR);
-}
-
-GLsizei RenderbufferD3D::getWidth() const
-{
-    return (mRenderTarget ? mRenderTarget->getWidth() : 0);
-}
-
-GLsizei RenderbufferD3D::getHeight() const
-{
-    return (mRenderTarget ? mRenderTarget->getHeight() : 0);
-}
-
-GLenum RenderbufferD3D::getInternalFormat() const
-{
-    return (mRenderTarget ? mRenderTarget->getInternalFormat() : GL_RGBA4);
-}
-
 GLenum RenderbufferD3D::getActualFormat() const
 {
     return (mRenderTarget ? mRenderTarget->getActualFormat() : GL_RGBA4);
 }
 
-GLsizei RenderbufferD3D::getSamples() const
-{
-    return (mRenderTarget ? mRenderTarget->getSamples() : 0);
-}
-
 RenderTarget *RenderbufferD3D::getRenderTarget()
 {
     return mRenderTarget;
diff --git a/src/libGLESv2/renderer/d3d/RenderbufferD3D.h b/src/libGLESv2/renderer/d3d/RenderbufferD3D.h
index 9440a44..fcc3463 100644
--- a/src/libGLESv2/renderer/d3d/RenderbufferD3D.h
+++ b/src/libGLESv2/renderer/d3d/RenderbufferD3D.h
@@ -29,13 +29,8 @@
     static RenderbufferD3D *makeRenderbufferD3D(RenderbufferImpl *renderbuffer);
 
     virtual gl::Error setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples) override;
-    gl::Error setStorage(SwapChain *swapChain, bool depth);
 
-    virtual GLsizei getWidth() const;
-    virtual GLsizei getHeight() const;
-    virtual GLenum getInternalFormat() const;
     virtual GLenum getActualFormat() const;
-    virtual GLsizei getSamples() const;
 
     RenderTarget *getRenderTarget();
     unsigned int getRenderTargetSerial() const;
diff --git a/src/libGLESv2/renderer/d3d/RendererD3D.cpp b/src/libGLESv2/renderer/d3d/RendererD3D.cpp
index 6f58243..b9314ed 100644
--- a/src/libGLESv2/renderer/d3d/RendererD3D.cpp
+++ b/src/libGLESv2/renderer/d3d/RendererD3D.cpp
@@ -537,7 +537,7 @@
     for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; i++)
     {
         gl::FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(i);
-        if (attachment && attachment->isTexture())
+        if (attachment && attachment->type() == GL_TEXTURE)
         {
             gl::Texture *texture = attachment->getTexture();
             (*outSerialArray)[serialCount++] = texture->getTextureSerial();
@@ -545,7 +545,7 @@
     }
 
     gl::FramebufferAttachment *depthStencilAttachment = drawFramebuffer->getDepthOrStencilbuffer();
-    if (depthStencilAttachment && depthStencilAttachment->isTexture())
+    if (depthStencilAttachment && depthStencilAttachment->type() == GL_TEXTURE)
     {
         gl::Texture *depthStencilTexture = depthStencilAttachment->getTexture();
         (*outSerialArray)[serialCount++] = depthStencilTexture->getTextureSerial();
diff --git a/src/libGLESv2/renderer/d3d/RendererD3D.h b/src/libGLESv2/renderer/d3d/RendererD3D.h
index 9919207..a8c2f21 100644
--- a/src/libGLESv2/renderer/d3d/RendererD3D.h
+++ b/src/libGLESv2/renderer/d3d/RendererD3D.h
@@ -116,7 +116,6 @@
                                  GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) = 0;
 
     // RenderTarget creation
-    virtual gl::Error createRenderTarget(SwapChain *swapChain, bool depth, RenderTarget **outRT) = 0;
     virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT) = 0;
 
     // Shader operations
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
index 13f1e08..4f31099 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
@@ -16,6 +16,7 @@
 #include "libGLESv2/renderer/d3d/ShaderD3D.h"
 #include "libGLESv2/renderer/d3d/TextureD3D.h"
 #include "libGLESv2/renderer/d3d/TransformFeedbackD3D.h"
+#include "libGLESv2/renderer/d3d/FramebufferD3D.h"
 #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
 #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
 #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
@@ -40,6 +41,7 @@
 #include "libGLESv2/renderer/d3d/RenderbufferD3D.h"
 
 #include "libEGL/Display.h"
+#include "libEGL/Surface.h"
 
 #include "common/utilities.h"
 #include "common/tls.h"
@@ -977,7 +979,7 @@
             }
 
             // Unbind render target SRVs from the shader here to prevent D3D11 warnings.
-            if (colorbuffer->isTexture())
+            if (colorbuffer->type() == GL_TEXTURE)
             {
                 ID3D11Resource *renderTargetResource = renderTarget->getTexture();
                 const gl::ImageIndex *index = colorbuffer->getTextureImageIndex();
@@ -2269,13 +2271,6 @@
     }
 }
 
-gl::Error Renderer11::createRenderTarget(SwapChain *swapChain, bool depth, RenderTarget **outRT)
-{
-    SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain);
-    *outRT = new SurfaceRenderTarget11(swapChain11, depth);
-    return gl::Error(GL_NO_ERROR);
-}
-
 gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT)
 {
     const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(format);
@@ -2410,6 +2405,40 @@
     return gl::Error(GL_NO_ERROR);
 }
 
+DefaultAttachmentImpl *Renderer11::createDefaultAttachment(GLenum type, egl::Surface *surface)
+{
+    SwapChain11 *swapChain = SwapChain11::makeSwapChain11(surface->getSwapChain());
+    switch (type)
+    {
+      case GL_BACK:
+        return new DefaultAttachmentD3D(new SurfaceRenderTarget11(swapChain, false));
+
+      case GL_DEPTH:
+        if (gl::GetInternalFormatInfo(swapChain->GetDepthBufferInternalFormat()).depthBits > 0)
+        {
+            return new DefaultAttachmentD3D(new SurfaceRenderTarget11(swapChain, true));
+        }
+        else
+        {
+            return NULL;
+        }
+
+      case GL_STENCIL:
+        if (gl::GetInternalFormatInfo(swapChain->GetDepthBufferInternalFormat()).stencilBits > 0)
+        {
+            return new DefaultAttachmentD3D(new SurfaceRenderTarget11(swapChain, true));
+        }
+        else
+        {
+            return NULL;
+        }
+
+      default:
+        UNREACHABLE();
+        return NULL;
+    }
+}
+
 ShaderImpl *Renderer11::createShader(const gl::Data &data, GLenum type)
 {
     return new ShaderD3D(data, type, this);
@@ -2913,13 +2942,6 @@
     return renderbuffer;
 }
 
-RenderbufferImpl *Renderer11::createRenderbuffer(SwapChain *swapChain, bool depth)
-{
-    RenderbufferD3D *renderbuffer = new RenderbufferD3D(this);
-    renderbuffer->setStorage(swapChain, depth);
-    return renderbuffer;
-}
-
 gl::Error Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format,
                                       GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels)
 {
@@ -3321,7 +3343,7 @@
 
 void Renderer11::invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *attachment, int mipLevel)
 {
-    ASSERT(attachment->isTexture());
+    ASSERT(attachment->type() == GL_TEXTURE);
     gl::Texture *texture = attachment->getTexture();
 
     TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
@@ -3344,20 +3366,20 @@
     for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
     {
         gl::FramebufferAttachment *attachment = framebuffer->getColorbuffer(colorAttachment);
-        if (attachment && attachment->isTexture())
+        if (attachment && attachment->type() == GL_TEXTURE)
         {
             invalidateFBOAttachmentSwizzles(attachment, attachment->mipLevel());
         }
     }
 
     gl::FramebufferAttachment *depthAttachment = framebuffer->getDepthbuffer();
-    if (depthAttachment && depthAttachment->isTexture())
+    if (depthAttachment && depthAttachment->type() == GL_TEXTURE)
     {
         invalidateFBOAttachmentSwizzles(depthAttachment, depthAttachment->mipLevel());
     }
 
     gl::FramebufferAttachment *stencilAttachment = framebuffer->getStencilbuffer();
-    if (stencilAttachment && stencilAttachment->isTexture())
+    if (stencilAttachment && stencilAttachment->type() == GL_TEXTURE)
     {
         invalidateFBOAttachmentSwizzles(stencilAttachment, stencilAttachment->mipLevel());
     }
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
index b525c3b..eaa6fc5 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
+++ b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
@@ -136,9 +136,11 @@
                                  GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels);
 
     // RenderTarget creation
-    virtual gl::Error createRenderTarget(SwapChain *swapChain, bool depth, RenderTarget **outRT);
     virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT);
 
+    // Framebuffer creation
+    virtual DefaultAttachmentImpl *createDefaultAttachment(GLenum type, egl::Surface *surface) override;
+
     // Shader creation
     virtual ShaderImpl *createShader(const gl::Data &data, GLenum type);
     virtual ProgramImpl *createProgram();
@@ -168,7 +170,6 @@
 
     // Renderbuffer creation
     virtual RenderbufferImpl *createRenderbuffer();
-    virtual RenderbufferImpl *createRenderbuffer(SwapChain *swapChain, bool depth);
 
     // Buffer creation
     virtual BufferImpl *createBuffer();
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
index 0398a41..d84486b 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
@@ -27,6 +27,7 @@
 #include "libGLESv2/renderer/d3d/TextureD3D.h"
 #include "libGLESv2/renderer/d3d/TransformFeedbackD3D.h"
 #include "libGLESv2/renderer/d3d/RenderbufferD3D.h"
+#include "libGLESv2/renderer/d3d/FramebufferD3D.h"
 #include "libGLESv2/main.h"
 #include "libGLESv2/Buffer.h"
 #include "libGLESv2/Texture.h"
@@ -38,6 +39,7 @@
 #include "libGLESv2/angletypes.h"
 
 #include "libEGL/Display.h"
+#include "libEGL/Surface.h"
 
 #include "common/features.h"
 #include "common/utilities.h"
@@ -2811,13 +2813,6 @@
     return gl::Error(GL_NO_ERROR);
 }
 
-gl::Error Renderer9::createRenderTarget(SwapChain *swapChain, bool depth, RenderTarget **outRT)
-{
-    SwapChain9 *swapChain9 = SwapChain9::makeSwapChain9(swapChain);
-    *outRT = new SurfaceRenderTarget9(swapChain9, depth);
-    return gl::Error(GL_NO_ERROR);
-}
-
 gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT)
 {
     const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(format);
@@ -2869,6 +2864,40 @@
     return gl::Error(GL_NO_ERROR);
 }
 
+DefaultAttachmentImpl *Renderer9::createDefaultAttachment(GLenum type, egl::Surface *surface)
+{
+    SwapChain9 *swapChain = SwapChain9::makeSwapChain9(surface->getSwapChain());
+    switch (type)
+    {
+      case GL_BACK:
+        return new DefaultAttachmentD3D(new SurfaceRenderTarget9(swapChain, false));
+
+      case GL_DEPTH:
+        if (gl::GetInternalFormatInfo(swapChain->GetDepthBufferInternalFormat()).depthBits > 0)
+        {
+            return new DefaultAttachmentD3D(new SurfaceRenderTarget9(swapChain, true));
+        }
+        else
+        {
+            return NULL;
+        }
+
+      case GL_STENCIL:
+        if (gl::GetInternalFormatInfo(swapChain->GetDepthBufferInternalFormat()).stencilBits > 0)
+        {
+            return new DefaultAttachmentD3D(new SurfaceRenderTarget9(swapChain, true));
+        }
+        else
+        {
+            return NULL;
+        }
+
+      default:
+        UNREACHABLE();
+        return NULL;
+    }
+}
+
 ShaderImpl *Renderer9::createShader(const gl::Data &data, GLenum type)
 {
     return new ShaderD3D(data, type, this);
@@ -3134,13 +3163,6 @@
     return renderbuffer;
 }
 
-RenderbufferImpl *Renderer9::createRenderbuffer(SwapChain *swapChain, bool depth)
-{
-    RenderbufferD3D *renderbuffer = new RenderbufferD3D(this);
-    renderbuffer->setStorage(swapChain, depth);
-    return renderbuffer;
-}
-
 bool Renderer9::getLUID(LUID *adapterLuid) const
 {
     adapterLuid->HighPart = 0;
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h
index 10d2fb1..d5d4870 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h
+++ b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h
@@ -142,9 +142,11 @@
                                  GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels);
 
     // RenderTarget creation
-    virtual gl::Error createRenderTarget(SwapChain *swapChain, bool depth, RenderTarget **outRT);
     virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT);
 
+    // Framebuffer creation
+    virtual DefaultAttachmentImpl *createDefaultAttachment(GLenum type, egl::Surface *surface) override;
+
     // Shader creation
     virtual ShaderImpl *createShader(const gl::Data &data, GLenum type);
     virtual ProgramImpl *createProgram();
@@ -174,7 +176,6 @@
 
     // Renderbuffer creation
     virtual RenderbufferImpl *createRenderbuffer();
-    virtual RenderbufferImpl *createRenderbuffer(SwapChain *swapChain, bool depth);
 
     // Buffer creation
     virtual BufferImpl *createBuffer();
diff --git a/src/libGLESv2/validationES.cpp b/src/libGLESv2/validationES.cpp
index 382653f..f857ee9 100644
--- a/src/libGLESv2/validationES.cpp
+++ b/src/libGLESv2/validationES.cpp
@@ -573,8 +573,11 @@
 
             if (fromAngleExtension)
             {
-                const GLenum readColorbufferType = readFramebuffer->getReadColorbufferType();
-                if (readColorbufferType != GL_TEXTURE_2D && readColorbufferType != GL_RENDERBUFFER)
+                FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
+                if (!readColorAttachment ||
+                    (!(readColorAttachment->type() == GL_TEXTURE && readColorAttachment->getTextureImageIndex()->type == GL_TEXTURE_2D) &&
+                    readColorAttachment->type() != GL_RENDERBUFFER &&
+                    readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT))
                 {
                     context->recordError(Error(GL_INVALID_OPERATION));
                     return false;
@@ -587,7 +590,9 @@
                         FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(colorAttachment);
                         ASSERT(attachment);
 
-                        if (attachment->type() != GL_TEXTURE_2D && attachment->type() != GL_RENDERBUFFER)
+                        if (!(attachment->type() == GL_TEXTURE && attachment->getTextureImageIndex()->type == GL_TEXTURE_2D) &&
+                            attachment->type() != GL_RENDERBUFFER &&
+                            attachment->type() != GL_FRAMEBUFFER_DEFAULT)
                         {
                             context->recordError(Error(GL_INVALID_OPERATION));
                             return false;