diff options
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/Display.cpp')
-rw-r--r-- | src/3rdparty/angle/src/libANGLE/Display.cpp | 426 |
1 files changed, 377 insertions, 49 deletions
diff --git a/src/3rdparty/angle/src/libANGLE/Display.cpp b/src/3rdparty/angle/src/libANGLE/Display.cpp index 1f54f82dea..486c74abc0 100644 --- a/src/3rdparty/angle/src/libANGLE/Display.cpp +++ b/src/3rdparty/angle/src/libANGLE/Display.cpp @@ -22,9 +22,15 @@ #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/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" @@ -33,6 +39,10 @@ #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" # else # error Unsupported OpenGL platform. # endif @@ -66,19 +76,6 @@ void InitDefaultPlatformImpl() } } -void DeinitDefaultPlatformImpl() -{ - if (defaultPlatform != nullptr) - { - if (ANGLEPlatformCurrent() == defaultPlatform) - { - ANGLEPlatformShutdown(); - } - - SafeDelete(defaultPlatform); - } -} - 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. @@ -88,14 +85,52 @@ static WindowSurfaceMap *GetWindowSurfaces() return &windowSurfaces; } -typedef std::map<EGLNativeDisplayType, Display*> DisplayMap; -static DisplayMap *GetDisplayMap() +typedef std::map<EGLNativeDisplayType, Display *> ANGLEPlatformDisplayMap; +static ANGLEPlatformDisplayMap *GetANGLEPlatformDisplayMap() +{ + static ANGLEPlatformDisplayMap displays; + return &displays; +} + +typedef std::map<Device *, Display *> DevicePlatformDisplayMap; +static DevicePlatformDisplayMap *GetDevicePlatformDisplayMap() { - static DisplayMap displays; + static DevicePlatformDisplayMap displays; return &displays; } -rx::DisplayImpl *CreateDisplayImpl(const AttributeMap &attribMap) +rx::DisplayImpl *CreateDisplayFromDevice(Device *eglDevice) +{ + rx::DisplayImpl *impl = nullptr; + + switch (eglDevice->getType()) + { +#if defined(ANGLE_ENABLE_D3D11) + case EGL_D3D11_DEVICE_ANGLE: + impl = new rx::DisplayD3D(); + 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) { rx::DisplayImpl *impl = nullptr; EGLint displayType = attribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE); @@ -105,6 +140,10 @@ rx::DisplayImpl *CreateDisplayImpl(const AttributeMap &attribMap) #if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11) // Default to D3D displays impl = new rx::DisplayD3D(); +#elif defined(ANGLE_USE_X11) + impl = new rx::DisplayGLX(); +#elif defined(ANGLE_PLATFORM_APPLE) + impl = new rx::DisplayCGL(); #else // No display available UNREACHABLE(); @@ -125,6 +164,10 @@ rx::DisplayImpl *CreateDisplayImpl(const AttributeMap &attribMap) #if defined(ANGLE_ENABLE_OPENGL) #if defined(ANGLE_PLATFORM_WINDOWS) impl = new rx::DisplayWGL(); +#elif defined(ANGLE_USE_X11) + impl = new rx::DisplayGLX(); +#elif defined(ANGLE_PLATFORM_APPLE) + impl = new rx::DisplayCGL(); #else #error Unsupported OpenGL platform. #endif @@ -133,26 +176,40 @@ rx::DisplayImpl *CreateDisplayImpl(const AttributeMap &attribMap) #endif break; +#if defined(ANGLE_ENABLE_OPENGL) + case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE: +#if defined(ANGLE_PLATFORM_WINDOWS) + impl = new rx::DisplayWGL(); +#elif defined(ANGLE_USE_X11) + impl = new rx::DisplayGLX(); +#else + // No GLES support on this platform, fail display creation. + impl = nullptr; +#endif + break; +#endif + default: UNREACHABLE(); break; } - ASSERT(impl != nullptr); return impl; } } -Display *Display::getDisplay(EGLNativeDisplayType displayId, const AttributeMap &attribMap) +Display *Display::GetDisplayFromAttribs(void *native_display, const AttributeMap &attribMap) { // Initialize the global platform if not already InitDefaultPlatformImpl(); - Display *display = NULL; + Display *display = nullptr; + + EGLNativeDisplayType displayId = reinterpret_cast<EGLNativeDisplayType>(native_display); - DisplayMap *displays = GetDisplayMap(); - DisplayMap::const_iterator iter = displays->find(displayId); + ANGLEPlatformDisplayMap *displays = GetANGLEPlatformDisplayMap(); + ANGLEPlatformDisplayMap::const_iterator iter = displays->find(displayId); if (iter != displays->end()) { display = iter->second; @@ -166,21 +223,77 @@ Display *Display::getDisplay(EGLNativeDisplayType displayId, const AttributeMap return NULL; } - display = new Display(displayId); + display = new Display(EGL_PLATFORM_ANGLE_ANGLE, displayId, nullptr); displays->insert(std::make_pair(displayId, display)); } // Apply new attributes if the display is not initialized yet. if (!display->isInitialized()) { - rx::DisplayImpl* impl = CreateDisplayImpl(attribMap); + rx::DisplayImpl *impl = CreateDisplayFromAttribs(attribMap); + if (impl == nullptr) + { + // No valid display implementation for these attributes + return nullptr; + } + display->setAttributes(impl, attribMap); } return display; } -Display::Display(EGLNativeDisplayType displayId) +Display *Display::GetDisplayFromDevice(void *native_display) +{ + // Initialize the global platform if not already + InitDefaultPlatformImpl(); + + Display *display = nullptr; + + Device *eglDevice = reinterpret_cast<Device *>(native_display); + ASSERT(Device::IsValidDevice(eglDevice)); + + 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() == eglDevice) + { + display = iterDisplay; + } + } + + if (display == nullptr) + { + // See if the eglDevice is in use by a Display created using the DEVICE platform + DevicePlatformDisplayMap::const_iterator iter = devicePlatformDisplays->find(eglDevice); + if (iter != devicePlatformDisplays->end()) + { + display = iter->second; + } + } + + if (display == nullptr) + { + // Otherwise create a new Display + display = new Display(EGL_PLATFORM_DEVICE_EXT, 0, eglDevice); + devicePlatformDisplays->insert(std::make_pair(eglDevice, display)); + } + + // Apply new attributes if the display is not initialized yet. + if (!display->isInitialized()) + { + rx::DisplayImpl *impl = CreateDisplayFromDevice(eglDevice); + display->setAttributes(impl, egl::AttributeMap()); + } + + return display; +} + +Display::Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDevice) : mImplementation(nullptr), mDisplayId(displayId), mAttributeMap(), @@ -190,7 +303,9 @@ Display::Display(EGLNativeDisplayType displayId) mCaps(), mDisplayExtensions(), mDisplayExtensionString(), - mVendorString() + mVendorString(), + mDevice(eglDevice), + mPlatform(platform) { } @@ -198,13 +313,30 @@ Display::~Display() { terminate(); - DisplayMap *displays = GetDisplayMap(); - DisplayMap::iterator iter = displays->find(mDisplayId); - if (iter != displays->end()) + 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 { - displays->erase(iter); + UNREACHABLE(); } + SafeDelete(mDevice); SafeDelete(mImplementation); } @@ -221,6 +353,12 @@ void Display::setAttributes(rx::DisplayImpl *impl, const AttributeMap &attribMap Error Display::initialize() { + // Re-initialize default platform if it's needed + InitDefaultPlatformImpl(); + + SCOPED_ANGLE_HISTOGRAM_TIMER("GPU.ANGLE.DisplayInitializeMS"); + TRACE_EVENT0("gpu.angle", "egl::Display::initialize"); + ASSERT(mImplementation != nullptr); if (isInitialized()) @@ -231,6 +369,11 @@ Error Display::initialize() Error error = mImplementation->initialize(this); if (error.isError()) { + // Log extended error message here + std::stringstream errorStream; + errorStream << "ANGLE Display::initialize error " << error.getID() << ": " + << error.getMessage(); + ANGLEPlatformCurrent()->logError(errorStream.str().c_str()); return error; } @@ -246,7 +389,38 @@ Error Display::initialize() 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; + error = mImplementation->getDevice(&impl); + if (error.isError()) + { + return error; + } + + error = Device::CreateDevice(this, impl, &mDevice); + if (error.isError()) + { + return error; + } + } + else + { + mDevice = nullptr; + } + } + else + { + // For EGL_PLATFORM_DEVICE_EXT, mDevice should always be populated using + // an external device + ASSERT(mDevice != nullptr); + } + mInitialized = true; + return Error(EGL_SUCCESS); } @@ -259,13 +433,30 @@ void Display::terminate() destroyContext(*mContextSet.begin()); } + while (!mImageSet.empty()) + { + destroyImage(*mImageSet.begin()); + } + + while (!mImplementation->getSurfaceSet().empty()) + { + destroySurface(*mImplementation->getSurfaceSet().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(); + mInitialized = false; - // De-init default platform - DeinitDefaultPlatformImpl(); + // Never de-init default platform.. terminate is not that final. } std::vector<const Config*> Display::getConfigs(const egl::AttributeMap &attribs) const @@ -288,6 +479,7 @@ bool Display::getConfigAttrib(const Config *configuration, EGLint attribute, EGL case EGL_CONFIG_ID: *value = configuration->configID; break; case EGL_LEVEL: *value = configuration->level; break; case EGL_NATIVE_RENDERABLE: *value = configuration->nativeRenderable; break; + case EGL_NATIVE_VISUAL_ID: *value = configuration->nativeVisualID; break; case EGL_NATIVE_VISUAL_TYPE: *value = configuration->nativeVisualType; break; case EGL_SAMPLES: *value = configuration->samples; break; case EGL_SAMPLE_BUFFERS: *value = configuration->sampleBuffers; break; @@ -309,6 +501,15 @@ bool Display::getConfigAttrib(const Config *configuration, EGLint attribute, EGL case EGL_MAX_PBUFFER_WIDTH: *value = configuration->maxPBufferWidth; break; case EGL_MAX_PBUFFER_HEIGHT: *value = configuration->maxPBufferHeight; break; case EGL_MAX_PBUFFER_PIXELS: *value = configuration->maxPBufferPixels; break; + + case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE: + if (!getExtensions().surfaceOrientation) + { + return false; + } + *value = configuration->optimalOrientation; + break; + default: return false; } @@ -328,14 +529,16 @@ Error Display::createWindowSurface(const Config *configuration, EGLNativeWindowT } } - rx::SurfaceImpl *surfaceImpl = nullptr; - Error error = mImplementation->createWindowSurface(configuration, window, attribs, &surfaceImpl); + rx::SurfaceImpl *surfaceImpl = mImplementation->createWindowSurface(configuration, window, attribs); + ASSERT(surfaceImpl != nullptr); + + Error error = surfaceImpl->initialize(); if (error.isError()) { + SafeDelete(surfaceImpl); return error; } - ASSERT(surfaceImpl != nullptr); Surface *surface = new Surface(surfaceImpl, EGL_WINDOW_BIT, configuration, attribs); mImplementation->getSurfaceSet().insert(surface); @@ -361,14 +564,16 @@ Error Display::createPbufferSurface(const Config *configuration, const Attribute } } - rx::SurfaceImpl *surfaceImpl = nullptr; - Error error = mImplementation->createPbufferSurface(configuration, attribs, &surfaceImpl); + rx::SurfaceImpl *surfaceImpl = mImplementation->createPbufferSurface(configuration, attribs); + ASSERT(surfaceImpl != nullptr); + + Error error = surfaceImpl->initialize(); if (error.isError()) { + SafeDelete(surfaceImpl); return error; } - ASSERT(surfaceImpl != nullptr); Surface *surface = new Surface(surfaceImpl, EGL_PBUFFER_BIT, configuration, attribs); mImplementation->getSurfaceSet().insert(surface); @@ -391,14 +596,16 @@ Error Display::createPbufferFromClientBuffer(const Config *configuration, EGLCli } } - rx::SurfaceImpl *surfaceImpl = nullptr; - Error error = mImplementation->createPbufferFromClientBuffer(configuration, shareHandle, attribs, &surfaceImpl); + rx::SurfaceImpl *surfaceImpl = mImplementation->createPbufferFromClientBuffer(configuration, shareHandle, attribs); + ASSERT(surfaceImpl != nullptr); + + Error error = surfaceImpl->initialize(); if (error.isError()) { + SafeDelete(surfaceImpl); return error; } - ASSERT(surfaceImpl != nullptr); Surface *surface = new Surface(surfaceImpl, EGL_PBUFFER_BIT, configuration, attribs); mImplementation->getSurfaceSet().insert(surface); @@ -421,14 +628,16 @@ Error Display::createPixmapSurface(const Config *configuration, NativePixmapType } } - rx::SurfaceImpl *surfaceImpl = nullptr; - Error error = mImplementation->createPixmapSurface(configuration, nativePixmap, attribs, &surfaceImpl); + rx::SurfaceImpl *surfaceImpl = mImplementation->createPixmapSurface(configuration, nativePixmap, attribs); + ASSERT(surfaceImpl != nullptr); + + Error error = surfaceImpl->initialize(); if (error.isError()) { + SafeDelete(surfaceImpl); return error; } - ASSERT(surfaceImpl != nullptr); Surface *surface = new Surface(surfaceImpl, EGL_PIXMAP_BIT, configuration, attribs); mImplementation->getSurfaceSet().insert(surface); @@ -437,8 +646,11 @@ Error Display::createPixmapSurface(const Config *configuration, NativePixmapType return Error(EGL_SUCCESS); } -Error Display::createContext(const Config *configuration, gl::Context *shareContext, const AttributeMap &attribs, - gl::Context **outContext) +Error Display::createImage(gl::Context *context, + EGLenum target, + EGLClientBuffer buffer, + const AttributeMap &attribs, + Image **outImage) { ASSERT(isInitialized()); @@ -451,13 +663,59 @@ Error Display::createContext(const Config *configuration, gl::Context *shareCont } } - gl::Context *context = nullptr; - Error error = mImplementation->createContext(configuration, shareContext, attribs, &context); + 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); + + rx::ImageImpl *imageImpl = mImplementation->createImage(target, sibling, attribs); + ASSERT(imageImpl != nullptr); + + Error error = imageImpl->initialize(); if (error.isError()) { return error; } + Image *image = new Image(imageImpl, target, sibling, attribs); + + 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 Error(EGL_SUCCESS); +} + +Error Display::createContext(const Config *configuration, gl::Context *shareContext, const AttributeMap &attribs, + gl::Context **outContext) +{ + ASSERT(isInitialized()); + + if (mImplementation->testDeviceLost()) + { + Error error = restoreLostDevice(); + if (error.isError()) + { + return error; + } + } + + gl::Context *context = *outContext = + mImplementation->createContext(configuration, shareContext, attribs); + ASSERT(context != nullptr); mContextSet.insert(context); @@ -474,8 +732,9 @@ Error Display::makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, return error; } - if (context && drawSurface) + if (context != nullptr && drawSurface != nullptr) { + ASSERT(readSurface == drawSurface); context->makeCurrent(drawSurface); } @@ -515,11 +774,20 @@ void Display::destroySurface(Surface *surface) } ASSERT(surfaceRemoved); + UNUSED_ASSERTION_VARIABLE(surfaceRemoved); } mImplementation->destroySurface(surface); } +void Display::destroyImage(egl::Image *image) +{ + auto iter = mImageSet.find(image); + ASSERT(iter != mImageSet.end()); + (*iter)->release(); + mImageSet.erase(iter); +} + void Display::destroyContext(gl::Context *context) { mContextSet.erase(context); @@ -546,6 +814,16 @@ void Display::notifyDeviceLost() } } +Error Display::waitClient() const +{ + return mImplementation->waitClient(); +} + +Error Display::waitNative(EGLint engine, egl::Surface *drawSurface, egl::Surface *readSurface) const +{ + return mImplementation->waitNative(engine, drawSurface, readSurface); +} + const Caps &Display::getCaps() const { return mCaps; @@ -571,6 +849,11 @@ bool Display::isValidSurface(Surface *surface) const return mImplementation->getSurfaceSet().find(surface) != mImplementation->getSurfaceSet().end(); } +bool Display::isValidImage(const Image *image) const +{ + return mImageSet.find(const_cast<Image *>(image)) != mImageSet.end(); +} + bool Display::hasExistingWindowSurface(EGLNativeWindowType window) { WindowSurfaceMap *windowSurfaces = GetWindowSurfaces(); @@ -589,12 +872,25 @@ static ClientExtensions GenerateClientExtensions() #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_D3D11) + extensions.deviceCreation = true; + extensions.deviceCreationD3D11 = true; + extensions.experimentalPresentPath = true; +#endif + +#if defined(ANGLE_USE_X11) + extensions.x11Visual = true; +#endif + + extensions.clientGetAllProcAddresses = true; + return extensions; } @@ -623,6 +919,10 @@ const std::string &Display::getClientExtensionString() void Display::initDisplayExtensions() { mDisplayExtensions = mImplementation->getExtensions(); + + // Force EGL_KHR_get_all_proc_addresses on. + mDisplayExtensions.getAllProcAddresses = true; + mDisplayExtensionString = GenerateExtensionsString(mDisplayExtensions); } @@ -631,6 +931,29 @@ bool Display::isValidNativeWindow(EGLNativeWindowType window) const return mImplementation->isValidNativeWindow(window); } +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 @@ -672,4 +995,9 @@ const std::string &Display::getVendorString() const return mVendorString; } +Device *Display::getDevice() const +{ + return mDevice; +} + } |