New issue
Advanced search Search tips

Issue 716163 link

Starred by 1 user

Issue metadata

Status: Fixed
Owner:
Closed: May 2017
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux , Android , Windows , Chrome , Mac
Pri: 3
Type: Bug



Sign in to add a comment

About subpixel accumulation through non-translation transforms

Project Member Reported by wangxianzhu@chromium.org, Apr 27 2017

Issue description

This 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.
 
subpixel.html
983 bytes View Download
Owner: wangxianzhu@chromium.org
Status: Assigned (was: Available)
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?
Summary: About subpixel accumulation through non-translation transforms (was: Should not accumulate subpixel through non-translation transforms when positioning composited layers)
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).

Components: Blink>Paint
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.
I think the testcase you uploaded in #4 is garbled.
Sorry. This is the correct test case.
radio.html
296 bytes View Download
Labels: BugSource-Team PaintTeamTriaged-20170503
Labels: -OS-All OS-Android OS-Chrome OS-Linux OS-Mac OS-Windows
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.
The test case for #9.
subpixel1.html
494 bytes View Download

Comment 11 by pdr@chromium.org, 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.
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)).

Status: Fixed (was: Assigned)

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