MailJDTourDownloadDocsQualityTestsCoverage

Which source lines and branches the tests execute. Lines 91.5 %, branches 75.0 % (minimum 85 % and 72 %). main @ 399ffe3d · 21 October 2026 · pipeline 7238.

GCC Code Coverage Report


Directory: src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 50.5% 54 / 0 / 107
Functions: 50.0% 1 / 0 / 2
Branches: 44.5% 53 / 0 / 119

presentation/GraphPaintCache.cpp
Line Branch Exec Source
1 #include "GraphPaintCache.h"
2
3 #include <QImage>
4 #include <QLoggingCategory>
5 #include <QPainter>
6 #include <QQuickItem>
7 #include <QQuickWindow>
8 #include <QSGGeometryNode>
9 #include <QSGImageNode>
10 #include <QSGRendererInterface>
11 #include <QSGTransformNode>
12 #include <QSGVertexColorMaterial>
13
14 #include <cmath>
15 #include <cstring>
16
17 Q_DECLARE_LOGGING_CATEGORY(lcGraphLines)
18
19 namespace {
20
21 ✗ QSGGeometryNode *meshNode(QSGGeometryNode *node, const GraphGeometry::Mesh &mesh) {
22 ✗ if (!node) {
23 ✗ node = new QSGGeometryNode;
24 ✗ auto *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_ColoredPoint2D(), 0, 0, QSGGeometry::UnsignedIntType);
25 ✗ geometry->setDrawingMode(QSGGeometry::DrawTriangles);
26 ✗ node->setGeometry(geometry);
27 ✗ node->setFlag(QSGNode::OwnsGeometry);
28 ✗ node->setMaterial(new QSGVertexColorMaterial);
29 ✗ node->setFlag(QSGNode::OwnsMaterial);
30 }
31 ✗ QSGGeometry *geometry = node->geometry();
32 ✗ const auto &vertices = mesh.vertices();
33 ✗ const auto &indices = mesh.indices();
34 ✗ geometry->allocate(int(vertices.size()), int(indices.size()));
35 static_assert(sizeof(GraphGeometry::Vertex) == sizeof(QSGGeometry::ColoredPoint2D));
36 ✗ if (!vertices.empty())
37 ✗ std::memcpy(geometry->vertexDataAsColoredPoint2D(), vertices.data(), vertices.size() * sizeof(GraphGeometry::Vertex));
38 ✗ if (!indices.empty())
39 ✗ std::memcpy(geometry->indexDataAsUInt(), indices.data(), indices.size() * sizeof(quint32));
40 ✗ node->markDirty(QSGNode::DirtyGeometry);
41 ✗ return node;
42 }
43
44 } // namespace
45
46 859 QSGNode *GraphPaintCache::update(QQuickItem *item, QSGNode *old, double k, QPointF t, bool contentChanged,
47 const Draw &draw, int *vertices, bool *refresh) {
48 859 *refresh = false;
49
1/1
✓ Branch 2 → 3 taken 859 times.
859 QQuickWindow *window = item->window();
50
3/5
✓ Branch 3 → 4 taken 859 times.
✗ Branch 3 → 10 not taken.
✓ Branch 4 → 5 taken 859 times.
✓ Branch 5 → 6 taken 859 times.
✗ Branch 5 → 10 not taken.
1718 const bool software = window && window->rendererInterface() &&
51
3/4
✓ Branch 6 → 7 taken 859 times.
✓ Branch 7 → 8 taken 859 times.
✓ Branch 8 → 9 taken 859 times.
✗ Branch 8 → 10 not taken.
859 window->rendererInterface()->graphicsApi() == QSGRendererInterface::Software;
52
2/2
✓ Branch 11 → 12 taken 859 times.
✓ Branch 12 → 13 taken 859 times.
859 const QSizeF size(item->width(), item->height());
53 // A node of the other kind (the renderer changed): start over.
54
3/4
✓ Branch 14 → 15 taken 820 times.
✓ Branch 14 → 19 taken 39 times.
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 19 taken 820 times.
859 if (old && software != m_software) {
55 ✗ delete old;
56 ✗ old = nullptr;
57 ✗ m_valid = false;
58 }
59 859 m_software = software;
60 859 const double extent = std::max(size.width(), size.height());
61
7/8
✓ Branch 22 → 23 taken 820 times.
✓ Branch 22 → 28 taken 39 times.
✓ Branch 23 → 24 taken 820 times.
✗ Branch 23 → 28 not taken.
✓ Branch 24 → 25 taken 733 times.
✓ Branch 24 → 28 taken 87 times.
✓ Branch 26 → 27 taken 732 times.
✓ Branch 26 → 28 taken 1 time.
859 const bool reusable = old && m_valid && !contentChanged && size == m_size;
62 859 const QPointF moved = t - m_t;
63
5/6
✓ Branch 30 → 31 taken 732 times.
✓ Branch 30 → 40 taken 127 times.
✓ Branch 32 → 33 taken 5 times.
✓ Branch 32 → 40 taken 727 times.
✓ Branch 35 → 36 taken 5 times.
✗ Branch 35 → 40 not taken.
864 const bool panOnly = reusable && std::abs(k - m_k) < 1e-9 && std::abs(moved.x()) <= 0.2 * extent &&
64
1/2
✓ Branch 38 → 39 taken 5 times.
✗ Branch 38 → 40 not taken.
5 std::abs(moved.y()) <= 0.2 * extent;
65
1/2
✗ Branch 41 → 42 not taken.
✓ Branch 41 → 70 taken 859 times.
859 if (!software) {
66 ✗ auto *transform = static_cast<QSGTransformNode *>(old);
67 ✗ if (panOnly) {
68 ✗ QMatrix4x4 shift;
69 ✗ shift.translate(float(moved.x()), float(moved.y()));
70 ✗ transform->setMatrix(shift);
71 ✗ return transform;
72 }
73 ✗ if (!transform)
74 ✗ transform = new QSGTransformNode;
75 ✗ GraphGeometry::Mesh mesh;
76 ✗ const double margin = 0.25 * extent;
77 ✗ mesh.setViewport(QRectF(QPointF(0, 0), size).adjusted(-margin, -margin, margin, margin));
78 ✗ draw(&mesh);
79 ✗ *vertices = int(mesh.vertices().size());
80 ✗ auto *geometry = static_cast<QSGGeometryNode *>(transform->firstChild());
81 ✗ const bool fresh = !geometry;
82 ✗ geometry = meshNode(geometry, mesh);
83 ✗ if (fresh)
84 ✗ transform->appendChildNode(geometry);
85 ✗ transform->setMatrix(QMatrix4x4());
86 ✗ m_valid = true;
87 ✗ m_k = k;
88 ✗ m_t = t;
89 ✗ m_size = size;
90 ✗ return transform;
91 ✗ }
92 859 auto *image = static_cast<QSGImageNode *>(old);
93
2/2
✓ Branch 70 → 71 taken 5 times.
✓ Branch 70 → 74 taken 854 times.
859 if (panOnly) {
94
1/1
✓ Branch 72 → 73 taken 5 times.
5 image->setRect(m_drawn.translated(moved));
95 5 return image;
96 }
97 // A zoom in progress: the last picture, scaled to where this view puts it
98 // (canvas = world·k + t, the picture drawn at k₀, t₀), until the view rests.
99
5/6
✓ Branch 74 → 75 taken 727 times.
✓ Branch 74 → 86 taken 127 times.
✓ Branch 75 → 76 taken 726 times.
✓ Branch 75 → 86 taken 1 time.
✓ Branch 76 → 77 taken 726 times.
✗ Branch 76 → 86 not taken.
854 if (reusable && k / m_k > 0.5 && k / m_k < 2) {
100 726 const double ratio = k / m_k;
101 726 const QPointF topLeft = (m_drawn.topLeft() - m_t) * ratio + t;
102
1/1
✓ Branch 84 → 85 taken 726 times.
726 image->setRect(QRectF(topLeft, m_drawn.size() * ratio));
103 726 *refresh = true;
104 726 return image;
105 }
106
2/2
✓ Branch 86 → 87 taken 39 times.
✓ Branch 86 → 89 taken 89 times.
128 if (!image) {
107
1/1
✓ Branch 87 → 88 taken 39 times.
39 image = window->createImageNode();
108
1/1
✓ Branch 88 → 89 taken 39 times.
39 image->setOwnsTexture(true);
109 }
110 128 const double margin = 0.25 * extent;
111 128 const QRectF drawn = QRectF(QPointF(0, 0), size).adjusted(-margin, -margin, margin, margin);
112 // S106-945: at most MaxPicturePixels (64 MiB ARGB32) per item — a large
113 // HiDPI window asked for ~370 MB per item; past the cap the picture is
114 // drawn at a lower resolution, and a failed allocation draws nothing.
115
1/1
✓ Branch 92 → 93 taken 128 times.
128 qreal dpr = window->effectiveDevicePixelRatio();
116 128 const double wanted = drawn.width() * drawn.height() * dpr * dpr;
117
1/2
✗ Branch 95 → 96 not taken.
✓ Branch 95 → 97 taken 128 times.
128 if (wanted > double(MaxPicturePixels))
118 ✗ dpr *= std::sqrt(double(MaxPicturePixels) / wanted);
119 128 const QSize pixels = (drawn.size() * dpr).toSize();
120
1/2
✗ Branch 101 → 102 not taken.
✓ Branch 101 → 105 taken 128 times.
128 if (pixels.isEmpty()) {
121 ✗ image->setRect(QRectF());
122 ✗ return image;
123 }
124
1/1
✓ Branch 105 → 106 taken 128 times.
128 QImage picture(pixels, QImage::Format_ARGB32_Premultiplied);
125
2/3
✓ Branch 106 → 107 taken 128 times.
✗ Branch 107 → 108 not taken.
✓ Branch 107 → 125 taken 128 times.
128 if (picture.isNull()) {
126 ✗ qCWarning(lcGraphLines) << "Graph picture not allocated:" << pixels;
127 ✗ image->setRect(QRectF());
128 ✗ return image;
129 }
130
1/1
✓ Branch 125 → 126 taken 128 times.
128 picture.setDevicePixelRatio(dpr);
131
1/1
✓ Branch 126 → 127 taken 128 times.
128 picture.fill(Qt::transparent);
132 {
133
1/1
✓ Branch 127 → 128 taken 128 times.
128 QPainter painter(&picture);
134
1/1
✓ Branch 130 → 131 taken 128 times.
128 painter.translate(-drawn.topLeft());
135 128 GraphGeometry::PainterSink sink(&painter);
136 128 sink.setViewport(drawn);
137
1/1
✓ Branch 133 → 134 taken 128 times.
128 draw(&sink);
138 128 }
139 128 *vertices = 0;
140
2/2
✓ Branch 136 → 137 taken 128 times.
✓ Branch 137 → 138 taken 128 times.
128 image->setTexture(window->createTextureFromImage(picture));
141
1/1
✓ Branch 138 → 139 taken 128 times.
128 image->setRect(drawn);
142 128 m_valid = true;
143 128 m_k = k;
144 128 m_t = t;
145 128 m_size = size;
146 128 m_drawn = drawn;
147 128 return image;
148 128 }
149