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 <oliver.wolff@digia.com>
This commit is contained in:
Andrew Knight 2014-03-07 15:57:28 +02:00 committed by The Qt Project
parent 04a632c88a
commit d38786deba
2 changed files with 29 additions and 5 deletions

View File

@ -207,14 +207,24 @@ QWinRTBackingStore::QWinRTBackingStore(QWindow *window)
, m_fbo(0)
, m_texture(0)
, m_screen(static_cast<QWinRTScreen*>(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 &region, const QPoint &offset)
{
Q_UNUSED(offset)
if (m_size.isEmpty())
return;
const QImage *image = static_cast<QImage *>(m_paintDevice.data());
@ -334,10 +349,16 @@ void QWinRTBackingStore::flush(QWindow *window, const QRegion &region, 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 &region)
{
Q_UNUSED(region)
resize(window()->size(), QRegion());
}
void QWinRTBackingStore::endPaint()

View File

@ -62,6 +62,8 @@ public:
void resize(const QSize &size, const QRegion &staticContents);
private:
bool initialize();
bool m_initialized;
QSize m_size;
QScopedPointer<QPaintDevice> m_paintDevice;
QScopedPointer<QOpenGLContext> m_context;