Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qsgopenvgnodevisitor.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 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
10#if QT_CONFIG(quick_sprite)
11#include "qsgopenvgspritenode.h"
12#endif
14
16
17#include <QtQuick/qsgsimplerectnode.h>
18#include <QtQuick/qsgsimpletexturenode.h>
19#include <QtQuick/qsgrendernode.h>
20
22
23QSGOpenVGNodeVisitor::QSGOpenVGNodeVisitor()
24{
25 //Store the current matrix state
26 QVector<VGfloat> matrix(9);
27 vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
28 vgGetMatrix(matrix.data());
29
30 m_transformStack.push(QOpenVGMatrix(matrix.constData()));
31
32 // Opacity
33 m_opacityState.push(1.0f);
34}
35
36bool QSGOpenVGNodeVisitor::visit(QSGTransformNode *node)
37{
38 const QVector<float> matrixData = { node->matrix().constData()[0], node->matrix().constData()[1], node->matrix().constData()[3],
39 node->matrix().constData()[4], node->matrix().constData()[5], node->matrix().constData()[7],
40 node->matrix().constData()[12], node->matrix().constData()[13], node->matrix().constData()[15] };
41 const QOpenVGMatrix matrix2d(matrixData.constData());
42
43 m_transformStack.push(m_transformStack.top() * matrix2d);
44 return true;
45}
46
47void QSGOpenVGNodeVisitor::endVisit(QSGTransformNode *)
48{
49 m_transformStack.pop();
50}
51
52bool QSGOpenVGNodeVisitor::visit(QSGClipNode *node)
53{
54 VGMaskOperation maskOperation = VG_INTERSECT_MASK;
55 if (m_clipStack.count() == 0) {
56 vgSeti(VG_MASKING, VG_TRUE);
57 vgMask(0,VG_FILL_MASK, 0, 0, VG_MAXINT, VG_MAXINT);
58 }
59
60 // Render clip node geometry to mask
61 vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
62 vgLoadIdentity();
63 VGPath clipPath = generateClipPath(node->clipRect());
64 vgRenderToMask(clipPath, VG_FILL_PATH, maskOperation);
65
66 m_clipStack.push(clipPath);
67
68 return true;
69}
70
71void QSGOpenVGNodeVisitor::endVisit(QSGClipNode *)
72{
73 // Remove clip node geometry from mask
74 auto clipState = m_clipStack.pop();
75 vgDestroyPath(clipState);
76
77 if (m_clipStack.count() == 0) {
78 vgSeti(VG_MASKING, VG_FALSE);
79 } else {
80 // Recreate the mask
81 vgMask(0,VG_FILL_MASK, 0, 0, VG_MAXINT, VG_MAXINT);
82 vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
83 vgLoadIdentity();
84 for (auto path : std::as_const(m_clipStack)) {
85 vgRenderToMask(path, VG_FILL_PATH, VG_INTERSECT_MASK);
86 }
87 }
88}
89
90bool QSGOpenVGNodeVisitor::visit(QSGGeometryNode *node)
91{
92 if (QSGSimpleRectNode *rectNode = dynamic_cast<QSGSimpleRectNode *>(node)) {
93 // TODO: Try and render the QSGSimpleRectNode
94 Q_UNUSED(rectNode);
95 return false;
96 } else if (QSGSimpleTextureNode *tn = dynamic_cast<QSGSimpleTextureNode *>(node)) {
97 // TODO: Try and render the QSGSimpleTextureNode
98 Q_UNUSED(tn);
99 return false;
100 } else if (QSGOpenVGNinePatchNode *nn = dynamic_cast<QSGOpenVGNinePatchNode *>(node)) {
101 renderRenderableNode(nn);
102 } else if (QSGOpenVGRectangleNode *rn = dynamic_cast<QSGOpenVGRectangleNode *>(node)) {
103 renderRenderableNode(rn);
104 } else if (QSGOpenVGImageNode *n = dynamic_cast<QSGOpenVGImageNode *>(node)) {
105 renderRenderableNode(n);
106 } else {
107 // We dont know, so skip
108 return false;
109 }
110
111 return true;
112}
113
114void QSGOpenVGNodeVisitor::endVisit(QSGGeometryNode *)
115{
116}
117
118bool QSGOpenVGNodeVisitor::visit(QSGOpacityNode *node)
119{
120 m_opacityState.push(m_opacityState.top() * node->opacity());
121 return true;
122}
123
124void QSGOpenVGNodeVisitor::endVisit(QSGOpacityNode *)
125{
126 m_opacityState.pop();
127}
128
129bool QSGOpenVGNodeVisitor::visit(QSGInternalImageNode *node)
130{
131 renderRenderableNode(static_cast<QSGOpenVGInternalImageNode*>(node));
132 return true;
133}
134
135void QSGOpenVGNodeVisitor::endVisit(QSGInternalImageNode *)
136{
137}
138
139bool QSGOpenVGNodeVisitor::visit(QSGPainterNode *node)
140{
141 renderRenderableNode(static_cast<QSGOpenVGPainterNode*>(node));
142 return true;
143}
144
145void QSGOpenVGNodeVisitor::endVisit(QSGPainterNode *)
146{
147}
148
149bool QSGOpenVGNodeVisitor::visit(QSGInternalRectangleNode *node)
150{
151 renderRenderableNode(static_cast<QSGOpenVGInternalRectangleNode*>(node));
152 return true;
153}
154
155void QSGOpenVGNodeVisitor::endVisit(QSGInternalRectangleNode *)
156{
157}
158
159bool QSGOpenVGNodeVisitor::visit(QSGGlyphNode *node)
160{
161 renderRenderableNode(static_cast<QSGOpenVGGlyphNode*>(node));
162 return true;
163}
164
165void QSGOpenVGNodeVisitor::endVisit(QSGGlyphNode *)
166{
167}
168
169bool QSGOpenVGNodeVisitor::visit(QSGRootNode *)
170{
171 return true;
172}
173
174void QSGOpenVGNodeVisitor::endVisit(QSGRootNode *)
175{
176}
177
178#if QT_CONFIG(quick_sprite)
179bool QSGOpenVGNodeVisitor::visit(QSGSpriteNode *node)
180{
181 renderRenderableNode(static_cast<QSGOpenVGSpriteNode*>(node));
182 return true;
183}
184
185void QSGOpenVGNodeVisitor::endVisit(QSGSpriteNode *)
186{
187}
188#endif
189
190bool QSGOpenVGNodeVisitor::visit(QSGRenderNode *)
191{
192 return true;
193}
194
195void QSGOpenVGNodeVisitor::endVisit(QSGRenderNode *)
196{
197}
198
199VGPath QSGOpenVGNodeVisitor::generateClipPath(const QRectF &rect) const
200{
201 VGPath clipPath = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1, 0, 0, 0,
202 VG_PATH_CAPABILITY_APPEND_TO);
203
204 // Create command list
205 static const VGubyte rectCommands[] = {
206 VG_MOVE_TO_ABS,
207 VG_LINE_TO_ABS,
208 VG_LINE_TO_ABS,
209 VG_LINE_TO_ABS,
210 VG_CLOSE_PATH
211 };
212
213 const QOpenVGMatrix &transform = m_transformStack.top();
214
215 // Create command data
216 QVector<VGfloat> coordinates(8);
217 const QPointF topLeft = transform.map(rect.topLeft());
218 const QPointF topRight = transform.map(rect.topRight());
219 const QPointF bottomLeft = transform.map(rect.bottomLeft());
220 const QPointF bottomRight = transform.map(rect.bottomRight());
221 coordinates[0] = bottomLeft.x();
222 coordinates[1] = bottomLeft.y();
223 coordinates[2] = bottomRight.x();
224 coordinates[3] = bottomRight.y();
225 coordinates[4] = topRight.x();
226 coordinates[5] = topRight.y();
227 coordinates[6] = topLeft.x();
228 coordinates[7] = topLeft.y();
229
230 vgAppendPathData(clipPath, 5, rectCommands, coordinates.constData());
231 return clipPath;
232}
233
234void QSGOpenVGNodeVisitor::renderRenderableNode(QSGOpenVGRenderable *node)
235{
236 if (!node)
237 return;
238 node->setTransform(m_transformStack.top());
239 node->setOpacity(m_opacityState.top());
240 node->render();
241}
242
243QT_END_NAMESPACE
void endVisit(QSGTransformNode *) override
bool visit(QSGTransformNode *) override
virtual void render()=0