diff options
-rw-r--r-- | src/opengl/qopenglcompositor.cpp | 9 | ||||
-rw-r--r-- | src/opengl/qopenglcompositor_p.h | 3 | ||||
-rw-r--r-- | src/opengl/qopenglcompositorbackingstore.cpp | 64 | ||||
-rw-r--r-- | src/opengl/qopenglvertexarrayobject.cpp | 2 | ||||
-rw-r--r-- | src/plugins/platforms/eglfs/api/qeglfsscreen.cpp | 3 | ||||
-rw-r--r-- | src/plugins/platforms/eglfs/api/qeglfswindow.cpp | 21 | ||||
-rw-r--r-- | src/plugins/platforms/eglfs/api/qeglfswindow_p.h | 7 |
7 files changed, 61 insertions, 48 deletions
diff --git a/src/opengl/qopenglcompositor.cpp b/src/opengl/qopenglcompositor.cpp index a5fe4dda304..9f661510adc 100644 --- a/src/opengl/qopenglcompositor.cpp +++ b/src/opengl/qopenglcompositor.cpp @@ -94,14 +94,17 @@ QOpenGLCompositor::~QOpenGLCompositor() compositor = 0; } -void QOpenGLCompositor::setTarget(QOpenGLContext *context, QWindow *targetWindow, - const QRect &nativeTargetGeometry) +void QOpenGLCompositor::setTargetWindow(QWindow *targetWindow, const QRect &nativeTargetGeometry) { - m_context = context; m_targetWindow = targetWindow; m_nativeTargetGeometry = nativeTargetGeometry; } +void QOpenGLCompositor::setTargetContext(QOpenGLContext *context) +{ + m_context = context; +} + void QOpenGLCompositor::setRotation(int degrees) { m_rotation = degrees; diff --git a/src/opengl/qopenglcompositor_p.h b/src/opengl/qopenglcompositor_p.h index 27ede567a8d..05b956c9c11 100644 --- a/src/opengl/qopenglcompositor_p.h +++ b/src/opengl/qopenglcompositor_p.h @@ -83,7 +83,8 @@ public: static QOpenGLCompositor *instance(); static void destroy(); - void setTarget(QOpenGLContext *context, QWindow *window, const QRect &nativeTargetGeometry); + void setTargetWindow(QWindow *window, const QRect &nativeTargetGeometry); + void setTargetContext(QOpenGLContext *context); void setRotation(int degrees); QOpenGLContext *context() const { return m_context; } QWindow *targetWindow() const { return m_targetWindow; } diff --git a/src/opengl/qopenglcompositorbackingstore.cpp b/src/opengl/qopenglcompositorbackingstore.cpp index ed4a0ffb3c3..df3a9e25250 100644 --- a/src/opengl/qopenglcompositorbackingstore.cpp +++ b/src/opengl/qopenglcompositorbackingstore.cpp @@ -40,7 +40,6 @@ #include <QtGui/QOpenGLContext> #include <QtGui/QWindow> #include <QtGui/QPainter> -#include <QtGui/QOffscreenSurface> #include <qpa/qplatformbackingstore.h> #include <private/qwindow_p.h> #include <private/qrhi_p.h> @@ -90,31 +89,12 @@ QOpenGLCompositorBackingStore::QOpenGLCompositorBackingStore(QWindow *window) QOpenGLCompositorBackingStore::~QOpenGLCompositorBackingStore() { - if (m_bsTexture) { - QOpenGLContext *ctx = QOpenGLContext::currentContext(); - // With render-to-texture-widgets QWidget makes sure the TLW's shareContext() is - // made current before destroying backingstores. That is however not the case for - // windows with regular widgets only. - QScopedPointer<QOffscreenSurface> tempSurface; - if (!ctx) { - ctx = QOpenGLCompositor::instance()->context(); - if (ctx) { - tempSurface.reset(new QOffscreenSurface); - tempSurface->setFormat(ctx->format()); - tempSurface->create(); - ctx->makeCurrent(tempSurface.data()); - } - } - - if (m_bsTextureContext && ctx && ctx->shareGroup() == m_bsTextureContext->shareGroup()) { - delete m_bsTextureWrapper; - glDeleteTextures(1, &m_bsTexture); - } else { - qWarning("QOpenGLCompositorBackingStore: Texture is not valid in the current context"); - } - - if (tempSurface && ctx) - ctx->doneCurrent(); + if (m_bsTexture && m_rhi) { + delete m_bsTextureWrapper; + // Contexts are sharing resources, won't matter which one is + // current here, use the rhi's shortcut. + m_rhi->makeThreadLocalNativeContextCurrent(); + glDeleteTextures(1, &m_bsTexture); } delete m_textures; // this does not actually own any GL resources @@ -137,8 +117,6 @@ void QOpenGLCompositorBackingStore::updateTexture() glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_image.width(), m_image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - m_bsTextureWrapper = m_rhi->newTexture(QRhiTexture::RGBA8, m_image.size()); - m_bsTextureWrapper->createFrom({m_bsTexture, 0}); } else { glBindTexture(GL_TEXTURE_2D, m_bsTexture); } @@ -185,6 +163,11 @@ void QOpenGLCompositorBackingStore::updateTexture() m_dirty = QRegion(); } + + if (!m_bsTextureWrapper) { + m_bsTextureWrapper = m_rhi->newTexture(QRhiTexture::RGBA8, m_image.size()); + m_bsTextureWrapper->createFrom({m_bsTexture, 0}); + } } void QOpenGLCompositorBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) @@ -194,15 +177,25 @@ void QOpenGLCompositorBackingStore::flush(QWindow *window, const QRegion ®ion Q_UNUSED(region); Q_UNUSED(offset); + m_rhi = rhi(); + if (!m_rhi) { + setRhiConfig(QPlatformBackingStoreRhiConfig(QPlatformBackingStoreRhiConfig::OpenGL)); + m_rhi = rhi(); + } + Q_ASSERT(m_rhi); + QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); QOpenGLContext *dstCtx = compositor->context(); - Q_ASSERT(dstCtx); + if (!dstCtx) + return; QWindow *dstWin = compositor->targetWindow(); if (!dstWin) return; - dstCtx->makeCurrent(dstWin); + if (!dstCtx->makeCurrent(dstWin)) + return; + updateTexture(); m_textures->clear(); m_textures->appendTexture(nullptr, m_bsTextureWrapper, window->geometry()); @@ -223,16 +216,23 @@ QPlatformBackingStore::FlushResult QOpenGLCompositorBackingStore::rhiFlush(QWind Q_UNUSED(translucentBackground); m_rhi = rhi(); + if (!m_rhi) { + setRhiConfig(QPlatformBackingStoreRhiConfig(QPlatformBackingStoreRhiConfig::OpenGL)); + m_rhi = rhi(); + } + Q_ASSERT(m_rhi); QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); QOpenGLContext *dstCtx = compositor->context(); - Q_ASSERT(dstCtx); // setTarget() must have been called before, e.g. from QEGLFSWindow + if (!dstCtx) + return FlushFailed; QWindow *dstWin = compositor->targetWindow(); if (!dstWin) return FlushFailed; - dstCtx->makeCurrent(dstWin); + if (!dstCtx->makeCurrent(dstWin)) + return FlushFailed; QWindowPrivate::get(window)->lastComposeTime.start(); diff --git a/src/opengl/qopenglvertexarrayobject.cpp b/src/opengl/qopenglvertexarrayobject.cpp index 63e37727f91..9df48a3ddc0 100644 --- a/src/opengl/qopenglvertexarrayobject.cpp +++ b/src/opengl/qopenglvertexarrayobject.cpp @@ -274,7 +274,7 @@ void QOpenGLVertexArrayObjectPrivate::destroy() vao = 0; } - if (oldContext && oldContextSurface) { + if (oldContext && oldContextSurface && oldContextSurface->surfaceHandle()) { if (!oldContext->makeCurrent(oldContextSurface)) qWarning("QOpenGLVertexArrayObject::destroy() failed to restore current context"); } diff --git a/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp index 0b133c55a72..703259d66cf 100644 --- a/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp @@ -201,7 +201,8 @@ QPixmap QEglFSScreen::grabWindow(WId wid, int x, int y, int width, int height) c QImage img; - if (static_cast<QEglFSWindow *>(windows.first()->sourceWindow()->handle())->isRaster()) { + QEglFSWindow *primaryWin = static_cast<QEglFSWindow *>(windows.first()->sourceWindow()->handle()); + if (primaryWin->isRaster() || primaryWin->backingStore()) { // Request the compositor to render everything into an FBO and read it back. This // is of course slow, but it's safe and reliable. It will not include the mouse // cursor, which is a plus. diff --git a/src/plugins/platforms/eglfs/api/qeglfswindow.cpp b/src/plugins/platforms/eglfs/api/qeglfswindow.cpp index 47f6d88e5cc..13cc65bdaf6 100644 --- a/src/plugins/platforms/eglfs/api/qeglfswindow.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfswindow.cpp @@ -110,7 +110,7 @@ void QEglFSWindow::create() #ifndef QT_NO_OPENGL QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); if (screen->primarySurface() != EGL_NO_SURFACE) { - if (Q_UNLIKELY(!isRaster() || !compositor->targetWindow())) { + if (Q_UNLIKELY(isRaster() != (compositor->targetWindow() != nullptr))) { # ifndef Q_OS_ANDROID // We can have either a single OpenGL window or multiple raster windows. // Other combinations cannot work. @@ -137,21 +137,30 @@ void QEglFSWindow::create() screen->setPrimarySurface(m_surface); #ifndef QT_NO_OPENGL - if (isRaster()) { + compositor->setTargetWindow(window(), screen->rawGeometry()); + compositor->setRotation(qEnvironmentVariableIntValue("QT_QPA_EGLFS_ROTATION")); +#endif +} + +void QEglFSWindow::setBackingStore(QOpenGLCompositorBackingStore *backingStore) +{ +#ifndef QT_NO_OPENGL + if (!m_rasterCompositingContext) { m_rasterCompositingContext = new QOpenGLContext; m_rasterCompositingContext->setShareContext(qt_gl_global_share_context()); m_rasterCompositingContext->setFormat(m_format); m_rasterCompositingContext->setScreen(window()->screen()); if (Q_UNLIKELY(!m_rasterCompositingContext->create())) qFatal("EGLFS: Failed to create compositing context"); - compositor->setTarget(m_rasterCompositingContext, window(), screen->rawGeometry()); - compositor->setRotation(qEnvironmentVariableIntValue("QT_QPA_EGLFS_ROTATION")); // If there is a "root" window into which raster and QOpenGLWidget content is // composited, all other contexts must share with its context. if (!qt_gl_global_share_context()) qt_gl_set_global_share_context(m_rasterCompositingContext); } -#endif // QT_NO_OPENGL + QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); + compositor->setTargetContext(m_rasterCompositingContext); +#endif + m_backingStore = backingStore; } void QEglFSWindow::destroy() @@ -352,7 +361,7 @@ WId QEglFSWindow::winId() const void QEglFSWindow::setOpacity(qreal) { - if (!isRaster()) + if (!isRaster() && !backingStore()) qWarning("QEglFSWindow: Cannot set opacity for non-raster windows"); // Nothing to do here. The opacity is stored in the QWindow. diff --git a/src/plugins/platforms/eglfs/api/qeglfswindow_p.h b/src/plugins/platforms/eglfs/api/qeglfswindow_p.h index 6b34071d1a9..1418ef82a17 100644 --- a/src/plugins/platforms/eglfs/api/qeglfswindow_p.h +++ b/src/plugins/platforms/eglfs/api/qeglfswindow_p.h @@ -103,12 +103,11 @@ public: void invalidateSurface() override; virtual void resetSurface(); -#ifndef QT_NO_OPENGL - QOpenGLCompositorBackingStore *backingStore() { return m_backingStore; } - void setBackingStore(QOpenGLCompositorBackingStore *backingStore) { m_backingStore = backingStore; } -#endif bool isRaster() const; + #ifndef QT_NO_OPENGL + QOpenGLCompositorBackingStore *backingStore() { return m_backingStore; } + void setBackingStore(QOpenGLCompositorBackingStore *backingStore); QWindow *sourceWindow() const override; const QPlatformTextureList *textures() const override; void endCompositing() override; |