New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 835328 link

Starred by 2 users

Issue metadata

Status: WontFix
Owner:
Closed: Apr 2018
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux , Android , Windows , Chrome , Mac
Pri: 2
Type: Bug



Sign in to add a comment

Matrix3d with scale re-rasters on every frame

Project Member Reported by pdr@chromium.org, Apr 20 2018

Issue description

Chrome Version: 67.0.3393.4
OS: MacOS

What steps will reproduce the problem?
(1) Open the attached testcase
(2) Notice it is very slow when "3d matrix" is checked
(3) Notice it is very fast when "3d matrix" is not checked

This was reported by GreenSock:
https://twitter.com/greensock/status/987088501937266691

This appears to be a regression from:
https://chromium.googlesource.com/chromium/src/+/edd476edadbe9b9316f3527b0692836ced4230ce

While will-change will fix this, is it possible to not re-raster every frame in this case?
 
matrixperf.html
1.3 KB View Download

Comment 1 by pdr@chromium.org, Apr 20 2018

Cc: greensoc...@gmail.com

Comment 2 by pdr@chromium.org, Apr 20 2018

Cc: surma@chromium.org majidvp@chromium.org jasonjmi...@chromium.org
Hosted demo with a few more options to tweak:
https://s.codepen.io/developit/debug/VxLQVB/VJkxxZoRgdwk

I'm not seeing will-change improve performance - it just seems to trigger the same framerate drop as applying a 3d transform.

Also worth noting, the 2d transform results in fairly serious tearing, at least on MacOS.

Comment 4 Deleted

(non-hosted version of the above)
transform-comparison.html
3.1 KB View Download
re #1: I wonder if we should just apply some heuristic to detect the fact that transform is changing every frame and thus consider it animated and treat it as if it has "will-change: transform".

re #3: On Linux, the 2d transform case is performing much worse that 3d transform. It is caused dues to re-rastering every frame and I can see that will-change is improving that situation considerable.



 

Cc: erikc...@chromium.org
Just tested on a Pixelbook and the difference is much less stark: ~150fps 2d transform and ~120fps 3d.  Will-change doesn't seem to affect the 3d transform, but does reduce the fps of the 2d transform to 120.  All combinations are smooth, and none seem to exhibit the strange excessive GPU use.

+erikchen@chromium.org
Possibly of note: turning on "Show Layer Borders" in DevTools causes the 3d transform to perform roughly as well as the 2d.
Cc: ccameron@chromium.org piman@chromium.org
+ ccameron, piman

jasonjmiller has a local repro. It looks like there are back-pressure issues - the page is rendering at 140FPS, but we're displaying at 14 fps.
Screen Shot 2018-04-20 at 2.04.57 PM.png
908 KB View Download
Screen Shot 2018-04-20 at 2.05.28 PM.png
794 KB View Download
Another note: the average time spent painting in the 3d case is roughly double that of the 2d case - that's counter-intuitive since the 3d case should be handled entirely by moving composited layers. 
TLDR: For the OP, you're right that will-change: transform will fix this. And no, we can't avoid re-raster for reasons discussed in similar issues:  crbug.com/556533  and  crbug.com/596382 .


There are a few things at play here:
- Whether or not each animated element gets a separate layer.
- Whether or not will-change: transform is specified for each animated layer.
- Whether or not scale changes on each tick of the animation.

As a general rule, 2d transforms do not get a separate layer, 3d transforms do get a separate layer. 

With each individual layer, without will-change: transform, and scale changes, we re-rasterize every element on every frame which makes it raster bound. This is worse than having every element be in a single layer, since there is also added overhead of creating more textures and submitting more work to the gpu. 

With will-change: transform we say that we don't re-rasterize content on scale changes, which would fix this issue and make the animation quick. This is also the proper use of the hint to Chromium, since we intend to change the transform and we indicate this by specifying will-change: transform.

Without scale changes, I think it's moot whether or not will-change transform is set, since it's just a matter of whether we re-rasterize one layer or simply submit many small layers to the gpu (and I think submitting many small layers would be perform better*). Will-change transform doesn't hurt in this case though.

* - We did notice that in case from comment #5, mac becomes bound on our CoreAnimation compositing path. I would say that this isn't directly related to this issue, but we filed a separate bug for this: crbug.com/835395.

Comment 12 by pdr@chromium.org, Apr 20 2018

Status: WontFix (was: Assigned)
Thanks Vlad, I think we can close this as wontfix and followup on the CA issue in crbug.com/835395.
I'm curious if anyone on the Chrome team has read below the "Partial solution: set will-change: transform" on this page: https://greensock.com/will-change and if so, what their advice would be. 

I offered several suggestions for compromises/fixes but I don't think anyone has taken them seriously (I could be wrong).

Obviously I feel strongly that this whole "will-change" thing isn't a good solution at all, and I'm pretty sure I'm in good company. 

Sadly this "WontFix" status strikes me as premature. Chrome performs TERRIBLY compared to other browsers in this scenario...is that really okay? And again, slapping will-change doesn't solve everything; there are other problems it introduces that may be unacceptable for many animators. 
We do take these suggestions seriously. 

In the example ("Oops, that breaks it in other ways" section), where this breaks down is if the scale begins with less than 1. This was addressed in  crbug.com/596382 . Your feedback contributed directly to the approach we took in fixing this. Specifically, the patch in comment 127, and the demo link in 128 with will-change: transform uncommented does not have the blurry/jittery behavior, because it rasterizes at scale 1 or ideal scale, whichever is bigger. This implementation is the second proposal in greensock.com/will-change (in "Is Chrome going to fix this?" section), which happens to be our current shipping behavior. 

I'm not by any means claiming that will-change: transform saves the day in every case. All I mean to say in #11 is that in the specific case of large number of animating elements, all of which change their transform (including scale), will-change: transform does help. 





@greensockjd - Have you checked the performance of your demos on another OS? I had been under the impression that this was a general Chrome issue, but it turned out (at least for my demos) it was isolated to MacOS.  If you're seeing the same, crbug.com/835395 should be our fix.
Yes indeed, it appears to be worst (by far) on Mac OS. 

And thanks for confirming that the team does indeed take the suggestions seriously - that means a lot.

I sure wish there was a flag that we could set via JavaScript that'd control whether or not an element was rasterized (and at what size). Kinda like in the Flash/ActionScript world, they had cachAsBitmap. It seems like the "will-change" stuff is sorta aimed at helping with that, but is fraught with gotchas. 
FYI on macOS (cross-posting from issue 835395):

I looked at how many CALayers we're updating, and I found that we're updating the IOSurface for ~200-300 layers on most frames -- ideally we should be updating zero.

So we're failing to match the DOM layers to CALayers and we end up doing way more work than we should.

Sign in to add a comment