aboutsummaryrefslogtreecommitdiffstats
path: root/src/quickshapes/qquickshapegenericrenderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quickshapes/qquickshapegenericrenderer.cpp')
-rw-r--r--src/quickshapes/qquickshapegenericrenderer.cpp252
1 files changed, 124 insertions, 128 deletions
diff --git a/src/quickshapes/qquickshapegenericrenderer.cpp b/src/quickshapes/qquickshapegenericrenderer.cpp
index f5fcd72152..a18479f776 100644
--- a/src/quickshapes/qquickshapegenericrenderer.cpp
+++ b/src/quickshapes/qquickshapegenericrenderer.cpp
@@ -1,56 +1,20 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qquickshapegenericrenderer_p.h"
#include <QtGui/private/qtriangulator_p.h>
#include <QtGui/private/qtriangulatingstroker_p.h>
-#include <QtGui/private/qrhi_p.h>
+#include <rhi/qrhi.h>
#include <QSGVertexColorMaterial>
+#include <QtQuick/private/qsggradientcache_p.h>
+
#if QT_CONFIG(thread)
#include <QThreadPool>
#endif
QT_BEGIN_NAMESPACE
-static const qreal TRI_SCALE = 1;
-
struct ColoredVertex // must match QSGGeometry::ColoredPoint2D
{
float x, y;
@@ -63,11 +27,13 @@ struct ColoredVertex // must match QSGGeometry::ColoredPoint2D
static inline QQuickShapeGenericRenderer::Color4ub colorToColor4ub(const QColor &c)
{
+ float r, g, b, a;
+ c.getRgbF(&r, &g, &b, &a);
QQuickShapeGenericRenderer::Color4ub color = {
- uchar(qRound(c.redF() * c.alphaF() * 255)),
- uchar(qRound(c.greenF() * c.alphaF() * 255)),
- uchar(qRound(c.blueF() * c.alphaF() * 255)),
- uchar(qRound(c.alphaF() * 255))
+ uchar(qRound(r * a * 255)),
+ uchar(qRound(g * a * 255)),
+ uchar(qRound(b * a * 255)),
+ uchar(qRound(a * 255))
};
return color;
}
@@ -124,7 +90,7 @@ QQuickShapeGenericRenderer::~QQuickShapeGenericRenderer()
void QQuickShapeGenericRenderer::beginSync(int totalCount, bool *countChanged)
{
- if (m_sp.count() != totalCount) {
+ if (m_sp.size() != totalCount) {
m_sp.resize(totalCount);
m_accDirty |= DirtyList;
*countChanged = true;
@@ -145,8 +111,12 @@ void QQuickShapeGenericRenderer::setPath(int index, const QQuickPath *path)
void QQuickShapeGenericRenderer::setStrokeColor(int index, const QColor &color)
{
ShapePathData &d(m_sp[index]);
+ const bool wasTransparent = d.strokeColor.a == 0;
d.strokeColor = colorToColor4ub(color);
+ const bool isTransparent = d.strokeColor.a == 0;
d.syncDirty |= DirtyColor;
+ if (wasTransparent && !isTransparent)
+ d.syncDirty |= DirtyStrokeGeom;
}
void QQuickShapeGenericRenderer::setStrokeWidth(int index, qreal w)
@@ -208,7 +178,7 @@ void QQuickShapeGenericRenderer::setFillGradient(int index, QQuickShapeGradient
ShapePathData &d(m_sp[index]);
if (gradient) {
d.fillGradient.stops = gradient->gradientStops(); // sorted
- d.fillGradient.spread = gradient->spread();
+ d.fillGradient.spread = QGradient::Spread(gradient->spread());
if (QQuickShapeLinearGradient *g = qobject_cast<QQuickShapeLinearGradient *>(gradient)) {
d.fillGradientActive = LinearGradient;
d.fillGradient.a = QPointF(g->x1(), g->y1());
@@ -232,15 +202,22 @@ void QQuickShapeGenericRenderer::setFillGradient(int index, QQuickShapeGradient
d.syncDirty |= DirtyFillGradient;
}
+void QQuickShapeGenericRenderer::setTriangulationScale(qreal scale)
+{
+ // No dirty, this is called at the start of every sync. Just store the value.
+ m_triangulationScale = scale;
+}
+
void QQuickShapeFillRunnable::run()
{
- QQuickShapeGenericRenderer::triangulateFill(path, fillColor, &fillVertices, &fillIndices, &indexType, supportsElementIndexUint);
+ QQuickShapeGenericRenderer::triangulateFill(path, fillColor, &fillVertices, &fillIndices, &indexType,
+ supportsElementIndexUint, triangulationScale);
emit done(this);
}
void QQuickShapeStrokeRunnable::run()
{
- QQuickShapeGenericRenderer::triangulateStroke(path, pen, strokeColor, &strokeVertices, clipSize);
+ QQuickShapeGenericRenderer::triangulateStroke(path, pen, strokeColor, &strokeVertices, clipSize, triangulationScale);
emit done(this);
}
@@ -270,7 +247,7 @@ void QQuickShapeGenericRenderer::endSync(bool async)
bool didKickOffAsync = false;
- for (int i = 0; i < m_sp.count(); ++i) {
+ for (int i = 0; i < m_sp.size(); ++i) {
ShapePathData &d(m_sp[i]);
if (!d.syncDirty)
continue;
@@ -320,12 +297,13 @@ void QQuickShapeGenericRenderer::endSync(bool async)
r->path = d.path;
r->fillColor = d.fillColor;
r->supportsElementIndexUint = supportsElementIndexUint;
+ r->triangulationScale = m_triangulationScale;
// Unlikely in practice but in theory m_sp could be
// resized. Therefore, capture 'i' instead of 'd'.
QObject::connect(r, &QQuickShapeFillRunnable::done, qApp, [this, i](QQuickShapeFillRunnable *r) {
// Bail out when orphaned (meaning either another run was
// started after this one, or the renderer got destroyed).
- if (!r->orphaned && i < m_sp.count()) {
+ if (!r->orphaned && i < m_sp.size()) {
ShapePathData &d(m_sp[i]);
d.fillVertices = r->fillVertices;
d.fillIndices = r->fillIndices;
@@ -344,7 +322,9 @@ void QQuickShapeGenericRenderer::endSync(bool async)
pathWorkThreadPool->start(r);
#endif
} else {
- triangulateFill(d.path, d.fillColor, &d.fillVertices, &d.fillIndices, &d.indexType, supportsElementIndexUint);
+ triangulateFill(d.path, d.fillColor, &d.fillVertices, &d.fillIndices, &d.indexType,
+ supportsElementIndexUint,
+ m_triangulationScale);
}
}
@@ -359,8 +339,9 @@ void QQuickShapeGenericRenderer::endSync(bool async)
r->pen = d.pen;
r->strokeColor = d.strokeColor;
r->clipSize = QSize(m_item->width(), m_item->height());
+ r->triangulationScale = m_triangulationScale;
QObject::connect(r, &QQuickShapeStrokeRunnable::done, qApp, [this, i](QQuickShapeStrokeRunnable *r) {
- if (!r->orphaned && i < m_sp.count()) {
+ if (!r->orphaned && i < m_sp.size()) {
ShapePathData &d(m_sp[i]);
d.strokeVertices = r->strokeVertices;
d.pendingStroke = nullptr;
@@ -378,7 +359,7 @@ void QQuickShapeGenericRenderer::endSync(bool async)
#endif
} else {
triangulateStroke(d.path, d.pen, d.strokeColor, &d.strokeVertices,
- QSize(m_item->width(), m_item->height()));
+ QSize(m_item->width(), m_item->height()), m_triangulationScale);
}
}
}
@@ -389,7 +370,7 @@ void QQuickShapeGenericRenderer::endSync(bool async)
void QQuickShapeGenericRenderer::maybeUpdateAsyncItem()
{
- for (const ShapePathData &d : qAsConst(m_sp)) {
+ for (const ShapePathData &d : std::as_const(m_sp)) {
if (d.pendingFill || d.pendingStroke)
return;
}
@@ -402,21 +383,22 @@ void QQuickShapeGenericRenderer::maybeUpdateAsyncItem()
// the stroke/fill triangulation functions may be invoked either on the gui
// thread or some worker thread and must thus be self-contained.
void QQuickShapeGenericRenderer::triangulateFill(const QPainterPath &path,
- const Color4ub &fillColor,
- VertexContainerType *fillVertices,
- IndexContainerType *fillIndices,
- QSGGeometry::Type *indexType,
- bool supportsElementIndexUint)
+ const Color4ub &fillColor,
+ VertexContainerType *fillVertices,
+ IndexContainerType *fillIndices,
+ QSGGeometry::Type *indexType,
+ bool supportsElementIndexUint,
+ qreal triangulationScale)
{
const QVectorPath &vp = qtVectorPathForPath(path);
- QTriangleSet ts = qTriangulate(vp, QTransform::fromScale(TRI_SCALE, TRI_SCALE), 1, supportsElementIndexUint);
- const int vertexCount = ts.vertices.count() / 2; // just a qreal vector with x,y hence the / 2
+ QTriangleSet ts = qTriangulate(vp, QTransform::fromScale(triangulationScale, triangulationScale), 1, supportsElementIndexUint);
+ const int vertexCount = ts.vertices.size() / 2; // just a qreal vector with x,y hence the / 2
fillVertices->resize(vertexCount);
ColoredVertex *vdst = reinterpret_cast<ColoredVertex *>(fillVertices->data());
const qreal *vsrc = ts.vertices.constData();
for (int i = 0; i < vertexCount; ++i)
- vdst[i].set(vsrc[i * 2] / TRI_SCALE, vsrc[i * 2 + 1] / TRI_SCALE, fillColor);
+ vdst[i].set(vsrc[i * 2] / triangulationScale, vsrc[i * 2 + 1] / triangulationScale, fillColor);
size_t indexByteSize;
if (ts.indices.type() == QVertexIndexVector::UnsignedShort) {
@@ -434,14 +416,15 @@ void QQuickShapeGenericRenderer::triangulateFill(const QPainterPath &path,
}
void QQuickShapeGenericRenderer::triangulateStroke(const QPainterPath &path,
- const QPen &pen,
- const Color4ub &strokeColor,
- VertexContainerType *strokeVertices,
- const QSize &clipSize)
+ const QPen &pen,
+ const Color4ub &strokeColor,
+ VertexContainerType *strokeVertices,
+ const QSize &clipSize,
+ qreal triangulationScale)
{
const QVectorPath &vp = qtVectorPathForPath(path);
const QRectF clip(QPointF(0, 0), clipSize);
- const qreal inverseScale = 1.0 / TRI_SCALE;
+ const qreal inverseScale = 1.0 / triangulationScale;
QTriangulatingStroker stroker;
stroker.setInvScale(inverseScale);
@@ -598,8 +581,7 @@ void QQuickShapeGenericRenderer::updateFillNode(ShapePathData *d, QQuickShapeGen
gradMat = QQuickShapeGenericStrokeFillNode::MatConicalGradient;
break;
default:
- Q_UNREACHABLE();
- return;
+ Q_UNREACHABLE_RETURN();
}
n->activateMaterial(m_item->window(), gradMat);
if (d->effectiveDirty & DirtyFillGradient) {
@@ -622,13 +604,13 @@ void QQuickShapeGenericRenderer::updateFillNode(ShapePathData *d, QQuickShapeGen
}
const int indexCount = d->indexType == QSGGeometry::UnsignedShortType
- ? d->fillIndices.count() * 2 : d->fillIndices.count();
+ ? d->fillIndices.size() * 2 : d->fillIndices.size();
if (g->indexType() != d->indexType) {
g = new QSGGeometry(QSGGeometry::defaultAttributes_ColoredPoint2D(),
- d->fillVertices.count(), indexCount, d->indexType);
+ d->fillVertices.size(), indexCount, d->indexType);
n->setGeometry(g);
} else {
- g->allocate(d->fillVertices.count(), indexCount);
+ g->allocate(d->fillVertices.size(), indexCount);
}
g->setDrawingMode(QSGGeometry::DrawTriangles);
memcpy(g->vertexData(), d->fillVertices.constData(), g->vertexCount() * g->sizeOfVertex());
@@ -669,7 +651,7 @@ void QQuickShapeGenericRenderer::updateStrokeNode(ShapePathData *d, QQuickShapeG
return;
}
- g->allocate(d->strokeVertices.count(), 0);
+ g->allocate(d->strokeVertices.size(), 0);
g->setDrawingMode(QSGGeometry::DrawTriangleStrip);
memcpy(g->vertexData(), d->strokeVertices.constData(), g->vertexCount() * g->sizeOfVertex());
}
@@ -721,10 +703,10 @@ QSGMaterial *QQuickShapeGenericMaterialFactory::createConicalGradient(QQuickWind
return nullptr;
}
-QQuickShapeLinearGradientRhiShader::QQuickShapeLinearGradientRhiShader()
+QQuickShapeLinearGradientRhiShader::QQuickShapeLinearGradientRhiShader(int viewCount)
{
- setShaderFileName(VertexStage, QStringLiteral(":/qt-project.org/shapes/shaders_ng/lineargradient.vert.qsb"));
- setShaderFileName(FragmentStage, QStringLiteral(":/qt-project.org/shapes/shaders_ng/lineargradient.frag.qsb"));
+ setShaderFileName(VertexStage, QStringLiteral(":/qt-project.org/shapes/shaders_ng/lineargradient.vert.qsb"), viewCount);
+ setShaderFileName(FragmentStage, QStringLiteral(":/qt-project.org/shapes/shaders_ng/lineargradient.frag.qsb"), viewCount);
}
bool QQuickShapeLinearGradientRhiShader::updateUniformData(RenderState &state,
@@ -735,11 +717,15 @@ bool QQuickShapeLinearGradientRhiShader::updateUniformData(RenderState &state,
bool changed = false;
QByteArray *buf = state.uniformData();
Q_ASSERT(buf->size() >= 84);
+ const int shaderMatrixCount = newMaterial->viewCount();
+ const int matrixCount = qMin(state.projectionMatrixCount(), shaderMatrixCount);
if (state.isMatrixDirty()) {
- const QMatrix4x4 m = state.combinedMatrix();
- memcpy(buf->data(), m.constData(), 64);
- changed = true;
+ for (int viewIndex = 0; viewIndex < matrixCount; ++viewIndex) {
+ const QMatrix4x4 m = state.combinedMatrix();
+ memcpy(buf->data() + 64 * viewIndex, m.constData(), 64);
+ changed = true;
+ }
}
QQuickShapeGenericStrokeFillNode *node = m->node();
@@ -747,19 +733,19 @@ bool QQuickShapeLinearGradientRhiShader::updateUniformData(RenderState &state,
if (!oldMaterial || m_gradA.x() != node->m_fillGradient.a.x() || m_gradA.y() != node->m_fillGradient.a.y()) {
m_gradA = QVector2D(node->m_fillGradient.a.x(), node->m_fillGradient.a.y());
Q_ASSERT(sizeof(m_gradA) == 8);
- memcpy(buf->data() + 64, &m_gradA, 8);
+ memcpy(buf->data() + 64 * shaderMatrixCount, &m_gradA, 8);
changed = true;
}
if (!oldMaterial || m_gradB.x() != node->m_fillGradient.b.x() || m_gradB.y() != node->m_fillGradient.b.y()) {
m_gradB = QVector2D(node->m_fillGradient.b.x(), node->m_fillGradient.b.y());
- memcpy(buf->data() + 72, &m_gradB, 8);
+ memcpy(buf->data() + 64 * shaderMatrixCount + 8, &m_gradB, 8);
changed = true;
}
if (state.isOpacityDirty()) {
const float opacity = state.opacity();
- memcpy(buf->data() + 80, &opacity, 4);
+ memcpy(buf->data() + 64 * shaderMatrixCount + 8 + 8, &opacity, 4);
changed = true;
}
@@ -774,8 +760,8 @@ void QQuickShapeLinearGradientRhiShader::updateSampledImage(RenderState &state,
QQuickShapeLinearGradientMaterial *m = static_cast<QQuickShapeLinearGradientMaterial *>(newMaterial);
QQuickShapeGenericStrokeFillNode *node = m->node();
- const QQuickShapeGradientCacheKey cacheKey(node->m_fillGradient.stops, node->m_fillGradient.spread);
- QSGTexture *t = QQuickShapeGradientCache::cacheForRhi(state.rhi())->get(cacheKey);
+ const QSGGradientCacheKey cacheKey(node->m_fillGradient.stops, QGradient::Spread(node->m_fillGradient.spread));
+ QSGTexture *t = QSGGradientCache::cacheForRhi(state.rhi())->get(cacheKey);
t->commitTextureOperations(state.rhi(), state.resourceUpdateBatch());
*texture = t;
}
@@ -797,8 +783,8 @@ int QQuickShapeLinearGradientMaterial::compare(const QSGMaterial *other) const
if (a == b)
return 0;
- const QQuickAbstractPathRenderer::GradientDesc *ga = &a->m_fillGradient;
- const QQuickAbstractPathRenderer::GradientDesc *gb = &b->m_fillGradient;
+ const QSGGradientCache::GradientDesc *ga = &a->m_fillGradient;
+ const QSGGradientCache::GradientDesc *gb = &b->m_fillGradient;
if (int d = ga->spread - gb->spread)
return d;
@@ -812,10 +798,10 @@ int QQuickShapeLinearGradientMaterial::compare(const QSGMaterial *other) const
if (int d = ga->b.y() - gb->b.y())
return d;
- if (int d = ga->stops.count() - gb->stops.count())
+ if (int d = ga->stops.size() - gb->stops.size())
return d;
- for (int i = 0; i < ga->stops.count(); ++i) {
+ for (int i = 0; i < ga->stops.size(); ++i) {
if (int d = ga->stops[i].first - gb->stops[i].first)
return d;
if (int d = ga->stops[i].second.rgba() - gb->stops[i].second.rgba())
@@ -828,28 +814,32 @@ int QQuickShapeLinearGradientMaterial::compare(const QSGMaterial *other) const
QSGMaterialShader *QQuickShapeLinearGradientMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
{
Q_UNUSED(renderMode);
- return new QQuickShapeLinearGradientRhiShader;
+ return new QQuickShapeLinearGradientRhiShader(viewCount());
}
-QQuickShapeRadialGradientRhiShader::QQuickShapeRadialGradientRhiShader()
+QQuickShapeRadialGradientRhiShader::QQuickShapeRadialGradientRhiShader(int viewCount)
{
- setShaderFileName(VertexStage, QStringLiteral(":/qt-project.org/shapes/shaders_ng/radialgradient.vert.qsb"));
- setShaderFileName(FragmentStage, QStringLiteral(":/qt-project.org/shapes/shaders_ng/radialgradient.frag.qsb"));
+ setShaderFileName(VertexStage, QStringLiteral(":/qt-project.org/shapes/shaders_ng/radialgradient.vert.qsb"), viewCount);
+ setShaderFileName(FragmentStage, QStringLiteral(":/qt-project.org/shapes/shaders_ng/radialgradient.frag.qsb"), viewCount);
}
bool QQuickShapeRadialGradientRhiShader::updateUniformData(RenderState &state,
QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
{
Q_ASSERT(oldMaterial == nullptr || newMaterial->type() == oldMaterial->type());
- QQuickShapeLinearGradientMaterial *m = static_cast<QQuickShapeLinearGradientMaterial *>(newMaterial);
+ QQuickShapeRadialGradientMaterial *m = static_cast<QQuickShapeRadialGradientMaterial *>(newMaterial);
bool changed = false;
QByteArray *buf = state.uniformData();
Q_ASSERT(buf->size() >= 92);
+ const int shaderMatrixCount = newMaterial->viewCount();
+ const int matrixCount = qMin(state.projectionMatrixCount(), shaderMatrixCount);
if (state.isMatrixDirty()) {
- const QMatrix4x4 m = state.combinedMatrix();
- memcpy(buf->data(), m.constData(), 64);
- changed = true;
+ for (int viewIndex = 0; viewIndex < matrixCount; ++viewIndex) {
+ const QMatrix4x4 m = state.combinedMatrix();
+ memcpy(buf->data() + 64 * viewIndex, m.constData(), 64);
+ changed = true;
+ }
}
QQuickShapeGenericStrokeFillNode *node = m->node();
@@ -863,32 +853,32 @@ bool QQuickShapeRadialGradientRhiShader::updateUniformData(RenderState &state,
if (!oldMaterial || m_focalPoint.x() != focalPoint.x() || m_focalPoint.y() != focalPoint.y()) {
m_focalPoint = QVector2D(focalPoint.x(), focalPoint.y());
Q_ASSERT(sizeof(m_focalPoint) == 8);
- memcpy(buf->data() + 64, &m_focalPoint, 8);
+ memcpy(buf->data() + 64 * shaderMatrixCount, &m_focalPoint, 8);
changed = true;
}
if (!oldMaterial || m_focalToCenter.x() != focalToCenter.x() || m_focalToCenter.y() != focalToCenter.y()) {
m_focalToCenter = QVector2D(focalToCenter.x(), focalToCenter.y());
Q_ASSERT(sizeof(m_focalToCenter) == 8);
- memcpy(buf->data() + 72, &m_focalToCenter, 8);
+ memcpy(buf->data() + 64 * shaderMatrixCount + 8, &m_focalToCenter, 8);
changed = true;
}
if (!oldMaterial || m_centerRadius != centerRadius) {
m_centerRadius = centerRadius;
- memcpy(buf->data() + 80, &m_centerRadius, 4);
+ memcpy(buf->data() + 64 * shaderMatrixCount + 8 + 8, &m_centerRadius, 4);
changed = true;
}
if (!oldMaterial || m_focalRadius != focalRadius) {
m_focalRadius = focalRadius;
- memcpy(buf->data() + 84, &m_focalRadius, 4);
+ memcpy(buf->data() + 64 * shaderMatrixCount + 8 + 8 + 4, &m_focalRadius, 4);
changed = true;
}
if (state.isOpacityDirty()) {
const float opacity = state.opacity();
- memcpy(buf->data() + 88, &opacity, 4);
+ memcpy(buf->data() + 64 * shaderMatrixCount + 8 + 8 + 4 + 4, &opacity, 4);
changed = true;
}
@@ -901,10 +891,10 @@ void QQuickShapeRadialGradientRhiShader::updateSampledImage(RenderState &state,
if (binding != 1)
return;
- QQuickShapeLinearGradientMaterial *m = static_cast<QQuickShapeLinearGradientMaterial *>(newMaterial);
+ QQuickShapeRadialGradientMaterial *m = static_cast<QQuickShapeRadialGradientMaterial *>(newMaterial);
QQuickShapeGenericStrokeFillNode *node = m->node();
- const QQuickShapeGradientCacheKey cacheKey(node->m_fillGradient.stops, node->m_fillGradient.spread);
- QSGTexture *t = QQuickShapeGradientCache::cacheForRhi(state.rhi())->get(cacheKey);
+ const QSGGradientCacheKey cacheKey(node->m_fillGradient.stops, QGradient::Spread(node->m_fillGradient.spread));
+ QSGTexture *t = QSGGradientCache::cacheForRhi(state.rhi())->get(cacheKey);
t->commitTextureOperations(state.rhi(), state.resourceUpdateBatch());
*texture = t;
}
@@ -926,8 +916,8 @@ int QQuickShapeRadialGradientMaterial::compare(const QSGMaterial *other) const
if (a == b)
return 0;
- const QQuickAbstractPathRenderer::GradientDesc *ga = &a->m_fillGradient;
- const QQuickAbstractPathRenderer::GradientDesc *gb = &b->m_fillGradient;
+ const QSGGradientCache::GradientDesc *ga = &a->m_fillGradient;
+ const QSGGradientCache::GradientDesc *gb = &b->m_fillGradient;
if (int d = ga->spread - gb->spread)
return d;
@@ -946,10 +936,10 @@ int QQuickShapeRadialGradientMaterial::compare(const QSGMaterial *other) const
if (int d = ga->v1 - gb->v1)
return d;
- if (int d = ga->stops.count() - gb->stops.count())
+ if (int d = ga->stops.size() - gb->stops.size())
return d;
- for (int i = 0; i < ga->stops.count(); ++i) {
+ for (int i = 0; i < ga->stops.size(); ++i) {
if (int d = ga->stops[i].first - gb->stops[i].first)
return d;
if (int d = ga->stops[i].second.rgba() - gb->stops[i].second.rgba())
@@ -962,28 +952,32 @@ int QQuickShapeRadialGradientMaterial::compare(const QSGMaterial *other) const
QSGMaterialShader *QQuickShapeRadialGradientMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
{
Q_UNUSED(renderMode);
- return new QQuickShapeRadialGradientRhiShader;
+ return new QQuickShapeRadialGradientRhiShader(viewCount());
}
-QQuickShapeConicalGradientRhiShader::QQuickShapeConicalGradientRhiShader()
+QQuickShapeConicalGradientRhiShader::QQuickShapeConicalGradientRhiShader(int viewCount)
{
- setShaderFileName(VertexStage, QStringLiteral(":/qt-project.org/shapes/shaders_ng/conicalgradient.vert.qsb"));
- setShaderFileName(FragmentStage, QStringLiteral(":/qt-project.org/shapes/shaders_ng/conicalgradient.frag.qsb"));
+ setShaderFileName(VertexStage, QStringLiteral(":/qt-project.org/shapes/shaders_ng/conicalgradient.vert.qsb"), viewCount);
+ setShaderFileName(FragmentStage, QStringLiteral(":/qt-project.org/shapes/shaders_ng/conicalgradient.frag.qsb"), viewCount);
}
bool QQuickShapeConicalGradientRhiShader::updateUniformData(RenderState &state,
QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
{
Q_ASSERT(oldMaterial == nullptr || newMaterial->type() == oldMaterial->type());
- QQuickShapeLinearGradientMaterial *m = static_cast<QQuickShapeLinearGradientMaterial *>(newMaterial);
+ QQuickShapeConicalGradientMaterial *m = static_cast<QQuickShapeConicalGradientMaterial *>(newMaterial);
bool changed = false;
QByteArray *buf = state.uniformData();
Q_ASSERT(buf->size() >= 80);
+ const int shaderMatrixCount = newMaterial->viewCount();
+ const int matrixCount = qMin(state.projectionMatrixCount(), shaderMatrixCount);
if (state.isMatrixDirty()) {
- const QMatrix4x4 m = state.combinedMatrix();
- memcpy(buf->data(), m.constData(), 64);
- changed = true;
+ for (int viewIndex = 0; viewIndex < matrixCount; ++viewIndex) {
+ const QMatrix4x4 m = state.combinedMatrix();
+ memcpy(buf->data() + 64 * viewIndex, m.constData(), 64);
+ changed = true;
+ }
}
QQuickShapeGenericStrokeFillNode *node = m->node();
@@ -994,19 +988,19 @@ bool QQuickShapeConicalGradientRhiShader::updateUniformData(RenderState &state,
if (!oldMaterial || m_centerPoint.x() != centerPoint.x() || m_centerPoint.y() != centerPoint.y()) {
m_centerPoint = QVector2D(centerPoint.x(), centerPoint.y());
Q_ASSERT(sizeof(m_centerPoint) == 8);
- memcpy(buf->data() + 64, &m_centerPoint, 8);
+ memcpy(buf->data() + 64 * shaderMatrixCount, &m_centerPoint, 8);
changed = true;
}
if (!oldMaterial || m_angle != angle) {
m_angle = angle;
- memcpy(buf->data() + 72, &m_angle, 4);
+ memcpy(buf->data() + 64 * shaderMatrixCount + 8, &m_angle, 4);
changed = true;
}
if (state.isOpacityDirty()) {
const float opacity = state.opacity();
- memcpy(buf->data() + 76, &opacity, 4);
+ memcpy(buf->data() + 64 * shaderMatrixCount + 8 + 4, &opacity, 4);
changed = true;
}
@@ -1019,10 +1013,10 @@ void QQuickShapeConicalGradientRhiShader::updateSampledImage(RenderState &state,
if (binding != 1)
return;
- QQuickShapeLinearGradientMaterial *m = static_cast<QQuickShapeLinearGradientMaterial *>(newMaterial);
+ QQuickShapeConicalGradientMaterial *m = static_cast<QQuickShapeConicalGradientMaterial *>(newMaterial);
QQuickShapeGenericStrokeFillNode *node = m->node();
- const QQuickShapeGradientCacheKey cacheKey(node->m_fillGradient.stops, node->m_fillGradient.spread);
- QSGTexture *t = QQuickShapeGradientCache::cacheForRhi(state.rhi())->get(cacheKey);
+ const QSGGradientCacheKey cacheKey(node->m_fillGradient.stops, QGradient::Spread(node->m_fillGradient.spread));
+ QSGTexture *t = QSGGradientCache::cacheForRhi(state.rhi())->get(cacheKey);
t->commitTextureOperations(state.rhi(), state.resourceUpdateBatch());
*texture = t;
}
@@ -1044,8 +1038,8 @@ int QQuickShapeConicalGradientMaterial::compare(const QSGMaterial *other) const
if (a == b)
return 0;
- const QQuickAbstractPathRenderer::GradientDesc *ga = &a->m_fillGradient;
- const QQuickAbstractPathRenderer::GradientDesc *gb = &b->m_fillGradient;
+ const QSGGradientCache::GradientDesc *ga = &a->m_fillGradient;
+ const QSGGradientCache::GradientDesc *gb = &b->m_fillGradient;
if (int d = ga->a.x() - gb->a.x())
return d;
@@ -1055,10 +1049,10 @@ int QQuickShapeConicalGradientMaterial::compare(const QSGMaterial *other) const
if (int d = ga->v0 - gb->v0)
return d;
- if (int d = ga->stops.count() - gb->stops.count())
+ if (int d = ga->stops.size() - gb->stops.size())
return d;
- for (int i = 0; i < ga->stops.count(); ++i) {
+ for (int i = 0; i < ga->stops.size(); ++i) {
if (int d = ga->stops[i].first - gb->stops[i].first)
return d;
if (int d = ga->stops[i].second.rgba() - gb->stops[i].second.rgba())
@@ -1071,7 +1065,9 @@ int QQuickShapeConicalGradientMaterial::compare(const QSGMaterial *other) const
QSGMaterialShader *QQuickShapeConicalGradientMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
{
Q_UNUSED(renderMode);
- return new QQuickShapeConicalGradientRhiShader;
+ return new QQuickShapeConicalGradientRhiShader(viewCount());
}
QT_END_NAMESPACE
+
+#include "moc_qquickshapegenericrenderer_p.cpp"