| Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/qtdeclarative/src/qtdeclarative/src/quickshapes/qquickshapegenericrenderer.cpp |
| Source code | Switch to Preprocessed file |
| Line | Source | Count | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 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 "qquickshapegenericrenderer_p.h" | - | ||||||||||||||||||
| 41 | #include <QtGui/private/qtriangulator_p.h> | - | ||||||||||||||||||
| 42 | #include <QtGui/private/qtriangulatingstroker_p.h> | - | ||||||||||||||||||
| 43 | #include <QThreadPool> | - | ||||||||||||||||||
| 44 | - | |||||||||||||||||||
| 45 | #if QT_CONFIG(opengl) | - | ||||||||||||||||||
| 46 | #include <QSGVertexColorMaterial> | - | ||||||||||||||||||
| 47 | #include <QOpenGLContext> | - | ||||||||||||||||||
| 48 | #include <QOffscreenSurface> | - | ||||||||||||||||||
| 49 | #include <QtGui/private/qopenglextensions_p.h> | - | ||||||||||||||||||
| 50 | #endif | - | ||||||||||||||||||
| 51 | - | |||||||||||||||||||
| 52 | QT_BEGIN_NAMESPACE | - | ||||||||||||||||||
| 53 | - | |||||||||||||||||||
| 54 | static const qreal TRI_SCALE = 1; | - | ||||||||||||||||||
| 55 | - | |||||||||||||||||||
| 56 | struct ColoredVertex // must match QSGGeometry::ColoredPoint2D | - | ||||||||||||||||||
| 57 | { | - | ||||||||||||||||||
| 58 | float x, y; | - | ||||||||||||||||||
| 59 | QQuickShapeGenericRenderer::Color4ub color; | - | ||||||||||||||||||
| 60 | void set(float nx, float ny, QQuickShapeGenericRenderer::Color4ub ncolor) | - | ||||||||||||||||||
| 61 | { | - | ||||||||||||||||||
| 62 | x = nx; y = ny; color = ncolor; | - | ||||||||||||||||||
| 63 | } executed 85750 times by 1 test: end of blockExecuted by:
| 85750 | ||||||||||||||||||
| 64 | }; | - | ||||||||||||||||||
| 65 | - | |||||||||||||||||||
| 66 | static inline QQuickShapeGenericRenderer::Color4ub colorToColor4ub(const QColor &c) | - | ||||||||||||||||||
| 67 | { | - | ||||||||||||||||||
| 68 | QQuickShapeGenericRenderer::Color4ub color = { | - | ||||||||||||||||||
| 69 | uchar(qRound(c.redF() * c.alphaF() * 255)), | - | ||||||||||||||||||
| 70 | uchar(qRound(c.greenF() * c.alphaF() * 255)), | - | ||||||||||||||||||
| 71 | uchar(qRound(c.blueF() * c.alphaF() * 255)), | - | ||||||||||||||||||
| 72 | uchar(qRound(c.alphaF() * 255)) | - | ||||||||||||||||||
| 73 | }; | - | ||||||||||||||||||
| 74 | return color; executed 2078 times by 1 test: return color;Executed by:
| 2078 | ||||||||||||||||||
| 75 | } | - | ||||||||||||||||||
| 76 | - | |||||||||||||||||||
| 77 | QQuickShapeGenericStrokeFillNode::QQuickShapeGenericStrokeFillNode(QQuickWindow *window) | - | ||||||||||||||||||
| 78 | : m_material(nullptr) | - | ||||||||||||||||||
| 79 | { | - | ||||||||||||||||||
| 80 | setFlag(QSGNode::OwnsGeometry, true); | - | ||||||||||||||||||
| 81 | setGeometry(new QSGGeometry(QSGGeometry::defaultAttributes_ColoredPoint2D(), 0, 0)); | - | ||||||||||||||||||
| 82 | activateMaterial(window, MatSolidColor); | - | ||||||||||||||||||
| 83 | #ifdef QSG_RUNTIME_DESCRIPTION | - | ||||||||||||||||||
| 84 | qsgnode_set_description(this, QLatin1String("stroke-fill")); | - | ||||||||||||||||||
| 85 | #endif | - | ||||||||||||||||||
| 86 | } executed 1327 times by 1 test: end of blockExecuted by:
| 1327 | ||||||||||||||||||
| 87 | - | |||||||||||||||||||
| 88 | void QQuickShapeGenericStrokeFillNode::activateMaterial(QQuickWindow *window, Material m) | - | ||||||||||||||||||
| 89 | { | - | ||||||||||||||||||
| 90 | switch (m) { | - | ||||||||||||||||||
| 91 | case MatSolidColor: executed 1341 times by 1 test: case MatSolidColor:Executed by:
| 1341 | ||||||||||||||||||
| 92 | // Use vertexcolor material. Items with different colors remain batchable | - | ||||||||||||||||||
| 93 | // this way, at the expense of having to provide per-vertex color values. | - | ||||||||||||||||||
| 94 | m_material.reset(QQuickShapeGenericMaterialFactory::createVertexColor(window)); | - | ||||||||||||||||||
| 95 | break; executed 1341 times by 1 test: break;Executed by:
| 1341 | ||||||||||||||||||
| 96 | case MatLinearGradient: executed 12 times by 1 test: case MatLinearGradient:Executed by:
| 12 | ||||||||||||||||||
| 97 | m_material.reset(QQuickShapeGenericMaterialFactory::createLinearGradient(window, this)); | - | ||||||||||||||||||
| 98 | break; executed 12 times by 1 test: break;Executed by:
| 12 | ||||||||||||||||||
| 99 | case MatRadialGradient: executed 4 times by 1 test: case MatRadialGradient:Executed by:
| 4 | ||||||||||||||||||
| 100 | m_material.reset(QQuickShapeGenericMaterialFactory::createRadialGradient(window, this)); | - | ||||||||||||||||||
| 101 | break; executed 4 times by 1 test: break;Executed by:
| 4 | ||||||||||||||||||
| 102 | case MatConicalGradient: executed 3 times by 1 test: case MatConicalGradient:Executed by:
| 3 | ||||||||||||||||||
| 103 | m_material.reset(QQuickShapeGenericMaterialFactory::createConicalGradient(window, this)); | - | ||||||||||||||||||
| 104 | break; executed 3 times by 1 test: break;Executed by:
| 3 | ||||||||||||||||||
| 105 | default: never executed: default: | 0 | ||||||||||||||||||
| 106 | qWarning("Unknown material %d", m); | - | ||||||||||||||||||
| 107 | return; never executed: return; | 0 | ||||||||||||||||||
| 108 | } | - | ||||||||||||||||||
| 109 | - | |||||||||||||||||||
| 110 | if (material() != m_material.data())
| 0-1360 | ||||||||||||||||||
| 111 | setMaterial(m_material.data()); executed 1360 times by 1 test: setMaterial(m_material.data());Executed by:
| 1360 | ||||||||||||||||||
| 112 | } executed 1360 times by 1 test: end of blockExecuted by:
| 1360 | ||||||||||||||||||
| 113 | - | |||||||||||||||||||
| 114 | static bool q_supportsElementIndexUint(QSGRendererInterface::GraphicsApi api) | - | ||||||||||||||||||
| 115 | { | - | ||||||||||||||||||
| 116 | static bool elementIndexUint = true; | - | ||||||||||||||||||
| 117 | #if QT_CONFIG(opengl) | - | ||||||||||||||||||
| 118 | if (api == QSGRendererInterface::OpenGL) {
| 0-937 | ||||||||||||||||||
| 119 | static bool elementIndexUintChecked = false; | - | ||||||||||||||||||
| 120 | if (!elementIndexUintChecked) {
| 2-935 | ||||||||||||||||||
| 121 | elementIndexUintChecked = true; | - | ||||||||||||||||||
| 122 | QOpenGLContext *context = QOpenGLContext::currentContext(); | - | ||||||||||||||||||
| 123 | QScopedPointer<QOpenGLContext> dummyContext; | - | ||||||||||||||||||
| 124 | QScopedPointer<QOffscreenSurface> dummySurface; | - | ||||||||||||||||||
| 125 | bool ok = true; | - | ||||||||||||||||||
| 126 | if (!context) {
| 0-2 | ||||||||||||||||||
| 127 | dummyContext.reset(new QOpenGLContext); | - | ||||||||||||||||||
| 128 | dummyContext->create(); | - | ||||||||||||||||||
| 129 | context = dummyContext.data(); | - | ||||||||||||||||||
| 130 | dummySurface.reset(new QOffscreenSurface); | - | ||||||||||||||||||
| 131 | dummySurface->setFormat(context->format()); | - | ||||||||||||||||||
| 132 | dummySurface->create(); | - | ||||||||||||||||||
| 133 | ok = context->makeCurrent(dummySurface.data()); | - | ||||||||||||||||||
| 134 | } never executed: end of block | 0 | ||||||||||||||||||
| 135 | if (ok) {
| 0-2 | ||||||||||||||||||
| 136 | elementIndexUint = static_cast<QOpenGLExtensions *>(context->functions())->hasOpenGLExtension( | - | ||||||||||||||||||
| 137 | QOpenGLExtensions::ElementIndexUint); | - | ||||||||||||||||||
| 138 | } executed 2 times by 1 test: end of blockExecuted by:
| 2 | ||||||||||||||||||
| 139 | } executed 2 times by 1 test: end of blockExecuted by:
| 2 | ||||||||||||||||||
| 140 | } executed 937 times by 1 test: end of blockExecuted by:
| 937 | ||||||||||||||||||
| 141 | #else | - | ||||||||||||||||||
| 142 | Q_UNUSED(api); | - | ||||||||||||||||||
| 143 | #endif | - | ||||||||||||||||||
| 144 | return elementIndexUint; executed 937 times by 1 test: return elementIndexUint;Executed by:
| 937 | ||||||||||||||||||
| 145 | } | - | ||||||||||||||||||
| 146 | - | |||||||||||||||||||
| 147 | QQuickShapeGenericRenderer::~QQuickShapeGenericRenderer() | - | ||||||||||||||||||
| 148 | { | - | ||||||||||||||||||
| 149 | for (ShapePathData &d : m_sp) { | - | ||||||||||||||||||
| 150 | if (d.pendingFill)
| 135-904 | ||||||||||||||||||
| 151 | d.pendingFill->orphaned = true; executed 904 times by 1 test: d.pendingFill->orphaned = true;Executed by:
| 904 | ||||||||||||||||||
| 152 | if (d.pendingStroke)
| 312-727 | ||||||||||||||||||
| 153 | d.pendingStroke->orphaned = true; executed 312 times by 1 test: d.pendingStroke->orphaned = true;Executed by:
| 312 | ||||||||||||||||||
| 154 | } executed 1039 times by 1 test: end of blockExecuted by:
| 1039 | ||||||||||||||||||
| 155 | } executed 83 times by 1 test: end of blockExecuted by:
| 83 | ||||||||||||||||||
| 156 | - | |||||||||||||||||||
| 157 | // sync, and so triangulation too, happens on the gui thread | - | ||||||||||||||||||
| 158 | // - except when async is set, in which case triangulation is moved to worker threads | - | ||||||||||||||||||
| 159 | - | |||||||||||||||||||
| 160 | void QQuickShapeGenericRenderer::beginSync(int totalCount) | - | ||||||||||||||||||
| 161 | { | - | ||||||||||||||||||
| 162 | if (m_sp.count() != totalCount) {
| 0-83 | ||||||||||||||||||
| 163 | m_sp.resize(totalCount); | - | ||||||||||||||||||
| 164 | m_accDirty |= DirtyList; | - | ||||||||||||||||||
| 165 | } executed 83 times by 1 test: end of blockExecuted by:
| 83 | ||||||||||||||||||
| 166 | for (ShapePathData &d : m_sp) | - | ||||||||||||||||||
| 167 | d.syncDirty = 0; executed 1039 times by 1 test: d.syncDirty = 0;Executed by:
| 1039 | ||||||||||||||||||
| 168 | } executed 83 times by 1 test: end of blockExecuted by:
| 83 | ||||||||||||||||||
| 169 | - | |||||||||||||||||||
| 170 | void QQuickShapeGenericRenderer::setPath(int index, const QQuickPath *path) | - | ||||||||||||||||||
| 171 | { | - | ||||||||||||||||||
| 172 | ShapePathData &d(m_sp[index]); | - | ||||||||||||||||||
| 173 | d.path = path ? path->path() : QPainterPath();
| 0-1039 | ||||||||||||||||||
| 174 | d.syncDirty |= DirtyFillGeom | DirtyStrokeGeom; | - | ||||||||||||||||||
| 175 | } executed 1039 times by 1 test: end of blockExecuted by:
| 1039 | ||||||||||||||||||
| 176 | - | |||||||||||||||||||
| 177 | void QQuickShapeGenericRenderer::setStrokeColor(int index, const QColor &color) | - | ||||||||||||||||||
| 178 | { | - | ||||||||||||||||||
| 179 | ShapePathData &d(m_sp[index]); | - | ||||||||||||||||||
| 180 | d.strokeColor = colorToColor4ub(color); | - | ||||||||||||||||||
| 181 | d.syncDirty |= DirtyColor; | - | ||||||||||||||||||
| 182 | } executed 1039 times by 1 test: end of blockExecuted by:
| 1039 | ||||||||||||||||||
| 183 | - | |||||||||||||||||||
| 184 | void QQuickShapeGenericRenderer::setStrokeWidth(int index, qreal w) | - | ||||||||||||||||||
| 185 | { | - | ||||||||||||||||||
| 186 | ShapePathData &d(m_sp[index]); | - | ||||||||||||||||||
| 187 | d.strokeWidth = w; | - | ||||||||||||||||||
| 188 | if (w >= 0.0f)
| 388-651 | ||||||||||||||||||
| 189 | d.pen.setWidthF(w); executed 388 times by 1 test: d.pen.setWidthF(w);Executed by:
| 388 | ||||||||||||||||||
| 190 | d.syncDirty |= DirtyStrokeGeom; | - | ||||||||||||||||||
| 191 | } executed 1039 times by 1 test: end of blockExecuted by:
| 1039 | ||||||||||||||||||
| 192 | - | |||||||||||||||||||
| 193 | void QQuickShapeGenericRenderer::setFillColor(int index, const QColor &color) | - | ||||||||||||||||||
| 194 | { | - | ||||||||||||||||||
| 195 | ShapePathData &d(m_sp[index]); | - | ||||||||||||||||||
| 196 | d.fillColor = colorToColor4ub(color); | - | ||||||||||||||||||
| 197 | d.syncDirty |= DirtyColor; | - | ||||||||||||||||||
| 198 | } executed 1039 times by 1 test: end of blockExecuted by:
| 1039 | ||||||||||||||||||
| 199 | - | |||||||||||||||||||
| 200 | void QQuickShapeGenericRenderer::setFillRule(int index, QQuickShapePath::FillRule fillRule) | - | ||||||||||||||||||
| 201 | { | - | ||||||||||||||||||
| 202 | ShapePathData &d(m_sp[index]); | - | ||||||||||||||||||
| 203 | d.fillRule = Qt::FillRule(fillRule); | - | ||||||||||||||||||
| 204 | d.syncDirty |= DirtyFillGeom; | - | ||||||||||||||||||
| 205 | } executed 1039 times by 1 test: end of blockExecuted by:
| 1039 | ||||||||||||||||||
| 206 | - | |||||||||||||||||||
| 207 | void QQuickShapeGenericRenderer::setJoinStyle(int index, QQuickShapePath::JoinStyle joinStyle, int miterLimit) | - | ||||||||||||||||||
| 208 | { | - | ||||||||||||||||||
| 209 | ShapePathData &d(m_sp[index]); | - | ||||||||||||||||||
| 210 | d.pen.setJoinStyle(Qt::PenJoinStyle(joinStyle)); | - | ||||||||||||||||||
| 211 | d.pen.setMiterLimit(miterLimit); | - | ||||||||||||||||||
| 212 | d.syncDirty |= DirtyStrokeGeom; | - | ||||||||||||||||||
| 213 | } executed 1039 times by 1 test: end of blockExecuted by:
| 1039 | ||||||||||||||||||
| 214 | - | |||||||||||||||||||
| 215 | void QQuickShapeGenericRenderer::setCapStyle(int index, QQuickShapePath::CapStyle capStyle) | - | ||||||||||||||||||
| 216 | { | - | ||||||||||||||||||
| 217 | ShapePathData &d(m_sp[index]); | - | ||||||||||||||||||
| 218 | d.pen.setCapStyle(Qt::PenCapStyle(capStyle)); | - | ||||||||||||||||||
| 219 | d.syncDirty |= DirtyStrokeGeom; | - | ||||||||||||||||||
| 220 | } executed 1039 times by 1 test: end of blockExecuted by:
| 1039 | ||||||||||||||||||
| 221 | - | |||||||||||||||||||
| 222 | void QQuickShapeGenericRenderer::setStrokeStyle(int index, QQuickShapePath::StrokeStyle strokeStyle, | - | ||||||||||||||||||
| 223 | qreal dashOffset, const QVector<qreal> &dashPattern) | - | ||||||||||||||||||
| 224 | { | - | ||||||||||||||||||
| 225 | ShapePathData &d(m_sp[index]); | - | ||||||||||||||||||
| 226 | d.pen.setStyle(Qt::PenStyle(strokeStyle)); | - | ||||||||||||||||||
| 227 | if (strokeStyle == QQuickShapePath::DashLine) {
| 21-1018 | ||||||||||||||||||
| 228 | d.pen.setDashPattern(dashPattern); | - | ||||||||||||||||||
| 229 | d.pen.setDashOffset(dashOffset); | - | ||||||||||||||||||
| 230 | } executed 21 times by 1 test: end of blockExecuted by:
| 21 | ||||||||||||||||||
| 231 | d.syncDirty |= DirtyStrokeGeom; | - | ||||||||||||||||||
| 232 | } executed 1039 times by 1 test: end of blockExecuted by:
| 1039 | ||||||||||||||||||
| 233 | - | |||||||||||||||||||
| 234 | void QQuickShapeGenericRenderer::setFillGradient(int index, QQuickShapeGradient *gradient) | - | ||||||||||||||||||
| 235 | { | - | ||||||||||||||||||
| 236 | ShapePathData &d(m_sp[index]); | - | ||||||||||||||||||
| 237 | if (gradient) {
| 19-1020 | ||||||||||||||||||
| 238 | d.fillGradient.stops = gradient->gradientStops(); // sorted | - | ||||||||||||||||||
| 239 | d.fillGradient.spread = gradient->spread(); | - | ||||||||||||||||||
| 240 | if (QQuickShapeLinearGradient *g = qobject_cast<QQuickShapeLinearGradient *>(gradient)) {
| 7-12 | ||||||||||||||||||
| 241 | d.fillGradientActive = LinearGradient; | - | ||||||||||||||||||
| 242 | d.fillGradient.a = QPointF(g->x1(), g->y1()); | - | ||||||||||||||||||
| 243 | d.fillGradient.b = QPointF(g->x2(), g->y2()); | - | ||||||||||||||||||
| 244 | } else if (QQuickShapeRadialGradient *g = qobject_cast<QQuickShapeRadialGradient *>(gradient)) { executed 12 times by 1 test: end of blockExecuted by:
| 3-12 | ||||||||||||||||||
| 245 | d.fillGradientActive = RadialGradient; | - | ||||||||||||||||||
| 246 | d.fillGradient.a = QPointF(g->centerX(), g->centerY()); | - | ||||||||||||||||||
| 247 | d.fillGradient.b = QPointF(g->focalX(), g->focalY()); | - | ||||||||||||||||||
| 248 | d.fillGradient.v0 = g->centerRadius(); | - | ||||||||||||||||||
| 249 | d.fillGradient.v1 = g->focalRadius(); | - | ||||||||||||||||||
| 250 | } else if (QQuickShapeConicalGradient *g = qobject_cast<QQuickShapeConicalGradient *>(gradient)) { executed 4 times by 1 test: end of blockExecuted by:
| 0-4 | ||||||||||||||||||
| 251 | d.fillGradientActive = ConicalGradient; | - | ||||||||||||||||||
| 252 | d.fillGradient.a = QPointF(g->centerX(), g->centerY()); | - | ||||||||||||||||||
| 253 | d.fillGradient.v0 = g->angle(); | - | ||||||||||||||||||
| 254 | } else { executed 3 times by 1 test: end of blockExecuted by:
| 3 | ||||||||||||||||||
| 255 | Q_UNREACHABLE(); | - | ||||||||||||||||||
| 256 | } never executed: end of block | 0 | ||||||||||||||||||
| 257 | } else { | - | ||||||||||||||||||
| 258 | d.fillGradientActive = NoGradient; | - | ||||||||||||||||||
| 259 | } executed 1020 times by 1 test: end of blockExecuted by:
| 1020 | ||||||||||||||||||
| 260 | d.syncDirty |= DirtyFillGradient; | - | ||||||||||||||||||
| 261 | } executed 1039 times by 1 test: end of blockExecuted by:
| 1039 | ||||||||||||||||||
| 262 | - | |||||||||||||||||||
| 263 | void QQuickShapeFillRunnable::run() | - | ||||||||||||||||||
| 264 | { | - | ||||||||||||||||||
| 265 | QQuickShapeGenericRenderer::triangulateFill(path, fillColor, &fillVertices, &fillIndices, &indexType, supportsElementIndexUint); | - | ||||||||||||||||||
| 266 | emit done(this); | - | ||||||||||||||||||
| 267 | } executed 904 times by 1 test: end of blockExecuted by:
| 904 | ||||||||||||||||||
| 268 | - | |||||||||||||||||||
| 269 | void QQuickShapeStrokeRunnable::run() | - | ||||||||||||||||||
| 270 | { | - | ||||||||||||||||||
| 271 | QQuickShapeGenericRenderer::triangulateStroke(path, pen, strokeColor, &strokeVertices, clipSize); | - | ||||||||||||||||||
| 272 | emit done(this); | - | ||||||||||||||||||
| 273 | } executed 312 times by 1 test: end of blockExecuted by:
| 312 | ||||||||||||||||||
| 274 | - | |||||||||||||||||||
| 275 | void QQuickShapeGenericRenderer::setAsyncCallback(void (*callback)(void *), void *data) | - | ||||||||||||||||||
| 276 | { | - | ||||||||||||||||||
| 277 | m_asyncCallback = callback; | - | ||||||||||||||||||
| 278 | m_asyncCallbackData = data; | - | ||||||||||||||||||
| 279 | } executed 4 times by 1 test: end of blockExecuted by:
| 4 | ||||||||||||||||||
| 280 | - | |||||||||||||||||||
| 281 | static QThreadPool *pathWorkThreadPool = nullptr; | - | ||||||||||||||||||
| 282 | - | |||||||||||||||||||
| 283 | static void deletePathWorkThreadPool() | - | ||||||||||||||||||
| 284 | { | - | ||||||||||||||||||
| 285 | delete pathWorkThreadPool; | - | ||||||||||||||||||
| 286 | pathWorkThreadPool = nullptr; | - | ||||||||||||||||||
| 287 | } executed 2 times by 1 test: end of blockExecuted by:
| 2 | ||||||||||||||||||
| 288 | - | |||||||||||||||||||
| 289 | void QQuickShapeGenericRenderer::endSync(bool async) | - | ||||||||||||||||||
| 290 | { | - | ||||||||||||||||||
| 291 | bool didKickOffAsync = false; | - | ||||||||||||||||||
| 292 | - | |||||||||||||||||||
| 293 | for (int i = 0; i < m_sp.count(); ++i) {
| 83-1039 | ||||||||||||||||||
| 294 | ShapePathData &d(m_sp[i]); | - | ||||||||||||||||||
| 295 | if (!d.syncDirty)
| 0-1039 | ||||||||||||||||||
| 296 | continue; never executed: continue; | 0 | ||||||||||||||||||
| 297 | - | |||||||||||||||||||
| 298 | m_accDirty |= d.syncDirty; | - | ||||||||||||||||||
| 299 | - | |||||||||||||||||||
| 300 | // Use a shadow dirty flag in order to avoid losing state in case there are | - | ||||||||||||||||||
| 301 | // multiple syncs with different dirty flags before we get to updateNode() | - | ||||||||||||||||||
| 302 | // on the render thread (with the gui thread blocked). For our purposes | - | ||||||||||||||||||
| 303 | // here syncDirty is still required since geometry regeneration must only | - | ||||||||||||||||||
| 304 | // happen when there was an actual change in this particular sync round. | - | ||||||||||||||||||
| 305 | d.effectiveDirty |= d.syncDirty; | - | ||||||||||||||||||
| 306 | - | |||||||||||||||||||
| 307 | if (d.path.isEmpty()) {
| 10-1029 | ||||||||||||||||||
| 308 | d.fillVertices.clear(); | - | ||||||||||||||||||
| 309 | d.fillIndices.clear(); | - | ||||||||||||||||||
| 310 | d.strokeVertices.clear(); | - | ||||||||||||||||||
| 311 | continue; executed 10 times by 1 test: continue;Executed by:
| 10 | ||||||||||||||||||
| 312 | } | - | ||||||||||||||||||
| 313 | - | |||||||||||||||||||
| 314 | if (async && !pathWorkThreadPool) {
| 2-956 | ||||||||||||||||||
| 315 | qAddPostRoutine(deletePathWorkThreadPool); | - | ||||||||||||||||||
| 316 | pathWorkThreadPool = new QThreadPool; | - | ||||||||||||||||||
| 317 | const int idealCount = QThread::idealThreadCount(); | - | ||||||||||||||||||
| 318 | pathWorkThreadPool->setMaxThreadCount(idealCount > 0 ? idealCount * 2 : 4); | - | ||||||||||||||||||
| 319 | } executed 2 times by 1 test: end of blockExecuted by:
| 2 | ||||||||||||||||||
| 320 | - | |||||||||||||||||||
| 321 | if ((d.syncDirty & DirtyFillGeom) && d.fillColor.a) {
| 0-1029 | ||||||||||||||||||
| 322 | d.path.setFillRule(d.fillRule); | - | ||||||||||||||||||
| 323 | if (m_api == QSGRendererInterface::Unknown)
| 37-900 | ||||||||||||||||||
| 324 | m_api = m_item->window()->rendererInterface()->graphicsApi(); executed 37 times by 1 test: m_api = m_item->window()->rendererInterface()->graphicsApi();Executed by:
| 37 | ||||||||||||||||||
| 325 | if (async) {
| 33-904 | ||||||||||||||||||
| 326 | QQuickShapeFillRunnable *r = new QQuickShapeFillRunnable; | - | ||||||||||||||||||
| 327 | r->setAutoDelete(false); | - | ||||||||||||||||||
| 328 | if (d.pendingFill)
| 0-904 | ||||||||||||||||||
| 329 | d.pendingFill->orphaned = true; never executed: d.pendingFill->orphaned = true; | 0 | ||||||||||||||||||
| 330 | d.pendingFill = r; | - | ||||||||||||||||||
| 331 | r->path = d.path; | - | ||||||||||||||||||
| 332 | r->fillColor = d.fillColor; | - | ||||||||||||||||||
| 333 | r->supportsElementIndexUint = q_supportsElementIndexUint(m_api); | - | ||||||||||||||||||
| 334 | // Unlikely in practice but in theory m_sp could be | - | ||||||||||||||||||
| 335 | // resized. Therefore, capture 'i' instead of 'd'. | - | ||||||||||||||||||
| 336 | QObject::connect(r, &QQuickShapeFillRunnable::done, qApp, [this, i](QQuickShapeFillRunnable *r) { | - | ||||||||||||||||||
| 337 | // Bail out when orphaned (meaning either another run was | - | ||||||||||||||||||
| 338 | // started after this one, or the renderer got destroyed). | - | ||||||||||||||||||
| 339 | if (!r->orphaned && i < m_sp.count()) {
| 0-904 | ||||||||||||||||||
| 340 | ShapePathData &d(m_sp[i]); | - | ||||||||||||||||||
| 341 | d.fillVertices = r->fillVertices; | - | ||||||||||||||||||
| 342 | d.fillIndices = r->fillIndices; | - | ||||||||||||||||||
| 343 | d.indexType = r->indexType; | - | ||||||||||||||||||
| 344 | d.pendingFill = nullptr; | - | ||||||||||||||||||
| 345 | d.effectiveDirty |= DirtyFillGeom; | - | ||||||||||||||||||
| 346 | maybeUpdateAsyncItem(); | - | ||||||||||||||||||
| 347 | } never executed: end of block | 0 | ||||||||||||||||||
| 348 | r->deleteLater(); | - | ||||||||||||||||||
| 349 | }); executed 904 times by 1 test: end of blockExecuted by:
| 904 | ||||||||||||||||||
| 350 | didKickOffAsync = true; | - | ||||||||||||||||||
| 351 | pathWorkThreadPool->start(r); | - | ||||||||||||||||||
| 352 | } else { executed 904 times by 1 test: end of blockExecuted by:
| 904 | ||||||||||||||||||
| 353 | triangulateFill(d.path, d.fillColor, &d.fillVertices, &d.fillIndices, &d.indexType, q_supportsElementIndexUint(m_api)); | - | ||||||||||||||||||
| 354 | } executed 33 times by 1 test: end of blockExecuted by:
| 33 | ||||||||||||||||||
| 355 | } | - | ||||||||||||||||||
| 356 | - | |||||||||||||||||||
| 357 | if ((d.syncDirty & DirtyStrokeGeom) && d.strokeWidth >= 0.0f && d.strokeColor.a) {
| 0-1029 | ||||||||||||||||||
| 358 | if (async) {
| 66-312 | ||||||||||||||||||
| 359 | QQuickShapeStrokeRunnable *r = new QQuickShapeStrokeRunnable; | - | ||||||||||||||||||
| 360 | r->setAutoDelete(false); | - | ||||||||||||||||||
| 361 | if (d.pendingStroke)
| 0-312 | ||||||||||||||||||
| 362 | d.pendingStroke->orphaned = true; never executed: d.pendingStroke->orphaned = true; | 0 | ||||||||||||||||||
| 363 | d.pendingStroke = r; | - | ||||||||||||||||||
| 364 | r->path = d.path; | - | ||||||||||||||||||
| 365 | r->pen = d.pen; | - | ||||||||||||||||||
| 366 | r->strokeColor = d.strokeColor; | - | ||||||||||||||||||
| 367 | r->clipSize = QSize(m_item->width(), m_item->height()); | - | ||||||||||||||||||
| 368 | QObject::connect(r, &QQuickShapeStrokeRunnable::done, qApp, [this, i](QQuickShapeStrokeRunnable *r) { | - | ||||||||||||||||||
| 369 | if (!r->orphaned && i < m_sp.count()) {
| 0-312 | ||||||||||||||||||
| 370 | ShapePathData &d(m_sp[i]); | - | ||||||||||||||||||
| 371 | d.strokeVertices = r->strokeVertices; | - | ||||||||||||||||||
| 372 | d.pendingStroke = nullptr; | - | ||||||||||||||||||
| 373 | d.effectiveDirty |= DirtyStrokeGeom; | - | ||||||||||||||||||
| 374 | maybeUpdateAsyncItem(); | - | ||||||||||||||||||
| 375 | } never executed: end of block | 0 | ||||||||||||||||||
| 376 | r->deleteLater(); | - | ||||||||||||||||||
| 377 | }); executed 312 times by 1 test: end of blockExecuted by:
| 312 | ||||||||||||||||||
| 378 | didKickOffAsync = true; | - | ||||||||||||||||||
| 379 | pathWorkThreadPool->start(r); | - | ||||||||||||||||||
| 380 | } else { executed 312 times by 1 test: end of blockExecuted by:
| 312 | ||||||||||||||||||
| 381 | triangulateStroke(d.path, d.pen, d.strokeColor, &d.strokeVertices, | - | ||||||||||||||||||
| 382 | QSize(m_item->width(), m_item->height())); | - | ||||||||||||||||||
| 383 | } executed 66 times by 1 test: end of blockExecuted by:
| 66 | ||||||||||||||||||
| 384 | } | - | ||||||||||||||||||
| 385 | } executed 1029 times by 1 test: end of blockExecuted by:
| 1029 | ||||||||||||||||||
| 386 | - | |||||||||||||||||||
| 387 | if (!didKickOffAsync && async && m_asyncCallback)
| 0-79 | ||||||||||||||||||
| 388 | m_asyncCallback(m_asyncCallbackData); never executed: m_asyncCallback(m_asyncCallbackData); | 0 | ||||||||||||||||||
| 389 | } executed 83 times by 1 test: end of blockExecuted by:
| 83 | ||||||||||||||||||
| 390 | - | |||||||||||||||||||
| 391 | void QQuickShapeGenericRenderer::maybeUpdateAsyncItem() | - | ||||||||||||||||||
| 392 | { | - | ||||||||||||||||||
| 393 | for (const ShapePathData &d : qAsConst(m_sp)) { | - | ||||||||||||||||||
| 394 | if (d.pendingFill || d.pendingStroke)
| 0 | ||||||||||||||||||
| 395 | return; never executed: return; | 0 | ||||||||||||||||||
| 396 | } never executed: end of block | 0 | ||||||||||||||||||
| 397 | m_accDirty |= DirtyFillGeom | DirtyStrokeGeom; | - | ||||||||||||||||||
| 398 | m_item->update(); | - | ||||||||||||||||||
| 399 | if (m_asyncCallback)
| 0 | ||||||||||||||||||
| 400 | m_asyncCallback(m_asyncCallbackData); never executed: m_asyncCallback(m_asyncCallbackData); | 0 | ||||||||||||||||||
| 401 | } never executed: end of block | 0 | ||||||||||||||||||
| 402 | - | |||||||||||||||||||
| 403 | // the stroke/fill triangulation functions may be invoked either on the gui | - | ||||||||||||||||||
| 404 | // thread or some worker thread and must thus be self-contained. | - | ||||||||||||||||||
| 405 | void QQuickShapeGenericRenderer::triangulateFill(const QPainterPath &path, | - | ||||||||||||||||||
| 406 | const Color4ub &fillColor, | - | ||||||||||||||||||
| 407 | VertexContainerType *fillVertices, | - | ||||||||||||||||||
| 408 | IndexContainerType *fillIndices, | - | ||||||||||||||||||
| 409 | QSGGeometry::Type *indexType, | - | ||||||||||||||||||
| 410 | bool supportsElementIndexUint) | - | ||||||||||||||||||
| 411 | { | - | ||||||||||||||||||
| 412 | const QVectorPath &vp = qtVectorPathForPath(path); | - | ||||||||||||||||||
| 413 | - | |||||||||||||||||||
| 414 | QTriangleSet ts = qTriangulate(vp, QTransform::fromScale(TRI_SCALE, TRI_SCALE), 1, supportsElementIndexUint); | - | ||||||||||||||||||
| 415 | const int vertexCount = ts.vertices.count() / 2; // just a qreal vector with x,y hence the / 2 | - | ||||||||||||||||||
| 416 | fillVertices->resize(vertexCount); | - | ||||||||||||||||||
| 417 | ColoredVertex *vdst = reinterpret_cast<ColoredVertex *>(fillVertices->data()); | - | ||||||||||||||||||
| 418 | const qreal *vsrc = ts.vertices.constData(); | - | ||||||||||||||||||
| 419 | for (int i = 0; i < vertexCount; ++i)
| 937-33801 | ||||||||||||||||||
| 420 | vdst[i].set(vsrc[i * 2] / TRI_SCALE, vsrc[i * 2 + 1] / TRI_SCALE, fillColor); executed 33800 times by 1 test: vdst[i].set(vsrc[i * 2] / TRI_SCALE, vsrc[i * 2 + 1] / TRI_SCALE, fillColor);Executed by:
| 33800 | ||||||||||||||||||
| 421 | - | |||||||||||||||||||
| 422 | size_t indexByteSize; | - | ||||||||||||||||||
| 423 | if (ts.indices.type() == QVertexIndexVector::UnsignedShort) {
| 0-936 | ||||||||||||||||||
| 424 | *indexType = QSGGeometry::UnsignedShortType; | - | ||||||||||||||||||
| 425 | // fillIndices is still QVector<quint32>. Just resize to N/2 and pack | - | ||||||||||||||||||
| 426 | // the N quint16s into it. | - | ||||||||||||||||||
| 427 | fillIndices->resize(ts.indices.size() / 2); | - | ||||||||||||||||||
| 428 | indexByteSize = ts.indices.size() * sizeof(quint16); | - | ||||||||||||||||||
| 429 | } else { never executed: end of block | 0 | ||||||||||||||||||
| 430 | *indexType = QSGGeometry::UnsignedIntType; | - | ||||||||||||||||||
| 431 | fillIndices->resize(ts.indices.size()); | - | ||||||||||||||||||
| 432 | indexByteSize = ts.indices.size() * sizeof(quint32); | - | ||||||||||||||||||
| 433 | } executed 935 times by 1 test: end of blockExecuted by:
| 935 | ||||||||||||||||||
| 434 | memcpy(fillIndices->data(), ts.indices.data(), indexByteSize); | - | ||||||||||||||||||
| 435 | } executed 935 times by 1 test: end of blockExecuted by:
| 935 | ||||||||||||||||||
| 436 | - | |||||||||||||||||||
| 437 | void QQuickShapeGenericRenderer::triangulateStroke(const QPainterPath &path, | - | ||||||||||||||||||
| 438 | const QPen &pen, | - | ||||||||||||||||||
| 439 | const Color4ub &strokeColor, | - | ||||||||||||||||||
| 440 | VertexContainerType *strokeVertices, | - | ||||||||||||||||||
| 441 | const QSize &clipSize) | - | ||||||||||||||||||
| 442 | { | - | ||||||||||||||||||
| 443 | const QVectorPath &vp = qtVectorPathForPath(path); | - | ||||||||||||||||||
| 444 | const QRectF clip(QPointF(0, 0), clipSize); | - | ||||||||||||||||||
| 445 | const qreal inverseScale = 1.0 / TRI_SCALE; | - | ||||||||||||||||||
| 446 | - | |||||||||||||||||||
| 447 | QTriangulatingStroker stroker; | - | ||||||||||||||||||
| 448 | stroker.setInvScale(inverseScale); | - | ||||||||||||||||||
| 449 | - | |||||||||||||||||||
| 450 | if (pen.style() == Qt::SolidLine) {
| 21-357 | ||||||||||||||||||
| 451 | stroker.process(vp, pen, clip, nullptr); | - | ||||||||||||||||||
| 452 | } else { executed 357 times by 1 test: end of blockExecuted by:
| 357 | ||||||||||||||||||
| 453 | QDashedStrokeProcessor dashStroker; | - | ||||||||||||||||||
| 454 | dashStroker.setInvScale(inverseScale); | - | ||||||||||||||||||
| 455 | dashStroker.process(vp, pen, clip, nullptr); | - | ||||||||||||||||||
| 456 | QVectorPath dashStroke(dashStroker.points(), dashStroker.elementCount(), | - | ||||||||||||||||||
| 457 | dashStroker.elementTypes(), 0); | - | ||||||||||||||||||
| 458 | stroker.process(dashStroke, pen, clip, nullptr); | - | ||||||||||||||||||
| 459 | } executed 21 times by 1 test: end of blockExecuted by:
| 21 | ||||||||||||||||||
| 460 | - | |||||||||||||||||||
| 461 | if (!stroker.vertexCount()) {
| 0-378 | ||||||||||||||||||
| 462 | strokeVertices->clear(); | - | ||||||||||||||||||
| 463 | return; never executed: return; | 0 | ||||||||||||||||||
| 464 | } | - | ||||||||||||||||||
| 465 | - | |||||||||||||||||||
| 466 | const int vertexCount = stroker.vertexCount() / 2; // just a float vector with x,y hence the / 2 | - | ||||||||||||||||||
| 467 | strokeVertices->resize(vertexCount); | - | ||||||||||||||||||
| 468 | ColoredVertex *vdst = reinterpret_cast<ColoredVertex *>(strokeVertices->data()); | - | ||||||||||||||||||
| 469 | const float *vsrc = stroker.vertices(); | - | ||||||||||||||||||
| 470 | for (int i = 0; i < vertexCount; ++i)
| 378-51988 | ||||||||||||||||||
| 471 | vdst[i].set(vsrc[i * 2], vsrc[i * 2 + 1], strokeColor); executed 51989 times by 1 test: vdst[i].set(vsrc[i * 2], vsrc[i * 2 + 1], strokeColor);Executed by:
| 51989 | ||||||||||||||||||
| 472 | } executed 378 times by 1 test: end of blockExecuted by:
| 378 | ||||||||||||||||||
| 473 | - | |||||||||||||||||||
| 474 | void QQuickShapeGenericRenderer::setRootNode(QQuickShapeGenericNode *node) | - | ||||||||||||||||||
| 475 | { | - | ||||||||||||||||||
| 476 | if (m_rootNode != node) {
| 0-83 | ||||||||||||||||||
| 477 | m_rootNode = node; | - | ||||||||||||||||||
| 478 | m_accDirty |= DirtyList; | - | ||||||||||||||||||
| 479 | } executed 83 times by 1 test: end of blockExecuted by:
| 83 | ||||||||||||||||||
| 480 | } executed 83 times by 1 test: end of blockExecuted by:
| 83 | ||||||||||||||||||
| 481 | - | |||||||||||||||||||
| 482 | // on the render thread with gui blocked | - | ||||||||||||||||||
| 483 | void QQuickShapeGenericRenderer::updateNode() | - | ||||||||||||||||||
| 484 | { | - | ||||||||||||||||||
| 485 | if (!m_rootNode || !m_accDirty)
| 0-83 | ||||||||||||||||||
| 486 | return; never executed: return; | 0 | ||||||||||||||||||
| 487 | - | |||||||||||||||||||
| 488 | // [ m_rootNode ] | - | ||||||||||||||||||
| 489 | // / / / | - | ||||||||||||||||||
| 490 | // #0 [ fill ] [ stroke ] [ next ] | - | ||||||||||||||||||
| 491 | // / / | | - | ||||||||||||||||||
| 492 | // #1 [ fill ] [ stroke ] [ next ] | - | ||||||||||||||||||
| 493 | // / / | | - | ||||||||||||||||||
| 494 | // #2 [ fill ] [ stroke ] [ next ] | - | ||||||||||||||||||
| 495 | // ... | - | ||||||||||||||||||
| 496 | // ... | - | ||||||||||||||||||
| 497 | - | |||||||||||||||||||
| 498 | QQuickShapeGenericNode **nodePtr = &m_rootNode; | - | ||||||||||||||||||
| 499 | QQuickShapeGenericNode *prevNode = nullptr; | - | ||||||||||||||||||
| 500 | - | |||||||||||||||||||
| 501 | for (ShapePathData &d : m_sp) { | - | ||||||||||||||||||
| 502 | if (!*nodePtr) {
| 83-956 | ||||||||||||||||||
| 503 | Q_ASSERT(prevNode); | - | ||||||||||||||||||
| 504 | *nodePtr = new QQuickShapeGenericNode; | - | ||||||||||||||||||
| 505 | prevNode->m_next = *nodePtr; | - | ||||||||||||||||||
| 506 | prevNode->appendChildNode(*nodePtr); | - | ||||||||||||||||||
| 507 | } executed 956 times by 1 test: end of blockExecuted by:
| 956 | ||||||||||||||||||
| 508 | - | |||||||||||||||||||
| 509 | QQuickShapeGenericNode *node = *nodePtr; | - | ||||||||||||||||||
| 510 | - | |||||||||||||||||||
| 511 | if (m_accDirty & DirtyList)
| 0-1039 | ||||||||||||||||||
| 512 | d.effectiveDirty |= DirtyFillGeom | DirtyStrokeGeom | DirtyColor | DirtyFillGradient; executed 1039 times by 1 test: d.effectiveDirty |= DirtyFillGeom | DirtyStrokeGeom | DirtyColor | DirtyFillGradient;Executed by:
| 1039 | ||||||||||||||||||
| 513 | - | |||||||||||||||||||
| 514 | if (!d.effectiveDirty) {
| 0-1039 | ||||||||||||||||||
| 515 | prevNode = node; | - | ||||||||||||||||||
| 516 | nodePtr = &node->m_next; | - | ||||||||||||||||||
| 517 | continue; never executed: continue; | 0 | ||||||||||||||||||
| 518 | } | - | ||||||||||||||||||
| 519 | - | |||||||||||||||||||
| 520 | if (d.fillColor.a == 0) {
| 96-943 | ||||||||||||||||||
| 521 | delete node->m_fillNode; | - | ||||||||||||||||||
| 522 | node->m_fillNode = nullptr; | - | ||||||||||||||||||
| 523 | } else if (!node->m_fillNode) { executed 96 times by 1 test: end of blockExecuted by:
| 0-943 | ||||||||||||||||||
| 524 | node->m_fillNode = new QQuickShapeGenericStrokeFillNode(m_item->window()); | - | ||||||||||||||||||
| 525 | if (node->m_strokeNode)
| 0-943 | ||||||||||||||||||
| 526 | node->removeChildNode(node->m_strokeNode); never executed: node->removeChildNode(node->m_strokeNode); | 0 | ||||||||||||||||||
| 527 | node->appendChildNode(node->m_fillNode); | - | ||||||||||||||||||
| 528 | if (node->m_strokeNode)
| 0-943 | ||||||||||||||||||
| 529 | node->appendChildNode(node->m_strokeNode); never executed: node->appendChildNode(node->m_strokeNode); | 0 | ||||||||||||||||||
| 530 | d.effectiveDirty |= DirtyFillGeom; | - | ||||||||||||||||||
| 531 | } executed 943 times by 1 test: end of blockExecuted by:
| 943 | ||||||||||||||||||
| 532 | - | |||||||||||||||||||
| 533 | if (d.strokeWidth < 0.0f || d.strokeColor.a == 0) {
| 4-651 | ||||||||||||||||||
| 534 | delete node->m_strokeNode; | - | ||||||||||||||||||
| 535 | node->m_strokeNode = nullptr; | - | ||||||||||||||||||
| 536 | } else if (!node->m_strokeNode) { executed 655 times by 1 test: end of blockExecuted by:
| 0-655 | ||||||||||||||||||
| 537 | node->m_strokeNode = new QQuickShapeGenericStrokeFillNode(m_item->window()); | - | ||||||||||||||||||
| 538 | node->appendChildNode(node->m_strokeNode); | - | ||||||||||||||||||
| 539 | d.effectiveDirty |= DirtyStrokeGeom; | - | ||||||||||||||||||
| 540 | } executed 384 times by 1 test: end of blockExecuted by:
| 384 | ||||||||||||||||||
| 541 | - | |||||||||||||||||||
| 542 | updateFillNode(&d, node); | - | ||||||||||||||||||
| 543 | updateStrokeNode(&d, node); | - | ||||||||||||||||||
| 544 | - | |||||||||||||||||||
| 545 | d.effectiveDirty = 0; | - | ||||||||||||||||||
| 546 | - | |||||||||||||||||||
| 547 | prevNode = node; | - | ||||||||||||||||||
| 548 | nodePtr = &node->m_next; | - | ||||||||||||||||||
| 549 | } executed 1039 times by 1 test: end of blockExecuted by:
| 1039 | ||||||||||||||||||
| 550 | - | |||||||||||||||||||
| 551 | if (*nodePtr && prevNode) {
| 0-83 | ||||||||||||||||||
| 552 | prevNode->removeChildNode(*nodePtr); | - | ||||||||||||||||||
| 553 | delete *nodePtr; | - | ||||||||||||||||||
| 554 | *nodePtr = nullptr; | - | ||||||||||||||||||
| 555 | } never executed: end of block | 0 | ||||||||||||||||||
| 556 | - | |||||||||||||||||||
| 557 | m_accDirty = 0; | - | ||||||||||||||||||
| 558 | } executed 83 times by 1 test: end of blockExecuted by:
| 83 | ||||||||||||||||||
| 559 | - | |||||||||||||||||||
| 560 | void QQuickShapeGenericRenderer::updateShadowDataInNode(ShapePathData *d, QQuickShapeGenericStrokeFillNode *n) | - | ||||||||||||||||||
| 561 | { | - | ||||||||||||||||||
| 562 | if (d->fillGradientActive) {
| 19-924 | ||||||||||||||||||
| 563 | if (d->effectiveDirty & DirtyFillGradient)
| 0-19 | ||||||||||||||||||
| 564 | n->m_fillGradient = d->fillGradient; executed 19 times by 1 test: n->m_fillGradient = d->fillGradient;Executed by:
| 19 | ||||||||||||||||||
| 565 | } executed 19 times by 1 test: end of blockExecuted by:
| 19 | ||||||||||||||||||
| 566 | } executed 943 times by 1 test: end of blockExecuted by:
| 943 | ||||||||||||||||||
| 567 | - | |||||||||||||||||||
| 568 | void QQuickShapeGenericRenderer::updateFillNode(ShapePathData *d, QQuickShapeGenericNode *node) | - | ||||||||||||||||||
| 569 | { | - | ||||||||||||||||||
| 570 | if (!node->m_fillNode)
| 96-943 | ||||||||||||||||||
| 571 | return; executed 96 times by 1 test: return;Executed by:
| 96 | ||||||||||||||||||
| 572 | if (!(d->effectiveDirty & (DirtyFillGeom | DirtyColor | DirtyFillGradient)))
| 0-943 | ||||||||||||||||||
| 573 | return; never executed: return; | 0 | ||||||||||||||||||
| 574 | - | |||||||||||||||||||
| 575 | // Make a copy of the data that will be accessed by the material on | - | ||||||||||||||||||
| 576 | // the render thread. This must be done even when we bail out below. | - | ||||||||||||||||||
| 577 | QQuickShapeGenericStrokeFillNode *n = node->m_fillNode; | - | ||||||||||||||||||
| 578 | updateShadowDataInNode(d, n); | - | ||||||||||||||||||
| 579 | - | |||||||||||||||||||
| 580 | QSGGeometry *g = n->geometry(); | - | ||||||||||||||||||
| 581 | if (d->fillVertices.isEmpty()) {
| 33-910 | ||||||||||||||||||
| 582 | if (g->vertexCount() || g->indexCount()) {
| 0-910 | ||||||||||||||||||
| 583 | g->allocate(0, 0); | - | ||||||||||||||||||
| 584 | n->markDirty(QSGNode::DirtyGeometry); | - | ||||||||||||||||||
| 585 | } never executed: end of block | 0 | ||||||||||||||||||
| 586 | return; executed 910 times by 1 test: return;Executed by:
| 910 | ||||||||||||||||||
| 587 | } | - | ||||||||||||||||||
| 588 | - | |||||||||||||||||||
| 589 | if (d->fillGradientActive) {
| 14-19 | ||||||||||||||||||
| 590 | QQuickShapeGenericStrokeFillNode::Material gradMat; | - | ||||||||||||||||||
| 591 | switch (d->fillGradientActive) { | - | ||||||||||||||||||
| 592 | case LinearGradient: executed 12 times by 1 test: case LinearGradient:Executed by:
| 12 | ||||||||||||||||||
| 593 | gradMat = QQuickShapeGenericStrokeFillNode::MatLinearGradient; | - | ||||||||||||||||||
| 594 | break; executed 12 times by 1 test: break;Executed by:
| 12 | ||||||||||||||||||
| 595 | case RadialGradient: executed 4 times by 1 test: case RadialGradient:Executed by:
| 4 | ||||||||||||||||||
| 596 | gradMat = QQuickShapeGenericStrokeFillNode::MatRadialGradient; | - | ||||||||||||||||||
| 597 | break; executed 4 times by 1 test: break;Executed by:
| 4 | ||||||||||||||||||
| 598 | case ConicalGradient: executed 3 times by 1 test: case ConicalGradient:Executed by:
| 3 | ||||||||||||||||||
| 599 | gradMat = QQuickShapeGenericStrokeFillNode::MatConicalGradient; | - | ||||||||||||||||||
| 600 | break; executed 3 times by 1 test: break;Executed by:
| 3 | ||||||||||||||||||
| 601 | default: never executed: default: | 0 | ||||||||||||||||||
| 602 | Q_UNREACHABLE(); | - | ||||||||||||||||||
| 603 | return; never executed: return; | 0 | ||||||||||||||||||
| 604 | } | - | ||||||||||||||||||
| 605 | n->activateMaterial(m_item->window(), gradMat); | - | ||||||||||||||||||
| 606 | if (d->effectiveDirty & DirtyFillGradient) {
| 0-19 | ||||||||||||||||||
| 607 | // Gradients are implemented via a texture-based material. | - | ||||||||||||||||||
| 608 | n->markDirty(QSGNode::DirtyMaterial); | - | ||||||||||||||||||
| 609 | // stop here if only the gradient changed; no need to touch the geometry | - | ||||||||||||||||||
| 610 | if (!(d->effectiveDirty & DirtyFillGeom))
| 0-19 | ||||||||||||||||||
| 611 | return; never executed: return; | 0 | ||||||||||||||||||
| 612 | } executed 19 times by 1 test: end of blockExecuted by:
| 19 | ||||||||||||||||||
| 613 | } else { executed 19 times by 1 test: end of blockExecuted by:
| 19 | ||||||||||||||||||
| 614 | n->activateMaterial(m_item->window(), QQuickShapeGenericStrokeFillNode::MatSolidColor); | - | ||||||||||||||||||
| 615 | // fast path for updating only color values when no change in vertex positions | - | ||||||||||||||||||
| 616 | if ((d->effectiveDirty & DirtyColor) && !(d->effectiveDirty & DirtyFillGeom)) {
| 0-14 | ||||||||||||||||||
| 617 | ColoredVertex *vdst = reinterpret_cast<ColoredVertex *>(g->vertexData()); | - | ||||||||||||||||||
| 618 | for (int i = 0; i < g->vertexCount(); ++i)
| 0 | ||||||||||||||||||
| 619 | vdst[i].set(vdst[i].x, vdst[i].y, d->fillColor); never executed: vdst[i].set(vdst[i].x, vdst[i].y, d->fillColor); | 0 | ||||||||||||||||||
| 620 | n->markDirty(QSGNode::DirtyGeometry); | - | ||||||||||||||||||
| 621 | return; never executed: return; | 0 | ||||||||||||||||||
| 622 | } | - | ||||||||||||||||||
| 623 | } executed 14 times by 1 test: end of blockExecuted by:
| 14 | ||||||||||||||||||
| 624 | - | |||||||||||||||||||
| 625 | const int indexCount = d->indexType == QSGGeometry::UnsignedShortType
| 0-33 | ||||||||||||||||||
| 626 | ? d->fillIndices.count() * 2 : d->fillIndices.count(); | - | ||||||||||||||||||
| 627 | if (g->indexType() != d->indexType) {
| 0-33 | ||||||||||||||||||
| 628 | g = new QSGGeometry(QSGGeometry::defaultAttributes_ColoredPoint2D(), | - | ||||||||||||||||||
| 629 | d->fillVertices.count(), indexCount, d->indexType); | - | ||||||||||||||||||
| 630 | n->setGeometry(g); | - | ||||||||||||||||||
| 631 | } else { executed 33 times by 1 test: end of blockExecuted by:
| 33 | ||||||||||||||||||
| 632 | g->allocate(d->fillVertices.count(), indexCount); | - | ||||||||||||||||||
| 633 | } never executed: end of block | 0 | ||||||||||||||||||
| 634 | g->setDrawingMode(QSGGeometry::DrawTriangles); | - | ||||||||||||||||||
| 635 | memcpy(g->vertexData(), d->fillVertices.constData(), g->vertexCount() * g->sizeOfVertex()); | - | ||||||||||||||||||
| 636 | memcpy(g->indexData(), d->fillIndices.constData(), g->indexCount() * g->sizeOfIndex()); | - | ||||||||||||||||||
| 637 | - | |||||||||||||||||||
| 638 | n->markDirty(QSGNode::DirtyGeometry); | - | ||||||||||||||||||
| 639 | } executed 33 times by 1 test: end of blockExecuted by:
| 33 | ||||||||||||||||||
| 640 | - | |||||||||||||||||||
| 641 | void QQuickShapeGenericRenderer::updateStrokeNode(ShapePathData *d, QQuickShapeGenericNode *node) | - | ||||||||||||||||||
| 642 | { | - | ||||||||||||||||||
| 643 | if (!node->m_strokeNode)
| 384-655 | ||||||||||||||||||
| 644 | return; executed 655 times by 1 test: return;Executed by:
| 655 | ||||||||||||||||||
| 645 | if (!(d->effectiveDirty & (DirtyStrokeGeom | DirtyColor)))
| 0-384 | ||||||||||||||||||
| 646 | return; never executed: return; | 0 | ||||||||||||||||||
| 647 | - | |||||||||||||||||||
| 648 | QQuickShapeGenericStrokeFillNode *n = node->m_strokeNode; | - | ||||||||||||||||||
| 649 | QSGGeometry *g = n->geometry(); | - | ||||||||||||||||||
| 650 | if (d->strokeVertices.isEmpty()) {
| 66-318 | ||||||||||||||||||
| 651 | if (g->vertexCount() || g->indexCount()) {
| 0-318 | ||||||||||||||||||
| 652 | g->allocate(0, 0); | - | ||||||||||||||||||
| 653 | n->markDirty(QSGNode::DirtyGeometry); | - | ||||||||||||||||||
| 654 | } never executed: end of block | 0 | ||||||||||||||||||
| 655 | return; executed 318 times by 1 test: return;Executed by:
| 318 | ||||||||||||||||||
| 656 | } | - | ||||||||||||||||||
| 657 | - | |||||||||||||||||||
| 658 | n->markDirty(QSGNode::DirtyGeometry); | - | ||||||||||||||||||
| 659 | - | |||||||||||||||||||
| 660 | // Async loading runs update once, bails out above, then updates again once | - | ||||||||||||||||||
| 661 | // ready. Set the material dirty then. This is in-line with fill where the | - | ||||||||||||||||||
| 662 | // first activateMaterial() achieves the same. | - | ||||||||||||||||||
| 663 | if (!g->vertexCount())
| 0-66 | ||||||||||||||||||
| 664 | n->markDirty(QSGNode::DirtyMaterial); executed 66 times by 1 test: n->markDirty(QSGNode::DirtyMaterial);Executed by:
| 66 | ||||||||||||||||||
| 665 | - | |||||||||||||||||||
| 666 | if ((d->effectiveDirty & DirtyColor) && !(d->effectiveDirty & DirtyStrokeGeom)) {
| 0-66 | ||||||||||||||||||
| 667 | ColoredVertex *vdst = reinterpret_cast<ColoredVertex *>(g->vertexData()); | - | ||||||||||||||||||
| 668 | for (int i = 0; i < g->vertexCount(); ++i)
| 0 | ||||||||||||||||||
| 669 | vdst[i].set(vdst[i].x, vdst[i].y, d->strokeColor); never executed: vdst[i].set(vdst[i].x, vdst[i].y, d->strokeColor); | 0 | ||||||||||||||||||
| 670 | return; never executed: return; | 0 | ||||||||||||||||||
| 671 | } | - | ||||||||||||||||||
| 672 | - | |||||||||||||||||||
| 673 | g->allocate(d->strokeVertices.count(), 0); | - | ||||||||||||||||||
| 674 | g->setDrawingMode(QSGGeometry::DrawTriangleStrip); | - | ||||||||||||||||||
| 675 | memcpy(g->vertexData(), d->strokeVertices.constData(), g->vertexCount() * g->sizeOfVertex()); | - | ||||||||||||||||||
| 676 | } executed 66 times by 1 test: end of blockExecuted by:
| 66 | ||||||||||||||||||
| 677 | - | |||||||||||||||||||
| 678 | QSGMaterial *QQuickShapeGenericMaterialFactory::createVertexColor(QQuickWindow *window) | - | ||||||||||||||||||
| 679 | { | - | ||||||||||||||||||
| 680 | QSGRendererInterface::GraphicsApi api = window->rendererInterface()->graphicsApi(); | - | ||||||||||||||||||
| 681 | - | |||||||||||||||||||
| 682 | #if QT_CONFIG(opengl) | - | ||||||||||||||||||
| 683 | if (api == QSGRendererInterface::OpenGL)
| 0-1341 | ||||||||||||||||||
| 684 | return new QSGVertexColorMaterial; executed 1341 times by 1 test: return new QSGVertexColorMaterial;Executed by:
| 1341 | ||||||||||||||||||
| 685 | #endif | - | ||||||||||||||||||
| 686 | - | |||||||||||||||||||
| 687 | qWarning("Vertex-color material: Unsupported graphics API %d", api); | - | ||||||||||||||||||
| 688 | return nullptr; never executed: return nullptr; | 0 | ||||||||||||||||||
| 689 | } | - | ||||||||||||||||||
| 690 | - | |||||||||||||||||||
| 691 | QSGMaterial *QQuickShapeGenericMaterialFactory::createLinearGradient(QQuickWindow *window, | - | ||||||||||||||||||
| 692 | QQuickShapeGenericStrokeFillNode *node) | - | ||||||||||||||||||
| 693 | { | - | ||||||||||||||||||
| 694 | QSGRendererInterface::GraphicsApi api = window->rendererInterface()->graphicsApi(); | - | ||||||||||||||||||
| 695 | - | |||||||||||||||||||
| 696 | #if QT_CONFIG(opengl) | - | ||||||||||||||||||
| 697 | if (api == QSGRendererInterface::OpenGL)
| 0-12 | ||||||||||||||||||
| 698 | return new QQuickShapeLinearGradientMaterial(node); executed 12 times by 1 test: return new QQuickShapeLinearGradientMaterial(node);Executed by:
| 12 | ||||||||||||||||||
| 699 | #else | - | ||||||||||||||||||
| 700 | Q_UNUSED(node); | - | ||||||||||||||||||
| 701 | #endif | - | ||||||||||||||||||
| 702 | - | |||||||||||||||||||
| 703 | qWarning("Linear gradient material: Unsupported graphics API %d", api); | - | ||||||||||||||||||
| 704 | return nullptr; never executed: return nullptr; | 0 | ||||||||||||||||||
| 705 | } | - | ||||||||||||||||||
| 706 | - | |||||||||||||||||||
| 707 | QSGMaterial *QQuickShapeGenericMaterialFactory::createRadialGradient(QQuickWindow *window, | - | ||||||||||||||||||
| 708 | QQuickShapeGenericStrokeFillNode *node) | - | ||||||||||||||||||
| 709 | { | - | ||||||||||||||||||
| 710 | QSGRendererInterface::GraphicsApi api = window->rendererInterface()->graphicsApi(); | - | ||||||||||||||||||
| 711 | - | |||||||||||||||||||
| 712 | #if QT_CONFIG(opengl) | - | ||||||||||||||||||
| 713 | if (api == QSGRendererInterface::OpenGL)
| 0-4 | ||||||||||||||||||
| 714 | return new QQuickShapeRadialGradientMaterial(node); executed 4 times by 1 test: return new QQuickShapeRadialGradientMaterial(node);Executed by:
| 4 | ||||||||||||||||||
| 715 | #else | - | ||||||||||||||||||
| 716 | Q_UNUSED(node); | - | ||||||||||||||||||
| 717 | #endif | - | ||||||||||||||||||
| 718 | - | |||||||||||||||||||
| 719 | qWarning("Radial gradient material: Unsupported graphics API %d", api); | - | ||||||||||||||||||
| 720 | return nullptr; never executed: return nullptr; | 0 | ||||||||||||||||||
| 721 | } | - | ||||||||||||||||||
| 722 | - | |||||||||||||||||||
| 723 | QSGMaterial *QQuickShapeGenericMaterialFactory::createConicalGradient(QQuickWindow *window, | - | ||||||||||||||||||
| 724 | QQuickShapeGenericStrokeFillNode *node) | - | ||||||||||||||||||
| 725 | { | - | ||||||||||||||||||
| 726 | QSGRendererInterface::GraphicsApi api = window->rendererInterface()->graphicsApi(); | - | ||||||||||||||||||
| 727 | - | |||||||||||||||||||
| 728 | #if QT_CONFIG(opengl) | - | ||||||||||||||||||
| 729 | if (api == QSGRendererInterface::OpenGL)
| 0-3 | ||||||||||||||||||
| 730 | return new QQuickShapeConicalGradientMaterial(node); executed 3 times by 1 test: return new QQuickShapeConicalGradientMaterial(node);Executed by:
| 3 | ||||||||||||||||||
| 731 | #else | - | ||||||||||||||||||
| 732 | Q_UNUSED(node); | - | ||||||||||||||||||
| 733 | #endif | - | ||||||||||||||||||
| 734 | - | |||||||||||||||||||
| 735 | qWarning("Conical gradient material: Unsupported graphics API %d", api); | - | ||||||||||||||||||
| 736 | return nullptr; never executed: return nullptr; | 0 | ||||||||||||||||||
| 737 | } | - | ||||||||||||||||||
| 738 | - | |||||||||||||||||||
| 739 | #if QT_CONFIG(opengl) | - | ||||||||||||||||||
| 740 | - | |||||||||||||||||||
| 741 | QSGMaterialType QQuickShapeLinearGradientShader::type; | - | ||||||||||||||||||
| 742 | - | |||||||||||||||||||
| 743 | QQuickShapeLinearGradientShader::QQuickShapeLinearGradientShader() | - | ||||||||||||||||||
| 744 | { | - | ||||||||||||||||||
| 745 | setShaderSourceFile(QOpenGLShader::Vertex, | - | ||||||||||||||||||
| 746 | QStringLiteral(":/qt-project.org/shapes/shaders/lineargradient.vert")); executed 8 times by 1 test: return qstring_literal_temp;Executed by:
| 8 | ||||||||||||||||||
| 747 | setShaderSourceFile(QOpenGLShader::Fragment, | - | ||||||||||||||||||
| 748 | QStringLiteral(":/qt-project.org/shapes/shaders/lineargradient.frag")); executed 8 times by 1 test: return qstring_literal_temp;Executed by:
| 8 | ||||||||||||||||||
| 749 | } executed 8 times by 1 test: end of blockExecuted by:
| 8 | ||||||||||||||||||
| 750 | - | |||||||||||||||||||
| 751 | void QQuickShapeLinearGradientShader::initialize() | - | ||||||||||||||||||
| 752 | { | - | ||||||||||||||||||
| 753 | m_opacityLoc = program()->uniformLocation("opacity"); | - | ||||||||||||||||||
| 754 | m_matrixLoc = program()->uniformLocation("matrix"); | - | ||||||||||||||||||
| 755 | m_gradStartLoc = program()->uniformLocation("gradStart"); | - | ||||||||||||||||||
| 756 | m_gradEndLoc = program()->uniformLocation("gradEnd"); | - | ||||||||||||||||||
| 757 | } executed 8 times by 1 test: end of blockExecuted by:
| 8 | ||||||||||||||||||
| 758 | - | |||||||||||||||||||
| 759 | void QQuickShapeLinearGradientShader::updateState(const RenderState &state, QSGMaterial *mat, QSGMaterial *) | - | ||||||||||||||||||
| 760 | { | - | ||||||||||||||||||
| 761 | QQuickShapeLinearGradientMaterial *m = static_cast<QQuickShapeLinearGradientMaterial *>(mat); | - | ||||||||||||||||||
| 762 | - | |||||||||||||||||||
| 763 | if (state.isOpacityDirty())
| 0-8 | ||||||||||||||||||
| 764 | program()->setUniformValue(m_opacityLoc, state.opacity()); executed 8 times by 1 test: program()->setUniformValue(m_opacityLoc, state.opacity());Executed by:
| 8 | ||||||||||||||||||
| 765 | - | |||||||||||||||||||
| 766 | if (state.isMatrixDirty())
| 0-8 | ||||||||||||||||||
| 767 | program()->setUniformValue(m_matrixLoc, state.combinedMatrix()); executed 8 times by 1 test: program()->setUniformValue(m_matrixLoc, state.combinedMatrix());Executed by:
| 8 | ||||||||||||||||||
| 768 | - | |||||||||||||||||||
| 769 | QQuickShapeGenericStrokeFillNode *node = m->node(); | - | ||||||||||||||||||
| 770 | program()->setUniformValue(m_gradStartLoc, QVector2D(node->m_fillGradient.a)); | - | ||||||||||||||||||
| 771 | program()->setUniformValue(m_gradEndLoc, QVector2D(node->m_fillGradient.b)); | - | ||||||||||||||||||
| 772 | - | |||||||||||||||||||
| 773 | const QQuickShapeGradientCache::Key cacheKey(node->m_fillGradient.stops, node->m_fillGradient.spread); | - | ||||||||||||||||||
| 774 | QSGTexture *tx = QQuickShapeGradientCache::currentCache()->get(cacheKey); | - | ||||||||||||||||||
| 775 | tx->bind(); | - | ||||||||||||||||||
| 776 | } executed 8 times by 1 test: end of blockExecuted by:
| 8 | ||||||||||||||||||
| 777 | - | |||||||||||||||||||
| 778 | char const *const *QQuickShapeLinearGradientShader::attributeNames() const | - | ||||||||||||||||||
| 779 | { | - | ||||||||||||||||||
| 780 | static const char *const attr[] = { "vertexCoord", "vertexColor", nullptr }; | - | ||||||||||||||||||
| 781 | return attr; executed 32 times by 1 test: return attr;Executed by:
| 32 | ||||||||||||||||||
| 782 | } | - | ||||||||||||||||||
| 783 | - | |||||||||||||||||||
| 784 | int QQuickShapeLinearGradientMaterial::compare(const QSGMaterial *other) const | - | ||||||||||||||||||
| 785 | { | - | ||||||||||||||||||
| 786 | Q_ASSERT(other && type() == other->type()); | - | ||||||||||||||||||
| 787 | const QQuickShapeLinearGradientMaterial *m = static_cast<const QQuickShapeLinearGradientMaterial *>(other); | - | ||||||||||||||||||
| 788 | - | |||||||||||||||||||
| 789 | QQuickShapeGenericStrokeFillNode *a = node(); | - | ||||||||||||||||||
| 790 | QQuickShapeGenericStrokeFillNode *b = m->node(); | - | ||||||||||||||||||
| 791 | Q_ASSERT(a && b); | - | ||||||||||||||||||
| 792 | if (a == b)
| 0 | ||||||||||||||||||
| 793 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
| 794 | - | |||||||||||||||||||
| 795 | const QQuickAbstractPathRenderer::GradientDesc *ga = &a->m_fillGradient; | - | ||||||||||||||||||
| 796 | const QQuickAbstractPathRenderer::GradientDesc *gb = &b->m_fillGradient; | - | ||||||||||||||||||
| 797 | - | |||||||||||||||||||
| 798 | if (int d = ga->spread - gb->spread)
| 0 | ||||||||||||||||||
| 799 | return d; never executed: return d; | 0 | ||||||||||||||||||
| 800 | - | |||||||||||||||||||
| 801 | if (int d = ga->a.x() - gb->a.x())
| 0 | ||||||||||||||||||
| 802 | return d; never executed: return d; | 0 | ||||||||||||||||||
| 803 | if (int d = ga->a.y() - gb->a.y())
| 0 | ||||||||||||||||||
| 804 | return d; never executed: return d; | 0 | ||||||||||||||||||
| 805 | if (int d = ga->b.x() - gb->b.x())
| 0 | ||||||||||||||||||
| 806 | return d; never executed: return d; | 0 | ||||||||||||||||||
| 807 | if (int d = ga->b.y() - gb->b.y())
| 0 | ||||||||||||||||||
| 808 | return d; never executed: return d; | 0 | ||||||||||||||||||
| 809 | - | |||||||||||||||||||
| 810 | if (int d = ga->stops.count() - gb->stops.count())
| 0 | ||||||||||||||||||
| 811 | return d; never executed: return d; | 0 | ||||||||||||||||||
| 812 | - | |||||||||||||||||||
| 813 | for (int i = 0; i < ga->stops.count(); ++i) {
| 0 | ||||||||||||||||||
| 814 | if (int d = ga->stops[i].first - gb->stops[i].first)
| 0 | ||||||||||||||||||
| 815 | return d; never executed: return d; | 0 | ||||||||||||||||||
| 816 | if (int d = ga->stops[i].second.rgba() - gb->stops[i].second.rgba())
| 0 | ||||||||||||||||||
| 817 | return d; never executed: return d; | 0 | ||||||||||||||||||
| 818 | } never executed: end of block | 0 | ||||||||||||||||||
| 819 | - | |||||||||||||||||||
| 820 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
| 821 | } | - | ||||||||||||||||||
| 822 | - | |||||||||||||||||||
| 823 | QSGMaterialType QQuickShapeRadialGradientShader::type; | - | ||||||||||||||||||
| 824 | - | |||||||||||||||||||
| 825 | QQuickShapeRadialGradientShader::QQuickShapeRadialGradientShader() | - | ||||||||||||||||||
| 826 | { | - | ||||||||||||||||||
| 827 | setShaderSourceFile(QOpenGLShader::Vertex, | - | ||||||||||||||||||
| 828 | QStringLiteral(":/qt-project.org/shapes/shaders/radialgradient.vert")); executed 4 times by 1 test: return qstring_literal_temp;Executed by:
| 4 | ||||||||||||||||||
| 829 | setShaderSourceFile(QOpenGLShader::Fragment, | - | ||||||||||||||||||
| 830 | QStringLiteral(":/qt-project.org/shapes/shaders/radialgradient.frag")); executed 4 times by 1 test: return qstring_literal_temp;Executed by:
| 4 | ||||||||||||||||||
| 831 | } executed 4 times by 1 test: end of blockExecuted by:
| 4 | ||||||||||||||||||
| 832 | - | |||||||||||||||||||
| 833 | void QQuickShapeRadialGradientShader::initialize() | - | ||||||||||||||||||
| 834 | { | - | ||||||||||||||||||
| 835 | QOpenGLShaderProgram *prog = program(); | - | ||||||||||||||||||
| 836 | m_opacityLoc = prog->uniformLocation("opacity"); | - | ||||||||||||||||||
| 837 | m_matrixLoc = prog->uniformLocation("matrix"); | - | ||||||||||||||||||
| 838 | m_translationPointLoc = prog->uniformLocation("translationPoint"); | - | ||||||||||||||||||
| 839 | m_focalToCenterLoc = prog->uniformLocation("focalToCenter"); | - | ||||||||||||||||||
| 840 | m_centerRadiusLoc = prog->uniformLocation("centerRadius"); | - | ||||||||||||||||||
| 841 | m_focalRadiusLoc = prog->uniformLocation("focalRadius"); | - | ||||||||||||||||||
| 842 | } executed 4 times by 1 test: end of blockExecuted by:
| 4 | ||||||||||||||||||
| 843 | - | |||||||||||||||||||
| 844 | void QQuickShapeRadialGradientShader::updateState(const RenderState &state, QSGMaterial *mat, QSGMaterial *) | - | ||||||||||||||||||
| 845 | { | - | ||||||||||||||||||
| 846 | QQuickShapeRadialGradientMaterial *m = static_cast<QQuickShapeRadialGradientMaterial *>(mat); | - | ||||||||||||||||||
| 847 | - | |||||||||||||||||||
| 848 | if (state.isOpacityDirty())
| 0-4 | ||||||||||||||||||
| 849 | program()->setUniformValue(m_opacityLoc, state.opacity()); executed 4 times by 1 test: program()->setUniformValue(m_opacityLoc, state.opacity());Executed by:
| 4 | ||||||||||||||||||
| 850 | - | |||||||||||||||||||
| 851 | if (state.isMatrixDirty())
| 0-4 | ||||||||||||||||||
| 852 | program()->setUniformValue(m_matrixLoc, state.combinedMatrix()); executed 4 times by 1 test: program()->setUniformValue(m_matrixLoc, state.combinedMatrix());Executed by:
| 4 | ||||||||||||||||||
| 853 | - | |||||||||||||||||||
| 854 | QQuickShapeGenericStrokeFillNode *node = m->node(); | - | ||||||||||||||||||
| 855 | - | |||||||||||||||||||
| 856 | const QPointF centerPoint = node->m_fillGradient.a; | - | ||||||||||||||||||
| 857 | const QPointF focalPoint = node->m_fillGradient.b; | - | ||||||||||||||||||
| 858 | const QPointF focalToCenter = centerPoint - focalPoint; | - | ||||||||||||||||||
| 859 | const GLfloat centerRadius = node->m_fillGradient.v0; | - | ||||||||||||||||||
| 860 | const GLfloat focalRadius = node->m_fillGradient.v1; | - | ||||||||||||||||||
| 861 | - | |||||||||||||||||||
| 862 | program()->setUniformValue(m_translationPointLoc, focalPoint); | - | ||||||||||||||||||
| 863 | program()->setUniformValue(m_centerRadiusLoc, centerRadius); | - | ||||||||||||||||||
| 864 | program()->setUniformValue(m_focalRadiusLoc, focalRadius); | - | ||||||||||||||||||
| 865 | program()->setUniformValue(m_focalToCenterLoc, focalToCenter); | - | ||||||||||||||||||
| 866 | - | |||||||||||||||||||
| 867 | const QQuickShapeGradientCache::Key cacheKey(node->m_fillGradient.stops, node->m_fillGradient.spread); | - | ||||||||||||||||||
| 868 | QSGTexture *tx = QQuickShapeGradientCache::currentCache()->get(cacheKey); | - | ||||||||||||||||||
| 869 | tx->bind(); | - | ||||||||||||||||||
| 870 | } executed 4 times by 1 test: end of blockExecuted by:
| 4 | ||||||||||||||||||
| 871 | - | |||||||||||||||||||
| 872 | char const *const *QQuickShapeRadialGradientShader::attributeNames() const | - | ||||||||||||||||||
| 873 | { | - | ||||||||||||||||||
| 874 | static const char *const attr[] = { "vertexCoord", "vertexColor", nullptr }; | - | ||||||||||||||||||
| 875 | return attr; executed 16 times by 1 test: return attr;Executed by:
| 16 | ||||||||||||||||||
| 876 | } | - | ||||||||||||||||||
| 877 | - | |||||||||||||||||||
| 878 | int QQuickShapeRadialGradientMaterial::compare(const QSGMaterial *other) const | - | ||||||||||||||||||
| 879 | { | - | ||||||||||||||||||
| 880 | Q_ASSERT(other && type() == other->type()); | - | ||||||||||||||||||
| 881 | const QQuickShapeRadialGradientMaterial *m = static_cast<const QQuickShapeRadialGradientMaterial *>(other); | - | ||||||||||||||||||
| 882 | - | |||||||||||||||||||
| 883 | QQuickShapeGenericStrokeFillNode *a = node(); | - | ||||||||||||||||||
| 884 | QQuickShapeGenericStrokeFillNode *b = m->node(); | - | ||||||||||||||||||
| 885 | Q_ASSERT(a && b); | - | ||||||||||||||||||
| 886 | if (a == b)
| 0 | ||||||||||||||||||
| 887 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
| 888 | - | |||||||||||||||||||
| 889 | const QQuickAbstractPathRenderer::GradientDesc *ga = &a->m_fillGradient; | - | ||||||||||||||||||
| 890 | const QQuickAbstractPathRenderer::GradientDesc *gb = &b->m_fillGradient; | - | ||||||||||||||||||
| 891 | - | |||||||||||||||||||
| 892 | if (int d = ga->spread - gb->spread)
| 0 | ||||||||||||||||||
| 893 | return d; never executed: return d; | 0 | ||||||||||||||||||
| 894 | - | |||||||||||||||||||
| 895 | if (int d = ga->a.x() - gb->a.x())
| 0 | ||||||||||||||||||
| 896 | return d; never executed: return d; | 0 | ||||||||||||||||||
| 897 | if (int d = ga->a.y() - gb->a.y())
| 0 | ||||||||||||||||||
| 898 | return d; never executed: return d; | 0 | ||||||||||||||||||
| 899 | if (int d = ga->b.x() - gb->b.x())
| 0 | ||||||||||||||||||
| 900 | return d; never executed: return d; | 0 | ||||||||||||||||||
| 901 | if (int d = ga->b.y() - gb->b.y())
| 0 | ||||||||||||||||||
| 902 | return d; never executed: return d; | 0 | ||||||||||||||||||
| 903 | - | |||||||||||||||||||
| 904 | if (int d = ga->v0 - gb->v0)
| 0 | ||||||||||||||||||
| 905 | return d; never executed: return d; | 0 | ||||||||||||||||||
| 906 | if (int d = ga->v1 - gb->v1)
| 0 | ||||||||||||||||||
| 907 | return d; never executed: return d; | 0 | ||||||||||||||||||
| 908 | - | |||||||||||||||||||
| 909 | if (int d = ga->stops.count() - gb->stops.count())
| 0 | ||||||||||||||||||
| 910 | return d; never executed: return d; | 0 | ||||||||||||||||||
| 911 | - | |||||||||||||||||||
| 912 | for (int i = 0; i < ga->stops.count(); ++i) {
| 0 | ||||||||||||||||||
| 913 | if (int d = ga->stops[i].first - gb->stops[i].first)
| 0 | ||||||||||||||||||
| 914 | return d; never executed: return d; | 0 | ||||||||||||||||||
| 915 | if (int d = ga->stops[i].second.rgba() - gb->stops[i].second.rgba())
| 0 | ||||||||||||||||||
| 916 | return d; never executed: return d; | 0 | ||||||||||||||||||
| 917 | } never executed: end of block | 0 | ||||||||||||||||||
| 918 | - | |||||||||||||||||||
| 919 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
| 920 | } | - | ||||||||||||||||||
| 921 | - | |||||||||||||||||||
| 922 | QSGMaterialType QQuickShapeConicalGradientShader::type; | - | ||||||||||||||||||
| 923 | - | |||||||||||||||||||
| 924 | QQuickShapeConicalGradientShader::QQuickShapeConicalGradientShader() | - | ||||||||||||||||||
| 925 | { | - | ||||||||||||||||||
| 926 | setShaderSourceFile(QOpenGLShader::Vertex, | - | ||||||||||||||||||
| 927 | QStringLiteral(":/qt-project.org/shapes/shaders/conicalgradient.vert")); executed 3 times by 1 test: return qstring_literal_temp;Executed by:
| 3 | ||||||||||||||||||
| 928 | setShaderSourceFile(QOpenGLShader::Fragment, | - | ||||||||||||||||||
| 929 | QStringLiteral(":/qt-project.org/shapes/shaders/conicalgradient.frag")); executed 3 times by 1 test: return qstring_literal_temp;Executed by:
| 3 | ||||||||||||||||||
| 930 | } executed 3 times by 1 test: end of blockExecuted by:
| 3 | ||||||||||||||||||
| 931 | - | |||||||||||||||||||
| 932 | void QQuickShapeConicalGradientShader::initialize() | - | ||||||||||||||||||
| 933 | { | - | ||||||||||||||||||
| 934 | QOpenGLShaderProgram *prog = program(); | - | ||||||||||||||||||
| 935 | m_opacityLoc = prog->uniformLocation("opacity"); | - | ||||||||||||||||||
| 936 | m_matrixLoc = prog->uniformLocation("matrix"); | - | ||||||||||||||||||
| 937 | m_angleLoc = prog->uniformLocation("angle"); | - | ||||||||||||||||||
| 938 | m_translationPointLoc = prog->uniformLocation("translationPoint"); | - | ||||||||||||||||||
| 939 | } executed 3 times by 1 test: end of blockExecuted by:
| 3 | ||||||||||||||||||
| 940 | - | |||||||||||||||||||
| 941 | void QQuickShapeConicalGradientShader::updateState(const RenderState &state, QSGMaterial *mat, QSGMaterial *) | - | ||||||||||||||||||
| 942 | { | - | ||||||||||||||||||
| 943 | QQuickShapeConicalGradientMaterial *m = static_cast<QQuickShapeConicalGradientMaterial *>(mat); | - | ||||||||||||||||||
| 944 | - | |||||||||||||||||||
| 945 | if (state.isOpacityDirty())
| 0-3 | ||||||||||||||||||
| 946 | program()->setUniformValue(m_opacityLoc, state.opacity()); executed 3 times by 1 test: program()->setUniformValue(m_opacityLoc, state.opacity());Executed by:
| 3 | ||||||||||||||||||
| 947 | - | |||||||||||||||||||
| 948 | if (state.isMatrixDirty())
| 0-3 | ||||||||||||||||||
| 949 | program()->setUniformValue(m_matrixLoc, state.combinedMatrix()); executed 3 times by 1 test: program()->setUniformValue(m_matrixLoc, state.combinedMatrix());Executed by:
| 3 | ||||||||||||||||||
| 950 | - | |||||||||||||||||||
| 951 | QQuickShapeGenericStrokeFillNode *node = m->node(); | - | ||||||||||||||||||
| 952 | - | |||||||||||||||||||
| 953 | const QPointF centerPoint = node->m_fillGradient.a; | - | ||||||||||||||||||
| 954 | const GLfloat angle = -qDegreesToRadians(node->m_fillGradient.v0); | - | ||||||||||||||||||
| 955 | - | |||||||||||||||||||
| 956 | program()->setUniformValue(m_angleLoc, angle); | - | ||||||||||||||||||
| 957 | program()->setUniformValue(m_translationPointLoc, centerPoint); | - | ||||||||||||||||||
| 958 | - | |||||||||||||||||||
| 959 | const QQuickShapeGradientCache::Key cacheKey(node->m_fillGradient.stops, QQuickShapeGradient::RepeatSpread); | - | ||||||||||||||||||
| 960 | QSGTexture *tx = QQuickShapeGradientCache::currentCache()->get(cacheKey); | - | ||||||||||||||||||
| 961 | tx->bind(); | - | ||||||||||||||||||
| 962 | } executed 3 times by 1 test: end of blockExecuted by:
| 3 | ||||||||||||||||||
| 963 | - | |||||||||||||||||||
| 964 | char const *const *QQuickShapeConicalGradientShader::attributeNames() const | - | ||||||||||||||||||
| 965 | { | - | ||||||||||||||||||
| 966 | static const char *const attr[] = { "vertexCoord", "vertexColor", nullptr }; | - | ||||||||||||||||||
| 967 | return attr; executed 12 times by 1 test: return attr;Executed by:
| 12 | ||||||||||||||||||
| 968 | } | - | ||||||||||||||||||
| 969 | - | |||||||||||||||||||
| 970 | int QQuickShapeConicalGradientMaterial::compare(const QSGMaterial *other) const | - | ||||||||||||||||||
| 971 | { | - | ||||||||||||||||||
| 972 | Q_ASSERT(other && type() == other->type()); | - | ||||||||||||||||||
| 973 | const QQuickShapeConicalGradientMaterial *m = static_cast<const QQuickShapeConicalGradientMaterial *>(other); | - | ||||||||||||||||||
| 974 | - | |||||||||||||||||||
| 975 | QQuickShapeGenericStrokeFillNode *a = node(); | - | ||||||||||||||||||
| 976 | QQuickShapeGenericStrokeFillNode *b = m->node(); | - | ||||||||||||||||||
| 977 | Q_ASSERT(a && b); | - | ||||||||||||||||||
| 978 | if (a == b)
| 0 | ||||||||||||||||||
| 979 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
| 980 | - | |||||||||||||||||||
| 981 | const QQuickAbstractPathRenderer::GradientDesc *ga = &a->m_fillGradient; | - | ||||||||||||||||||
| 982 | const QQuickAbstractPathRenderer::GradientDesc *gb = &b->m_fillGradient; | - | ||||||||||||||||||
| 983 | - | |||||||||||||||||||
| 984 | if (int d = ga->a.x() - gb->a.x())
| 0 | ||||||||||||||||||
| 985 | return d; never executed: return d; | 0 | ||||||||||||||||||
| 986 | if (int d = ga->a.y() - gb->a.y())
| 0 | ||||||||||||||||||
| 987 | return d; never executed: return d; | 0 | ||||||||||||||||||
| 988 | - | |||||||||||||||||||
| 989 | if (int d = ga->v0 - gb->v0)
| 0 | ||||||||||||||||||
| 990 | return d; never executed: return d; | 0 | ||||||||||||||||||
| 991 | - | |||||||||||||||||||
| 992 | if (int d = ga->stops.count() - gb->stops.count())
| 0 | ||||||||||||||||||
| 993 | return d; never executed: return d; | 0 | ||||||||||||||||||
| 994 | - | |||||||||||||||||||
| 995 | for (int i = 0; i < ga->stops.count(); ++i) {
| 0 | ||||||||||||||||||
| 996 | if (int d = ga->stops[i].first - gb->stops[i].first)
| 0 | ||||||||||||||||||
| 997 | return d; never executed: return d; | 0 | ||||||||||||||||||
| 998 | if (int d = ga->stops[i].second.rgba() - gb->stops[i].second.rgba())
| 0 | ||||||||||||||||||
| 999 | return d; never executed: return d; | 0 | ||||||||||||||||||
| 1000 | } never executed: end of block | 0 | ||||||||||||||||||
| 1001 | - | |||||||||||||||||||
| 1002 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
| 1003 | } | - | ||||||||||||||||||
| 1004 | - | |||||||||||||||||||
| 1005 | #endif // QT_CONFIG(opengl) | - | ||||||||||||||||||
| 1006 | - | |||||||||||||||||||
| 1007 | QT_END_NAMESPACE | - | ||||||||||||||||||
| Source code | Switch to Preprocessed file |