OpenCoverage

qsgabstractsoftwarerenderer.cpp

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/qtdeclarative/src/qtdeclarative/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Contact: https://www.qt.io/licensing/-
5**-
6** This file is part of the QtQuick module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see https://www.qt.io/terms-conditions. For further-
15** information use the contact form at https://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 3 as published by the Free Software-
20** Foundation and appearing in the file LICENSE.LGPL3 included in the-
21** packaging of this file. Please review the following information to-
22** ensure the GNU Lesser General Public License version 3 requirements-
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
24**-
25** GNU General Public License Usage-
26** Alternatively, this file may be used under the terms of the GNU-
27** General Public License version 2.0 or (at your option) the GNU General-
28** Public license version 3 or any later version approved by the KDE Free-
29** Qt Foundation. The licenses are as published by the Free Software-
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
31** included in the packaging of this file. Please review the following-
32** information to ensure the GNU General Public License requirements will-
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
34** https://www.gnu.org/licenses/gpl-3.0.html.-
35**-
36** $QT_END_LICENSE$-
37**-
38****************************************************************************/-
39-
40#include "qsgabstractsoftwarerenderer_p.h"-
41-
42#include "qsgsoftwarerenderablenodeupdater_p.h"-
43#include "qsgsoftwarerenderlistbuilder_p.h"-
44#include "qsgsoftwarecontext_p.h"-
45#include "qsgsoftwarerenderablenode_p.h"-
46-
47#include <QtCore/QLoggingCategory>-
48#include <QtGui/QWindow>-
49#include <QtQuick/QSGSimpleRectNode>-
50-
51Q_LOGGING_CATEGORY(lc2DRender, "qt.scenegraph.softwarecontext.abstractrenderer")
executed 88 times by 1 test: return category;
Executed by:
  • tst_qquickshape
88
52-
53QT_BEGIN_NAMESPACE-
54-
55QSGAbstractSoftwareRenderer::QSGAbstractSoftwareRenderer(QSGRenderContext *context)-
56 : QSGRenderer(context)-
57 , m_background(new QSGSimpleRectNode)-
58 , m_nodeUpdater(new QSGSoftwareRenderableNodeUpdater(this))-
59{-
60 // Setup special background node-
61 auto backgroundRenderable = new QSGSoftwareRenderableNode(QSGSoftwareRenderableNode::SimpleRect, m_background);-
62 addNodeMapping(m_background, backgroundRenderable);-
63}
executed 8 times by 1 test: end of block
Executed by:
  • tst_qquickshape
8
64-
65QSGAbstractSoftwareRenderer::~QSGAbstractSoftwareRenderer()-
66{-
67 // Cleanup RenderableNodes-
68 delete m_background;-
69-
70 qDeleteAll(m_nodes);-
71-
72 delete m_nodeUpdater;-
73}
executed 8 times by 1 test: end of block
Executed by:
  • tst_qquickshape
8
74-
75QSGSoftwareRenderableNode *QSGAbstractSoftwareRenderer::renderableNode(QSGNode *node) const-
76{-
77 return m_nodes.value(node, nullptr);
executed 104 times by 1 test: return m_nodes.value(node, nullptr);
Executed by:
  • tst_qquickshape
104
78}-
79-
80const QLinkedList<QSGSoftwareRenderableNode*> &QSGAbstractSoftwareRenderer::renderableNodes() const-
81{-
82 return m_renderableNodes;
never executed: return m_renderableNodes;
0
83}-
84-
85void QSGAbstractSoftwareRenderer::addNodeMapping(QSGNode *node, QSGSoftwareRenderableNode *renderableNode)-
86{-
87 m_nodes.insert(node, renderableNode);-
88}
executed 16 times by 1 test: end of block
Executed by:
  • tst_qquickshape
16
89-
90void QSGAbstractSoftwareRenderer::appendRenderableNode(QSGSoftwareRenderableNode *node)-
91{-
92 m_renderableNodes.append(node);-
93}
executed 24 times by 1 test: end of block
Executed by:
  • tst_qquickshape
