Anisotropic antialiasing for distance field text

For perspective transforms, we need to find the sample
range in the glyph cache per pixel. We can do this by
getting the gradient of the distance field at the
specific pixel.

This will ensure proper antialiasing with any
projection, but has the limitation that when glyph contours
become thinner than a pixel, they may disappear or become
too emphasized, because the hardware-gradient - based on
neighbouring fragments - is not reliable at that scale.
So we should only default to this when we detect that the
text is child of a 3D scene.

To make this smooth, we need to know the mode of the renderer
when creating the shader. So QSGMaterial::createShader()
now takes a render mode that we can use to customize behavior
based on whether it is rendering into a 2D or 3D scene.

[ChangeLog][QtQuick] The QSGMaterial::createShader() virtual
function has been extended to take a render mode argument,
which can be used for any customizations needed in the case
where the shader will be used in combination with 3D perspective
transformations.

Fixes: QTBUG-84695
Change-Id: I5a18a4edbdfa07e8f9d506c42bb20e8eb580927d
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
This commit is contained in:
Eskil Abrahamsen Blomfeldt 2020-06-09 10:57:35 +02:00
parent a8d357761d
commit 90bf30376c
46 changed files with 378 additions and 80 deletions

View File

@ -79,7 +79,7 @@ public:
return &type;
}
QSGMaterialShader *createShader() const override
QSGMaterialShader *createShader(QSGRendererInterface::RenderMode) const override
{
return new LineShader;
}

View File

@ -90,7 +90,7 @@ public:
return &type;
}
QSGMaterialShader *createShader() const override
QSGMaterialShader *createShader(QSGRendererInterface::RenderMode) const override
{
return new NoisyShader;
}

View File

@ -69,7 +69,7 @@ class XorBlendMaterial : public QSGMaterial
public:
XorBlendMaterial();
QSGMaterialType *type() const override;
QSGMaterialShader *createShader() const override;
QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const override;
int compare(const QSGMaterial *other) const override;
struct {
@ -93,7 +93,7 @@ XorBlendMaterial::XorBlendMaterial()
setFlag(Blending);
}
QSGMaterialShader *XorBlendMaterial::createShader() const
QSGMaterialShader *XorBlendMaterial::createShader(QSGRendererInterface::RenderMode) const
{
return new XorBlendRhiShader;
}

View File

