diff options
Diffstat (limited to 'src/plugins/platforms/winrt/qwinrteglcontext.cpp')
-rw-r--r-- | src/plugins/platforms/winrt/qwinrteglcontext.cpp | 68 |
1 files changed, 50 insertions, 18 deletions
diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.cpp b/src/plugins/platforms/winrt/qwinrteglcontext.cpp index 9cb45336d6..3fd0278360 100644 --- a/src/plugins/platforms/winrt/qwinrteglcontext.cpp +++ b/src/plugins/platforms/winrt/qwinrteglcontext.cpp @@ -40,6 +40,8 @@ #include <functional> +#include <d3d11.h> + #include <EGL/egl.h> #define EGL_EGLEXT_PROTOTYPES #include <EGL/eglext.h> @@ -49,13 +51,30 @@ QT_BEGIN_NAMESPACE +struct WinRTEGLDisplay +{ + WinRTEGLDisplay() { + eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (eglDisplay == EGL_NO_DISPLAY) + qCritical("Failed to initialize EGL display: 0x%x", eglGetError()); + } + ~WinRTEGLDisplay() { + eglTerminate(eglDisplay); + } + + EGLDisplay eglDisplay; +}; + +Q_GLOBAL_STATIC(WinRTEGLDisplay, g) + class QWinRTEGLContextPrivate { public: + QWinRTEGLContextPrivate() : eglContext(EGL_NO_CONTEXT), eglShareContext(EGL_NO_CONTEXT) { } QSurfaceFormat format; - EGLDisplay eglDisplay; EGLConfig eglConfig; EGLContext eglContext; + EGLContext eglShareContext; }; QWinRTEGLContext::QWinRTEGLContext(QOpenGLContext *context) @@ -64,30 +83,44 @@ QWinRTEGLContext::QWinRTEGLContext(QOpenGLContext *context) Q_D(QWinRTEGLContext); d->format = context->format(); d->format.setRenderableType(QSurfaceFormat::OpenGLES); + if (QPlatformOpenGLContext *shareHandle = context->shareHandle()) + d->eglShareContext = static_cast<QWinRTEGLContext *>(shareHandle)->d_ptr->eglContext; } QWinRTEGLContext::~QWinRTEGLContext() { Q_D(QWinRTEGLContext); if (d->eglContext != EGL_NO_CONTEXT) - eglDestroyContext(d->eglDisplay, d->eglContext); - if (d->eglDisplay != EGL_NO_DISPLAY) - eglTerminate(d->eglDisplay); + eglDestroyContext(g->eglDisplay, d->eglContext); } void QWinRTEGLContext::initialize() { Q_D(QWinRTEGLContext); + // Test if the hardware supports at least level 9_3 + D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_9_3 }; // minimum feature level + HRESULT hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, featureLevels, 1, + D3D11_SDK_VERSION, nullptr, nullptr, nullptr); + EGLint deviceType = SUCCEEDED(hr) ? EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE + : EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE; + eglBindAPI(EGL_OPENGL_ES_API); - d->eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); - if (d->eglDisplay == EGL_NO_DISPLAY) + + const EGLint displayAttributes[] = { + EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, + EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, deviceType, + EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, true, + EGL_NONE, + }; + g->eglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, displayAttributes); + if (g->eglDisplay == EGL_NO_DISPLAY) qCritical("Failed to initialize EGL display: 0x%x", eglGetError()); - if (!eglInitialize(d->eglDisplay, nullptr, nullptr)) + if (!eglInitialize(g->eglDisplay, nullptr, nullptr)) qCritical("Failed to initialize EGL: 0x%x", eglGetError()); - d->eglConfig = q_configFromGLFormat(d->eglDisplay, d->format); + d->eglConfig = q_configFromGLFormat(g->eglDisplay, d->format); const EGLint flags = d->format.testOption(QSurfaceFormat::DebugContext) ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0; @@ -97,7 +130,7 @@ void QWinRTEGLContext::initialize() EGL_CONTEXT_FLAGS_KHR, flags, EGL_NONE }; - d->eglContext = eglCreateContext(d->eglDisplay, d->eglConfig, nullptr, attributes); + d->eglContext = eglCreateContext(g->eglDisplay, d->eglConfig, d->eglShareContext, attributes); if (d->eglContext == EGL_NO_CONTEXT) { qWarning("QEGLPlatformContext: Failed to create context: %x", eglGetError()); return; @@ -107,41 +140,40 @@ void QWinRTEGLContext::initialize() bool QWinRTEGLContext::makeCurrent(QPlatformSurface *windowSurface) { Q_D(QWinRTEGLContext); - Q_ASSERT(windowSurface->surface()->surfaceType() == QSurface::OpenGLSurface); + Q_ASSERT(windowSurface->surface()->supportsOpenGL()); QWinRTWindow *window = static_cast<QWinRTWindow *>(windowSurface); if (window->eglSurface() == EGL_NO_SURFACE) - window->createEglSurface(d->eglDisplay, d->eglConfig); + window->createEglSurface(g->eglDisplay, d->eglConfig); EGLSurface surface = window->eglSurface(); if (surface == EGL_NO_SURFACE) return false; - const bool ok = eglMakeCurrent(d->eglDisplay, surface, surface, d->eglContext); + const bool ok = eglMakeCurrent(g->eglDisplay, surface, surface, d->eglContext); if (!ok) { qWarning("QEGLPlatformContext: eglMakeCurrent failed: %x", eglGetError()); return false; } - eglSwapInterval(d->eglDisplay, d->format.swapInterval()); + eglSwapInterval(g->eglDisplay, d->format.swapInterval()); return true; } void QWinRTEGLContext::doneCurrent() { - Q_D(const QWinRTEGLContext); - const bool ok = eglMakeCurrent(d->eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + const bool ok = eglMakeCurrent(g->eglDisplay, EGL_NO_SURFACE, + EGL_NO_SURFACE, EGL_NO_CONTEXT); if (!ok) qWarning("QEGLPlatformContext: eglMakeCurrent failed: %x", eglGetError()); } void QWinRTEGLContext::swapBuffers(QPlatformSurface *windowSurface) { - Q_D(QWinRTEGLContext); - Q_ASSERT(windowSurface->surface()->surfaceType() == QSurface::OpenGLSurface); + Q_ASSERT(windowSurface->surface()->supportsOpenGL()); const QWinRTWindow *window = static_cast<QWinRTWindow *>(windowSurface); - eglSwapBuffers(d->eglDisplay, window->eglSurface()); + eglSwapBuffers(g->eglDisplay, window->eglSurface()); } QSurfaceFormat QWinRTEGLContext::format() const |