⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 121124 in webkit


Ignore:
Timestamp:
Jun 24, 2012, 5:14:23 PM (14 years ago)
Author:
Antti Koivisto
Message:

Optimize RenderGeometryMap mappings gathering
https://bugs.webkit.org/show_bug.cgi?id=89828

Reviewed by Simon Fraser.

RenderGeometryMap currently gathers mappings by climbing the rendering tree. This is slow and can produce
large number of mapping steps. In the common case we already have the child layer coordinates available in
the layer tree and we can just use that.

The combination of faster mappings gathering and fewer number of applying steps reduces time spent under
RenderLayerCompositor::computeCompositingRequirements to less than half when scrolling the mobile version
of twitter.com.

  • rendering/RenderGeometryMap.cpp:

(WebCore):
(WebCore::RenderGeometryMap::pushMappingsToAncestor):

Use pre-computed mapping from the layer tree when possible.

(WebCore::RenderGeometryMap::popMappingsToAncestor):

  • rendering/RenderGeometryMap.h:


Add some inline capacity.

(WebCore):
(RenderGeometryMap):

  • rendering/RenderLayer.h:

(WebCore::RenderLayer::canUseConvertToLayerCoords):
(RenderLayer):

  • rendering/RenderLayerCompositor.cpp:

(WebCore::RenderLayerCompositor::addToOverlapMapRecursive):
(WebCore::RenderLayerCompositor::computeCompositingRequirements):

Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r121123 r121124  
     12012-06-24  Antti Koivisto  <antti@apple.com>
     2
     3        Optimize RenderGeometryMap mappings gathering
     4        https://bugs.webkit.org/show_bug.cgi?id=89828
     5
     6        Reviewed by Simon Fraser.
     7
     8        RenderGeometryMap currently gathers mappings by climbing the rendering tree. This is slow and can produce
     9        large number of mapping steps. In the common case we already have the child layer coordinates available in
     10        the layer tree and we can just use that.
     11       
     12        The combination of faster mappings gathering and fewer number of applying steps reduces time spent under
     13        RenderLayerCompositor::computeCompositingRequirements to less than half when scrolling the mobile version
     14        of twitter.com.
     15       
     16        * rendering/RenderGeometryMap.cpp:
     17        (WebCore):
     18        (WebCore::RenderGeometryMap::pushMappingsToAncestor):
     19       
     20            Use pre-computed mapping from the layer tree when possible.
     21
     22        (WebCore::RenderGeometryMap::popMappingsToAncestor):
     23        * rendering/RenderGeometryMap.h:
     24       
     25            Add some inline capacity.
     26
     27        (WebCore):
     28        (RenderGeometryMap):
     29        * rendering/RenderLayer.h:
     30        (WebCore::RenderLayer::canUseConvertToLayerCoords):
     31        (RenderLayer):
     32        * rendering/RenderLayerCompositor.cpp:
     33        (WebCore::RenderLayerCompositor::addToOverlapMapRecursive):
     34        (WebCore::RenderLayerCompositor::computeCompositingRequirements):
     35
    1362012-06-24  Simon Fraser  <simon.fraser@apple.com>
    237
  • trunk/Source/WebCore/rendering/RenderGeometryMap.cpp

    r118957 r121124  
    2727#include "RenderGeometryMap.h"
    2828
     29#include "RenderLayer.h"
    2930#include "RenderView.h"
    3031#include "TransformState.h"
     32#include <wtf/TemporaryChange.h>
    3133
    3234namespace WebCore {
    33 
    3435
    3536// Stores data about how to map from one renderer to its container.
     
    171172}
    172173
    173 void RenderGeometryMap::pushMappingsToAncestor(const RenderObject* renderer, const RenderBoxModelObject* ancestor)
    174 {
    175     const RenderObject* currRenderer = renderer;
    176    
     174void RenderGeometryMap::pushMappingsToAncestor(const RenderObject* renderer, const RenderBoxModelObject* ancestorRenderer)
     175{
    177176    // We need to push mappings in reverse order here, so do insertions rather than appends.
    178     m_insertionPosition = m_mapping.size();
    179    
     177    TemporaryChange<size_t> positionChange(m_insertionPosition, m_mapping.size());
    180178    do {
    181         currRenderer = currRenderer->pushMappingToContainer(ancestor, *this);
    182     } while (currRenderer && currRenderer != ancestor);
    183    
    184     m_insertionPosition = notFound;
     179        renderer = renderer->pushMappingToContainer(ancestorRenderer, *this);
     180    } while (renderer && renderer != ancestorRenderer);
     181}
     182
     183void RenderGeometryMap::pushMappingsToAncestor(const RenderLayer* layer, const RenderLayer* ancestorLayer)
     184{
     185    const RenderObject* renderer = layer->renderer();
     186
     187    // The simple case can be handled fast in the layer tree.
     188    bool canConvertInLayerTree = ancestorLayer && renderer->style()->position() != FixedPosition;
     189    for (const RenderLayer* current = layer; current != ancestorLayer && canConvertInLayerTree; current = current->parent())
     190        canConvertInLayerTree = current->canUseConvertToLayerCoords();
     191
     192    if (canConvertInLayerTree) {
     193        TemporaryChange<size_t> positionChange(m_insertionPosition, m_mapping.size());
     194        LayoutPoint layerOffset;
     195        layer->convertToLayerCoords(ancestorLayer, layerOffset);
     196        push(renderer, toLayoutSize(layerOffset), /*accumulatingTransform*/ true, /*isNonUniform*/ false, /*isFixedPosition*/ false, /*hasTransform*/ false);
     197        return;
     198    }
     199    const RenderBoxModelObject* ancestorRenderer = ancestorLayer ? ancestorLayer->renderer() : 0;
     200    pushMappingsToAncestor(renderer, ancestorRenderer);
    185201}
    186202
     
    221237}
    222238
    223 void RenderGeometryMap::popMappingsToAncestor(const RenderBoxModelObject* ancestor)
     239void RenderGeometryMap::popMappingsToAncestor(const RenderBoxModelObject* ancestorRenderer)
    224240{
    225241    ASSERT(m_mapping.size());
    226242
    227     while (m_mapping.size() && m_mapping.last()->m_renderer != ancestor) {
     243    while (m_mapping.size() && m_mapping.last()->m_renderer != ancestorRenderer) {
    228244        stepRemoved(*m_mapping.last().get());
    229245        m_mapping.removeLast();
    230246    }
     247}
     248
     249void RenderGeometryMap::popMappingsToAncestor(const RenderLayer* ancestorLayer)
     250{
     251    const RenderBoxModelObject* ancestorRenderer = ancestorLayer ? ancestorLayer->renderer() : 0;
     252    popMappingsToAncestor(ancestorRenderer);
    231253}
    232254
  • trunk/Source/WebCore/rendering/RenderGeometryMap.h

    r118567 r121124  
    3737
    3838class RenderGeometryMapStep;
     39class RenderLayer;
    3940
    4041// Can be used while walking the Renderer tree to cache data about offsets and transforms.
     
    4849   
    4950    // Called by code walking the renderer or layer trees.
    50     void pushMappingsToAncestor(const RenderObject*, const RenderBoxModelObject* ancestor);
     51    void pushMappingsToAncestor(const RenderLayer*, const RenderLayer* ancestorLayer);
     52    void popMappingsToAncestor(const RenderLayer*);
     53    void pushMappingsToAncestor(const RenderObject*, const RenderBoxModelObject* ancestorRenderer);
    5154    void popMappingsToAncestor(const RenderBoxModelObject*);
    5255   
     
    7174    bool hasFixedPositionStep() const { return m_fixedStepsCount; }
    7275   
    73     typedef Vector<OwnPtr<RenderGeometryMapStep> > RenderGeometryMapSteps; // FIXME: inline capacity?
    74    
     76    typedef Vector<OwnPtr<RenderGeometryMapStep>, 32> RenderGeometryMapSteps;
     77
    7578    size_t m_insertionPosition;
    7679    int m_nonUniformStepsCount;
  • trunk/Source/WebCore/rendering/RenderLayer.h

    r120832 r121124  
    474474#endif
    475475
     476    bool canUseConvertToLayerCoords() const
     477    {
     478        // These RenderObject have an impact on their layers' without them knowing about it.
     479        return !renderer()->hasColumns() && !renderer()->hasTransform() && !isComposited()
     480#if ENABLE(SVG)
     481            && !renderer()->isSVGRoot()
     482#endif
     483            ;
     484    }
     485
    476486    void convertToPixelSnappedLayerCoords(const RenderLayer* ancestorLayer, IntPoint& location) const;
    477487    void convertToPixelSnappedLayerCoords(const RenderLayer* ancestorLayer, IntRect&) const;
     
    859869    LayoutUnit overflowRight() const;
    860870
    861     bool canUseConvertToLayerCoords() const
    862     {
    863         // These RenderObject have an impact on their layers' without them knowing about it.
    864         return !renderer()->hasColumns() && !renderer()->hasTransform() && !isComposited()
    865 #if ENABLE(SVG)
    866             && !renderer()->isSVGRoot()
    867 #endif
    868             ;
    869     }
    870 
    871871    LayoutUnit verticalScrollbarStart(int minX, int maxX) const;
    872872    LayoutUnit horizontalScrollbarStart(int minX) const;
  • trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp

    r121123 r121124  
    672672    // A null ancestorLayer is an indication that 'layer' has already been pushed.
    673673    if (ancestorLayer)
    674         overlapMap.geometryMap().pushMappingsToAncestor(layer->renderer(), ancestorLayer->renderer());
     674        overlapMap.geometryMap().pushMappingsToAncestor(layer, ancestorLayer);
    675675   
    676676    IntRect bounds;
     
    711711   
    712712    if (ancestorLayer)
    713         overlapMap.geometryMap().popMappingsToAncestor(ancestorLayer->renderer());
     713        overlapMap.geometryMap().popMappingsToAncestor(ancestorLayer);
    714714}
    715715
     
    728728   
    729729    if (overlapMap)
    730         overlapMap->geometryMap().pushMappingsToAncestor(layer->renderer(), ancestorLayer ? ancestorLayer->renderer() : 0);
     730        overlapMap->geometryMap().pushMappingsToAncestor(layer, ancestorLayer);
    731731   
    732732    // Clear the flag
     
    911911
    912912    if (overlapMap)
    913         overlapMap->geometryMap().popMappingsToAncestor(ancestorLayer ? ancestorLayer->renderer() : 0);
     913        overlapMap->geometryMap().popMappingsToAncestor(ancestorLayer);
    914914}
    915915
Note: See TracChangeset for help on using the changeset viewer.