Randomly corrupt font / text / characters in Unity8

Bug #1583088 reported by Daniel van Vugt on 2016-05-18
62
This bug affects 8 people
Affects Status Importance Assigned to Milestone
Canonical System Image
High
Michał Sawicz
Mir
Opinion
Undecided
Unassigned
gnome-desktop (Ubuntu)
Undecided
Unassigned
mir (Ubuntu)
Undecided
Unassigned
qtdeclarative-opensource-src (Ubuntu)
High
Unassigned
qtmir (Ubuntu)
High
Gerry Boland
unity8 (Ubuntu)
High
Unassigned

Bug Description

Corrupted characters in text rendering.

Only happens after starting non-GL application, like GTK application or mir_demo_client_fingerpaint.

Related branches

Changed in unity8 (Ubuntu):
importance: Undecided → High
summary: - Corrupted characters in text rendering, mainly in Unity8 window
+ Randomly corrupt characters in text rendering, mainly in Unity8 window
titlebars
Changed in qtmir (Ubuntu):
importance: Undecided → High
kevin gunn (kgunn72) wrote :

comparison screenshot even better

Daniel van Vugt (vanvugt) wrote :

Here's a screenshot of a couple of slightly corrupt titlebars.

Ignore the messed up window contents. That's just a screenshot bug I'll log separately. The window contents look right on the real screen. But the corrupt titlebar text is visible.

Daniel van Vugt (vanvugt) wrote :

Other bugs are visible in that screenshot:
  Blurry window contents after moving (Web Browser) -> bug 1510382
  White/translucent window contents for screenshots of Xmir -> bug 1583399
  All white QML window contents for Scopes -> bug 1577639
  Thin titlebar font -> bug 1583092

Sorry for the confusion. I didn't intend to capture so may bugs in one picture.

Daniel van Vugt (vanvugt) wrote :

Oh bug 1543467 is visible too.

Gerry Boland (gerboland) wrote :

This is on Intel I guess? Your investigations into bug 1580792 does point out that the driver complains of a bad argument to glCopyTexSubImage - the only consumer of glCopyTexSubImage that I can find is in the Qt's font rendering system - so if it fails, it would cause font rendering issues. That's my best guess currently

Daniel van Vugt (vanvugt) wrote :

glCopyTexSubImage isn't failing (it reports no errors), just falling back to slower software rasterization. So that should be visually correct, just slower. It should be unrelated to this bug.

Daniel van Vugt (vanvugt) wrote :

It's only certain characters that are sometimes corrupt. So it's the typography renderer at fault and not the shell.

Here's a pair of screenshots showing the glyph '4' is corrupt for me today, and what it looks like when the clock changes from '11:43' to '11:44'.

Daniel van Vugt (vanvugt) wrote :

And a completely different screenshot of the same bug. Here it's kind of more obvious that the glyph renderer is using an incorrect buffer stride/width.

Marlin Forbes (datashaman) wrote :

I'm seeing the same corruption in Gnome Shell in Ubuntu Xenial, it's not Unity-specific. I'm using the intel graphics driver from ppa:oibaf/graphics-drivers (to try and upgrade myself out of the issue), but it was happening before changing to a custom PPA.

affects: gnome-shell → ubuntu
affects: ubuntu → gnome-desktop (Ubuntu)
summary: - Randomly corrupt characters in text rendering, mainly in Unity8 window
- titlebars
+ Randomly corrupt characters in Unity8 window titlebars and logout dialog
tags: added: visual-quality

Status changed to 'Confirmed' because the bug affects multiple users.

Changed in gnome-desktop (Ubuntu):
status: New → Confirmed
Changed in qtmir (Ubuntu):
status: New → Confirmed
Changed in unity8 (Ubuntu):
status: New → Confirmed
Michał Sawicz (saviq) on 2016-07-04
summary: - Randomly corrupt characters in Unity8 window titlebars and logout dialog
+ Randomly corrupt characters in Unity8
kevin gunn (kgunn72) on 2016-07-05
tags: added: unity8-desktop

If you can reproduce this relative easily, could you try setting QML_USE_GLYPHCACHE_WORKAROUND=1 for unity8. This should do the trick:

stop unity8 && start unity8 QML_USE_GLYPHCACHE_WORKAROUND=1

Can also try these:
QSG_DISTANCEFIELD_ANTIALIASING=subpixel-lowq or gray

Need to determine if that text is being drawn by the DistanceField approach, or using the "native" rendering technique
http://doc.qt.io/qt-5/qml-qtquick-text.html#renderType-prop

If distance field, perhaps the contents of the distance field texture is corrupted somehow. Grabbing the contents of the texture to visually verify it is corrupt or not would be my next step. apitrace might be able to grab the texture. Else would need to write code..

Changed in gnome-desktop (Ubuntu):
status: Confirmed → Invalid
kevin gunn (kgunn72) wrote :

