MANGLE egl::Display.
BUG=angle:794
Change-Id: Id131f3119100030d6ee630e357a8d28396a6a813
Reviewed-on: https://chromium-review.googlesource.com/231852
Tested-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/renderer/DisplayImpl.cpp b/src/libANGLE/renderer/DisplayImpl.cpp
new file mode 100644
index 0000000..8da133c
--- /dev/null
+++ b/src/libANGLE/renderer/DisplayImpl.cpp
@@ -0,0 +1,30 @@
+//
+// Copyright (c) 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.
+//
+
+// DisplayImpl.cpp: Implementation methods of egl::Display
+
+#include "libANGLE/renderer/DisplayImpl.h"
+
+#include "libANGLE/Surface.h"
+
+namespace rx
+{
+
+DisplayImpl::~DisplayImpl()
+{
+ while (!mSurfaceSet.empty())
+ {
+ destroySurface(*mSurfaceSet.begin());
+ }
+}
+
+void DisplayImpl::destroySurface(egl::Surface *surface)
+{
+ mSurfaceSet.erase(surface);
+ SafeDelete(surface);
+}
+
+}
diff --git a/src/libANGLE/renderer/DisplayImpl.h b/src/libANGLE/renderer/DisplayImpl.h
new file mode 100644
index 0000000..34f6e50
--- /dev/null
+++ b/src/libANGLE/renderer/DisplayImpl.h
@@ -0,0 +1,59 @@
+//
+// Copyright (c) 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.
+//
+
+// DisplayImpl.h: Implementation methods of egl::Display
+
+#ifndef LIBANGLE_RENDERER_DISPLAYIMPL_H_
+#define LIBANGLE_RENDERER_DISPLAYIMPL_H_
+
+#include "common/angleutils.h"
+#include "libANGLE/Error.h"
+
+#include <set>
+
+namespace egl
+{
+class Display;
+class Config;
+class Surface;
+}
+
+namespace rx
+{
+class SurfaceImpl;
+
+class DisplayImpl
+{
+ public:
+ DisplayImpl() {}
+ virtual ~DisplayImpl();
+
+ virtual SurfaceImpl *createWindowSurface(egl::Display *display, const egl::Config *config,
+ EGLNativeWindowType window, EGLint fixedSize,
+ EGLint width, EGLint height, EGLint postSubBufferSupported) = 0;
+ virtual SurfaceImpl *createOffscreenSurface(egl::Display *display, const egl::Config *config,
+ EGLClientBuffer shareHandle, EGLint width, EGLint height,
+ EGLenum textureFormat, EGLenum textureTarget) = 0;
+ virtual egl::Error restoreLostDevice() = 0;
+
+ typedef std::set<egl::Surface*> SurfaceSet;
+ const SurfaceSet &getSurfaceSet() const { return mSurfaceSet; }
+ SurfaceSet &getSurfaceSet() { return mSurfaceSet; }
+
+ void destroySurface(egl::Surface *surface);
+
+ protected:
+ // Place the surface set here so it can be accessible for handling
+ // context loss events. (It is shared between the Display and Impl.)
+ SurfaceSet mSurfaceSet;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DisplayImpl);
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_DISPLAYIMPL_H_
diff --git a/src/libANGLE/renderer/Renderer.h b/src/libANGLE/renderer/Renderer.h
index 9d91914..ac16544 100644
--- a/src/libANGLE/renderer/Renderer.h
+++ b/src/libANGLE/renderer/Renderer.h
@@ -58,6 +58,7 @@
struct TranslatedIndexData;
struct Workarounds;
class SwapChain;
+class DisplayImpl;
struct ConfigDesc
{
@@ -76,7 +77,6 @@
virtual ~Renderer();
virtual EGLint initialize() = 0;
- virtual bool resetDevice() = 0;
virtual int generateConfigs(ConfigDesc **configDescList) = 0;
virtual void deleteConfigs(ConfigDesc *configDescList) = 0;
@@ -161,6 +161,8 @@
virtual int getMinSwapInterval() const = 0;
virtual int getMaxSwapInterval() const = 0;
+ virtual DisplayImpl *createDisplay() = 0;
+
private:
DISALLOW_COPY_AND_ASSIGN(Renderer);
diff --git a/src/libANGLE/renderer/d3d/DisplayD3D.cpp b/src/libANGLE/renderer/d3d/DisplayD3D.cpp
new file mode 100644
index 0000000..2c9866d
--- /dev/null
+++ b/src/libANGLE/renderer/d3d/DisplayD3D.cpp
@@ -0,0 +1,68 @@
+//
+// Copyright (c) 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.
+//
+
+// DisplayD3D.cpp: D3D implementation of egl::Display
+
+#include "libANGLE/renderer/d3d/DisplayD3D.h"
+
+#include "libANGLE/Surface.h"
+#include "libANGLE/renderer/SwapChain.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+#include "libANGLE/renderer/d3d/SurfaceD3D.h"
+
+namespace rx
+{
+
+SurfaceImpl *DisplayD3D::createWindowSurface(egl::Display *display, const egl::Config *config,
+ EGLNativeWindowType window, EGLint fixedSize,
+ EGLint width, EGLint height, EGLint postSubBufferSupported)
+{
+ return SurfaceD3D::createFromWindow(display, config, window, fixedSize,
+ width, height, postSubBufferSupported);
+}
+
+SurfaceImpl *DisplayD3D::createOffscreenSurface(egl::Display *display, const egl::Config *config,
+ EGLClientBuffer shareHandle, EGLint width, EGLint height,
+ EGLenum textureFormat, EGLenum textureTarget)
+{
+ return SurfaceD3D::createOffscreen(display, config, shareHandle,
+ width, height, textureFormat, textureTarget);
+}
+
+egl::Error DisplayD3D::restoreLostDevice()
+{
+ // Release surface resources to make the Reset() succeed
+ for (auto &surface : mSurfaceSet)
+ {
+ if (surface->getBoundTexture())
+ {
+ surface->releaseTexImage(EGL_BACK_BUFFER);
+ }
+ SurfaceD3D *surfaceD3D = SurfaceD3D::makeSurfaceD3D(surface);
+ surfaceD3D->releaseSwapChain();
+ }
+
+ if (!mRenderer->resetDevice())
+ {
+ return egl::Error(EGL_BAD_ALLOC);
+ }
+
+ // Restore any surfaces that may have been lost
+ for (const auto &surface : mSurfaceSet)
+ {
+ SurfaceD3D *surfaceD3D = SurfaceD3D::makeSurfaceD3D(surface);
+
+ egl::Error error = surfaceD3D->resetSwapChain();
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+}
diff --git a/src/libANGLE/renderer/d3d/DisplayD3D.h b/src/libANGLE/renderer/d3d/DisplayD3D.h
new file mode 100644
index 0000000..7716d56
--- /dev/null
+++ b/src/libANGLE/renderer/d3d/DisplayD3D.h
@@ -0,0 +1,38 @@
+//
+// Copyright (c) 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.
+//
+
+// DisplayD3D.h: D3D implementation of egl::Display
+
+#ifndef LIBANGLE_RENDERER_D3D_DISPLAYD3D_H_
+#define LIBANGLE_RENDERER_D3D_DISPLAYD3D_H_
+
+#include "libANGLE/renderer/DisplayImpl.h"
+
+namespace rx
+{
+class RendererD3D;
+
+class DisplayD3D : public DisplayImpl
+{
+ public:
+ DisplayD3D(rx::RendererD3D *renderer) {}
+ SurfaceImpl *createWindowSurface(egl::Display *display, const egl::Config *config,
+ EGLNativeWindowType window, EGLint fixedSize,
+ EGLint width, EGLint height, EGLint postSubBufferSupported) override;
+ SurfaceImpl *createOffscreenSurface(egl::Display *display, const egl::Config *config,
+ EGLClientBuffer shareHandle, EGLint width, EGLint height,
+ EGLenum textureFormat, EGLenum textureTarget) override;
+ egl::Error restoreLostDevice() override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DisplayD3D);
+
+ rx::RendererD3D *mRenderer;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_D3D_DISPLAYD3D_H_
diff --git a/src/libANGLE/renderer/d3d/RendererD3D.cpp b/src/libANGLE/renderer/d3d/RendererD3D.cpp
index 8312b8a..d5d729b 100644
--- a/src/libANGLE/renderer/d3d/RendererD3D.cpp
+++ b/src/libANGLE/renderer/d3d/RendererD3D.cpp
@@ -16,6 +16,7 @@
#include "libANGLE/State.h"
#include "libANGLE/VertexArray.h"
#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/d3d/DisplayD3D.h"
#include "libANGLE/renderer/d3d/IndexDataManager.h"
namespace rx
@@ -824,4 +825,9 @@
return std::string("");
}
+DisplayImpl *RendererD3D::createDisplay()
+{
+ return new DisplayD3D(this);
+}
+
}
diff --git a/src/libANGLE/renderer/d3d/RendererD3D.h b/src/libANGLE/renderer/d3d/RendererD3D.h
index 6df0487..d0b6ba9 100644
--- a/src/libANGLE/renderer/d3d/RendererD3D.h
+++ b/src/libANGLE/renderer/d3d/RendererD3D.h
@@ -69,6 +69,8 @@
bool isDeviceLost() const override;
std::string getVendorString() const override;
+ DisplayImpl *createDisplay() override;
+
// Direct3D Specific methods
virtual GUID getAdapterIdentifier() const = 0;
@@ -155,7 +157,9 @@
virtual VertexBuffer *createVertexBuffer() = 0;
virtual IndexBuffer *createIndexBuffer() = 0;
+ // Device lost
void notifyDeviceLost() override;
+ virtual bool resetDevice() = 0;
protected:
virtual gl::Error drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive) = 0;