From d38786debadf8b5673f4e5706ea6c0f10129268d Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Fri, 7 Mar 2014 15:57:28 +0200 Subject: WinRT: Separate backing store initialization to be more robust If the GL context cannot be made current in the backing store's constructor, the framebuffer resources won't be allocated. Fix this by creating an initialization routine that can be called again if it fails. The issue was revealed by the GUI Analog Clock demo, which creates the backing store before the window has a native handle. Task-number: QTBUG-36008 Change-Id: I875f8183eff60908fc2b46f441bb553b42ff500d Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtbackingstore.cpp | 32 ++++++++++++++++++---- src/plugins/platforms/winrt/qwinrtbackingstore.h | 2 ++ 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp index 10136dbead..9b623048af 100644 --- a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp +++ b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp @@ -207,14 +207,24 @@ QWinRTBackingStore::QWinRTBackingStore(QWindow *window) , m_fbo(0) , m_texture(0) , m_screen(static_cast(window->screen()->handle())) + , m_initialized(false) { window->setSurfaceType(QSurface::OpenGLSurface); // Required for flipping, but could be done in the swap +} - m_context->setFormat(window->requestedFormat()); - m_context->setScreen(window->screen()); - m_context->create(); +bool QWinRTBackingStore::initialize() +{ + if (m_initialized) + return true; + + m_context->setFormat(window()->requestedFormat()); + m_context->setScreen(window()->screen()); + if (!m_context->create()) + return false; + + if (!m_context->makeCurrent(window())) + return false; - m_context->makeCurrent(window); glGenFramebuffers(1, &m_fbo); glGenRenderbuffers(1, &m_rbo); glGenTextures(1, &m_texture); @@ -258,11 +268,14 @@ QWinRTBackingStore::QWinRTBackingStore(QWindow *window) glProgramBinaryOES(m_shaderProgram, GL_PROGRAM_BINARY_ANGLE, binary.constData(), binary.size()); #endif m_context->doneCurrent(); - resize(window->size(), QRegion()); + m_initialized = true; + return true; } QWinRTBackingStore::~QWinRTBackingStore() { + if (!m_initialized) + return; glDeleteBuffers(1, &m_fbo); glDeleteRenderbuffers(1, &m_rbo); glDeleteTextures(1, &m_texture); @@ -277,6 +290,8 @@ QPaintDevice *QWinRTBackingStore::paintDevice() void QWinRTBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) { Q_UNUSED(offset) + if (m_size.isEmpty()) + return; const QImage *image = static_cast(m_paintDevice.data()); @@ -334,10 +349,16 @@ void QWinRTBackingStore::flush(QWindow *window, const QRegion ®ion, const QPo void QWinRTBackingStore::resize(const QSize &size, const QRegion &staticContents) { Q_UNUSED(staticContents) + if (!initialize()) + return; + if (m_size == size) return; m_size = size; + if (m_size.isEmpty()) + return; + m_paintDevice.reset(new QImage(m_size, QImage::Format_ARGB32_Premultiplied)); m_context->makeCurrent(window()); @@ -360,6 +381,7 @@ void QWinRTBackingStore::resize(const QSize &size, const QRegion &staticContents void QWinRTBackingStore::beginPaint(const QRegion ®ion) { Q_UNUSED(region) + resize(window()->size(), QRegion()); } void QWinRTBackingStore::endPaint() diff --git a/src/plugins/platforms/winrt/qwinrtbackingstore.h b/src/plugins/platforms/winrt/qwinrtbackingstore.h index 8be549b441..726f7c838f 100644 --- a/src/plugins/platforms/winrt/qwinrtbackingstore.h +++ b/src/plugins/platforms/winrt/qwinrtbackingstore.h @@ -62,6 +62,8 @@ public: void resize(const QSize &size, const QRegion &staticContents); private: + bool initialize(); + bool m_initialized; QSize m_size; QScopedPointer m_paintDevice; QScopedPointer m_context; -- cgit v1.2.3