Rending to Canvas 2d Significantly Slower Than Other Browsers
Reported by
j...@ironhelmet.com,
Oct 5 2016
|
|||
Issue descriptionUserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36 Example URL: blight.ironhelemt.com/hardware Steps to reproduce the problem: 1. Load the site above 2. Observe the framerate 3. Load site above in other browsers and observe the framerate. What is the expected behavior? Chrome would perform as well as other browsers. What went wrong? On my windows machine, a surface pro 3, It would appear to take about 80 ms to render a 1024 texture 50 times into a canvas Edge browser can do it in less than 16ms. firefox can do it in about 20ms. for comparison: my nexus 5 renders this 31ms (I think max for requestAnimationFrame). Our iPad Air 2 less than 16ms. I have been asking around to see if this is "just my machine" but others are reporting similar behaviour. chrome://gup says the canvas is hardware accelerated but I suspect it is not. Attached is a self contained html file you can open to see the effects. Does it occur on multiple sites: N/A Is it a problem with a plugin? No Did this work before? N/A Does this work in other browsers? Yes Chrome version: 53.0.2785.116 Channel: n/a OS Version: 10 Flash Version: Shockwave Flash 23.0 r0
,
Oct 5 2016
OKOK. I have updated the sample code at https://blight.ironhelmet.com/hardware In this code I render 63 1024 jpegs into a canvas! Firefox, Edge on Windows handle it without breaking a sweat 17ms. Safari on Mac and iOS also a breeze. 17ms Chrome on Windows is destroyed! - 300ms a frame or more. Chrome on Android Nexus 5 - 120ms Chrome on Mac, a little better - 80 ms ---- You can feel the slowness in real world situations which is why I started investigating in the first place. I have a game where the map is baked into a grid of 1024 textures. My work around has been to render the large textures into smaller canvases after they are downloaded (512 and 256) and as the player zooms the map in, selecting the textures closest to the output render size. Its not very nice, and given other browsers have some kind of optimisation baked in, it would be nice if Chrome had this as well.
,
Oct 6 2016
Have you tried with Chrome 55.0.2881.5 or later? There are recent changes that are worth evaluating. Get the latest pre-release build here: https://www.google.com/chrome/browser/canary.html
,
Oct 6 2016
trace is attached (from Mac)
,
Oct 6 2016
Trace shows that this use case is thrashing the texture cache. A large number of tiles are being re-uploaded to the GPU for each frame. I think we should revise some of our heuristic thresholds. I'll look into this. Thank you Xida for the preliminary investigation.
,
Oct 11 2016
Hey Junov, do you think it's likely that we'll be able to get Chrome to perform like other browsers here? I would like to hold off on the release of my game if there is a fix coming down the pipe. If you tell me that this probably won't be fixed I would just go ahead and release now. I would be sad though. Chrome is my favorite browser!
,
Oct 18 2016
Hey there, Any thoughts or progress on this issue?
,
Oct 19 2016
Hi, sorry about the delayed response.
We should be able to fix this soon-ish, but it typically takes two or three months for fixes to reach a stable release, and several more weeks until most users have upgraded and restarted their browsers.
I am guessing you may not want to wait that long for your launch, so let's help you find a workaround.
After you call getContext('2d') on the game's main canvas, try calling .getImageData(0, 0, 1, 1) on the 2D context. Call getImageData again every time the canvas is resized.
Here is the rationale behind the workaround:
The call to getImageData will trigger a performance heuristic that disables GPU acceleration. In general, we want GPU acceleration to be enabled, but your game hits an edge case that Chrome does not handle well. Until we fix Chrome to do a better job, you will get much better performance by disabling GPU-acceleration.
By the way, this solution is a total hack and you should probably only do it on browsers with a 'Chrome' or 'Chromium' user agent string. And remove the hack once this bug is fixed in stable releases of Chrome so that your game can go back to using the GPU.
I hope that helps.
,
Oct 23 2016
Ah, thanks very much Junov, great to hear that you expect to be able to fix it. I couldn't get the getImageData work around to work in my game, but I had mostly fixed it by saving smaller versions of the map textures into temporary canvases. Half and quarter sizes based on how much of the map could be seen. It's good to know that in 6 months or so I could remove this work around. We are also most concerned with our performance in Electron so we don't need to wait for the changes to filter down to everybody, just to the Electron team.
,
Nov 6 2016
No progress on this yet Junov?
,
Nov 8 2016
Not yet. This issue will be updated as soon as there is activity on this front.
,
Jul 25
|
|||
►
Sign in to add a comment |
|||
Comment 1 Deleted