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;
......
......@@ -24,97 +24,13 @@
#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
#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
# include "libANGLE/renderer/d3d/DisplayD3D.h"
#endif
namespace egl
{
typedef rx::Renderer *(*CreateRendererFunction)(Display*, EGLNativeDisplayType, const AttributeMap &);
template <typename RendererType>
static rx::Renderer *CreateTypedRenderer(Display *display, EGLNativeDisplayType nativeDisplay, const AttributeMap &attributes)
{
return new RendererType(display, nativeDisplay, attributes);
}
rx::Renderer *CreateRenderer(Display *display, EGLNativeDisplayType nativeDisplay, const AttributeMap &attribMap)
{
std::vector<CreateRendererFunction> 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(CreateTypedRenderer<rx::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(CreateTypedRenderer<rx::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(CreateTypedRenderer<rx::Renderer11>);
# endif
# if defined(ANGLE_ENABLE_D3D9)
rendererCreationFunctions.push_back(CreateTypedRenderer<rx::Renderer9>);
# endif
# else
# if defined(ANGLE_ENABLE_D3D9)
rendererCreationFunctions.push_back(CreateTypedRenderer<rx::Renderer9>);
# endif
# if defined(ANGLE_ENABLE_D3D11)
rendererCreationFunctions.push_back(CreateTypedRenderer<rx::Renderer11>);
# endif
# endif
}
for (size_t i = 0; i < rendererCreationFunctions.size(); i++)
{
rx::Renderer *renderer = rendererCreationFunctions[i](display, nativeDisplay, attribMap);
if (renderer->initialize() == EGL_SUCCESS)
{
return renderer;
}
else
{
// Failed to create the renderer, try the next
SafeDelete(renderer);
}
}
return NULL;
}
typedef std::map<EGLNativeDisplayType, Display*> DisplayMap;
static DisplayMap *GetDisplayMap()
{
......@@ -134,7 +50,39 @@ Display *Display::getDisplay(EGLNativeDisplayType displayId, const AttributeMap
}
else
{
display = new Display(displayId);
rx::DisplayImpl *impl = nullptr;
EGLint displayType = attribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE);
switch (displayType)
{
case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE:
#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
// Default to D3D displays
impl = new rx::DisplayD3D();
#else
// No display available
UNREACHABLE();
#endif
break;
case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE:
case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
impl = new rx::DisplayD3D();
#else
// A D3D display was requested on a platform that doesn't support it
UNREACHABLE();
#endif
break;
default:
UNREACHABLE();
break;
}
ASSERT(impl != nullptr);
display = new Display(impl, displayId);
// Validate the native display
if (!display->isValidNativeDisplay(displayId))
......@@ -156,12 +104,13 @@ Display *Display::getDisplay(EGLNativeDisplayType displayId, const AttributeMap
return display;
}
Display::Display(EGLNativeDisplayType displayId)
: mImplementation(NULL),
Display::Display(rx::DisplayImpl *impl, EGLNativeDisplayType displayId)
: mImplementation(impl),
mDisplayId(displayId),
mAttributeMap(),
mRenderer(NULL)
mInitialized(false)
{
ASSERT(mImplementation != nullptr);
}
Display::~Display()
......@@ -174,6 +123,8 @@ Display::~Display()
{
displays->erase(iter);
}
SafeDelete(mImplementation);
}
void Display::setAttributes(const AttributeMap &attribMap)
......@@ -188,29 +139,15 @@ Error Display::initialize()
return Error(EGL_SUCCESS);
}
mRenderer = CreateRenderer(this, mDisplayId, mAttributeMap);
if (!mRenderer)
Error error = mImplementation->initialize(this, mDisplayId, mAttributeMap);
if (error.isError())
{
terminate();
return Error(EGL_NOT_INITIALIZED);
return error;
}
mImplementation = mRenderer->createDisplay();
ASSERT(mImplementation);
//TODO(jmadill): should be part of caps?
EGLint minSwapInterval = mRenderer->getMinSwapInterval();
EGLint maxSwapInterval = mRenderer->getMaxSwapInterval();
EGLint maxTextureSize = mRenderer->getRendererCaps().max2DTextureSize;
std::vector<rx::ConfigDesc> descList = mImplementation->generateConfigs();
mCaps = mImplementation->getCaps();
ConfigSet configSet;
for (size_t i = 0; i < descList.size(); ++i)
{
configSet.add(descList[i], minSwapInterval, maxSwapInterval, maxTextureSize, maxTextureSize);
}
ConfigSet configSet = mImplementation->generateConfigs();
// Give the sorted configs a unique ID and store them internally
EGLint index = 1;
......@@ -223,15 +160,16 @@ Error Display::initialize()
mConfigSet.mSet.insert(configuration);
}
if (!isInitialized())
if (mConfigSet.size() == 0)
{
terminate();
mImplementation->terminate();
return Error(EGL_NOT_INITIALIZED);
}
initDisplayExtensions();
initVendorString();
mInitialized = true;
return Error(EGL_SUCCESS);
}
......@@ -242,9 +180,10 @@ void Display::terminate()
destroyContext(*mContextSet.begin());
}
SafeDelete(mRenderer);
mConfigSet.mSet.clear();
mImplementation->terminate();
mInitialized = false;
}
bool Display::getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig)
......@@ -365,7 +304,7 @@ Error Display::createWindowSurface(EGLNativeWindowType window, EGLConfig config,
return Error(EGL_BAD_ALLOC);
}
if (mRenderer->testDeviceLost())
if (mImplementation->testDeviceLost())
{
Error error = restoreLostDevice();
if (error.isError())
......@@ -465,7 +404,7 @@ Error Display::createOffscreenSurface(EGLConfig config, EGLClientBuffer shareHan
return Error(EGL_BAD_ATTRIBUTE);
}
if (textureFormat != EGL_NO_TEXTURE && !mRenderer->getRendererExtensions().textureNPOT && (!gl::isPow2(width) || !gl::isPow2(height)))
if (textureFormat != EGL_NO_TEXTURE && !mCaps.textureNPOT && (!gl::isPow2(width) || !gl::isPow2(height)))
{
return Error(EGL_BAD_MATCH);
}
......@@ -487,7 +426,7 @@ Error Display::createOffscreenSurface(EGLConfig config, EGLClientBuffer shareHan
return Error(EGL_BAD_ATTRIBUTE);
}
if (mRenderer->testDeviceLost())
if (mImplementation->testDeviceLost())
{
Error error = restoreLostDevice();
if (error.isError())
......@@ -513,17 +452,12 @@ Error Display::createOffscreenSurface(EGLConfig config, EGLClientBuffer shareHan
return Error(EGL_SUCCESS);
}
Error Display::createContext(EGLConfig configHandle, EGLint clientVersion, const gl::Context *shareContext, bool notifyResets,
bool robustAccess, EGLContext *outContext)
Error Display::createContext(EGLConfig configHandle, EGLContext shareContext, const egl::AttributeMap &attribs,
EGLContext *outContext)
{
const Config *configuration = mConfigSet.get(configHandle);
ASSERT(isInitialized());
if (!mRenderer)
{
*outContext = EGL_NO_CONTEXT;
return Error(EGL_SUCCESS);
}
else if (mRenderer->testDeviceLost()) // Lost device
if (mImplementation->testDeviceLost())
{
Error error = restoreLostDevice();
if (error.isError())
......@@ -532,12 +466,21 @@ Error Display::createContext(EGLConfig configHandle, EGLint clientVersion, const
}
}
if (clientVersion == 3 && !(configuration->mConformant & EGL_OPENGL_ES3_BIT_KHR))
const Config *configuration = mConfigSet.get(configHandle);
if (attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1) == 3 && !(configuration->mConformant & EGL_OPENGL_ES3_BIT_KHR))
{
return Error(EGL_BAD_CONFIG);
}
gl::Context *context = new gl::Context(clientVersion, shareContext, mRenderer, notifyResets, robustAccess);
gl::Context *context = nullptr;
Error error = mImplementation->createContext(configuration, reinterpret_cast<gl::Context*>(shareContext),
attribs, &context);
if (error.isError())
{
return error;
}
ASSERT(context != nullptr);
mContextSet.insert(context);
*outContext = context;
......@@ -569,6 +512,18 @@ void Display::destroyContext(gl::Context *context)
SafeDelete(context);
}
bool Display::isDeviceLost() const
{
ASSERT(isInitialized());
return mImplementation->isDeviceLost();
}
bool Display::testDeviceLost()
{
ASSERT(isInitialized());
return mImplementation->testDeviceLost();
}
void Display::notifyDeviceLost()
{
for (ContextSet::iterator context = mContextSet.begin(); context != mContextSet.end(); context++)
......@@ -577,9 +532,14 @@ void Display::notifyDeviceLost()
}
}
const Caps &Display::getCaps() const
{
return mCaps;
}
bool Display::isInitialized() const
{
return mRenderer != NULL && mConfigSet.size() > 0;
return mInitialized;
}
bool Display::isValidConfig(EGLConfig config)
......@@ -685,13 +645,7 @@ bool Display::isValidNativeDisplay(EGLNativeDisplayType display) const
void Display::initVendorString()
{
mVendorString = "Google Inc.";
// TODO(jmadill): clean this up
if (mRenderer)
{
mVendorString += " " + mRenderer->getVendorString();
}
mVendorString = mImplementation->getVendorString();
}
const DisplayExtensions &Display::getExtensions() const
......
......@@ -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