24
94-
95void QSGAbstractSoftwareRenderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state)-
96{-
97 if (state & QSGNode::DirtyGeometry) {
state & QSGNode::DirtyGeometryDescription
TRUEnever evaluated
FALSEevaluated 72 times by 1 test
Evaluated by:
  • tst_qquickshape
0-72
98 nodeGeometryUpdated(node);-
99 }
never executed: end of block
0
100 if (state & QSGNode::DirtyMaterial) {
state & QSGNode::DirtyMaterialDescription
TRUEnever evaluated
FALSEevaluated 72 times by 1 test
Evaluated by:
  • tst_qquickshape
0-72
101 nodeMaterialUpdated(node);-
102 }
never executed: end of block
0
103 if (state & QSGNode::DirtyMatrix) {
state & QSGNode::DirtyMatrixDescription
TRUEevaluated 16 times by 1 test
Evaluated by:
  • tst_qquickshape
FALSEevaluated 56 times by 1 test
Evaluated by:
  • tst_qquickshape
16-56
104 nodeMatrixUpdated(node);-
105 }
executed 16 times by 1 test: end of block
Executed by:
  • tst_qquickshape
16
106 if (state & QSGNode::DirtyNodeAdded) {
state & QSGNod...DirtyNodeAddedDescription
TRUEevaluated 32 times by 1 test
Evaluated by:
  • tst_qquickshape
FALSEevaluated 40 times by 1 test
Evaluated by:
  • tst_qquickshape
32-40
107 nodeAdded(node);-
108 }
executed 32 times by 1 test: end of block
Executed by:
  • tst_qquickshape
32
109 if (state & QSGNode::DirtyNodeRemoved) {
state & QSGNod...rtyNodeRemovedDescription
TRUEevaluated 24 times by 1 test
Evaluated by:
  • tst_qquickshape
FALSEevaluated 48 times by 1 test
Evaluated by:
  • tst_qquickshape
24-48
110 nodeRemoved(node);-
111 }
executed 24 times by 1 test: end of block
Executed by:
  • tst_qquickshape
24
112 if (state & QSGNode::DirtyOpacity) {
state & QSGNode::DirtyOpacityDescription
TRUEnever evaluated
FALSEevaluated 72 times by 1 test
Evaluated by:
  • tst_qquickshape
0-72
113 nodeOpacityUpdated(node);-
114 }
never executed: end of block
0
115 if (state & QSGNode::DirtySubtreeBlocked) {
state & QSGNod...SubtreeBlockedDescription
TRUEnever evaluated
FALSEevaluated 72 times by 1 test
Evaluated by:
  • tst_qquickshape
0-72
116 m_nodeUpdater->updateNodes(node);-
117 }
never executed: end of block
0
118 if (state & QSGNode::DirtyForceUpdate) {
state & QSGNod...rtyForceUpdateDescription
TRUEnever evaluated
FALSEevaluated 72 times by 1 test
Evaluated by:
  • tst_qquickshape
0-72
119 m_nodeUpdater->updateNodes(node);-
120 }
never executed: end of block
0
121 QSGRenderer::nodeChanged(node, state);-
122}
executed 72 times by 1 test: end of block
Executed by:
  • tst_qquickshape
72
123-
124QRegion QSGAbstractSoftwareRenderer::renderNodes(QPainter *painter)-
125{-
126 QRegion dirtyRegion;-
127 // If there are no nodes, do nothing-
128 if (m_renderableNodes.isEmpty())
m_renderableNodes.isEmpty()Description
TRUEnever evaluated
FALSEevaluated 24 times by 1 test
Evaluated by:
  • tst_qquickshape
0-24
129 return dirtyRegion;
never executed: return dirtyRegion;
0
130-
131 auto iterator = m_renderableNodes.begin();-
132 // First node is the background and needs to painted without blending-
133 auto backgroundNode = *iterator;-
134 dirtyRegion += backgroundNode->renderNode(painter, /*force opaque painting*/ true);-
135 iterator++;-
136-
137 for (; iterator != m_renderableNodes.end(); ++iterator) {
iterator != m_...bleNodes.end()Description
TRUEevaluated 24 times by 1 test
Evaluated by:
  • tst_qquickshape
FALSEevaluated 24 times by 1 test
Evaluated by:
  • tst_qquickshape
24
138 auto node = *iterator;-
139 dirtyRegion += node->renderNode(painter);-
140 }
executed 24 times by 1 test: end of block
Executed by:
  • tst_qquickshape
24
141-
142 return dirtyRegion;
executed 24 times by 1 test: return dirtyRegion;
Executed by:
  • tst_qquickshape
24
143}-
144-
145void QSGAbstractSoftwareRenderer::buildRenderList()-
146{-
147 // Clear the previous renderlist-
148 m_renderableNodes.clear();-
149 // Add the background renderable (always first)-
150 m_renderableNodes.append(renderableNode(m_background));-
151 // Build the renderlist-
152 QSGSoftwareRenderListBuilder(this).visitChildren(rootNode());-
153}
executed 24 times by 1 test: end of block
Executed by:
  • tst_qquickshape
24
154-
155QRegion QSGAbstractSoftwareRenderer::optimizeRenderList()-
156{-
157 // Iterate through the renderlist from front to back-
158 // Objective is to update the dirty status and rects.-
159 for (auto i = m_renderableNodes.rbegin(); i != m_renderableNodes.rend(); ++i) {
i != m_renderableNodes.rend()Description
TRUEevaluated 48 times by 1 test
Evaluated by:
  • tst_qquickshape
FALSEevaluated 24 times by 1 test
Evaluated by:
  • tst_qquickshape
24-48
160 auto node = *i;-
161 if (!m_dirtyRegion.isEmpty()) {
!m_dirtyRegion.isEmpty()Description
TRUEevaluated 16 times by 1 test
Evaluated by:
  • tst_qquickshape
FALSEevaluated 32 times by 1 test
Evaluated by:
  • tst_qquickshape
16-32
162 // See if the current dirty regions apply to the current node-
163 node->addDirtyRegion(m_dirtyRegion, true);-
164 }
executed 16 times by 1 test: end of block
Executed by:
  • tst_qquickshape
16
165-
166 if (!m_obscuredRegion.isEmpty()) {
!m_obscuredRegion.isEmpty()Description
TRUEnever evaluated
FALSEevaluated 48 times by 1 test
Evaluated by:
  • tst_qquickshape
0-48
167 // Don't try to paint things that are covered by opaque objects-
168 node->subtractDirtyRegion(m_obscuredRegion);-
169 }
never executed: end of block
0
170-
171 // Keep up with obscured regions-
172 if (node->isOpaque()) {
node->isOpaque()Description
TRUEevaluated 24 times by 1 test
Evaluated by:
  • tst_qquickshape
FALSEevaluated 24 times by 1 test
Evaluated by:
  • tst_qquickshape
24
173 m_obscuredRegion += node->boundingRectMin();-
174 }
executed 24 times by 1 test: end of block
Executed by:
  • tst_qquickshape
24
175-
176 if (node->isDirty()) {
node->isDirty()Description
TRUEevaluated 16 times by 1 test
Evaluated by:
  • tst_qquickshape
FALSEevaluated 32 times by 1 test
Evaluated by:
  • tst_qquickshape
16-32
177 // Don't paint things outside of the rendering area-
178 if (!m_background->rect().toRect().contains(node->boundingRectMax(), /*proper*/ true)) {
!m_background-...ctMax(), true)Description
TRUEevaluated 10 times by 1 test
Evaluated by:
  • tst_qquickshape
FALSEevaluated 6 times by 1 test
Evaluated by:
  • tst_qquickshape
6-10
179 // Some part(s) of node is(are) outside of the rendering area-
180 QRegion renderArea(m_background->rect().toRect());-
181 QRegion outsideRegions = node->dirtyRegion().subtracted(renderArea);-
182 if (!outsideRegions.isEmpty())
!outsideRegions.isEmpty()Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • tst_qquickshape
FALSEevaluated 8 times by 1 test
Evaluated by:
  • tst_qquickshape
2-8
183 node->subtractDirtyRegion(outsideRegions);
executed 2 times by 1 test: node->subtractDirtyRegion(outsideRegions);
Executed by:
  • tst_qquickshape
2
184 }
executed 10 times by 1 test: end of block
Executed by:
  • tst_qquickshape
10
185-
186 // Get the dirty region's to pass to the next nodes-
187 if (node->isOpaque()) {
node->isOpaque()Description
TRUEevaluated 8 times by 1 test
Evaluated by:
  • tst_qquickshape
FALSEevaluated 8 times by 1 test
Evaluated by:
  • tst_qquickshape
8
188 // if isOpaque, subtract node's dirty rect from m_dirtyRegion-
189 m_dirtyRegion -= node->boundingRectMin();-
190 } else {
executed 8 times by 1 test: end of block
Executed by:
  • tst_qquickshape
8
191 // if isAlpha, add node's dirty rect to m_dirtyRegion-
192 m_dirtyRegion += node->dirtyRegion();-
193 }
executed 8 times by 1 test: end of block
Executed by:
  • tst_qquickshape
8
194 // if previousDirtyRegion has content outside of boundingRect add to m_dirtyRegion-
195 QRegion prevDirty = node->previousDirtyRegion();-
196 if (!prevDirty.isNull())
!prevDirty.isNull()Description
TRUEnever evaluated
FALSEevaluated 16 times by 1 test
Evaluated by:
  • tst_qquickshape
0-16
197 m_dirtyRegion += prevDirty;
never executed: m_dirtyRegion += prevDirty;
0
198 }
executed 16 times by 1 test: end of block
Executed by:
  • tst_qquickshape
16
199 }
executed 48 times by 1 test: end of block
Executed by:
  • tst_qquickshape
48
200-
201 if (m_obscuredRegion.contains(m_background->rect().toAlignedRect())) {
m_obscuredRegi...AlignedRect())Description
TRUEevaluated 24 times by 1 test
Evaluated by:
  • tst_qquickshape
FALSEnever evaluated
0-24
202 m_isOpaque = true;-
203 } else {
executed 24 times by 1 test: end of block
Executed by:
  • tst_qquickshape
24
204 m_isOpaque = false;-
205 }
never executed: end of block
0
206-
207 // Empty dirtyRegion (for second pass)-
208 m_dirtyRegion = QRegion();-
209 m_obscuredRegion = QRegion();-
210-
211 // Iterate through the renderlist from back to front-
212 // Objective is to make sure all non-opaque items are painted when an item under them is dirty-
213 for (auto j = m_renderableNodes.begin(); j != m_renderableNodes.end(); ++j) {
j != m_renderableNodes.end()Description
TRUEevaluated 48 times by 1 test
Evaluated by:
  • tst_qquickshape
FALSEevaluated 24 times by 1 test
Evaluated by:
  • tst_qquickshape
24-48
214 auto node = *j;-
215-
216 if (!node->isOpaque() && !m_dirtyRegion.isEmpty()) {
!node->isOpaque()Description
TRUEevaluated 24 times by 1 test
Evaluated by:
  • tst_qquickshape
FALSEevaluated 24 times by 1 test
Evaluated by:
  • tst_qquickshape
!m_dirtyRegion.isEmpty()Description
TRUEevaluated 8 times by 1 test
Evaluated by:
  • tst_qquickshape
FALSEevaluated 16 times by 1 test
Evaluated by:
  • tst_qquickshape
8-24
217 // Only blended nodes need to be updated-
218 node->addDirtyRegion(m_dirtyRegion, true);-
219 }
executed 8 times by 1 test: end of block
Executed by:
  • tst_qquickshape
8
220-
221 m_dirtyRegion += node->dirtyRegion();-
222 }
executed 48 times by 1 test: end of block
Executed by:
  • tst_qquickshape
