Closed Bug 836372 Opened 12 years ago Closed 9 years ago

Animated images cause very high CPU usage

Categories

(Firefox OS Graveyard :: General, defect)

ARM
Gonk (Firefox OS)
defect
Not set
normal

Tracking

(Not tracked)

RESOLVED WONTFIX

People

(Reporter: gsvelto, Unassigned)

Details

Attachments

(1 file)

While investigating bug 822345 I've come across the fact that small animated GIFs (or PNGs) in Firefox OS' status bar could consume a significant amount of CPU time. To reproduce the issue point the browser app on your device to this page: http://people.mozilla.org/~gsvelto/animated.html The two images on the page draw a total of 13 frames per second and are taken from the status bar. On my Otoro this causes CPU usage in excess of 25% split between the browser process and the main b2g process. Crude profiling of the browser app shows most of the time being spent in nsDisplayList::PaintRoot() calls, with little self time and most of the actual time being spent in a lot of different methods. Nothing interesting is visible in the main b2g process profile suggesting the time there is being spent outside of the main thread. I'm putting this under Boot2Gecko and not Core because I couldn't reproduce it under plain Firefox. Even when lowering my PC's CPU clock speed to the minimum the CPU usage remains quite modest there.
Did we ever determine why we weren't hitting the empty txn optimization for these? (Or were we.)
(In reply to Chris Jones [:cjones] [:warhammer] from comment #1) > Did we ever determine why we weren't hitting the empty txn optimization for > these? (Or were we.) We didn't determine it, I just saw that independently of how the images would be added to the page (or if transformation would be present) the CPU load would remain the same. I will try to dig into this by manually timing the expensive calls because it's unclear if we're hitting a B2G-specific problem (maybe caused by running OOP?) or not.
It's pretty easy to tell --- grab a profile and if you see things that say "*DisplayList" taking a long time, we're not hitting the optimization.
http://people.mozilla.com/~bgirard/cleopatra/#report=2d4853cf81a54b478dd8ef5b9c1bb71e7d5cb821 Not many, so I would imagine we're hitting the optimization. However I can see a surprising large amount of write()s which I hadn't noticed earlier. I'll double check those tomorrow with finer grained profiling and some manual instrumentation.
This is a finer grained profile run, with interval time set to 1ms (reported sample time is 1.34ms): http://people.mozilla.com/~bgirard/cleopatra/#report=cd37b74ff283065ee837b7f021b7852b07f94d74 Time seems to be spread over a fairly large number of methods below nsDisplayList::PaintRoot() and it's hard to tell if there are major contributors. I'll try poking around that method with clock_gettime() in the hope that I can find some large timesink and not just a plethora of short calls.
We should not be hitting PaintRoot! Can you get call stacks for calls to nsIFrame::SchedulePaint? We should not be hitting that.
I've attached the backtrace from the nsIFrame::SchedulePaint() invocation, I've taken a few and they all look identical. I'll try again with the tricks described in bug 822345 to see if they make a difference regarding hitting nsDisplayList::PaintRoot() (bug 822345 comment 23 notably). This is all done on the device BTW.
That stack indicates that we didn't get a dedicated layer for the image. The "transform: perspective(1px)" should ensure we get a dedicated layer for the image.
I tried to investigate this bug on b2g18. Your testcase doesn't have any special CSS magic to layerize the images. This testcase does: http://people.mozilla.com/~roc/tag.html With this testcase I verified we don't do any display list construction. Note that I had to set "transform: perspective(1px)" *and* "display:block", since <img> defaults to display:inline, which can't have a transform on it.
After the patch my "top" results look like this: User 16%, System 8%, IOW 1%, IRQ 0% User 23 + Nice 29 + Sys 27 + Idle 225 + IOW 4 + IRQ 0 + SIRQ 0 = 308 PID PR CPU% S #THR VSS RSS PCY UID Name 444 0 12% S 13 73232K 28180K fg app_444 /system/b2g/plugin-container 112 0 10% S 41 188564K 95980K fg root /system/b2g/b2g User % is down from about 25% when not using those styles.
Note, this is a debug build. Results in an opt build should be better.
(In reply to Robert O'Callahan (:roc) (Mozilla Corporation) from comment #9) > Note that I had to set "transform: perspective(1px)" *and* "display:block", > since <img> defaults to display:inline, which can't have a transform on it. Thanks for pointing this out, that's something I didn't know and never tried. None of my tests had display:block set :-( I did a quick test with a v1-train build on my Leo phone using your link and I can see b2g and the app consuming 13-15% of CPU time in total vs 20-22% without display:block. I'll try and make a test page with the same code as I've put in Gaia for the statusbar and see how it compares. If the performance difference is minimal I'll be glad to remove my workaround; it'll make the statusbar code simpler and hopefully fix bugs 884188 and 885345 in the process.
(In reply to Gabriele Svelto [:gsvelto] from comment #12) > Thanks for pointing this out, that's something I didn't know and never > tried. None of my tests had display:block set :-( I didn't think of it until just now either! And I should have known.
why do we need to "force" a separate layer using perspective ?
Because otherwise nothing else will cause creation of a separate layer for the image. That means the image goes into a large layer buffer, and then whenever we update the image we have to figure out which part of the layer buffer changed, and repaint that part of the buffer. On central, we're working on bug 717872 which will automatically put each animated image into its own layer, without any CSS hacks, *and* drive the animation off the main thread so should be even more efficient than than what you get with the CSS hacks.
Thanks, I exactly meant: why don't we have something like what you're working on bug 717872 (which we won't get in b2g18 of course) :)
central has another nice feature which should help --- synchronizing the start times for multiple animated images. This will reduce the amount of compositing we have to do, when you're rendering multiple animated images with the same frame rate.
I made another test page with the canvas hack code: http://people.mozilla.org/~gsvelto/canvas.html Testing it on the same phone as your page shows similar CPU usage and in fact your page seems better behaved: in both pages total CPU usage hovers in the 12-15% range but the canvas code sometimes spikes higher (maybe because of GC? JIT kicking in?). If you're OK with it I'll prepare a Gaia pull request that removes the canvas, puts the animated icons back using the perspective transform and display:block
(In reply to Gabriele Svelto [:gsvelto] from comment #18) > If you're OK with it I'll prepare a Gaia pull > request that removes the canvas, puts the animated icons back using the > perspective transform and display:block Please do!
(In reply to Robert O'Callahan (:roc) (Mozilla Corporation) from comment #19) > Please do! I've created bug 888184 with a summary of the problem and made it block related bugs. I wanted to gather all the information on this in one place so it would be easier to refer to this specific problem. The patch will be coming soon.
Status: NEW → RESOLVED
Closed: 9 years ago
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: