Open Bug 739176 Opened 13 years ago Updated 11 months ago

No sub-pixel rendering while transitioning translate transforms

Categories

(Core :: Layout, defect)

x86
macOS
defect

Tracking

()

People

(Reporter: jaffathecake, Unassigned)

References

Details

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.83 Safari/535.11 Steps to reproduce: http://dabblet.com/gist/2204184 Actual results: Both circles exhibit a jerky transition on hover Expected results: WebKit transitions the 2nd circle using sub-pixel positioning, giving a smoother animation, similar to Flash transitions. Although this isn't part of the specification, using non-integer pixel values in transforms make animations much smoother, especially on displays where 1 css pixel is greater than one device pixel.
Component: Untriaged → Layout
Product: Firefox → Core
QA Contact: untriaged → layout
Version: 13 Branch → Trunk
As far as I know we do in fact do subpixel positioning for both transforms and style.left....
It doesn't appear so from the example, or are you seeing something different?
I'm definitely seeing the jerkiness in the example; it would be even more obvious if you made the transition 20s long, not 2s long. What I don't understand is why it's happening; that seems like a paint-time effect, not layout-time...
For active transforms, we snap coordinates to integers when rendering. It's a performance improvement because it means we don't need to constantly rerender the transformed object.
Note that we snap to device pixels, so for high-density displays it should look smoother.
We don't currently have support for subpixel rendering of border-radius so even if we did rerender the object on every frame and let its layer take a subpixel offset, the visual results would be the same.
I'm not sure what Chrome does ... maybe they render the moving object's layer at a subpixel offset, so it gets resampled? That'd work OK for these green circles, but I think in general it would look poor.
I'd like to test that assumption, what is 'general' in terms of transitioned & translated items on the web? Interestingly, Firefox DOES do sub-pixel positioning if you throw in a tiny little rotate http://dabblet.com/gist/2214045. Why switch on this?
When we rotate, we have to resample the buffer and things necessarily get blurry. Try an example that has lots of thin vertical lines that are pixel-aligned, and transition it horizontally, slowly.
Here you go http://dabblet.com/gist/2214028 I still prefer the 2nd, higher framerate although it phases in and out a bit. I think you hit the nail on the head when you considered what it might look like 'in general'. I don't think animating things with thin vertical lines is the general case. How would you decide what is general in transitions & transforms?
Thanks for that. The text toggling between blurred and non-blurred looks quite awful to me. It's subjective. We could change our behavior so that your use-cases look better to you, but quite probably someone will soon file a bug complaining that we made their use-cases look worse to them. Unfortunately it's not easy to figure out what maximises the total happiness of users. The good news is comment #5; as display density increases, this matters less.
What would convince you that sub pixel positioning would have an overall positive effect? I'm having trouble finding an in-the-wild example that would show the negatives of the slow-moving-text example. I did a quick poll on Twitter (and I understand this isn't a scientific test) and people were pretty split on the "worst case" example, perhaps even still preferring the webkit method. Do you have any in-the-wild examples that would be worse off with smoother sub-pixel animation?
Oops, was supported to link to the tweet https://twitter.com/#!/jaffathecake/status/184564915607056384
(In reply to Jake Archibald from comment #12) > What would convince you that sub pixel positioning would have an overall > positive effect? I don't know. Sorry. > I'm having trouble finding an in-the-wild example that > would show the negatives of the slow-moving-text example. Most transitions are not slow enough to show the problem in this bug *or* the text example. As far as I know this is the first Bugzilla bug on the subject. One extra factor that comes into this is that when not using GPU acceleration, resampling for subpixel offsets is much slower than just copying to integer device coordinates. So we definitely would not change this for the non-accelerated case, and keeping the accelerated case consistent with that is beneficial.
Blocks: 770810
We're running into this while trying to implement Shumway rendering using many DOM elements instead of one large canvas. At least when it comes to Flash animations, there are many cases where this is very clearly visible and looks much worse than what Chrome does. Is there any chance to get a CSS property similar to `image-rendering` for specifying whether sub-pixel rendering should be applied during transitions or not?
Status: UNCONFIRMED → NEW
Ever confirmed: true
Flags: needinfo?(roc)
Can you say something about the content you're animating? And how slow your transitions are?
Flags: needinfo?(roc)
(In reply to Robert O'Callahan (:roc) (Mozilla Corporation) from comment #16) > Can you say something about the content you're animating? And how slow your > transitions are? As we aren't trying to support some specific content directly, that's hard to do. We want to support as broad a range of existing Flash content as possible. Supporting very smooth animations even for slow-moving elements is an important quality of the Flash rendering system, however, so not being able to support it would be a serious issue for us.
Apart from Shumway's needs, I think that there are some arguments to be made in favor of always having sub-pixel rendering turned on. I just stumbled upon a particularly illustrative example of how switching between rendering modes can cause weird effects: http://jsoverson.github.io/plato/examples/jquery/ Hovering over the graphs will cause info overlays to move around. In those, the text visibly jumps down once the very slight transition applied to the overlay finishes. Note, though, that I'm still mostly concerned with the needs of the Shumway project, so having a flag that can be set to activate sub-pixel-rendered transitions would work just fine.
Flags: needinfo?(roc)
(In reply to Till Schneidereit [:till] from comment #18) > Hovering over the graphs will cause info overlays to move around. In those, > the text visibly jumps down once the very slight transition applied to the > overlay finishes. I don't see this on Linux, although it may be because Linux doesn't do subpixel text rendering. I think you can hack around this by adding a very slight rotation to your transform, but there's a performance cost to that especially on non-GPU systems. I think a reasonable thing to do here would be to enable subpixel rendering for "slow" transitions, e.g. if the difference between one translation and the next is less than 1 pixel in each direction. Would that help your Shumway content?
Flags: needinfo?(roc)
(In reply to Robert O'Callahan (:roc) (Mozilla Corporation) from comment #19) > I think you can hack around this by adding a very slight rotation to your > transform, but there's a performance cost to that especially on non-GPU > systems. Actually you probably can't.
I have been working on some transforms and noticed they looked awful on Firefox compared to both Chrome and IE 10. I have used the rotation hack on the lower example, but subjectively I find Chrome looks much better. I have reduced this down, and it can be viewed at: http://codepen.io/MattyBalaam/details/eaJto
Thanks, this is a very nice demo of the problem. In Chrome Canary, both versions look very smooth, with no internal or external distortions. (In reply to Robert O'Callahan (:roc) (Mozilla Corporation) from comment #19) > I think a reasonable thing to do here would be to enable subpixel rendering > for "slow" transitions, e.g. if the difference between one translation and > the next is less than 1 pixel in each direction. Would that help your > Shumway content? @roc, the problem with this solution is that there'd probably a somewhat visible mode switch between "slow" and "fast" transitions. Except if we interpret "slow" very liberally, of course. In that case, this sounds like a good solution to me.
Flags: needinfo?(roc)
Here's an example I just stumbled upon that suffers very badly from the lack of sub-pixel positioning: http://www.dragoncastle.eu/ The animation is done by changing the values for top and left, but IIUC, the mechanism for disabling sub-pixel positioning is the same, right?
No. Currently absolute/relative positioning do not trigger layerization. Image rendering snaps to pixels using a different mechanism. I'm not sure why the text appears to be jiggling up and down in the boxes in Firefox but not in Chrome, but I'm pretty sure it's nothing to do with subpixel positioning or this bug.
Flags: needinfo?(roc)
I've been struggling with this too. I'm experimenting with the canvas & parallax.js lib and the result is awful in firefox compared to chrome. Notice pixel snapping when motion comes to an end: http://episode17.com/public/flockr/ For me, rotate(0.0001deg) fixes the problem just fine as any blurring is not really noticeable.
I always use a slight rotation of 0.01 and then the element animates smooth without being jerky in Firefox. I add that anytime I animate along the x or y axis. rotate(0.01deg) Forking the example from above with slight rotation fix: http://dabblet.com/gist/cde81e39acec41eae786 .test2:hover { transform: translate(20px, 0) rotate(0.01deg); }
Guys, vertically oriented div choppy and shake. Looks like very BIG problem with transition width of rotated div. Please see demo. https://jsfiddle.net/r4qrnL0z/4/ Vertically oriented div very choppy and shake. If set rotate 90.3deg instead 90deg, div less choppy, but text inside div start choppy. Does this behavior up on discussed issue?
Addon This animation looks smooth and clean in Chrome, IE, Safari but FireFox choppy and shake.
Very annoying bug. And sad to see it hasn't been addressed properly for 4 years. To anyone who having issues with transitions and weird text rendering, I used the following hack to make transitions more acceptable. (the rotate trick did not work for me) // Firefox fix @-moz-document url-prefix() { .your-element { transform: translate3d(0,0,0); filter: blur(0px); &:hover, &:focus { transform: translate3d(0,0,0) translateY(-5px)); //replace translateY with your own transform } } }
Maybe this can helb too. I needes to scale an element up on hover. So i did this by transitioning the transform > scale value. I tried all the things mentioned above and it was a bit smoother, but it did still jump about 1px to the top at the end of the transition. Then i changed the height of the element from 275px to 276px. Now it animates perfectly smooth. (all the fixes from above are still in place too.)

This issue has gotten worse over the years. Firefox now smoothly transitions parts of an element, but not all of it.

Demo: https://jsbin.com/vagacil/2/edit?html,css,output
Screencast: https://www.youtube.com/watch?v=C665W2nwECk

Thanks, I filed that testcase as bug 1729646.

Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.