48
223-
224 QRegion updateRegion = m_dirtyRegion;-
225-
226 // Empty dirtyRegion-
227 m_dirtyRegion = QRegion();-
228 m_obscuredRegion = QRegion();-
229-
230 return updateRegion;
executed 24 times by 1 test: return updateRegion;
Executed by:
  • tst_qquickshape
24
231}-
232-
233void QSGAbstractSoftwareRenderer::setBackgroundColor(const QColor &color)-
234{-
235 if (m_background->color() == color)
m_background->color() == colorDescription
TRUEevaluated 24 times by 1 test
Evaluated by:
  • tst_qquickshape
FALSEnever evaluated
0-24
236 return;
executed 24 times by 1 test: return;
Executed by:
  • tst_qquickshape
24
237 m_background->setColor(color);-
238 renderableNode(m_background)->markMaterialDirty();-
239}
never executed: end of block
0
240-
241void QSGAbstractSoftwareRenderer::setBackgroundRect(const QRect &rect)-
242{-
243 if (m_background->rect().toRect() == rect)
m_background->...Rect() == rectDescription
TRUEevaluated 16 times by 1 test
Evaluated by:
  • tst_qquickshape
FALSEevaluated 8 times by 1 test
Evaluated by:
  • tst_qquickshape
8-16
244 return;
executed 16 times by 1 test: return;
Executed by:
  • tst_qquickshape
16
245 m_background->setRect(rect);-
246 renderableNode(m_background)->markGeometryDirty();-
247 // Invalidate the whole scene when the background is resized-
248 markDirty();-
249}
executed 8 times by 1 test: end of block
Executed by:
  • tst_qquickshape
8
250-
251QColor QSGAbstractSoftwareRenderer::backgroundColor()-
252{-
253 return m_background->color();
never executed: return m_background->color();
0
254}-
255-
256QRect QSGAbstractSoftwareRenderer::backgroundRect()-
257{-
258 return m_background->rect().toRect();
never executed: return m_background->rect().toRect();
0
259}-
260-
261void QSGAbstractSoftwareRenderer::nodeAdded(QSGNode *node)-
262{-
263 qCDebug(lc2DRender, "nodeAdded %p", (void*)node);
never executed: QMessageLogger(__FILE__, 263, __PRETTY_FUNCTION__, lc2DRender().categoryName()).debug("nodeAdded %p", (void*)node);
qt_category_enabledDescription
TRUEnever evaluated
FALSEevaluated 32 times by 1 test
Evaluated by:
  • tst_qquickshape
0-32
264-
265 m_nodeUpdater->updateNodes(node);-
266}
executed 32 times by 1 test: end of block
Executed by:
  • tst_qquickshape
32
267-
268void QSGAbstractSoftwareRenderer::nodeRemoved(QSGNode *node)-
269{-
270 qCDebug(lc2DRender, "nodeRemoved %p", (void*)node);
never executed: QMessageLogger(__FILE__, 270, __PRETTY_FUNCTION__, lc2DRender().categoryName()).debug("nodeRemoved %p", (void*)node);
qt_category_enabledDescription
TRUEnever evaluated
FALSEevaluated 40 times by 1 test
Evaluated by:
  • tst_qquickshape
0-40
271-
272 auto renderable = renderableNode(node);-
273 // remove mapping-
274 if (renderable != nullptr) {
renderable != nullptrDescription
TRUEevaluated 8 times by 1 test
Evaluated by:
  • tst_qquickshape
FALSEevaluated 32 times by 1 test
Evaluated by:
  • tst_qquickshape
8-32
275 // Need to mark this region dirty in the other nodes-
276 QRegion dirtyRegion = renderable->previousDirtyRegion(true);-
277 if (dirtyRegion.isEmpty())
dirtyRegion.isEmpty()Description
TRUEnever evaluated
FALSEevaluated 8 times by 1 test
Evaluated by:
  • tst_qquickshape
0-8
278 dirtyRegion = renderable->boundingRectMax();
never executed: dirtyRegion = renderable->boundingRectMax();
0
279 m_dirtyRegion += dirtyRegion;-
280 m_nodes.remove(node);-
281 delete renderable;-
282 }
executed 8 times by 1 test: end of block
Executed by:
  • tst_qquickshape
8
283-
284 // Remove all children nodes as well-
285 for (QSGNode *child = node->firstChild(); child; child = child->nextSibling()) {
childDescription
TRUEevaluated 16 times by 1 test
Evaluated by:
  • tst_qquickshape
FALSEevaluated 40 times by 1 test
Evaluated by:
  • tst_qquickshape
16-40
286 nodeRemoved(child);-
287 }
executed 16 times by 1 test: end of block
Executed by:
  • tst_qquickshape
16
288-
289 m_nodeUpdater->updateNodes(node, true);-
290}
executed 40 times by 1 test: end of block
Executed by:
  • tst_qquickshape
