aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/scenegraph/qsgrhilayer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/scenegraph/qsgrhilayer.cpp')
-rw-r--r--src/quick/scenegraph/qsgrhilayer.cpp153
1 files changed, 67 insertions, 86 deletions
diff --git a/src/quick/scenegraph/qsgrhilayer.cpp b/src/quick/scenegraph/qsgrhilayer.cpp
index cef9737fd8..5299cb54ce 100644
--- a/src/quick/scenegraph/qsgrhilayer.cpp
+++ b/src/quick/scenegraph/qsgrhilayer.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qsgrhilayer_p.h"
@@ -137,31 +101,51 @@ void QSGRhiLayer::setItem(QSGNode *item)
markDirtyTexture();
}
-void QSGRhiLayer::setRect(const QRectF &rect)
+void QSGRhiLayer::setRect(const QRectF &logicalRect)
{
- if (rect == m_rect)
+ if (logicalRect == m_logicalRect)
return;
- m_rect = rect;
+ m_logicalRect = logicalRect;
markDirtyTexture();
}
-void QSGRhiLayer::setSize(const QSize &size)
+void QSGRhiLayer::setSize(const QSize &pixelSize)
{
- if (size == m_size)
+ if (pixelSize == m_pixelSize)
return;
- m_size = size;
+ m_pixelSize = pixelSize;
- if (m_live && m_size.isNull())
+ if (m_live && m_pixelSize.isNull())
releaseResources();
markDirtyTexture();
}
-void QSGRhiLayer::setFormat(uint format)
+void QSGRhiLayer::setFormat(Format format)
{
- Q_UNUSED(format);
+ QRhiTexture::Format rhiFormat = QRhiTexture::RGBA8;
+ switch (format) {
+ case RGBA16F:
+ rhiFormat = QRhiTexture::RGBA16F;
+ break;
+ case RGBA32F:
+ rhiFormat = QRhiTexture::RGBA32F;
+ break;
+ default:
+ break;
+ }
+
+ if (rhiFormat == m_format)
+ return;
+
+ if (m_rhi->isTextureFormatSupported(rhiFormat)) {
+ m_format = rhiFormat;
+ markDirtyTexture();
+ } else {
+ qWarning("QSGRhiLayer: Attempted to set unsupported texture format %d", int(rhiFormat));
+ }
}
void QSGRhiLayer::setLive(bool live)
@@ -171,7 +155,7 @@ void QSGRhiLayer::setLive(bool live)
m_live = live;
- if (m_live && (!m_item || m_size.isNull()))
+ if (m_live && (!m_item || m_pixelSize.isNull()))
releaseResources();
markDirtyTexture();
@@ -214,12 +198,8 @@ void QSGRhiLayer::releaseResources()
delete m_rt;
m_rt = nullptr;
- if (m_rtRp) {
- if (m_renderer)
- m_renderer->invalidatePipelineCacheDependency(m_rtRp);
- delete m_rtRp;
- m_rtRp = nullptr;
- }
+ delete m_rtRp;
+ m_rtRp = nullptr;
delete m_ds;
m_ds = nullptr;
@@ -236,7 +216,7 @@ void QSGRhiLayer::releaseResources()
void QSGRhiLayer::grab()
{
- if (!m_item || m_size.isEmpty()) {
+ if (!m_item || m_pixelSize.isEmpty()) {
releaseResources();
m_dirtyTexture = false;
return;
@@ -247,7 +227,7 @@ void QSGRhiLayer::grab()
if (effectiveSamples <= 1)
effectiveSamples = m_context->msaaSampleCount();
- const bool needsNewRt = !m_rt || m_rt->pixelSize() != m_size || (m_recursive && !m_secondaryTexture);
+ const bool needsNewRt = !m_rt || m_rt->pixelSize() != m_pixelSize || (m_recursive && !m_secondaryTexture) || (m_texture && m_texture->format() != m_format);
const bool mipmapSettingChanged = m_texture && m_texture->flags().testFlag(QRhiTexture::MipMapped) != m_mipmap;
const bool msaaSettingChanged = (effectiveSamples > 1 && !m_msaaColorBuffer) || (effectiveSamples <= 1 && m_msaaColorBuffer);
@@ -275,21 +255,21 @@ void QSGRhiLayer::grab()
if (m_multisampling) {
releaseResources();
- m_msaaColorBuffer = m_rhi->newRenderBuffer(QRhiRenderBuffer::Color, m_size, effectiveSamples);
+ m_msaaColorBuffer = m_rhi->newRenderBuffer(QRhiRenderBuffer::Color, m_pixelSize, effectiveSamples);
if (!m_msaaColorBuffer->create()) {
qWarning("Failed to build multisample color buffer for layer of size %dx%d, sample count %d",
- m_size.width(), m_size.height(), effectiveSamples);
+ m_pixelSize.width(), m_pixelSize.height(), effectiveSamples);
releaseResources();
return;
}
- m_texture = m_rhi->newTexture(m_format, m_size, 1, textureFlags);
+ m_texture = m_rhi->newTexture(m_format, m_pixelSize, 1, textureFlags);
if (!m_texture->create()) {
- qWarning("Failed to build texture for layer of size %dx%d", m_size.width(), m_size.height());
+ qWarning("Failed to build texture for layer of size %dx%d", m_pixelSize.width(), m_pixelSize.height());
releaseResources();
return;
}
if (depthBufferEnabled) {
- m_ds = m_rhi->newRenderBuffer(QRhiRenderBuffer::DepthStencil, m_size, effectiveSamples);
+ m_ds = m_rhi->newRenderBuffer(QRhiRenderBuffer::DepthStencil, m_pixelSize, effectiveSamples);
if (!m_ds->create()) {
qWarning("Failed to build depth-stencil buffer for layer");
releaseResources();
@@ -317,14 +297,14 @@ void QSGRhiLayer::grab()
}
} else {
releaseResources();
- m_texture = m_rhi->newTexture(m_format, m_size, 1, textureFlags);
+ m_texture = m_rhi->newTexture(m_format, m_pixelSize, 1, textureFlags);
if (!m_texture->create()) {
- qWarning("Failed to build texture for layer of size %dx%d", m_size.width(), m_size.height());
+ qWarning("Failed to build texture for layer of size %dx%d", m_pixelSize.width(), m_pixelSize.height());
releaseResources();
return;
}
if (depthBufferEnabled) {
- m_ds = m_rhi->newRenderBuffer(QRhiRenderBuffer::DepthStencil, m_size);
+ m_ds = m_rhi->newRenderBuffer(QRhiRenderBuffer::DepthStencil, m_pixelSize);
if (!m_ds->create()) {
qWarning("Failed to build depth-stencil buffer for layer");
releaseResources();
@@ -335,9 +315,9 @@ void QSGRhiLayer::grab()
if (m_recursive) {
// Here rt is associated with m_secondaryTexture instead of m_texture.
// We will issue a copy to m_texture afterwards.
- m_secondaryTexture = m_rhi->newTexture(m_format, m_size, 1, textureFlags);
+ m_secondaryTexture = m_rhi->newTexture(m_format, m_pixelSize, 1, textureFlags);
if (!m_secondaryTexture->create()) {
- qWarning("Failed to build texture for layer of size %dx%d", m_size.width(), m_size.height());
+ qWarning("Failed to build texture for layer of size %dx%d", m_pixelSize.width(), m_pixelSize.height());
releaseResources();
return;
}
@@ -385,42 +365,40 @@ void QSGRhiLayer::grab()
m_dirtyTexture = false;
m_renderer->setDevicePixelRatio(m_dpr);
- m_renderer->setDeviceRect(m_size);
- m_renderer->setViewportRect(m_size);
- QRectF mirrored;
+ m_renderer->setDeviceRect(m_pixelSize);
+ m_renderer->setViewportRect(m_pixelSize);
+ QRectF mirrored; // in logical coordinates (no dpr) since this gets passed to setProjectionMatrixToRect()
if (m_rhi->isYUpInFramebuffer()) {
- mirrored = QRectF(m_mirrorHorizontal ? m_rect.right() : m_rect.left(),
- m_mirrorVertical ? m_rect.bottom() : m_rect.top(),
- m_mirrorHorizontal ? -m_rect.width() : m_rect.width(),
- m_mirrorVertical ? -m_rect.height() : m_rect.height());
+ mirrored = QRectF(m_mirrorHorizontal ? m_logicalRect.right() : m_logicalRect.left(),
+ m_mirrorVertical ? m_logicalRect.bottom() : m_logicalRect.top(),
+ m_mirrorHorizontal ? -m_logicalRect.width() : m_logicalRect.width(),
+ m_mirrorVertical ? -m_logicalRect.height() : m_logicalRect.height());
} else {
- mirrored = QRectF(m_mirrorHorizontal ? m_rect.right() : m_rect.left(),
- m_mirrorVertical ? m_rect.top() : m_rect.bottom(),
- m_mirrorHorizontal ? -m_rect.width() : m_rect.width(),
- m_mirrorVertical ? m_rect.height() : -m_rect.height());
+ mirrored = QRectF(m_mirrorHorizontal ? m_logicalRect.right() : m_logicalRect.left(),
+ m_mirrorVertical ? m_logicalRect.top() : m_logicalRect.bottom(),
+ m_mirrorHorizontal ? -m_logicalRect.width() : m_logicalRect.width(),
+ m_mirrorVertical ? m_logicalRect.height() : -m_logicalRect.height());
}
QSGAbstractRenderer::MatrixTransformFlags matrixFlags;
if (!m_rhi->isYUpInNDC())
matrixFlags |= QSGAbstractRenderer::MatrixTransformFlipY;
m_renderer->setProjectionMatrixToRect(mirrored, matrixFlags);
m_renderer->setClearColor(Qt::transparent);
- m_renderer->setRenderTarget(m_rt);
- m_renderer->setCommandBuffer(m_context->currentFrameCommandBuffer());
- m_renderer->setRenderPassDescriptor(m_rtRp);
+ m_renderer->setRenderTarget({ m_rt, m_rtRp, m_context->currentFrameCommandBuffer() });
QRhiResourceUpdateBatch *resourceUpdates = nullptr;
// render with our own "sub-renderer" (this will just add a render pass to the command buffer)
if (m_multisampling) {
- m_context->renderNextRhiFrame(m_renderer);
+ m_context->renderNextFrame(m_renderer);
} else {
if (m_recursive) {
- m_context->renderNextRhiFrame(m_renderer);
+ m_context->renderNextFrame(m_renderer);
if (!resourceUpdates)
resourceUpdates = m_rhi->nextResourceUpdateBatch();
resourceUpdates->copyTexture(m_texture, m_secondaryTexture);
} else {
- m_context->renderNextRhiFrame(m_renderer);
+ m_context->renderNextFrame(m_renderer);
}
}
@@ -465,10 +443,13 @@ QImage QSGRhiLayer::toImage() const
return QImage();
}
- // There is no room for negotiation here, the texture is RGBA8, and the
- // readback happens with GL_RGBA on GL, so RGBA8888 is the only option.
+ // There is little room for negotiation here, the texture is one of the formats from setFormat.
// Also, Quick is always premultiplied alpha.
- const QImage::Format imageFormat = QImage::Format_RGBA8888_Premultiplied;
+ QImage::Format imageFormat = QImage::Format_RGBA8888_Premultiplied;
+ if (m_format == QRhiTexture::RGBA16F)
+ imageFormat = QImage::Format_RGBA16FPx4_Premultiplied;
+ else if (m_format == QRhiTexture::RGBA32F)
+ imageFormat = QImage::Format_RGBA32FPx4_Premultiplied;
const uchar *p = reinterpret_cast<const uchar *>(result.data.constData());
return QImage(p, result.pixelSize.width(), result.pixelSize.height(), imageFormat).mirrored();