performance degradation with CSS3 HW accelerated transforms (scale & rotate) |
||||||||||||||||||||||||
Issue descriptionFiling from https://plus.google.com/u/0/117263508691705702027/posts/LKRivGXZRpH Report: "we are seeing a severe performance degradation with CSS3 HW accelerated transforms (scale & rotate) on various devices (Nexus 5, Sony Xperia, ..) since webview upgrade to 49.0.2623.105. Pinch&Zoom like transforms are getting really slow whereas it was quite fluid so far. Any idea of what's wrong ?" Via chrishtr@: "This is probably due to https://chromium.googlesource.com/chromium/src/+/66978ff65abbb473f8662444c2dc0823e0f45795 We now re-raster on scale changes. Please file a new bug and assign to me." If we have a regression let's get it fixed for 50 stable please.
,
Apr 5 2016
This is not fixable for M50. The change referenced was intentional. Also, the context of this bug is not actionable.
,
Apr 5 2016
satyavathir@, do we have a test shell where we could load a page with CSS3 transforms and test this out?
,
Apr 5 2016
From G+ thread for repro: "Here is a sample app. You can download it from http://mobile-spot.mobi/mobigeotest-releases/mobigeotest.apk Once started, just press Map. You can then compare pinch & zoom performance with WV49 installed vs. previous ones."
,
Apr 5 2016
amineer@ -working on it.
,
Apr 5 2016
Are you animating the size of raw images in <img> elements?
,
Apr 5 2016
I want to keep the RB-Stable label as a tracking mechanism until we confirm we haven't regressed in M49. We can remove it if need be shortly.
,
Apr 5 2016
We have checked on M49:49.0.2623.105 vs M48: 48.0.2564.106 few devices (5) including Nexus 5 & Sony Xpera Z3 +, Pinch & Zoom is slower on M49 on the above app #4.
,
Apr 5 2016
,
Apr 5 2016
Per TE performance in 49 is 2-3x worse than 48 in workflows given above.
,
Apr 5 2016
By "animate" I just meant to ask how you are manipulating the transform, and what content is inside it. You answered that in comment 11, thanks. What we changed in Chrome 49 was to re-raster the contents on every frame when re-sizing via CSS 3D transforms (or more generally, composited content). We did this because otherwise the content would start to look blurry as you scale it up. We had previously not rastered on every frame to optimize performance, but got a number of complaints about blurry content. Now the content is sharp, but displayed more slowly. If you are zooming <svg> in a div, there is really nothing you can do to avoid this peformance characteristic after Chrome 49. But your map will look clearer. Does this make sense to you? Please let me know also if I am misunderstanding your use case.
,
Apr 5 2016
Issue 596253 has been merged into this issue.
,
Apr 5 2016
Hi again, Can you try putting this in your webview HTML? <meta name="viewport" content="width=device-width, minimum-scale=1.0"> This should trigger GPU rasterization, which is much faster on many classes of content. Also, if it does change performance, can you send me a second apk for review? It would also be great for the apk to enable me to debug its webview: https://developer.chrome.com/devtools/docs/remote-debugging#debugging-webviews
,
Apr 5 2016
,
Apr 6 2016
,
Apr 6 2016
Frames are rendering at about 25fps or so. I confirmed that the version uploaded in comment is receiving GPU rasterization. On a Sony Xperia Z5, I see raster time per frame of about 18ms wall time, of which about half is descheduled, most likely due to: Each frame has about 20ms of javascript code running. @ mobilespot75: I think you can double the frame rate or more by reducing the time spent in javascript. Could you profile your javascript and see if that can be optimized? Chrome DevTools has some good tools for this. Trace attached.
,
Apr 6 2016
fwiw, since this is gpu raster, looking at cpu time on the raster thread wall time is probably not that useful by itself. You also have to look at time on the gpu thread (Chrome_InProcGpuThread), which can also delay/block Display::DrawAndSwap. Unfortunately gpu thread events are not split nicely into frames, so hard to estimate per frame cost there
,
Apr 7 2016
,
Apr 7 2016
,
Apr 7 2016
@mobilespot75, I'm not sure there is much more we can do on this bug without reduced testcases that show individual bugs. Would you be up for minimizing your app to show just the code that regresses, and filing those as separate bugs?
,
Apr 8 2016
Hi , we could indeed simplify our sample app around the pinch&zoom. Still this pinch&zoom performance issue seems not to be specific to our app. We tried the web version of Google Maps on a Nexus 5 Android 6.0.1 and see the same thing: www.google.fr/maps on Nexus 5 Android 6.0.1 Pinch&zoom on Google Maps on Chrome 44 : ~19 FPS Pinch&zoom on Google Maps on Chrome 49 : ~4 FPS Can you confirm this ?
,
Apr 8 2016
,
Apr 8 2016
@pdr missing in my previous post : if the issue is also visible on other web apps like Google Maps, do you still need more precisions around our own code ? We are ready to help as much as we can of course.
,
Apr 9 2016
Please have a look at this test case: https://jsfiddle.net/s9rqa2t8/2/ since Chrome 49 performance on Android has degraded noticeably. Before 49 the svg would get scaled and blurred, but in a performant manner.
,
Apr 9 2016
about this: https://bugs.chromium.org/p/chromium/issues/detail?id=600482#c12 I don't get this feature. with the "blurry" image problem, they could have used a width/height percentage scale to achieve a static "scaled" image. But now there is absolutely no performant way to animate the zoom of a SVG.
,
Apr 9 2016
@taddei Thank you very much for the JSfiddle; I took the liberty to fork it to add a pinch & zoom with low JS overhead. https://jsfiddle.net/mspot75/tz65jq2w/ I recorded timelines of it on a Nexus 5 Android 6.0.1 with Chrome 49 and Chrome 44 (enclosed) Chrome 44 : close to 30 FPS (most of the time on Compositing) Chrome 49 : between 8 and 10 FPS (most of the time on Rasterize Paint)
,
Apr 11 2016
Chiming in to advise that the performance degradation introduced in Chrome 49 resulted in a serious business delay and additional development overhead for us. If re-rastering on scale change is a must-have for so many users that it should be the new default, I'd ask for an escape hatch to allow devs to opt out of the behaviour. Alternatively, having users opt in would seem the more consistent cross-platform approach.
,
Apr 12 2016
We're in a tough spot because the blurry scaling problem has been a long-standing issue. I think the current approach of crisp scaling is the correct long-term behavior (fewer heuristic surprises, more power to the developer), but we definitely need a solution to the pan&zoom problem. mobilespot75 and oliver.turner, I'd like to understand your usecase a bit more. Are you both doing your own zoom implementation in javascript by setting a transform after touch/mouse events, as the jsfiddle in comment 30 shows? I was able to get smooth zooming on my nexus 5X by converting the SVG content into a 200x200 png image (using canvas), then replacing the tiger/map with the low-res image during zooming. I can put together a more polished demo if this sounds like something you could use.
,
Apr 12 2016
@pdr I'm working on implementing a mobile friendly interactive venue map. We deal with thousands of seats simultaneously (up to 100k). I have an SVG which has a background image, polygons for the sections, circles for the seats and text elements for the labels. I've Implemented my own pinch/zoom in javascript because of the interactivity of the map. We needed to animate the zoom in/out and the panning. we also need to show/hide seats/sections depending on zoom levels... etc. Similar to @mobilespot I've worked around the blurry effect by applying the "scale" transformation during the pinch and, once the user lifts the fingers, move to scale(1) and adjust the width/height of the svg to re-rasterize the venue. On the next pinch/zoom I apply the scale to the already resized svg image, reducing the blur effect. We were going to production the same week chrome49 went out but had to stop everything and implement a series of workarounds. We'll probably go to production for a few users soon but are very concerned for our Android users' experience. I've experimented with many different types of technologies, including canvas, but the setup we found seemed ideal until v49. The opt-in/out solution @oliver.turner suggested would be ideal for us. But I think the solution @mobilespot suggested of a debounce timeout for the re-rasterization is a smart solution too.
,
Apr 12 2016
In addition, just as reference, our venues are designed with a viewBox of 10240x7680.
,
Apr 13 2016
While a debounce would work for these usecases, it will break others. I'd like to avoid heuristics in the platform if at all possible so we don't put developers in this situation again. Here's the demo I referred to before: http://jsbin.com/pimoto The approach is to emulate what Chrome did before where svg content is rendered as a bitmap during zoom. Can you see if something like this would work for you? I tested this on a Micromax Canvas A1 (512MB Android One), a Galaxy S4, and a Nexus 5X. If this approach works for you all, I can brush it up as a library on github so others can use it too.
,
Apr 13 2016
@pdr thank you for your proposed mechanism. Unfortunately it does not work on our use case as memory explodes when the user has zoomed in and the SVG container becomes quite big. Reason is : at high zoom levels we need high resolution rasters. More explanations below The user zooms in on the map to see details and read text of a given area. At maximum zoom level (e.g x30), the SVG container div may have dimensions over 10000 "px" (even 20000 for biggest maps). At high zoom level you need a high resolution raster for subsequent user pinch&zoom because if you use a low resolution raster like 200px wide, the map gets totally blurred during the pinch&zoom (we can see that effect in your demo). Canvas raster cannot handle such sizes : we tried and Chrome just crashes on a Nexus 5) whereas Chrome internal Paint Raster handles those sizes without problem. Attached file screen capture showing blurred pinch&zoom when started at a already high zoom level on a real map. We set raster dimensions to 3000x3750, but this is still far from enough. Doubling the size makes Chrome crash. Also there is an uncomfortable delay after the user has started zoom action because of the SVG to raster swap I guess http://jsbin.com/roduye/23 So Chrome internal Paint Rasterizer is the one we have to use but we need either : - a call to the Paint Raster under our control at is was the case until Chrome 48 - or a faster rasterizing compatible with 30+ FPS - or a defer / cancel execution as mentioned in comment #33 - or at least a webview option (and Chrome user option) that allows to deactivate the new behaviour, as suggested by @olver.turner
,
Apr 15 2016
pdr@, any further thoughts?
,
Apr 15 2016
It's unlikely we can revert to the old behavior because so many developers are affected by the opposite bug (e.g., 556533, 413636, 368201, 542166). The new behavior removes a confusing heuristic and will be better long-term (we won't have to put folks through this again). Simple zoom scenarios can be covered with a technique like comment 37 shows, although more complex cases will require significant logic (e.g., dynamically generating tiles) to emulate the old behavior. For these reasons, I'm going to unhappily* mark as WontFix. This bug will stay open for discussion though. * I don't think many folks really understood the re-raster zoom usecase before this bug (at least I didn't). It's clear we need a real API for controlling this behavior in general (both SVG and HTML). Some colleagues and I have started looking into this in https://goo.gl/fJ9yHD.
,
Apr 15 2016
@pdr the workaround suggested of implementing rasterizing logic in javascript to mimic the previous behavior of the browser doesn't feel like it can scale. As @mobilespot suggested we need to create high res images dynamically depending on the current zoom size for an acceptable user experience. This will consume a lot of CPU and memory. Without taking in consideration the complete re-architecting of our Javascript application. The bugs mentioned in the comment #40 all seem like unexpected behaviors, I agree, but none of those examples needed at all a GPU rendered page. It felt like they used the wrong tool and got an unexpected result. Except for (542166) who had the expected behavior, same as other browsers too. In my opinion re-rasterizing at every zoom level seems like a patch, not a solution. Completely ignoring performance from the equation seems a little drastic. My suggestion would be to use an attribute, like "will-change", to allow the developer to tell the browser that the property in question (transform) will be subject to frequent updates. This attribute could then re-activate the previous performant behavior. Thanks for not dropping this. Performance is very important to us.
,
Apr 15 2016
@pdr I totally back @taddei's last comment. Please do not drop this issue. On comment #38 we tried the canvas raster workaround and confirmed it does not scale. This issue is not only about Ticketmaster's and Mobile-Spot's use cases. It is also about Google Maps for which the pinch&zoom performance severely degraded since Chrome 49 (comment #25). This means that every use of Google Maps on the web (either full page or embedded in an iFrame) has now become a poor UI experience on Android, while it is very fluid on iOS ! Do you agree with this ? It seems to be quite a high price to pay to fix the blurring bug.
,
Apr 15 2016
@pdr Allowing developers to express their intent via the `will-change` property sounds the ideal solution here: - It's specifically designed to inform the browser of upcoming transforms - It already exists (unlike the rasterScale proposal) - It provides an escape hatch for those who want a different behaviour I'd love to hear from anyone on the Google Maps team regarding what their plan is here. As others have said, thank you for keeping this discussion open.
,
Apr 15 2016
will-change: transform is used on a large number of pages (https://www.chromestatus.com/metrics/css/timeline/popularity/445) and changing how it works would affect a whole lot of content. This would be risky enough that we would have to wait for a full release cycle (~6 weeks) or more to make the change. We could introduce something like will-change: scale, but it seems better to add just the API we need (something like rasterScale). We're continuing to look into this to see if we can find some way to reduce the impact of this regression. vmpstr@ just prototyped a new approach to solving this and it does fix the gpu-is-flooded issue that seems to be the primary cause of the jank. I've switched this to an assigned P1 to reflect that the team is treating this as the top priority, but I've removed the release block label for the reasons listed in comment #40.
,
Apr 19 2016
We've discussed this and decided that the patch I'm working on is not enough to fix this.
,
Apr 19 2016
We're going to revert for 50 and 51. Per pdr@ / danakj@, this code has not changed since 49, and while this is less correct in some cases, it restores performance on a number of sites, including maps.google.com. "Merge" approved for branch 2661 and 2704.
,
Apr 19 2016
Reverts in CQ here https://codereview.chromium.org/1894173004/
,
Apr 19 2016
This affects Desktop as well.
,
Apr 20 2016
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/bb4146c4a2bb20b9a0075a56fb7a631cdd30ad2d commit bb4146c4a2bb20b9a0075a56fb7a631cdd30ad2d Author: Alex Mineer <amineer@chromium.org> Date: Wed Apr 20 00:11:08 2016 Revert "cc: Stop locking the raster scale factor at 1 after any change." This reverts commit 66978ff65abbb473f8662444c2dc0823e0f45795. BUG= 600482 Cr-Commit-Position: refs/branch-heads/2661@{#614} Cr-Branched-From: ef6f6ae5e4c96622286b563658d5cd62a6cf1197-refs/heads/master@{#378081} [modify] https://crrev.com/bb4146c4a2bb20b9a0075a56fb7a631cdd30ad2d/cc/layers/picture_layer_impl.cc [modify] https://crrev.com/bb4146c4a2bb20b9a0075a56fb7a631cdd30ad2d/cc/layers/picture_layer_impl.h [modify] https://crrev.com/bb4146c4a2bb20b9a0075a56fb7a631cdd30ad2d/cc/layers/picture_layer_impl_unittest.cc
,
Apr 20 2016
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/4f40f4a1a9c306c1359583309e15eb005ed8dd64 commit 4f40f4a1a9c306c1359583309e15eb005ed8dd64 Author: Alex Mineer <amineer@chromium.org> Date: Wed Apr 20 00:21:04 2016 Revert "cc: Stop locking the raster scale factor at 1 after any change." This reverts commit 66978ff65abbb473f8662444c2dc0823e0f45795. BUG= 600482 Cr-Commit-Position: refs/branch-heads/2704@{#135} Cr-Branched-From: 6e53600def8f60d8c632fadc70d7c1939ccea347-refs/heads/master@{#386251} [modify] https://crrev.com/4f40f4a1a9c306c1359583309e15eb005ed8dd64/cc/layers/picture_layer_impl.cc [modify] https://crrev.com/4f40f4a1a9c306c1359583309e15eb005ed8dd64/cc/layers/picture_layer_impl.h [modify] https://crrev.com/4f40f4a1a9c306c1359583309e15eb005ed8dd64/cc/layers/picture_layer_impl_unittest.cc
,
Apr 20 2016
To close the loop here, we're going to look at a few approaches to fix the original bug: * Fixing several viewport tiling and gpu scheduling bugs may let us re-land this patch as-is in the future. * Investigating will-change: transform as was suggested above. This is feasible now that we have the runway of a full release cycle to catch regressions. * Changing along with other browser vendors using an approach like rasterScale (https://goo.gl/UbtIvi). This is difficult but I think it's the best long-term sane solution.
,
Apr 20 2016
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/1e9c8f7aa1a0e05450bdc35b94fdbf37c2f1cf18 commit 1e9c8f7aa1a0e05450bdc35b94fdbf37c2f1cf18 Author: danakj <danakj@chromium.org> Date: Wed Apr 20 03:50:15 2016 Revert of cc: Stop locking the raster scale factor at 1 after any change. (patchset #1 id:1 of https://codereview.chromium.org/1474853002/ ) Reason for revert: https://bugs.chromium.org/p/chromium/issues/detail?id=600482 Original issue's description: > cc: Stop locking the raster scale factor at 1 after any change. > > Currently if the PictureLayerImpl's transform scale changes ever > outside of a CSS animation, we lock the raster scale to 1 to prevent > any re-raster work from happening. > > This leads to really inconsistent/buggy/unpredictable behaviour for > web developers. Sometimes this only becomes visible after switching > tabs and back, causing the old tiling to be evicted. > > This optimization was added when CSS animations were very new to the > web, now they are more common and we should expect developers to use > CSS animations if they want to change the scale of an element frequently > as this provides the needed hints to the compositor about how to raster > the content. We cargo-culted this into the impl-side painting > implementation and tweaked it from there. > > This patch removes the hueristic entirely around fixing the raster scale, > meaning that we'll always raster at the scale javascript provides on the > layer. This eliminates many "things are blurry" problems from the web > (see bugs 556533 , 413636 , 368201 , and 542166 for some examples). > > R=enne, vmpstr > BUG= 556533 > CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel > > Committed: https://crrev.com/66978ff65abbb473f8662444c2dc0823e0f45795 > Cr-Commit-Position: refs/heads/master@{#361551} TBR=enne@chromium.org,vmpstr@chromium.org BUG= 556533 , 600482 CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel Review URL: https://codereview.chromium.org/1899843005 Cr-Commit-Position: refs/heads/master@{#388425} [modify] https://crrev.com/1e9c8f7aa1a0e05450bdc35b94fdbf37c2f1cf18/cc/layers/picture_layer_impl.cc [modify] https://crrev.com/1e9c8f7aa1a0e05450bdc35b94fdbf37c2f1cf18/cc/layers/picture_layer_impl.h [modify] https://crrev.com/1e9c8f7aa1a0e05450bdc35b94fdbf37c2f1cf18/cc/layers/picture_layer_impl_unittest.cc
,
Apr 20 2016
Thank you all for your support. We will test as from this is available, and we will do so with the next modifications listed in comment #51
,
Apr 20 2016
Tested the same on win8.1, mac 10.11 and Linux 14.04 chrome version 50.0.2661.86 with the sample fiddle https://jsfiddle.net/s9rqa2t8/2/ given in comment #28 - observed that the image gets blurred on Zooming in. Observed image not getting blurred on canary version 52.0.2713.0 Please find the screencast to find the difference in behavior between 50.0.2661.86 and canary pdr@ Could you please confirm on the fix as we are still seeing the blurry issue on latest build as well.
,
Apr 20 2016
Android OS: with the sample fiddle https://jsfiddle.net/s9rqa2t8/2/ given in comment #28 - observed that the image gets blurred on Zooming in. Issue is observed on 50.0.2661.86 and Latest M51. Looks good in Latest Canary version, no blurring observed.
,
Apr 20 2016
Verified with https://jsfiddle.net/s9rqa2t8/2/ on Android with latest M50 beta build, the image is more blurred when zoomed in, performance is very good and animation is smooth. Devices verified: Sony Xperia Z3+ Samsung Galaxy S7 Samsung Galaxy S6 Edge Nexus 5 Asus Zenfone 2 Motorola Moto X 2
,
Apr 20 2016
tkonchada and kgnaidu, the patch is not yet in Canary so it isn't possible to confirm this using canary yet. You can use the official build for M50 off the bots if you want, or a tip-of-tree build. Otherwise, you will need to wait until tomorrow to confirm this on Canary. You can use https://omahaproxy.appspot.com/ to confirm that this is not in canary; you are looking for a canary build after #388425. You should see the following on https://jsfiddle.net/s9rqa2t8/2 The old behavior: not blurry The new behavior: blurry I manually confirmed this is working at tip-of-tree (blurry). I know it seems backwards, but the blurry behavior is what we want.
,
Apr 20 2016
,
Jun 10 2016
Update: we intend to re-launch the change which led to this bug, but this time with a change to allow developers to control the performance-quality tradeoff. Please review https://docs.google.com/document/d/1f8WS99F9GORWP_m74l_JfsTHgCrHkbEorHYu72D4Xag/edit# and give feedback by commenting on the document (or commenting here if you prefer). The approach is very similar to that suggested in Comment 41. Thank you to everyone who helped to find a solution! We expect this change to launch with Chrome 53, which goes to the stable channel in early September.
,
Jun 15 2016
@chrishtr Thank you for the proposed specification. We think it is OK and will test when it is available on beta, including the addition of translateZ(0) to maintain the composited layer while setting the will-change:transform property off and on to refresh the picture, when the user releases the map after a pinch&zoom gesture.
,
Jun 23 2016
To those who are following this bug: we have landed the change. To re-iterate, please read this document for the details: https://docs.google.com/document/d/1f8WS99F9GORWP_m74l_JfsTHgCrHkbEorHYu72D4Xag/edit#
,
Mar 24 2017
|
||||||||||||||||||||||||
►
Sign in to add a comment |
||||||||||||||||||||||||
Comment 1 by amin...@google.com
, Apr 4 2016