Matrix3d with scale re-rasters on every frame |
|||||
Issue descriptionChrome 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?
,
Apr 20 2018
,
Apr 20 2018
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.
,
Apr 20 2018
(non-hosted version of the above)
,
Apr 20 2018
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.
,
Apr 20 2018
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
,
Apr 20 2018
Possibly of note: turning on "Show Layer Borders" in DevTools causes the 3d transform to perform roughly as well as the 2d.
,
Apr 20 2018
+ 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.
,
Apr 20 2018
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.
,
Apr 20 2018
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.
,
Apr 20 2018
Thanks Vlad, I think we can close this as wontfix and followup on the CA issue in crbug.com/835395.
,
Apr 20 2018
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.
,
Apr 20 2018
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.
,
Apr 21 2018
@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.
,
Apr 24 2018
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.
,
Apr 25 2018
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 |
|||||
Comment 1 by pdr@chromium.org
, Apr 20 2018