@ -147,7 +147,8 @@ public:
class TabledMaterial : public ImageMaterial
{
public:
QSGMaterialShader *createShader() const override {
QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const override {
Q_UNUSED(renderMode);
return new TabledMaterialRhiShader;
}
QSGMaterialType *type() const override { return &m_type; }
@ -210,7 +211,8 @@ public:
class DeformableMaterial : public ImageMaterial
{
public:
QSGMaterialShader *createShader() const override {
QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const override {
Q_UNUSED(renderMode);
return new DeformableMaterialRhiShader;
}
QSGMaterialType *type() const override { return &m_type; }
@ -287,7 +289,8 @@ public:
class SpriteMaterial : public ImageMaterial
{
public:
QSGMaterialShader *createShader() const override {
QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const override {
Q_UNUSED(renderMode);
return new ParticleSpriteMaterialRhiShader;
}
QSGMaterialType *type() const override { return &m_type; }
@ -350,7 +353,8 @@ public:
class ColoredMaterial : public ImageMaterial
{
public:
QSGMaterialShader *createShader() const override {
QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const override {
Q_UNUSED(renderMode);
return new ColoredMaterialRhiShader;
}
QSGMaterialType *type() const override { return &m_type; }
@ -413,7 +417,8 @@ public:
class SimpleMaterial : public ImageMaterial
{
public:
QSGMaterialShader *createShader() const override {
QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const override {
Q_UNUSED(renderMode);
return new SimpleMaterialRhiShader;
}
QSGMaterialType *type() const override { return &m_type; }

View File

@ -240,10 +240,14 @@ QRhiGraphicsPipeline::Topology qsg_topology(int geomDrawMode)
return topology;
}
ShaderManager::Shader *ShaderManager::prepareMaterial(QSGMaterial *material, const QSGGeometry *geometry)
ShaderManager::Shader *ShaderManager::prepareMaterial(QSGMaterial *material,
const QSGGeometry *geometry,
QSGRendererInterface::RenderMode renderMode)
{
QSGMaterialType *type = material->type();
Shader *shader = rewrittenShaders.value(type, 0);
ShaderKey key = qMakePair(type, renderMode);
Shader *shader = rewrittenShaders.value(key, nullptr);
if (shader)
return shader;
@ -253,7 +257,7 @@ ShaderManager::Shader *ShaderManager::prepareMaterial(QSGMaterial *material, con
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphContextFrame);
shader = new Shader;
QSGMaterialShader *s = static_cast<QSGMaterialShader *>(material->createShader());
QSGMaterialShader *s = static_cast<QSGMaterialShader *>(material->createShader(renderMode));
context->initializeRhiShader(s, QShader::BatchableVertexShader);
shader->programRhi.program = s;
shader->programRhi.inputLayout = calculateVertexInputLayout(s, geometry, true);
@ -270,14 +274,18 @@ ShaderManager::Shader *ShaderManager::prepareMaterial(QSGMaterial *material, con
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphContextFrame,
QQuickProfiler::SceneGraphContextMaterialCompile);
rewrittenShaders[type] = shader;
rewrittenShaders[key] = shader;
return shader;
}
ShaderManager::Shader *ShaderManager::prepareMaterialNoRewrite(QSGMaterial *material, const QSGGeometry *geometry)
ShaderManager::Shader *ShaderManager::prepareMaterialNoRewrite(QSGMaterial *material,
const QSGGeometry *geometry,
QSGRendererInterface::RenderMode renderMode)
{
QSGMaterialType *type = material->type();
Shader *shader = stockShaders.value(type, 0);
ShaderKey key = qMakePair(type, renderMode);
Shader *shader = stockShaders.value(key, nullptr);
if (shader)
return shader;
@ -287,7 +295,7 @@ ShaderManager::Shader *ShaderManager::prepareMaterialNoRewrite(QSGMaterial *mate
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphContextFrame);
shader = new Shader;
QSGMaterialShader *s = static_cast<QSGMaterialShader *>(material->createShader());
QSGMaterialShader *s = static_cast<QSGMaterialShader *>(material->createShader(renderMode));
context->initializeRhiShader(s, QShader::StandardShader);
shader->programRhi.program = s;
shader->programRhi.inputLayout = calculateVertexInputLayout(s, geometry, false);
@ -299,7 +307,7 @@ ShaderManager::Shader *ShaderManager::prepareMaterialNoRewrite(QSGMaterial *mate
shader->lastOpacity = 0;
stockShaders[type] = shader;
stockShaders[key] = shader;
qCDebug(QSG_LOG_TIME_COMPILATION, "shader compiled in %dms (no rewrite)", (int) qsg_renderer_timer.elapsed());
@ -2971,8 +2979,8 @@ bool Renderer::prepareRenderMergedBatch(Batch *batch, PreparedRenderBatch *rende
updateClipState(gn->clipList(), batch);
const QSGGeometry *g = gn->geometry();
ShaderManager::Shader *sms = useDepthBuffer() ? m_shaderManager->prepareMaterial(material, g)
: m_shaderManager->prepareMaterialNoRewrite(material, g);
ShaderManager::Shader *sms = useDepthBuffer() ? m_shaderManager->prepareMaterial(material, g, m_renderMode)
: m_shaderManager->prepareMaterialNoRewrite(material, g, m_renderMode);
if (!sms)
return false;

View File

@ -696,12 +696,13 @@ public Q_SLOTS:
void invalidated();
public:
Shader *prepareMaterial(QSGMaterial *material, const QSGGeometry *geometry = nullptr);
Shader *prepareMaterialNoRewrite(QSGMaterial *material, const QSGGeometry *geometry = nullptr);
Shader *prepareMaterial(QSGMaterial *material, const QSGGeometry *geometry = nullptr, QSGRendererInterface::RenderMode renderMode = QSGRendererInterface::RenderMode2D);
Shader *prepareMaterialNoRewrite(QSGMaterial *material, const QSGGeometry *geometry = nullptr, QSGRendererInterface::RenderMode renderMode = QSGRendererInterface::RenderMode2D);
private:
QHash<QSGMaterialType *, Shader *> rewrittenShaders;
QHash<QSGMaterialType *, Shader *> stockShaders;
typedef QPair<QSGMaterialType *, QSGRendererInterface::RenderMode> ShaderKey;
QHash<ShaderKey, Shader *> rewrittenShaders;
QHash<ShaderKey, Shader *> stockShaders;
QSGDefaultRenderContext *context;

View File

@ -119,7 +119,7 @@ static void qt_print_material_count()
{
public:
QSGMaterialType *type() const { static QSGMaterialType type; return &type; }
QSGMaterialShader *createShader() const { return new Shader; }
QSGMaterialShader *createShader(QSGRendererInterface::RenderMode) const { return new Shader; }
};
\endcode
@ -239,14 +239,19 @@ int QSGMaterial::compare(const QSGMaterial *other) const
/*!
\fn QSGMaterialShader *QSGMaterial::createShader() const
\fn QSGMaterialShader *QSGMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
This function returns a new instance of a the QSGMaterialShader
implementatation used to render geometry for a specific implementation
implementation used to render geometry for a specific implementation
of QSGMaterial.
The function will be called only once for each material type that
exists in the scene graph and will be cached internally.
The function will be called only once for each combination of material type and \a renderMode
and will be cached internally.
For most materials, the \a renderMode can be ignored. A few materials may need
custom handling for specific render modes. For instance if the material implements
antialiasing in a way that needs to account for perspective transformations when
RenderMode3D is in use.
*/
QT_END_NAMESPACE

View File

@ -43,6 +43,7 @@
#include <QtQuick/qtquickglobal.h>
#include <QtQuick/qsgmaterialshader.h>
#include <QtQuick/qsgmaterialtype.h>
#include <QtQuick/qsgrendererinterface.h>
QT_BEGIN_NAMESPACE
@ -63,7 +64,7 @@ public:
virtual ~QSGMaterial();
virtual QSGMaterialType *type() const = 0;
virtual QSGMaterialShader *createShader() const = 0;
virtual QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const = 0;
virtual int compare(const QSGMaterial *other) const;
QSGMaterial::Flags flags() const { return m_flags; }

View File

@ -485,6 +485,7 @@ public:
virtual void processPendingGlyphs();
virtual bool eightBitFormatIsAlphaSwizzled() const = 0;
virtual bool screenSpaceDerivativesSupported() const = 0;
protected:
struct GlyphPosition {

View File

@ -564,8 +564,9 @@ QSGRhiTextureGlyphCache *QSGTextMaskMaterial::rhiGlyphCache() const
return static_cast<QSGRhiTextureGlyphCache *>(glyphCache());
}
QSGMaterialShader *QSGTextMaskMaterial::createShader() const
QSGMaterialShader *QSGTextMaskMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
{
Q_UNUSED(renderMode);
QSGRhiTextureGlyphCache *gc = rhiGlyphCache();
const QFontEngine::GlyphFormat glyphFormat = gc->glyphFormat();
switch (glyphFormat) {
@ -630,8 +631,9 @@ QSGMaterialType *QSGStyledTextMaterial::type() const
return &type;
}
QSGMaterialShader *QSGStyledTextMaterial::createShader() const
QSGMaterialShader *QSGStyledTextMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
{
Q_UNUSED(renderMode);
QSGRhiTextureGlyphCache *gc = rhiGlyphCache();
return new QSGStyledTextRhiShader(gc->glyphFormat(), gc->eightBitFormatIsAlphaSwizzled());
}
@ -661,8 +663,9 @@ QSGMaterialType *QSGOutlinedTextMaterial::type() const
return &type;
}
QSGMaterialShader *QSGOutlinedTextMaterial::createShader() const
QSGMaterialShader *QSGOutlinedTextMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
{
Q_UNUSED(renderMode);
QSGRhiTextureGlyphCache *gc = rhiGlyphCache();
return new QSGOutlinedTextRhiShader(gc->glyphFormat(), gc->eightBitFormatIsAlphaSwizzled());
}

View File

@ -76,7 +76,7 @@ public:
virtual ~QSGTextMaskMaterial();
QSGMaterialType *type() const override;
QSGMaterialShader *createShader() const override;
QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const override;
int compare(const QSGMaterial *other) const override;
void setColor(const QColor &c) { setColor(QVector4D(c.redF(), c.greenF(), c.blueF(), c.alphaF())); }
@ -122,7 +122,7 @@ public:
const QVector4D &styleColor() const { return m_styleColor; }
QSGMaterialType *type() const override;
QSGMaterialShader *createShader() const override;
QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const override;
int compare(const QSGMaterial *other) const override;
private:
@ -137,7 +137,7 @@ public:
~QSGOutlinedTextMaterial() { }
QSGMaterialType *type() const override;
QSGMaterialShader *createShader() const override;
QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const override;
};
QT_END_NAMESPACE

View File

@ -73,8 +73,9 @@ QSGMaterialType *QSGSmoothTextureMaterial::type() const
return &type;
}
QSGMaterialShader *QSGSmoothTextureMaterial::createShader() const
QSGMaterialShader *QSGSmoothTextureMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
{
Q_UNUSED(renderMode);
return new SmoothTextureMaterialRhiShader;
}

View File

@ -69,7 +69,7 @@ public:
protected:
QSGMaterialType *type() const override;
QSGMaterialShader *createShader() const override;
QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const override;
};
class Q_QUICK_PRIVATE_EXPORT QSGDefaultInternalImageNode : public QSGBasicInternalImageNode

View File

@ -112,8 +112,9 @@ QSGMaterialType *QSGSmoothColorMaterial::type() const
return &type;
}
QSGMaterialShader *QSGSmoothColorMaterial::createShader() const
QSGMaterialShader *QSGSmoothColorMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
{
Q_UNUSED(renderMode);
return new SmoothColorMaterialRhiShader;
}

View File

@ -69,7 +69,7 @@ public:
protected:
QSGMaterialType *type() const override;
QSGMaterialShader *createShader() const override;
QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const override;
};
class Q_QUICK_PRIVATE_EXPORT QSGDefaultInternalRectangleNode : public QSGBasicInternalRectangleNode

View File

@ -63,7 +63,7 @@ public:
QQuickSpriteMaterial();
~QQuickSpriteMaterial();
QSGMaterialType *type() const override { static QSGMaterialType type; return &type; }
QSGMaterialShader *createShader() const override;
QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const override;
QSGTexture *texture = nullptr;
@ -153,8 +153,9 @@ void SpriteMaterialRhiShader::updateSampledImage(RenderState &state, int binding
*texture = t;
}
QSGMaterialShader *QQuickSpriteMaterial::createShader() const
QSGMaterialShader *QQuickSpriteMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
{
Q_UNUSED(renderMode);
return new SpriteMaterialRhiShader;
}

View File

@ -89,6 +89,7 @@ QSGDistanceFieldTextMaterialRhiShader::QSGDistanceFieldTextMaterialRhiShader(boo
{
setShaderFileName(VertexStage,
QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldtext.vert.qsb"));
if (alphaTexture)
setShaderFileName(FragmentStage,
QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldtext_a.frag.qsb"));
@ -166,6 +167,25 @@ void QSGDistanceFieldTextMaterialRhiShader::updateSampledImage(RenderState &stat
*texture = t;
}
class DistanceFieldAnisotropicTextMaterialRhiShader : public QSGDistanceFieldTextMaterialRhiShader
{
public:
DistanceFieldAnisotropicTextMaterialRhiShader(bool alphaTexture);
};
DistanceFieldAnisotropicTextMaterialRhiShader::DistanceFieldAnisotropicTextMaterialRhiShader(bool alphaTexture)
: QSGDistanceFieldTextMaterialRhiShader(alphaTexture)
{
setShaderFileName(VertexStage,
QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldtext.vert.qsb"));
if (alphaTexture)
setShaderFileName(FragmentStage,
QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldtext_a_fwidth.frag.qsb"));
else
setShaderFileName(FragmentStage,
QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldtext_fwidth.frag.qsb"));
}
QSGDistanceFieldTextMaterial::QSGDistanceFieldTextMaterial()
: m_glyph_cache(nullptr)
, m_texture(nullptr)
@ -194,9 +214,12 @@ void QSGDistanceFieldTextMaterial::setColor(const QColor &color)
color.alphaF());
}
QSGMaterialShader *QSGDistanceFieldTextMaterial::createShader() const
QSGMaterialShader *QSGDistanceFieldTextMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
{
return new QSGDistanceFieldTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled());
if (renderMode == QSGRendererInterface::RenderMode3D && m_glyph_cache->screenSpaceDerivativesSupported())
return new DistanceFieldAnisotropicTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled());
else
return new QSGDistanceFieldTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled());
}
bool QSGDistanceFieldTextMaterial::updateTextureSize()
@ -245,7 +268,6 @@ int QSGDistanceFieldTextMaterial::compare(const QSGMaterial *o) const
const qintptr diff = t0 - t1;
return diff < 0 ? -1 : (diff > 0 ? 1 : 0);
}
class DistanceFieldStyledTextMaterialRhiShader : public QSGDistanceFieldTextMaterialRhiShader
{
public:
@ -318,6 +340,7 @@ DistanceFieldOutlineTextMaterialRhiShader::DistanceFieldOutlineTextMaterialRhiSh
{
setShaderFileName(VertexStage,
QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldoutlinetext.vert.qsb"));
if (alphaTexture)
setShaderFileName(FragmentStage,
QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag.qsb"));
@ -326,6 +349,25 @@ DistanceFieldOutlineTextMaterialRhiShader::DistanceFieldOutlineTextMaterialRhiSh
QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldoutlinetext.frag.qsb"));
}
class DistanceFieldAnisotropicOutlineTextMaterialRhiShader : public DistanceFieldOutlineTextMaterialRhiShader
{
public:
DistanceFieldAnisotropicOutlineTextMaterialRhiShader(bool alphaTexture);
};
DistanceFieldAnisotropicOutlineTextMaterialRhiShader::DistanceFieldAnisotropicOutlineTextMaterialRhiShader(bool alphaTexture)
: DistanceFieldOutlineTextMaterialRhiShader(alphaTexture)
{
setShaderFileName(VertexStage,
QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldoutlinetext.vert.qsb"));
if (alphaTexture)
setShaderFileName(FragmentStage,
QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldoutlinetext_a_fwidth.frag.qsb"));
else
setShaderFileName(FragmentStage,
QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldoutlinetext_fwidth.frag.qsb"));
}
bool DistanceFieldOutlineTextMaterialRhiShader::updateUniformData(RenderState &state,
QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
{
@ -368,9 +410,12 @@ QSGMaterialType *QSGDistanceFieldOutlineTextMaterial::type() const
return &type;
}
QSGMaterialShader *QSGDistanceFieldOutlineTextMaterial::createShader() const
QSGMaterialShader *QSGDistanceFieldOutlineTextMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
{
return new DistanceFieldOutlineTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled());
if (renderMode == QSGRendererInterface::RenderMode3D && m_glyph_cache->screenSpaceDerivativesSupported())
return new DistanceFieldAnisotropicOutlineTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled());
else
return new DistanceFieldOutlineTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled());
}
class DistanceFieldShiftedStyleTextMaterialRhiShader : public DistanceFieldStyledTextMaterialRhiShader
@ -416,6 +461,25 @@ bool DistanceFieldShiftedStyleTextMaterialRhiShader::updateUniformData(RenderSta
return changed;
}
class DistanceFieldAnisotropicShiftedTextMaterialRhiShader : public DistanceFieldShiftedStyleTextMaterialRhiShader
{
public:
DistanceFieldAnisotropicShiftedTextMaterialRhiShader(bool alphaTexture);
};
DistanceFieldAnisotropicShiftedTextMaterialRhiShader::DistanceFieldAnisotropicShiftedTextMaterialRhiShader(bool alphaTexture)
: DistanceFieldShiftedStyleTextMaterialRhiShader(alphaTexture)
{
setShaderFileName(VertexStage,
QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldshiftedtext.vert.qsb"));
if (alphaTexture)
setShaderFileName(FragmentStage,
QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldshiftedtext_a_fwidth.frag.qsb"));
else
setShaderFileName(FragmentStage,
QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/distancefieldshiftedtext_fwidth.frag.qsb"));
}
QSGDistanceFieldShiftedStyleTextMaterial::QSGDistanceFieldShiftedStyleTextMaterial()
: QSGDistanceFieldStyledTextMaterial()
{
@ -431,9 +495,12 @@ QSGMaterialType *QSGDistanceFieldShiftedStyleTextMaterial::type() const
return &type;
}
QSGMaterialShader *QSGDistanceFieldShiftedStyleTextMaterial::createShader() const
QSGMaterialShader *QSGDistanceFieldShiftedStyleTextMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
{
return new DistanceFieldShiftedStyleTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled());
if (renderMode == QSGRendererInterface::RenderMode3D && m_glyph_cache->screenSpaceDerivativesSupported())
return new DistanceFieldAnisotropicShiftedTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled());
else
return new DistanceFieldShiftedStyleTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled());
}
int QSGDistanceFieldShiftedStyleTextMaterial::compare(const QSGMaterial *o) const
@ -519,9 +586,12 @@ QSGMaterialType *QSGHiQSubPixelDistanceFieldTextMaterial::type() const
return &type;
}
QSGMaterialShader *QSGHiQSubPixelDistanceFieldTextMaterial::createShader() const
QSGMaterialShader *QSGHiQSubPixelDistanceFieldTextMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
{
return new QSGHiQSubPixelDistanceFieldTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled());
if (renderMode == QSGRendererInterface::RenderMode3D && m_glyph_cache->screenSpaceDerivativesSupported())
return new DistanceFieldAnisotropicTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled());
else
return new QSGHiQSubPixelDistanceFieldTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled());
}
class QSGLoQSubPixelDistanceFieldTextMaterialRhiShader : public QSGHiQSubPixelDistanceFieldTextMaterialRhiShader
@ -549,9 +619,12 @@ QSGMaterialType *QSGLoQSubPixelDistanceFieldTextMaterial::type() const
return &type;
}
QSGMaterialShader *QSGLoQSubPixelDistanceFieldTextMaterial::createShader() const
QSGMaterialShader *QSGLoQSubPixelDistanceFieldTextMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
{
return new QSGLoQSubPixelDistanceFieldTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled());
if (renderMode == QSGRendererInterface::RenderMode3D && m_glyph_cache->screenSpaceDerivativesSupported())
return new DistanceFieldAnisotropicTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled());
else
return new QSGLoQSubPixelDistanceFieldTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled());
}
QT_END_NAMESPACE

View File

@ -67,7 +67,7 @@ public:
~QSGDistanceFieldTextMaterial();
QSGMaterialType *type() const override;
QSGMaterialShader *createShader() const override;
QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const override;
int compare(const QSGMaterial *other) const override;
virtual void setColor(const QColor &color);
@ -104,7 +104,7 @@ public:
~QSGDistanceFieldStyledTextMaterial();
QSGMaterialType *type() const override = 0;
QSGMaterialShader *createShader() const override = 0;
QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const override = 0;
int compare(const QSGMaterial *other) const override;
void setStyleColor(const QColor &color);
@ -121,7 +121,7 @@ public:
~QSGDistanceFieldOutlineTextMaterial();
QSGMaterialType *type() const override;
QSGMaterialShader *createShader() const override;
QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const override;
};
class Q_QUICK_PRIVATE_EXPORT QSGDistanceFieldShiftedStyleTextMaterial : public QSGDistanceFieldStyledTextMaterial
@ -131,7 +131,7 @@ public:
~QSGDistanceFieldShiftedStyleTextMaterial();
QSGMaterialType *type() const override;
QSGMaterialShader *createShader() const override;
QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const override;
int compare(const QSGMaterial *other) const override;
void setShift(const QPointF &shift) { m_shift = shift; }
@ -145,7 +145,7 @@ class Q_QUICK_PRIVATE_EXPORT QSGHiQSubPixelDistanceFieldTextMaterial : public QS
{
public:
QSGMaterialType *type() const override;
QSGMaterialShader *createShader() const override;
QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const override;
void setColor(const QColor &color) override { m_color = QVector4D(color.redF(), color.greenF(), color.blueF(), color.alphaF()); }
};
@ -153,7 +153,7 @@ class Q_QUICK_PRIVATE_EXPORT QSGLoQSubPixelDistanceFieldTextMaterial : public QS
{
public:
QSGMaterialType *type() const override;
QSGMaterialShader *createShader() const override;
QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const override;
void setColor(const QColor &color) override { m_color = QVector4D(color.redF(), color.greenF(), color.blueF(), color.alphaF()); }
};

View File

@ -565,6 +565,11 @@ bool QSGRhiDistanceFieldGlyphCache::eightBitFormatIsAlphaSwizzled() const
return !m_rhi->isFeatureSupported(QRhi::RedOrAlpha8IsRed);
}
bool QSGRhiDistanceFieldGlyphCache::screenSpaceDerivativesSupported() const
{
return m_rhi->isFeatureSupported(QRhi::ScreenSpaceDerivatives);
}
#if defined(QSG_DISTANCEFIELD_CACHE_DEBUG)
void QSGRhiDistanceFieldGlyphCache::saveTexture(QRhiTexture *texture, const QString &nameBase) const
{

View File

@ -78,6 +78,7 @@ public:
void commitResourceUpdates(QRhiResourceUpdateBatch *mergeInto);
bool eightBitFormatIsAlphaSwizzled() const override;
bool screenSpaceDerivativesSupported() const override;
#if defined(QSG_DISTANCEFIELD_CACHE_DEBUG)
void saveTexture(QRhiTexture *texture, const QString &nameBase) const override;

View File

@ -519,8 +519,9 @@ QSGMaterialType *QSGRhiShaderEffectMaterial::type() const
return m_materialType;
}
QSGMaterialShader *QSGRhiShaderEffectMaterial::createShader() const
QSGMaterialShader *QSGRhiShaderEffectMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
{
Q_UNUSED(renderMode);
return new QSGRhiShaderEffectMaterialShader(this);
}

View File

@ -102,7 +102,7 @@ public:
int compare(const QSGMaterial *other) const override;
QSGMaterialType *type() const override;
QSGMaterialShader *createShader() const override;
QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const override;
void updateTextureProviders(bool layoutChange);

View File

@ -30,13 +30,19 @@
<file>shaders_ng/distancefieldtext.vert.qsb</file>
<file>shaders_ng/distancefieldtext.frag.qsb</file>
<file>shaders_ng/distancefieldtext_fwidth.frag.qsb</file>
<file>shaders_ng/distancefieldtext_a.frag.qsb</file>
<file>shaders_ng/distancefieldtext_a_fwidth.frag.qsb</file>
<file>shaders_ng/distancefieldshiftedtext.vert.qsb</file>
<file>shaders_ng/distancefieldshiftedtext.frag.qsb</file>
<file>shaders_ng/distancefieldshiftedtext_fwidth.frag.qsb</file>
<file>shaders_ng/distancefieldshiftedtext_a.frag.qsb</file>
<file>shaders_ng/distancefieldshiftedtext_a_fwidth.frag.qsb</file>
<file>shaders_ng/distancefieldoutlinetext.vert.qsb</file>
<file>shaders_ng/distancefieldoutlinetext.frag.qsb</file>
<file>shaders_ng/distancefieldoutlinetext_fwidth.frag.qsb</file>
<file>shaders_ng/distancefieldoutlinetext_a.frag.qsb</file>
<file>shaders_ng/distancefieldoutlinetext_a_fwidth.frag.qsb</file>
<file>shaders_ng/hiqsubpixeldistancefieldtext.vert.qsb</file>
<file>shaders_ng/hiqsubpixeldistancefieldtext.frag.qsb</file>
<file>shaders_ng/hiqsubpixeldistancefieldtext_a.frag.qsb</file>

View File

@ -68,13 +68,19 @@ qsb --glsl "150,120,100 es" --hlsl 50 -c --msl 12 -o styledtext.frag.qsb styledt
qsb --glsl "150,120,100 es" -o styledtext_a.frag.qsb styledtext_a.frag
qsb -b --glsl "150,120,100 es" --hlsl 50 -c --msl 12 -o distancefieldtext.vert.qsb distancefieldtext.vert
qsb --glsl "150,120,100 es" --hlsl 50 -c --msl 12 -o distancefieldtext.frag.qsb distancefieldtext.frag
qsb --glsl "150,120,100 es" --hlsl 50 -c --msl 12 -o distancefieldtext_fwidth.frag.qsb distancefieldtext_fwidth.frag
qsb --glsl "150,120,100 es" --hlsl 50 -c --msl 12 -o distancefieldtext_a.frag.qsb distancefieldtext_a.frag
qsb --glsl "150,120,100 es" --hlsl 50 -c --msl 12 -o distancefieldtext_a_fwidth.frag.qsb distancefieldtext_a_fwidth.frag
qsb -b --glsl "150,120,100 es" --hlsl 50 -c --msl 12 -o distancefieldshiftedtext.vert.qsb distancefieldshiftedtext.vert
qsb --glsl "150,120,100 es" --hlsl 50 -c --msl 12 -o distancefieldshiftedtext.frag.qsb distancefieldshiftedtext.frag
qsb --glsl "150,120,100 es" --hlsl 50 -c --msl 12 -o distancefieldshiftedtext_fwidth.frag.qsb distancefieldshiftedtext_fwidth.frag
qsb --glsl "150,120,100 es" --hlsl 50 -c --msl 12 -o distancefieldshiftedtext_a.frag.qsb distancefieldshiftedtext_a.frag
qsb --glsl "150,120,100 es" --hlsl 50 -c --msl 12 -o distancefieldshiftedtext_a_fwidth.frag.qsb distancefieldshiftedtext_a_fwidth.frag
qsb -b --glsl "150,120,100 es" --hlsl 50 -c --msl 12 -o distancefieldoutlinetext.vert.qsb distancefieldoutlinetext.vert
qsb --glsl "150,120,100 es" --hlsl 50 -c --msl 12 -o distancefieldoutlinetext.frag.qsb distancefieldoutlinetext.frag
qsb --glsl "150,120,100 es" --hlsl 50 -c --msl 12 -o distancefieldoutlinetext_fwidth.frag.qsb distancefieldoutlinetext_fwidth.frag
qsb --glsl "150,120,100 es" --hlsl 50 -c --msl 12 -o distancefieldoutlinetext_a.frag.qsb distancefieldoutlinetext_a.frag
qsb --glsl "150,120,100 es" --hlsl 50 -c --msl 12 -o distancefieldoutlinetext_a_fwidth.frag.qsb distancefieldoutlinetext_a_fwidth.frag
qsb -b --glsl "150,120,100 es" --hlsl 50 -c --msl 12 -o hiqsubpixeldistancefieldtext.vert.qsb hiqsubpixeldistancefieldtext.vert
qsb --glsl "150,120,100 es" --hlsl 50 -c --msl 12 -o hiqsubpixeldistancefieldtext.frag.qsb hiqsubpixeldistancefieldtext.frag
qsb --glsl "150,120,100 es" --hlsl 50 -c --msl 12 -o hiqsubpixeldistancefieldtext_a.frag.qsb hiqsubpixeldistancefieldtext_a.frag

View File

@ -19,7 +19,8 @@ layout(std140, binding = 0) uniform buf {
void main()
{
float d = texture(_qt_texture, sampleCoord).r;
fragColor = mix(ubuf.styleColor, ubuf.color, smoothstep(ubuf.alphaMin, ubuf.alphaMax, d))
* smoothstep(ubuf.outlineAlphaMax0, ubuf.outlineAlphaMax1, d);
float distance = texture(_qt_texture, sampleCoord).r;
float f = fwidth(distance);
fragColor = mix(ubuf.styleColor, ubuf.color, smoothstep(0.5 - f, 0.5 + f, distance))
* smoothstep(ubuf.outlineAlphaMax0, ubuf.outlineAlphaMax1, distance);
}

View File

@ -19,7 +19,8 @@ layout(std140, binding = 0) uniform buf {
void main()
{
float d = texture(_qt_texture, sampleCoord).a;
fragColor = mix(ubuf.styleColor, ubuf.color, smoothstep(ubuf.alphaMin, ubuf.alphaMax, d))
* smoothstep(ubuf.outlineAlphaMax0, ubuf.outlineAlphaMax1, d);
float distance = texture(_qt_texture, sampleCoord).a;
float f = fwidth(distance);
fragColor = mix(ubuf.styleColor, ubuf.color, smoothstep(0.5 - f, 0.5 + f, distance))
* smoothstep(ubuf.outlineAlphaMax0, ubuf.outlineAlphaMax1, distance);
}

View File

@ -0,0 +1,31 @@
#version 440
layout(location = 0) in vec2 sampleCoord;
layout(location = 0) out vec4 fragColor;
layout(binding = 1) uniform sampler2D _qt_texture;
layout(std140, binding = 0) uniform buf {
mat4 matrix;
vec2 textureScale;
vec4 color;
float alphaMin;
float alphaMax;
// up to this point it must match distancefieldtext
vec4 styleColor;
float outlineAlphaMax0;
float outlineAlphaMax1;
} ubuf;
void main()
{
float distance = texture(_qt_texture, sampleCoord).a;
float f = fwidth(distance);
// The outlineLimit is based on font size, but scales with the transform, so
// we can calculate it from the outline span.
float outlineLimit = (ubuf.outlineAlphaMax1 - ubuf.outlineAlphaMax0) / 2.0 + ubuf.outlineAlphaMax0;
fragColor = mix(ubuf.styleColor, ubuf.color, smoothstep(max(0.0, 0.5 - f), min(1.0, 0.5 + f), distance))
* smoothstep(max(0.0, outlineLimit - f), min(outlineLimit + f, 0.5 - f), distance);
}

View File

@ -0,0 +1,31 @@
#version 440
layout(location = 0) in vec2 sampleCoord;
layout(location = 0) out vec4 fragColor;
layout(binding = 1) uniform sampler2D _qt_texture;
layout(std140, binding = 0) uniform buf {
mat4 matrix;
vec2 textureScale;
vec4 color;
float alphaMin;
float alphaMax;
// up to this point it must match distancefieldtext
vec4 styleColor;
float outlineAlphaMax0;
float outlineAlphaMax1;
} ubuf;
void main()
{
float distance = texture(_qt_texture, sampleCoord).r;
float f = fwidth(distance);
// The outlineLimit is based on font size, but scales with the transform, so
// we can calculate it from the outline span.
float outlineLimit = (ubuf.outlineAlphaMax1 - ubuf.outlineAlphaMax0) / 2.0 + ubuf.outlineAlphaMax0;
fragColor = mix(ubuf.styleColor, ubuf.color, smoothstep(max(0.0, 0.5 - f), min(1.0, 0.5 + f), distance))
* smoothstep(max(0.0, outlineLimit - f), min(outlineLimit + f, 0.5 - f), distance);
}

View File

@ -0,0 +1,33 @@
#version 440
layout(location = 0) in vec2 sampleCoord;
layout(location = 1) in vec2 shiftedSampleCoord;
layout(location = 0) out vec4 fragColor;
layout(binding = 1) uniform sampler2D _qt_texture;
layout(std140, binding = 0) uniform buf {
mat4 matrix;
vec2 textureScale;
vec4 color;
float alphaMin;
float alphaMax;
// up to this point it must match distancefieldtext
vec4 styleColor;
vec2 shift;
} ubuf;
void main()
{
float distance = texture(_qt_texture, sampleCoord).a;
float f = fwidth(distance);
float a = smoothstep(0.5 - f, 0.5 + f, distance);
float shiftedDistance = texture(_qt_texture, shiftedSampleCoord).a;
float shiftedF = fwidth(shiftedDistance);
float shiftedA = smoothstep(0.5 - shiftedF, 0.5 + shiftedF, shiftedDistance);
vec4 shifted = ubuf.styleColor * shiftedA;
fragColor = mix(shifted, ubuf.color, a);
}

View File

@ -0,0 +1,33 @@
#version 440
layout(location = 0) in vec2 sampleCoord;
layout(location = 1) in vec2 shiftedSampleCoord;
layout(location = 0) out vec4 fragColor;
layout(binding = 1) uniform sampler2D _qt_texture;
layout(std140, binding = 0) uniform buf {
mat4 matrix;
vec2 textureScale;
vec4 color;
float alphaMin;
float alphaMax;
// up to this point it must match distancefieldtext
vec4 styleColor;
vec2 shift;
} ubuf;
void main()
{
float distance = texture(_qt_texture, sampleCoord).r;
float f = fwidth(distance);
float a = smoothstep(0.5 - f, 0.5 + f, distance);
float shiftedDistance = texture(_qt_texture, shiftedSampleCoord).r;
float shiftedF = fwidth(shiftedDistance);
float shiftedA = smoothstep(0.5 - shiftedF, 0.5 + shiftedF, shiftedDistance);
vec4 shifted = ubuf.styleColor * shiftedA;
fragColor = mix(shifted, ubuf.color, a);
}

View File

@ -0,0 +1,21 @@
#version 440
layout(location = 0) in vec2 sampleCoord;
layout(location = 0) out vec4 fragColor;
layout(binding = 1) uniform sampler2D _qt_texture;
layout(std140, binding = 0) uniform buf {
mat4 matrix;
vec2 textureScale;
vec4 color;
float alphaMin;
float alphaMax;
} ubuf;
void main()
{
float distance = texture(_qt_texture, sampleCoord).a;
float f = fwidth(distance);
fragColor = ubuf.color * smoothstep(max(0.0, 0.5 - f), min(1.0, 0.5 + f), distance);
}

View File

@ -0,0 +1,21 @@
#version 440
layout(location = 0) in vec2 sampleCoord;
layout(location = 0) out vec4 fragColor;
layout(binding = 1) uniform sampler2D _qt_texture;
layout(std140, binding = 0) uniform buf {
mat4 matrix;
vec2 textureScale;
vec4 color;
float alphaMin;
float alphaMax;
} ubuf;
void main()
{
float distance = texture(_qt_texture, sampleCoord).r;
float f = fwidth(distance);
fragColor = ubuf.color * smoothstep(max(0.0, 0.5 - f), min(1.0, 0.5 + f), distance);
}

View File

@ -164,8 +164,9 @@ QSGMaterialType *QSGFlatColorMaterial::type() const
\internal
*/
QSGMaterialShader *QSGFlatColorMaterial::createShader() const
QSGMaterialShader *QSGFlatColorMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
{
Q_UNUSED(renderMode);
return new FlatColorMaterialRhiShader;
}

View File

@ -50,7 +50,7 @@ class Q_QUICK_EXPORT QSGFlatColorMaterial : public QSGMaterial
public:
QSGFlatColorMaterial();
QSGMaterialType *type() const override;
QSGMaterialShader *createShader() const override;
QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const override;
void setColor(const QColor &color);
const QColor &color() const { return m_color; }

View File

@ -171,8 +171,9 @@ QSGMaterialType *QSGOpaqueTextureMaterial::type() const
/*!
\internal
*/
QSGMaterialShader *QSGOpaqueTextureMaterial::createShader() const
QSGMaterialShader *QSGOpaqueTextureMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
{
Q_UNUSED(renderMode);
return new QSGOpaqueTextureMaterialRhiShader;
}
@ -359,8 +360,9 @@ QSGMaterialType *QSGTextureMaterial::type() const
\internal
*/
QSGMaterialShader *QSGTextureMaterial::createShader() const
QSGMaterialShader *QSGTextureMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
{
Q_UNUSED(renderMode);
return new QSGTextureMaterialRhiShader;
}

View File

@ -51,7 +51,7 @@ public:
QSGOpaqueTextureMaterial();
QSGMaterialType *type() const override;
QSGMaterialShader *createShader() const override;
QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const override;
int compare(const QSGMaterial *other) const override;
void setTexture(QSGTexture *texture);
@ -88,7 +88,7 @@ class Q_QUICK_EXPORT QSGTextureMaterial : public QSGOpaqueTextureMaterial
{
public:
QSGMaterialType *type() const override;
QSGMaterialShader *createShader() const override;
QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const override;
};
QT_END_NAMESPACE

View File

@ -147,8 +147,9 @@ QSGMaterialType *QSGVertexColorMaterial::type() const
\internal
*/
QSGMaterialShader *QSGVertexColorMaterial::createShader() const
QSGMaterialShader *QSGVertexColorMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
{
Q_UNUSED(renderMode);
return new QSGVertexColorMaterialRhiShader;
}

View File

@ -53,7 +53,7 @@ public:
protected:
QSGMaterialType *type() const override;
QSGMaterialShader *createShader() const override;
QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const override;
};
QT_END_NAMESPACE

View File

@ -856,8 +856,9 @@ int QQuickShapeLinearGradientMaterial::compare(const QSGMaterial *other) const
return 0;
}
QSGMaterialShader *QQuickShapeLinearGradientMaterial::createShader() const
QSGMaterialShader *QQuickShapeLinearGradientMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
{
Q_UNUSED(renderMode);
return new QQuickShapeLinearGradientRhiShader;
}
@ -989,8 +990,9 @@ int QQuickShapeRadialGradientMaterial::compare(const QSGMaterial *other) const
return 0;
}
QSGMaterialShader *QQuickShapeRadialGradientMaterial::createShader() const
QSGMaterialShader *QQuickShapeRadialGradientMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
{
Q_UNUSED(renderMode);
return new QQuickShapeRadialGradientRhiShader;
}
@ -1097,8 +1099,9 @@ int QQuickShapeConicalGradientMaterial::compare(const QSGMaterial *other) const
return 0;
}
QSGMaterialShader *QQuickShapeConicalGradientMaterial::createShader() const
QSGMaterialShader *QQuickShapeConicalGradientMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
{
Q_UNUSED(renderMode);
return new QQuickShapeConicalGradientRhiShader;
}

View File

@ -274,7 +274,7 @@ public:
QSGMaterialType *type() const override;
int compare(const QSGMaterial *other) const override;
QSGMaterialShader *createShader() const override;
QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const override;
QQuickShapeGenericStrokeFillNode *node() const { return m_node; }
@ -310,7 +310,7 @@ public:
QSGMaterialType *type() const override;
int compare(const QSGMaterial *other) const override;
QSGMaterialShader *createShader() const override;
QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const override;
QQuickShapeGenericStrokeFillNode *node() const { return m_node; }
@ -344,7 +344,7 @@ public:
QSGMaterialType *type() const override;
int compare(const QSGMaterial *other) const override;
QSGMaterialShader *createShader() const override;
QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const override;
QQuickShapeGenericStrokeFillNode *node() const { return m_node; }