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

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