1/*
2 * SPDX-FileCopyrightText: 2020 Arjen Hiemstra <ahiemstra@heimr.nl>
3 *
4 * SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6
7#include "shadowedrectanglematerial.h"
8
9#include <QOpenGLContext>
10
11QSGMaterialType ShadowedRectangleMaterial::staticType;
12
13ShadowedRectangleMaterial::ShadowedRectangleMaterial()
14{
15 setFlag(flags: QSGMaterial::Blending, on: true);
16}
17
18QSGMaterialShader *ShadowedRectangleMaterial::createShader(QSGRendererInterface::RenderMode) const
19{
20 return new ShadowedRectangleShader{shaderType};
21}
22
23QSGMaterialType *ShadowedRectangleMaterial::type() const
24{
25 return &staticType;
26}
27
28int ShadowedRectangleMaterial::compare(const QSGMaterial *other) const
29{
30 auto material = static_cast<const ShadowedRectangleMaterial *>(other);
31 /* clang-format off */
32 if (material->color == color
33 && material->shadowColor == shadowColor
34 && material->offset == offset
35 && material->aspect == aspect
36 && qFuzzyCompare(p1: material->size, p2: size)
37 && qFuzzyCompare(v1: material->radius, v2: radius)) { /* clang-format on */
38 return 0;
39 }
40
41 return QSGMaterial::compare(other);
42}
43
44ShadowedRectangleShader::ShadowedRectangleShader(ShadowedRectangleMaterial::ShaderType shaderType)
45{
46 setShader(shaderType, QStringLiteral("shadowedrectangle"));
47}
48
49bool ShadowedRectangleShader::updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
50{
51 bool changed = false;
52 QByteArray *buf = state.uniformData();
53 Q_ASSERT(buf->size() >= 160);
54
55 if (state.isMatrixDirty()) {
56 const QMatrix4x4 m = state.combinedMatrix();
57 memcpy(dest: buf->data(), src: m.constData(), n: 64);
58 changed = true;
59 }
60
61 if (state.isOpacityDirty()) {
62 const float opacity = state.opacity();
63 memcpy(dest: buf->data() + 72, src: &opacity, n: 4);
64 changed = true;
65 }
66
67 if (!oldMaterial || newMaterial->compare(other: oldMaterial) != 0) {
68 const auto material = static_cast<ShadowedRectangleMaterial *>(newMaterial);
69 memcpy(dest: buf->data() + 64, src: &material->aspect, n: 8);
70 memcpy(dest: buf->data() + 76, src: &material->size, n: 4);
71 memcpy(dest: buf->data() + 80, src: &material->radius, n: 16);
72 float c[4];
73 material->color.getRgbF(r: &c[0], g: &c[1], b: &c[2], a: &c[3]);
74 memcpy(dest: buf->data() + 96, src: c, n: 16);
75 material->shadowColor.getRgbF(r: &c[0], g: &c[1], b: &c[2], a: &c[3]);
76 memcpy(dest: buf->data() + 112, src: c, n: 16);
77 memcpy(dest: buf->data() + 128, src: &material->offset, n: 8);
78 changed = true;
79 }
80
81 return changed;
82}
83
84void ShadowedRectangleShader::setShader(ShadowedRectangleMaterial::ShaderType shaderType, const QString &shader)
85{
86 const auto shaderRoot = QStringLiteral(":/org/kde/kirigami/shaders/");
87
88 setShaderFileName(stage: QSGMaterialShader::VertexStage, filename: shaderRoot + QStringLiteral("shadowedrectangle.vert.qsb"));
89
90 auto shaderFile = shader;
91 if (shaderType == ShadowedRectangleMaterial::ShaderType::LowPower) {
92 shaderFile += QStringLiteral("_lowpower");
93 }
94 setShaderFileName(stage: QSGMaterialShader::FragmentStage, filename: shaderRoot + shaderFile + QStringLiteral(".frag.qsb"));
95}
96

source code of kirigami/src/scenegraph/shadowedrectanglematerial.cpp