Very bad performance while drawing on canvas on tablets with android
Reported by
vehlken...@gmail.com,
Jul 22 2016
|
||||||||||||
Issue descriptionSteps to reproduce the problem: 1. Open http://ezl.github.io/signature-pad/examples/full-window.html 2. Draw a curve in a fast manner 3. Observe the registert input-points What is the expected behavior? Faster drawing that does not block the registration of "touchmove" events What went wrong? When the script starts the drawing on the canvas, the browser doesn't register als many touchevents as before (it's not a slight decrease, more a night and day issue). Did this work before? Yes Chrome 43.0.2357.93 works without a problem. Not testet with versions in between Chrome version: 53.0.2785.21 Channel: dev OS Version: 5.0.2 Flash Version: I could observe the issue only while using tablets. Hardware used: - Samsung Galaxy Note pro - Samsung Galaxy Tab A - Sony xperia z2 Drawing happens with the following code: canvasContext.beginPath(); canvasContext.moveTo(previous.x, previous.y); canvasContext.lineTo(newX, newY); canvasContext.lineCap = settings.penCap; canvasContext.stroke(); canvasContext.closePath();
,
Jul 26 2016
After some further testing i can add a few things to this: The issue depends on the used OS and only appears while using a Android-Version that is lower than 6. While using iOS with the latest Chrome version everything runs without a problem. The performance gap is quite huge. When a call the above linked website and draw a circle on an older Chrome version (like 43) i get around 40 "touchmove"-Events that are fired. While repeating the same thing on a device where the problem appears there are about 8 to 10 "touchmove"-Events that appear while doing the same thing. Other browsers like Firefox, Opera or the Build in Browser have no issues, with the exception of Android System Webview where the case is kind of the same as in chrome (old versions seem to work fine, but new versions on Android verions smaller than 6 have really bad performance)
,
Aug 2 2016
,
Aug 2 2016
junov@ Any idea why this is not a canvas issue in terms of performance? Since the author is doing drawing on the main thread the rate of touch moves goes down because they get coalesced together as I indicated in #1. But that slowness is an effect of the slow canvas drawing. It seems the reporter has indicated that when drawing a circle the performance has decreased significantly between 43 and the current version. If you aren't doing the canvas drawing you can easily get 60 touch move events per second.
,
Aug 3 2016
Performance of path drawing has improved in that range AFAIK. I thought the regression had to do with a change in the event coalescing behavior. I'll put back the canvas component until we have a better handle on what exactly regressed. Would be useful to narrow down the regression range. @senorblanco: Any idea why path stroking would have issue on these platforms? The problematic devices mentioned in the description are all snapdragon/adreno
,
Aug 3 2016
The coalescing has been there for years. vehlkentim@ The best thing to provide us is a trace. See https://www.chromium.org/developers/how-tos/submitting-a-performance-bug
,
Aug 3 2016
+1 to tracing. Getting the contents of chrome://gpu might help too. It would also be interesting to know if this page is getting display list canvas, or if it's still using the Canvas2DLayerBridge path (we should be able to tell this from a trace). There is a fast path for circles in accelerated Skia. But I'm not sure if circles generated via round-capped stroked points get the fast path that path.ellipseTo() does. Also, Brian could tell you if this code has changed recently.
,
Aug 4 2016
I attached a trace of the issue.
,
Aug 4 2016
Interesting, thanks! It seems to be blocked on 6 calls to OneCopyRasterBuffer::Playback(), which block on GLImageMemory::CopyTexSubImage() on the GPU. 15ms does seem pretty slow for a 512x512 upload, but it is Android. The more interesting question is what's doing the uploads. My first guess would be path rendering which is on CPU and uploaded to texture. Are these paths really 512x512? That seems pretty large, given that they're just circles. Perhaps something in 53 is rounding up to a larger texture size? Or failing to notice that only a subregion is used? It would also be helpful to get a trace on a device which does not exhibit the problem (Android 6+).
,
Aug 4 2016
Might just be coincidence, but all three of the problematic devices listed (Samsung Galaxy Note pro, Samsung Galaxy Tab A, Sony xperia z2) have an Adreno 3XX series GPU. I can't repro the issue on Nexus7 2013 (also Adreno 3XX), but it's on Android 6.0.1.
,
Aug 4 2016
I can't repro on Nexus4 (also Adreno 3XX), which is on Android 5.1.1. Tried on Chrome 51 (Stable) and 53 (Dev).
,
Aug 4 2016
BTW, I think I misunderstood your comment about "circles": initially I thought you meant drawing a precise circle with canvas path commands, but now I'm thinking you mean touch-drawing an approximate circle with your finger. Is the latter correct?
,
Aug 4 2016
Smells like a slow path in the driver. Might be worth experimenting with alternative texture formats. Did a quick search survey and found several devs reporting that RGBA is faster than BGRA with Adreno.
,
Aug 4 2016
There's a mechanism to split large tile uploads into smaller chunks on devices where texture uploads are slow [1]. If you're not able to find a way to make these fast then this mechanism might be the best option. [1] https://crrev.com/e92ab037dbaab094d7b2253d63fd60cd48e9f9dc
,
Aug 5 2016
Senorblanco: This is correct. I added two additional traces. One done on the SM-P900 in Chrome 43 (Same device as the first trace) and the other on Galaxy Tab A 10.1 in Chrome 51. In both cases the application works as intended.
,
Aug 5 2016
senorblanco@: Looking at the trace of the normal one and slower version, it looks like GPU texture uploading is slower in the slower version, which makes me think that this could be related to this bug: https://bugs.chromium.org/p/chromium/issues/detail?id=627082 In that bug, the tests that regressed are: upload-video-to-texture, upload-canvas-2d-to-texture, upload-webgl-to-texture There is a change seems to be related: https://chromium.googlesource.com/chromium/src/+/ae22291b584735f8458ce123ceac88d8567f53cd WDYT?
,
Aug 5 2016
This definitely looks plausible. CopySubTextureCHROMIUM is being used in both cases, and definitely looks slower in the "bad" case (15ms vs 1-2ms). However, another interesting datapoint is that the textures are 288x288 in the "good" case, and 512x512 in the "bad" case. There are a number of other differences which may or may not be relevant: I see Canvas2DLayerBridge on the "good" path, and not in the "bad" path, which suggests to me that we're getting display list canvas in the "bad", which we weren't before. On the compositor worker side, OneCopyRasterBuffer::Playback() is being called in the "bad" case, and TileTaskWorkerPool::PlaybackToMemory in the "good" case. This may be a slower path, or it may just be an artifact of display list vs. non-display list canvas rendering.
,
Aug 8 2016
vehlkentim@gmail.com: I'm still having trouble reproing this locally. Could you try this experiment on a problematic device: navigate to chrome://flags, set "Display list 2D canvas" to "Disabled", restart Chrome and capture a trace? That might help narrow things down.
,
Aug 8 2016
Also, could you attach the contents of chrome://gpu on the problematic device? After some discussion with Justin, I think this may be that accelerated canvas is simply not working in this case (either blacklisted, or running out of VRAM and falling back to software). If you want to simulate that behaviour, you could try setting "Accelerated 2D canvas" to "Disabled" on your "good" device, and see if it mimics the bad behaviour.
,
Aug 8 2016
removing some people from 'cc' Now that we isolated that this is an issue with GPU acceleration getting disabled. I found there is a blacklist rule for Adreno 3xx GPUs with ES2 drivers. This might explain why things are faster on newer versions of Android : I'm guessing they have newer drivers that support GL ES3, and therefore do not trigger this blacklist entry. Also, I am wondering how accurate this blacklist entry is. @aelias: Could this be a causualty of harmonizing the gpu_rasterization and accelerated_2d_canvas rules?
,
Aug 8 2016
,
Aug 8 2016
Sure, that's likely the case. That blacklist entry was added due to P1 correctness bug http://crbug.com/480149 . In theory, it could probably be narrowed, but in practice whenever I've tried to narrow the blacklist entry some outlier devices don't fit the narrow criteria and exhibit the bug anyway, because the Android update situation is so chaotic. Blacklist adjustment is a can of worms and something that IMO is only worth the effort to tackle with devices with high market share (which none of the affected devices seem to).
,
Aug 8 2016
I am just wondering whether it would be reasonable to blacklist only gpu_rasterization and not accelerated_2d_canvas in this blacklist entry. Any insight into what is affected by the driver bug?
,
Aug 8 2016
I don't know the specific scenario going wrong, you would have to try to repro the symptoms in http://crbug.com/480149 to analyze it and try to confirm that for some reason it can never occur in canvas. It's certainly the case that in terms of patterns of bugs filed, for GPU raster we have users complaining about incorrect rendering whereas for canvas we have developers (never users) complaining about performance, but I'm not sure that reporting artifact is a sufficient reason to make the policy diverge.
,
Aug 8 2016
Yeah, I have an alternative idea: loosen the criteria for promoting canvases to having their own compositing layers. Right now, the display list 2d canvas implementation tends to nest its content into the parent layer instead of having its own layer. This mean that when a canvas needs to be updated, we end-up re-painting the containing layer and re-rasterizing all the compositor tiles that intersect the canvas. This is probably why we are seeing 512x512 texture uploads.
,
Aug 8 2016
Sounds great! Yeah, blacklist adjustment is a zero-sum tradeoff game. I'm happier to see engineering effort into fixing underlying bugs or performance issues so that we can be happy regardless of the blacklist policy. (Layerization policy is another sort of tough tradeoff game though... we should think about whether slimming paint v2 might allow smarter and more dynamic decisions about canvas too.)
,
Aug 9 2016
Another trace, this time with "Display list 2D canvas" set to "Disabled". Disabling "Accelerated 2D canvas" on working devices doesn't reproduce the problem there.
,
Aug 9 2016
@#27: Yep, that makes sense. The regression was probably cause when "Display list 2D canvas" became enabled by default, which is almost always a perf win, but not in this case. @#26: Good idea about deferring the layerization decision. Will look into that.
,
Oct 17 2017
vehlkentim@ are you still seeing this issue in latest chrome stable?
,
Oct 23 2017
I could only retest it on the Samsung Galaxy Tab A and there the issue is no more.
,
Jul 25
,
Jul 25
|
||||||||||||
►
Sign in to add a comment |
||||||||||||
Comment 1 by dtapu...@chromium.org
, Jul 22 2016Components: -Blink Blink>Canvas