Open Bug 1825871 Opened 1 year ago Updated 3 months ago

box-shadows render unevenly if they work out to being 1.5 display pixels thick on the user's display

Categories

(Core :: Graphics: WebRender, defect)

Firefox 111
defect

Tracking

()

Tracking Status
firefox-esr102 --- wontfix
firefox111 --- wontfix
firefox112 --- wontfix
firefox113 --- fix-optional

People

(Reporter: unison447, Unassigned)

References

(Blocks 2 open bugs, Regression)

Details

(Keywords: regression)

Attachments

(4 files)

Attached image firefox_VoN4uxQwXB.png

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/111.0

Steps to reproduce:

This bug I can reproduce ONLY with 4k (3840x2160) monitor, in windows display scale to 150% (as recomended for this monitor) and page scale in browser 100%.

I create a simple component.
HTML
<div></div>

CSS
div {
width: 100px;
height: 48px;
box-shadow: inset 0 0 0 1px blue;
}

Actual results:

You can visit this link and if you have not 4k monitor - you should see just rectangle with 1px "border".
But if you have setup like I describe, you will see the "border" on the top and left is thicker than on the right and bottom.

https://codepen.io/serhiishf/pen/dyqBMmL

Expected results:

Expected result - just rectangle with the same "border" thickness

The Bugbug bot thinks this bug should belong to the 'Core::Layout' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.

Component: Untriaged → Layout
Product: Firefox → Core

Also if add (:hover) with (transition) for element with (box-shadow) this will slow down the animation on a 4k monitor.
You can see it by clicking on the following link: https://mozilla-box-shadow-bug.netlify.app/

Even an inexpensive FHD (1920 x 1080) monitor can reproduce the problem by increasing the zoom level (150% zoom on 100% dpi monitor, 120% zoom on 125% dpi monitor).

Interesting, I can't reproduce this on my machine with 100% or 125% DPI DPI (Linux, WebRender, AMD GPU, X11), though my monitor is pretty small at 1440x900.

:dholbert I remember you use non-100% DPI sometimes, can you take a look?

Flags: needinfo?(dholbert)

I can reproduce on Windows:

  • with 150% OS-level scaling (I reproduced at both 1920x1080 and 3440x1440).
  • with 100% OS-level scaling, if I use Firefox's full-page-zoom to zoom in 150%
    (in all of these cases, producing a window.devicePixelRatio of 1.5)

I can reproduce on Ubuntu with 150% full-page-zoom (under standard 100% os-level display settings), too. I'll post a reduced testcase.

I don't think this is exactly a bug. This is essentially a case where the page is requesting a box-shadow that is 1.5 device pixels wide (technically 1px but rendered with 150% display scaling that's 1.5 device pixels). We clearly can't draw a solid-color 1.5-device-pixel-wide line, so we have to round one way or the other. And apparently we round different ways depending on where the line falls on screen (e.g. depending on whether its left edge is device-pixel-aligned or not)

For borders, we have special handling for this, with a high-level principal that borders whose specified sizes are the same (whether fractional or not) have to be drawn with the same on-screen thickness. See https://crisal.io/words/2020/06/13/rounding-borders.html for a bunch of notes on this; as noted towards the beginning, "Rendering borders that aren’t crisp, or that are uneven, is not an option."

We don't necessarily have that same principal for box-shadow (since by definition shadows can be fuzzy). Though perhaps it would be nice to have something like that principal for cases like this...

(In reply to Daniel Holbert [:dholbert] from comment #6)

See https://crisal.io/words/2020/06/13/rounding-borders.html for a bunch of notes on this; as noted towards the beginning, "Rendering borders that aren’t crisp, or that are uneven, is not an option."

For the box-shadow property (to which that principal doesn't apply as much & we compromise a bit), it looks to me like:

  • Chrome is compromising on the "crisp" aspect of that principal here; they render the 1.5-device-pixel box-shadow as being even-but-not-crisp.
  • Firefox is compromising on the "even" aspect -- we render the 1.5px box-shadow as being crisp-but-not-even.
Flags: needinfo?(dholbert)

Here's a testcase, using a variety of box-shadow widths.

When viewed at 100% display scaling (OS settings & full-page-zoom both at standard "100%" values), this shows the uneven box-shadow for the blue div (the one with a thickness of precisely 1.5).

Here's a screenshot comparing Firefox vs. Chrome on the attached testcase, showing the crisp-but-occasionally-uneven (Firefox) vs. even-but-not-crisp (Chrome) as described in my previous comment.

Looks like this is a regression. We used to render my attached testcase with a consistent 1px-thickness-shadow up until we actually reach 2 display pixels; i.e. all of the boxes in my testcase would render with a consistent 1px-thick shadow, except for the final one (with explicit 2px thickness in its style) which renders with a 2px thick shadow.

That regressed with this pushlog, on my system:
Nightly 2019-05-26 - 2019-05-27
https://hg.mozilla.org/mozilla-central/pushloghtml?fromchange=b223e35b6540089f2f9e7db8902f12cf85bb9c16&tochange=29c76bc4b5901f6fd331435e6db5ff47bcde04bb

In that range, this would've been Bug 1554251 - Enable WebRender on nightly for AMD hardware with Linux [...]

After that range, we nearly-but-not-quite match the current Nightly behavior shown in the left half of my above screenshot. The only difference back then (in Nightly 2019-05-27) was that we'd render the bottom & right edges of the blue shadow as being the thicker edges. We changed to the current behavior (upper & left edges being thicker) in this range:
Nightly 2019-09-13 - 2019-09-14
https://hg.mozilla.org/mozilla-central/pushloghtml?fromchange=598d441e4ebaa93ab098d266035a396057c82129&tochange=6cbf1430a66ef5aa5f066ed77677f47ea44fc0e1

In that range, the behavior-change would've probably been from bug 1574493 whose title is "Re-architect how WebRender snapping works" which seems reasonably-likely to have influenced this. (In any case, that's just an observation; that's not what regressed this.)

So: bottom line, this seems to have been a regression introduced via WebRender becoming enabled.

ni=gw to weigh in & assess severity, given that he worked on related-seeming bug 1523882 which mentioned "uneven rendering of box-shadows" (the thing we're getting here) as being something we want to avoid.

Status: UNCONFIRMED → NEW
Component: Layout → Graphics: WebRender
Ever confirmed: true
Flags: needinfo?(gwatson)

(In reply to Daniel Holbert [:dholbert] from comment #10)

[...] We used to render my attached testcase with a consistent 1px-thickness-shadow up until we actually reach 2 display pixels; i.e. all of the boxes in my testcase would render with a consistent 1px-thick shadow, except for the final one (with explicit 2px thickness in its style) which renders with a 2px thick shadow.

Here's a screenshot taken with Nightly 2019-05-26 to illustrate what that looked like.

(One additional thought, RE how this relates to emilio's blog post about borders -- one key difference with box-shadows is that they don't occupy layout-space; they're just a paint-time effect. That changes the constraint-space quite a bit, and simplifies things somewhat, I think.)

Summary: Bug with css property box-shadow on 4k monitor → box-shadows render unevenly if they work out to being 1.5 display pixels thick on the user's display
Severity: -- → S3

This bug has been marked as a regression. Setting status flag for Nightly to affected.

Blocks: wr-snap
Flags: needinfo?(gwatson)

:aosmond, since you are the author of the regressor, bug 1574493, could you take a look?

For more information, please visit auto_nag documentation.

Flags: needinfo?(aosmond)
Flags: needinfo?(aosmond)
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: