Blame SOURCES/0034-Fix-distorted-text-with-subpixel-matrix-translation.patch

72ccf7
From c1ddd97c87c729c7d05c7a74f82d41cfc5bd9cf8 Mon Sep 17 00:00:00 2001
72ccf7
From: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
72ccf7
Date: Tue, 12 Oct 2021 13:13:01 +0200
72ccf7
Subject: [PATCH 34/36] Fix distorted text with subpixel matrix translation
72ccf7
72ccf7
We would pixel-align native text *before* applying the
72ccf7
model-view matrix, which would cause GL_NEAREST artifacts to
72ccf7
show up when the text was positioned at a subpixel offset in
72ccf7
some cases. Instead, we pixel-align the coordinates after mapping
72ccf7
them to the view frustum, but before applying the projection to the
72ccf7
screen.
72ccf7
72ccf7
To make it easier to modify the buffer layout for the shaders the
72ccf7
next time, this also adds some constants for offsets.
72ccf7
72ccf7
[ChangeLog][Text] Fixed an issue where text using NativeRendering
72ccf7
would look slightly skewed if it was inside a parent that had
72ccf7
been positioned at a subpixel offset.
72ccf7
72ccf7
Pick-to: 5.15 6.2
72ccf7
Fixes: QTBUG-96112
72ccf7
Fixes: QTBUG-83626
72ccf7
Task-number: QTBUG-55638
72ccf7
Change-Id: Ifb785ad5830093df94afc75a7bc288e24ca7aa38
72ccf7
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
72ccf7
(cherry picked from commit b21948f5e811ce1b7abf065bc48af61a231e86f4)
72ccf7
---
72ccf7
 .../scenegraph/qsgdefaultglyphnode_p.cpp      | 46 ++++++----
72ccf7
 .../scenegraph/shaders_ng/24bittextmask.frag  |  5 +-
72ccf7
 .../scenegraph/shaders_ng/32bitcolortext.frag |  5 +-
72ccf7
 .../scenegraph/shaders_ng/8bittextmask.frag   |  3 +-
72ccf7
 .../scenegraph/shaders_ng/8bittextmask_a.frag |  3 +-
72ccf7
 .../scenegraph/shaders_ng/outlinedtext.frag   |  5 +-
72ccf7
 .../scenegraph/shaders_ng/outlinedtext.vert   |  9 +-
72ccf7
 .../scenegraph/shaders_ng/outlinedtext_a.frag |  5 +-
72ccf7
 .../scenegraph/shaders_ng/styledtext.frag     |  3 +-
72ccf7
 .../scenegraph/shaders_ng/styledtext.vert     |  7 +-
72ccf7
 .../scenegraph/shaders_ng/styledtext_a.frag   |  3 +-
72ccf7
 src/quick/scenegraph/shaders_ng/textmask.frag |  3 +-
72ccf7
 src/quick/scenegraph/shaders_ng/textmask.vert |  7 +-
72ccf7
 ...text_nativerendering_subpixelpositions.qml | 91 +++++++++++++++++++
72ccf7
 14 files changed, 155 insertions(+), 40 deletions(-)
72ccf7
 create mode 100644 tests/manual/scenegraph_lancelot/data/text/text_nativerendering_subpixelpositions.qml
72ccf7
72ccf7
diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
72ccf7
index 3c60f830de..0fd6581dc4 100644
72ccf7
--- a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
72ccf7
+++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
72ccf7
@@ -428,6 +428,18 @@ QSGTextMaskRhiShader::QSGTextMaskRhiShader(QFontEngine::GlyphFormat glyphFormat)
72ccf7
                       QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/textmask.frag.qsb"));
72ccf7
 }
72ccf7
 
