Refactor DefaultAttachments.

Instead of using an Impl type for default attachments, store the
egl::Surface pointer where possible.

BUG=angleproject:963

Change-Id: I3e34849e8b1ccae0c91a79617ec6f64aaaab6b10
Reviewed-on: https://chromium-review.googlesource.com/263483
Tested-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/Framebuffer.cpp b/src/libANGLE/Framebuffer.cpp
index 7e27bb7..5fa7513 100644
--- a/src/libANGLE/Framebuffer.cpp
+++ b/src/libANGLE/Framebuffer.cpp
@@ -8,18 +8,20 @@
 // objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.
 
 #include "libANGLE/Framebuffer.h"
-#include "libANGLE/formatutils.h"
-#include "libANGLE/Texture.h"
+
+#include "common/utilities.h"
+#include "libANGLE/Config.h"
 #include "libANGLE/Context.h"
-#include "libANGLE/Renderbuffer.h"
 #include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/Renderbuffer.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/formatutils.h"
 #include "libANGLE/renderer/FramebufferImpl.h"
 #include "libANGLE/renderer/ImplFactory.h"
 #include "libANGLE/renderer/RenderbufferImpl.h"
 #include "libANGLE/renderer/Workarounds.h"
 
-#include "common/utilities.h"
-
 namespace gl
 {
 
@@ -633,20 +635,17 @@
 DefaultFramebuffer::DefaultFramebuffer(const Caps &caps, rx::ImplFactory *factory, egl::Surface *surface)
     : Framebuffer(caps, factory, 0)
 {
-    rx::DefaultAttachmentImpl *colorAttachment = factory->createDefaultAttachment(GL_BACK, surface);
-    rx::DefaultAttachmentImpl *depthAttachment = factory->createDefaultAttachment(GL_DEPTH, surface);
-    rx::DefaultAttachmentImpl *stencilAttachment = factory->createDefaultAttachment(GL_STENCIL, surface);
+    const egl::Config *config = surface->getConfig();
 
-    ASSERT(colorAttachment);
-    setAttachment(GL_BACK, new DefaultAttachment(GL_BACK, colorAttachment));
+    setAttachment(GL_BACK, new DefaultAttachment(GL_BACK, surface));
 
-    if (depthAttachment)
+    if (config->depthSize > 0)
     {
-        setAttachment(GL_DEPTH, new DefaultAttachment(GL_DEPTH, depthAttachment));
+        setAttachment(GL_DEPTH, new DefaultAttachment(GL_DEPTH, surface));
     }
-    if (stencilAttachment)
+    if (config->stencilSize > 0)
     {
-        setAttachment(GL_STENCIL, new DefaultAttachment(GL_STENCIL, stencilAttachment));
+        setAttachment(GL_STENCIL, new DefaultAttachment(GL_STENCIL, surface));
     }
 
     GLenum drawBufferState = GL_BACK;
diff --git a/src/libANGLE/FramebufferAttachment.cpp b/src/libANGLE/FramebufferAttachment.cpp
index 8e745d2..3c8f4af 100644
--- a/src/libANGLE/FramebufferAttachment.cpp
+++ b/src/libANGLE/FramebufferAttachment.cpp
@@ -10,7 +10,9 @@
 #include "libANGLE/FramebufferAttachment.h"
 
 #include "common/utilities.h"
+#include "libANGLE/Config.h"
 #include "libANGLE/Renderbuffer.h"
+#include "libANGLE/Surface.h"
 #include "libANGLE/Texture.h"
 #include "libANGLE/formatutils.h"
 #include "libANGLE/renderer/DefaultAttachmentImpl.h"
@@ -222,36 +224,37 @@
 }
 
 
-DefaultAttachment::DefaultAttachment(GLenum binding, rx::DefaultAttachmentImpl *impl)
-    : FramebufferAttachment(binding),
-      mImpl(impl)
+DefaultAttachment::DefaultAttachment(GLenum binding, egl::Surface *surface)
+    : FramebufferAttachment(binding)
 {
-    ASSERT(mImpl);
+    mSurface.set(surface);
 }
 
 DefaultAttachment::~DefaultAttachment()
 {
-    SafeDelete(mImpl);
+    mSurface.set(nullptr);
 }
 
 GLsizei DefaultAttachment::getWidth() const
 {
-    return mImpl->getWidth();
+    return mSurface->getWidth();
 }
 
 GLsizei DefaultAttachment::getHeight() const
 {
-    return mImpl->getHeight();
+    return mSurface->getHeight();
 }
 
 GLenum DefaultAttachment::getInternalFormat() const
 {
-    return mImpl->getInternalFormat();
+    const egl::Config *config = mSurface->getConfig();
+    return (getBinding() == GL_BACK ? config->renderTargetFormat : config->depthStencilFormat);
 }
 
 GLsizei DefaultAttachment::getSamples() const
 {
-    return mImpl->getSamples();
+    const egl::Config *config = mSurface->getConfig();
+    return config->samples;
 }
 
 GLuint DefaultAttachment::id() const
@@ -297,9 +300,4 @@
     return NULL;
 }
 
