Closed Bug 753228 Opened 12 years ago Closed 3 years ago

Too many gfxImageSurface allocations on linux while scrolling with xrender disabled and GL layers enabled

Categories

(Core :: Graphics, defect)

x86_64
Linux
defect
Not set
normal

Tracking

()

RESOLVED WONTFIX

People

(Reporter: bjacob, Unassigned)

References

Details

Attachments

(1 file)

On linux, with these prefs,

  gfx.xrender.enabled=false
  layers.acceleration.force-enabled=true

scrolling is really slow.

The attached profile was recorded while scrolling on planet.mozilla.org. It's an inverted callgraph (perf report -G).

The top entry is GL work, called by the LayerManagerOGL, called by PresShell::Paint. Seems normal for scrolling.

But below that, we have what seems like the kernel going crazy.

Further below, some libcairo.so stuff without frame pointers, so that's system cairo, I guess called by GTK (?).

And the next Firefox entry is

  gfxImageSurface::gfxImageSurface(nsIntSize const&, gfxASurface::gfxImageFormat, bool)

With this nice inverted callgraph:

                expose_event_cb(_GtkWidget*, _GdkEventExpose*)
                nsWindow::OnExposeEvent(_GdkEventExpose*)
                nsWindow::DispatchEvent(nsGUIEvent*, nsEventStatus&)
                HandleEvent(nsGUIEvent*)
                nsViewManager::DispatchEvent(nsGUIEvent*, nsIView*, nsEventStatus*)
                nsViewManager::Refresh(nsView*, nsIWidget*, nsIntRegion const&, bool)
                PresShell::Paint(nsIView*, nsIWidget*, nsRegion const&, nsIntRegion const&, bool)
                nsLayoutUtils::PaintFrame(nsRenderingContext*, nsIFrame*, nsRegion const&, unsigned int, unsigned int)
                nsDisplayList::PaintRoot(nsDisplayListBuilder*, nsRenderingContext*, unsigned int) const
                nsDisplayList::PaintForFrame(nsDisplayListBuilder*, nsRenderingContext*, nsIFrame*, unsigned int) const
                mozilla::layers::LayerManagerOGL::EndTransaction(void (*)(mozilla::layers::ThebesLayer*, gfxContext*, nsIntRegion const&, nsIntRegion const&, void*), void*, mozilla::layers::LayerManager::EndTransactionFlags)
                mozilla::layers::LayerManagerOGL::Render()
                mozilla::layers::ContainerLayerOGL::RenderLayer(int, nsIntPoint const&)
                mozilla::layers::ContainerLayerOGL::RenderLayer(int, nsIntPoint const&)
               |          
               |--93.31%-- _ZN7mozilla6layers14ThebesLayerOGL11RenderLayerEiRK10nsIntPoint.part.71
               |          mozilla::layers::BasicBufferOGL::BeginPaint(gfxASurface::gfxContentType, unsigned int)
               |          mozilla::gl::BasicTextureImage::BeginUpdate(nsIntRegion&)
               |          mozilla::layers::LayerManager::CreateOptimalSurface(nsIntSize const&, gfxASurface::gfxImageFormat)
               |          gfxPlatformGtk::CreateOffscreenSurface(nsIntSize const&, gfxASurface::gfxContentType)
               |          gfxImageSurface::gfxImageSurface(nsIntSize const&, gfxASurface::gfxImageFormat, bool)
               |          
                --6.69%-- mozilla::layers::ContainerLayerOGL::RenderLayer(int, nsIntPoint const&)
                          _ZN7mozilla6layers14ThebesLayerOGL11RenderLayerEiRK10nsIntPoint.part.71
                          mozilla::layers::BasicBufferOGL::BeginPaint(gfxASurface::gfxContentType, unsigned int)
                          mozilla::gl::BasicTextureImage::BeginUpdate(nsIntRegion&)
                          mozilla::layers::LayerManager::CreateOptimalSurface(nsIntSize const&, gfxASurface::gfxImageFormat)
                          gfxPlatformGtk::CreateOffscreenSurface(nsIntSize const&, gfxASurface::gfxContentType)
                          gfxImageSurface::gfxImageSurface(nsIntSize const&, gfxASurface::gfxImageFormat, bool)
If I correctly interprete

  $ perf script | grep gfxImageSurface\:\:gfxImageSurface | wc -l
  80

It seems that over the few seconds of scrolling that I recorded, 80 gfxImageSurface's were constructed.
Scrap comment 1, it rather means that 80 samples were under gfxImageSurface constructors.
Here's a sample (from `perf script`) showing gfxImageSurface constructor causing a page fault:

