diff options
Diffstat (limited to 'src/quick/scenegraph/util/qsgtexturematerial.cpp')
-rw-r--r-- | src/quick/scenegraph/util/qsgtexturematerial.cpp | 199 |
1 files changed, 75 insertions, 124 deletions
diff --git a/src/quick/scenegraph/util/qsgtexturematerial.cpp b/src/quick/scenegraph/util/qsgtexturematerial.cpp index 7b1d5abb26..c573284f47 100644 --- a/src/quick/scenegraph/util/qsgtexturematerial.cpp +++ b/src/quick/scenegraph/util/qsgtexturematerial.cpp @@ -1,124 +1,76 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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) 2016 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 "qsgtexturematerial_p.h" -#include "qsgtexture_p.h" -#if QT_CONFIG(opengl) -# include <QtGui/qopenglshaderprogram.h> -# include <QtGui/qopenglfunctions.h> -#endif +#include <private/qsgtexture_p.h> +#include <rhi/qrhi.h> QT_BEGIN_NAMESPACE -#if QT_CONFIG(opengl) inline static bool isPowerOfTwo(int x) { // Assumption: x >= 1 return x == (x & -x); } -#endif - -QSGMaterialType QSGOpaqueTextureMaterialShader::type; -QSGOpaqueTextureMaterialShader::QSGOpaqueTextureMaterialShader() +QSGOpaqueTextureMaterialRhiShader::QSGOpaqueTextureMaterialRhiShader(int viewCount) { -#if QT_CONFIG(opengl) - setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/scenegraph/shaders/opaquetexture.vert")); - setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/opaquetexture.frag")); -#endif + setShaderFileName(VertexStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/opaquetexture.vert.qsb"), viewCount); + setShaderFileName(FragmentStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/opaquetexture.frag.qsb"), viewCount); } -char const *const *QSGOpaqueTextureMaterialShader::attributeNames() const +bool QSGOpaqueTextureMaterialRhiShader::updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *) { - static char const *const attr[] = { "qt_VertexPosition", "qt_VertexTexCoord", nullptr }; - return attr; -} + bool changed = false; + QByteArray *buf = state.uniformData(); + const int matrixCount = qMin(state.projectionMatrixCount(), newMaterial->viewCount()); + + for (int viewIndex = 0; viewIndex < matrixCount; ++viewIndex) { + if (state.isMatrixDirty()) { + const QMatrix4x4 m = state.combinedMatrix(viewIndex); + memcpy(buf->data() + 64 * viewIndex, m.constData(), 64); + changed = true; + } + } -void QSGOpaqueTextureMaterialShader::initialize() -{ -#if QT_CONFIG(opengl) - m_matrix_id = program()->uniformLocation("qt_Matrix"); -#endif + return changed; } -void QSGOpaqueTextureMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) +void QSGOpaqueTextureMaterialRhiShader::updateSampledImage(RenderState &state, int binding, QSGTexture **texture, + QSGMaterial *newMaterial, QSGMaterial *oldMaterial) { - Q_ASSERT(oldEffect == nullptr || newEffect->type() == oldEffect->type()); - QSGOpaqueTextureMaterial *tx = static_cast<QSGOpaqueTextureMaterial *>(newEffect); - QSGOpaqueTextureMaterial *oldTx = static_cast<QSGOpaqueTextureMaterial *>(oldEffect); + if (binding != 1) + return; +#ifdef QT_NO_DEBUG + Q_UNUSED(oldMaterial); +#endif + Q_ASSERT(oldMaterial == nullptr || newMaterial->type() == oldMaterial->type()); + QSGOpaqueTextureMaterial *tx = static_cast<QSGOpaqueTextureMaterial *>(newMaterial); QSGTexture *t = tx->texture(); - -#ifndef QT_NO_DEBUG - if (!qsg_safeguard_texture(t)) + if (!t) { + *texture = nullptr; return; -#endif + } t->setFiltering(tx->filtering()); + t->setMipmapFiltering(tx->mipmapFiltering()); + t->setAnisotropyLevel(tx->anisotropyLevel()); t->setHorizontalWrapMode(tx->horizontalWrapMode()); t->setVerticalWrapMode(tx->verticalWrapMode()); -#if QT_CONFIG(opengl) - bool npotSupported = const_cast<QOpenGLContext *>(state.context()) - ->functions()->hasOpenGLFeature(QOpenGLFunctions::NPOTTextureRepeat); - if (!npotSupported) { + if (!state.rhi()->isFeatureSupported(QRhi::NPOTTextureRepeat)) { QSize size = t->textureSize(); const bool isNpot = !isPowerOfTwo(size.width()) || !isPowerOfTwo(size.height()); if (isNpot) { t->setHorizontalWrapMode(QSGTexture::ClampToEdge); t->setVerticalWrapMode(QSGTexture::ClampToEdge); + t->setMipmapFiltering(QSGTexture::None); } } -#else - Q_UNUSED(state) -#endif - t->setMipmapFiltering(tx->mipmapFiltering()); - t->setAnisotropyLevel(tx->anisotropyLevel()); - if (oldTx == nullptr || oldTx->texture()->textureId() != t->textureId()) - t->bind(); - else - t->updateBindOptions(); -#if QT_CONFIG(opengl) - if (state.isMatrixDirty()) - program()->setUniformValue(m_matrix_id, state.combinedMatrix()); -#endif + t->commitTextureOperations(state.rhi(), state.resourceUpdateBatch()); + *texture = t; } @@ -129,8 +81,8 @@ void QSGOpaqueTextureMaterialShader::updateState(const RenderState &state, QSGMa \inmodule QtQuick \ingroup qtquick-scenegraph-materials - \warning This utility class is only functional when running with the OpenGL - backend of the Qt Quick scenegraph. + \warning This utility class is only functional when running with the + default backend of the Qt Quick scenegraph. The opaque textured material will fill every pixel in a geometry with the supplied texture. The material does not respect the opacity of the @@ -183,19 +135,20 @@ QSGOpaqueTextureMaterial::QSGOpaqueTextureMaterial() */ QSGMaterialType *QSGOpaqueTextureMaterial::type() const { - return &QSGOpaqueTextureMaterialShader::type; + static QSGMaterialType type; + return &type; } /*! \internal */ -QSGMaterialShader *QSGOpaqueTextureMaterial::createShader() const +QSGMaterialShader *QSGOpaqueTextureMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const { - return new QSGOpaqueTextureMaterialShader; + Q_UNUSED(renderMode); + return new QSGOpaqueTextureMaterialRhiShader(viewCount()); } - /*! \fn QSGTexture *QSGOpaqueTextureMaterial::texture() const @@ -323,8 +276,11 @@ int QSGOpaqueTextureMaterial::compare(const QSGMaterial *o) const { Q_ASSERT(o && type() == o->type()); const QSGOpaqueTextureMaterial *other = static_cast<const QSGOpaqueTextureMaterial *>(o); - if (int diff = m_texture->textureId() - other->texture()->textureId()) - return diff; + Q_ASSERT(m_texture); + Q_ASSERT(other->texture()); + const qint64 diff = m_texture->comparisonKey() - other->texture()->comparisonKey(); + if (diff != 0) + return diff < 0 ? -1 : 1; return int(m_filtering) - int(other->m_filtering); } @@ -337,8 +293,8 @@ int QSGOpaqueTextureMaterial::compare(const QSGMaterial *o) const \inmodule QtQuick \ingroup qtquick-scenegraph-materials - \warning This utility class is only functional when running with the OpenGL - backend of the Qt Quick scenegraph. + \warning This utility class is only functional when running with the + default backend of the Qt Quick scenegraph. The textured material will fill every pixel in a geometry with the supplied texture. @@ -363,54 +319,49 @@ int QSGOpaqueTextureMaterial::compare(const QSGMaterial *o) const a material in the scene graph. */ -QSGMaterialType QSGTextureMaterialShader::type; - - - /*! \internal */ QSGMaterialType *QSGTextureMaterial::type() const { - return &QSGTextureMaterialShader::type; + static QSGMaterialType type; + return &type; } - - /*! \internal */ -QSGMaterialShader *QSGTextureMaterial::createShader() const +QSGMaterialShader *QSGTextureMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const { - return new QSGTextureMaterialShader; + Q_UNUSED(renderMode); + return new QSGTextureMaterialRhiShader(viewCount()); } -QSGTextureMaterialShader::QSGTextureMaterialShader() - : QSGOpaqueTextureMaterialShader() -{ -#if QT_CONFIG(opengl) - setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/texture.frag")); -#endif -} -void QSGTextureMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) +QSGTextureMaterialRhiShader::QSGTextureMaterialRhiShader(int viewCount) + : QSGOpaqueTextureMaterialRhiShader(viewCount) { - Q_ASSERT(oldEffect == nullptr || newEffect->type() == oldEffect->type()); -#if QT_CONFIG(opengl) - if (state.isOpacityDirty()) - program()->setUniformValue(m_opacity_id, state.opacity()); -#endif - QSGOpaqueTextureMaterialShader::updateState(state, newEffect, oldEffect); + setShaderFileName(VertexStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/texture.vert.qsb"), viewCount); + setShaderFileName(FragmentStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/texture.frag.qsb"), viewCount); } -void QSGTextureMaterialShader::initialize() +bool QSGTextureMaterialRhiShader::updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) { - QSGOpaqueTextureMaterialShader::initialize(); -#if QT_CONFIG(opengl) - m_opacity_id = program()->uniformLocation("opacity"); -#endif + bool changed = false; + QByteArray *buf = state.uniformData(); + const int shaderMatrixCount = newMaterial->viewCount(); + + if (state.isOpacityDirty()) { + const float opacity = state.opacity(); + memcpy(buf->data() + 64 * shaderMatrixCount, &opacity, 4); + changed = true; + } + + changed |= QSGOpaqueTextureMaterialRhiShader::updateUniformData(state, newMaterial, oldMaterial); + + return changed; } QT_END_NAMESPACE |