diff options
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/Display.cpp')
-rw-r--r-- | src/3rdparty/angle/src/libANGLE/Display.cpp | 1240 |
1 files changed, 0 insertions, 1240 deletions
diff --git a/src/3rdparty/angle/src/libANGLE/Display.cpp b/src/3rdparty/angle/src/libANGLE/Display.cpp deleted file mode 100644 index 0bb0bb05b1..0000000000 --- a/src/3rdparty/angle/src/libANGLE/Display.cpp +++ /dev/null @@ -1,1240 +0,0 @@ -// -// Copyright (c) 2002-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. -// - -// Display.cpp: Implements the egl::Display class, representing the abstract -// display on which graphics are drawn. Implements EGLDisplay. -// [EGL 1.4] section 2.1.2 page 3. - -#include "libANGLE/Display.h" - -#include <algorithm> -#include <iterator> -#include <map> -#include <sstream> -#include <vector> - -#include <platform/Platform.h> -#include <EGL/eglext.h> - -#include "common/debug.h" -#include "common/mathutil.h" -#include "common/platform.h" -#include "common/utilities.h" -#include "libANGLE/Context.h" -#include "libANGLE/Device.h" -#include "libANGLE/histogram_macros.h" -#include "libANGLE/Image.h" -#include "libANGLE/Surface.h" -#include "libANGLE/Stream.h" -#include "libANGLE/ResourceManager.h" -#include "libANGLE/renderer/DisplayImpl.h" -#include "libANGLE/renderer/ImageImpl.h" -#include "third_party/trace_event/trace_event.h" - -#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11) -# include "libANGLE/renderer/d3d/DisplayD3D.h" -#endif - -#if defined(ANGLE_ENABLE_OPENGL) -# if defined(ANGLE_PLATFORM_WINDOWS) -# include "libANGLE/renderer/gl/wgl/DisplayWGL.h" -# elif defined(ANGLE_USE_X11) -# include "libANGLE/renderer/gl/glx/DisplayGLX.h" -# elif defined(ANGLE_PLATFORM_APPLE) -# include "libANGLE/renderer/gl/cgl/DisplayCGL.h" -# elif defined(ANGLE_USE_OZONE) -# include "libANGLE/renderer/gl/egl/ozone/DisplayOzone.h" -# elif defined(ANGLE_PLATFORM_ANDROID) -# include "libANGLE/renderer/gl/egl/android/DisplayAndroid.h" -# else -# error Unsupported OpenGL platform. -# endif -#endif - -#if defined(ANGLE_ENABLE_NULL) -#include "libANGLE/renderer/null/DisplayNULL.h" -#endif // defined(ANGLE_ENABLE_NULL) - -#if defined(ANGLE_ENABLE_VULKAN) -#if defined(ANGLE_PLATFORM_WINDOWS) -#include "libANGLE/renderer/vulkan/win32/DisplayVkWin32.h" -#elif defined(ANGLE_PLATFORM_LINUX) -#include "libANGLE/renderer/vulkan/xcb/DisplayVkXcb.h" -#else -#error Unsupported Vulkan platform. -#endif -#endif // defined(ANGLE_ENABLE_VULKAN) - -namespace egl -{ - -namespace -{ - -typedef std::map<EGLNativeWindowType, Surface*> WindowSurfaceMap; -// Get a map of all EGL window surfaces to validate that no window has more than one EGL surface -// associated with it. -static WindowSurfaceMap *GetWindowSurfaces() -{ - static WindowSurfaceMap windowSurfaces; - return &windowSurfaces; -} - -typedef std::map<EGLNativeDisplayType, Display *> ANGLEPlatformDisplayMap; -static ANGLEPlatformDisplayMap *GetANGLEPlatformDisplayMap() -{ - static ANGLEPlatformDisplayMap displays; - return &displays; -} - -typedef std::map<Device *, Display *> DevicePlatformDisplayMap; -static DevicePlatformDisplayMap *GetDevicePlatformDisplayMap() -{ - static DevicePlatformDisplayMap displays; - return &displays; -} - -rx::DisplayImpl *CreateDisplayFromDevice(Device *eglDevice, const DisplayState &state) -{ - rx::DisplayImpl *impl = nullptr; - - switch (eglDevice->getType()) - { -#if defined(ANGLE_ENABLE_D3D11) - case EGL_D3D11_DEVICE_ANGLE: - impl = new rx::DisplayD3D(state); - break; -#endif -#if defined(ANGLE_ENABLE_D3D9) - case EGL_D3D9_DEVICE_ANGLE: - // Currently the only way to get EGLDeviceEXT representing a D3D9 device - // is to retrieve one from an already-existing EGLDisplay. - // When eglGetPlatformDisplayEXT is called with a D3D9 EGLDeviceEXT, - // the already-existing display should be returned. - // Therefore this codepath to create a new display from the device - // should never be hit. - UNREACHABLE(); - break; -#endif - default: - UNREACHABLE(); - break; - } - - ASSERT(impl != nullptr); - return impl; -} - -rx::DisplayImpl *CreateDisplayFromAttribs(const AttributeMap &attribMap, const DisplayState &state) -{ - rx::DisplayImpl *impl = nullptr; - EGLAttrib 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(state); -#elif defined(ANGLE_USE_X11) - impl = new rx::DisplayGLX(state); -#elif defined(ANGLE_PLATFORM_APPLE) - impl = new rx::DisplayCGL(state); -#elif defined(ANGLE_USE_OZONE) - impl = new rx::DisplayOzone(state); -#elif defined(ANGLE_PLATFORM_ANDROID) - impl = new rx::DisplayAndroid(state); -#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(state); -#else - // A D3D display was requested on a platform that doesn't support it - UNREACHABLE(); -#endif - break; - - case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE: -#if defined(ANGLE_ENABLE_OPENGL) -#if defined(ANGLE_PLATFORM_WINDOWS) - impl = new rx::DisplayWGL(state); -#elif defined(ANGLE_USE_X11) - impl = new rx::DisplayGLX(state); -#elif defined(ANGLE_PLATFORM_APPLE) - impl = new rx::DisplayCGL(state); -#elif defined(ANGLE_USE_OZONE) - // This might work but has never been tried, so disallow for now. - impl = nullptr; -#elif defined(ANGLE_PLATFORM_ANDROID) - // No GL support on this platform, fail display creation. - impl = nullptr; -#else -#error Unsupported OpenGL platform. -#endif -#else - // No display available - UNREACHABLE(); -#endif // defined(ANGLE_ENABLE_OPENGL) - break; - - case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE: -#if defined(ANGLE_ENABLE_OPENGL) -#if defined(ANGLE_PLATFORM_WINDOWS) - impl = new rx::DisplayWGL(state); -#elif defined(ANGLE_USE_X11) - impl = new rx::DisplayGLX(state); -#elif defined(ANGLE_USE_OZONE) - impl = new rx::DisplayOzone(state); -#elif defined(ANGLE_PLATFORM_ANDROID) - impl = new rx::DisplayAndroid(state); -#else - // No GLES support on this platform, fail display creation. - impl = nullptr; -#endif -#endif // defined(ANGLE_ENABLE_OPENGL) - break; - - case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE: -#if defined(ANGLE_ENABLE_VULKAN) -#if defined(ANGLE_PLATFORM_WINDOWS) - impl = new rx::DisplayVkWin32(state); -#elif defined(ANGLE_PLATFORM_LINUX) - impl = new rx::DisplayVkXcb(state); -#else -#error Unsupported Vulkan platform. -#endif -#else - // No display available - UNREACHABLE(); -#endif // defined(ANGLE_ENABLE_VULKAN) - break; - - case EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE: -#if defined(ANGLE_ENABLE_NULL) - impl = new rx::DisplayNULL(state); -#else - // No display available - UNREACHABLE(); -#endif // defined(ANGLE_ENABLE_NULL) - break; - - default: - UNREACHABLE(); - break; - } - - return impl; -} - -void Display_logError(angle::PlatformMethods *platform, const char *errorMessage) -{ - gl::Trace(gl::LOG_ERR, errorMessage); -} - -void Display_logWarning(angle::PlatformMethods *platform, const char *warningMessage) -{ - gl::Trace(gl::LOG_WARN, warningMessage); -} - -void Display_logInfo(angle::PlatformMethods *platform, const char *infoMessage) -{ - // Uncomment to get info spam - // gl::Trace(gl::LOG_WARN, infoMessage); -} - -void ANGLESetDefaultDisplayPlatform(angle::EGLDisplayType display) -{ - angle::PlatformMethods *platformMethods = ANGLEPlatformCurrent(); - if (platformMethods->logError != angle::DefaultLogError) - { - // Don't reset pre-set Platform to Default - return; - } - - ANGLEResetDisplayPlatform(display); - platformMethods->logError = Display_logError; - platformMethods->logWarning = Display_logWarning; - platformMethods->logInfo = Display_logInfo; -} - -} // anonymous namespace - -DisplayState::DisplayState() -{ -} - -DisplayState::~DisplayState() -{ -} - -// static -Display *Display::GetDisplayFromNativeDisplay(EGLNativeDisplayType nativeDisplay, - const AttributeMap &attribMap) -{ - Display *display = nullptr; - - ANGLEPlatformDisplayMap *displays = GetANGLEPlatformDisplayMap(); - const auto &iter = displays->find(nativeDisplay); - if (iter != displays->end()) - { - display = iter->second; - } - - if (display == nullptr) - { - // Validate the native display - if (!Display::isValidNativeDisplay(nativeDisplay)) - { - return nullptr; - } - - display = new Display(EGL_PLATFORM_ANGLE_ANGLE, nativeDisplay, nullptr); - displays->insert(std::make_pair(nativeDisplay, display)); - } - - // Apply new attributes if the display is not initialized yet. - if (!display->isInitialized()) - { - rx::DisplayImpl *impl = CreateDisplayFromAttribs(attribMap, display->getState()); - if (impl == nullptr) - { - // No valid display implementation for these attributes - return nullptr; - } - - display->setAttributes(impl, attribMap); - } - - return display; -} - -// static -Display *Display::GetDisplayFromDevice(Device *device, const AttributeMap &attribMap) -{ - Display *display = nullptr; - - ASSERT(Device::IsValidDevice(device)); - - ANGLEPlatformDisplayMap *anglePlatformDisplays = GetANGLEPlatformDisplayMap(); - DevicePlatformDisplayMap *devicePlatformDisplays = GetDevicePlatformDisplayMap(); - - // First see if this eglDevice is in use by a Display created using ANGLE platform - for (auto &displayMapEntry : *anglePlatformDisplays) - { - egl::Display *iterDisplay = displayMapEntry.second; - if (iterDisplay->getDevice() == device) - { - display = iterDisplay; - } - } - - if (display == nullptr) - { - // See if the eglDevice is in use by a Display created using the DEVICE platform - const auto &iter = devicePlatformDisplays->find(device); - if (iter != devicePlatformDisplays->end()) - { - display = iter->second; - } - } - - if (display == nullptr) - { - // Otherwise create a new Display - display = new Display(EGL_PLATFORM_DEVICE_EXT, 0, device); - devicePlatformDisplays->insert(std::make_pair(device, display)); - } - - // Apply new attributes if the display is not initialized yet. - if (!display->isInitialized()) - { - rx::DisplayImpl *impl = CreateDisplayFromDevice(device, display->getState()); - display->setAttributes(impl, attribMap); - } - - return display; -} - -//static -void Display::CleanupDisplays() -{ - // ~Display takes care of removing the entry from the according map - { - ANGLEPlatformDisplayMap *displays = GetANGLEPlatformDisplayMap(); - while (!displays->empty()) - delete displays->begin()->second; - } - - { - DevicePlatformDisplayMap *displays = GetDevicePlatformDisplayMap(); - while (!displays->empty()) - delete displays->begin()->second; - } -} - -Display::Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDevice) - : mImplementation(nullptr), - mDisplayId(displayId), - mAttributeMap(), - mConfigSet(), - mContextSet(), - mStreamSet(), - mInitialized(false), - mDeviceLost(false), - mCaps(), - mDisplayExtensions(), - mDisplayExtensionString(), - mVendorString(), - mDevice(eglDevice), - mPlatform(platform), - mTextureManager(nullptr), - mMemoryProgramCache(gl::kDefaultMaxProgramCacheMemoryBytes), - mGlobalTextureShareGroupUsers(0), - mProxyContext(this) -{ -} - -Display::~Display() -{ - // TODO(jmadill): When is this called? - // terminate(); - - if (mPlatform == EGL_PLATFORM_ANGLE_ANGLE) - { - ANGLEPlatformDisplayMap *displays = GetANGLEPlatformDisplayMap(); - ANGLEPlatformDisplayMap::iterator iter = displays->find(mDisplayId); - if (iter != displays->end()) - { - displays->erase(iter); - } - } - else if (mPlatform == EGL_PLATFORM_DEVICE_EXT) - { - DevicePlatformDisplayMap *displays = GetDevicePlatformDisplayMap(); - DevicePlatformDisplayMap::iterator iter = displays->find(mDevice); - if (iter != displays->end()) - { - displays->erase(iter); - } - } - else - { - UNREACHABLE(); - } - - mProxyContext.reset(nullptr); - - SafeDelete(mDevice); - SafeDelete(mImplementation); -} - -void Display::setAttributes(rx::DisplayImpl *impl, const AttributeMap &attribMap) -{ - ASSERT(!mInitialized); - - ASSERT(impl != nullptr); - SafeDelete(mImplementation); - mImplementation = impl; - - mAttributeMap = attribMap; -} - -Error Display::initialize() -{ - // TODO(jmadill): Store Platform in Display and init here. - const angle::PlatformMethods *platformMethods = - reinterpret_cast<const angle::PlatformMethods *>( - mAttributeMap.get(EGL_PLATFORM_ANGLE_PLATFORM_METHODS_ANGLEX, 0)); - if (platformMethods != nullptr) - { - *ANGLEPlatformCurrent() = *platformMethods; - } - else - { - ANGLESetDefaultDisplayPlatform(this); - } - - gl::InitializeDebugAnnotations(&mAnnotator); - - SCOPED_ANGLE_HISTOGRAM_TIMER("GPU.ANGLE.DisplayInitializeMS"); - TRACE_EVENT0("gpu.angle", "egl::Display::initialize"); - - ASSERT(mImplementation != nullptr); - - if (isInitialized()) - { - return NoError(); - } - - Error error = mImplementation->initialize(this); - if (error.isError()) - { - // Log extended error message here - ERR() << "ANGLE Display::initialize error " << error.getID() << ": " << error.getMessage(); - return error; - } - - mCaps = mImplementation->getCaps(); - - mConfigSet = mImplementation->generateConfigs(); - if (mConfigSet.size() == 0) - { - mImplementation->terminate(); - return EglNotInitialized(); - } - - initDisplayExtensions(); - initVendorString(); - - // Populate the Display's EGLDeviceEXT if the Display wasn't created using one - if (mPlatform != EGL_PLATFORM_DEVICE_EXT) - { - if (mDisplayExtensions.deviceQuery) - { - rx::DeviceImpl *impl = nullptr; - ANGLE_TRY(mImplementation->getDevice(&impl)); - ANGLE_TRY(Device::CreateDevice(this, impl, &mDevice)); - } - else - { - mDevice = nullptr; - } - } - else - { - // For EGL_PLATFORM_DEVICE_EXT, mDevice should always be populated using - // an external device - ASSERT(mDevice != nullptr); - } - - mProxyContext.reset(nullptr); - gl::Context *proxyContext = new gl::Context(mImplementation, nullptr, nullptr, nullptr, nullptr, - egl::AttributeMap(), mDisplayExtensions); - mProxyContext.reset(proxyContext); - - mInitialized = true; - - return NoError(); -} - -Error Display::terminate() -{ - ANGLE_TRY(makeCurrent(nullptr, nullptr, nullptr)); - - mMemoryProgramCache.clear(); - - mProxyContext.reset(nullptr); - - while (!mContextSet.empty()) - { - ANGLE_TRY(destroyContext(*mContextSet.begin())); - } - - // The global texture manager should be deleted with the last context that uses it. - ASSERT(mGlobalTextureShareGroupUsers == 0 && mTextureManager == nullptr); - - while (!mImageSet.empty()) - { - destroyImage(*mImageSet.begin()); - } - - while (!mStreamSet.empty()) - { - destroyStream(*mStreamSet.begin()); - } - - while (!mState.surfaceSet.empty()) - { - ANGLE_TRY(destroySurface(*mState.surfaceSet.begin())); - } - - mConfigSet.clear(); - - if (mDevice != nullptr && mDevice->getOwningDisplay() != nullptr) - { - // Don't delete the device if it was created externally using eglCreateDeviceANGLE - // We also shouldn't set it to null in case eglInitialize() is called again later - SafeDelete(mDevice); - } - - mImplementation->terminate(); - - mDeviceLost = false; - - mInitialized = false; - - gl::UninitializeDebugAnnotations(); - - // TODO(jmadill): Store Platform in Display and deinit here. - ANGLEResetDisplayPlatform(this); - - return NoError(); -} - -std::vector<const Config*> Display::getConfigs(const egl::AttributeMap &attribs) const -{ - return mConfigSet.filter(attribs); -} - -Error Display::createWindowSurface(const Config *configuration, - EGLNativeWindowType window, - const AttributeMap &attribs, - Surface **outSurface) -{ - if (mImplementation->testDeviceLost()) - { - ANGLE_TRY(restoreLostDevice()); - } - - SurfacePointer surface(new WindowSurface(mImplementation, configuration, window, attribs), - this); - ANGLE_TRY(surface->initialize(this)); - - ASSERT(outSurface != nullptr); - *outSurface = surface.release(); - mState.surfaceSet.insert(*outSurface); - - WindowSurfaceMap *windowSurfaces = GetWindowSurfaces(); - ASSERT(windowSurfaces && windowSurfaces->find(window) == windowSurfaces->end()); - windowSurfaces->insert(std::make_pair(window, *outSurface)); - - return NoError(); -} - -Error Display::createPbufferSurface(const Config *configuration, - const AttributeMap &attribs, - Surface **outSurface) -{ - ASSERT(isInitialized()); - - if (mImplementation->testDeviceLost()) - { - ANGLE_TRY(restoreLostDevice()); - } - - SurfacePointer surface(new PbufferSurface(mImplementation, configuration, attribs), this); - ANGLE_TRY(surface->initialize(this)); - - ASSERT(outSurface != nullptr); - *outSurface = surface.release(); - mState.surfaceSet.insert(*outSurface); - - return NoError(); -} - -Error Display::createPbufferFromClientBuffer(const Config *configuration, - EGLenum buftype, - EGLClientBuffer clientBuffer, - const AttributeMap &attribs, - Surface **outSurface) -{ - ASSERT(isInitialized()); - - if (mImplementation->testDeviceLost()) - { - ANGLE_TRY(restoreLostDevice()); - } - - SurfacePointer surface( - new PbufferSurface(mImplementation, configuration, buftype, clientBuffer, attribs), this); - ANGLE_TRY(surface->initialize(this)); - - ASSERT(outSurface != nullptr); - *outSurface = surface.release(); - mState.surfaceSet.insert(*outSurface); - - return NoError(); -} - -Error Display::createPixmapSurface(const Config *configuration, - NativePixmapType nativePixmap, - const AttributeMap &attribs, - Surface **outSurface) -{ - ASSERT(isInitialized()); - - if (mImplementation->testDeviceLost()) - { - ANGLE_TRY(restoreLostDevice()); - } - - SurfacePointer surface(new PixmapSurface(mImplementation, configuration, nativePixmap, attribs), - this); - ANGLE_TRY(surface->initialize(this)); - - ASSERT(outSurface != nullptr); - *outSurface = surface.release(); - mState.surfaceSet.insert(*outSurface); - - return NoError(); -} - -Error Display::createImage(const gl::Context *context, - EGLenum target, - EGLClientBuffer buffer, - const AttributeMap &attribs, - Image **outImage) -{ - ASSERT(isInitialized()); - - if (mImplementation->testDeviceLost()) - { - ANGLE_TRY(restoreLostDevice()); - } - - egl::ImageSibling *sibling = nullptr; - if (IsTextureTarget(target)) - { - sibling = context->getTexture(egl_gl::EGLClientBufferToGLObjectHandle(buffer)); - } - else if (IsRenderbufferTarget(target)) - { - sibling = context->getRenderbuffer(egl_gl::EGLClientBufferToGLObjectHandle(buffer)); - } - else - { - UNREACHABLE(); - } - ASSERT(sibling != nullptr); - - angle::UniqueObjectPointer<Image, gl::Context> imagePtr( - new Image(mImplementation, target, sibling, attribs), context); - ANGLE_TRY(imagePtr->initialize()); - - Image *image = imagePtr.release(); - - ASSERT(outImage != nullptr); - *outImage = image; - - // Add this image to the list of all images and hold a ref to it. - image->addRef(); - mImageSet.insert(image); - - return NoError(); -} - -Error Display::createStream(const AttributeMap &attribs, Stream **outStream) -{ - ASSERT(isInitialized()); - - Stream *stream = new Stream(this, attribs); - - ASSERT(stream != nullptr); - mStreamSet.insert(stream); - - ASSERT(outStream != nullptr); - *outStream = stream; - - return NoError(); -} - -Error Display::createContext(const Config *configuration, - gl::Context *shareContext, - const AttributeMap &attribs, - gl::Context **outContext) -{ - ASSERT(isInitialized()); - - if (mImplementation->testDeviceLost()) - { - ANGLE_TRY(restoreLostDevice()); - } - - // This display texture sharing will allow the first context to create the texture share group. - bool usingDisplayTextureShareGroup = - attribs.get(EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE, EGL_FALSE) == EGL_TRUE; - gl::TextureManager *shareTextures = nullptr; - - if (usingDisplayTextureShareGroup) - { - ASSERT((mTextureManager == nullptr) == (mGlobalTextureShareGroupUsers == 0)); - if (mTextureManager == nullptr) - { - mTextureManager = new gl::TextureManager(); - } - - mGlobalTextureShareGroupUsers++; - shareTextures = mTextureManager; - } - - gl::MemoryProgramCache *cachePointer = &mMemoryProgramCache; - - // Check context creation attributes to see if we should enable the cache. - if (mAttributeMap.get(EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE, EGL_TRUE) == EGL_FALSE) - { - cachePointer = nullptr; - } - - // A program cache size of zero indicates it should be disabled. - if (mMemoryProgramCache.maxSize() == 0) - { - cachePointer = nullptr; - } - - gl::Context *context = - new gl::Context(mImplementation, configuration, shareContext, shareTextures, cachePointer, - attribs, mDisplayExtensions); - - ASSERT(context != nullptr); - mContextSet.insert(context); - - ASSERT(outContext != nullptr); - *outContext = context; - return NoError(); -} - -Error Display::makeCurrent(egl::Surface *drawSurface, - egl::Surface *readSurface, - gl::Context *context) -{ - ANGLE_TRY(mImplementation->makeCurrent(drawSurface, readSurface, context)); - - if (context != nullptr) - { - ASSERT(readSurface == drawSurface); - ANGLE_TRY(context->makeCurrent(this, drawSurface)); - } - - return NoError(); -} - -Error Display::restoreLostDevice() -{ - for (ContextSet::iterator ctx = mContextSet.begin(); ctx != mContextSet.end(); ctx++) - { - if ((*ctx)->isResetNotificationEnabled()) - { - // If reset notifications have been requested, application must delete all contexts first - return EglContextLost(); - } - } - - return mImplementation->restoreLostDevice(this); -} - -Error Display::destroySurface(Surface *surface) -{ - if (surface->getType() == EGL_WINDOW_BIT) - { - WindowSurfaceMap *windowSurfaces = GetWindowSurfaces(); - ASSERT(windowSurfaces); - - bool surfaceRemoved = false; - for (WindowSurfaceMap::iterator iter = windowSurfaces->begin(); iter != windowSurfaces->end(); iter++) - { - if (iter->second == surface) - { - windowSurfaces->erase(iter); - surfaceRemoved = true; - break; - } - } - - ASSERT(surfaceRemoved); - } - - mState.surfaceSet.erase(surface); - ANGLE_TRY(surface->onDestroy(this)); - return NoError(); -} - -void Display::destroyImage(egl::Image *image) -{ - auto iter = mImageSet.find(image); - ASSERT(iter != mImageSet.end()); - (*iter)->release(mProxyContext.get()); - mImageSet.erase(iter); -} - -void Display::destroyStream(egl::Stream *stream) -{ - mStreamSet.erase(stream); - SafeDelete(stream); -} - -Error Display::destroyContext(gl::Context *context) -{ - if (context->usingDisplayTextureShareGroup()) - { - ASSERT(mGlobalTextureShareGroupUsers >= 1 && mTextureManager != nullptr); - if (mGlobalTextureShareGroupUsers == 1) - { - // If this is the last context using the global share group, destroy the global texture - // manager so that the textures can be destroyed while a context still exists - mTextureManager->release(context); - mTextureManager = nullptr; - } - mGlobalTextureShareGroupUsers--; - } - - ANGLE_TRY(context->onDestroy(this)); - mContextSet.erase(context); - SafeDelete(context); - return NoError(); -} - -bool Display::isDeviceLost() const -{ - ASSERT(isInitialized()); - return mDeviceLost; -} - -bool Display::testDeviceLost() -{ - ASSERT(isInitialized()); - - if (!mDeviceLost && mImplementation->testDeviceLost()) - { - notifyDeviceLost(); - } - - return mDeviceLost; -} - -void Display::notifyDeviceLost() -{ - if (mDeviceLost) - { - return; - } - - for (ContextSet::iterator context = mContextSet.begin(); context != mContextSet.end(); context++) - { - (*context)->markContextLost(); - } - - mDeviceLost = true; -} - -Error Display::waitClient(const gl::Context *context) const -{ - return mImplementation->waitClient(context); -} - -Error Display::waitNative(const gl::Context *context, EGLint engine) const -{ - return mImplementation->waitNative(context, engine); -} - -const Caps &Display::getCaps() const -{ - return mCaps; -} - -bool Display::isInitialized() const -{ - return mInitialized; -} - -bool Display::isValidConfig(const Config *config) const -{ - return mConfigSet.contains(config); -} - -bool Display::isValidContext(const gl::Context *context) const -{ - return mContextSet.find(const_cast<gl::Context *>(context)) != mContextSet.end(); -} - -bool Display::isValidSurface(const Surface *surface) const -{ - return mState.surfaceSet.find(const_cast<Surface *>(surface)) != mState.surfaceSet.end(); -} - -bool Display::isValidImage(const Image *image) const -{ - return mImageSet.find(const_cast<Image *>(image)) != mImageSet.end(); -} - -bool Display::isValidStream(const Stream *stream) const -{ - return mStreamSet.find(const_cast<Stream *>(stream)) != mStreamSet.end(); -} - -bool Display::hasExistingWindowSurface(EGLNativeWindowType window) -{ - WindowSurfaceMap *windowSurfaces = GetWindowSurfaces(); - ASSERT(windowSurfaces); - - return windowSurfaces->find(window) != windowSurfaces->end(); -} - -static ClientExtensions GenerateClientExtensions() -{ - ClientExtensions extensions; - - extensions.clientExtensions = true; - extensions.platformBase = true; - extensions.platformANGLE = true; - -#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11) - extensions.platformANGLED3D = true; - extensions.platformDevice = true; -#endif - -#if defined(ANGLE_ENABLE_OPENGL) - extensions.platformANGLEOpenGL = true; -#endif - -#if defined(ANGLE_ENABLE_NULL) - extensions.platformANGLENULL = true; -#endif - -#if defined(ANGLE_ENABLE_D3D11) - extensions.deviceCreation = true; - extensions.deviceCreationD3D11 = true; - extensions.experimentalPresentPath = true; -#endif - -#if defined(ANGLE_ENABLE_VULKAN) - extensions.platformANGLEVulkan = true; -#endif - -#if defined(ANGLE_USE_X11) - extensions.x11Visual = true; -#endif - - extensions.clientGetAllProcAddresses = true; - - return extensions; -} - -template <typename T> -static std::string GenerateExtensionsString(const T &extensions) -{ - std::vector<std::string> extensionsVector = extensions.getStrings(); - - std::ostringstream stream; - std::copy(extensionsVector.begin(), extensionsVector.end(), std::ostream_iterator<std::string>(stream, " ")); - return stream.str(); -} - -// static -const ClientExtensions &Display::GetClientExtensions() -{ - static const ClientExtensions clientExtensions = GenerateClientExtensions(); - return clientExtensions; -} - -// static -const std::string &Display::GetClientExtensionString() -{ - static const std::string clientExtensionsString = - GenerateExtensionsString(GetClientExtensions()); - return clientExtensionsString; -} - -void Display::initDisplayExtensions() -{ - mDisplayExtensions = mImplementation->getExtensions(); - - // Some extensions are always available because they are implemented in the EGL layer. - mDisplayExtensions.createContext = true; - mDisplayExtensions.createContextNoError = true; - mDisplayExtensions.createContextWebGLCompatibility = true; - mDisplayExtensions.createContextBindGeneratesResource = true; - mDisplayExtensions.createContextClientArrays = true; - mDisplayExtensions.pixelFormatFloat = true; - - // Force EGL_KHR_get_all_proc_addresses on. - mDisplayExtensions.getAllProcAddresses = true; - - // Enable program cache control since it is not back-end dependent. - mDisplayExtensions.programCacheControl = true; - - mDisplayExtensionString = GenerateExtensionsString(mDisplayExtensions); -} - -bool Display::isValidNativeWindow(EGLNativeWindowType window) const -{ - return mImplementation->isValidNativeWindow(window); -} - -Error Display::validateClientBuffer(const Config *configuration, - EGLenum buftype, - EGLClientBuffer clientBuffer, - const AttributeMap &attribs) -{ - return mImplementation->validateClientBuffer(configuration, buftype, clientBuffer, attribs); -} - -bool Display::isValidDisplay(const egl::Display *display) -{ - const ANGLEPlatformDisplayMap *anglePlatformDisplayMap = GetANGLEPlatformDisplayMap(); - for (const auto &displayPair : *anglePlatformDisplayMap) - { - if (displayPair.second == display) - { - return true; - } - } - - const DevicePlatformDisplayMap *devicePlatformDisplayMap = GetDevicePlatformDisplayMap(); - for (const auto &displayPair : *devicePlatformDisplayMap) - { - if (displayPair.second == display) - { - return true; - } - } - - return false; -} - -bool Display::isValidNativeDisplay(EGLNativeDisplayType display) -{ - // TODO(jmadill): handle this properly - if (display == EGL_DEFAULT_DISPLAY) - { - return true; - } - -#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(ANGLE_ENABLE_WINDOWS_STORE) - if (display == EGL_SOFTWARE_DISPLAY_ANGLE || - display == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE || - display == EGL_D3D11_ONLY_DISPLAY_ANGLE) - { - return true; - } - return (WindowFromDC(display) != nullptr); -#else - return true; -#endif -} - -void Display::initVendorString() -{ - mVendorString = mImplementation->getVendorString(); -} - -const DisplayExtensions &Display::getExtensions() const -{ - return mDisplayExtensions; -} - -const std::string &Display::getExtensionString() const -{ - return mDisplayExtensionString; -} - -const std::string &Display::getVendorString() const -{ - return mVendorString; -} - -Device *Display::getDevice() const -{ - return mDevice; -} - -gl::Version Display::getMaxSupportedESVersion() const -{ - return mImplementation->getMaxSupportedESVersion(); -} - -EGLint Display::programCacheGetAttrib(EGLenum attrib) const -{ - switch (attrib) - { - case EGL_PROGRAM_CACHE_KEY_LENGTH_ANGLE: - return static_cast<EGLint>(gl::kProgramHashLength); - - case EGL_PROGRAM_CACHE_SIZE_ANGLE: - return static_cast<EGLint>(mMemoryProgramCache.entryCount()); - - default: - UNREACHABLE(); - return 0; - } -} - -Error Display::programCacheQuery(EGLint index, - void *key, - EGLint *keysize, - void *binary, - EGLint *binarysize) -{ - ASSERT(index >= 0 && index < static_cast<EGLint>(mMemoryProgramCache.entryCount())); - - const angle::MemoryBuffer *programBinary = nullptr; - gl::ProgramHash programHash; - // TODO(jmadill): Make this thread-safe. - bool result = - mMemoryProgramCache.getAt(static_cast<size_t>(index), &programHash, &programBinary); - if (!result) - { - return EglBadAccess() << "Program binary not accessible."; - } - - ASSERT(keysize && binarysize); - - if (key) - { - ASSERT(*keysize == static_cast<EGLint>(gl::kProgramHashLength)); - memcpy(key, programHash.data(), gl::kProgramHashLength); - } - - if (binary) - { - // Note: we check the size here instead of in the validation code, since we need to - // access the cache as atomically as possible. It's possible that the cache contents - // could change between the validation size check and the retrieval. - if (programBinary->size() > static_cast<size_t>(*binarysize)) - { - return EglBadAccess() << "Program binary too large or changed during access."; - } - - memcpy(binary, programBinary->data(), programBinary->size()); - } - - *binarysize = static_cast<EGLint>(programBinary->size()); - *keysize = static_cast<EGLint>(gl::kProgramHashLength); - - return NoError(); -} - -Error Display::programCachePopulate(const void *key, - EGLint keysize, - const void *binary, - EGLint binarysize) -{ - ASSERT(keysize == static_cast<EGLint>(gl::kProgramHashLength)); - - gl::ProgramHash programHash; - memcpy(programHash.data(), key, gl::kProgramHashLength); - - mMemoryProgramCache.putBinary(programHash, reinterpret_cast<const uint8_t *>(binary), - static_cast<size_t>(binarysize)); - return NoError(); -} - -EGLint Display::programCacheResize(EGLint limit, EGLenum mode) -{ - switch (mode) - { - case EGL_PROGRAM_CACHE_RESIZE_ANGLE: - { - size_t initialSize = mMemoryProgramCache.size(); - mMemoryProgramCache.resize(static_cast<size_t>(limit)); - return static_cast<EGLint>(initialSize); - } - - case EGL_PROGRAM_CACHE_TRIM_ANGLE: - return static_cast<EGLint>(mMemoryProgramCache.trim(static_cast<size_t>(limit))); - - default: - UNREACHABLE(); - return 0; - } -} - -} // namespace egl |