aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2020-05-02 14:27:13 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2020-06-02 15:16:46 +0200
commitb87b3d3d43c200f22f0799ca59ab366d851b5db6 (patch)
treefb8258e0659a91934d2c77c359295da92e4221cd /src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
parent1f0b3a54ffa2ab0dc0cdff1345980ea68d749d24 (diff)
Make QSGMaterialRhiShader become QSGMaterialShader
After a symbiotic relationship in Qt 5.14 and 5.15, it is time for QSGMaterialRhiShader to devour its older sibling and take its place. This makes the direct OpenGL rendering path disfunctional. All QSGMaterial Qt 6 TODOs are solved, the API is clean and straightforward again: a QSGMaterial creates a QSGMaterialShader, no special flags and options needed. (it's just that QSGMaterialShader now has a slightly different API) Task-number: QTBUG-79268 Task-number: QTBUG-82997 Change-Id: I545ca8d796c5535e81957c706e7832133be15b7d Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
Diffstat (limited to 'src/quick/scenegraph/qsgdefaultglyphnode_p.cpp')
-rw-r--r--src/quick/scenegraph/qsgdefaultglyphnode_p.cpp351
1 files changed, 15 insertions, 336 deletions
diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
index 44fef4ddef..e13b16c95b 100644
--- a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
+++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
@@ -90,9 +90,6 @@ static inline qreal fontSmoothingGamma()
return fontSmoothingGamma;
}
-
-// ***** legacy (GL) material shader implementations
-
static inline qreal qsg_device_pixel_ratio(QOpenGLContext *ctx)
{
qreal devicePixelRatio = 1;
@@ -108,304 +105,7 @@ static inline qreal qsg_device_pixel_ratio(QOpenGLContext *ctx)
return devicePixelRatio;
}
-class QSGTextMaskShader : public QSGMaterialShader
-{
-public:
- QSGTextMaskShader(QFontEngine::GlyphFormat glyphFormat);
-
- void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
- char const *const *attributeNames() const override;
-
-protected:
- void initialize() override;
-
- int m_matrix_id;
- int m_color_id;
- int m_textureScale_id;
- float m_devicePixelRatio;
-
- QFontEngine::GlyphFormat m_glyphFormat;
-};
-
-char const *const *QSGTextMaskShader::attributeNames() const
-{
- static char const *const attr[] = { "vCoord", "tCoord", nullptr };
- return attr;
-}
-
-QSGTextMaskShader::QSGTextMaskShader(QFontEngine::GlyphFormat glyphFormat)
- : QSGMaterialShader(*new QSGMaterialShaderPrivate)
- , m_matrix_id(-1)
- , m_color_id(-1)
- , m_textureScale_id(-1)
- , m_glyphFormat(glyphFormat)
-{
- setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/scenegraph/shaders/textmask.vert"));
- setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/textmask.frag"));
-}
-
-void QSGTextMaskShader::initialize()
-{
- m_matrix_id = program()->uniformLocation("matrix");
- m_color_id = program()->uniformLocation("color");
- m_textureScale_id = program()->uniformLocation("textureScale");
- m_devicePixelRatio = (float) qsg_device_pixel_ratio(QOpenGLContext::currentContext());
- program()->setUniformValue("dpr", m_devicePixelRatio);
-}
-
-void QSGTextMaskShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
-{
- QSGTextMaskMaterial *material = static_cast<QSGTextMaskMaterial *>(newEffect);
- QSGTextMaskMaterial *oldMaterial = static_cast<QSGTextMaskMaterial *>(oldEffect);
- Q_ASSERT(oldEffect == nullptr || newEffect->type() == oldEffect->type());
- bool updated = material->ensureUpToDate();
- Q_ASSERT(material->texture());
-
- Q_ASSERT(oldMaterial == nullptr || oldMaterial->texture());
- if (updated
- || oldMaterial == nullptr
- || oldMaterial->texture()->textureId() != material->texture()->textureId()) {
- program()->setUniformValue(m_textureScale_id, QVector2D(1.0 / material->openglGlyphCache()->width(),
- 1.0 / material->openglGlyphCache()->height()));
- QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
- funcs->glBindTexture(GL_TEXTURE_2D, material->texture()->textureId());
-
- // Set the mag/min filters to be nearest. We only need to do this when the texture
- // has been recreated.
- if (updated) {
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- }
- }
-
- float devicePixelRatio = (float) qsg_device_pixel_ratio(QOpenGLContext::currentContext());
- if (m_devicePixelRatio != devicePixelRatio) {
- m_devicePixelRatio = devicePixelRatio;
- program()->setUniformValue("dpr", m_devicePixelRatio);
- }
-
- if (state.isMatrixDirty())
- program()->setUniformValue(m_matrix_id, state.combinedMatrix());
-}
-
-class QSG8BitTextMaskShader : public QSGTextMaskShader
-{
-public:
- QSG8BitTextMaskShader(QFontEngine::GlyphFormat glyphFormat)
- : QSGTextMaskShader(glyphFormat)
- {
- setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/8bittextmask.frag"));
- }
-
- void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
-};
-
-void QSG8BitTextMaskShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
-{
- QSGTextMaskShader::updateState(state, newEffect, oldEffect);
- QSGTextMaskMaterial *material = static_cast<QSGTextMaskMaterial *>(newEffect);
- QSGTextMaskMaterial *oldMaterial = static_cast<QSGTextMaskMaterial *>(oldEffect);
-
- if (oldMaterial == nullptr || material->color() != oldMaterial->color() || state.isOpacityDirty()) {
- QVector4D color = qsg_premultiply(material->color(), state.opacity());
- program()->setUniformValue(m_color_id, color);
- }
-}
-
-class QSG24BitTextMaskShader : public QSGTextMaskShader
-{
-public:
- QSG24BitTextMaskShader(QFontEngine::GlyphFormat glyphFormat)
- : QSGTextMaskShader(glyphFormat)
- , m_useSRGB(false)
- {
- setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/24bittextmask.frag"));
- }
-
- void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
- void initialize() override;
- void activate() override;
- void deactivate() override;
-
- bool useSRGB() const;
- uint m_useSRGB : 1;
-};
-
-void QSG24BitTextMaskShader::initialize()
-{
- QSGTextMaskShader::initialize();
- // 0.25 was found to be acceptable error margin by experimentation. On Mac, the gamma is 2.0,
- // but using sRGB looks okay.
- if (QOpenGLContext::currentContext()->hasExtension(QByteArrayLiteral("GL_ARB_framebuffer_sRGB"))
- && m_glyphFormat == QFontEngine::Format_A32
- && qAbs(fontSmoothingGamma() - 2.2) < 0.25) {
- QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
- GLint srgbCapable = 0;
- funcs->glGetIntegerv(GL_FRAMEBUFFER_SRGB_CAPABLE, &srgbCapable);
- if (srgbCapable)
- m_useSRGB = true;
- }
-}
-
-bool QSG24BitTextMaskShader::useSRGB() const
-{
-#ifdef Q_OS_MACOS
- if (!m_useSRGB)
- return false;
-
- // m_useSRGB is true, but if some QOGLFBO was bound check it's texture format:
- QOpenGLContext *ctx = QOpenGLContext::currentContext();
- QOpenGLFramebufferObject *qfbo = QOpenGLContextPrivate::get(ctx)->qgl_current_fbo;
- bool fboInvalid = QOpenGLContextPrivate::get(ctx)->qgl_current_fbo_invalid;
- return !qfbo || fboInvalid || qfbo->format().internalTextureFormat() == GL_SRGB8_ALPHA8_EXT;
-#else
- return m_useSRGB;
-#endif
-}
-
-void QSG24BitTextMaskShader::activate()
-{
- QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
- funcs->glBlendFunc(GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR);
- if (useSRGB())
- funcs->glEnable(GL_FRAMEBUFFER_SRGB);
-}
-
-void QSG24BitTextMaskShader::deactivate()
-{
- QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
- funcs->glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- if (useSRGB())
- funcs->glDisable(GL_FRAMEBUFFER_SRGB);
-}
-
-void QSG24BitTextMaskShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
-{
- QSGTextMaskShader::updateState(state, newEffect, oldEffect);
- QSGTextMaskMaterial *material = static_cast<QSGTextMaskMaterial *>(newEffect);
- QSGTextMaskMaterial *oldMaterial = static_cast<QSGTextMaskMaterial *>(oldEffect);
-
- if (oldMaterial == nullptr || material->color() != oldMaterial->color() || state.isOpacityDirty()) {
- QVector4D color = material->color();
- if (useSRGB())
- color = qt_sRGB_to_linear_RGB(color);
- QOpenGLContext::currentContext()->functions()->glBlendColor(color.x(), color.y(), color.z(), color.w());
- color = qsg_premultiply(color, state.opacity());
- program()->setUniformValue(m_color_id, color.w());
- }
-}
-
-class QSG32BitColorTextShader : public QSGTextMaskShader
-{
-public:
- QSG32BitColorTextShader(QFontEngine::GlyphFormat glyphFormat)
- : QSGTextMaskShader(glyphFormat)
- {
- setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/32bitcolortext.frag"));
- }
-
- void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
-};
-
-void QSG32BitColorTextShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
-{
- QSGTextMaskShader::updateState(state, newEffect, oldEffect);
- QSGTextMaskMaterial *material = static_cast<QSGTextMaskMaterial *>(newEffect);
- QSGTextMaskMaterial *oldMaterial = static_cast<QSGTextMaskMaterial *>(oldEffect);
-
- if (oldMaterial == nullptr || material->color() != oldMaterial->color() || state.isOpacityDirty()) {
- float opacity = material->color().w() * state.opacity();
- program()->setUniformValue(m_color_id, opacity);
- }
-}
-
-class QSGStyledTextShader : public QSG8BitTextMaskShader
-{
-public:
- QSGStyledTextShader(QFontEngine::GlyphFormat glyphFormat)
- : QSG8BitTextMaskShader(glyphFormat)
- {
- setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/scenegraph/shaders/styledtext.vert"));
- setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/styledtext.frag"));
- }
-
- void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
-
-private:
- void initialize() override;
-
- int m_shift_id;
- int m_styleColor_id;
-};
-
-void QSGStyledTextShader::initialize()
-{
- QSG8BitTextMaskShader::initialize();
- m_shift_id = program()->uniformLocation("shift");
- m_styleColor_id = program()->uniformLocation("styleColor");
-}
-
-void QSGStyledTextShader::updateState(const RenderState &state,
- QSGMaterial *newEffect,
- QSGMaterial *oldEffect)
-{
- Q_ASSERT(oldEffect == nullptr || newEffect->type() == oldEffect->type());
-
- QSGStyledTextMaterial *material = static_cast<QSGStyledTextMaterial *>(newEffect);
- QSGStyledTextMaterial *oldMaterial = static_cast<QSGStyledTextMaterial *>(oldEffect);
-
- if (oldMaterial == nullptr || oldMaterial->styleShift() != material->styleShift())
- program()->setUniformValue(m_shift_id, material->styleShift());
-
- if (oldMaterial == nullptr || material->color() != oldMaterial->color() || state.isOpacityDirty()) {
- QVector4D color = qsg_premultiply(material->color(), state.opacity());
- program()->setUniformValue(m_color_id, color);
- }
-
- if (oldMaterial == nullptr || material->styleColor() != oldMaterial->styleColor() || state.isOpacityDirty()) {
- QVector4D styleColor = qsg_premultiply(material->styleColor(), state.opacity());
- program()->setUniformValue(m_styleColor_id, styleColor);
- }
-
- bool updated = material->ensureUpToDate();
- Q_ASSERT(material->texture());
-
- Q_ASSERT(oldMaterial == nullptr || oldMaterial->texture());
- if (updated
- || oldMaterial == nullptr
- || oldMaterial->texture()->textureId() != material->texture()->textureId()) {
- program()->setUniformValue(m_textureScale_id, QVector2D(1.0 / material->openglGlyphCache()->width(),
- 1.0 / material->openglGlyphCache()->height()));
- QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
- funcs->glBindTexture(GL_TEXTURE_2D, material->texture()->textureId());
-
- // Set the mag/min filters to be nearest. We only need to do this when the texture
- // has been recreated.
- if (updated) {
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- }
- }
-
- if (state.isMatrixDirty())
- program()->setUniformValue(m_matrix_id, state.combinedMatrix());
-}
-
-class QSGOutlinedTextShader : public QSGStyledTextShader
-{
-public:
- QSGOutlinedTextShader(QFontEngine::GlyphFormat glyphFormat)
- : QSGStyledTextShader(glyphFormat)
- {
- setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/scenegraph/shaders/outlinedtext.vert"));
- setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/outlinedtext.frag"));
- }
-};
-
-
-// ***** RHI shader implementations
-
-class QSGTextMaskRhiShader : public QSGMaterialRhiShader
+class QSGTextMaskRhiShader : public QSGMaterialShader
{
public:
QSGTextMaskRhiShader(QFontEngine::GlyphFormat glyphFormat);
@@ -721,7 +421,6 @@ void QSGTextMaskMaterial::init(QFontEngine::GlyphFormat glyphFormat)
{
Q_ASSERT(m_font.isValid());
- setFlag(SupportsRhiShader, true);
setFlag(Blending, true);
Q_ASSERT(m_rc);
@@ -902,28 +601,16 @@ QSGRhiTextureGlyphCache *QSGTextMaskMaterial::rhiGlyphCache() const
QSGMaterialShader *QSGTextMaskMaterial::createShader() const
{
- if (flags().testFlag(RhiShaderWanted)) {
- QSGRhiTextureGlyphCache *gc = rhiGlyphCache();
- const QFontEngine::GlyphFormat glyphFormat = gc->glyphFormat();
- switch (glyphFormat) {
- case QFontEngine::Format_ARGB:
- return new QSG32BitColorTextRhiShader(glyphFormat);
- case QFontEngine::Format_A32:
- return new QSG24BitTextMaskRhiShader(glyphFormat);
- case QFontEngine::Format_A8:
- default:
- return new QSG8BitTextMaskRhiShader(glyphFormat, gc->eightBitFormatIsAlphaSwizzled());
- }
- } else {
- switch (QFontEngine::GlyphFormat glyphFormat = glyphCache()->glyphFormat()) {
- case QFontEngine::Format_ARGB:
- return new QSG32BitColorTextShader(glyphFormat);
- case QFontEngine::Format_A32:
- return new QSG24BitTextMaskShader(glyphFormat);
- case QFontEngine::Format_A8:
- default:
- return new QSG8BitTextMaskShader(glyphFormat);
- }
+ QSGRhiTextureGlyphCache *gc = rhiGlyphCache();
+ const QFontEngine::GlyphFormat glyphFormat = gc->glyphFormat();
+ switch (glyphFormat) {
+ case QFontEngine::Format_ARGB:
+ return new QSG32BitColorTextRhiShader(glyphFormat);
+ case QFontEngine::Format_A32:
+ return new QSG24BitTextMaskRhiShader(glyphFormat);
+ case QFontEngine::Format_A8:
+ default:
+ return new QSG8BitTextMaskRhiShader(glyphFormat, gc->eightBitFormatIsAlphaSwizzled());
}
}
@@ -996,12 +683,8 @@ QSGMaterialType *QSGStyledTextMaterial::type() const
QSGMaterialShader *QSGStyledTextMaterial::createShader() const
{
- if (flags().testFlag(RhiShaderWanted)) {
- QSGRhiTextureGlyphCache *gc = rhiGlyphCache();
- return new QSGStyledTextRhiShader(gc->glyphFormat(), gc->eightBitFormatIsAlphaSwizzled());
- } else {
- return new QSGStyledTextShader(glyphCache()->glyphFormat());
- }
+ QSGRhiTextureGlyphCache *gc = rhiGlyphCache();
+ return new QSGStyledTextRhiShader(gc->glyphFormat(), gc->eightBitFormatIsAlphaSwizzled());
}
int QSGStyledTextMaterial::compare(const QSGMaterial *o) const
@@ -1031,12 +714,8 @@ QSGMaterialType *QSGOutlinedTextMaterial::type() const
QSGMaterialShader *QSGOutlinedTextMaterial::createShader() const
{
- if (flags().testFlag(RhiShaderWanted)) {
- QSGRhiTextureGlyphCache *gc = rhiGlyphCache();
- return new QSGOutlinedTextRhiShader(gc->glyphFormat(), gc->eightBitFormatIsAlphaSwizzled());
- } else {
- return new QSGOutlinedTextShader(glyphCache()->glyphFormat());
- }
+ QSGRhiTextureGlyphCache *gc = rhiGlyphCache();
+ return new QSGOutlinedTextRhiShader(gc->glyphFormat(), gc->eightBitFormatIsAlphaSwizzled());
}
QT_END_NAMESPACE