Open Bug 1562857 Opened 2 years ago Updated 2 years ago

[ARM] Text on reddit is washed out if using 100% scale from windows

Categories

(Core :: Graphics: Text, defect, P3)

ARM64
Windows 10
defect

Tracking

()

Tracking Status
firefox67 --- affected
firefox68 --- affected
firefox69 --- affected

People

(Reporter: bogdan_maris, Unassigned)

Details

Attachments

(3 files)

Attached image Image showing the issue

Affected versions

  • Firefox 66.0 RC
  • Firefox 68.0 RC
  • Latest Nightly 69.0a1

Affected platforms

  • Windows 10 ARM (Lenovo Yoga C630-13Q50)

Steps to reproduce

  1. Change the scale of text to 100% (Settings/Display/Scale and Layout)
    (windows will request to signout, do that)
  2. Start Firefox
  3. Open https://www.reddit.com

Expected result

  • The test on the website is correctly displayed.

Actual result

  • In many areas the text is washed out.

Regression range

  • This is not a regression since it reproduces to the first build available on ARM as well (Fx67).

Additional notes

  • Resolution of the display is 1920 x 1080, Scale and layout to 100%, only one monitor. (I did signed out after altering the scale)
  • GPU: Qualcomm(R) Adreno(TM) 630
  • There are no issues if using the recommended setting for scale - 150%
  • Chrome does not have this issue.
Has Regression Range: --- → irrelevant
Has STR: --- → yes

For comparison, could you also attach a screenshot of how Chrome renders the same content, at the same scale? Thanks.

Flags: needinfo?(bogdan.maris)

Sure thing. Please let me know if I can help further on.
Firefox on the left | Chrome on the right

Flags: needinfo?(bogdan.maris) → needinfo?(jfkthame)

So the main issue here seems to be that at small sizes, we're rendering the IBM Plex Sans font that reddit uses without any antialiasing. Looking closely at text such as "r/aww" and "Posted by u/BenVenn..." we can see that the Chrome screenshot has antialiasing (font smoothing) applied, while the Firefox version does not; it's blocky, uneven and aliased.

Looking in the font resources they're using (e.g. https://www.redditstatic.com/desktop2x/fonts/IBMPlexSans/Regular-116bb6d508f5307861d3b1269bc597e7.woff2, which is the Regular face of IBM Plex Sans), there is this 'gasp' table in the font:

<gasp>
  <gaspRange rangeMaxPPEM="8" rangeGaspBehavior="10"/>
  <gaspRange rangeMaxPPEM="16" rangeGaspBehavior="5"/>
  <gaspRange rangeMaxPPEM="65535" rangeGaspBehavior="15"/>
</gasp>

And checking the OpenType spec at https://docs.microsoft.com/en-gb/typography/opentype/spec/gasp, we find that the values here indicate:

  • 10: GASP_DOGRAY | GASP_SYMMETRIC_SMOOTHING
  • 5: GASP_GRIDFIT | GASP_SYMMETRIC_GRIDFIT
  • 15: GASP_GRIDFIT | GASP_DOGRAY | GASP_SYMMETRIC_GRIDFIT | GASP_SYMMETRIC_SMOOTHING

So the expected rendering should be:

  • Sizes <= 8ppem: no grid-fitting, apply antialiasing
  • Sizes <= 16ppem: apply grid-fitting, no antialiasing
  • Larger sizes: apply grid-fitting and antialiasing

That small text has font-size: 12px, so at 100% scaling, it's rendered at 12ppem and so we do what the 'gasp' table says: grid-fitting, no antialiasing. Unfortunately, the result is really ugly; the font doesn't look as though it was actually hinted well for this rendering mode.

At 150% scaling, the 12px text will resolve to 18ppem, so it uses the "larger sizes" mode where antialiasing is applied.

Apparently, Chrome doesn't respect the rendering modes requested by the font via its 'gasp' table; it just makes its own decision and uses antialiasing regardless of the size. Maybe we should do the same, if there are lots of fonts out there with bad 'gasp' tables. (I suspect this one was just set to default values, maybe by a font authoring tool, without proper consideration or review. It's interesting to note that the thresholds at 8ppem and 16ppem just happen to match the "typical" size thresholds suggested in the 'gasp' table documentation.)

Component: Layout: Text and Fonts → Graphics: Text
Flags: needinfo?(jfkthame)

Marking as P3 because it sounds like we are doing the right thing, and the fix would be somewhat radical by ignoring hints from the font; maybe there are cases where it looks bad only in Chrome because we honour the hints? Needinfo'ing Lee however to get his thoughts on the matter.

Flags: needinfo?(lsalzman)
Priority: -- → P3

Bug 1321901 is where Mason modified Skia to use DWrite's GetRecommendedRenderingMode which theoretically is what checks the gasp table. Now, even without that modification, Skia has its own code to dig into the gasp table without GetRecommendedRenderingMode, although that code doesn't disable AA. The overriding concern there was to make rendering results consistent with what Direct2D does.

Direct2D is currently blacklisted on ARM due to stability/correctness issues, but it would be nice to know how it tries to render the font. If you force-enable direct2d with the gfx.direct2d.force-enabled pref, does it disable anti-aliasing as well?

Flags: needinfo?(lsalzman) → needinfo?(bogdan.maris)

(In reply to Lee Salzman [:lsalzman] from comment #5)

Bug 1321901 is where Mason modified Skia to use DWrite's GetRecommendedRenderingMode which theoretically is what checks the gasp table. Now, even without that modification, Skia has its own code to dig into the gasp table without GetRecommendedRenderingMode, although that code doesn't disable AA. The overriding concern there was to make rendering results consistent with what Direct2D does.

Direct2D is currently blacklisted on ARM due to stability/correctness issues, but it would be nice to know how it tries to render the font. If you force-enable direct2d with the gfx.direct2d.force-enabled pref, does it disable anti-aliasing as well?

Sorry for the late reply.
Forcing direct2d with that pref changed nothing for me in terms of visuals. Dumb question alert: How can I check if forcing direct2d had disabled anti-aliasing or not in this case?

Flags: needinfo?(bogdan.maris) → needinfo?(lsalzman)

In this case, if it looked the same as with Skia, then you know it didn't disable AA, or there might be some possibility that Direct2D somehow still didn't get enabled (verify via about:support). So if Direct2D itself is doing this, then it makes changing it a harder sell since then we're going to be disagreeing with even how Direct2D is trying to interact with DirectWrite internally.

Flags: needinfo?(lsalzman)

Checking about:support after forcing direct2d I see that it got enabled.
I did noticed that activating clearType from windows solved the looks on reddit though.

You need to log in before you can comment on or make changes to this bug.