Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qsgcurvefillnode_p.cpp
Go to the documentation of this file.
1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
7
8#include <private/qsgtexture_p.h>
9
11
12namespace {
13
15 {
16 public:
18 bool useDerivatives,
19 int viewCount);
20
21 bool updateUniformData(RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
22 void updateSampledImage(RenderState &state, int binding, QSGTexture **texture,
23 QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override;
24 };
25
26 QSGCurveFillMaterialShader::QSGCurveFillMaterialShader(QGradient::Type gradientType,
27 bool useDerivatives,
28 int viewCount)
29 {
30 QString baseName = QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/shapecurve");
31
32 if (gradientType == QGradient::LinearGradient) {
33 baseName += QStringLiteral("_lg");
34 } else if (gradientType == QGradient::RadialGradient) {
35 baseName += QStringLiteral("_rg");
36 } else if (gradientType == QGradient::ConicalGradient) {
37 baseName += QStringLiteral("_cg");
38 }
39
40 if (useDerivatives)
41 baseName += QStringLiteral("_derivatives");
42
43 setShaderFileName(VertexStage, baseName + QStringLiteral(".vert.qsb"), viewCount);
44 setShaderFileName(FragmentStage, baseName + QStringLiteral(".frag.qsb"), viewCount);
45 }
46
47 void QSGCurveFillMaterialShader::updateSampledImage(RenderState &state, int binding, QSGTexture **texture,
48 QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
49 {
50 Q_UNUSED(oldMaterial);
51 const QSGCurveFillMaterial *m = static_cast<QSGCurveFillMaterial *>(newMaterial);
52 const QSGCurveFillNode *node = m->node();
53 if (binding != 1 || node->gradientType() == QGradient::NoGradient)
54 return;
55
57 node->fillGradient()->spread);
59 t->commitTextureOperations(state.rhi(), state.resourceUpdateBatch());
60 *texture = t;
61 }
62
63 bool QSGCurveFillMaterialShader::updateUniformData(RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
64 {
65 bool changed = false;
66 QByteArray *buf = state.uniformData();
67 Q_ASSERT(buf->size() >= 80);
68 const int matrixCount = qMin(state.projectionMatrixCount(), newEffect->viewCount());
69
70 int offset = 0;
71 float matrixScale = 0.0f;
72 if (state.isMatrixDirty()) {
73 for (int viewIndex = 0; viewIndex < matrixCount; ++viewIndex) {
74 const QMatrix4x4 m = state.combinedMatrix(viewIndex);
75 memcpy(buf->data() + offset + viewIndex * 64, m.constData(), 64);
76 }
77
78 matrixScale = qSqrt(qAbs(state.determinant()));
79 memcpy(buf->data() + offset + matrixCount * 64, &matrixScale, 4);
80
81 changed = true;
82 }
83 offset += matrixCount * 64 + 4;
84
85 if (state.isOpacityDirty()) {
86 const float opacity = state.opacity();
87 memcpy(buf->data() + offset, &opacity, 4);
88 changed = true;
89 }
90 offset += 4;
91
92 QSGCurveFillMaterial *newMaterial = static_cast<QSGCurveFillMaterial *>(newEffect);
93 QSGCurveFillMaterial *oldMaterial = static_cast<QSGCurveFillMaterial *>(oldEffect);
94
95 QSGCurveFillNode *newNode = newMaterial != nullptr ? newMaterial->node() : nullptr;
96 QSGCurveFillNode *oldNode = oldMaterial != nullptr ? oldMaterial->node() : nullptr;
97
98 if (newNode == nullptr)
99 return changed;
100
101 if (oldNode == nullptr || oldNode->debug() != newNode->debug()) {
102 float debug = newNode->debug();
103 memcpy(buf->data() + offset, &debug, 4);
104 changed = true;
105 }
106 offset += 8;
107
108 if (newNode->gradientType() == QGradient::NoGradient) {
109 Q_ASSERT(buf->size() >= offset + 16);
110
111 QVector4D newColor = QVector4D(newNode->color().redF(),
112 newNode->color().greenF(),
113 newNode->color().blueF(),
114 newNode->color().alphaF());
115 QVector4D oldColor = oldNode != nullptr
116 ? QVector4D(oldNode->color().redF(),
117 oldNode->color().greenF(),
118 oldNode->color().blueF(),
119 oldNode->color().alphaF())
120 : QVector4D{};
121
122 if (oldNode == nullptr || oldColor != newColor) {
123 memcpy(buf->data() + offset, &newColor, 16);
124 changed = true;
125 }
126
127 offset += 16;
128 } else {
129 Q_ASSERT(buf->size() >= offset + 64);
130
131 if (!oldNode || *oldNode->fillTransform() != *newNode->fillTransform()) {
132 memcpy(buf->data() + offset, newNode->fillTransform()->invertedData(), 64);
133 changed = true;
134 }
135
136 offset += 64;
137 }
138
139 if (newNode->gradientType() == QGradient::LinearGradient) {
140 Q_ASSERT(buf->size() >= offset + 8 + 8);
141
142 QVector2D newGradientStart = QVector2D(newNode->fillGradient()->a);
143 QVector2D oldGradientStart = oldNode != nullptr
144 ? QVector2D(oldNode->fillGradient()->a)
145 : QVector2D{};
146
147 if (newGradientStart != oldGradientStart || oldEffect == nullptr) {
148 memcpy(buf->data() + offset, &newGradientStart, 8);
149 changed = true;
150 }
151 offset += 8;
152
153 QVector2D newGradientEnd = QVector2D(newNode->fillGradient()->b);
154 QVector2D oldGradientEnd = oldNode!= nullptr
155 ? QVector2D(oldNode->fillGradient()->b)
156 : QVector2D{};
157
158 if (newGradientEnd != oldGradientEnd || oldEffect == nullptr) {
159 memcpy(buf->data() + offset, &newGradientEnd, 8);
160 changed = true;
161 }
162
163 offset += 8;
164 } else if (newNode->gradientType() == QGradient::RadialGradient) {
165 Q_ASSERT(buf->size() >= offset + 8 + 8 + 4 + 4);
166
167 QVector2D newFocalPoint = QVector2D(newNode->fillGradient()->b);
168 QVector2D oldFocalPoint = oldNode != nullptr
169 ? QVector2D(oldNode->fillGradient()->b)
170 : QVector2D{};
171 if (oldNode == nullptr || newFocalPoint != oldFocalPoint) {
172 memcpy(buf->data() + offset, &newFocalPoint, 8);
173 changed = true;
174 }
175 offset += 8;
176
177 QVector2D newCenterPoint = QVector2D(newNode->fillGradient()->a);
178 QVector2D oldCenterPoint = oldNode != nullptr
179 ? QVector2D(oldNode->fillGradient()->a)
180 : QVector2D{};
181
182 QVector2D newCenterToFocal = newCenterPoint - newFocalPoint;
183 QVector2D oldCenterToFocal = oldCenterPoint - oldFocalPoint;
184 if (oldNode == nullptr || newCenterToFocal != oldCenterToFocal) {
185 memcpy(buf->data() + offset, &newCenterToFocal, 8);
186 changed = true;
187 }
188 offset += 8;
189
190 float newCenterRadius = newNode->fillGradient()->v0;
191 float oldCenterRadius = oldNode != nullptr
192 ? oldNode->fillGradient()->v0
193 : 0.0f;
194 if (oldNode == nullptr || !qFuzzyCompare(newCenterRadius, oldCenterRadius)) {
195 memcpy(buf->data() + offset, &newCenterRadius, 4);
196 changed = true;
197 }
198 offset += 4;
199
200 float newFocalRadius = newNode->fillGradient()->v1;
201 float oldFocalRadius = oldNode != nullptr
202 ? oldNode->fillGradient()->v1
203 : 0.0f;
204 if (oldNode == nullptr || !qFuzzyCompare(newFocalRadius, oldFocalRadius)) {
205 memcpy(buf->data() + offset, &newFocalRadius, 4);
206 changed = true;
207 }
208 offset += 4;
209
210 } else if (newNode->gradientType() == QGradient::ConicalGradient) {
211 Q_ASSERT(buf->size() >= offset + 8 + 4);
212
213 QVector2D newFocalPoint = QVector2D(newNode->fillGradient()->a);
214 QVector2D oldFocalPoint = oldNode != nullptr
215 ? QVector2D(oldNode->fillGradient()->a)
216 : QVector2D{};
217 if (oldNode == nullptr || newFocalPoint != oldFocalPoint) {
218 memcpy(buf->data() + offset, &newFocalPoint, 8);
219 changed = true;
220 }
221 offset += 8;
222
223 float newAngle = newNode->fillGradient()->v0;
224 float oldAngle = oldNode != nullptr
225 ? oldNode->fillGradient()->v0
226 : 0.0f;
227 if (oldNode == nullptr || !qFuzzyCompare(newAngle, oldAngle)) {
228 newAngle = -qDegreesToRadians(newAngle);
229 memcpy(buf->data() + offset, &newAngle, 4);
230 changed = true;
231 }
232 offset += 4;
233 }
234
235 return changed;
236 }
237
238}
239
246
248{
249 if (other->type() != type())
250 return (type() - other->type());
251
252 const QSGCurveFillMaterial *otherMaterial =
253 static_cast<const QSGCurveFillMaterial *>(other);
254
256 QSGCurveFillNode *b = otherMaterial->node();
257 if (a == b)
258 return 0;
259
260 if (a->gradientType() == QGradient::NoGradient) {
261 if (int d = a->color().red() - b->color().red())
262 return d;
263 if (int d = a->color().green() - b->color().green())
264 return d;
265 if (int d = a->color().blue() - b->color().blue())
266 return d;
267 if (int d = a->color().alpha() - b->color().alpha())
268 return d;
269 } else {
270 const QSGGradientCache::GradientDesc &ga = *a->fillGradient();
271 const QSGGradientCache::GradientDesc &gb = *b->fillGradient();
272
273 if (int d = ga.a.x() - gb.a.x())
274 return d;
275 if (int d = ga.a.y() - gb.a.y())
276 return d;
277 if (int d = ga.b.x() - gb.b.x())
278 return d;
279 if (int d = ga.b.y() - gb.b.y())
280 return d;
281
282 if (int d = ga.v0 - gb.v0)
283 return d;
284 if (int d = ga.v1 - gb.v1)
285 return d;
286
287 if (int d = ga.spread - gb.spread)
288 return d;
289
290 if (int d = ga.stops.size() - gb.stops.size())
291 return d;
292
293 for (int i = 0; i < ga.stops.size(); ++i) {
294 if (int d = ga.stops[i].first - gb.stops[i].first)
295 return d;
296 if (int d = ga.stops[i].second.rgba() - gb.stops[i].second.rgba())
297 return d;
298 }
299
300 if (int d = a->fillTransform()->compareTo(*b->fillTransform()))
301 return d;
302 }
303
304 return 0;
305}
306
308{
309 static QSGMaterialType type[4];
311 Q_ASSERT((index & ~3) == 0); // Only two first bits for gradient type
312
313 return &type[index];
314}
315
317{
318 return new QSGCurveFillMaterialShader(node()->gradientType(),
320 viewCount());
321}
322
\inmodule QtCore
Definition qbytearray.h:57
float greenF() const noexcept
Returns the green color component of this color.
Definition qcolor.cpp:1643
float redF() const noexcept
Returns the red color component of this color.
Definition qcolor.cpp:1611
float alphaF() const noexcept
Returns the alpha color component of this color.
Definition qcolor.cpp:1497
float blueF() const noexcept
Returns the blue color component of this color.
Definition qcolor.cpp:1675
Type
Specifies the type of gradient.
Definition qbrush.h:138
@ LinearGradient
Definition qbrush.h:139
@ NoGradient
Definition qbrush.h:142
@ ConicalGradient
Definition qbrush.h:141
@ RadialGradient
Definition qbrush.h:140
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
Definition qmatrix4x4.h:25
QSGMaterialType * type() const override
This function is called by the scene graph to query an identifier that is unique to the QSGMaterialSh...
QSGCurveFillNode * node() const
int compare(const QSGMaterial *other) const override
Compares this material to other and returns 0 if they are equal; -1 if this material should sort befo...
QSGCurveFillMaterial(QSGCurveFillNode *node)
QSGMaterialShader * createShader(QSGRendererInterface::RenderMode renderMode) const override
This function returns a new instance of a the QSGMaterialShader implementation used to render geometr...
QGradient::Type gradientType() const
const QSGGradientCache::GradientDesc * fillGradient() const
const QSGTransform * fillTransform() const
QColor color() const
static QSGGradientCache * cacheForRhi(QRhi *rhi)
Encapsulates the current rendering state during a call to QSGMaterialShader::updateUniformData() and ...
The QSGMaterialShader class represents a graphics API independent shader program.
The QSGMaterial class encapsulates rendering state for a shader program.
Definition qsgmaterial.h:15
int viewCount() const
void setFlag(Flags flags, bool on=true)
Sets the flags flags on this material if on is true; otherwise clears the attribute.
@ RequiresDeterminant
Definition qsgmaterial.h:19
RenderMode
\value RenderMode2D Normal 2D rendering \value RenderMode2DNoDepthBuffer Normal 2D rendering with dep...
\inmodule QtQuick
Definition qsgtexture.h:20
const float * invertedData() const
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
The QVector2D class represents a vector or vertex in 2D space.
Definition qvectornd.h:31
The QVector4D class represents a vector or vertex in 4D space.
Definition qvectornd.h:330
else opt state
[0]
Combined button and popup list for selecting options.
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
Definition qfloat16.h:333
qfloat16 qSqrt(qfloat16 f)
Definition qfloat16.h:289
static QByteArray cacheKey(Args &&...args)
constexpr float qDegreesToRadians(float degrees)
Definition qmath.h:260
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr T qAbs(const T &t)
Definition qnumeric.h:328
GLboolean GLboolean GLboolean b
const GLfloat * m
GLboolean GLboolean GLboolean GLboolean a
[7]
GLuint index
[2]
GLenum type
GLenum GLuint GLenum GLsizei const GLchar * buf
GLenum GLuint texture
GLenum GLuint GLintptr offset
GLdouble GLdouble t
Definition qopenglext.h:243
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define QStringLiteral(str)
#define Q_UNUSED(x)
unsigned int uint
Definition qtypes.h:34
QSharedPointer< T > other(t)
[5]
The QSGMaterialType class is used as a unique type token in combination with QSGMaterial.