summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/winrt/qwinrteglcontext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/winrt/qwinrteglcontext.cpp')
-rw-r--r--src/plugins/platforms/winrt/qwinrteglcontext.cpp68
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