diff options
author | Alexandru Croitor <alexandru.croitor@qt.io> | 2019-07-11 14:51:40 +0200 |
---|---|---|
committer | Alexandru Croitor <alexandru.croitor@qt.io> | 2019-07-11 17:24:39 +0200 |
commit | 13374ceb165c44658aa97890c37b206859c9a31c (patch) | |
tree | 562362b196a459ee3449a5a1e60e5216a9dd6984 /src/quickshapes/qquickshapegenericrenderer.cpp | |
parent | ae47deba4c943c496412530a8d2a5a688ae12038 (diff) | |
parent | b5d18be5a03406d0aac83856dd41e1525fd14a28 (diff) |
Merge remote-tracking branch 'origin/wip/qt6' into wip/cmake
Change-Id: I2963c1209316fb6755f572969f368970450d7991
Diffstat (limited to 'src/quickshapes/qquickshapegenericrenderer.cpp')
-rw-r--r-- | src/quickshapes/qquickshapegenericrenderer.cpp | 307 |
1 files changed, 277 insertions, 30 deletions
diff --git a/src/quickshapes/qquickshapegenericrenderer.cpp b/src/quickshapes/qquickshapegenericrenderer.cpp index 604da2a889..6ddd055d85 100644 --- a/src/quickshapes/qquickshapegenericrenderer.cpp +++ b/src/quickshapes/qquickshapegenericrenderer.cpp @@ -40,13 +40,13 @@ #include "qquickshapegenericrenderer_p.h" #include <QtGui/private/qtriangulator_p.h> #include <QtGui/private/qtriangulatingstroker_p.h> +#include <QSGVertexColorMaterial> #if QT_CONFIG(thread) #include <QThreadPool> #endif #if QT_CONFIG(opengl) -#include <QSGVertexColorMaterial> #include <QOpenGLContext> #include <QOffscreenSurface> #include <QtGui/private/qopenglextensions_p.h> @@ -361,6 +361,9 @@ void QQuickShapeGenericRenderer::endSync(bool async) }); didKickOffAsync = true; #if QT_CONFIG(thread) + // qtVectorPathForPath() initializes a unique_ptr without locking. + // Do that before starting the threads as otherwise we get a race condition. + qtVectorPathForPath(r->path); pathWorkThreadPool->start(r); #endif } else { @@ -391,6 +394,9 @@ void QQuickShapeGenericRenderer::endSync(bool async) }); didKickOffAsync = true; #if QT_CONFIG(thread) + // qtVectorPathForPath() initializes a unique_ptr without locking. + // Do that before starting the threads as otherwise we get a race condition. + qtVectorPathForPath(r->path); pathWorkThreadPool->start(r); #endif } else { @@ -695,10 +701,8 @@ QSGMaterial *QQuickShapeGenericMaterialFactory::createVertexColor(QQuickWindow * { QSGRendererInterface::GraphicsApi api = window->rendererInterface()->graphicsApi(); -#if QT_CONFIG(opengl) - if (api == QSGRendererInterface::OpenGL) + if (api == QSGRendererInterface::OpenGL || QSGRendererInterface::isApiRhiBased(api)) return new QSGVertexColorMaterial; -#endif qWarning("Vertex-color material: Unsupported graphics API %d", api); return nullptr; @@ -709,12 +713,8 @@ QSGMaterial *QQuickShapeGenericMaterialFactory::createLinearGradient(QQuickWindo { QSGRendererInterface::GraphicsApi api = window->rendererInterface()->graphicsApi(); -#if QT_CONFIG(opengl) - if (api == QSGRendererInterface::OpenGL) + if (api == QSGRendererInterface::OpenGL || QSGRendererInterface::isApiRhiBased(api)) return new QQuickShapeLinearGradientMaterial(node); -#else - Q_UNUSED(node); -#endif qWarning("Linear gradient material: Unsupported graphics API %d", api); return nullptr; @@ -725,12 +725,8 @@ QSGMaterial *QQuickShapeGenericMaterialFactory::createRadialGradient(QQuickWindo { QSGRendererInterface::GraphicsApi api = window->rendererInterface()->graphicsApi(); -#if QT_CONFIG(opengl) - if (api == QSGRendererInterface::OpenGL) + if (api == QSGRendererInterface::OpenGL || QSGRendererInterface::isApiRhiBased(api)) return new QQuickShapeRadialGradientMaterial(node); -#else - Q_UNUSED(node); -#endif qWarning("Radial gradient material: Unsupported graphics API %d", api); return nullptr; @@ -741,12 +737,8 @@ QSGMaterial *QQuickShapeGenericMaterialFactory::createConicalGradient(QQuickWind { QSGRendererInterface::GraphicsApi api = window->rendererInterface()->graphicsApi(); -#if QT_CONFIG(opengl) - if (api == QSGRendererInterface::OpenGL) + if (api == QSGRendererInterface::OpenGL || QSGRendererInterface::isApiRhiBased(api)) return new QQuickShapeConicalGradientMaterial(node); -#else - Q_UNUSED(node); -#endif qWarning("Conical gradient material: Unsupported graphics API %d", api); return nullptr; @@ -754,8 +746,6 @@ QSGMaterial *QQuickShapeGenericMaterialFactory::createConicalGradient(QQuickWind #if QT_CONFIG(opengl) -QSGMaterialType QQuickShapeLinearGradientShader::type; - QQuickShapeLinearGradientShader::QQuickShapeLinearGradientShader() { setShaderSourceFile(QOpenGLShader::Vertex, @@ -786,8 +776,8 @@ void QQuickShapeLinearGradientShader::updateState(const RenderState &state, QSGM program()->setUniformValue(m_gradStartLoc, QVector2D(node->m_fillGradient.a)); program()->setUniformValue(m_gradEndLoc, QVector2D(node->m_fillGradient.b)); - const QQuickShapeGradientCache::Key cacheKey(node->m_fillGradient.stops, node->m_fillGradient.spread); - QSGTexture *tx = QQuickShapeGradientCache::currentCache()->get(cacheKey); + const QQuickShapeGradientCacheKey cacheKey(node->m_fillGradient.stops, node->m_fillGradient.spread); + QSGTexture *tx = QQuickShapeGradientOpenGLCache::currentCache()->get(cacheKey); tx->bind(); } @@ -797,6 +787,73 @@ char const *const *QQuickShapeLinearGradientShader::attributeNames() const return attr; } +#endif // QT_CONFIG(opengl) + +QQuickShapeLinearGradientRhiShader::QQuickShapeLinearGradientRhiShader() +{ + setShaderFileName(VertexStage, QStringLiteral(":/qt-project.org/shapes/shaders_ng/lineargradient.vert.qsb")); + setShaderFileName(FragmentStage, QStringLiteral(":/qt-project.org/shapes/shaders_ng/lineargradient.frag.qsb")); +} + +bool QQuickShapeLinearGradientRhiShader::updateUniformData(const RenderState &state, + QSGMaterial *newMaterial, QSGMaterial *oldMaterial) +{ + Q_ASSERT(oldMaterial == nullptr || newMaterial->type() == oldMaterial->type()); + QQuickShapeLinearGradientMaterial *m = static_cast<QQuickShapeLinearGradientMaterial *>(newMaterial); + bool changed = false; + QByteArray *buf = state.uniformData(); + Q_ASSERT(buf->size() >= 84); + + if (state.isMatrixDirty()) { + const QMatrix4x4 m = state.combinedMatrix(); + memcpy(buf->data(), m.constData(), 64); + changed = true; + } + + QQuickShapeGenericStrokeFillNode *node = m->node(); + + 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); + 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); + changed = true; + } + + if (state.isOpacityDirty()) { + const float opacity = state.opacity(); + memcpy(buf->data() + 80, &opacity, 4); + changed = true; + } + + return changed; +} + +void QQuickShapeLinearGradientRhiShader::updateSampledImage(const RenderState &state, int binding, QSGTexture **texture, + QSGMaterial *newMaterial, QSGMaterial *) +{ + if (binding != 1) + return; + + 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); + t->updateRhiTexture(state.rhi(), state.resourceUpdateBatch()); + *texture = t; +} + +QSGMaterialType *QQuickShapeLinearGradientMaterial::type() const +{ + static QSGMaterialType type; + return &type; +} + int QQuickShapeLinearGradientMaterial::compare(const QSGMaterial *other) const { Q_ASSERT(other && type() == other->type()); @@ -836,7 +893,19 @@ int QQuickShapeLinearGradientMaterial::compare(const QSGMaterial *other) const return 0; } -QSGMaterialType QQuickShapeRadialGradientShader::type; +QSGMaterialShader *QQuickShapeLinearGradientMaterial::createShader() const +{ + if (flags().testFlag(RhiShaderWanted)) + return new QQuickShapeLinearGradientRhiShader; +#if QT_CONFIG(opengl) + else + return new QQuickShapeLinearGradientShader; +#else + return nullptr; +#endif +} + +#if QT_CONFIG(opengl) QQuickShapeRadialGradientShader::QQuickShapeRadialGradientShader() { @@ -880,8 +949,8 @@ void QQuickShapeRadialGradientShader::updateState(const RenderState &state, QSGM program()->setUniformValue(m_focalRadiusLoc, focalRadius); program()->setUniformValue(m_focalToCenterLoc, focalToCenter); - const QQuickShapeGradientCache::Key cacheKey(node->m_fillGradient.stops, node->m_fillGradient.spread); - QSGTexture *tx = QQuickShapeGradientCache::currentCache()->get(cacheKey); + const QQuickShapeGradientCacheKey cacheKey(node->m_fillGradient.stops, node->m_fillGradient.spread); + QSGTexture *tx = QQuickShapeGradientOpenGLCache::currentCache()->get(cacheKey); tx->bind(); } @@ -891,6 +960,92 @@ char const *const *QQuickShapeRadialGradientShader::attributeNames() const return attr; } +#endif // QT_CONFIG(opengl) + +QQuickShapeRadialGradientRhiShader::QQuickShapeRadialGradientRhiShader() +{ + setShaderFileName(VertexStage, QStringLiteral(":/qt-project.org/shapes/shaders_ng/radialgradient.vert.qsb")); + setShaderFileName(FragmentStage, QStringLiteral(":/qt-project.org/shapes/shaders_ng/radialgradient.frag.qsb")); +} + +bool QQuickShapeRadialGradientRhiShader::updateUniformData(const RenderState &state, + QSGMaterial *newMaterial, QSGMaterial *oldMaterial) +{ + Q_ASSERT(oldMaterial == nullptr || newMaterial->type() == oldMaterial->type()); + QQuickShapeLinearGradientMaterial *m = static_cast<QQuickShapeLinearGradientMaterial *>(newMaterial); + bool changed = false; + QByteArray *buf = state.uniformData(); + Q_ASSERT(buf->size() >= 92); + + if (state.isMatrixDirty()) { + const QMatrix4x4 m = state.combinedMatrix(); + memcpy(buf->data(), m.constData(), 64); + changed = true; + } + + QQuickShapeGenericStrokeFillNode *node = m->node(); + + const QPointF centerPoint = node->m_fillGradient.a; + const QPointF focalPoint = node->m_fillGradient.b; + const QPointF focalToCenter = centerPoint - focalPoint; + const float centerRadius = node->m_fillGradient.v0; + const float focalRadius = node->m_fillGradient.v1; + + 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); + 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); + changed = true; + } + + if (!oldMaterial || m_centerRadius != centerRadius) { + m_centerRadius = centerRadius; + memcpy(buf->data() + 80, &m_centerRadius, 4); + changed = true; + } + + if (!oldMaterial || m_focalRadius != focalRadius) { + m_focalRadius = focalRadius; + memcpy(buf->data() + 84, &m_focalRadius, 4); + changed = true; + } + + if (state.isOpacityDirty()) { + const float opacity = state.opacity(); + memcpy(buf->data() + 88, &opacity, 4); + changed = true; + } + + return changed; +} + +void QQuickShapeRadialGradientRhiShader::updateSampledImage(const RenderState &state, int binding, QSGTexture **texture, + QSGMaterial *newMaterial, QSGMaterial *) +{ + if (binding != 1) + return; + + 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); + t->updateRhiTexture(state.rhi(), state.resourceUpdateBatch()); + *texture = t; +} + +QSGMaterialType *QQuickShapeRadialGradientMaterial::type() const +{ + static QSGMaterialType type; + return &type; +} + int QQuickShapeRadialGradientMaterial::compare(const QSGMaterial *other) const { Q_ASSERT(other && type() == other->type()); @@ -935,7 +1090,19 @@ int QQuickShapeRadialGradientMaterial::compare(const QSGMaterial *other) const return 0; } -QSGMaterialType QQuickShapeConicalGradientShader::type; +QSGMaterialShader *QQuickShapeRadialGradientMaterial::createShader() const +{ + if (flags().testFlag(RhiShaderWanted)) + return new QQuickShapeRadialGradientRhiShader; +#if QT_CONFIG(opengl) + else + return new QQuickShapeRadialGradientShader; +#else + return nullptr; +#endif +} + +#if QT_CONFIG(opengl) QQuickShapeConicalGradientShader::QQuickShapeConicalGradientShader() { @@ -972,8 +1139,8 @@ void QQuickShapeConicalGradientShader::updateState(const RenderState &state, QSG program()->setUniformValue(m_angleLoc, angle); program()->setUniformValue(m_translationPointLoc, centerPoint); - const QQuickShapeGradientCache::Key cacheKey(node->m_fillGradient.stops, QQuickShapeGradient::RepeatSpread); - QSGTexture *tx = QQuickShapeGradientCache::currentCache()->get(cacheKey); + const QQuickShapeGradientCacheKey cacheKey(node->m_fillGradient.stops, QQuickShapeGradient::RepeatSpread); + QSGTexture *tx = QQuickShapeGradientOpenGLCache::currentCache()->get(cacheKey); tx->bind(); } @@ -983,6 +1150,76 @@ char const *const *QQuickShapeConicalGradientShader::attributeNames() const return attr; } +#endif // QT_CONFIG(opengl) + +QQuickShapeConicalGradientRhiShader::QQuickShapeConicalGradientRhiShader() +{ + setShaderFileName(VertexStage, QStringLiteral(":/qt-project.org/shapes/shaders_ng/conicalgradient.vert.qsb")); + setShaderFileName(FragmentStage, QStringLiteral(":/qt-project.org/shapes/shaders_ng/conicalgradient.frag.qsb")); +} + +bool QQuickShapeConicalGradientRhiShader::updateUniformData(const RenderState &state, + QSGMaterial *newMaterial, QSGMaterial *oldMaterial) +{ + Q_ASSERT(oldMaterial == nullptr || newMaterial->type() == oldMaterial->type()); + QQuickShapeLinearGradientMaterial *m = static_cast<QQuickShapeLinearGradientMaterial *>(newMaterial); + bool changed = false; + QByteArray *buf = state.uniformData(); + Q_ASSERT(buf->size() >= 80); + + if (state.isMatrixDirty()) { + const QMatrix4x4 m = state.combinedMatrix(); + memcpy(buf->data(), m.constData(), 64); + changed = true; + } + + QQuickShapeGenericStrokeFillNode *node = m->node(); + + 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); + changed = true; + } + + if (!oldMaterial || m_angle != angle) { + m_angle = angle; + memcpy(buf->data() + 72, &m_angle, 4); + changed = true; + } + + if (state.isOpacityDirty()) { + const float opacity = state.opacity(); + memcpy(buf->data() + 76, &opacity, 4); + changed = true; + } + + return changed; +} + +void QQuickShapeConicalGradientRhiShader::updateSampledImage(const RenderState &state, int binding, QSGTexture **texture, + QSGMaterial *newMaterial, QSGMaterial *) +{ + if (binding != 1) + return; + + 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); + t->updateRhiTexture(state.rhi(), state.resourceUpdateBatch()); + *texture = t; +} + +QSGMaterialType *QQuickShapeConicalGradientMaterial::type() const +{ + static QSGMaterialType type; + return &type; +} + int QQuickShapeConicalGradientMaterial::compare(const QSGMaterial *other) const { Q_ASSERT(other && type() == other->type()); @@ -1018,6 +1255,16 @@ int QQuickShapeConicalGradientMaterial::compare(const QSGMaterial *other) const return 0; } -#endif // QT_CONFIG(opengl) +QSGMaterialShader *QQuickShapeConicalGradientMaterial::createShader() const +{ + if (flags().testFlag(RhiShaderWanted)) + return new QQuickShapeConicalGradientRhiShader; +#if QT_CONFIG(opengl) + else + return new QQuickShapeConicalGradientShader; +#else + return nullptr; +#endif +} QT_END_NAMESPACE |