Closed
Bug 1250073
Opened 8 years ago
Closed 8 years ago
Firefox 44.0.2 has performance issues with 'drawImage' for canvas
Categories
(Core :: Graphics: Canvas2D, defect)
Tracking
()
RESOLVED
WONTFIX
People
(Reporter: funda.pulic, Assigned: mchang)
References
()
Details
(Keywords: perf, Whiteboard: [gfx-noted])
Attachments
(7 files, 3 obsolete files)
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.109 Safari/537.36 Steps to reproduce: The demo creates a grid of tiles with canvas. The tiles are positioned and scaled depending on the amount of tiles we want to add. Variable 'amountOfTiles' can be set to any integer, unfortunately the Firefox 44.0.2 has huge performance issues when set to 200 tiles or even stops executing the JS (>400 tiles). The issue seems to be the 'drawImage' function, executed for each tile. The weird thing is that Firefox 38.0.1 has no issues with it, even not with 900 tiles or more! Thanks in advance! https://jsfiddle.net/funda/t8kromod/ Actual results: JS stops being executed in FF44.0.2. In FF38.0.1 no issues!!!! Expected results: FF 44.0.2 should work fine just like FF 38.0.1
Severity: normal → critical
OS: Unspecified → All
Hardware: Unspecified → All
Attachment #8721919 -
Attachment is obsolete: true
Attachment #8721921 -
Attachment is obsolete: true
Attachment #8721959 -
Attachment is obsolete: true
Comment 7•8 years ago
|
||
I am doing my best
On my MacBook FF44.0.2 stops executing JS. Model: MacBook Pro (Retina, 13", 2013) OS: OS X Yosemite 10.10.5 CPU: 2,8 GHz intel Core i7 RAM: 16GB 1600 MHz DDR3 GPU: Intel Iris 1536 MB Serial-No. C022M829TFH04 On our iMac it works fine. Model: iMac 27" 2010 OS: OS X Yosemite 10.10.5 CPU: 2,93 GHz intel Core i7 RAM: 12GB 1333 MHz DDR3 GPU: ATI Radeon HD 5750 1024MB Serial-No. CK0461EYDNR I've checked the Versions of FF 44.0.2 on both systems with about:config. I've got the same results. On Windows 7 with FF 44.0.2 it works, too. Thanks in advance!
Updated•8 years ago
|
Component: Untriaged → Canvas: 2D
Product: Firefox → Core
Updated•8 years ago
|
Whiteboard: [gfx-noted]
Assignee | ||
Comment 10•8 years ago
|
||
If you go to about:config and set the preference "gfx.canvas.azure.accelerated" to false, restart firefox, and load your test again, is it fast again? 900 tiles actually makes my retina macbook pro totally unresponsive, I can't even do force shutdowns, and I have to forcefully shut down my mac.
Flags: needinfo?(funda.pulic)
Keywords: perf
Reporter | ||
Comment 11•8 years ago
|
||
Indeed, that setting fixes it! But how do I ensure that each user visiting out website has this flag set to false?
Flags: needinfo?(funda.pulic)
Reporter | ||
Comment 12•8 years ago
|
||
Indeed, that setting fixed it! But how do I ensure that each user visiting our website has this flag set to false???
Assignee | ||
Comment 13•8 years ago
|
||
Some profiles of this test with 100 tiles. On a retina macbook pro, we're spending large amounts of time in the GPU. Call stack like: Running Time Self (ms) Symbol Name PresShell::Paint(nsView*, nsRegion const&, unsigned int) nsLayoutUtils::PaintFrame(nsRenderingContext*, nsIFrame*, nsRegion const&, unsigned int, unsigned int) nsDisplayList::PaintRoot(nsDisplayListBuilder*, nsRenderingContext*, unsigned int) mozilla::layers::ClientLayerManager::EndTransaction(void (*)(mozilla::layers::PaintedLayer*, gfxContext*, mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const&, mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const&, mozilla::layers::DrawRegionClip, mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const&, void*), void*, mozilla::layers::LayerManager::EndTransactionFlags) mozilla::layers::ClientLayerManager::EndTransactionInternal(void (*)(mozilla::layers::PaintedLayer*, gfxContext*, mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const&, mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const&, mozilla::layers::DrawRegionClip, mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const&, void*), void*, mozilla::layers::LayerManager::EndTransactionFlags) mozilla::layers::ClientContainerLayer::RenderLayer() mozilla::layers::ClientContainerLayer::RenderLayer() mozilla::layers::ClientCanvasLayer::RenderLayer() mozilla::layers::CanvasClientSharedSurface::Update(mozilla::gfx::IntSizeTyped<mozilla::gfx::UnknownUnits>, mozilla::layers::ClientCanvasLayer*) mozilla::layers::CanvasClientSharedSurface::UpdateRenderer(mozilla::gfx::IntSizeTyped<mozilla::gfx::UnknownUnits>, mozilla::MaybeOneOf<mozilla::layers::ClientCanvasLayer*, mozilla::layers::AsyncCanvasRenderer*>&) mozilla::gl::SharedSurface_IOSurface::ProducerReleaseImpl() intelSubmitCommands IntelCommandBuffer::getNew(GLDContextRec*) gpusSubmitDataBuffers IOAccelContextSubmitDataBuffersExt IOConnectCallStructMethod IOConnectCallMethod io_connect_method mach_msg
Assignee | ||
Comment 14•8 years ago
|
||
(In reply to Funda from comment #12) > Indeed, that setting fixed it! But how do I ensure that each user visiting > our website has this flag set to false??? Not really, but it means we're onto a lead about why this is happening! Also just to make sure that I'm reproducing the same problem as you. We have to fix this in Firefox.
Assignee | ||
Updated•8 years ago
|
Assignee: nobody → mchang
Reporter | ||
Comment 15•8 years ago
|
||
Got exactly the same Problem with my Android phone. When set flag to false, FF mobile does not crash either.
Assignee | ||
Comment 16•8 years ago
|
||
I started looking at this, and essentially it looks like we clone a surface[1] and force a flush of the command buffer [3] once we release the lock [2]. This can take up to 600+ ms on my retina macbook pro, with both the nvidia and intel gpus. Morris, Jeff - I'm not too familiar with the texture sharing stuff, do you know why we have to clone the surface? A full callstack is in comment 13. [1] https://dxr.mozilla.org/mozilla-central/source/gfx/layers/client/CanvasClient.cpp?from=CanvasClient.cpp#384 [2] https://dxr.mozilla.org/mozilla-central/source/gfx/layers/client/CanvasClient.cpp?from=CanvasClient.cpp#345 [3] https://dxr.mozilla.org/mozilla-central/source/gfx/gl/SharedSurfaceIO.cpp?from=SharedSurfaceIO.cpp#36
Flags: needinfo?(mtseng)
Flags: needinfo?(jgilbert)
Comment 17•8 years ago
|
||
JS should be executed in FF44.0.2 there is some performance issues.
Reporter | ||
Comment 18•8 years ago
|
||
Hi there, do you have any new information for us? It is still a big issue for us and we would really appreciate a fix. Regards, Funda
Assignee | ||
Updated•8 years ago
|
Flags: needinfo?(mtseng)
Flags: needinfo?(jgilbert)
Assignee | ||
Comment 19•8 years ago
|
||
Zipped testcase for use offline
Assignee | ||
Comment 20•8 years ago
|
||
Not really sure why the flush is taking so long here, but OS X basically says the CPU is waiting for the GPU to finish something. It doesn't seem like creating a new texture, copying the contents to the new shared texture, should take this long.
Comment 21•8 years ago
|
||
(In reply to Mason Chang [:mchang] from comment #20) > Created attachment 8742578 [details] > 10ms gl flush draw commands > > Not really sure why the flush is taking so long here, but OS X basically > says the CPU is waiting for the GPU to finish something. It doesn't seem > like creating a new texture, copying the contents to the new shared texture, > should take this long. That flush is similar to glFinish in nature, so it's at least waiting for the GPU to finish rendering. Depending on the flags associated with the IOSurf, it may be waiting on something else as well. 10ms seems high for this workload, I agree, particularly if it's 10ms every time we call the same workload. You might test with CGL multithreading disabled. (In reply to Mason Chang [:mchang] from comment #16) > I started looking at this, and essentially it looks like we clone a > surface[1] and force a flush of the command buffer [3] once we release the > lock [2]. This can take up to 600+ ms on my retina macbook pro, with both > the nvidia and intel gpus. > > Morris, Jeff - I'm not too familiar with the texture sharing stuff, do you > know why we have to clone the surface? A full callstack is in comment 13. We need a copy because content must be preserved between frames, and we haven't written any code to make this copy-on-write.
Updated•8 years ago
|
Severity: critical → normal
Assignee | ||
Comment 22•8 years ago
|
||
The root cause of this problem was that for every tile we created, it would create a new DOM image element. Then, when we went to drawImage(), we'd use this DOM image element and check to see if it was in our Canvas source surface cache. Since each call to drawImage would be a different HTML element, our cache would fail, and we'd have to upload the 2100x2970 image to the GPU, causing the slowdown. This didn't happen before Skia since Quartz doesn't upload the texture to the GPU. Can you see the attached test case and verifies that this works for you? Basically, I do one new Image() with the source, then once it loads, load up the tiles to refer to the same ImageElement. I can do 500 tiles easily. Thanks!
Flags: needinfo?(funda.pulic)
Assignee | ||
Comment 23•8 years ago
|
||
I'm also going to test out an idea that Seth came up with where we'd cache the source surface based on the image itself and not just the HTML image element.
Reporter | ||
Comment 24•8 years ago
|
||
Hi Mason, thanks for your reply, I've tried with 900 tiles and it worked for me. We're thinking about a hotfix for our project. But we are still interested in that issue. So keep us please updated. :) https://jsfiddle.net/t8kromod/5/ Regards, Funda
Comment 25•8 years ago
|
||
Cool, I'll mark this as WONTFIX then. Bug 1267260 is where mchang is looking at the surface cache.
Status: UNCONFIRMED → RESOLVED
Closed: 8 years ago
Flags: needinfo?(funda.pulic)
Resolution: --- → WONTFIX
See Also: → 1267260
You need to log in
before you can comment on or make changes to this bug.
Description
•