firefox 32231 cycles: 
        ffffffff81316f01 clear_page ([kernel.kallsyms])
        ffffffff8112010f get_page_from_freelist ([kernel.kallsyms])
        ffffffff8112071e __alloc_pages_nodemask ([kernel.kallsyms])
        ffffffff811594da alloc_pages_vma ([kernel.kallsyms])
        ffffffff81139dec do_anonymous_page.isra.38 ([kernel.kallsyms])
        ffffffff8113d801 handle_pte_fault ([kernel.kallsyms])
        ffffffff8113dbd8 handle_mm_fault ([kernel.kallsyms])
        ffffffff8165ffa0 do_page_fault ([kernel.kallsyms])
        ffffffff8165cbf5 page_fault ([kernel.kallsyms])
            7f71cf18ee0f gfxImageSurface::gfxImageSurface(nsIntSize const&, gfxASurface::gfxImageFormat, bool) (/hack/mozilla-central/ob
            7f71cf1addaf gfxPlatformGtk::CreateOffscreenSurface(nsIntSize const&, gfxASurface::gfxContentType) (/hack/mozilla-central/ob
            7f71cf1ba4e2 mozilla::layers::LayerManager::CreateOptimalSurface(nsIntSize const&, gfxASurface::gfxImageFormat) (/hack/mozil
            7f71cf1d0eae mozilla::gl::BasicTextureImage::BeginUpdate(nsIntRegion&) (/hack/mozilla-central/obj-firefox-release/toolkit/li
            7f71cf1c7f08 mozilla::layers::BasicBufferOGL::BeginPaint(gfxASurface::gfxContentType, unsigned int) (/hack/mozilla-central/o
            7f71cf1c6a5a _ZN7mozilla6layers14ThebesLayerOGL11RenderLayerEiRK10nsIntPoint.part.71 (/hack/mozilla-central/obj-firefox-rele
            7f71cf1bfd17 mozilla::layers::ContainerLayerOGL::RenderLayer(int, nsIntPoint const&) (/hack/mozilla-central/obj-firefox-rele
            7f71cf1bfd17 mozilla::layers::ContainerLayerOGL::RenderLayer(int, nsIntPoint const&) (/hack/mozilla-central/obj-firefox-rele
            7f71cf1c3ed2 mozilla::layers::LayerManagerOGL::Render() (/hack/mozilla-central/obj-firefox-release/toolkit/library/libxul.so
            7f71cf1c4330 mozilla::layers::LayerManagerOGL::EndTransaction(void (*)(mozilla::layers::ThebesLayer*, gfxContext*, nsIntRegi
            7f71ce8b3287 nsDisplayList::PaintForFrame(nsDisplayListBuilder*, nsRenderingContext*, nsIFrame*, unsigned int) const (/hack/
            7f71ce8b332d nsDisplayList::PaintRoot(nsDisplayListBuilder*, nsRenderingContext*, unsigned int) const (/hack/mozilla-central
            7f71ce8c62ad nsLayoutUtils::PaintFrame(nsRenderingContext*, nsIFrame*, nsRegion const&, unsigned int, unsigned int) (/hack/m
            7f71ce8d5cdb PresShell::Paint(nsIView*, nsIWidget*, nsRegion const&, nsIntRegion const&, bool) (/hack/mozilla-central/obj-fi
            7f71ceba34b6 nsViewManager::Refresh(nsView*, nsIWidget*, nsIntRegion const&, bool) (/hack/mozilla-central/obj-firefox-releas
            7f71ceba49e8 nsViewManager::DispatchEvent(nsGUIEvent*, nsIView*, nsEventStatus*) (/hack/mozilla-central/obj-firefox-release/
            7f71ceba2968 HandleEvent(nsGUIEvent*) (/hack/mozilla-central/obj-firefox-release/toolkit/library/libxul.so)
            7f71cefee1fd nsWindow::DispatchEvent(nsGUIEvent*, nsEventStatus&) (/hack/mozilla-central/obj-firefox-release/toolkit/library
            7f71ceff5678 nsWindow::OnExposeEvent(_GdkEventExpose*) (/hack/mozilla-central/obj-firefox-release/toolkit/library/libxul.so)
            7f71ceff5a6e expose_event_cb(_GtkWidget*, _GdkEventExpose*) (/hack/mozilla-central/obj-firefox-release/toolkit/library/libxu
            7f71cb801dd8  (/usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0.2400.10)
And gfxImageSurface destructors are causing the kernel to do work too, see sample below. This suggests that it might be worth reusing gfxImageSurface's rather than creating them and destroying them all the time.

        ffffffff8111dad6 get_pageblock_flags_group ([kernel.kallsyms])
        ffffffff8111f997 free_hot_cold_page ([kernel.kallsyms])
        ffffffff8111fce4 __pagevec_free ([kernel.kallsyms])
        ffffffff81123dec release_pages ([kernel.kallsyms])
        ffffffff8114e59e free_pages_and_swap_cache ([kernel.kallsyms])
        ffffffff8113a70c tlb_flush_mmu ([kernel.kallsyms])
        ffffffff8113a744 tlb_finish_mmu ([kernel.kallsyms])
        ffffffff8113d007 zap_page_range ([kernel.kallsyms])
        ffffffff8113951d madvise_vma ([kernel.kallsyms])
        ffffffff8113973e sys_madvise ([kernel.kallsyms])
        ffffffff81664a82 system_call_fastpath ([kernel.kallsyms])
            7f71d05d2957 madvise (/lib/x86_64-linux-gnu/libc-2.15.so)
                  40bc7d arena_dalloc (/hack/mozilla-central/obj-firefox-release/dist/bin/firefox)
            7f71cf18eb0c gfxImageSurface::~gfxImageSurface() (/hack/mozilla-central/obj-firefox-release/toolkit/library/libxul.so)
            7f71cf18eb27 gfxImageSurface::~gfxImageSurface() (/hack/mozilla-central/obj-firefox-release/toolkit/library/libxul.so)
            7f71cf1f548a _cairo_user_data_array_fini (/hack/mozilla-central/obj-firefox-release/toolkit/library/libxul.so)
            7f71cf217d01 INT__moz_cairo_surface_destroy (/hack/mozilla-central/obj-firefox-release/toolkit/library/libxul.so)
            7f71cf187496 gfxASurface::Release() (/hack/mozilla-central/obj-firefox-release/toolkit/library/libxul.so)
            7f71cf18df6d gfxContext::~gfxContext() (/hack/mozilla-central/obj-firefox-release/toolkit/library/libxul.so)
            7f71ce8a0e05 gfxContext::Release() (/hack/mozilla-central/obj-firefox-release/toolkit/library/libxul.so)
            7f71cf1c6bde _ZN7mozilla6layers14ThebesLayerOGL11RenderLayerEiRK10nsIntPoint.part.71 (/hack/mozilla-central/obj-firefox-rele
            7f71cf1bfd17 mozilla::layers::ContainerLayerOGL::RenderLayer(int, nsIntPoint const&) (/hack/mozilla-central/obj-firefox-rele
            7f71cf1bfd17 mozilla::layers::ContainerLayerOGL::RenderLayer(int, nsIntPoint const&) (/hack/mozilla-central/obj-firefox-rele
            7f71cf1c3ed2 mozilla::layers::LayerManagerOGL::Render() (/hack/mozilla-central/obj-firefox-release/toolkit/library/libxul.so
            7f71cf1c4330 mozilla::layers::LayerManagerOGL::EndTransaction(void (*)(mozilla::layers::ThebesLayer*, gfxContext*, nsIntRegi
            7f71ce8b3287 nsDisplayList::PaintForFrame(nsDisplayListBuilder*, nsRenderingContext*, nsIFrame*, unsigned int) const (/hack/
            7f71ce8b332d nsDisplayList::PaintRoot(nsDisplayListBuilder*, nsRenderingContext*, unsigned int) const (/hack/mozilla-central
            7f71ce8c62ad nsLayoutUtils::PaintFrame(nsRenderingContext*, nsIFrame*, nsRegion const&, unsigned int, unsigned int) (/hack/m
            7f71ce8d5cdb PresShell::Paint(nsIView*, nsIWidget*, nsRegion const&, nsIntRegion const&, bool) (/hack/mozilla-central/obj-fi
            7f71ceba34b6 nsViewManager::Refresh(nsView*, nsIWidget*, nsIntRegion const&, bool) (/hack/mozilla-central/obj-firefox-releas
            7f71ceba49e8 nsViewManager::DispatchEvent(nsGUIEvent*, nsIView*, nsEventStatus*) (/hack/mozilla-central/obj-firefox-release/
            7f71ceba2968 HandleEvent(nsGUIEvent*) (/hack/mozilla-central/obj-firefox-release/toolkit/library/libxul.so)
            7f71cefee1fd nsWindow::DispatchEvent(nsGUIEvent*, nsEventStatus&) (/hack/mozilla-central/obj-firefox-release/toolkit/library
            7f71ceff5678 nsWindow::OnExposeEvent(_GdkEventExpose*) (/hack/mozilla-central/obj-firefox-release/toolkit/library/libxul.so)
            7f71ceff5a6e expose_event_cb(_GtkWidget*, _GdkEventExpose*) (/hack/mozilla-central/obj-firefox-release/toolkit/library/libxu
            7f71cb801dd8  (/usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0.2400.10)
We keep creating a lot of gfxImageSurface with the same size.
For instance when a throbber is spinning on a tab, a 16x16 gfxImageSurface is allocated every frame.
Assignee: nobody → nsilva
Assignee: nical.bugzilla → nobody
See Also: → 1247935
Status: NEW → RESOLVED
Closed: 3 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: