File indexing completed on 2024-05-05 03:56:28

0001 /*
0002  *  SPDX-FileCopyrightText: 2020 Arjen Hiemstra <ahiemstra@heimr.nl>
0003  *
0004  *  SPDX-License-Identifier: LGPL-2.0-or-later
0005  */
0006 
0007 #include "shadowedrectanglematerial.h"
0008 
0009 #include <QOpenGLContext>
0010 
0011 QSGMaterialType ShadowedRectangleMaterial::staticType;
0012 
0013 ShadowedRectangleMaterial::ShadowedRectangleMaterial()
0014 {
0015     setFlag(QSGMaterial::Blending, true);
0016 }
0017 
0018 QSGMaterialShader *ShadowedRectangleMaterial::createShader(QSGRendererInterface::RenderMode) const
0019 {
0020     return new ShadowedRectangleShader{shaderType};
0021 }
0022 
0023 QSGMaterialType *ShadowedRectangleMaterial::type() const
0024 {
0025     return &staticType;
0026 }
0027 
0028 int ShadowedRectangleMaterial::compare(const QSGMaterial *other) const
0029 {
0030     auto material = static_cast<const ShadowedRectangleMaterial *>(other);
0031     /* clang-format off */
0032     if (material->color == color
0033         && material->shadowColor == shadowColor
0034         && material->offset == offset
0035         && material->aspect == aspect
0036         && qFuzzyCompare(material->size, size)
0037         && qFuzzyCompare(material->radius, radius)) { /* clang-format on */
0038         return 0;
0039     }
0040 
0041     return QSGMaterial::compare(other);
0042 }
0043 
0044 ShadowedRectangleShader::ShadowedRectangleShader(ShadowedRectangleMaterial::ShaderType shaderType)
0045 {
0046     setShader(shaderType, QStringLiteral("shadowedrectangle"));
0047 }
0048 
0049 bool ShadowedRectangleShader::updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
0050 {
0051     bool changed = false;
0052     QByteArray *buf = state.uniformData();
0053     Q_ASSERT(buf->size() >= 160);
0054 
0055     if (state.isMatrixDirty()) {
0056         const QMatrix4x4 m = state.combinedMatrix();
0057         memcpy(buf->data(), m.constData(), 64);
0058         changed = true;
0059     }
0060 
0061     if (state.isOpacityDirty()) {
0062         const float opacity = state.opacity();
0063         memcpy(buf->data() + 72, &opacity, 4);
0064         changed = true;
0065     }
0066 
0067     if (!oldMaterial || newMaterial->compare(oldMaterial) != 0) {
0068         const auto material = static_cast<ShadowedRectangleMaterial *>(newMaterial);
0069         memcpy(buf->data() + 64, &material->aspect, 8);
0070         memcpy(buf->data() + 76, &material->size, 4);
0071         memcpy(buf->data() + 80, &material->radius, 16);
0072         float c[4];
0073         material->color.getRgbF(&c[0], &c[1], &c[2], &c[3]);
0074         memcpy(buf->data() + 96, c, 16);
0075         material->shadowColor.getRgbF(&c[0], &c[1], &c[2], &c[3]);
0076         memcpy(buf->data() + 112, c, 16);
0077         memcpy(buf->data() + 128, &material->offset, 8);
0078         changed = true;
0079     }
0080 
0081     return changed;
0082 }
0083 
0084 void ShadowedRectangleShader::setShader(ShadowedRectangleMaterial::ShaderType shaderType, const QString &shader)
0085 {
0086     const auto shaderRoot = QStringLiteral(":/org/kde/kirigami/shaders/");
0087 
0088     setShaderFileName(QSGMaterialShader::VertexStage, shaderRoot + QStringLiteral("shadowedrectangle.vert.qsb"));
0089 
0090     auto shaderFile = shader;
0091     if (shaderType == ShadowedRectangleMaterial::ShaderType::LowPower) {
0092         shaderFile += QStringLiteral("_lowpower");
0093     }
0094     setShaderFileName(QSGMaterialShader::FragmentStage, shaderRoot + shaderFile + QStringLiteral(".frag.qsb"));
0095 }