Bug 131561 - Subpixel rendering: Content with ::before leaves bits behind while animating its position.
Summary: Subpixel rendering: Content with ::before leaves bits behind while animating ...
Status: ASSIGNED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Layout and Rendering (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: zalan
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-04-11 13:51 PDT by zalan
Modified: 2014-04-13 23:35 PDT (History)
2 users (show)

See Also:


Attachments
Test reduction (460 bytes, text/html)
2014-04-11 13:52 PDT, zalan
no flags Details
Patch (6.70 KB, patch)
2014-04-13 12:28 PDT, zalan
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description zalan 2014-04-11 13:51:55 PDT
it's the combination of ::before + (non-compositing)layer + starting position being off screen + moving the content by 0.05 (has to be less than 0.1)

div:before {
 position: absolute;
  top: 0px;
  left: -1px;
  width: 100px;
  height: 100px;
  background-color: red;
  content: "";
}

div {
  position: absolute;
  -webkit-transform: translateX(0px);
}

setInterval(function() { document.getElementById("foo").style.left = pos + "px"; pos += 0.05; }, 10);
Comment 1 zalan 2014-04-11 13:52:26 PDT
Created attachment 229159 [details]
Test reduction
Comment 2 zalan 2014-04-13 12:28:38 PDT
Created attachment 229240 [details]
Patch
Comment 3 zalan 2014-04-13 12:29:10 PDT
Comment on attachment 229240 [details]
Patch

EWS first.
Comment 4 Darin Adler 2014-04-13 23:35:11 PDT
Comment on attachment 229240 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=229240&action=review

> Source/WebCore/platform/LayoutUnit.h:948
> -    return roundf((value.rawValue() * pixelSnappingFactor) / kEffectiveFixedPointDenominator) / pixelSnappingFactor;
> +    int rawValue = value.rawValue();
> +    if (rawValue >= 0)
> +        return roundf((rawValue * pixelSnappingFactor) / kEffectiveFixedPointDenominator) / pixelSnappingFactor;
> +
> +    // We need to ceil negative halfway values to maintain rounding direction.
> +    float halfwayRoundingValue = kEffectiveFixedPointDenominator / pixelSnappingFactor / 2;
> +    if (!fmodf(rawValue, halfwayRoundingValue))
> +        return ceilf((rawValue * pixelSnappingFactor) / kEffectiveFixedPointDenominator) / pixelSnappingFactor;
> +    return roundf((rawValue * pixelSnappingFactor) / kEffectiveFixedPointDenominator) / pixelSnappingFactor;

There is a simpler way of doing this without all the branching. Should just do floorf(x + 0.5f).