About subpixel accumulation through non-translation transforms |
||||||
Issue descriptionThis is separated from bug 710665 for the composited layer positioning case. The attached test case reproduces the issue. The 3rd and 4th squares jump around because of this issue.
,
May 1 2017
I'm not sure what the correct values in the following cases. I marked all unsure values with "?".
<style>
body { margin: 0 }
.container { position: relative; width: 0; height: 0; left: 0.3px }
.composited { will-change: transform; }
.scale { transform-origin: 0 0; transform: scale(40); }
.child { width: 1px; height: 1px; background: blue; position: relative; left: 0.4px }
</style>
<div class="container scale composited">
<div class="child composited"></div>
</div>
current correct?
container GraphicsLayer
position 0,0 0,0
bounds 0,0 0,0
subpixelAccumulation 0.3,0 0,0?
offsetFromLayoutObject 0,0 -0.3,0?
child GraphicsLayer
position 1,0 0,0?
bounds 1,1 1,1?
subpixelAccumulation -0.3,0 0.4,0? [1]
offsetFromLayoutObject 0,0 -0.7,0?
child painted offset 0.4,0 0.4,0?
child abs painted location 40,0 40x40 0,0 40x40? [2]
[1] The current value -0.3 results from 0.4 + 0.3 - 1.
[2] With https://codereview.chromium.org/2847873002/, in non-composited cases, we'll paint the child at absolute location (0.3,0 40x40). The 0.3 fraction is because of the subpixelAccumulation baked in container's transform. However, I'm not sure if we can do the same for composited cases because CompositedLayerMapping seems to always assume integer locations of GraphicsLayers (though GraphicsLayer allows FloatPoint). Without the subpixelAccumulation baked into transform, the "correct?" absolute painted location would be snapped to 0,0 40x40.
The following table shows the difference between non-composited and composited cases, with https://codereview.chromium.org/2847873002/ and if we achieve the "correct?" values:
<child abs painted location>
container child non-composited composited
0.3 0.1 0.1,0 0,0
0.3 0.4 0.3,0 0,0?
0.6 0.4 0.6,0 1,0?
0.3 0.8 40.3,0 40,0?
0.6 0.8 40.6,0 41,0?
0.9 0.8 40.9,0 41,0?
For comparison, the following are the current values that are mostly incorrect:
<child abs painted location>
container child non-composited composited
0.3 0.1 0,0 0,0
0.3 0.4 40,0 40,0
0.6 0.4 1,0 1,0
0.3 0.8 41,0 41,0
0.6 0.8 1,0 1,0
0.9 0.8 41,0 41,0
Firefox's behavior:
<child abs painted location>
container child non-composited composited
0.3 0.1 0,0 0,0
0.3 0.4 16,0 0,0
0.6 0.4 17,0 1,0
0.3 0.8 32,0 40,0
0.6 0.8 33,0 41,0
0.9 0.8 33,0 41,0
IE 11's behavior:
<child abs painted location>
container child non-composited composited
0.3 0.1 0,0 0,0
0.3 0.4 16,0 16,0
0.6 0.4 17,0 17,0
0.3 0.8 32,0 32,0
0.6 0.8 33,0 33,0
0.9 0.8 33,0 33,0
Perhaps IE 11 and Firefox non-composited behavior is the most correct?
,
May 3 2017
As https://codereview.chromium.org/2847873002 is being reverted, I use this bug to track all subpixel accumulation issues. The solution might be to still accumulate subpixels, but the accumulated subpixel will be applied in screen space instead of the transformed space (that is, the accumulated subpixel is in pixel unit of screen-space). A further step might be to implement the FireFox and IE behavior: when painting, we snap to pixel in screen space instead of transformed space (which might not be applicable to non-translate non-scale transforms).
,
May 3 2017
This is a test case reduced from bug 717882 . The circle and the disc are at the same location, and the disc is scaled by 0.5. It's reasonable to expect that their centers are aligned, given that their sizes are even numbers.
,
May 3 2017
I think the testcase you uploaded in #4 is garbled.
,
May 3 2017
Sorry. This is the correct test case.
,
May 3 2017
,
May 3 2017
,
May 4 2017
It seems good to snap paint offset translation to whole pixels, and discard the remainder if the object has a non-translation transform. The attached test case shows the result. FireFox seems to behave in the above way.
,
May 4 2017
The test case for #9.
,
May 4 2017
If we change how this snaps, will it change how transformed and non-transformed content aligns? I worry about introducing bleed on content designed based on how webkit and blink currently work. FWIW, Edge just shows blue in the subpixel1.html testcase.
,
May 4 2017
For the #9 test case, either discarding the remainder or not won't align the blue and red aligned squares in Chrome. I guess Edge aligns them because it doesn't discard the remainder, and accumulates sub pixels in screen space (that is, accumulated sub pixels are not transformed), and snap to pixel in screen space. I guess FireFox also snaps to pixels in screen space based on the behaviors described in #2. Without accumulating subpixels and snapping to pixels in screen space, we might have to discard the remainder to make things better (making the squares not jump around in subpixel.html (#0), while keeping the composited and non-composited paintings aligned in radio.html (#1)).
,
May 10 2017
commit d9e07a4e55c864a16fc67366c2a29efd037c5c3c Author: Xianzhu Wang <wangxianzhu@chromium.org> Date: Wed May 10 15:30:27 2017 -0700 Don't pass subpixel offsets through non-translation transforms (composited case) For non-translation transforms, discard subpixel accumulation. BUG= 717882 CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2 R=chrishtr@chromium.org Review-Url: https://codereview.chromium.org/2868933002 . Cr-Commit-Position: refs/heads/master@{#470733} |
||||||
►
Sign in to add a comment |
||||||
Comment 1 by wangxianzhu@chromium.org
, Apr 28 2017Status: Assigned (was: Available)