aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp')
-rw-r--r--src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp636
1 files changed, 141 insertions, 495 deletions
diff --git a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp
index e8e9f76d04..afb41f32e4 100644
--- a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp
+++ b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp
@@ -1,45 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 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) 2019 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 "qsgdistancefieldglyphnode_p_p.h"
#include "qsgrhidistancefieldglyphcache_p.h"
-#include <QtGui/qopenglfunctions.h>
#include <QtGui/qsurface.h>
#include <QtGui/qwindow.h>
#include <qmath.h>
@@ -70,147 +33,10 @@ static float spreadFunc(float glyphScale)
return range / glyphScale;
}
-class QSGDistanceFieldTextMaterialShader : public QSGMaterialShader
+class QSGDistanceFieldTextMaterialRhiShader : public QSGMaterialShader
{
public:
- QSGDistanceFieldTextMaterialShader();
-
- void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
- char const *const *attributeNames() const override;
-
-protected:
- void initialize() override;
-
- void updateAlphaRange();
- void updateColor(const QVector4D &c);
- void updateTextureScale(const QVector2D &ts);
-
- float m_fontScale = 1.0;
- float m_matrixScale = 1.0;
-
- int m_matrix_id = -1;
- int m_textureScale_id = -1;
- int m_alphaMin_id = -1;
- int m_alphaMax_id = -1;
- int m_color_id = -1;
-
- QVector2D m_lastTextureScale;
- QVector4D m_lastColor;
- float m_lastAlphaMin = -1;
- float m_lastAlphaMax = -1;
-};
-
-char const *const *QSGDistanceFieldTextMaterialShader::attributeNames() const {
- static char const *const attr[] = { "vCoord", "tCoord", nullptr };
- return attr;
-}
-
-QSGDistanceFieldTextMaterialShader::QSGDistanceFieldTextMaterialShader()
-{
- setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/scenegraph/shaders/distancefieldtext.vert"));
- setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/distancefieldtext.frag"));
-}
-
-void QSGDistanceFieldTextMaterialShader::updateAlphaRange()
-{
- float combinedScale = m_fontScale * m_matrixScale;
- float base = thresholdFunc(combinedScale);
- float range = spreadFunc(combinedScale);
- float alphaMin = qMax(0.0f, base - range);
- float alphaMax = qMin(base + range, 1.0f);
- if (alphaMin != m_lastAlphaMin) {
- program()->setUniformValue(m_alphaMin_id, GLfloat(alphaMin));
- m_lastAlphaMin = alphaMin;
- }
- if (alphaMax != m_lastAlphaMax) {
- program()->setUniformValue(m_alphaMax_id, GLfloat(alphaMax));
- m_lastAlphaMax = alphaMax;
- }
-}
-
-void QSGDistanceFieldTextMaterialShader::updateColor(const QVector4D &c)
-{
- if (m_lastColor != c) {
- program()->setUniformValue(m_color_id, c);
- m_lastColor = c;
- }
-}
-
-void QSGDistanceFieldTextMaterialShader::updateTextureScale(const QVector2D &ts)
-{
- if (m_lastTextureScale != ts) {
- program()->setUniformValue(m_textureScale_id, ts);
- m_lastTextureScale = ts;
- }
-}
-
-void QSGDistanceFieldTextMaterialShader::initialize()
-{
- QSGMaterialShader::initialize();
- m_matrix_id = program()->uniformLocation("matrix");
- m_textureScale_id = program()->uniformLocation("textureScale");
- m_color_id = program()->uniformLocation("color");
- m_alphaMin_id = program()->uniformLocation("alphaMin");
- m_alphaMax_id = program()->uniformLocation("alphaMax");
-}
-
-void QSGDistanceFieldTextMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
-{
- Q_ASSERT(oldEffect == nullptr || newEffect->type() == oldEffect->type());
- QSGDistanceFieldTextMaterial *material = static_cast<QSGDistanceFieldTextMaterial *>(newEffect);
- QSGDistanceFieldTextMaterial *oldMaterial = static_cast<QSGDistanceFieldTextMaterial *>(oldEffect);
-
- bool updated = material->updateTextureSize();
-
- if (oldMaterial == nullptr
- || material->color() != oldMaterial->color()
- || state.isOpacityDirty()) {
- QVector4D color = material->color();
- color *= state.opacity();
- updateColor(color);
- }
-
- bool updateRange = false;
- if (oldMaterial == nullptr
- || material->fontScale() != oldMaterial->fontScale()) {
- m_fontScale = material->fontScale();
- updateRange = true;
- }
- if (state.isMatrixDirty()) {
- program()->setUniformValue(m_matrix_id, state.combinedMatrix());
- m_matrixScale = qSqrt(qAbs(state.determinant())) * state.devicePixelRatio();
- updateRange = true;
- }
- if (updateRange) {
- updateAlphaRange();
- }
-
- Q_ASSERT(material->glyphCache());
-
- if (updated
- || oldMaterial == nullptr
- || oldMaterial->texture()->textureId != material->texture()->textureId) {
- updateTextureScale(QVector2D(1.0 / material->textureSize().width(),
- 1.0 / material->textureSize().height()));
-
- QOpenGLFunctions *funcs = state.context()->functions();
- funcs->glBindTexture(GL_TEXTURE_2D, material->texture()->textureId);
-
- if (updated) {
- // Set the mag/min filters to be linear. We only need to do this when the texture
- // has been recreated.
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- }
- }
-}
-
-class QSGDistanceFieldTextMaterialRhiShader : public QSGMaterialRhiShader
-{
-public:
- QSGDistanceFieldTextMaterialRhiShader(bool alphaTexture);
+ QSGDistanceFieldTextMaterialRhiShader(bool alphaTexture, int viewCount);
bool updateUniformData(RenderState &state,
QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override;
@@ -221,18 +47,16 @@ public:
protected:
float m_fontScale = 1.0;
float m_matrixScale = 1.0;
+ quint32 m_currentUbufOffset;
};
-QSGDistanceFieldTextMaterialRhiShader::QSGDistanceFieldTextMaterialRhiShader(bool alphaTexture)
+QSGDistanceFieldTextMaterialRhiShader::QSGDistanceFieldTextMaterialRhiShader(bool alphaTexture, int viewCount)
{
- setShaderFileName(VertexStage,
- QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldtext.vert.qsb"));
+ setShaderFileName(VertexStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldtext.vert.qsb"), viewCount);
if (alphaTexture)
- setShaderFileName(FragmentStage,
- QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldtext_a.frag.qsb"));
+ setShaderFileName(FragmentStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldtext_a.frag.qsb"), viewCount);
else
- setShaderFileName(FragmentStage,
- QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldtext.frag.qsb"));
+ setShaderFileName(FragmentStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldtext.frag.qsb"), viewCount);
}
bool QSGDistanceFieldTextMaterialRhiShader::updateUniformData(RenderState &state,
@@ -258,36 +82,47 @@ bool QSGDistanceFieldTextMaterialRhiShader::updateUniformData(RenderState &state
updateRange = true;
}
if (state.isMatrixDirty()) {
- const QMatrix4x4 m = state.combinedMatrix();
- memcpy(buf->data(), m.constData(), 64);
- changed = true;
m_matrixScale = qSqrt(qAbs(state.determinant())) * state.devicePixelRatio();
updateRange = true;
}
+ quint32 offset = 0;
+ const int matrixCount = qMin(state.projectionMatrixCount(), newMaterial->viewCount());
+ for (int viewIndex = 0; viewIndex < matrixCount; ++viewIndex) {
+ if (state.isMatrixDirty()) {
+ const QMatrix4x4 m = state.combinedMatrix(viewIndex);
+ memcpy(buf->data() + 64 * viewIndex, m.constData(), 64);
+ changed = true;
+ }
+ offset += 64;
+ }
if (textureUpdated || !oldMat || oldMat->texture()->texture != mat->texture()->texture) {
const QVector2D ts(1.0f / mat->textureSize().width(), 1.0f / mat->textureSize().height());
Q_ASSERT(sizeof(ts) == 8);
- memcpy(buf->data() + 64, &ts, 8);
+ memcpy(buf->data() + offset, &ts, 8);
changed = true;
}
+ offset += 8 + 8; // 8 is padding for vec4 alignment
if (!oldMat || mat->color() != oldMat->color() || state.isOpacityDirty()) {
const QVector4D color = mat->color() * state.opacity();
Q_ASSERT(sizeof(color) == 16);
- memcpy(buf->data() + 80, &color, 16);
+ memcpy(buf->data() + offset, &color, 16);
changed = true;
}
+ offset += 16;
if (updateRange) { // deferred because depends on m_fontScale and m_matrixScale
const float combinedScale = m_fontScale * m_matrixScale;
const float base = thresholdFunc(combinedScale);
const float range = spreadFunc(combinedScale);
const QVector2D alphaMinMax(qMax(0.0f, base - range), qMin(base + range, 1.0f));
- memcpy(buf->data() + 96, &alphaMinMax, 8);
+ memcpy(buf->data() + offset, &alphaMinMax, 8);
changed = true;
}
+ offset += 8; // not adding any padding here since we are not sure what comes afterwards in the subclasses' shaders
// move texture uploads/copies onto the renderer's soon-to-be-committed list
static_cast<QSGRhiDistanceFieldGlyphCache *>(mat->glyphCache())->commitResourceUpdates(state.resourceUpdateBatch());
+ m_currentUbufOffset = offset;
return changed;
}
@@ -304,13 +139,29 @@ void QSGDistanceFieldTextMaterialRhiShader::updateSampledImage(RenderState &stat
*texture = t;
}
+class DistanceFieldAnisotropicTextMaterialRhiShader : public QSGDistanceFieldTextMaterialRhiShader
+{
+public:
+ DistanceFieldAnisotropicTextMaterialRhiShader(bool alphaTexture, int viewCount);
+};
+
+DistanceFieldAnisotropicTextMaterialRhiShader::DistanceFieldAnisotropicTextMaterialRhiShader(bool alphaTexture, int viewCount)
+ : QSGDistanceFieldTextMaterialRhiShader(alphaTexture, viewCount)
+{
+ setShaderFileName(VertexStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldtext.vert.qsb"), viewCount);
+ if (alphaTexture)
+ setShaderFileName(FragmentStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldtext_a_fwidth.frag.qsb"), viewCount);
+ else
+ setShaderFileName(FragmentStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldtext_fwidth.frag.qsb"), viewCount);
+}
+
QSGDistanceFieldTextMaterial::QSGDistanceFieldTextMaterial()
: m_glyph_cache(nullptr)
, m_texture(nullptr)
, m_fontScale(1.0)
, m_sgTexture(nullptr)
{
- setFlag(Blending | RequiresDeterminant | SupportsRhiShader, true);
+ setFlag(Blending | RequiresDeterminant, true);
}
QSGDistanceFieldTextMaterial::~QSGDistanceFieldTextMaterial()
@@ -326,18 +177,17 @@ QSGMaterialType *QSGDistanceFieldTextMaterial::type() const
void QSGDistanceFieldTextMaterial::setColor(const QColor &color)
{
- m_color = QVector4D(color.redF() * color.alphaF(),
- color.greenF() * color.alphaF(),
- color.blueF() * color.alphaF(),
- color.alphaF());
+ float r, g, b, a;
+ color.getRgbF(&r, &g, &b, &a);
+ m_color = QVector4D(r * a, g * a, b * a, a);
}
-QSGMaterialShader *QSGDistanceFieldTextMaterial::createShader() const
+QSGMaterialShader *QSGDistanceFieldTextMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
{
- if (flags().testFlag(RhiShaderWanted))
- return new QSGDistanceFieldTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled());
+ if (renderMode == QSGRendererInterface::RenderMode3D && m_glyph_cache->screenSpaceDerivativesSupported())
+ return new DistanceFieldAnisotropicTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled(), viewCount());
else
- return new QSGDistanceFieldTextMaterialShader;
+ return new QSGDistanceFieldTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled(), viewCount());
}
bool QSGDistanceFieldTextMaterial::updateTextureSize()
@@ -381,62 +231,21 @@ int QSGDistanceFieldTextMaterial::compare(const QSGMaterial *o) const
}
if (m_color != other->m_color)
return &m_color < &other->m_color ? -1 : 1;
- int t0 = m_texture ? (m_texture->rhiBased ? qintptr(m_texture->texture) : m_texture->textureId) : 0;
- int t1 = other->m_texture ? (other->m_texture->rhiBased ? qintptr(other->m_texture->texture) : other->m_texture->textureId) : 0;
- return t0 - t1;
+ qintptr t0 = m_texture ? qintptr(m_texture->texture) : 0;
+ qintptr t1 = other->m_texture ? qintptr(other->m_texture->texture) : 0;
+ const qintptr diff = t0 - t1;
+ return diff < 0 ? -1 : (diff > 0 ? 1 : 0);
}
-
-
-class DistanceFieldStyledTextMaterialShader : public QSGDistanceFieldTextMaterialShader
-{
-public:
- DistanceFieldStyledTextMaterialShader();
-
- void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
-
-protected:
- void initialize() override;
-
- int m_styleColor_id = -1;
-};
-
-DistanceFieldStyledTextMaterialShader::DistanceFieldStyledTextMaterialShader()
- : QSGDistanceFieldTextMaterialShader()
-{
-}
-
-void DistanceFieldStyledTextMaterialShader::initialize()
-{
- QSGDistanceFieldTextMaterialShader::initialize();
- m_styleColor_id = program()->uniformLocation("styleColor");
-}
-
-void DistanceFieldStyledTextMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
-{
- QSGDistanceFieldTextMaterialShader::updateState(state, newEffect, oldEffect);
-
- QSGDistanceFieldStyledTextMaterial *material = static_cast<QSGDistanceFieldStyledTextMaterial *>(newEffect);
- QSGDistanceFieldStyledTextMaterial *oldMaterial = static_cast<QSGDistanceFieldStyledTextMaterial *>(oldEffect);
-
- if (oldMaterial == nullptr
- || material->styleColor() != oldMaterial->styleColor()
- || (state.isOpacityDirty())) {
- QVector4D color = material->styleColor();
- color *= state.opacity();
- program()->setUniformValue(m_styleColor_id, color);
- }
-}
-
class DistanceFieldStyledTextMaterialRhiShader : public QSGDistanceFieldTextMaterialRhiShader
{
public:
- DistanceFieldStyledTextMaterialRhiShader(bool alphaTexture);
+ DistanceFieldStyledTextMaterialRhiShader(bool alphaTexture, int viewCount);
bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override;
};
-DistanceFieldStyledTextMaterialRhiShader::DistanceFieldStyledTextMaterialRhiShader(bool alphaTexture)
- : QSGDistanceFieldTextMaterialRhiShader(alphaTexture)
+DistanceFieldStyledTextMaterialRhiShader::DistanceFieldStyledTextMaterialRhiShader(bool alphaTexture, int viewCount)
+ : QSGDistanceFieldTextMaterialRhiShader(alphaTexture, viewCount)
{
}
@@ -450,12 +259,17 @@ bool DistanceFieldStyledTextMaterialRhiShader::updateUniformData(RenderState &st
QByteArray *buf = state.uniformData();
Q_ASSERT(buf->size() >= 128);
+ // must add 8 bytes padding for vec4 alignment, the base class did not do this
+ m_currentUbufOffset += 8; // now at StyleColor
+
if (!oldMat || mat->styleColor() != oldMat->styleColor() || state.isOpacityDirty()) {
QVector4D styleColor = mat->styleColor();
styleColor *= state.opacity();
- memcpy(buf->data() + 112, &styleColor, 16);
+
+ memcpy(buf->data() + m_currentUbufOffset, &styleColor, 16);
changed = true;
}
+ m_currentUbufOffset += 16;
return changed;
}
@@ -471,10 +285,9 @@ QSGDistanceFieldStyledTextMaterial::~QSGDistanceFieldStyledTextMaterial()
void QSGDistanceFieldStyledTextMaterial::setStyleColor(const QColor &color)
{
- m_styleColor = QVector4D(color.redF() * color.alphaF(),
- color.greenF() * color.alphaF(),
- color.blueF() * color.alphaF(),
- color.alphaF());
+ float r, g, b, a;
+ color.getRgbF(&r, &g, &b, &a);
+ m_styleColor = QVector4D(r * a, g * a, b * a, a);
}
int QSGDistanceFieldStyledTextMaterial::compare(const QSGMaterial *o) const
@@ -486,82 +299,38 @@ int QSGDistanceFieldStyledTextMaterial::compare(const QSGMaterial *o) const
return QSGDistanceFieldTextMaterial::compare(o);
}
-
-class DistanceFieldOutlineTextMaterialShader : public DistanceFieldStyledTextMaterialShader
+class DistanceFieldOutlineTextMaterialRhiShader : public DistanceFieldStyledTextMaterialRhiShader
{
public:
- DistanceFieldOutlineTextMaterialShader();
-
- void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
+ DistanceFieldOutlineTextMaterialRhiShader(bool alphaTexture, int viewCount);
-protected:
- void initialize() override;
-
- void updateOutlineAlphaRange(int dfRadius);
-
- int m_outlineAlphaMax0_id = -1;
- int m_outlineAlphaMax1_id = -1;
+ bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override;
};
-DistanceFieldOutlineTextMaterialShader::DistanceFieldOutlineTextMaterialShader()
- : DistanceFieldStyledTextMaterialShader()
-{
- setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/distancefieldoutlinetext.frag"));
-}
-
-void DistanceFieldOutlineTextMaterialShader::initialize()
-{
- DistanceFieldStyledTextMaterialShader::initialize();
- m_outlineAlphaMax0_id = program()->uniformLocation("outlineAlphaMax0");
- m_outlineAlphaMax1_id = program()->uniformLocation("outlineAlphaMax1");
-}
-
-void DistanceFieldOutlineTextMaterialShader::updateOutlineAlphaRange(int dfRadius)
-{
- float combinedScale = m_fontScale * m_matrixScale;
- float base = thresholdFunc(combinedScale);
- float range = spreadFunc(combinedScale);
- float outlineLimit = qMax(0.2f, base - 0.5f / dfRadius / m_fontScale);
-
- float alphaMin = qMax(0.0f, base - range);
- float styleAlphaMin0 = qMax(0.0f, outlineLimit - range);
- float styleAlphaMin1 = qMin(outlineLimit + range, alphaMin);
- program()->setUniformValue(m_outlineAlphaMax0_id, GLfloat(styleAlphaMin0));
- program()->setUniformValue(m_outlineAlphaMax1_id, GLfloat(styleAlphaMin1));
-}
-
-void DistanceFieldOutlineTextMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
+DistanceFieldOutlineTextMaterialRhiShader::DistanceFieldOutlineTextMaterialRhiShader(bool alphaTexture, int viewCount)
+ : DistanceFieldStyledTextMaterialRhiShader(alphaTexture, viewCount)
{
- DistanceFieldStyledTextMaterialShader::updateState(state, newEffect, oldEffect);
-
- QSGDistanceFieldOutlineTextMaterial *material = static_cast<QSGDistanceFieldOutlineTextMaterial *>(newEffect);
- QSGDistanceFieldOutlineTextMaterial *oldMaterial = static_cast<QSGDistanceFieldOutlineTextMaterial *>(oldEffect);
-
- if (oldMaterial == nullptr
- || material->fontScale() != oldMaterial->fontScale()
- || state.isMatrixDirty())
- updateOutlineAlphaRange(material->glyphCache()->distanceFieldRadius());
+ setShaderFileName(VertexStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldoutlinetext.vert.qsb"), viewCount);
+ if (alphaTexture)
+ setShaderFileName(FragmentStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag.qsb"), viewCount);
+ else
+ setShaderFileName(FragmentStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldoutlinetext.frag.qsb"), viewCount);
}
-class DistanceFieldOutlineTextMaterialRhiShader : public DistanceFieldStyledTextMaterialRhiShader
+class DistanceFieldAnisotropicOutlineTextMaterialRhiShader : public DistanceFieldOutlineTextMaterialRhiShader
{
public:
- DistanceFieldOutlineTextMaterialRhiShader(bool alphaTexture);
-
- bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override;
+ DistanceFieldAnisotropicOutlineTextMaterialRhiShader(bool alphaTexture, int viewCount);
};
-DistanceFieldOutlineTextMaterialRhiShader::DistanceFieldOutlineTextMaterialRhiShader(bool alphaTexture)
- : DistanceFieldStyledTextMaterialRhiShader(alphaTexture)
+DistanceFieldAnisotropicOutlineTextMaterialRhiShader::DistanceFieldAnisotropicOutlineTextMaterialRhiShader(bool alphaTexture, int viewCount)
+ : DistanceFieldOutlineTextMaterialRhiShader(alphaTexture, viewCount)
{
- setShaderFileName(VertexStage,
- QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldoutlinetext.vert.qsb"));
+ setShaderFileName(VertexStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldoutlinetext.vert.qsb"), viewCount);
if (alphaTexture)
- setShaderFileName(FragmentStage,
- QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag.qsb"));
+ setShaderFileName(FragmentStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldoutlinetext_a_fwidth.frag.qsb"), viewCount);
else
- setShaderFileName(FragmentStage,
- QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldoutlinetext.frag.qsb"));
+ setShaderFileName(FragmentStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldoutlinetext_fwidth.frag.qsb"), viewCount);
}
bool DistanceFieldOutlineTextMaterialRhiShader::updateUniformData(RenderState &state,
@@ -583,8 +352,8 @@ bool DistanceFieldOutlineTextMaterialRhiShader::updateUniformData(RenderState &s
float alphaMin = qMax(0.0f, base - range);
float styleAlphaMin0 = qMax(0.0f, outlineLimit - range);
float styleAlphaMin1 = qMin(outlineLimit + range, alphaMin);
- memcpy(buf->data() + 128, &styleAlphaMin0, 4);
- memcpy(buf->data() + 132, &styleAlphaMin1, 4);
+ memcpy(buf->data() + m_currentUbufOffset, &styleAlphaMin0, 4);
+ memcpy(buf->data() + m_currentUbufOffset + 4, &styleAlphaMin1, 4);
changed = true;
}
@@ -606,84 +375,30 @@ QSGMaterialType *QSGDistanceFieldOutlineTextMaterial::type() const
return &type;
}
-QSGMaterialShader *QSGDistanceFieldOutlineTextMaterial::createShader() const
+QSGMaterialShader *QSGDistanceFieldOutlineTextMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
{
- if (flags().testFlag(RhiShaderWanted))
- return new DistanceFieldOutlineTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled());
+ if (renderMode == QSGRendererInterface::RenderMode3D && m_glyph_cache->screenSpaceDerivativesSupported())
+ return new DistanceFieldAnisotropicOutlineTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled(), viewCount());
else
- return new DistanceFieldOutlineTextMaterialShader;
-}
-
-
-class DistanceFieldShiftedStyleTextMaterialShader : public DistanceFieldStyledTextMaterialShader
-{
-public:
- DistanceFieldShiftedStyleTextMaterialShader();
-
- void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
-
-protected:
- void initialize() override;
-
- void updateShift(qreal fontScale, const QPointF& shift);
-
- int m_shift_id = -1;
-};
-
-DistanceFieldShiftedStyleTextMaterialShader::DistanceFieldShiftedStyleTextMaterialShader()
- : DistanceFieldStyledTextMaterialShader()
-{
- setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/scenegraph/shaders/distancefieldshiftedtext.vert"));
- setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/distancefieldshiftedtext.frag"));
-}
-
-void DistanceFieldShiftedStyleTextMaterialShader::initialize()
-{
- DistanceFieldStyledTextMaterialShader::initialize();
- m_shift_id = program()->uniformLocation("shift");
-}
-
-void DistanceFieldShiftedStyleTextMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
-{
- DistanceFieldStyledTextMaterialShader::updateState(state, newEffect, oldEffect);
-
- QSGDistanceFieldShiftedStyleTextMaterial *material = static_cast<QSGDistanceFieldShiftedStyleTextMaterial *>(newEffect);
- QSGDistanceFieldShiftedStyleTextMaterial *oldMaterial = static_cast<QSGDistanceFieldShiftedStyleTextMaterial *>(oldEffect);
-
- if (oldMaterial == nullptr
- || oldMaterial->fontScale() != material->fontScale()
- || oldMaterial->shift() != material->shift()
- || oldMaterial->textureSize() != material->textureSize()) {
- updateShift(material->fontScale(), material->shift());
- }
-}
-
-void DistanceFieldShiftedStyleTextMaterialShader::updateShift(qreal fontScale, const QPointF &shift)
-{
- QPointF texel(1.0 / fontScale * shift.x(),
- 1.0 / fontScale * shift.y());
- program()->setUniformValue(m_shift_id, texel);
+ return new DistanceFieldOutlineTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled(), viewCount());
}
class DistanceFieldShiftedStyleTextMaterialRhiShader : public DistanceFieldStyledTextMaterialRhiShader
{
public:
- DistanceFieldShiftedStyleTextMaterialRhiShader(bool alphaTexture);
+ DistanceFieldShiftedStyleTextMaterialRhiShader(bool alphaTexture, int viewCount);
bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override;
};
-DistanceFieldShiftedStyleTextMaterialRhiShader::DistanceFieldShiftedStyleTextMaterialRhiShader(bool alphaTexture)
- : DistanceFieldStyledTextMaterialRhiShader(alphaTexture)
+DistanceFieldShiftedStyleTextMaterialRhiShader::DistanceFieldShiftedStyleTextMaterialRhiShader(bool alphaTexture, int viewCount)
+ : DistanceFieldStyledTextMaterialRhiShader(alphaTexture, viewCount)
{
- setShaderFileName(VertexStage,
- QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldshiftedtext.vert.qsb"));
+ setShaderFileName(VertexStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldshiftedtext.vert.qsb"), viewCount);
if (alphaTexture)
- setShaderFileName(FragmentStage,
- QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag.qsb"));
+ setShaderFileName(FragmentStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag.qsb"), viewCount);
else
- setShaderFileName(FragmentStage,
- QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldshiftedtext.frag.qsb"));
+ setShaderFileName(FragmentStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldshiftedtext.frag.qsb"), viewCount);
}
bool DistanceFieldShiftedStyleTextMaterialRhiShader::updateUniformData(RenderState &state,
@@ -699,15 +414,31 @@ bool DistanceFieldShiftedStyleTextMaterialRhiShader::updateUniformData(RenderSta
if (!oldMat || oldMat->fontScale() != mat->fontScale() || oldMat->shift() != mat->shift()
|| oldMat->textureSize() != mat->textureSize())
{
- QPointF shift(1.0 / mat->fontScale() * mat->shift().x(),
- 1.0 / mat->fontScale() * mat->shift().y());
- memcpy(buf->data() + 128, &shift, 8);
+ QVector2D shift(1.0 / mat->fontScale() * mat->shift().x(),
+ 1.0 / mat->fontScale() * mat->shift().y());
+ memcpy(buf->data() + m_currentUbufOffset, &shift, 8);
changed = true;
}
return changed;
}
+class DistanceFieldAnisotropicShiftedTextMaterialRhiShader : public DistanceFieldShiftedStyleTextMaterialRhiShader
+{
+public:
+ DistanceFieldAnisotropicShiftedTextMaterialRhiShader(bool alphaTexture, int viewCount);
+};
+
+DistanceFieldAnisotropicShiftedTextMaterialRhiShader::DistanceFieldAnisotropicShiftedTextMaterialRhiShader(bool alphaTexture, int viewCount)
+ : DistanceFieldShiftedStyleTextMaterialRhiShader(alphaTexture, viewCount)
+{
+ setShaderFileName(VertexStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldshiftedtext.vert.qsb"), viewCount);
+ if (alphaTexture)
+ setShaderFileName(FragmentStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldshiftedtext_a_fwidth.frag.qsb"), viewCount);
+ else
+ setShaderFileName(FragmentStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldshiftedtext_fwidth.frag.qsb"), viewCount);
+}
+
QSGDistanceFieldShiftedStyleTextMaterial::QSGDistanceFieldShiftedStyleTextMaterial()
: QSGDistanceFieldStyledTextMaterial()
{
@@ -723,12 +454,12 @@ QSGMaterialType *QSGDistanceFieldShiftedStyleTextMaterial::type() const
return &type;
}
-QSGMaterialShader *QSGDistanceFieldShiftedStyleTextMaterial::createShader() const
+QSGMaterialShader *QSGDistanceFieldShiftedStyleTextMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
{
- if (flags().testFlag(RhiShaderWanted))
- return new DistanceFieldShiftedStyleTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled());
+ if (renderMode == QSGRendererInterface::RenderMode3D && m_glyph_cache->screenSpaceDerivativesSupported())
+ return new DistanceFieldAnisotropicShiftedTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled(), viewCount());
else
- return new DistanceFieldShiftedStyleTextMaterialShader;
+ return new DistanceFieldShiftedStyleTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled(), viewCount());
}
int QSGDistanceFieldShiftedStyleTextMaterial::compare(const QSGMaterial *o) const
@@ -739,94 +470,25 @@ int QSGDistanceFieldShiftedStyleTextMaterial::compare(const QSGMaterial *o) cons
return QSGDistanceFieldStyledTextMaterial::compare(o);
}
-
-class QSGHiQSubPixelDistanceFieldTextMaterialShader : public QSGDistanceFieldTextMaterialShader
-{
-public:
- QSGHiQSubPixelDistanceFieldTextMaterialShader();
-
- void initialize() override;
- void activate() override;
- void deactivate() override;
- void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
-
-private:
- int m_fontScale_id = -1;
- int m_vecDelta_id = -1;
-};
-
-QSGHiQSubPixelDistanceFieldTextMaterialShader::QSGHiQSubPixelDistanceFieldTextMaterialShader()
- : QSGDistanceFieldTextMaterialShader()
-{
- setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/scenegraph/shaders/hiqsubpixeldistancefieldtext.vert"));
- setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/hiqsubpixeldistancefieldtext.frag"));
-}
-
-void QSGHiQSubPixelDistanceFieldTextMaterialShader::initialize()
-{
- QSGDistanceFieldTextMaterialShader::initialize();
- m_fontScale_id = program()->uniformLocation("fontScale");
- m_vecDelta_id = program()->uniformLocation("vecDelta");
-}
-
-void QSGHiQSubPixelDistanceFieldTextMaterialShader::activate()
-{
- QSGDistanceFieldTextMaterialShader::activate();
- QOpenGLContext::currentContext()->functions()->glBlendFunc(GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR);
-}
-
-void QSGHiQSubPixelDistanceFieldTextMaterialShader::deactivate()
-{
- QSGDistanceFieldTextMaterialShader::deactivate();
- QOpenGLContext::currentContext()->functions()->glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
-}
-
-void QSGHiQSubPixelDistanceFieldTextMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
-{
- Q_ASSERT(oldEffect == nullptr || newEffect->type() == oldEffect->type());
- QSGDistanceFieldTextMaterial *material = static_cast<QSGDistanceFieldTextMaterial *>(newEffect);
- QSGDistanceFieldTextMaterial *oldMaterial = static_cast<QSGDistanceFieldTextMaterial *>(oldEffect);
-
- if (oldMaterial == nullptr || material->color() != oldMaterial->color()) {
- QVector4D c = material->color();
- state.context()->functions()->glBlendColor(c.x(), c.y(), c.z(), 1.0f);
- }
-
- if (oldMaterial == nullptr || material->fontScale() != oldMaterial->fontScale())
- program()->setUniformValue(m_fontScale_id, GLfloat(material->fontScale()));
-
- if (oldMaterial == nullptr || state.isMatrixDirty()) {
- int viewportWidth = state.viewportRect().width();
- QMatrix4x4 mat = state.combinedMatrix().inverted();
- program()->setUniformValue(m_vecDelta_id, mat.column(0) * (qreal(2) / viewportWidth));
- }
-
- QSGDistanceFieldTextMaterialShader::updateState(state, newEffect, oldEffect);
-}
-
class QSGHiQSubPixelDistanceFieldTextMaterialRhiShader : public QSGDistanceFieldTextMaterialRhiShader
{
public:
- QSGHiQSubPixelDistanceFieldTextMaterialRhiShader(bool alphaTexture);
+ QSGHiQSubPixelDistanceFieldTextMaterialRhiShader(bool alphaTexture, int viewCount);
bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override;
bool updateGraphicsPipelineState(RenderState &state, GraphicsPipelineState *ps,
QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override;
};
-QSGHiQSubPixelDistanceFieldTextMaterialRhiShader::QSGHiQSubPixelDistanceFieldTextMaterialRhiShader(bool alphaTexture)
- : QSGDistanceFieldTextMaterialRhiShader(alphaTexture)
+QSGHiQSubPixelDistanceFieldTextMaterialRhiShader::QSGHiQSubPixelDistanceFieldTextMaterialRhiShader(bool alphaTexture, int viewCount)
+ : QSGDistanceFieldTextMaterialRhiShader(alphaTexture, viewCount)
{
setFlag(UpdatesGraphicsPipelineState, true);
-
- setShaderFileName(VertexStage,
- QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.vert.qsb"));
+ setShaderFileName(VertexStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.vert.qsb"), viewCount);
if (alphaTexture)
- setShaderFileName(FragmentStage,
- QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag.qsb"));
+ setShaderFileName(FragmentStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag.qsb"), viewCount);
else
- setShaderFileName(FragmentStage,
- QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag.qsb"));
+ setShaderFileName(FragmentStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag.qsb"), viewCount);
}
bool QSGHiQSubPixelDistanceFieldTextMaterialRhiShader::updateUniformData(RenderState &state,
@@ -841,15 +503,16 @@ bool QSGHiQSubPixelDistanceFieldTextMaterialRhiShader::updateUniformData(RenderS
if (!oldMat || mat->fontScale() != oldMat->fontScale()) {
float fontScale = mat->fontScale();
- memcpy(buf->data() + 104, &fontScale, 4);
+ memcpy(buf->data() + m_currentUbufOffset, &fontScale, 4);
changed = true;
}
+ m_currentUbufOffset += 4 + 4; // 4 for padding for vec2 alignment
if (!oldMat || state.isMatrixDirty()) {
int viewportWidth = state.viewportRect().width();
QMatrix4x4 mat = state.combinedMatrix().inverted();
QVector4D vecDelta = mat.column(0) * (qreal(2) / viewportWidth);
- memcpy(buf->data() + 112, &vecDelta, 16);
+ memcpy(buf->data() + m_currentUbufOffset, &vecDelta, 16);
}
return changed;
@@ -879,45 +542,28 @@ QSGMaterialType *QSGHiQSubPixelDistanceFieldTextMaterial::type() const
return &type;
}
-QSGMaterialShader *QSGHiQSubPixelDistanceFieldTextMaterial::createShader() const
+QSGMaterialShader *QSGHiQSubPixelDistanceFieldTextMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
{
- if (flags().testFlag(RhiShaderWanted))
- return new QSGHiQSubPixelDistanceFieldTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled());
+ if (renderMode == QSGRendererInterface::RenderMode3D && m_glyph_cache->screenSpaceDerivativesSupported())
+ return new DistanceFieldAnisotropicTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled(), viewCount());
else
- return new QSGHiQSubPixelDistanceFieldTextMaterialShader;
-}
-
-
-class QSGLoQSubPixelDistanceFieldTextMaterialShader : public QSGHiQSubPixelDistanceFieldTextMaterialShader
-{
-public:
- QSGLoQSubPixelDistanceFieldTextMaterialShader();
-};
-
-QSGLoQSubPixelDistanceFieldTextMaterialShader::QSGLoQSubPixelDistanceFieldTextMaterialShader()
- : QSGHiQSubPixelDistanceFieldTextMaterialShader()
-{
- setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/scenegraph/shaders/loqsubpixeldistancefieldtext.vert"));
- setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/loqsubpixeldistancefieldtext.frag"));
+ return new QSGHiQSubPixelDistanceFieldTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled(), viewCount());
}
class QSGLoQSubPixelDistanceFieldTextMaterialRhiShader : public QSGHiQSubPixelDistanceFieldTextMaterialRhiShader
{
public:
- QSGLoQSubPixelDistanceFieldTextMaterialRhiShader(bool alphaTexture);
+ QSGLoQSubPixelDistanceFieldTextMaterialRhiShader(bool alphaTexture, int viewCount);
};
-QSGLoQSubPixelDistanceFieldTextMaterialRhiShader::QSGLoQSubPixelDistanceFieldTextMaterialRhiShader(bool alphaTexture)
- : QSGHiQSubPixelDistanceFieldTextMaterialRhiShader(alphaTexture)
+QSGLoQSubPixelDistanceFieldTextMaterialRhiShader::QSGLoQSubPixelDistanceFieldTextMaterialRhiShader(bool alphaTexture, int viewCount)
+ : QSGHiQSubPixelDistanceFieldTextMaterialRhiShader(alphaTexture, viewCount)
{
- setShaderFileName(VertexStage,
- QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.vert.qsb"));
+ setShaderFileName(VertexStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.vert.qsb"), viewCount);
if (alphaTexture)
- setShaderFileName(FragmentStage,
- QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag.qsb"));
+ setShaderFileName(FragmentStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag.qsb"), viewCount);
else
- setShaderFileName(FragmentStage,
- QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag.qsb"));
+ setShaderFileName(FragmentStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag.qsb"), viewCount);
}
QSGMaterialType *QSGLoQSubPixelDistanceFieldTextMaterial::type() const
@@ -926,12 +572,12 @@ QSGMaterialType *QSGLoQSubPixelDistanceFieldTextMaterial::type() const
return &type;
}
-QSGMaterialShader *QSGLoQSubPixelDistanceFieldTextMaterial::createShader() const
+QSGMaterialShader *QSGLoQSubPixelDistanceFieldTextMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
{
- if (flags().testFlag(RhiShaderWanted))
- return new QSGLoQSubPixelDistanceFieldTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled());
+ if (renderMode == QSGRendererInterface::RenderMode3D && m_glyph_cache->screenSpaceDerivativesSupported())
+ return new DistanceFieldAnisotropicTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled(), viewCount());
else
- return new QSGLoQSubPixelDistanceFieldTextMaterialShader;
+ return new QSGLoQSubPixelDistanceFieldTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled(), viewCount());
}
QT_END_NAMESPACE