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.cpp156
1 files changed, 103 insertions, 53 deletions
diff --git a/src/quickshapes/qquickshapegenericrenderer.cpp b/src/quickshapes/qquickshapegenericrenderer.cpp
index b2b6af041f..20dfe21040 100644
--- a/src/quickshapes/qquickshapegenericrenderer.cpp
+++ b/src/quickshapes/qquickshapegenericrenderer.cpp
@@ -4,9 +4,11 @@
#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
@@ -176,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());
@@ -200,6 +202,13 @@ void QQuickShapeGenericRenderer::setFillGradient(int index, QQuickShapeGradient
d.syncDirty |= DirtyFillGradient;
}
+void QQuickShapeGenericRenderer::setFillTransform(int index, const QSGTransform &transform)
+{
+ ShapePathData &d(m_sp[index]);
+ d.fillTransform = transform;
+ d.syncDirty |= DirtyFillTransform;
+}
+
void QQuickShapeGenericRenderer::setTriangulationScale(qreal scale)
{
// No dirty, this is called at the start of every sync. Just store the value.
@@ -489,7 +498,7 @@ void QQuickShapeGenericRenderer::updateNode()
QQuickShapeGenericNode *node = *nodePtr;
if (m_accDirty & DirtyList)
- d.effectiveDirty |= DirtyFillGeom | DirtyStrokeGeom | DirtyColor | DirtyFillGradient;
+ d.effectiveDirty |= DirtyFillGeom | DirtyStrokeGeom | DirtyColor | DirtyFillGradient | DirtyFillTransform;
if (!d.effectiveDirty) {
prevNode = node;
@@ -542,6 +551,8 @@ void QQuickShapeGenericRenderer::updateShadowDataInNode(ShapePathData *d, QQuick
if (d->fillGradientActive) {
if (d->effectiveDirty & DirtyFillGradient)
n->m_fillGradient = d->fillGradient;
+ if (d->effectiveDirty & DirtyFillTransform)
+ n->m_fillTransform = d->fillTransform;
}
}
@@ -549,7 +560,7 @@ void QQuickShapeGenericRenderer::updateFillNode(ShapePathData *d, QQuickShapeGen
{
if (!node->m_fillNode)
return;
- if (!(d->effectiveDirty & (DirtyFillGeom | DirtyColor | DirtyFillGradient)))
+ if (!(d->effectiveDirty & (DirtyFillGeom | DirtyColor | DirtyFillGradient | DirtyFillTransform)))
return;
// Make a copy of the data that will be accessed by the material on
@@ -582,10 +593,10 @@ void QQuickShapeGenericRenderer::updateFillNode(ShapePathData *d, QQuickShapeGen
Q_UNREACHABLE_RETURN();
}
n->activateMaterial(m_item->window(), gradMat);
- if (d->effectiveDirty & DirtyFillGradient) {
+ if (d->effectiveDirty & (DirtyFillGradient | DirtyFillTransform)) {
// Gradients are implemented via a texture-based material.
n->markDirty(QSGNode::DirtyMaterial);
- // stop here if only the gradient changed; no need to touch the geometry
+ // stop here if only the gradient or filltransform changed; no need to touch the geometry
if (!(d->effectiveDirty & DirtyFillGeom))
return;
}
@@ -701,10 +712,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,
@@ -714,32 +725,42 @@ bool QQuickShapeLinearGradientRhiShader::updateUniformData(RenderState &state,
QQuickShapeLinearGradientMaterial *m = static_cast<QQuickShapeLinearGradientMaterial *>(newMaterial);
bool changed = false;
QByteArray *buf = state.uniformData();
- Q_ASSERT(buf->size() >= 84);
+ Q_ASSERT(buf->size() >= 84 + 64);
+ 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();
+ if (!oldMaterial || m_fillTransform != node->m_fillTransform) {
+ memcpy(buf->data() + 64 * shaderMatrixCount, node->m_fillTransform.invertedData(), 64);
+ m_fillTransform = node->m_fillTransform;
+ changed = true;
+ }
+
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 + 64, &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 + 64 + 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 + 64 + 8 + 8, &opacity, 4);
changed = true;
}
@@ -754,8 +775,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;
}
@@ -777,8 +798,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;
@@ -802,19 +823,22 @@ int QQuickShapeLinearGradientMaterial::compare(const QSGMaterial *other) const
return d;
}
+ if (int d = a->m_fillTransform.compareTo(b->m_fillTransform))
+ return d;
+
return 0;
}
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,
@@ -824,16 +848,26 @@ bool QQuickShapeRadialGradientRhiShader::updateUniformData(RenderState &state,
QQuickShapeRadialGradientMaterial *m = static_cast<QQuickShapeRadialGradientMaterial *>(newMaterial);
bool changed = false;
QByteArray *buf = state.uniformData();
- Q_ASSERT(buf->size() >= 92);
+ Q_ASSERT(buf->size() >= 92 + 64);
+ 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();
+ if (!oldMaterial || m_fillTransform != node->m_fillTransform) {
+ memcpy(buf->data() + 64 * shaderMatrixCount, node->m_fillTransform.invertedData(), 64);
+ m_fillTransform = node->m_fillTransform;
+ changed = true;
+ }
+
const QPointF centerPoint = node->m_fillGradient.a;
const QPointF focalPoint = node->m_fillGradient.b;
const QPointF focalToCenter = centerPoint - focalPoint;
@@ -843,32 +877,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 + 64, &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 + 64 + 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 + 64 + 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 + 64 + 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 + 64 + 8 + 8 + 4 + 4, &opacity, 4);
changed = true;
}
@@ -883,8 +917,8 @@ void QQuickShapeRadialGradientRhiShader::updateSampledImage(RenderState &state,
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;
}
@@ -906,8 +940,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;
@@ -936,19 +970,22 @@ int QQuickShapeRadialGradientMaterial::compare(const QSGMaterial *other) const
return d;
}
+ if (int d = a->m_fillTransform.compareTo(b->m_fillTransform))
+ return d;
+
return 0;
}
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,
@@ -958,35 +995,45 @@ bool QQuickShapeConicalGradientRhiShader::updateUniformData(RenderState &state,
QQuickShapeConicalGradientMaterial *m = static_cast<QQuickShapeConicalGradientMaterial *>(newMaterial);
bool changed = false;
QByteArray *buf = state.uniformData();
- Q_ASSERT(buf->size() >= 80);
+ Q_ASSERT(buf->size() >= 80 + 64);
+ 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();
+ if (!oldMaterial || m_fillTransform != node->m_fillTransform) {
+ memcpy(buf->data() + 64 * shaderMatrixCount, node->m_fillTransform.invertedData(), 64);
+ m_fillTransform = node->m_fillTransform;
+ changed = true;
+ }
+
const QPointF centerPoint = node->m_fillGradient.a;
const float angle = -qDegreesToRadians(node->m_fillGradient.v0);
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 + 64, &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 + 64 + 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 + 64 + 8 + 4, &opacity, 4);
changed = true;
}
@@ -1001,8 +1048,8 @@ void QQuickShapeConicalGradientRhiShader::updateSampledImage(RenderState &state,
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;
}
@@ -1024,8 +1071,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;
@@ -1045,13 +1092,16 @@ int QQuickShapeConicalGradientMaterial::compare(const QSGMaterial *other) const
return d;
}
+ if (int d = a->m_fillTransform.compareTo(b->m_fillTransform))
+ return d;
+
return 0;
}
QSGMaterialShader *QQuickShapeConicalGradientMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
{
Q_UNUSED(renderMode);
- return new QQuickShapeConicalGradientRhiShader;
+ return new QQuickShapeConicalGradientRhiShader(viewCount());
}
QT_END_NAMESPACE