Closed Bug 850263 Opened 7 years ago Closed 6 years ago

IE fishbowl exceeds skia texture cache size

Categories

(Core :: Canvas: 2D, defect)

defect
Not set

Tracking

()

RESOLVED FIXED
mozilla26
Tracking Status
fennec + ---

People

(Reporter: donrhummy, Assigned: snorp)

Details

Attachments

(1 file, 3 obsolete files)

User Agent: Mozilla/5.0 (Android; Tablet; rv:20.0) Gecko/20.0 Firefox/20.0
Build ID: 20130307073701

Steps to reproduce:

ran the fish bowl test: http://ie.microsoft.com/testdrive/performance/fishbowl/ in both Firefox beta and chrome for android on a quad core nexus 4.


Actual results:

Firefox 10 fish: 3fps

Chrome 10 fish: 56fps
chrome 25 fish: 44fps
chrome 50 fish: 39fps
chrome 100 fish: 27fps


Expected results:

Firefox should have done at least 50% as well as chrome
Component: General → Canvas: WebGL
Product: Firefox for Android → Core
Whiteboard: DUPEME
Version: Firefox 20 → unspecified
tracking-fennec: --- → ?
Assignee: nobody → chrislord.net
tracking-fennec: ? → +
Assignee: chrislord.net → snorp
Status: UNCONFIRMED → NEW
Ever confirmed: true
I am fairly confident this is a canvas2d demo.
Component: Canvas: WebGL → Canvas: 2D
This is equally miserable on Mac, so setting to platform all. On Android (and Mac, where I am measuring), we are falling back onto a Cairo CPU path, which of course is devastatingly bad.

However, thats not the only issue here. Even with our new shiny SkiaGL path enabled on mac, we still suck pretty bad. I am seeing a lot of time being spent in the texture upload:

Running Time	Self		Symbol Name
1183.0ms   29.2%	1.0	 	    SkCanvas::drawRect(SkRect const&, SkPaint const&)
1180.0ms   29.1%	1.0	 	     SkGpuDevice::drawRect(SkDraw const&, SkRect const&, SkPaint const&)
945.0ms   23.3%	0.0	 	      (anonymous namespace)::skPaint2GrPaintShader(SkGpuDevice*, SkPaint const&, bool, SkGpuDevice::SkAutoCachedTexture*, GrPaint*)
942.0ms   23.3%	0.0	 	       GrLockCachedBitmapTexture(GrContext*, SkBitmap const&, GrTextureParams const*)
942.0ms   23.3%	0.0	 	        sk_gr_create_bitmap_texture(GrContext*, unsigned long long, GrTextureParams const*, SkBitmap const&)
942.0ms   23.3%	0.0	 	         GrContext::createTexture(GrTextureParams const*, GrTextureDesc const&, GrCacheData const&, void*, unsigned long)
941.0ms   23.2%	1.0	 	          GrGpu::createTexture(GrTextureDesc const&, void const*, unsigned long)
940.0ms   23.2%	0.0	 	           GrGpuGL::onCreateTexture(GrTextureDesc const&, void const*, unsigned long)
927.0ms   22.9%	0.0	 	            GrGpuGL::uploadTexData(GrGLTexture::Desc const&, bool, int, int, int, int, GrPixelConfig, void const*, unsigned long)
923.0ms   22.8%	0.0	 	             glTexImage2D
923.0ms   22.8%	1.0	 	              glTexImage2D_Exec

There is another stack that adds up to basically 90% CPU time along this path, even with GPU acceleration. My best guess is that to be reasonably fast on this benchmark we need to cache the uploads. Instead we keep re-uploading.
OS: Android → All
Hardware: Other → All
Lets dup all the other fishbowl reports against this and we need a couple blocking bugs to make things better.
Summary: fishbowl test runs at 3fps with 10 fish on nexus 4. in chrome it runs at 56fps → slow on IE Fishbowl
I did some digging. We a threshing the texture cache. The fishbowl page uses around 32MB of textures. Our cache defaults to 16MB. As a result we upload our little heart out. I added some code to set the texture cache via a pref and we hit 60fps right away. We still slow down with a lot of fish (> 500), but this is a _A LOT_ better than before. Without this patch with 10 fish we get 10fps.
Attached patch patch (obsolete) — Splinter Review
Assignee: snorp → gal
Comment on attachment 761955 [details] [diff] [review]
patch

