From 342ae435a198acdd794e575dc54ccab1d33b320b Mon Sep 17 00:00:00 2001 From: Mikko Hallamaa Date: Thu, 15 Feb 2024 10:58:40 +0100 Subject: OpenGL: Add parameters to choose FBO grab orientation We want to be able to pass as an argument whether the texture grabbed to an FBO is supposed to have a flipped y-axis or not. This is required for screen capture on the EGLFS platform. Task-number: QTBUG-121835 Pick-to: 6.7 6.6 6.5 Change-Id: I6dddc879a4be7ff2c2c189747193423644be55a0 Reviewed-by: Laszlo Agocs Reviewed-by: Artem Dyomin --- src/opengl/qopenglcompositor.cpp | 34 +++++++++++++++++++++------------- src/opengl/qopenglcompositor_p.h | 13 ++++++++++--- 2 files changed, 31 insertions(+), 16 deletions(-) (limited to 'src/opengl') diff --git a/src/opengl/qopenglcompositor.cpp b/src/opengl/qopenglcompositor.cpp index 6fda40c27c..3c5b1df905 100644 --- a/src/opengl/qopenglcompositor.cpp +++ b/src/opengl/qopenglcompositor.cpp @@ -90,7 +90,7 @@ QImage QOpenGLCompositor::grab() return fbo.toImage(); } -bool QOpenGLCompositor::grabToFrameBufferObject(QOpenGLFramebufferObject *fbo) +bool QOpenGLCompositor::grabToFrameBufferObject(QOpenGLFramebufferObject *fbo, GrabOrientation orientation) { Q_ASSERT(fbo); if (fbo->size() != m_nativeTargetGeometry.size() @@ -98,7 +98,9 @@ bool QOpenGLCompositor::grabToFrameBufferObject(QOpenGLFramebufferObject *fbo) return false; m_context->makeCurrent(m_targetWindow); - renderAll(fbo); + renderAll(fbo, + orientation == Flipped ? QOpenGLTextureBlitter::OriginTopLeft + : QOpenGLTextureBlitter::OriginBottomLeft); return true; } @@ -109,7 +111,7 @@ void QOpenGLCompositor::handleRenderAllRequest() renderAll(0); } -void QOpenGLCompositor::renderAll(QOpenGLFramebufferObject *fbo) +void QOpenGLCompositor::renderAll(QOpenGLFramebufferObject *fbo, QOpenGLTextureBlitter::Origin origin) { if (fbo) fbo->bind(); @@ -126,7 +128,7 @@ void QOpenGLCompositor::renderAll(QOpenGLFramebufferObject *fbo) m_windows.at(i)->beginCompositing(); for (int i = 0; i < m_windows.size(); ++i) - render(m_windows.at(i)); + render(m_windows.at(i), origin); m_blitter.release(); if (!fbo) @@ -167,9 +169,10 @@ static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight) topLeftRect.width(), topLeftRect.height()); } -static void clippedBlit(const QPlatformTextureList *textures, int idx, const QRect &sourceWindowRect, - const QRect &targetWindowRect, - QOpenGLTextureBlitter *blitter, QMatrix4x4 *rotationMatrix) +static void clippedBlit(const QPlatformTextureList *textures, int idx, + const QRect &sourceWindowRect, const QRect &targetWindowRect, + QOpenGLTextureBlitter *blitter, QMatrix4x4 *rotationMatrix, + QOpenGLTextureBlitter::Origin sourceOrigin) { const QRect clipRect = textures->clipRect(idx); if (clipRect.isEmpty()) @@ -184,13 +187,13 @@ static void clippedBlit(const QPlatformTextureList *textures, int idx, const QRe target = *rotationMatrix * target; const QMatrix3x3 source = QOpenGLTextureBlitter::sourceTransform(srcRect, rectInWindow.size(), - QOpenGLTextureBlitter::OriginBottomLeft); + sourceOrigin); const uint textureId = textures->texture(idx)->nativeTexture().object; blitter->blit(textureId, target, source); } -void QOpenGLCompositor::render(QOpenGLCompositorWindow *window) +void QOpenGLCompositor::render(QOpenGLCompositorWindow *window, QOpenGLTextureBlitter::Origin origin) { const QPlatformTextureList *textures = window->textures(); if (!textures) @@ -200,6 +203,9 @@ void QOpenGLCompositor::render(QOpenGLCompositorWindow *window) float currentOpacity = 1.0f; BlendStateBinder blend; const QRect sourceWindowRect = window->sourceWindow()->geometry(); + auto clippedBlitSourceOrigin = origin == QOpenGLTextureBlitter::OriginTopLeft + ? QOpenGLTextureBlitter::OriginBottomLeft + : QOpenGLTextureBlitter::OriginTopLeft; for (int i = 0; i < textures->count(); ++i) { const uint textureId = textures->texture(i)->nativeTexture().object; const float opacity = window->sourceWindow()->opacity(); @@ -214,7 +220,7 @@ void QOpenGLCompositor::render(QOpenGLCompositorWindow *window) QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect); if (m_rotation) target = m_rotationMatrix * target; - m_blitter.blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft); + m_blitter.blit(textureId, target, origin); } else if (textures->count() == 1) { // A regular QWidget window const bool translucent = window->sourceWindow()->requestedFormat().alphaBufferSize() > 0; @@ -222,18 +228,20 @@ void QOpenGLCompositor::render(QOpenGLCompositorWindow *window) QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect); if (m_rotation) target = m_rotationMatrix * target; - m_blitter.blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft); + m_blitter.blit(textureId, target, origin); } else if (!textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) { // Texture from an FBO belonging to a QOpenGLWidget or QQuickWidget blend.set(false); - clippedBlit(textures, i, sourceWindowRect, targetWindowRect, &m_blitter, m_rotation ? &m_rotationMatrix : nullptr); + clippedBlit(textures, i, sourceWindowRect, targetWindowRect, &m_blitter, + m_rotation ? &m_rotationMatrix : nullptr, clippedBlitSourceOrigin); } } for (int i = 0; i < textures->count(); ++i) { if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) { blend.set(true); - clippedBlit(textures, i, sourceWindowRect, targetWindowRect, &m_blitter, m_rotation ? &m_rotationMatrix : nullptr); + clippedBlit(textures, i, sourceWindowRect, targetWindowRect, &m_blitter, + m_rotation ? &m_rotationMatrix : nullptr, clippedBlitSourceOrigin); } } diff --git a/src/opengl/qopenglcompositor_p.h b/src/opengl/qopenglcompositor_p.h index f2059f90fa..86229b13ca 100644 --- a/src/opengl/qopenglcompositor_p.h +++ b/src/opengl/qopenglcompositor_p.h @@ -47,6 +47,11 @@ class Q_OPENGL_EXPORT QOpenGLCompositor : public QObject Q_OBJECT public: + enum GrabOrientation { + Flipped, + NotFlipped, + }; + static QOpenGLCompositor *instance(); static void destroy(); @@ -60,7 +65,7 @@ public: void update(); QImage grab(); - bool grabToFrameBufferObject(QOpenGLFramebufferObject *fbo); + bool grabToFrameBufferObject(QOpenGLFramebufferObject *fbo, GrabOrientation orientation = Flipped); QList windows() const { return m_windows; } void addWindow(QOpenGLCompositorWindow *window); @@ -78,8 +83,10 @@ private: QOpenGLCompositor(); ~QOpenGLCompositor(); - void renderAll(QOpenGLFramebufferObject *fbo); - void render(QOpenGLCompositorWindow *window); + void renderAll(QOpenGLFramebufferObject *fbo, + QOpenGLTextureBlitter::Origin origin = QOpenGLTextureBlitter::OriginTopLeft); + void render(QOpenGLCompositorWindow *window, + QOpenGLTextureBlitter::Origin origin = QOpenGLTextureBlitter::OriginTopLeft); void ensureCorrectZOrder(); QOpenGLContext *m_context; -- cgit v1.2.3