Changeset 132990 in webkit


Ignore:
Timestamp:
Oct 30, 2012 11:48:11 PM (11 years ago)
Author:
eric@webkit.org
Message:

RoboHornetPro spends ~25% of total test time in WebCore::Region::Shape methods
https://bugs.webkit.org/show_bug.cgi?id=98800

Reviewed by Sam Weinig.

This patch brings our total RoboHornetPro time from 8.2 seconds to 5.3 seconds!

OverlapMap previously used Regions to track Layer bounds rects.
Unfortunately unioning a list of Regions is O(N2)
where N is the number of Shapes (in this case rects).
This is because Shapes are immutable, so to union two shapes, we copy
both Shapes' segment/span vectors into a single new Shape.
Thus if we union a set of M Regions, each with 1 Shape, we'll end up copying
the segments of the first Shape N times before we have the final Region/Shape
and the second shape N-1 times. The sum of 1 to N is (N*(N-1))/2 aka order N
2.
Fixing the N2 algorithm covered by https://bugs.webkit.org/show_bug.cgi?id=100814.

For now we just avoid this O(N2) by moving away from Region, since OverlapMap
doesn't need it. We just collect a vector of the layer rects and hit-test that directly.
Hit-testing the rect list is O(N), just like hit-testing the same information in a Region would be.

Even better for us is that the OverlapMap is never even used in RoboHornetPro.
We just collect these rects to end up doing nothing with them. :)

  • rendering/RenderLayerCompositor.cpp:

(WebCore::RenderLayerCompositor::OverlapMap::add):
(WebCore::RenderLayerCompositor::OverlapMap::overlapsLayers):
(WebCore::RenderLayerCompositor::OverlapMap::pushCompositingContainer):
(WebCore::RenderLayerCompositor::OverlapMap::popCompositingContainer):
(RenderLayerCompositor::OverlapMap):

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r132986 r132990  
     12012-10-30  Eric Seidel  <eric@webkit.org>
     2
     3        RoboHornetPro spends ~25% of total test time in WebCore::Region::Shape methods
     4        https://bugs.webkit.org/show_bug.cgi?id=98800
     5
     6        Reviewed by Sam Weinig.
     7
     8        This patch brings our total RoboHornetPro time from 8.2 seconds to 5.3 seconds!
     9
     10        OverlapMap previously used Regions to track Layer bounds rects.
     11        Unfortunately unioning a list of Regions is O(N^2)
     12        where N is the number of Shapes (in this case rects).
     13        This is because Shapes are immutable, so to union two shapes, we copy
     14        both Shapes' segment/span vectors into a single new Shape.
     15        Thus if we union a set of M Regions, each with 1 Shape, we'll end up copying
     16        the segments of the first Shape N times before we have the final Region/Shape
     17        and the second shape N-1 times. The sum of 1 to N is (N*(N-1))/2 aka order N^2.
     18        Fixing the N^2 algorithm covered by https://bugs.webkit.org/show_bug.cgi?id=100814.
     19
     20        For now we just avoid this O(N^2) by moving away from Region, since OverlapMap
     21        doesn't need it. We just collect a vector of the layer rects and hit-test that directly.
     22        Hit-testing the rect list is O(N), just like hit-testing the same information in a Region would be.
     23
     24        Even better for us is that the OverlapMap is never even used in RoboHornetPro.
     25        We just collect these rects to end up doing nothing with them. :)
     26
     27        * rendering/RenderLayerCompositor.cpp:
     28        (WebCore::RenderLayerCompositor::OverlapMap::add):
     29        (WebCore::RenderLayerCompositor::OverlapMap::overlapsLayers):
     30        (WebCore::RenderLayerCompositor::OverlapMap::pushCompositingContainer):
     31        (WebCore::RenderLayerCompositor::OverlapMap::popCompositingContainer):
     32        (RenderLayerCompositor::OverlapMap):
     33
    1342012-10-30  Beth Dakin  <bdakin@apple.com>
    235
  • trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp

    r132542 r132990  
    9696        // recursively processed and popped off the stack.
    9797        ASSERT(m_overlapStack.size() >= 2);
    98         m_overlapStack[m_overlapStack.size() - 2].unite(bounds);
     98        m_overlapStack[m_overlapStack.size() - 2].append(bounds);
    9999        m_layers.add(layer);
    100100    }
     
    107107    bool overlapsLayers(const IntRect& bounds) const
    108108    {
    109         return m_overlapStack.last().intersects(bounds);
     109        const RectList& layerRects = m_overlapStack.last();
     110        for (unsigned i = 0; i < layerRects.size(); i++) {
     111            if (layerRects[i].intersects(bounds))
     112                return true;
     113        }
     114        return false;
    110115    }
    111116
     
    117122    void pushCompositingContainer()
    118123    {
    119         m_overlapStack.append(Region());
     124        m_overlapStack.append(RectList());
    120125    }
    121126
    122127    void popCompositingContainer()
    123128    {
    124         m_overlapStack[m_overlapStack.size() - 2].unite(m_overlapStack.last());
     129        m_overlapStack[m_overlapStack.size() - 2].append(m_overlapStack.last());
    125130        m_overlapStack.removeLast();
    126131    }
    127    
     132
    128133    RenderGeometryMap& geometryMap() { return m_geometryMap; }
    129134
    130135private:
    131     Vector<Region> m_overlapStack;
     136    typedef Vector<IntRect> RectList;
     137    Vector<RectList> m_overlapStack;
    132138    HashSet<const RenderLayer*> m_layers;
    133139    RenderGeometryMap m_geometryMap;
Note: See TracChangeset for help on using the changeset viewer.