Ignore the assert changes. Thats to work around an instant crash in debug mode on mac. What defaults should we use? And we probably want to wire this up to the low memory notification.
Attachment #761955 - Flags: review?(roc)
I am going to hijack this bug. With skiaGL enabled and this patch we are doing reasonably well, and without it, we have no chance to not suck, so we need to enable skiaGL, and we need this patch, and we should have the worst behind us.
Summary: slow on IE Fishbowl → IE fishbowl exceeds skia texture cache size
Whiteboard: DUPEME
Milan, can you please find someone to take this bug and drive this in? Thanks.
Attachment #761955 - Flags: review?(roc) → review?(gwright)
We definitely should hook up the memory observer stuff here. I have no idea how to do that though. GrContext->purgeCaches() does the purging for us, but I don't know how we find all currently allocated GLContext or GrContext.
jlebar might know what we already do about GLContexts.
Ok, with this fixed the next big thing is that we are rebuilding the display lists for 100% CPU time. That makes our FPS collapse above 250 fish or so.
Nice catch! I wonder if we can try to set a good default based on system memory size.
(In reply to Andreas Gal :gal from comment #11)
> Ok, with this fixed the next big thing is that we are rebuilding the display
> lists for 100% CPU time. That makes our FPS collapse above 250 fish or so.

Is that because there is some non-canvas content being updated for the FPS display or something? That might be hard to avoid. I ran into that a lot while trying to optimize webgl stuff too.
(In reply to Andreas Gal :gal from comment #11)
> Ok, with this fixed the next big thing is that we are rebuilding the display
> lists for 100% CPU time. That makes our FPS collapse above 250 fish or so.

Strange. As far as I can tell nothing changes except for canvases, so we shouldn't be doing any display list or layer construction.

Even if there was, the cost of display lists should be independent of the number of fish.
Assignee: gal → snorp
(In reply to Andreas Gal :gal from comment #10)
> jlebar might know what we already do about GLContexts.

We drop them on memory pressure if the process is in the bg.  See WebGLContext.cpp::WebGLMemoryPressureObserver.
Oh, and sending a fg process into the bg sends memory-pressure events.

I even wrote a test for this, but it's disabled because of bug 865844.
(In reply to Andreas Gal :gal from comment #8)
> Milan, can you please find someone to take this bug and drive this in?
> Thanks.

Looks like James is running with this, and he's part of the group that's doing the overall SkiaGL work, so it all fits.  George is reviewing, and I added Peter as he's been looking at performance.
roc, here is the DL stack:

Running Time	Self		Symbol Name
3624.0ms   27.6%	0.0	 	                        nsTimerEvent::Run()
3624.0ms   27.6%	0.0	 	                         nsTimerImpl::Fire()
3517.0ms   26.8%	0.0	 	                          mozilla::RefreshDriverTimer::TimerTick(nsITimer*, void*)
3517.0ms   26.8%	0.0	 	                           mozilla::RefreshDriverTimer::Tick()
3515.0ms   26.7%	1.0	 	                            mozilla::RefreshDriverTimer::TickDriver(nsRefreshDriver*, long long, mozilla::TimeStamp)
3512.0ms   26.7%	0.0	 	                             nsRefreshDriver::Tick(long long, mozilla::TimeStamp)
3501.0ms   26.6%	0.0	 	                              nsViewManager::ProcessPendingUpdates()
3246.0ms   24.7%	0.0	 	                               nsViewManager::ProcessPendingUpdatesForView(nsView*, bool)
3224.0ms   24.5%	0.0	 	                                PresShell::Paint(nsView*, nsRegion const&, unsigned int)
3201.0ms   24.3%	0.0	 	                                 nsLayoutUtils::PaintFrame(nsRenderingContext*, nsIFrame*, nsRegion const&, unsigned int, unsigned int)
2728.0ms   20.7%	0.0	 	                                  nsDisplayList::PaintRoot(nsDisplayListBuilder*, nsRenderingContext*, unsigned int) const
2727.0ms   20.7%	1.0	 	                                   nsDisplayList::PaintForFrame(nsDisplayListBuilder*, nsRenderingContext*, nsIFrame*, unsigned int) const
2236.0ms   17.0%	1.0	 	                                    mozilla::FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder*, mozilla::layers::LayerManager*, nsIFrame*, nsDisplayItem*, nsDisplayList const&, mozilla::FrameLayerBuilder::ContainerParameters const&, gfx3DMatrix const*, unsigned int)
2222.0ms   16.9%	3.0	 	                                     mozilla::(anonymous namespace)::ContainerState::ProcessDisplayItems(nsDisplayList const&, unsigned int)
1786.0ms   13.6%	0.0	 	                                      nsDisplayOwnLayer::BuildLayer(nsDisplayListBuilder*, mozilla::layers::LayerManager*, mozilla::FrameLayerBuilder::ContainerParameters const&)
1786.0ms   13.6%	2.0	 	                                       mozilla::FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder*, mozilla::layers::LayerManager*, nsIFrame*, nsDisplayItem*, nsDisplayList const&, mozilla::FrameLayerBuilder::ContainerParameters const&, gfx3DMatrix const*, unsigned int)
1760.0ms   13.4%	3.0	 	                                        mozilla::(anonymous namespace)::ContainerState::ProcessDisplayItems(nsDisplayList const&, unsigned int)
1530.0ms   11.6%	0.0	 	                                         nsDisplayCanvas::BuildLayer(nsDisplayListBuilder*, mozilla::layers::LayerManager*, mozilla::FrameLayerBuilder::ContainerParameters const&)
1529.0ms   11.6%	0.0	 	                                          nsHTMLCanvasFrame::BuildLayer(nsDisplayListBuilder*, mozilla::layers::LayerManager*, nsDisplayItem*, mozilla::FrameLayerBuilder::ContainerParameters const&)
1522.0ms   11.6%	0.0	 	                                           mozilla::dom::HTMLCanvasElement::GetCanvasLayer(nsDisplayListBuilder*, mozilla::layers::CanvasLayer*, mozilla::layers::LayerManager*)
1522.0ms   11.6%	0.0	 	                                            mozilla::dom::CanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder*, mozilla::layers::CanvasLayer*, mozilla::layers::LayerManager*)
1522.0ms   11.6%	0.0	 	                                             mozilla::gfx::DrawTargetSkia::Flush()
1522.0ms   11.6%	0.0	 	                                              SkCanvas::flush()
1522.0ms   11.6%	0.0	 	                                               SkGpuDevice::flush()
1522.0ms   11.6%	0.0	 	                                                GrContext::resolveRenderTarget(GrRenderTarget*)
1521.0ms   11.5%	0.0	 	                                                 GrContext::flush(int)

Flushing the draw target kills us.
I just merged patch from bug 869178 with latest m-c trunk.
I could get 55 fps with 100 fish...
Attached file new stack (obsolete) —
Attach new stack which was also related to flush calls


6385.0ms   16.4%	0.0	             nsHTMLCanvasFrame::BuildLayer(nsDisplayListBuilder*, mozilla::layers::LayerManager*, nsDisplayItem*, mozilla::FrameLayerBuilder::ContainerParameters const&)
6342.0ms   16.3%	1.0	              mozilla::dom::HTMLCanvasElement::GetCanvasLayer(nsDisplayListBuilder*, mozilla::layers::CanvasLayer*, mozilla::layers::LayerManager*)
6341.0ms   16.3%	0.0	               mozilla::dom::CanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder*, mozilla::layers::CanvasLayer*, mozilla::layers::LayerManager*)
6337.0ms   16.3%	0.0	                mozilla::gfx::DrawTargetSkia::Flush()
6336.0ms   16.3%	0.0	SkCanvas::flush()
(In reply to peter chang[:pchang] from comment #20)
> Created attachment 762599 [details]
> new stack
> 
> Attach new stack which was also related to flush calls
> 
> 
> 6385.0ms   16.4%	0.0	            
> nsHTMLCanvasFrame::BuildLayer(nsDisplayListBuilder*,
> mozilla::layers::LayerManager*, nsDisplayItem*,
> mozilla::FrameLayerBuilder::ContainerParameters const&)
> 6342.0ms   16.3%	1.0	             
> mozilla::dom::HTMLCanvasElement::GetCanvasLayer(nsDisplayListBuilder*,
> mozilla::layers::CanvasLayer*, mozilla::layers::LayerManager*)
> 6341.0ms   16.3%	0.0	              
> mozilla::dom::CanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder*,
> mozilla::layers::CanvasLayer*, mozilla::layers::LayerManager*)
> 6337.0ms   16.3%	0.0	                mozilla::gfx::DrawTargetSkia::Flush()
> 6336.0ms   16.3%	0.0	SkCanvas::flush()