72ccf7
+enum UbufOffset {
72ccf7
+    ModelViewMatrixOffset = 0,
72ccf7
+    ProjectionMatrixOffset = ModelViewMatrixOffset + 64,
72ccf7
+    ColorOffset = ProjectionMatrixOffset + 64,
72ccf7
+    TextureScaleOffset = ColorOffset + 16,
72ccf7
+    DprOffset = TextureScaleOffset + 8,
72ccf7
+
72ccf7
+    // + 1 float padding (vec4 must be aligned to 16)
72ccf7
+    StyleColorOffset = DprOffset + 4 + 4,
72ccf7
+    ShiftOffset = StyleColorOffset + 16
72ccf7
+};
72ccf7
+
72ccf7
 bool QSGTextMaskRhiShader::updateUniformData(RenderState &state,
72ccf7
                                              QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
72ccf7
 {
72ccf7
@@ -443,11 +455,14 @@ bool QSGTextMaskRhiShader::updateUniformData(RenderState &state,
72ccf7
 
72ccf7
     bool changed = false;
72ccf7
     QByteArray *buf = state.uniformData();
72ccf7
-    Q_ASSERT(buf->size() >= 92);
72ccf7
+    Q_ASSERT(buf->size() >= DprOffset + 4);
72ccf7
 
72ccf7
     if (state.isMatrixDirty()) {
72ccf7
-        const QMatrix4x4 m = state.combinedMatrix();
72ccf7
-        memcpy(buf->data(), m.constData(), 64);
72ccf7
+        const QMatrix4x4 mv = state.modelViewMatrix();
72ccf7
+        memcpy(buf->data() + ModelViewMatrixOffset, mv.constData(), 64);
72ccf7
+        const QMatrix4x4 p = state.projectionMatrix();
72ccf7
+        memcpy(buf->data() + ProjectionMatrixOffset, p.constData(), 64);
72ccf7
+
72ccf7
         changed = true;
72ccf7
     }
72ccf7
 
72ccf7
@@ -456,13 +471,13 @@ bool QSGTextMaskRhiShader::updateUniformData(RenderState &state,
72ccf7
     if (updated || !oldMat || oldRtex != newRtex) {
72ccf7
         const QVector2D textureScale = QVector2D(1.0f / mat->rhiGlyphCache()->width(),
72ccf7
                                                  1.0f / mat->rhiGlyphCache()->height());
72ccf7
-        memcpy(buf->data() + 64 + 16, &textureScale, 8);
72ccf7
+        memcpy(buf->data() + TextureScaleOffset, &textureScale, 8);
72ccf7
         changed = true;
72ccf7
     }
72ccf7
 
72ccf7
     if (!oldMat) {
72ccf7
         float dpr = state.devicePixelRatio();
72ccf7
-        memcpy(buf->data() + 64 + 16 + 8, &dpr, 4);
72ccf7
+        memcpy(buf->data() + DprOffset, &dpr, 4);
72ccf7
     }
72ccf7
 
72ccf7
     // move texture uploads/copies onto the renderer's soon-to-be-committed list
72ccf7
@@ -510,11 +525,11 @@ bool QSG8BitTextMaskRhiShader::updateUniformData(RenderState &state,
72ccf7
     QSGTextMaskMaterial *oldMat = static_cast<QSGTextMaskMaterial *>(oldMaterial);
72ccf7
 
72ccf7
     QByteArray *buf = state.uniformData();
72ccf7
-    Q_ASSERT(buf->size() >= 80);
72ccf7
+    Q_ASSERT(buf->size() >= ColorOffset + 16);
72ccf7
 
72ccf7
     if (oldMat == nullptr || mat->color() != oldMat->color() || state.isOpacityDirty()) {
72ccf7
         const QVector4D color = qsg_premultiply(mat->color(), state.opacity());
72ccf7
-        memcpy(buf->data() + 64, &color, 16);
72ccf7
+        memcpy(buf->data() + ColorOffset, &color, 16);
72ccf7
         changed = true;
72ccf7
     }
72ccf7
 
72ccf7
@@ -553,12 +568,12 @@ bool QSG24BitTextMaskRhiShader::updateUniformData(RenderState &state,
72ccf7
     QSGTextMaskMaterial *oldMat = static_cast<QSGTextMaskMaterial *>(oldMaterial);
72ccf7
 
72ccf7
     QByteArray *buf = state.uniformData();
72ccf7
-    Q_ASSERT(buf->size() >= 92);
72ccf7
+    Q_ASSERT(buf->size() >= ColorOffset + 16);
72ccf7
 
72ccf7
     if (oldMat == nullptr || mat->color() != oldMat->color() || state.isOpacityDirty()) {
72ccf7
         // shader takes vec4 but uses alpha only; coloring happens via the blend constant
72ccf7
         const QVector4D color = qsg_premultiply(mat->color(), state.opacity());
72ccf7
-        memcpy(buf->data() + 64, &color, 16);
72ccf7
+        memcpy(buf->data() + ColorOffset, &color, 16);
72ccf7
         changed = true;
72ccf7
     }
72ccf7
 
72ccf7
@@ -608,12 +623,12 @@ bool QSG32BitColorTextRhiShader::updateUniformData(RenderState &state,
72ccf7
     QSGTextMaskMaterial *oldMat = static_cast<QSGTextMaskMaterial *>(oldMaterial);
72ccf7
 
72ccf7
     QByteArray *buf = state.uniformData();
72ccf7
-    Q_ASSERT(buf->size() >= 92);
72ccf7
+    Q_ASSERT(buf->size() >= ColorOffset + 16);
72ccf7
 
72ccf7
     if (oldMat == nullptr || mat->color() != oldMat->color() || state.isOpacityDirty()) {
72ccf7
         // shader takes vec4 but uses alpha only
72ccf7
         const QVector4D color(0, 0, 0, mat->color().w() * state.opacity());
72ccf7
-        memcpy(buf->data() + 64, &color, 16);
72ccf7
+        memcpy(buf->data() + ColorOffset, &color, 16);
72ccf7
         changed = true;
72ccf7
     }
72ccf7
 
72ccf7
@@ -649,20 +664,17 @@ bool QSGStyledTextRhiShader::updateUniformData(RenderState &state,
72ccf7
     QSGStyledTextMaterial *oldMat = static_cast<QSGStyledTextMaterial *>(oldMaterial);
72ccf7
 
72ccf7
     QByteArray *buf = state.uniformData();
72ccf7
-    Q_ASSERT(buf->size() >= 120);
72ccf7
-
72ccf7
-    // matrix..dpr + 1 float padding (vec4 must be aligned to 16)
72ccf7
-    const int startOffset = 64 + 16 + 8 + 4 + 4;
72ccf7
+    Q_ASSERT(buf->size() >= ShiftOffset + 8);
72ccf7
 
72ccf7
     if (oldMat == nullptr || mat->styleColor() != oldMat->styleColor() || state.isOpacityDirty()) {
72ccf7
         const QVector4D styleColor = qsg_premultiply(mat->styleColor(), state.opacity());
72ccf7
-        memcpy(buf->data() + startOffset, &styleColor, 16);
72ccf7
+        memcpy(buf->data() + StyleColorOffset, &styleColor, 16);
72ccf7
         changed = true;
72ccf7
     }
72ccf7
 
72ccf7
     if (oldMat == nullptr || oldMat->styleShift() != mat->styleShift()) {
72ccf7
         const QVector2D v = mat->styleShift();
72ccf7
-        memcpy(buf->data() + startOffset + 16, &v, 8);
72ccf7
+        memcpy(buf->data() + ShiftOffset, &v, 8);
72ccf7
         changed = true;
72ccf7
     }
72ccf7
 
72ccf7
diff --git a/src/quick/scenegraph/shaders_ng/24bittextmask.frag b/src/quick/scenegraph/shaders_ng/24bittextmask.frag
72ccf7
index bc3826a924..ed8da4cd30 100644
72ccf7
--- a/src/quick/scenegraph/shaders_ng/24bittextmask.frag
72ccf7
+++ b/src/quick/scenegraph/shaders_ng/24bittextmask.frag
72ccf7
@@ -6,8 +6,9 @@ layout(location = 0) out vec4 fragColor;
72ccf7
 layout(binding = 1) uniform sampler2D _qt_texture;
72ccf7
 
72ccf7
 layout(std140, binding = 0) uniform buf {
72ccf7
-    mat4 matrix;
72ccf7
-    vec4 color; // only alpha is used, but must be vec4 due to layout compat
72ccf7
+    mat4 modelViewMatrix;
72ccf7
+    mat4 projectionMatrix;
72ccf7
+    vec4 color;
72ccf7
     vec2 textureScale;
72ccf7
     float dpr;
72ccf7
 } ubuf;
72ccf7
diff --git a/src/quick/scenegraph/shaders_ng/32bitcolortext.frag b/src/quick/scenegraph/shaders_ng/32bitcolortext.frag
72ccf7
index 63e445f90b..4198a4d339 100644
72ccf7
--- a/src/quick/scenegraph/shaders_ng/32bitcolortext.frag
72ccf7
+++ b/src/quick/scenegraph/shaders_ng/32bitcolortext.frag
72ccf7
@@ -6,8 +6,9 @@ layout(location = 0) out vec4 fragColor;
72ccf7
 layout(binding = 1) uniform sampler2D _qt_texture;
72ccf7
 
72ccf7
 layout(std140, binding = 0) uniform buf {
72ccf7
-    mat4 matrix;
72ccf7
-    vec4 color; // only alpha is used, but must be vec4 due to layout compat
72ccf7
+    mat4 modelViewMatrix;
72ccf7
+    mat4 projectionMatrix;
72ccf7
+    vec4 color;
72ccf7
     vec2 textureScale;
72ccf7
     float dpr;
72ccf7
 } ubuf;
72ccf7
diff --git a/src/quick/scenegraph/shaders_ng/8bittextmask.frag b/src/quick/scenegraph/shaders_ng/8bittextmask.frag
72ccf7
index 6304e821ff..a06743876d 100644
72ccf7
--- a/src/quick/scenegraph/shaders_ng/8bittextmask.frag
72ccf7
+++ b/src/quick/scenegraph/shaders_ng/8bittextmask.frag
72ccf7
@@ -6,7 +6,8 @@ layout(location = 0) out vec4 fragColor;
72ccf7
 layout(binding = 1) uniform sampler2D _qt_texture;
72ccf7
 
72ccf7
 layout(std140, binding = 0) uniform buf {
72ccf7
-    mat4 matrix;
72ccf7
+    mat4 modelViewMatrix;
72ccf7
+    mat4 projectionMatrix;
72ccf7
     vec4 color;
72ccf7
     vec2 textureScale;
72ccf7
     float dpr;
72ccf7
diff --git a/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag b/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag
72ccf7
index 0d0fa1cd3a..f725cbc5e7 100644
72ccf7
--- a/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag
72ccf7
+++ b/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag
72ccf7
@@ -6,7 +6,8 @@ layout(location = 0) out vec4 fragColor;
72ccf7
 layout(binding = 1) uniform sampler2D _qt_texture;
72ccf7
 
72ccf7
 layout(std140, binding = 0) uniform buf {
72ccf7
-    mat4 matrix;
72ccf7
+    mat4 modelViewMatrix;
72ccf7
+    mat4 projectionMatrix;
72ccf7
     vec4 color;
72ccf7
     vec2 textureScale;
72ccf7
     float dpr;
72ccf7
diff --git a/src/quick/scenegraph/shaders_ng/outlinedtext.frag b/src/quick/scenegraph/shaders_ng/outlinedtext.frag
72ccf7
index 947d161a50..e2f82d3845 100644
72ccf7
--- a/src/quick/scenegraph/shaders_ng/outlinedtext.frag
72ccf7
+++ b/src/quick/scenegraph/shaders_ng/outlinedtext.frag
72ccf7
@@ -11,11 +11,12 @@ layout(location = 0) out vec4 fragColor;
72ccf7
 layout(binding = 1) uniform sampler2D _qt_texture;
72ccf7
 
72ccf7
 layout(std140, binding = 0) uniform buf {
72ccf7
-    // must match styledtext
72ccf7
-    mat4 matrix;
72ccf7
+    mat4 modelViewMatrix;
72ccf7
+    mat4 projectionMatrix;
72ccf7
     vec4 color;
72ccf7
     vec2 textureScale;
72ccf7
     float dpr;
72ccf7
+    // the above must stay compatible with textmask/8bittextmask
72ccf7
     vec4 styleColor;
72ccf7
     vec2 shift;
72ccf7
 } ubuf;
72ccf7
diff --git a/src/quick/scenegraph/shaders_ng/outlinedtext.vert b/src/quick/scenegraph/shaders_ng/outlinedtext.vert
72ccf7
index 023f9dfdc2..4068e42f28 100644
72ccf7
--- a/src/quick/scenegraph/shaders_ng/outlinedtext.vert
72ccf7
+++ b/src/quick/scenegraph/shaders_ng/outlinedtext.vert
72ccf7
@@ -10,11 +10,12 @@ layout(location = 3) out vec2 sCoordLeft;
72ccf7
 layout(location = 4) out vec2 sCoordRight;
72ccf7
 
72ccf7
 layout(std140, binding = 0) uniform buf {
72ccf7
-    // must match styledtext
72ccf7
-    mat4 matrix;
72ccf7
+    mat4 modelViewMatrix;
72ccf7
+    mat4 projectionMatrix;
72ccf7
     vec4 color;
72ccf7
     vec2 textureScale;
72ccf7
     float dpr;
72ccf7
+    // the above must stay compatible with textmask/8bittextmask
72ccf7
     vec4 styleColor;
72ccf7
     vec2 shift;
72ccf7
 } ubuf;
72ccf7
@@ -28,6 +29,6 @@ void main()
72ccf7
      sCoordDown = (tCoord - vec2(0.0, 1.0)) * ubuf.textureScale;
72ccf7
      sCoordLeft = (tCoord - vec2(-1.0, 0.0)) * ubuf.textureScale;
72ccf7
      sCoordRight = (tCoord - vec2(1.0, 0.0)) * ubuf.textureScale;
72ccf7
-     vec3 dprSnapPos = floor(vCoord.xyz * ubuf.dpr + 0.5) / ubuf.dpr;
72ccf7
-     gl_Position = ubuf.matrix * vec4(dprSnapPos, vCoord.w);
72ccf7
+     vec4 xformed = ubuf.modelViewMatrix * vCoord;
72ccf7
+     gl_Position = ubuf.projectionMatrix * vec4(floor(xformed.xyz * ubuf.dpr + 0.5) / ubuf.dpr, xformed.w);
72ccf7
 }
72ccf7
diff --git a/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag b/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag
72ccf7
index 5b7bd9ca82..274d891a3c 100644
72ccf7
--- a/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag
72ccf7
+++ b/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag
72ccf7
@@ -11,11 +11,12 @@ layout(location = 0) out vec4 fragColor;
72ccf7
 layout(binding = 1) uniform sampler2D _qt_texture;
72ccf7
 
72ccf7
 layout(std140, binding = 0) uniform buf {
72ccf7
-    // must match styledtext
72ccf7
-    mat4 matrix;
72ccf7
+    mat4 modelViewMatrix;
72ccf7
+    mat4 projectionMatrix;
72ccf7
     vec4 color;
72ccf7
     vec2 textureScale;
72ccf7
     float dpr;
72ccf7
+    // the above must stay compatible with textmask/8bittextmask
72ccf7
     vec4 styleColor;
72ccf7
     vec2 shift;
72ccf7
 } ubuf;
72ccf7
diff --git a/src/quick/scenegraph/shaders_ng/styledtext.frag b/src/quick/scenegraph/shaders_ng/styledtext.frag
72ccf7
index 0b16396037..2e380dfeae 100644
72ccf7
--- a/src/quick/scenegraph/shaders_ng/styledtext.frag
72ccf7
+++ b/src/quick/scenegraph/shaders_ng/styledtext.frag
72ccf7
@@ -8,7 +8,8 @@ layout(location = 0) out vec4 fragColor;
72ccf7
 layout(binding = 1) uniform sampler2D _qt_texture;
72ccf7
 
72ccf7
 layout(std140, binding = 0) uniform buf {
72ccf7
-    mat4 matrix;
72ccf7
+    mat4 modelViewMatrix;
72ccf7
+    mat4 projectionMatrix;
72ccf7
     vec4 color;
72ccf7
     vec2 textureScale;
72ccf7
     float dpr;
72ccf7
diff --git a/src/quick/scenegraph/shaders_ng/styledtext.vert b/src/quick/scenegraph/shaders_ng/styledtext.vert
72ccf7
index beadf07c79..271dae8d8a 100644
72ccf7
--- a/src/quick/scenegraph/shaders_ng/styledtext.vert
72ccf7
+++ b/src/quick/scenegraph/shaders_ng/styledtext.vert
72ccf7
@@ -7,7 +7,8 @@ layout(location = 0) out vec2 sampleCoord;
72ccf7
 layout(location = 1) out vec2 shiftedSampleCoord;
72ccf7
 
72ccf7
 layout(std140, binding = 0) uniform buf {
72ccf7
-    mat4 matrix;
72ccf7
+    mat4 modelViewMatrix;
72ccf7
+    mat4 projectionMatrix;
72ccf7
     vec4 color;
72ccf7
     vec2 textureScale;
72ccf7
     float dpr;
72ccf7
@@ -22,6 +23,6 @@ void main()
72ccf7
 {
72ccf7
      sampleCoord = tCoord * ubuf.textureScale;
72ccf7
      shiftedSampleCoord = (tCoord - ubuf.shift) * ubuf.textureScale;
72ccf7
-     vec3 dprSnapPos = floor(vCoord.xyz * ubuf.dpr + 0.5) / ubuf.dpr;
72ccf7
-     gl_Position = ubuf.matrix * vec4(dprSnapPos, vCoord.w);
72ccf7
+     vec4 xformed = ubuf.modelViewMatrix * vCoord;
72ccf7
+     gl_Position = ubuf.projectionMatrix * vec4(floor(xformed.xyz * ubuf.dpr + 0.5) / ubuf.dpr, xformed.w);
72ccf7
 }
72ccf7
diff --git a/src/quick/scenegraph/shaders_ng/styledtext_a.frag b/src/quick/scenegraph/shaders_ng/styledtext_a.frag
72ccf7
index b673137895..62e162c851 100644
72ccf7
--- a/src/quick/scenegraph/shaders_ng/styledtext_a.frag
72ccf7
+++ b/src/quick/scenegraph/shaders_ng/styledtext_a.frag
72ccf7
@@ -8,7 +8,8 @@ layout(location = 0) out vec4 fragColor;
72ccf7
 layout(binding = 1) uniform sampler2D _qt_texture;
72ccf7
 
72ccf7
 layout(std140, binding = 0) uniform buf {
72ccf7
-    mat4 matrix;
72ccf7
+    mat4 modelViewMatrix;
72ccf7
+    mat4 projectionMatrix;
72ccf7
     vec4 color;
72ccf7
     vec2 textureScale;
72ccf7
     float dpr;
72ccf7
diff --git a/src/quick/scenegraph/shaders_ng/textmask.frag b/src/quick/scenegraph/shaders_ng/textmask.frag
72ccf7
index 518d5c965f..ed8da4cd30 100644
72ccf7
--- a/src/quick/scenegraph/shaders_ng/textmask.frag
72ccf7
+++ b/src/quick/scenegraph/shaders_ng/textmask.frag
72ccf7
@@ -6,7 +6,8 @@ layout(location = 0) out vec4 fragColor;
72ccf7
 layout(binding = 1) uniform sampler2D _qt_texture;
72ccf7
 
72ccf7
 layout(std140, binding = 0) uniform buf {
72ccf7
-    mat4 matrix;
72ccf7
+    mat4 modelViewMatrix;
72ccf7
+    mat4 projectionMatrix;
72ccf7
     vec4 color;
72ccf7
     vec2 textureScale;
72ccf7
     float dpr;
72ccf7
diff --git a/src/quick/scenegraph/shaders_ng/textmask.vert b/src/quick/scenegraph/shaders_ng/textmask.vert
72ccf7
index 9d80d5dadb..e0b3c01bce 100644
72ccf7
--- a/src/quick/scenegraph/shaders_ng/textmask.vert
72ccf7
+++ b/src/quick/scenegraph/shaders_ng/textmask.vert
72ccf7
@@ -6,7 +6,8 @@ layout(location = 1) in vec2 tCoord;
72ccf7
 layout(location = 0) out vec2 sampleCoord;
72ccf7
 
72ccf7
 layout(std140, binding = 0) uniform buf {
72ccf7
-    mat4 matrix;
72ccf7
+    mat4 modelViewMatrix;
72ccf7
+    mat4 projectionMatrix;
72ccf7
     vec4 color;
72ccf7
     vec2 textureScale;
72ccf7
     float dpr;
72ccf7
@@ -17,6 +18,6 @@ out gl_PerVertex { vec4 gl_Position; };
72ccf7
 void main()
72ccf7
 {
72ccf7
      sampleCoord = tCoord * ubuf.textureScale;
72ccf7
-     vec3 dprSnapPos = floor(vCoord.xyz * ubuf.dpr + 0.5) / ubuf.dpr;
72ccf7
-     gl_Position = ubuf.matrix * vec4(dprSnapPos, vCoord.w);
72ccf7
+     vec4 xformed = ubuf.modelViewMatrix * vCoord;
72ccf7
+     gl_Position = ubuf.projectionMatrix * vec4(floor(xformed.xyz * ubuf.dpr + 0.5) / ubuf.dpr, xformed.w);
72ccf7
 }
72ccf7
diff --git a/tests/manual/scenegraph_lancelot/data/text/text_nativerendering_subpixelpositions.qml b/tests/manual/scenegraph_lancelot/data/text/text_nativerendering_subpixelpositions.qml
72ccf7
new file mode 100644
72ccf7
index 0000000000..c60fc4d8b0
72ccf7
--- /dev/null
72ccf7
+++ b/tests/manual/scenegraph_lancelot/data/text/text_nativerendering_subpixelpositions.qml
72ccf7
@@ -0,0 +1,91 @@
72ccf7
+import QtQuick 2.0
72ccf7
+
72ccf7
+//vary font style, native rendering at non-integer offsets
72ccf7
+
72ccf7
+Item {
72ccf7
+    id: topLevel
72ccf7
+    width: 320
72ccf7
+    height: 580
72ccf7
+
72ccf7
+    Repeater {
72ccf7
+        model: [Text.Normal, Text.Outline, Text.Raised, Text.Sunken]
72ccf7
+        Text {
72ccf7
+            y: 20 * index
72ccf7
+            clip: true
72ccf7
+            renderType: Text.NativeRendering
72ccf7
+            width: parent.width
72ccf7
+            wrapMode: Text.Wrap
72ccf7
+            font.pointSize: 10
72ccf7
+            style: modelData
72ccf7
+            styleColor: "green"
72ccf7
+            text: "The quick fox jumps in style " + modelData
72ccf7
+        }
72ccf7
+    }
72ccf7
+
72ccf7
+    Repeater {
72ccf7
+        model: [Text.Normal, Text.Outline, Text.Raised, Text.Sunken]
72ccf7
+        Text {
72ccf7
+            y: 100.5 + 20 * index
72ccf7
+            clip: true
72ccf7
+            renderType: Text.NativeRendering
72ccf7
+            width: parent.width
72ccf7
+            wrapMode: Text.Wrap
72ccf7
+            font.pointSize: 10
72ccf7
+            style: modelData
72ccf7
+            styleColor: "green"
72ccf7
+            text: "The quick fox jumps in style " + modelData
72ccf7
+        }
72ccf7
+    }
72ccf7
+
72ccf7
+    Repeater {
72ccf7
+        model: [Text.Normal, Text.Outline, Text.Raised, Text.Sunken]
72ccf7
+        Text {
72ccf7
+            y: 200.5 + 20 * index
72ccf7
+            x: 0.5
72ccf7
+            clip: true
72ccf7
+            renderType: Text.NativeRendering
72ccf7
+            width: parent.width
72ccf7
+            wrapMode: Text.Wrap
72ccf7
+            font.pointSize: 10
72ccf7
+            style: modelData
72ccf7
+            styleColor: "green"
72ccf7
+            text: "The quick fox jumps in style " + modelData
72ccf7
+        }
72ccf7
+    }
72ccf7
+
72ccf7
+    Repeater {
72ccf7
+        model: [Text.Normal, Text.Outline, Text.Raised, Text.Sunken]
72ccf7
+        Text {
72ccf7
+            y: 300.5 + 20 * index
72ccf7
+            x: 0.5
72ccf7
+            clip: true
72ccf7
+            renderType: Text.NativeRendering
72ccf7
+            width: parent.width
72ccf7
+            wrapMode: Text.Wrap
72ccf7
+            font.pointSize: 10
72ccf7
+            style: modelData
72ccf7
+            styleColor: "green"
72ccf7
+            text: "The quick fox jumps in style " + modelData
72ccf7
+        }
72ccf7
+    }
72ccf7
+
72ccf7
+    Repeater {
72ccf7
+        model: [Text.Normal, Text.Outline, Text.Raised, Text.Sunken]
72ccf7
+        Rectangle {
72ccf7
+            y: 400.5 + 20 * index
72ccf7
+            x: 0.5
72ccf7
+            width: topLevel.width
72ccf7
+            height: topLevel.height
72ccf7
+            clip: true
72ccf7
+            Text {
72ccf7
+                renderType: Text.NativeRendering
72ccf7
+                width: parent.width
72ccf7
+                wrapMode: Text.Wrap
72ccf7
+                font.pointSize: 10
72ccf7
+                style: modelData
72ccf7
+                styleColor: "green"
72ccf7
+                text: "The quick fox jumps in style " + modelData
72ccf7
+            }
72ccf7
+        }
72ccf7
+    }
72ccf7
+}
72ccf7
-- 
72ccf7
2.31.1
72ccf7