so question was asked from a previous dupe bug about repro steps. afaict, there are no specific repro steps and the specific letters which get corrupted seems random. But I've been using unity8 quite regularly, and I've seen this several times so doesn't seem infrequent.

Might be worth noting that once a letter gets corrupt it seems corrupted everywhere for that rendering - for instance on the power down prompt, the letter "f" is repeated in the word "off" in 2 different places - in one experience, no other letters were corrupted expect "f" in all 4 locations.

Gerry Boland (gerboland) wrote :

That would imply the distance field texture is corrupted.

As a note to myself, there is a nice glyph test application in this bug:
https://bugreports.qt.io/browse/QTBUG-49490

Gerry Boland (gerboland) wrote :

Also worth noting, there are env vars:
QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH & HEIGHT to set the size of the glyph cache. Need to see what size texture Qt is creating, perhaps it is creating one too large for the hardware </guess>

draco (draco31-fr) wrote :

Screenshot on comment 12 seems very close to behaviour in bug #1573959 , which is present only on Intel graphic cards. Could it be the same bug ?

Daniel van Vugt (vanvugt) wrote :

Comments #11 and #12 are not this bug at all. I have hidden those now to avoid confusion.

Daniel van Vugt (vanvugt) wrote :

This is still happening in zesty (seen today in the Unity8 indicator menu and logout dialog).

It looks like the text renderer might have mistaken buffer width for buffer stride in some cases...?

Changed in canonical-devices-system-image:
importance: Undecided → High
status: New → Confirmed
dinamic (dinamic6661) wrote :

same here on both 17.04 and 16.04+overlay (intel and nvidia)

Daniel van Vugt (vanvugt) wrote :

Just updating the bug title so that people searching for keywords can find it (Launchpad only finds keywords separated by spaces)

summary: - Randomly corrupt characters in Unity8
+ Randomly corrupt font/text/characters in Unity8
summary: - Randomly corrupt font/text/characters in Unity8
+ Randomly corrupt font / text / characters in Unity8
dinamic (dinamic6661) wrote :

just my observation, i only see character corruption when using Xmir (on desktop), i am now using unity8 for 20h and the fonts look ok, no corruption.

dinamic (dinamic6661) wrote :

hm.. ok.. so not sure it's Xmir, now i gedit corrupted my fonts, after 20h of using only ubuntu system apps and qt5 apps i just run "ubuntu-app-launch gedit" and my fonts are corrupted now, i have to restart :D

Daniel van Vugt (vanvugt) wrote :

It's not Xmir. I experience this bug with the default Unity8 setup (just settings and web browser apps).

Daniel van Vugt (vanvugt) wrote :

Without knowing what project is to blame or where the source code is, I think this actually looks like a glPixelStorei bug, or lack of glPixelStorei. If you don't call glPixelStorei before your glTexImage2D then the default unpack alignment is 4 bytes. And it's possible the font glyph cache code doesn't know that, assuming default stride alignment is to 1 byte accuracy instead.

kevin gunn (kgunn72) wrote :

@Gerry
I was going to try your suggestion, stop unity8 && start unity8 QML_USE_GLYPHCACHE_WORKAROUND=1. but it seems simply starting and stopping unity8 is unhappy on zesty atm

fwiw, my current setup I'm seeing this 100%, and i agree cache seems likely as first few windows are ok, but eventually text gets corrupt

Gerry Boland (gerboland) wrote :

@kgunn - yes I can reproduce it quite reliably too. No need to try the glyph cache workaround thing, I checked it and it had no impact.

@duflu - Qt is rendering the text.

Since Qt renders text ok in Unity7, there must be some GL configuration problem in QtMir/QtUbuntu causing this kind of issue. At the moment, I've not really dug into why.

Daniel van Vugt (vanvugt) wrote :

It could still be lack of glPixelStorei. In many cases the default unpack alignment will be right by accident, so in those cases the text will appear correct. It's possible that a different backend (X11 vs Mir) creates a slightly different GL state and so the bug only appears in some backends but not others.

Daniel van Vugt (vanvugt) wrote :

I'm referring to the diagonal lines problem, like we see here and like is documented here:
https://www.khronos.org/opengl/wiki/Common_Mistakes#Texture_upload_and_pixel_reads

Gerry Boland (gerboland) wrote :

I'm looking into this now. I took an api trace of some simple font rendering by Qt on Mir showing the problem, and executed it on my X11 session. It renders ok on X11. Reading through the apitrace, Qt seems to be doing the right thing.

I suspect the mismatch we have between Mir creating a GLES context and Qt expecting a GL context is hitting us here.

Daniel van Vugt (vanvugt) wrote :

If you could point me to the exact code that does the glyph rendering/caching I would be interested to read it...