Please skip this comment because the stack was the same as gal pasted at comment 18.
bug 857895 adds off-mainthread canvas painting. Thats probably the right fix here.
Comment on attachment 773345 [details] [diff] [review]
Set SkiaGL texture cache size to reasonable values

Review of attachment 773345 [details] [diff] [review]:
-----------------------------------------------------------------

::: content/canvas/src/CanvasRenderingContext2D.cpp
@@ +882,5 @@
>           if (glContext) {
>             SkAutoTUnref<GrGLInterface> i(CreateGrGLInterfaceFromGLContext(glContext));
>             mTarget = Factory::CreateDrawTargetSkiaWithGLContextAndGrGLInterface(glContext, i, size, format);
> +           mTarget->SetTextureCacheLimits(gfxPlatform::GetPlatform()->GetSkiaMaxTextureCacheCount(),
> +                                          gfxPlatform::GetPlatform()->GetSkiaMaxTextureCacheCount());

Cut and paste error?  I'm assuming you wanted the second one to be "CacheBytes"?
FYI: in Firefox 22 (on Linux) the Fishbowl does not even run. It just gives a white screen with "initializing Fishbowl..." and never gets past that. It still runs on Chrome.
Using Cairo or Skia?
Attachment #773345 - Flags: review?(gwright) → review+
Comment on attachment 773345 [details] [diff] [review]
Set SkiaGL texture cache size to reasonable values

Review of attachment 773345 [details] [diff] [review]:
-----------------------------------------------------------------

George, not sure if you saw my comment, so I don't know if the original code was correct, or if the code with my suggested modification is correct.
Attachment #773345 - Flags: review-
Yeah there was a typo. It had a lot of problems. I have some fixes on the graphics branch, will post a new patch once I know it's working alright there.
Thanks, sorry for the noise.
Attachment #761955 - Attachment is obsolete: true
Attachment #762599 - Attachment is obsolete: true
Attachment #773345 - Attachment is obsolete: true
Attachment #761955 - Flags: review?(gwright)
Attachment #796243 - Flags: review?(matt.woodrow)
Attachment #796243 - Flags: review?(matt.woodrow) → review+
Is there a nightly version of this that I can test for you guys to see how it performs? I can test on Linux (openSUSE and Ubuntu), Nexus 4, Nexus 7, Samsung Galaxy Tab 10.1.
https://hg.mozilla.org/mozilla-central/rev/7fa52a171426
Status: NEW → RESOLVED
Closed: 6 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla26
You need to log in before you can comment on or make changes to this bug.