-rx::DefaultAttachmentImpl *DefaultAttachment::getImplementation() const
-{
-    return mImpl;
-}
-
 }
diff --git a/src/libANGLE/FramebufferAttachment.h b/src/libANGLE/FramebufferAttachment.h
index 277eaf9..68c0f96 100644
--- a/src/libANGLE/FramebufferAttachment.h
+++ b/src/libANGLE/FramebufferAttachment.h
@@ -129,7 +129,7 @@
 class DefaultAttachment : public FramebufferAttachment
 {
   public:
-    DefaultAttachment(GLenum binding, rx::DefaultAttachmentImpl *impl);
+    DefaultAttachment(GLenum binding, egl::Surface *surface);
 
     virtual ~DefaultAttachment();
 
@@ -148,10 +148,10 @@
     virtual const ImageIndex *getTextureImageIndex() const;
     virtual Renderbuffer *getRenderbuffer() const;
 
-    rx::DefaultAttachmentImpl *getImplementation() const;
+    const egl::Surface *getSurface() const { return mSurface.get(); }
 
   private:
-    rx::DefaultAttachmentImpl *mImpl;
+    BindingPointer<egl::Surface> mSurface;
 };
 
 }
diff --git a/src/libANGLE/renderer/d3d/FramebufferD3D.cpp b/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
index 80f64e1..26493e3 100644
--- a/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
+++ b/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
@@ -7,13 +7,17 @@
 // FramebufferD3D.cpp: Implements the DefaultAttachmentD3D and FramebufferD3D classes.
 
 #include "libANGLE/renderer/d3d/FramebufferD3D.h"
-#include "libANGLE/renderer/d3d/TextureD3D.h"
-#include "libANGLE/renderer/d3d/RendererD3D.h"
-#include "libANGLE/renderer/d3d/RenderTargetD3D.h"
-#include "libANGLE/renderer/d3d/RenderbufferD3D.h"
+
 #include "libANGLE/formatutils.h"
 #include "libANGLE/Framebuffer.h"
 #include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+#include "libANGLE/renderer/d3d/RenderbufferD3D.h"
+#include "libANGLE/renderer/d3d/RenderTargetD3D.h"
+#include "libANGLE/renderer/d3d/SurfaceD3D.h"
+#include "libANGLE/renderer/d3d/SwapChainD3D.h"
+#include "libANGLE/renderer/d3d/TextureD3D.h"
 
 namespace rx
 {
@@ -433,10 +437,19 @@
     else if (attachment->type() == GL_FRAMEBUFFER_DEFAULT)
     {
         const gl::DefaultAttachment *defaultAttachment = static_cast<const gl::DefaultAttachment *>(attachment);
-        DefaultAttachmentD3D *defaultAttachmentD3D = DefaultAttachmentD3D::makeDefaultAttachmentD3D(defaultAttachment->getImplementation());
-        ASSERT(defaultAttachmentD3D);
+        const egl::Surface *surface = defaultAttachment->getSurface();
+        ASSERT(surface);
+        const SurfaceD3D *surfaceD3D = GetImplAs<SurfaceD3D>(surface);
+        ASSERT(surfaceD3D);
 
-        *outRT = defaultAttachmentD3D->getRenderTarget();
+        if (defaultAttachment->getBinding() == GL_BACK)
+        {
+            *outRT = surfaceD3D->getSwapChain()->getColorRenderTarget();
+        }
+        else
+        {
+            *outRT = surfaceD3D->getSwapChain()->getDepthStencilRenderTarget();
+        }
         return gl::Error(GL_NO_ERROR);
     }
     else
@@ -468,9 +481,19 @@
     else if (attachment->type() == GL_FRAMEBUFFER_DEFAULT)
     {
         const gl::DefaultAttachment *defaultAttachment = static_cast<const gl::DefaultAttachment *>(attachment);
-        DefaultAttachmentD3D *defaultAttachmentD3D = DefaultAttachmentD3D::makeDefaultAttachmentD3D(defaultAttachment->getImplementation());
-        ASSERT(defaultAttachmentD3D);
-        return defaultAttachmentD3D->getRenderTarget()->getSerial();
+        const egl::Surface *surface = defaultAttachment->getSurface();
+        ASSERT(surface);
+        const SurfaceD3D *surfaceD3D = GetImplAs<SurfaceD3D>(surface);
+        ASSERT(surfaceD3D);
+
+        if (defaultAttachment->getBinding() == GL_BACK)
+        {
+            return surfaceD3D->getSwapChain()->getColorRenderTarget()->getSerial();
+        }
+        else
+        {
+            return surfaceD3D->getSwapChain()->getDepthStencilRenderTarget()->getSerial();
+        }
     }
     else
     {
diff --git a/src/libANGLE/renderer/d3d/SurfaceD3D.cpp b/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
index d412a27..a3c457d 100644
--- a/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
+++ b/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
@@ -40,7 +40,7 @@
       mFixedSize(fixedSize == EGL_TRUE),
       mRenderTargetFormat(config->renderTargetFormat),
       mDepthStencilFormat(config->depthStencilFormat),
-      mSwapChain(NULL),
+      mSwapChain(nullptr),
       mSwapIntervalDirty(true),
       mWindowSubclassed(false),
       mNativeWindow(window),
diff --git a/src/libANGLE/renderer/d3d/SurfaceD3D.h b/src/libANGLE/renderer/d3d/SurfaceD3D.h
index b8c7184..070b7cd 100644
--- a/src/libANGLE/renderer/d3d/SurfaceD3D.h
+++ b/src/libANGLE/renderer/d3d/SurfaceD3D.h
@@ -46,8 +46,8 @@
 
     EGLint isPostSubBufferSupported() const override;
 
-    // D3D implementations (some virtual to hack across DLL boundaries)
-    virtual SwapChainD3D *getSwapChain() const;
+    // D3D implementations
+    SwapChainD3D *getSwapChain() const;
 
     egl::Error resetSwapChain();
 
diff --git a/src/libANGLE/renderer/d3d/SwapChainD3D.h b/src/libANGLE/renderer/d3d/SwapChainD3D.h
index ca6e6ff..3bde92e 100644
--- a/src/libANGLE/renderer/d3d/SwapChainD3D.h
+++ b/src/libANGLE/renderer/d3d/SwapChainD3D.h
@@ -10,14 +10,14 @@
 #ifndef LIBANGLE_RENDERER_D3D_SWAPCHAIND3D_H_
 #define LIBANGLE_RENDERER_D3D_SWAPCHAIND3D_H_
 
-// TODO: move SwapChain to be d3d only
-#include "libANGLE/renderer/d3d/d3d11/NativeWindow.h"
+#include <GLES2/gl2.h>
+#include <EGL/egl.h>
 
 #include "common/angleutils.h"
 #include "common/platform.h"
 
-#include <GLES2/gl2.h>
-#include <EGL/egl.h>
+// TODO: move out of D3D11
+#include "libANGLE/renderer/d3d/d3d11/NativeWindow.h"
 
 #if !defined(ANGLE_FORCE_VSYNC_OFF)
 #define ANGLE_FORCE_VSYNC_OFF 0
@@ -25,6 +25,7 @@
 
 namespace rx
 {
+class RenderTargetD3D;
 
 class SwapChainD3D : angle::NonCopyable
 {
@@ -41,10 +42,13 @@
     virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height) = 0;
     virtual void recreate() = 0;
 
+    virtual RenderTargetD3D *getColorRenderTarget() = 0;
+    virtual RenderTargetD3D *getDepthStencilRenderTarget() = 0;
+
     GLenum GetBackBufferInternalFormat() const { return mBackBufferFormat; }
     GLenum GetDepthBufferInternalFormat() const { return mDepthBufferFormat; }
 
-    virtual HANDLE getShareHandle() {return mShareHandle;};
+    HANDLE getShareHandle() { return mShareHandle; }
 
   protected:
     rx::NativeWindow mNativeWindow;  // Handler for the Window that the surface is created for.
diff --git a/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
index ac311ae..2558528 100644
--- a/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
@@ -24,7 +24,9 @@
 SwapChain11::SwapChain11(Renderer11 *renderer, NativeWindow nativeWindow, HANDLE shareHandle,
                          GLenum backBufferFormat, GLenum depthBufferFormat)
     : mRenderer(renderer),
-      SwapChainD3D(nativeWindow, shareHandle, backBufferFormat, depthBufferFormat)
+      SwapChainD3D(nativeWindow, shareHandle, backBufferFormat, depthBufferFormat),
+      mColorRenderTarget(this, renderer, false),
+      mDepthStencilRenderTarget(this, renderer, true)
 {
     mSwapChain = NULL;
     mBackBufferTexture = NULL;
diff --git a/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h b/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h
index 031e62e..4ea6778 100644
--- a/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h
+++ b/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h
@@ -9,9 +9,9 @@
 #ifndef LIBANGLE_RENDERER_D3D_D3D11_SWAPCHAIN11_H_
 #define LIBANGLE_RENDERER_D3D_D3D11_SWAPCHAIN11_H_
 
-#include "libANGLE/renderer/d3d/SwapChainD3D.h"
-
 #include "common/angleutils.h"
+#include "libANGLE/renderer/d3d/SwapChainD3D.h"
+#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
 
 namespace rx
 {
@@ -29,6 +29,9 @@
     virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
     virtual void recreate();
 
+    RenderTargetD3D *getColorRenderTarget() override { return &mColorRenderTarget; }
+    RenderTargetD3D *getDepthStencilRenderTarget() override { return &mDepthStencilRenderTarget; }
+
     virtual ID3D11Texture2D *getOffscreenTexture();
     virtual ID3D11RenderTargetView *getRenderTarget();
     virtual ID3D11ShaderResourceView *getRenderTargetShaderResource();
@@ -73,6 +76,9 @@
     ID3D11InputLayout *mPassThroughIL;
     ID3D11VertexShader *mPassThroughVS;
     ID3D11PixelShader *mPassThroughPS;
+
+    SurfaceRenderTarget11 mColorRenderTarget;
+    SurfaceRenderTarget11 mDepthStencilRenderTarget;
 };
 
 }
diff --git a/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp b/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp
index 245282e..1620668 100644
--- a/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp
@@ -18,7 +18,9 @@
 SwapChain9::SwapChain9(Renderer9 *renderer, NativeWindow nativeWindow, HANDLE shareHandle,
                        GLenum backBufferFormat, GLenum depthBufferFormat)
     : mRenderer(renderer),
-      SwapChainD3D(nativeWindow, shareHandle, backBufferFormat, depthBufferFormat)
+      SwapChainD3D(nativeWindow, shareHandle, backBufferFormat, depthBufferFormat),
+      mColorRenderTarget(this, false),
+      mDepthStencilRenderTarget(this, true)
 {
     mSwapChain = NULL;
     mBackBuffer = NULL;
diff --git a/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h b/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h
index 8b03565..81ac08c 100644
--- a/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h
+++ b/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h
@@ -9,9 +9,9 @@
 #ifndef LIBANGLE_RENDERER_D3D_D3D9_SWAPCHAIN9_H_
 #define LIBANGLE_RENDERER_D3D_D3D9_SWAPCHAIN9_H_
 
-#include "libANGLE/renderer/d3d/SwapChainD3D.h"
-
 #include "common/angleutils.h"
+#include "libANGLE/renderer/d3d/SwapChainD3D.h"
+#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h"
 
 namespace rx
 {
@@ -29,6 +29,9 @@
     virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
     virtual void recreate();
 
+    RenderTargetD3D *getColorRenderTarget() override { return &mColorRenderTarget; }
+    RenderTargetD3D *getDepthStencilRenderTarget() override { return &mDepthStencilRenderTarget; }
+
     virtual IDirect3DSurface9 *getRenderTarget();
     virtual IDirect3DSurface9 *getDepthStencil();
     virtual IDirect3DTexture9 *getOffscreenTexture();
@@ -51,6 +54,9 @@
     IDirect3DSurface9 *mRenderTarget;
     IDirect3DSurface9 *mDepthStencil;
     IDirect3DTexture9* mOffscreenTexture;
+
+    SurfaceRenderTarget9 mColorRenderTarget;
+    SurfaceRenderTarget9 mDepthStencilRenderTarget;
 };
 
 }