diff options
author | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2017-10-03 19:24:50 +0200 |
---|---|---|
committer | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2017-10-05 12:34:23 +0000 |
commit | 8e70241dccaf5a9e5c79c8d6da5665b881c5914d (patch) | |
tree | 99d69b1a932b76f476df48418b39f171d3348012 /src/gui | |
parent | aeee3be166aff737990fe2cade05bff7b39dfebc (diff) |
Let QPlatformBackingStore handle its own QOpenGLContext
The resources allocated by QPlatformBackingStore are owned by the class,
and should be allocated in a context the class also owns. This removes
the asymmetry of having to pass in a context to composeAndFlush, while
having to make the same context current before destroying the platform
backingstore.
The context owned by QPlatformBackingStore is shared with the associated
window though a new QWindowPrivate::shareContext() API.
The result is that on e.g. iOS, the backingstore does not need to tie
the resource allocation of QPlatformBackingStore to the global share
context, but can instead tie them to the per-window context, and hence
clean them up after each window is closed.
Task-number: QTBUG-56653
Change-Id: Ic1bcae50dafeeafaa8d16a7febd83b840ec6367a
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/kernel/qwindow.cpp | 6 | ||||
-rw-r--r-- | src/gui/kernel/qwindow_p.h | 2 | ||||
-rw-r--r-- | src/gui/painting/qplatformbackingstore.cpp | 32 | ||||
-rw-r--r-- | src/gui/painting/qplatformbackingstore.h | 2 |
4 files changed, 32 insertions, 10 deletions
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index b4e2b47c03..42b54bf98a 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -45,6 +45,7 @@ #ifndef QT_NO_OPENGL #include <qpa/qplatformopenglcontext.h> #include "qopenglcontext.h" +#include "qopenglcontext_p.h" #endif #include "qscreen.h" @@ -2633,6 +2634,11 @@ QWindow *QWindowPrivate::topLevelWindow() const return window; } +QOpenGLContext *QWindowPrivate::shareContext() const +{ + return qt_gl_global_share_context(); +}; + /*! Creates a local representation of a window created by another process or by using native libraries below Qt. diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h index 9b8e2c47e4..bf6be1bb98 100644 --- a/src/gui/kernel/qwindow_p.h +++ b/src/gui/kernel/qwindow_p.h @@ -130,6 +130,8 @@ public: QWindow *topLevelWindow() const; + virtual QOpenGLContext *shareContext() const; + virtual QWindow *eventReceiver() { Q_Q(QWindow); return q; } virtual void setVisible(bool visible); diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp index 6cb115afba..8ab22beb31 100644 --- a/src/gui/painting/qplatformbackingstore.cpp +++ b/src/gui/painting/qplatformbackingstore.cpp @@ -50,6 +50,7 @@ #include <QtGui/QOpenGLFunctions> #ifndef QT_NO_OPENGL #include <QtGui/qopengltextureblitter.h> +#include <QtGui/qoffscreensurface.h> #endif #include <qpa/qplatformgraphicsbuffer.h> #include <qpa/qplatformgraphicsbufferhelper.h> @@ -95,14 +96,15 @@ public: ~QPlatformBackingStorePrivate() { #ifndef QT_NO_OPENGL - QOpenGLContext *ctx = QOpenGLContext::currentContext(); - if (ctx) { + if (context) { + QOffscreenSurface offscreenSurface; + offscreenSurface.setFormat(context->format()); + offscreenSurface.create(); + context->makeCurrent(&offscreenSurface); if (textureId) - ctx->functions()->glDeleteTextures(1, &textureId); + context->functions()->glDeleteTextures(1, &textureId); if (blitter) blitter->destroy(); - } else if (textureId || blitter) { - qWarning("No context current during QPlatformBackingStore destruction, OpenGL resources not released"); } delete blitter; #endif @@ -110,6 +112,7 @@ public: QWindow *window; QBackingStore *backingStore; #ifndef QT_NO_OPENGL + QScopedPointer<QOpenGLContext> context; mutable GLuint textureId; mutable QSize textureSize; mutable bool needsSwizzle; @@ -316,20 +319,31 @@ static void blitTextureForWidget(const QPlatformTextureList *textures, int idx, void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®ion, const QPoint &offset, - QPlatformTextureList *textures, QOpenGLContext *context, + QPlatformTextureList *textures, bool translucentBackground) { if (!qt_window_private(window)->receivedExpose) return; - if (!context->makeCurrent(window)) { + if (!d_ptr->context) { + d_ptr->context.reset(new QOpenGLContext); + d_ptr->context->setFormat(d_ptr->window->requestedFormat()); + d_ptr->context->setScreen(d_ptr->window->screen()); + d_ptr->context->setShareContext(qt_window_private(d_ptr->window)->shareContext()); + if (!d_ptr->context->create()) { + qWarning("composeAndFlush: QOpenGLContext creation failed"); + return; + } + } + + if (!d_ptr->context->makeCurrent(window)) { qWarning("composeAndFlush: makeCurrent() failed"); return; } QWindowPrivate::get(window)->lastComposeTime.start(); - QOpenGLFunctions *funcs = context->functions(); + QOpenGLFunctions *funcs = d_ptr->context->functions(); funcs->glViewport(0, 0, window->width() * window->devicePixelRatio(), window->height() * window->devicePixelRatio()); funcs->glClearColor(0, 0, 0, translucentBackground ? 0 : 1); funcs->glClear(GL_COLOR_BUFFER_BIT); @@ -435,7 +449,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i funcs->glDisable(GL_BLEND); d_ptr->blitter->release(); - context->swapBuffers(window); + d_ptr->context->swapBuffers(window); } #endif /*! diff --git a/src/gui/painting/qplatformbackingstore.h b/src/gui/painting/qplatformbackingstore.h index 9956c032a9..381c564079 100644 --- a/src/gui/painting/qplatformbackingstore.h +++ b/src/gui/painting/qplatformbackingstore.h @@ -120,7 +120,7 @@ public: virtual void flush(QWindow *window, const QRegion ®ion, const QPoint &offset) = 0; #ifndef QT_NO_OPENGL virtual void composeAndFlush(QWindow *window, const QRegion ®ion, const QPoint &offset, - QPlatformTextureList *textures, QOpenGLContext *context, + QPlatformTextureList *textures, bool translucentBackground); #endif virtual QImage toImage() const; |