Commit 5c39f688 by Geoff Lang

Have the DisplayImpl create the Renderer and Contexts.

BUG=angle:658 Change-Id: I726d87b90be8382c5dd8964e4d8686711e404ffe Reviewed-on: https://chromium-review.googlesource.com/238861Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 821f40a4
......@@ -433,6 +433,11 @@ Caps::Caps()
namespace egl
{
Caps::Caps()
: textureNPOT(false)
{
}
DisplayExtensions::DisplayExtensions()
: createContextRobustness(false),
d3dShareHandleClientBuffer(false),
......
......@@ -283,6 +283,14 @@ struct Caps
namespace egl
{
struct Caps
{
Caps();
// Support for NPOT surfaces
bool textureNPOT;
};
struct DisplayExtensions
{
DisplayExtensions();
......
......@@ -102,8 +102,6 @@ class ConfigSet
const egl::Config *get(EGLConfig configHandle);
private:
DISALLOW_COPY_AND_ASSIGN(ConfigSet);
typedef std::set<Config, SortConfig> Set;
typedef Set::iterator Iterator;
Set mSet;
......
......@@ -50,8 +50,7 @@ class Display final
Error createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList, EGLSurface *outSurface);
Error createOffscreenSurface(EGLConfig config, EGLClientBuffer shareHandle, const EGLint *attribList, EGLSurface *outSurface);
Error createContext(EGLConfig configHandle, EGLint clientVersion, const gl::Context *shareContext, bool notifyResets,
bool robustAccess, EGLContext *outContext);
Error createContext(EGLConfig configHandle, EGLContext shareContext, const egl::AttributeMap &attribs, EGLContext *outContext);
void destroySurface(egl::Surface *surface);
void destroyContext(gl::Context *context);
......@@ -64,10 +63,12 @@ class Display final
bool isValidNativeWindow(EGLNativeWindowType window) const;
bool isValidNativeDisplay(EGLNativeDisplayType display) const;
rx::Renderer *getRenderer() { return mRenderer; };
bool isDeviceLost() const;
bool testDeviceLost();
void notifyDeviceLost();
const Caps &getCaps() const;
const DisplayExtensions &getExtensions() const;
const std::string &getExtensionString() const;
const std::string &getVendorString() const;
......@@ -75,7 +76,7 @@ class Display final
private:
DISALLOW_COPY_AND_ASSIGN(Display);
Display(EGLNativeDisplayType displayId);
Display(rx::DisplayImpl *impl, EGLNativeDisplayType displayId);
void setAttributes(const AttributeMap &attribMap);
......@@ -94,7 +95,9 @@ class Display final
typedef std::set<gl::Context*> ContextSet;
ContextSet mContextSet;
rx::Renderer *mRenderer;
bool mInitialized;
Caps mCaps;
DisplayExtensions mDisplayExtensions;
std::string mDisplayExtensionString;
......
......@@ -14,7 +14,8 @@ namespace rx
{
DisplayImpl::DisplayImpl()
: mExtensionsInitialized(false)
: mExtensionsInitialized(false),
mCapsInitialized(false)
{
}
......@@ -43,4 +44,15 @@ const egl::DisplayExtensions &DisplayImpl::getExtensions() const
return mExtensions;
}
const egl::Caps &DisplayImpl::getCaps() const
{
if (!mCapsInitialized)
{
generateCaps(&mCaps);
mCapsInitialized = true;
}
return mCaps;
}
}
......@@ -18,11 +18,18 @@
namespace egl
{
class AttributeMap;
class Display;
class Config;
class ConfigSet;
class Surface;
}
namespace gl
{
class Context;
}
namespace rx
{
class SurfaceImpl;
......@@ -34,19 +41,30 @@ class DisplayImpl
DisplayImpl();
virtual ~DisplayImpl();
virtual egl::Error initialize(egl::Display *display, EGLNativeDisplayType nativeDisplay, const egl::AttributeMap &attribMap) = 0;
virtual void terminate() = 0;
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 createContext(const egl::Config *config, const gl::Context *shareContext, const egl::AttributeMap &attribs,
gl::Context **outContext) = 0;
virtual std::vector<ConfigDesc> generateConfigs() const = 0;
virtual egl::ConfigSet generateConfigs() const = 0;
virtual bool isDeviceLost() const = 0;
virtual bool testDeviceLost() = 0;
virtual egl::Error restoreLostDevice() = 0;
virtual bool isValidNativeWindow(EGLNativeWindowType window) const = 0;
const egl::Caps &getCaps() const;
virtual std::string getVendorString() const = 0;
typedef std::set<egl::Surface*> SurfaceSet;
const SurfaceSet &getSurfaceSet() const { return mSurfaceSet; }
SurfaceSet &getSurfaceSet() { return mSurfaceSet; }
......@@ -64,9 +82,13 @@ class DisplayImpl
DISALLOW_COPY_AND_ASSIGN(DisplayImpl);
virtual void generateExtensions(egl::DisplayExtensions *outExtensions) const = 0;
virtual void generateCaps(egl::Caps *outCaps) const = 0;
mutable bool mExtensionsInitialized;
mutable egl::DisplayExtensions mExtensions;
mutable bool mCapsInitialized;
mutable egl::Caps mCaps;
};
}
......
......@@ -70,8 +70,6 @@ class Renderer
Renderer();
virtual ~Renderer();
virtual EGLint initialize() = 0;
virtual gl::Error flush() = 0;
virtual gl::Error finish() = 0;
......@@ -133,8 +131,6 @@ class Renderer
virtual int getMinSwapInterval() const = 0;
virtual int getMaxSwapInterval() const = 0;
virtual DisplayImpl *createDisplay() = 0;
private:
DISALLOW_COPY_AND_ASSIGN(Renderer);
......
......@@ -8,19 +8,123 @@
#include "libANGLE/renderer/d3d/DisplayD3D.h"
#include "libANGLE/Context.h"
#include "libANGLE/Config.h"
#include "libANGLE/Surface.h"
#include "libANGLE/renderer/d3d/RendererD3D.h"
#include "libANGLE/renderer/d3d/SurfaceD3D.h"
#include "libANGLE/renderer/d3d/SwapChainD3D.h"
#include <EGL/eglext.h>
#if defined (ANGLE_ENABLE_D3D9)
# include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
#endif // ANGLE_ENABLE_D3D9
#if defined (ANGLE_ENABLE_D3D11)
# include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#endif // ANGLE_ENABLE_D3D11
#if defined (ANGLE_TEST_CONFIG)
# define ANGLE_DEFAULT_D3D11 1
#endif
#if !defined(ANGLE_DEFAULT_D3D11)
// Enables use of the Direct3D 11 API for a default display, when available
# define ANGLE_DEFAULT_D3D11 0
#endif
namespace rx
{
typedef RendererD3D *(*CreateRendererD3DFunction)(egl::Display*, EGLNativeDisplayType, const egl::AttributeMap &);
template <typename RendererType>
static RendererD3D *CreateTypedRendererD3D(egl::Display *display, EGLNativeDisplayType nativeDisplay, const egl::AttributeMap &attributes)
{
return new RendererType(display, nativeDisplay, attributes);
}
egl::Error CreateRendererD3D(egl::Display *display, EGLNativeDisplayType nativeDisplay, const egl::AttributeMap &attribMap, RendererD3D **outRenderer)
{
ASSERT(outRenderer != nullptr);
std::vector<CreateRendererD3DFunction> rendererCreationFunctions;
EGLint requestedDisplayType = attribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE);
# if defined(ANGLE_ENABLE_D3D11)
if (nativeDisplay == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ||
nativeDisplay == EGL_D3D11_ONLY_DISPLAY_ANGLE ||
requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
{
rendererCreationFunctions.push_back(CreateTypedRendererD3D<Renderer11>);
}
# endif
# if defined(ANGLE_ENABLE_D3D9)
if (nativeDisplay == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ||
requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE)
{
rendererCreationFunctions.push_back(CreateTypedRendererD3D<Renderer9>);
}
# endif
if (nativeDisplay != EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE &&
nativeDisplay != EGL_D3D11_ONLY_DISPLAY_ANGLE &&
requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE)
{
// The default display is requested, try the D3D9 and D3D11 renderers, order them using
// the definition of ANGLE_DEFAULT_D3D11
# if ANGLE_DEFAULT_D3D11
# if defined(ANGLE_ENABLE_D3D11)
rendererCreationFunctions.push_back(CreateTypedRendererD3D<Renderer11>);
# endif
# if defined(ANGLE_ENABLE_D3D9)
rendererCreationFunctions.push_back(CreateTypedRendererD3D<Renderer9>);
# endif
# else
# if defined(ANGLE_ENABLE_D3D9)
rendererCreationFunctions.push_back(CreateTypedRendererD3D<Renderer9>);
# endif
# if defined(ANGLE_ENABLE_D3D11)
rendererCreationFunctions.push_back(CreateTypedRendererD3D<Renderer11>);
# endif
# endif
}
EGLint result = EGL_NOT_INITIALIZED;
for (size_t i = 0; i < rendererCreationFunctions.size(); i++)
{
RendererD3D *renderer = rendererCreationFunctions[i](display, nativeDisplay, attribMap);
result = renderer->initialize();
if (result == EGL_SUCCESS)
{
*outRenderer = renderer;
break;
}
else
{
// Failed to create the renderer, try the next
SafeDelete(renderer);
}
}
return egl::Error(result);
}
DisplayD3D::DisplayD3D()
: mRenderer(nullptr)
{
}
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,
ASSERT(mRenderer != nullptr);
return SurfaceD3D::createFromWindow(mRenderer, display, config, window, fixedSize,
width, height, postSubBufferSupported);
}
......@@ -28,18 +132,64 @@ SurfaceImpl *DisplayD3D::createOffscreenSurface(egl::Display *display, const egl
EGLClientBuffer shareHandle, EGLint width, EGLint height,
EGLenum textureFormat, EGLenum textureTarget)
{
return SurfaceD3D::createOffscreen(display, config, shareHandle,
ASSERT(mRenderer != nullptr);
return SurfaceD3D::createOffscreen(mRenderer, display, config, shareHandle,
width, height, textureFormat, textureTarget);
}
DisplayD3D::DisplayD3D(rx::RendererD3D *renderer)
: mRenderer(renderer)
egl::Error DisplayD3D::createContext(const egl::Config *config, const gl::Context *shareContext, const egl::AttributeMap &attribs,
gl::Context **outContext)
{
ASSERT(mRenderer != nullptr);
EGLint clientVersion = attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1);
bool notifyResets = (attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_NO_RESET_NOTIFICATION_EXT) == EGL_LOSE_CONTEXT_ON_RESET_EXT);
bool robustAccess = (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE);
*outContext = new gl::Context(clientVersion, shareContext, mRenderer, notifyResets, robustAccess);
return egl::Error(EGL_SUCCESS);
}
egl::Error DisplayD3D::initialize(egl::Display *display, EGLNativeDisplayType nativeDisplay, const egl::AttributeMap &attribMap)
{
ASSERT(mRenderer == nullptr);
return CreateRendererD3D(display, nativeDisplay, attribMap, &mRenderer);
}
std::vector<ConfigDesc> DisplayD3D::generateConfigs() const
void DisplayD3D::terminate()
{
return mRenderer->generateConfigs();
SafeDelete(mRenderer);
}
egl::ConfigSet DisplayD3D::generateConfigs() const
{
ASSERT(mRenderer != nullptr);
EGLint minSwapInterval = mRenderer->getMinSwapInterval();
EGLint maxSwapInterval = mRenderer->getMaxSwapInterval();
EGLint maxTextureSize = mRenderer->getRendererCaps().max2DTextureSize;
std::vector<ConfigDesc> descList = mRenderer->generateConfigs();
egl::ConfigSet configSet;
for (size_t i = 0; i < descList.size(); ++i)
{
configSet.add(descList[i], minSwapInterval, maxSwapInterval, maxTextureSize, maxTextureSize);
}
return configSet;
}
bool DisplayD3D::isDeviceLost() const
{
ASSERT(mRenderer != nullptr);
return mRenderer->isDeviceLost();
}
bool DisplayD3D::testDeviceLost()
{
ASSERT(mRenderer != nullptr);
return mRenderer->testDeviceLost();
}
egl::Error DisplayD3D::restoreLostDevice()
......@@ -102,4 +252,23 @@ void DisplayD3D::generateExtensions(egl::DisplayExtensions *outExtensions) const
outExtensions->createContext = true;
}
std::string DisplayD3D::getVendorString() const
{
std::string vendorString = "Google Inc.";
if (mRenderer)
{
vendorString += " " + mRenderer->getVendorString();
}
return vendorString;
}
void DisplayD3D::generateCaps(egl::Caps *outCaps) const
{
// Display must be initialized to generate caps
ASSERT(mRenderer != nullptr);
outCaps->textureNPOT = mRenderer->getRendererExtensions().textureNPOT;
}
}
......@@ -18,7 +18,11 @@ class RendererD3D;
class DisplayD3D : public DisplayImpl
{
public:
DisplayD3D(rx::RendererD3D *renderer);
DisplayD3D();
egl::Error initialize(egl::Display *display, EGLNativeDisplayType nativeDisplay, const egl::AttributeMap &attribMap) override;
virtual void terminate() override;
SurfaceImpl *createWindowSurface(egl::Display *display, const egl::Config *config,
EGLNativeWindowType window, EGLint fixedSize,
EGLint width, EGLint height, EGLint postSubBufferSupported) override;
......@@ -26,16 +30,24 @@ class DisplayD3D : public DisplayImpl
EGLClientBuffer shareHandle, EGLint width, EGLint height,
EGLenum textureFormat, EGLenum textureTarget) override;
std::vector<ConfigDesc> generateConfigs() const override;
egl::Error createContext(const egl::Config *config, const gl::Context *shareContext, const egl::AttributeMap &attribs,
gl::Context **outContext) override;
egl::ConfigSet generateConfigs() const override;
bool isDeviceLost() const override;
bool testDeviceLost() override;
egl::Error restoreLostDevice() override;
bool isValidNativeWindow(EGLNativeWindowType window) const override;
std::string getVendorString() const override;
private:
DISALLOW_COPY_AND_ASSIGN(DisplayD3D);
void generateExtensions(egl::DisplayExtensions *outExtensions) const override;
void generateCaps(egl::Caps *outCaps) const override;
rx::RendererD3D *mRenderer;
};
......
......@@ -627,11 +627,6 @@ std::string RendererD3D::getVendorString() const
return std::string("");
}
DisplayImpl *RendererD3D::createDisplay()
{
return new DisplayD3D(this);
}
gl::Error RendererD3D::getScratchMemoryBuffer(size_t requestedSize, MemoryBuffer **bufferOut)
{
if (mScratchMemoryBuffer.size() == requestedSize)
......
......@@ -51,6 +51,8 @@ class RendererD3D : public Renderer
static RendererD3D *makeRendererD3D(Renderer *renderer);
virtual EGLint initialize() = 0;
virtual std::vector<ConfigDesc> generateConfigs() const = 0;
gl::Error drawArrays(const gl::Data &data,
......@@ -68,8 +70,6 @@ class RendererD3D : public Renderer
virtual int getMinorShaderModel() const = 0;
virtual std::string getShaderModelSuffix() const = 0;
DisplayImpl *createDisplay() override;
// Direct3D Specific methods
virtual GUID getAdapterIdentifier() const = 0;
......
......@@ -20,25 +20,25 @@
namespace rx
{
SurfaceD3D *SurfaceD3D::createOffscreen(egl::Display *display, const egl::Config *config, EGLClientBuffer shareHandle,
SurfaceD3D *SurfaceD3D::createOffscreen(RendererD3D *renderer, egl::Display *display, const egl::Config *config, EGLClientBuffer shareHandle,
EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureType)
{
return new SurfaceD3D(display, config, width, height, EGL_TRUE, EGL_FALSE,
return new SurfaceD3D(renderer, display, config, width, height, EGL_TRUE, EGL_FALSE,
textureFormat, textureType, shareHandle, NULL);
}
SurfaceD3D *SurfaceD3D::createFromWindow(egl::Display *display, const egl::Config *config, EGLNativeWindowType window,
SurfaceD3D *SurfaceD3D::createFromWindow(RendererD3D *renderer, egl::Display *display, const egl::Config *config, EGLNativeWindowType window,
EGLint fixedSize, EGLint width, EGLint height, EGLint postSubBufferSupported)
{
return new SurfaceD3D(display, config, width, height, fixedSize, postSubBufferSupported,
return new SurfaceD3D(renderer, display, config, width, height, fixedSize, postSubBufferSupported,
EGL_NO_TEXTURE, EGL_NO_TEXTURE, static_cast<EGLClientBuffer>(0), window);
}
SurfaceD3D::SurfaceD3D(egl::Display *display, const egl::Config *config, EGLint width, EGLint height,
SurfaceD3D::SurfaceD3D(RendererD3D *renderer, egl::Display *display, const egl::Config *config, EGLint width, EGLint height,
EGLint fixedSize, EGLint postSubBufferSupported, EGLenum textureFormat,
EGLenum textureType, EGLClientBuffer shareHandle, EGLNativeWindowType window)
: SurfaceImpl(display, config, width, height, fixedSize, postSubBufferSupported, textureFormat, textureType, shareHandle),
mRenderer(static_cast<rx::RendererD3D*>(mDisplay->getRenderer())),
mRenderer(renderer),
mSwapChain(NULL),
mWindowSubclassed(false),
mNativeWindow(window)
......
......@@ -25,10 +25,10 @@ class RendererD3D;
class SurfaceD3D : public SurfaceImpl
{
public:
static SurfaceD3D *createFromWindow(egl::Display *display, const egl::Config *config,
static SurfaceD3D *createFromWindow(RendererD3D *renderer, egl::Display *display, const egl::Config *config,
EGLNativeWindowType window, EGLint fixedSize,
EGLint width, EGLint height, EGLint postSubBufferSupported);
static SurfaceD3D *createOffscreen(egl::Display *display, const egl::Config *config,
static SurfaceD3D *createOffscreen(RendererD3D *renderer, egl::Display *display, const egl::Config *config,
EGLClientBuffer shareHandle, EGLint width, EGLint height,
EGLenum textureFormat, EGLenum textureTarget);
~SurfaceD3D() override;
......@@ -55,7 +55,7 @@ class SurfaceD3D : public SurfaceImpl
private:
DISALLOW_COPY_AND_ASSIGN(SurfaceD3D);
SurfaceD3D(egl::Display *display, const egl::Config *config, EGLint width, EGLint height,
SurfaceD3D(RendererD3D *renderer, egl::Display *display, const egl::Config *config, EGLint width, EGLint height,
EGLint fixedSize, EGLint postSubBufferSupported, EGLenum textureFormat,
EGLenum textureType, EGLClientBuffer shareHandle, EGLNativeWindowType window);
egl::Error swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
......
......@@ -587,22 +587,23 @@ EGLContext EGLAPIENTRY CreateContext(EGLDisplay dpy, EGLConfig config, EGLContex
if (share_context)
{
gl::Context* sharedGLContext = static_cast<gl::Context*>(share_context);
if (sharedGLContext->isResetNotificationEnabled() != resetNotification)
// Shared context is invalid or is owned by another display
if (!display->isValidContext(sharedGLContext))
{
SetGlobalError(Error(EGL_BAD_MATCH));
return EGL_NO_CONTEXT;
}
if (sharedGLContext->getClientVersion() != clientMajorVersion)
if (sharedGLContext->isResetNotificationEnabled() != resetNotification)
{
SetGlobalError(Error(EGL_BAD_CONTEXT));
SetGlobalError(Error(EGL_BAD_MATCH));
return EGL_NO_CONTEXT;
}
// Can not share contexts between displays
if (sharedGLContext->getRenderer() != display->getRenderer())
if (sharedGLContext->getClientVersion() != clientMajorVersion)
{
SetGlobalError(Error(EGL_BAD_MATCH));
SetGlobalError(Error(EGL_BAD_CONTEXT));
return EGL_NO_CONTEXT;
}
}
......@@ -613,8 +614,7 @@ EGLContext EGLAPIENTRY CreateContext(EGLDisplay dpy, EGLConfig config, EGLContex
}
EGLContext context = EGL_NO_CONTEXT;
Error error = display->createContext(config, clientMajorVersion, static_cast<gl::Context*>(share_context),
resetNotification, robustAccess, &context);
Error error = display->createContext(config, share_context, egl::AttributeMap(attrib_list), &context);
if (error.isError())
{
SetGlobalError(error);
......@@ -677,14 +677,13 @@ EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface r
if (dpy != EGL_NO_DISPLAY && display->isInitialized())
{
rx::Renderer *renderer = display->getRenderer();
if (renderer->testDeviceLost())
if (display->testDeviceLost())
{
display->notifyDeviceLost();
return EGL_FALSE;
}
if (renderer->isDeviceLost())
if (display->isDeviceLost())
{
SetGlobalError(Error(EGL_CONTEXT_LOST));
return EGL_FALSE;
......@@ -801,7 +800,7 @@ EGLBoolean EGLAPIENTRY SwapBuffers(EGLDisplay dpy, EGLSurface surface)
return EGL_FALSE;
}
if (display->getRenderer()->isDeviceLost())
if (display->isDeviceLost())
{
SetGlobalError(Error(EGL_CONTEXT_LOST));
return EGL_FALSE;
......@@ -836,7 +835,7 @@ EGLBoolean EGLAPIENTRY CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNative
return EGL_FALSE;
}
if (display->getRenderer()->isDeviceLost())
if (display->isDeviceLost())
{
SetGlobalError(Error(EGL_CONTEXT_LOST));
return EGL_FALSE;
......
......@@ -118,7 +118,7 @@ EGLBoolean EGLAPIENTRY PostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLin
return EGL_FALSE;
}
if (display->getRenderer()->isDeviceLost())
if (display->isDeviceLost())
{
SetGlobalError(Error(EGL_CONTEXT_LOST));
return EGL_FALSE;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment