Commit 86803677 by Geoff Lang

Update Display to allow for changing implementation objects.

Previously it was possible to change from a D3D9 to D3D11 display because both were implemented with a DisplayD3D. Now that there is a DisplayGL, the DisplayImpl must be updated while maintaining the same EGLDisplay value. Allow the value of Display::mImplementation to be updated when the display is not already initialized. BUG=angle:890 Change-Id: Ic18a8a120218cd130a71b9aa044b6ec00006d6a0 Reviewed-on: https://chromium-review.googlesource.com/252250Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarNicolas Capens <capn@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 99a3a9b2
......@@ -86,96 +86,103 @@ static DisplayMap *GetDisplayMap()
return &displays;
}
}
Display *Display::getDisplay(EGLNativeDisplayType displayId, const AttributeMap &attribMap)
rx::DisplayImpl *CreateDisplayImpl(const AttributeMap &attribMap)
{
// Initialize the global platform if not already
InitDefaultPlatformImpl();
Display *display = NULL;
DisplayMap *displays = GetDisplayMap();
DisplayMap::const_iterator iter = displays->find(displayId);
if (iter != displays->end())
rx::DisplayImpl *impl = nullptr;
EGLint displayType = attribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE);
switch (displayType)
{
display = iter->second;
}
else
{
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:
case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE:
#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
// Default to D3D displays
impl = new rx::DisplayD3D();
// Default to D3D displays
impl = new rx::DisplayD3D();
#else
// No display available
UNREACHABLE();
// No display available
UNREACHABLE();
#endif
break;
break;
case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE:
case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
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();
impl = new rx::DisplayD3D();
#else
// A D3D display was requested on a platform that doesn't support it
UNREACHABLE();
// A D3D display was requested on a platform that doesn't support it
UNREACHABLE();
#endif
break;
break;
case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
#if defined(ANGLE_ENABLE_OPENGL)
#if defined(ANGLE_PLATFORM_WINDOWS)
impl = new rx::DisplayWGL();
impl = new rx::DisplayWGL();
#else
#error Unsupported OpenGL platform.
#endif
#else
UNREACHABLE();
UNREACHABLE();
#endif
break;
break;
default:
UNREACHABLE();
break;
}
default:
UNREACHABLE();
break;
}
ASSERT(impl != nullptr);
return impl;
}
ASSERT(impl != nullptr);
}
display = new Display(impl, displayId);
Display *Display::getDisplay(EGLNativeDisplayType displayId, const AttributeMap &attribMap)
{
// Initialize the global platform if not already
InitDefaultPlatformImpl();
Display *display = NULL;
DisplayMap *displays = GetDisplayMap();
DisplayMap::const_iterator iter = displays->find(displayId);
if (iter != displays->end())
{
display = iter->second;
}
if (display == nullptr)
{
// Validate the native display
if (!display->isValidNativeDisplay(displayId))
if (!Display::isValidNativeDisplay(displayId))
{
// Still returns success
SafeDelete(display);
return NULL;
}
display = new Display(displayId);
displays->insert(std::make_pair(displayId, display));
}
// Apply new attributes if the display is not initialized yet.
if (!display->isInitialized())
{
display->setAttributes(attribMap);
rx::DisplayImpl* impl = CreateDisplayImpl(attribMap);
display->setAttributes(impl, attribMap);
}
return display;
}
Display::Display(rx::DisplayImpl *impl, EGLNativeDisplayType displayId)
: mImplementation(impl),
Display::Display(EGLNativeDisplayType displayId)
: mImplementation(nullptr),
mDisplayId(displayId),
mAttributeMap(),
mInitialized(false)
mConfigSet(),
mContextSet(),
mInitialized(false),
mCaps(),
mDisplayExtensions(),
mDisplayExtensionString(),
mVendorString()
{
ASSERT(mImplementation != nullptr);
}
Display::~Display()
......@@ -192,13 +199,21 @@ Display::~Display()
SafeDelete(mImplementation);
}
void Display::setAttributes(const AttributeMap &attribMap)
void Display::setAttributes(rx::DisplayImpl *impl, const AttributeMap &attribMap)
{
ASSERT(!mInitialized);
ASSERT(impl != nullptr);
SafeDelete(mImplementation);
mImplementation = impl;
mAttributeMap = attribMap;
}
Error Display::initialize()
{
ASSERT(mImplementation != nullptr);
if (isInitialized())
{
return Error(EGL_SUCCESS);
......@@ -559,7 +574,7 @@ bool Display::isValidNativeWindow(EGLNativeWindowType window) const
return mImplementation->isValidNativeWindow(window);
}
bool Display::isValidNativeDisplay(EGLNativeDisplayType display) const
bool Display::isValidNativeDisplay(EGLNativeDisplayType display)
{
// TODO(jmadill): handle this properly
if (display == EGL_DEFAULT_DISPLAY)
......
......@@ -69,7 +69,8 @@ class Display final
bool isValidSurface(egl::Surface *surface) const;
bool hasExistingWindowSurface(EGLNativeWindowType window) const;
bool isValidNativeWindow(EGLNativeWindowType window) const;
bool isValidNativeDisplay(EGLNativeDisplayType display) const;
static bool isValidNativeDisplay(EGLNativeDisplayType display);
bool isDeviceLost() const;
bool testDeviceLost();
......@@ -89,9 +90,9 @@ class Display final
private:
DISALLOW_COPY_AND_ASSIGN(Display);
Display(rx::DisplayImpl *impl, EGLNativeDisplayType displayId);
Display(EGLNativeDisplayType displayId);
void setAttributes(const AttributeMap &attribMap);
void setAttributes(rx::DisplayImpl *impl, const AttributeMap &attribMap);
Error restoreLostDevice();
......
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