Gerry Boland (gerboland) on 2017-02-14
Changed in unity8 (Ubuntu):
status: Confirmed → Invalid
Changed in qtmir (Ubuntu):
status: Confirmed → In Progress
assignee: nobody → Gerry Boland (gerboland)
description: updated
Gerry Boland (gerboland) wrote :

@vanvugt
you were right that glPixelStorei was to blame. In ShmBuffer Mir uses glPixelStorei to change the GL_UNPACK_ALIGNMENT from 4 (that Qt set) to 1 (that Mir sets, as it is more careful about stride).

Mir fails to restore the state the Qt set, which broke Qt's rendering from then on.

ShmBuffer only used for clients that do not use GL to draw, so Gtk and mir demos like fingerpaint, which is why this bug was "random"

Could Mir be patched to revert any GL state changes it makes, when called into by Qt?

Daniel van Vugt (vanvugt) wrote :

Yes, but probably no :)

Performance of the GL pipeline suffers, sometimes dramatically, if you glGet-anything like the current GL_UNPACK_ALIGNMENT.

So getting it for later restoration is highly undesirable. Better to just set it to the right value whenever it's important. That keeps communication between the CPU and GPU in one direction and avoids stalling the pipeline.

https://www.khronos.org/opengl/wiki/Common_Mistakes#glGetFloatv_glGetBooleanv_glGetDoublev_glGetIntegerv

Changed in mir (Ubuntu):
status: New → Won't Fix
Changed in mir:
status: New → Won't Fix
Changed in canonical-devices-system-image:
status: Confirmed → In Progress
assignee: nobody → Michał Sawicz (saviq)
Changed in qtdeclarative-opensource-src (Ubuntu):
importance: Undecided → High
dinamic (dinamic6661) wrote :

using silo 2481, seems to work fine, i don't see the font corruption anymore

Daniel van Vugt (vanvugt) wrote :

Awesome.

I would like to see a permanent fix done in a more appropriate place though. I think somewhere in qtdeclarative-opensource-src there is the bad assumption about the current state of GL_UNPACK_ALIGNMENT. We need to find that code and add an explicit setting right before it uploads the corrupt/skewed texture.

Gerry Boland (gerboland) wrote :

Here is what Qt is doing, on upload:
https://code.woboq.org/qt5/qtdeclarative/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp.html#158
It saves & restores the alignment, and assumes the default alignment of 4 for drawing. IMO Mir isn't playing along, as it changes the alignment but does not restore it.

Daniel van Vugt (vanvugt) wrote :

Assuming the current value is 4 might be incorrect in this case but also won't cause the bug unless they also fail to call "glPixelStorei(GL_UNPACK_ALIGNMENT, 4)" somewhere that they need it to be 4.

Where you see Qt code that uses alignment 1, that's not relevant here because it will play perfectly with Mir. The problem is elsewhere... some GL unpacking without a glPixelStorei call is being done and that location expects/requires alignment of 4.

So I guess start by searching for all glTexImage2D calls and ensure they are all /immediately/ preceded by glPixelStorei. It's possible Qt already has some housekeeping for that but then the bind call happens in the middle:

Qt: glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
Qt: calls the offending Mir bind code
Qt: glTexSubImage2D or glTexImage2D

So the fix then would still be in qtdeclarative; either reorder lines 1 & 2, or add another glPixelStorei call in before the glTex*Image2D calls in Qt.

Launchpad Janitor (janitor) wrote :

Status changed to 'Confirmed' because the bug affects multiple users.

Changed in qtdeclarative-opensource-src (Ubuntu):
status: New → Confirmed
kevin gunn (kgunn72) on 2017-03-06
Changed in canonical-devices-system-image:
milestone: none → u8c-1
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package qtmir - 0.5.1+17.04.20170307-0ubuntu1

---------------
qtmir (0.5.1+17.04.20170307-0ubuntu1) zesty; urgency=medium

  [ Albert Astals Cid ]
  * Fix clang build

  [ Daniel d'Andrada ]
  * Some qtmir::Session fixes
  * Make TaskController absorb SessionManager
  * Don't pass command line arguments to Mir
  * Reduce default log verbosity (LP: #1664151)
  * DBusFocusInfo: fix crash when trying to access a null session from
    an application (LP: #1670710)

  [ Gerry Boland ]
  * Workaround for Mir changing GL state unexpectedly on Qt, breaking
    font rendering. (LP: #1583088)

  [ Lukáš Tinkl ]
  * Use the shell chrome, as provided by miral window info (LP:
    #1658117)

 -- Lukáš Tinkl <email address hidden> Tue, 07 Mar 2017 23:43:16 +0000

Changed in qtmir (Ubuntu):
status: In Progress → Fix Released
Michał Sawicz (saviq) on 2017-03-13
Changed in canonical-devices-system-image:
status: In Progress → Fix Released
Changed in mir:
status: Won't Fix → Opinion
Changed in mir (Ubuntu):
status: Won't Fix → Opinion
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers