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.6 6.5 Change-Id: I6dddc879a4be7ff2c2c189747193423644be55a0 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io> Reviewed-by: Artem Dyomin <artem.dyomin@qt.io> (cherry picked from commit 342ae435a198acdd794e575dc54ccab1d33b320b) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
2a0d34373e
commit
d33437c4f9
@ -90,7 +90,7 @@ QImage QOpenGLCompositor::grab()
|
|||||||
return fbo.toImage();
|
return fbo.toImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QOpenGLCompositor::grabToFrameBufferObject(QOpenGLFramebufferObject *fbo)
|
bool QOpenGLCompositor::grabToFrameBufferObject(QOpenGLFramebufferObject *fbo, GrabOrientation orientation)
|
||||||
{
|
{
|
||||||
Q_ASSERT(fbo);
|
Q_ASSERT(fbo);
|
||||||
if (fbo->size() != m_nativeTargetGeometry.size()
|
if (fbo->size() != m_nativeTargetGeometry.size()
|
||||||
@ -98,7 +98,9 @@ bool QOpenGLCompositor::grabToFrameBufferObject(QOpenGLFramebufferObject *fbo)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_context->makeCurrent(m_targetWindow);
|
m_context->makeCurrent(m_targetWindow);
|
||||||
renderAll(fbo);
|
renderAll(fbo,
|
||||||
|
orientation == Flipped ? QOpenGLTextureBlitter::OriginTopLeft
|
||||||
|
: QOpenGLTextureBlitter::OriginBottomLeft);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +111,7 @@ void QOpenGLCompositor::handleRenderAllRequest()
|
|||||||
renderAll(0);
|
renderAll(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QOpenGLCompositor::renderAll(QOpenGLFramebufferObject *fbo)
|
void QOpenGLCompositor::renderAll(QOpenGLFramebufferObject *fbo, QOpenGLTextureBlitter::Origin origin)
|
||||||
{
|
{
|
||||||
if (fbo)
|
if (fbo)
|
||||||
fbo->bind();
|
fbo->bind();
|
||||||
@ -126,7 +128,7 @@ void QOpenGLCompositor::renderAll(QOpenGLFramebufferObject *fbo)
|
|||||||
m_windows.at(i)->beginCompositing();
|
m_windows.at(i)->beginCompositing();
|
||||||
|
|
||||||
for (int i = 0; i < m_windows.size(); ++i)
|
for (int i = 0; i < m_windows.size(); ++i)
|
||||||
render(m_windows.at(i));
|
render(m_windows.at(i), origin);
|
||||||
|
|
||||||
m_blitter.release();
|
m_blitter.release();
|
||||||
if (!fbo)
|
if (!fbo)
|
||||||
@ -167,9 +169,10 @@ static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight)
|
|||||||
topLeftRect.width(), topLeftRect.height());
|
topLeftRect.width(), topLeftRect.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clippedBlit(const QPlatformTextureList *textures, int idx, const QRect &sourceWindowRect,
|
static void clippedBlit(const QPlatformTextureList *textures, int idx,
|
||||||
const QRect &targetWindowRect,
|
const QRect &sourceWindowRect, const QRect &targetWindowRect,
|
||||||
QOpenGLTextureBlitter *blitter, QMatrix4x4 *rotationMatrix)
|
QOpenGLTextureBlitter *blitter, QMatrix4x4 *rotationMatrix,
|
||||||
|
QOpenGLTextureBlitter::Origin sourceOrigin)
|
||||||
{
|
{
|
||||||
const QRect clipRect = textures->clipRect(idx);
|
const QRect clipRect = textures->clipRect(idx);
|
||||||
if (clipRect.isEmpty())
|
if (clipRect.isEmpty())
|
||||||
@ -184,13 +187,13 @@ static void clippedBlit(const QPlatformTextureList *textures, int idx, const QRe
|
|||||||
target = *rotationMatrix * target;
|
target = *rotationMatrix * target;
|
||||||
|
|
||||||
const QMatrix3x3 source = QOpenGLTextureBlitter::sourceTransform(srcRect, rectInWindow.size(),
|
const QMatrix3x3 source = QOpenGLTextureBlitter::sourceTransform(srcRect, rectInWindow.size(),
|
||||||
QOpenGLTextureBlitter::OriginBottomLeft);
|
sourceOrigin);
|
||||||
|
|
||||||
const uint textureId = textures->texture(idx)->nativeTexture().object;
|
const uint textureId = textures->texture(idx)->nativeTexture().object;
|
||||||
blitter->blit(textureId, target, source);
|
blitter->blit(textureId, target, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QOpenGLCompositor::render(QOpenGLCompositorWindow *window)
|
void QOpenGLCompositor::render(QOpenGLCompositorWindow *window, QOpenGLTextureBlitter::Origin origin)
|
||||||
{
|
{
|
||||||
const QPlatformTextureList *textures = window->textures();
|
const QPlatformTextureList *textures = window->textures();
|
||||||
if (!textures)
|
if (!textures)
|
||||||
@ -200,6 +203,9 @@ void QOpenGLCompositor::render(QOpenGLCompositorWindow *window)
|
|||||||
float currentOpacity = 1.0f;
|
float currentOpacity = 1.0f;
|
||||||
BlendStateBinder blend;
|
BlendStateBinder blend;
|
||||||
const QRect sourceWindowRect = window->sourceWindow()->geometry();
|
const QRect sourceWindowRect = window->sourceWindow()->geometry();
|
||||||
|
auto clippedBlitSourceOrigin = origin == QOpenGLTextureBlitter::OriginTopLeft
|
||||||
|
? QOpenGLTextureBlitter::OriginBottomLeft
|
||||||
|
: QOpenGLTextureBlitter::OriginTopLeft;
|
||||||
for (int i = 0; i < textures->count(); ++i) {
|
for (int i = 0; i < textures->count(); ++i) {
|
||||||
const uint textureId = textures->texture(i)->nativeTexture().object;
|
const uint textureId = textures->texture(i)->nativeTexture().object;
|
||||||
const float opacity = window->sourceWindow()->opacity();
|
const float opacity = window->sourceWindow()->opacity();
|
||||||
@ -214,7 +220,7 @@ void QOpenGLCompositor::render(QOpenGLCompositorWindow *window)
|
|||||||
QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect);
|
QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect);
|
||||||
if (m_rotation)
|
if (m_rotation)
|
||||||
target = m_rotationMatrix * target;
|
target = m_rotationMatrix * target;
|
||||||
m_blitter.blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft);
|
m_blitter.blit(textureId, target, origin);
|
||||||
} else if (textures->count() == 1) {
|
} else if (textures->count() == 1) {
|
||||||
// A regular QWidget window
|
// A regular QWidget window
|
||||||
const bool translucent = window->sourceWindow()->requestedFormat().alphaBufferSize() > 0;
|
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);
|
QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect);
|
||||||
if (m_rotation)
|
if (m_rotation)
|
||||||
target = m_rotationMatrix * target;
|
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)) {
|
} else if (!textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) {
|
||||||
// Texture from an FBO belonging to a QOpenGLWidget or QQuickWidget
|
// Texture from an FBO belonging to a QOpenGLWidget or QQuickWidget
|
||||||
blend.set(false);
|
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) {
|
for (int i = 0; i < textures->count(); ++i) {
|
||||||
if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) {
|
if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) {
|
||||||
blend.set(true);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,6 +47,11 @@ class Q_OPENGL_EXPORT QOpenGLCompositor : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum GrabOrientation {
|
||||||
|
Flipped,
|
||||||
|
NotFlipped,
|
||||||
|
};
|
||||||
|
|
||||||
static QOpenGLCompositor *instance();
|
static QOpenGLCompositor *instance();
|
||||||
static void destroy();
|
static void destroy();
|
||||||
|
|
||||||
@ -60,7 +65,7 @@ public:
|
|||||||
void update();
|
void update();
|
||||||
QImage grab();
|
QImage grab();
|
||||||
|
|
||||||
bool grabToFrameBufferObject(QOpenGLFramebufferObject *fbo);
|
bool grabToFrameBufferObject(QOpenGLFramebufferObject *fbo, GrabOrientation orientation = Flipped);
|
||||||
|
|
||||||
QList<QOpenGLCompositorWindow *> windows() const { return m_windows; }
|
QList<QOpenGLCompositorWindow *> windows() const { return m_windows; }
|
||||||
void addWindow(QOpenGLCompositorWindow *window);
|
void addWindow(QOpenGLCompositorWindow *window);
|
||||||
@ -78,8 +83,10 @@ private:
|
|||||||
QOpenGLCompositor();
|
QOpenGLCompositor();
|
||||||
~QOpenGLCompositor();
|
~QOpenGLCompositor();
|
||||||
|
|
||||||
void renderAll(QOpenGLFramebufferObject *fbo);
|
void renderAll(QOpenGLFramebufferObject *fbo,
|
||||||
void render(QOpenGLCompositorWindow *window);
|
QOpenGLTextureBlitter::Origin origin = QOpenGLTextureBlitter::OriginTopLeft);
|
||||||
|
void render(QOpenGLCompositorWindow *window,
|
||||||
|
QOpenGLTextureBlitter::Origin origin = QOpenGLTextureBlitter::OriginTopLeft);
|
||||||
void ensureCorrectZOrder();
|
void ensureCorrectZOrder();
|
||||||
|
|
||||||
QOpenGLContext *m_context;
|
QOpenGLContext *m_context;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user