6#include <QtGui/qsurface.h>
7#include <QtGui/qwindow.h>
14 if (Q_LIKELY(!qEnvironmentVariableIsSet(name)))
17 const float value = qgetenv(name).toFloat(&ok);
18 return ok ? value : defaultValue;
27 return base - ((qBound(devScaleMin, glyphScale, devScaleMax) - devScaleMin) / (devScaleMax - devScaleMin) * -baseDev + baseDev);
33 return range / glyphScale;
42 QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
override;
45 QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
override;
55 setShaderFileName(VertexStage, QStringLiteral(
":/qt-project.org/scenegraph/shaders_ng/distancefieldtext.vert.qsb"), viewCount);
57 setShaderFileName(FragmentStage, QStringLiteral(
":/qt-project.org/scenegraph/shaders_ng/distancefieldtext_a.frag.qsb"), viewCount);
59 setShaderFileName(FragmentStage, QStringLiteral(
":/qt-project.org/scenegraph/shaders_ng/distancefieldtext.frag.qsb"), viewCount);
63 QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
65 Q_ASSERT(oldMaterial ==
nullptr || newMaterial->type() == oldMaterial->type());
66 QSGDistanceFieldTextMaterial *mat =
static_cast<QSGDistanceFieldTextMaterial *>(newMaterial);
67 QSGDistanceFieldTextMaterial *oldMat =
static_cast<QSGDistanceFieldTextMaterial *>(oldMaterial);
71 const bool textureUpdated = mat->updateTextureSizeAndWrapper();
72 Q_ASSERT(mat->wrapperTexture());
73 Q_ASSERT(oldMat ==
nullptr || oldMat->texture());
76 QByteArray *buf = state.uniformData();
77 Q_ASSERT(buf->size() >= 104);
79 bool updateRange =
false;
80 if (!oldMat || mat->fontScale() != oldMat->fontScale()) {
84 if (state.isMatrixDirty()) {
85 m_matrixScale = qSqrt(qAbs(state.determinant())) * state.devicePixelRatio();
89 const int matrixCount = qMin(state.projectionMatrixCount(), newMaterial->viewCount());
90 for (
int viewIndex = 0; viewIndex < matrixCount; ++viewIndex) {
91 if (state.isMatrixDirty()) {
92 const QMatrix4x4 m = state.combinedMatrix(viewIndex);
93 memcpy(buf->data() + 64 * viewIndex, m.constData(), 64);
98 if (textureUpdated || !oldMat || oldMat->texture()->texture != mat->texture()->texture) {
99 const QVector2D ts(1.0f / mat->textureSize().width(), 1.0f / mat->textureSize().height());
100 Q_ASSERT(
sizeof(ts) == 8);
101 memcpy(buf->data() + offset, &ts, 8);
105 if (!oldMat || mat->color() != oldMat->color() || state.isOpacityDirty()) {
106 const QVector4D color = mat->color() * state.opacity();
107 Q_ASSERT(
sizeof(color) == 16);
108 memcpy(buf->data() + offset, &color, 16);
116 const QVector2D alphaMinMax(qMax(0.0f, base - range), qMin(base + range, 1.0f));
117 memcpy(buf->data() + offset, &alphaMinMax, 8);
123 static_cast<QSGRhiDistanceFieldGlyphCache *>(mat->glyphCache())->commitResourceUpdates(state.resourceUpdateBatch());
125 m_currentUbufOffset = offset;
130 QSGMaterial *newMaterial, QSGMaterial *)
136 QSGDistanceFieldTextMaterial *mat =
static_cast<QSGDistanceFieldTextMaterial *>(newMaterial);
137 QSGTexture *t = mat->wrapperTexture();
138 t->setFiltering(QSGTexture::Linear);
151 setShaderFileName(VertexStage, QStringLiteral(
":/qt-project.org/scenegraph/shaders_ng/distancefieldtext.vert.qsb"), viewCount);
153 setShaderFileName(FragmentStage, QStringLiteral(
":/qt-project.org/scenegraph/shaders_ng/distancefieldtext_a_fwidth.frag.qsb"), viewCount);
155 setShaderFileName(FragmentStage, QStringLiteral(
":/qt-project.org/scenegraph/shaders_ng/distancefieldtext_fwidth.frag.qsb"), viewCount);
158QSGDistanceFieldTextMaterial::QSGDistanceFieldTextMaterial()
159 : m_glyph_cache(
nullptr)
162 , m_sgTexture(
nullptr)
164 setFlag(Blending | RequiresDeterminant,
true);
167QSGDistanceFieldTextMaterial::~QSGDistanceFieldTextMaterial()
172QSGMaterialType *QSGDistanceFieldTextMaterial::type()
const
174 static QSGMaterialType type;
178void QSGDistanceFieldTextMaterial::setColor(
const QColor &color)
181 color.getRgbF(&r, &g, &b, &a);
182 m_color = QVector4D(r * a, g * a, b * a, a);
185QSGMaterialShader *QSGDistanceFieldTextMaterial::createShader(QSGRendererInterface::RenderMode renderMode)
const
187 if (renderMode == QSGRendererInterface::RenderMode3D && m_glyph_cache->screenSpaceDerivativesSupported())
188 return new DistanceFieldAnisotropicTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled(), viewCount());
190 return new QSGDistanceFieldTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled(), viewCount());
193bool QSGDistanceFieldTextMaterial::updateTextureSize()
196 m_texture = m_glyph_cache->glyphTexture(0);
198 if (m_texture->size != m_size) {
199 m_size = m_texture->size;
209bool QSGDistanceFieldTextMaterial::updateTextureSizeAndWrapper()
211 bool updated = updateTextureSize();
215 m_sgTexture =
new QSGPlainTexture;
216 m_sgTexture->setTexture(m_texture->texture);
217 m_sgTexture->setTextureSize(m_size);
218 m_sgTexture->setOwnsTexture(
false);
223int QSGDistanceFieldTextMaterial::compare(
const QSGMaterial *o)
const
225 Q_ASSERT(o && type() == o->type());
226 const QSGDistanceFieldTextMaterial *other =
static_cast<
const QSGDistanceFieldTextMaterial *>(o);
227 if (m_glyph_cache != other->m_glyph_cache)
228 return m_glyph_cache - other->m_glyph_cache;
229 if (m_fontScale != other->m_fontScale) {
230 return int(other->m_fontScale < m_fontScale) -
int(m_fontScale < other->m_fontScale);
232 if (m_color != other->m_color)
233 return &m_color < &other->m_color ? -1 : 1;
234 qintptr t0 = m_texture ? qintptr(m_texture->texture) : 0;
235 qintptr t1 = other->m_texture ? qintptr(other->m_texture->texture) : 0;
236 const qintptr diff = t0 - t1;
237 return diff < 0 ? -1 : (diff > 0 ? 1 : 0);
244 bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
override;
253 QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
255 bool changed = QSGDistanceFieldTextMaterialRhiShader::updateUniformData(state, newMaterial, oldMaterial);
256 QSGDistanceFieldStyledTextMaterial *mat =
static_cast<QSGDistanceFieldStyledTextMaterial *>(newMaterial);
257 QSGDistanceFieldStyledTextMaterial *oldMat =
static_cast<QSGDistanceFieldStyledTextMaterial *>(oldMaterial);
259 QByteArray *buf = state.uniformData();
260 Q_ASSERT(buf->size() >= 128);
263 m_currentUbufOffset += 8;
265 if (!oldMat || mat->styleColor() != oldMat->styleColor() || state.isOpacityDirty()) {
266 QVector4D styleColor = mat->styleColor();
267 styleColor *= state.opacity();
269 memcpy(buf->data() + m_currentUbufOffset, &styleColor, 16);
272 m_currentUbufOffset += 16;
277QSGDistanceFieldStyledTextMaterial::QSGDistanceFieldStyledTextMaterial()
278 : QSGDistanceFieldTextMaterial()
282QSGDistanceFieldStyledTextMaterial::~QSGDistanceFieldStyledTextMaterial()
286void QSGDistanceFieldStyledTextMaterial::setStyleColor(
const QColor &color)
289 color.getRgbF(&r, &g, &b, &a);
290 m_styleColor = QVector4D(r * a, g * a, b * a, a);
293int QSGDistanceFieldStyledTextMaterial::compare(
const QSGMaterial *o)
const
295 Q_ASSERT(o && type() == o->type());
296 const QSGDistanceFieldStyledTextMaterial *other =
static_cast<
const QSGDistanceFieldStyledTextMaterial *>(o);
297 if (m_styleColor != other->m_styleColor)
298 return &m_styleColor < &other->m_styleColor ? -1 : 1;
299 return QSGDistanceFieldTextMaterial::compare(o);
307 bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
override;
313 setShaderFileName(VertexStage, QStringLiteral(
":/qt-project.org/scenegraph/shaders_ng/distancefieldoutlinetext.vert.qsb"), viewCount);
315 setShaderFileName(FragmentStage, QStringLiteral(
":/qt-project.org/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag.qsb"), viewCount);
317 setShaderFileName(FragmentStage, QStringLiteral(
":/qt-project.org/scenegraph/shaders_ng/distancefieldoutlinetext.frag.qsb"), viewCount);
329 setShaderFileName(VertexStage, QStringLiteral(
":/qt-project.org/scenegraph/shaders_ng/distancefieldoutlinetext.vert.qsb"), viewCount);
331 setShaderFileName(FragmentStage, QStringLiteral(
":/qt-project.org/scenegraph/shaders_ng/distancefieldoutlinetext_a_fwidth.frag.qsb"), viewCount);
333 setShaderFileName(FragmentStage, QStringLiteral(
":/qt-project.org/scenegraph/shaders_ng/distancefieldoutlinetext_fwidth.frag.qsb"), viewCount);
337 QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
339 bool changed = DistanceFieldStyledTextMaterialRhiShader::updateUniformData(state, newMaterial, oldMaterial);
340 QSGDistanceFieldOutlineTextMaterial *mat =
static_cast<QSGDistanceFieldOutlineTextMaterial *>(newMaterial);
341 QSGDistanceFieldOutlineTextMaterial *oldMat =
static_cast<QSGDistanceFieldOutlineTextMaterial *>(oldMaterial);
343 QByteArray *buf = state.uniformData();
344 Q_ASSERT(buf->size() >= 136);
346 if (!oldMat || mat->fontScale() != oldMat->fontScale() || state.isMatrixDirty()) {
347 float dfRadius = mat->glyphCache()->distanceFieldRadius();
351 float outlineLimit = qMax(0.2f, base - 0.5f / dfRadius /
m_fontScale);
352 float alphaMin = qMax(0.0f, base - range);
353 float styleAlphaMin0 = qMax(0.0f, outlineLimit - range);
354 float styleAlphaMin1 = qMin(outlineLimit + range, alphaMin);
355 memcpy(buf->data() + m_currentUbufOffset, &styleAlphaMin0, 4);
356 memcpy(buf->data() + m_currentUbufOffset + 4, &styleAlphaMin1, 4);
363QSGDistanceFieldOutlineTextMaterial::QSGDistanceFieldOutlineTextMaterial()
364 : QSGDistanceFieldStyledTextMaterial()
368QSGDistanceFieldOutlineTextMaterial::~QSGDistanceFieldOutlineTextMaterial()
372QSGMaterialType *QSGDistanceFieldOutlineTextMaterial::type()
const
374 static QSGMaterialType type;
378QSGMaterialShader *QSGDistanceFieldOutlineTextMaterial::createShader(QSGRendererInterface::RenderMode renderMode)
const
380 if (renderMode == QSGRendererInterface::RenderMode3D && m_glyph_cache->screenSpaceDerivativesSupported())
381 return new DistanceFieldAnisotropicOutlineTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled(), viewCount());
383 return new DistanceFieldOutlineTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled(), viewCount());
391 bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
override;
397 setShaderFileName(VertexStage, QStringLiteral(
":/qt-project.org/scenegraph/shaders_ng/distancefieldshiftedtext.vert.qsb"), viewCount);
399 setShaderFileName(FragmentStage, QStringLiteral(
":/qt-project.org/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag.qsb"), viewCount);
401 setShaderFileName(FragmentStage, QStringLiteral(
":/qt-project.org/scenegraph/shaders_ng/distancefieldshiftedtext.frag.qsb"), viewCount);
405 QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
407 bool changed = DistanceFieldStyledTextMaterialRhiShader::updateUniformData(state, newMaterial, oldMaterial);
408 QSGDistanceFieldShiftedStyleTextMaterial *mat =
static_cast<QSGDistanceFieldShiftedStyleTextMaterial *>(newMaterial);
409 QSGDistanceFieldShiftedStyleTextMaterial *oldMat =
static_cast<QSGDistanceFieldShiftedStyleTextMaterial *>(oldMaterial);
411 QByteArray *buf = state.uniformData();
412 Q_ASSERT(buf->size() >= 136);
414 if (!oldMat || oldMat->fontScale() != mat->fontScale() || oldMat->shift() != mat->shift()
415 || oldMat->textureSize() != mat->textureSize())
417 QVector2D shift(1.0 / mat->fontScale() * mat->shift().x(),
418 1.0 / mat->fontScale() * mat->shift().y());
419 memcpy(buf->data() + m_currentUbufOffset, &shift, 8);
435 setShaderFileName(VertexStage, QStringLiteral(
":/qt-project.org/scenegraph/shaders_ng/distancefieldshiftedtext.vert.qsb"), viewCount);
437 setShaderFileName(FragmentStage, QStringLiteral(
":/qt-project.org/scenegraph/shaders_ng/distancefieldshiftedtext_a_fwidth.frag.qsb"), viewCount);
439 setShaderFileName(FragmentStage, QStringLiteral(
":/qt-project.org/scenegraph/shaders_ng/distancefieldshiftedtext_fwidth.frag.qsb"), viewCount);
442QSGDistanceFieldShiftedStyleTextMaterial::QSGDistanceFieldShiftedStyleTextMaterial()
443 : QSGDistanceFieldStyledTextMaterial()
447QSGDistanceFieldShiftedStyleTextMaterial::~QSGDistanceFieldShiftedStyleTextMaterial()
451QSGMaterialType *QSGDistanceFieldShiftedStyleTextMaterial::type()
const
453 static QSGMaterialType type;
457QSGMaterialShader *QSGDistanceFieldShiftedStyleTextMaterial::createShader(QSGRendererInterface::RenderMode renderMode)
const
459 if (renderMode == QSGRendererInterface::RenderMode3D && m_glyph_cache->screenSpaceDerivativesSupported())
460 return new DistanceFieldAnisotropicShiftedTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled(), viewCount());
462 return new DistanceFieldShiftedStyleTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled(), viewCount());
465int QSGDistanceFieldShiftedStyleTextMaterial::compare(
const QSGMaterial *o)
const
467 const QSGDistanceFieldShiftedStyleTextMaterial *other =
static_cast<
const QSGDistanceFieldShiftedStyleTextMaterial *>(o);
468 if (m_shift != other->m_shift)
469 return &m_shift < &other->m_shift ? -1 : 1;
470 return QSGDistanceFieldStyledTextMaterial::compare(o);
478 bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
override;
480 QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
override;
486 setFlag(UpdatesGraphicsPipelineState,
true);
487 setShaderFileName(VertexStage, QStringLiteral(
":/qt-project.org/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.vert.qsb"), viewCount);
489 setShaderFileName(FragmentStage, QStringLiteral(
":/qt-project.org/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag.qsb"), viewCount);
491 setShaderFileName(FragmentStage, QStringLiteral(
":/qt-project.org/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag.qsb"), viewCount);
495 QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
497 bool changed = QSGDistanceFieldTextMaterialRhiShader::updateUniformData(state, newMaterial, oldMaterial);
498 QSGHiQSubPixelDistanceFieldTextMaterial *mat =
static_cast<QSGHiQSubPixelDistanceFieldTextMaterial *>(newMaterial);
499 QSGHiQSubPixelDistanceFieldTextMaterial *oldMat =
static_cast<QSGHiQSubPixelDistanceFieldTextMaterial *>(oldMaterial);
501 QByteArray *buf = state.uniformData();
502 Q_ASSERT(buf->size() >= 128);
504 if (!oldMat || mat->fontScale() != oldMat->fontScale()) {
505 float fontScale = mat->fontScale();
506 memcpy(buf->data() + m_currentUbufOffset, &fontScale, 4);
509 m_currentUbufOffset += 4 + 4;
511 if (!oldMat || state.isMatrixDirty()) {
512 int viewportWidth = state.viewportRect().width();
513 QMatrix4x4 mat = state.combinedMatrix().inverted();
514 QVector4D vecDelta = mat.column(0) * (qreal(2) / viewportWidth);
515 memcpy(buf->data() + m_currentUbufOffset, &vecDelta, 16);
522 QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
525 Q_UNUSED(oldMaterial);
526 QSGHiQSubPixelDistanceFieldTextMaterial *mat =
static_cast<QSGHiQSubPixelDistanceFieldTextMaterial *>(newMaterial);
528 ps->blendEnable =
true;
529 ps->srcColor = GraphicsPipelineState::ConstantColor;
530 ps->dstColor = GraphicsPipelineState::OneMinusSrcColor;
532 const QVector4D color = mat->color();
534 ps->blendConstant = QColor::fromRgbF(color.x(), color.y(), color.z(), 1.0f);
539QSGMaterialType *QSGHiQSubPixelDistanceFieldTextMaterial::type()
const
541 static QSGMaterialType type;
545QSGMaterialShader *QSGHiQSubPixelDistanceFieldTextMaterial::createShader(QSGRendererInterface::RenderMode renderMode)
const
547 if (renderMode == QSGRendererInterface::RenderMode3D && m_glyph_cache->screenSpaceDerivativesSupported())
548 return new DistanceFieldAnisotropicTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled(), viewCount());
550 return new QSGHiQSubPixelDistanceFieldTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled(), viewCount());
562 setShaderFileName(VertexStage, QStringLiteral(
":/qt-project.org/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.vert.qsb"), viewCount);
564 setShaderFileName(FragmentStage, QStringLiteral(
":/qt-project.org/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag.qsb"), viewCount);
566 setShaderFileName(FragmentStage, QStringLiteral(
":/qt-project.org/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag.qsb"), viewCount);
569QSGMaterialType *QSGLoQSubPixelDistanceFieldTextMaterial::type()
const
571 static QSGMaterialType type;
575QSGMaterialShader *QSGLoQSubPixelDistanceFieldTextMaterial::createShader(QSGRendererInterface::RenderMode renderMode)
const
577 if (renderMode == QSGRendererInterface::RenderMode3D && m_glyph_cache->screenSpaceDerivativesSupported())
578 return new DistanceFieldAnisotropicTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled(), viewCount());
580 return new QSGLoQSubPixelDistanceFieldTextMaterialRhiShader(m_glyph_cache->eightBitFormatIsAlphaSwizzled(), viewCount());
DistanceFieldAnisotropicOutlineTextMaterialRhiShader(bool alphaTexture, int viewCount)
DistanceFieldAnisotropicShiftedTextMaterialRhiShader(bool alphaTexture, int viewCount)
DistanceFieldAnisotropicTextMaterialRhiShader(bool alphaTexture, int viewCount)
bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override
This function is called by the scene graph to get the contents of the shader program's uniform buffer...
DistanceFieldOutlineTextMaterialRhiShader(bool alphaTexture, int viewCount)
bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override
This function is called by the scene graph to get the contents of the shader program's uniform buffer...
DistanceFieldShiftedStyleTextMaterialRhiShader(bool alphaTexture, int viewCount)
DistanceFieldStyledTextMaterialRhiShader(bool alphaTexture, int viewCount)
bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override
This function is called by the scene graph to get the contents of the shader program's uniform buffer...
void updateSampledImage(RenderState &state, int binding, QSGTexture **texture, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override
This function is called by the scene graph to prepare use of sampled images in the shader,...
bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override
This function is called by the scene graph to get the contents of the shader program's uniform buffer...
quint32 m_currentUbufOffset
QSGDistanceFieldTextMaterialRhiShader(bool alphaTexture, int viewCount)
QSGHiQSubPixelDistanceFieldTextMaterialRhiShader(bool alphaTexture, int viewCount)
bool updateGraphicsPipelineState(RenderState &state, GraphicsPipelineState *ps, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override
This function is called by the scene graph to enable the material to provide a custom set of graphics...
bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override
This function is called by the scene graph to get the contents of the shader program's uniform buffer...
QSGLoQSubPixelDistanceFieldTextMaterialRhiShader(bool alphaTexture, int viewCount)
static float thresholdFunc(float glyphScale)
static QT_BEGIN_NAMESPACE float qt_sg_envFloat(const char *name, float defaultValue)
static float spreadFunc(float glyphScale)