winrt: Add support for offscreen surfaces

Previously offscreen surfaces were only needed to properly shutdown Qt
Quick applications and the scene graph to have something to potentially
render into but not show on the screen.

However, Canvas3D requires a fully functional surface, preferably
offscreen. Hence we use the QEGLPbuffer provided by eglconvenience in
platformsupport.

Task-number: QTBUG-50576
Change-Id: I1a32820bb2f2c6823be4e96dd92cf7965566f2c3
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@theqtcompany.com>
Reviewed-by: Andrew Knight <andrew.knight@intopalo.com>
bb10
Maurice Kalinowski 2016-01-26 10:49:31 +01:00
parent a1ba281a26
commit ba7f76dea0
3 changed files with 38 additions and 13 deletions

View File

@ -49,6 +49,7 @@
#include <QOffscreenSurface>
#include <QOpenGLContext>
#include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <QtPlatformSupport/private/qeglpbuffer_p.h>
QT_BEGIN_NAMESPACE
@ -148,14 +149,17 @@ bool QWinRTEGLContext::makeCurrent(QPlatformSurface *windowSurface)
Q_D(QWinRTEGLContext);
Q_ASSERT(windowSurface->surface()->supportsOpenGL());
if (windowSurface->surface()->surfaceClass() == QSurface::Offscreen)
return false;
EGLSurface surface;
if (windowSurface->surface()->surfaceClass() == QSurface::Window) {
QWinRTWindow *window = static_cast<QWinRTWindow *>(windowSurface);
if (window->eglSurface() == EGL_NO_SURFACE)
window->createEglSurface(g->eglDisplay, d->eglConfig);
QWinRTWindow *window = static_cast<QWinRTWindow *>(windowSurface);
if (window->eglSurface() == EGL_NO_SURFACE)
window->createEglSurface(g->eglDisplay, d->eglConfig);
surface = window->eglSurface();
} else { // Offscreen
surface = static_cast<QEGLPbuffer *>(windowSurface)->pbuffer();
}
EGLSurface surface = window->eglSurface();
if (surface == EGL_NO_SURFACE)
return false;
@ -346,4 +350,9 @@ QFunctionPointer QWinRTEGLContext::getProcAddress(const QByteArray &procName)
return eglGetProcAddress(procName.constData());
}
EGLDisplay QWinRTEGLContext::display()
{
return g->eglDisplay;
}
QT_END_NAMESPACE

View File

@ -38,6 +38,7 @@
#define QWINDOWSEGLCONTEXT_H
#include <qpa/qplatformopenglcontext.h>
#include <EGL/egl.h>
QT_BEGIN_NAMESPACE
@ -57,6 +58,7 @@ public:
QSurfaceFormat format() const Q_DECL_OVERRIDE;
QFunctionPointer getProcAddress(const QByteArray &procName) Q_DECL_OVERRIDE;
static EGLDisplay display();
private:
QScopedPointer<QWinRTEGLContextPrivate> d_ptr;
Q_DECLARE_PRIVATE(QWinRTEGLContext)

View File

@ -45,12 +45,17 @@
#include "qwinrtfontdatabase.h"
#include "qwinrttheme.h"
#include <QtGui/QSurface>
#include <QtGui/QOffscreenSurface>
#include <QtGui/QOpenGLContext>
#include <qfunctions_winrt.h>
#include <QtGui/QSurface>
#include <QtPlatformSupport/private/qeglpbuffer_p.h>
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatformwindow.h>
#include <qpa/qplatformoffscreensurface.h>
#include <qfunctions_winrt.h>
#include <functional>
#include <wrl.h>
#include <windows.ui.xaml.h>
@ -385,11 +390,20 @@ HRESULT QWinRTIntegration::onResume(IInspectable *, IInspectable *)
QPlatformOffscreenSurface *QWinRTIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
{
// This is only used for shutdown of applications.
// In case we do not return an empty surface the scenegraph will try
// to create a new native window during application exit causing crashes
// or assertions.
return new QPlatformOffscreenSurface(surface);
QEGLPbuffer *pbuffer = nullptr;
HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([&pbuffer, surface]() {
pbuffer = new QEGLPbuffer(QWinRTEGLContext::display(), surface->requestedFormat(), surface);
return S_OK;
});
if (hr == UI_E_WINDOW_CLOSED) {
// This is only used for shutdown of applications.
// In case we do not return an empty surface the scenegraph will try
// to create a new native window during application exit causing crashes
// or assertions.
return new QPlatformOffscreenSurface(surface);
}
return pbuffer;
}