40
291-
292void QSGAbstractSoftwareRenderer::nodeGeometryUpdated(QSGNode *node)-
293{-
294 qCDebug(lc2DRender, "nodeGeometryUpdated");
never executed: QMessageLogger(__FILE__, 294, __PRETTY_FUNCTION__, lc2DRender().categoryName()).debug("nodeGeometryUpdated");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
295-
296 // Mark node as dirty-
297 auto renderable = renderableNode(node);-
298 if (renderable != nullptr) {
renderable != nullptrDescription
TRUEnever evaluated
FALSEnever evaluated
0
299 renderable->markGeometryDirty();-
300 } else {
never executed: end of block
0
301 m_nodeUpdater->updateNodes(node);-
302 }
never executed: end of block
0
303}-
304-
305void QSGAbstractSoftwareRenderer::nodeMaterialUpdated(QSGNode *node)-
306{-
307 qCDebug(lc2DRender, "nodeMaterialUpdated");
never executed: QMessageLogger(__FILE__, 307, __PRETTY_FUNCTION__, lc2DRender().categoryName()).debug("nodeMaterialUpdated");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
308-
309 // Mark node as dirty-
310 auto renderable = renderableNode(node);-
311 if (renderable != nullptr) {
renderable != nullptrDescription
TRUEnever evaluated
FALSEnever evaluated
0
312 renderable->markMaterialDirty();-
313 } else {
never executed: end of block
0
314 m_nodeUpdater->updateNodes(node);-
315 }
never executed: end of block
0
316}-
317-
318void QSGAbstractSoftwareRenderer::nodeMatrixUpdated(QSGNode *node)-
319{-
320 qCDebug(lc2DRender, "nodeMaterialUpdated");
never executed: QMessageLogger(__FILE__, 320, __PRETTY_FUNCTION__, lc2DRender().categoryName()).debug("nodeMaterialUpdated");
qt_category_enabledDescription
TRUEnever evaluated
FALSEevaluated 16 times by 1 test
Evaluated by:
  • tst_qquickshape
0-16
321-
322 // Update children nodes-
323 m_nodeUpdater->updateNodes(node);-
324}
executed 16 times by 1 test: end of block
Executed by:
  • tst_qquickshape
16
325-
326void QSGAbstractSoftwareRenderer::nodeOpacityUpdated(QSGNode *node)-
327{-
328 qCDebug(lc2DRender, "nodeOpacityUpdated");
never executed: QMessageLogger(__FILE__, 328, __PRETTY_FUNCTION__, lc2DRender().categoryName()).debug("nodeOpacityUpdated");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
329-
330 // Update children nodes-
331 m_nodeUpdater->updateNodes(node);-
332}
never executed: end of block
0
333-
334void QSGAbstractSoftwareRenderer::markDirty()-
335{-
336 m_dirtyRegion = QRegion(m_background->rect().toRect());-
337}
executed 8 times by 1 test: end of block
Executed by:
  • tst_qquickshape
8
338-
339QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.2.0