aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/scenegraph
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2020-08-12 09:27:03 +0200
committerEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2020-08-17 07:09:31 +0200
commitcbbbfe3bff29d8db84771e07ac6f16209b0969d1 (patch)
treea37c1a23cadc6ae6a0d8e367d0b582768e943e6a /src/quick/scenegraph
parent0cb02b7ee0f72674640ffe5a0fabc1dacc259de0 (diff)
Add renderTypeQuality property to Text element
For large scale text, the default distance field size gives artifacts on certain font features. We already have an environment variable which overrides this on an application level, but this will cause all distance fields to be rendered at the high resolution, whereas you may just want it for one particular text field. Since this becomes an especially important use case now that we can embed the text fields in a 3D scene, we add a property which can be used to tweak the base font size used for generating the distance fields. [ChangeLog][QtQuick][Text] Added "renderTypeQuality" property, which can be used in cases of very large fonts, where Qt's font rasterization may show some rendering artifacts when using the default quality. Fixes: QTBUG-84696 Change-Id: Ie4205e82cf441562dcc65a8e432a941a3baeddf3 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src/quick/scenegraph')
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp3
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarecontext_p.h2
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer.cpp12
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer_p.h10
-rw-r--r--src/quick/scenegraph/qsgcontext.cpp2
-rw-r--r--src/quick/scenegraph/qsgcontext_p.h4
-rw-r--r--src/quick/scenegraph/qsgdefaultcontext.cpp5
-rw-r--r--src/quick/scenegraph/qsgdefaultcontext_p.h2
-rw-r--r--src/quick/scenegraph/qsgdefaultrendercontext.cpp25
-rw-r--r--src/quick/scenegraph/qsgdefaultrendercontext_p.h4
-rw-r--r--src/quick/scenegraph/qsgdistancefieldglyphnode.cpp11
-rw-r--r--src/quick/scenegraph/qsgdistancefieldglyphnode_p.h2
-rw-r--r--src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp6
-rw-r--r--src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h2
14 files changed, 60 insertions, 30 deletions
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
index cb2af431f8..4ddef6b4c2 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
@@ -111,10 +111,11 @@ QSGPainterNode *QSGSoftwareContext::createPainterNode(QQuickPaintedItem *item)
return new QSGSoftwarePainterNode(item);
}
-QSGGlyphNode *QSGSoftwareContext::createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode)
+QSGGlyphNode *QSGSoftwareContext::createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode, int renderTypeQuality)
{
Q_UNUSED(rc);
Q_UNUSED(preferNativeGlyphNode);
+ Q_UNUSED(renderTypeQuality);
return new QSGSoftwareGlyphNode();
}
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext_p.h
index feb664cfd1..23e1867f09 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext_p.h
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext_p.h
@@ -91,7 +91,7 @@ public:
QSGInternalRectangleNode *createInternalRectangleNode() override;
QSGInternalImageNode *createInternalImageNode(QSGRenderContext *renderContext) override;
QSGPainterNode *createPainterNode(QQuickPaintedItem *item) override;
- QSGGlyphNode *createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode) override;
+ QSGGlyphNode *createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode, int renderTypeQuality) override;
QSGLayer *createLayer(QSGRenderContext *renderContext) override;
QSurfaceFormat defaultSurfaceFormat() const override;
QSGRendererInterface *rendererInterface(QSGRenderContext *renderContext) override;
diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp
index 226c580fb2..9d18868c58 100644
--- a/src/quick/scenegraph/qsgadaptationlayer.cpp
+++ b/src/quick/scenegraph/qsgadaptationlayer.cpp
@@ -58,8 +58,9 @@ static QElapsedTimer qsg_render_timer;
QSGDistanceFieldGlyphCache::Texture QSGDistanceFieldGlyphCache::s_emptyTexture;
-QSGDistanceFieldGlyphCache::QSGDistanceFieldGlyphCache(const QRawFont &font)
- : m_pendingGlyphs(64)
+QSGDistanceFieldGlyphCache::QSGDistanceFieldGlyphCache(const QRawFont &font, int renderTypeQuality)
+ : m_renderTypeQuality(renderTypeQuality)
+ , m_pendingGlyphs(64)
{
Q_ASSERT(font.isValid());
@@ -71,7 +72,7 @@ QSGDistanceFieldGlyphCache::QSGDistanceFieldGlyphCache(const QRawFont &font)
m_referenceFont = font;
// we set the same pixel size as used by the distance field internally.
// this allows us to call pathForGlyph once and reuse the result.
- m_referenceFont.setPixelSize(QT_DISTANCEFIELD_BASEFONTSIZE(m_doubleGlyphResolution) * QT_DISTANCEFIELD_SCALE(m_doubleGlyphResolution));
+ m_referenceFont.setPixelSize(baseFontSize() * QT_DISTANCEFIELD_SCALE(m_doubleGlyphResolution));
Q_ASSERT(m_referenceFont.isValid());
}
@@ -79,6 +80,11 @@ QSGDistanceFieldGlyphCache::~QSGDistanceFieldGlyphCache()
{
}
+int QSGDistanceFieldGlyphCache::baseFontSize() const
+{
+ return m_renderTypeQuality > 0 ? m_renderTypeQuality : QT_DISTANCEFIELD_BASEFONTSIZE(m_doubleGlyphResolution);
+}
+
QSGDistanceFieldGlyphCache::GlyphData &QSGDistanceFieldGlyphCache::emptyData(glyph_t glyph)
{
GlyphData gd;
diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h
index a59d11430e..020ba3aa4c 100644
--- a/src/quick/scenegraph/qsgadaptationlayer_p.h
+++ b/src/quick/scenegraph/qsgadaptationlayer_p.h
@@ -396,6 +396,7 @@ public:
virtual void setBoundingRect(const QRectF &bounds) { m_bounding_rect = bounds; }
virtual void setPreferredAntialiasingMode(AntialiasingMode) = 0;
+ virtual void setRenderTypeQuality(int renderTypeQuality) { Q_UNUSED(renderTypeQuality) }
virtual void update() = 0;
@@ -421,7 +422,8 @@ typedef QIntrusiveList<QSGDistanceFieldGlyphConsumer, &QSGDistanceFieldGlyphCons
class Q_QUICK_PRIVATE_EXPORT QSGDistanceFieldGlyphCache
{
public:
- QSGDistanceFieldGlyphCache(const QRawFont &font);
+ QSGDistanceFieldGlyphCache(const QRawFont &font,
+ int renderTypeQuality);
virtual ~QSGDistanceFieldGlyphCache();
struct Metrics {
@@ -460,7 +462,7 @@ public:
qreal fontScale(qreal pixelSize) const
{
- return pixelSize / QT_DISTANCEFIELD_BASEFONTSIZE(m_doubleGlyphResolution);
+ return pixelSize / baseFontSize();
}
int distanceFieldRadius() const
{
@@ -468,6 +470,7 @@ public:
}
int glyphCount() const { return m_glyphCount; }
bool doubleGlyphResolution() const { return m_doubleGlyphResolution; }
+ int renderTypeQuality() const { return m_renderTypeQuality; }
Metrics glyphMetrics(glyph_t glyph, qreal pixelSize);
inline TexCoord glyphTexCoord(glyph_t glyph);
@@ -521,11 +524,14 @@ protected:
GlyphData &glyphData(glyph_t glyph);
GlyphData &emptyData(glyph_t glyph);
+ int baseFontSize() const;
+
#if defined(QSG_DISTANCEFIELD_CACHE_DEBUG)
virtual void saveTexture(QRhiTexture *texture, const QString &nameBase) const = 0;
#endif
bool m_doubleGlyphResolution;
+ int m_renderTypeQuality;
protected:
QRawFont m_referenceFont;
diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp
index d550b2c66a..3275efdb15 100644
--- a/src/quick/scenegraph/qsgcontext.cpp
+++ b/src/quick/scenegraph/qsgcontext.cpp
@@ -407,7 +407,7 @@ void QSGRenderContext::preprocess()
/*!
Factory function for scene graph backends of the distance-field glyph cache.
*/
-QSGDistanceFieldGlyphCache *QSGRenderContext::distanceFieldGlyphCache(const QRawFont &)
+QSGDistanceFieldGlyphCache *QSGRenderContext::distanceFieldGlyphCache(const QRawFont &, int)
{
return nullptr;
}
diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h
index fc3e3fc854..730a40f24b 100644
--- a/src/quick/scenegraph/qsgcontext_p.h
+++ b/src/quick/scenegraph/qsgcontext_p.h
@@ -127,7 +127,7 @@ public:
virtual QSGInternalRectangleNode *createInternalRectangleNode() = 0;
virtual QSGInternalImageNode *createInternalImageNode(QSGRenderContext *renderContext) = 0;
virtual QSGPainterNode *createPainterNode(QQuickPaintedItem *item) = 0;
- virtual QSGGlyphNode *createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode) = 0;
+ virtual QSGGlyphNode *createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode, int renderTypeQuality) = 0;
virtual QSGLayer *createLayer(QSGRenderContext *renderContext) = 0;
virtual QSGGuiThreadShaderEffectManager *createGuiThreadShaderEffectManager();
virtual QSGShaderEffectNode *createShaderEffectNode(QSGRenderContext *renderContext);
@@ -197,7 +197,7 @@ public:
virtual void endSync();
virtual void preprocess();
- virtual QSGDistanceFieldGlyphCache *distanceFieldGlyphCache(const QRawFont &font);
+ virtual QSGDistanceFieldGlyphCache *distanceFieldGlyphCache(const QRawFont &font, int renderTypeQuality);
QSGTexture *textureForFactory(QQuickTextureFactory *factory, QQuickWindow *window);
virtual QSGTexture *createTexture(const QImage &image, uint flags = CreateTexture_Alpha) const = 0;
diff --git a/src/quick/scenegraph/qsgdefaultcontext.cpp b/src/quick/scenegraph/qsgdefaultcontext.cpp
index 37674eb19c..2df9c50898 100644
--- a/src/quick/scenegraph/qsgdefaultcontext.cpp
+++ b/src/quick/scenegraph/qsgdefaultcontext.cpp
@@ -181,13 +181,16 @@ QSGPainterNode *QSGDefaultContext::createPainterNode(QQuickPaintedItem *item)
return new QSGDefaultPainterNode(item);
}
-QSGGlyphNode *QSGDefaultContext::createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode)
+QSGGlyphNode *QSGDefaultContext::createGlyphNode(QSGRenderContext *rc,
+ bool preferNativeGlyphNode,
+ int renderTypeQuality)
{
if (m_distanceFieldDisabled || preferNativeGlyphNode) {
return new QSGDefaultGlyphNode(rc);
} else {
QSGDistanceFieldGlyphNode *node = new QSGDistanceFieldGlyphNode(rc);
node->setPreferredAntialiasingMode(m_distanceFieldAntialiasing);
+ node->setRenderTypeQuality(renderTypeQuality);
return node;
}
}
diff --git a/src/quick/scenegraph/qsgdefaultcontext_p.h b/src/quick/scenegraph/qsgdefaultcontext_p.h
index 414a4151f1..5c840895da 100644
--- a/src/quick/scenegraph/qsgdefaultcontext_p.h
+++ b/src/quick/scenegraph/qsgdefaultcontext_p.h
@@ -69,7 +69,7 @@ public:
QSGInternalRectangleNode *createInternalRectangleNode() override;
QSGInternalImageNode *createInternalImageNode(QSGRenderContext *renderContext) override;
QSGPainterNode *createPainterNode(QQuickPaintedItem *item) override;
- QSGGlyphNode *createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode) override;
+ QSGGlyphNode *createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode, int renderTypeQuality) override;
QSGLayer *createLayer(QSGRenderContext *renderContext) override;
QSurfaceFormat defaultSurfaceFormat() const override;
QSGRendererInterface *rendererInterface(QSGRenderContext *renderContext) override;
diff --git a/src/quick/scenegraph/qsgdefaultrendercontext.cpp b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
index 6dbc20d9cb..1b2dbab84f 100644
--- a/src/quick/scenegraph/qsgdefaultrendercontext.cpp
+++ b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
@@ -257,23 +257,24 @@ QSGTexture *QSGDefaultRenderContext::compressedTextureForFactory(const QSGCompre
return nullptr;
}
-QString QSGDefaultRenderContext::fontKey(const QRawFont &font)
+QString QSGDefaultRenderContext::fontKey(const QRawFont &font, int renderTypeQuality)
{
QFontEngine *fe = QRawFontPrivate::get(font)->fontEngine;
if (!fe->faceId().filename.isEmpty()) {
- QByteArray keyName = fe->faceId().filename + ' ' + QByteArray::number(fe->faceId().index);
- if (font.style() != QFont::StyleNormal)
- keyName += QByteArray(" I");
- if (font.weight() != QFont::Normal)
- keyName += ' ' + QByteArray::number(font.weight());
- keyName += QByteArray(" DF");
+ QByteArray keyName =
+ fe->faceId().filename + ' ' + QByteArray::number(fe->faceId().index)
+ + (font.style() != QFont::StyleNormal ? QByteArray(" I") : QByteArray())
+ + (font.weight() != QFont::Normal ? ' ' + QByteArray::number(font.weight()) : QByteArray())
+ + ' ' + QByteArray::number(renderTypeQuality)
+ + QByteArray(" DF");
return QString::fromUtf8(keyName);
} else {
- return QString::fromLatin1("%1_%2_%3_%4")
+ return QString::fromLatin1("%1_%2_%3_%4_%5")
.arg(font.familyName())
.arg(font.styleName())
.arg(font.weight())
- .arg(font.style());
+ .arg(font.style())
+ .arg(renderTypeQuality);
}
}
@@ -290,12 +291,12 @@ void QSGDefaultRenderContext::preprocess()
}
}
-QSGDistanceFieldGlyphCache *QSGDefaultRenderContext::distanceFieldGlyphCache(const QRawFont &font)
+QSGDistanceFieldGlyphCache *QSGDefaultRenderContext::distanceFieldGlyphCache(const QRawFont &font, int renderTypeQuality)
{
- QString key = fontKey(font);
+ QString key = fontKey(font, renderTypeQuality);
QSGDistanceFieldGlyphCache *cache = m_glyphCaches.value(key, 0);
if (!cache) {
- cache = new QSGRhiDistanceFieldGlyphCache(m_rhi, font);
+ cache = new QSGRhiDistanceFieldGlyphCache(m_rhi, font, renderTypeQuality);
m_glyphCaches.insert(key, cache);
}
diff --git a/src/quick/scenegraph/qsgdefaultrendercontext_p.h b/src/quick/scenegraph/qsgdefaultrendercontext_p.h
index a110172a6f..002513c0e4 100644
--- a/src/quick/scenegraph/qsgdefaultrendercontext_p.h
+++ b/src/quick/scenegraph/qsgdefaultrendercontext_p.h
@@ -110,7 +110,7 @@ public:
void endNextRhiFrame(QSGRenderer *renderer) override;
void preprocess() override;
- QSGDistanceFieldGlyphCache *distanceFieldGlyphCache(const QRawFont &font) override;
+ QSGDistanceFieldGlyphCache *distanceFieldGlyphCache(const QRawFont &font, int renderTypeQuality) override;
QSGTexture *createTexture(const QImage &image, uint flags) const override;
QSGRenderer *createRenderer(QSGRendererInterface::RenderMode renderMode = QSGRendererInterface::RenderMode2D) override;
@@ -144,7 +144,7 @@ public:
}
protected:
- static QString fontKey(const QRawFont &font);
+ static QString fontKey(const QRawFont &font, int renderTypeQuality);
InitParams m_initParams;
QRhi *m_rhi;
diff --git a/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp b/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp
index 70ba9f005d..8ac112b106 100644
--- a/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp
+++ b/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp
@@ -52,6 +52,7 @@ QSGDistanceFieldGlyphNode::QSGDistanceFieldGlyphNode(QSGRenderContext *context)
, m_style(QQuickText::Normal)
, m_antialiasingMode(GrayAntialiasing)
, m_texture(nullptr)
+ , m_renderTypeQuality(-1)
, m_dirtyGeometry(false)
, m_dirtyMaterial(false)
{
@@ -87,6 +88,14 @@ void QSGDistanceFieldGlyphNode::setColor(const QColor &color)
}
}
+void QSGDistanceFieldGlyphNode::setRenderTypeQuality(int renderTypeQuality)
+{
+ if (renderTypeQuality == m_renderTypeQuality)
+ return;
+
+ m_renderTypeQuality = renderTypeQuality;
+}
+
void QSGDistanceFieldGlyphNode::setPreferredAntialiasingMode(AntialiasingMode mode)
{
if (mode == m_antialiasingMode)
@@ -107,7 +116,7 @@ void QSGDistanceFieldGlyphNode::setGlyphs(const QPointF &position, const QGlyphR
setFlag(UsePreprocess);
QSGDistanceFieldGlyphCache *oldCache = m_glyph_cache;
- m_glyph_cache = m_context->distanceFieldGlyphCache(m_glyphs.rawFont());
+ m_glyph_cache = m_context->distanceFieldGlyphCache(m_glyphs.rawFont(), m_renderTypeQuality);
if (m_glyphNodeType == SubGlyphNode)
return;
diff --git a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.h b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.h
index 7b6be29bcb..2b2975ccb3 100644
--- a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.h
+++ b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.h
@@ -72,6 +72,7 @@ public:
void setColor(const QColor &color) override;
void setPreferredAntialiasingMode(AntialiasingMode mode) override;
+ void setRenderTypeQuality(int renderTypeQuality) override;
void setStyle(QQuickText::TextStyle style) override;
void setStyleColor(const QColor &color) override;
@@ -107,6 +108,7 @@ private:
AntialiasingMode m_antialiasingMode;
QRectF m_boundingRect;
const QSGDistanceFieldGlyphCache::Texture *m_texture;
+ int m_renderTypeQuality;
struct GlyphInfo {
QVector<quint32> indexes;
diff --git a/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
index a87ac56cc2..ae6d41076f 100644
--- a/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
+++ b/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
@@ -54,8 +54,10 @@ DEFINE_BOOL_CONFIG_OPTION(qsgPreferFullSizeGlyphCacheTextures, QSG_PREFER_FULLSI
# define QSG_RHI_DISTANCEFIELD_GLYPH_CACHE_PADDING 2
#endif
-QSGRhiDistanceFieldGlyphCache::QSGRhiDistanceFieldGlyphCache(QRhi *rhi, const QRawFont &font)
- : QSGDistanceFieldGlyphCache(font)
+QSGRhiDistanceFieldGlyphCache::QSGRhiDistanceFieldGlyphCache(QRhi *rhi,
+ const QRawFont &font,
+ int renderTypeQuality)
+ : QSGDistanceFieldGlyphCache(font, renderTypeQuality)
, m_rhi(rhi)
{
// Load a pregenerated cache if the font contains one
diff --git a/src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h b/src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h
index f7055eabe2..48d666e7e2 100644
--- a/src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h
+++ b/src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h
@@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE
class Q_QUICK_PRIVATE_EXPORT QSGRhiDistanceFieldGlyphCache : public QSGDistanceFieldGlyphCache
{
public:
- QSGRhiDistanceFieldGlyphCache(QRhi *rhi, const QRawFont &font);
+ QSGRhiDistanceFieldGlyphCache(QRhi *rhi, const QRawFont &font, int renderTypeQuality);
virtual ~QSGRhiDistanceFieldGlyphCache();
void requestGlyphs(const QSet<glyph_t> &glyphs) override;