Changeset 26077 in webkit


Ignore:
Timestamp:
Oct 6, 2007 1:49:47 AM (17 years ago)
Author:
eseidel
Message:

2007-10-06 Eric Seidel <eric@webkit.org>

Reviewed by Oliver Hunt.

RenderSVGContainer (<g>) should not repaint when its bounds change (unless it has a filter)
http://bugs.webkit.org/show_bug.cgi?id=15388
This makes the Sun Lively Kernel invalidate only what it should!


No tests possible in DRT.

  • ksvg2/svg/SVGCircleElement.cpp: (WebCore::SVGCircleElement::notifyAttributeChange): replace call to rebuildRenderer
  • ksvg2/svg/SVGEllipseElement.cpp: (WebCore::SVGEllipseElement::notifyAttributeChange): replace call to rebuildRenderer
  • ksvg2/svg/SVGImageElement.cpp: (WebCore::SVGImageElement::notifyAttributeChange): replace call to rebuildRenderer (WebCore::SVGImageElement::hasRelativeValues): implemented
  • ksvg2/svg/SVGImageElement.h:
  • ksvg2/svg/SVGLineElement.cpp: (WebCore::SVGLineElement::notifyAttributeChange): replace call to rebuildRenderer
  • ksvg2/svg/SVGPathElement.cpp: (WebCore::SVGPathElement::notifyAttributeChange): replace call to rebuildRenderer
  • ksvg2/svg/SVGPolyElement.cpp: (WebCore::SVGPolyElement::notifyAttributeChange): replace call to rebuildRenderer
  • ksvg2/svg/SVGRectElement.cpp: (WebCore::SVGRectElement::notifyAttributeChange): replace call to rebuildRenderer
  • ksvg2/svg/SVGStyledElement.cpp:
  • ksvg2/svg/SVGStyledElement.h: (WebCore::SVGStyledElement::hasRelativeValues): default to true instead
  • ksvg2/svg/SVGStyledTransformableElement.cpp: (WebCore::SVGStyledTransformableElement::updateLocalTransform): don't layout if no change
  • ksvg2/svg/SVGStyledTransformableElement.h:
  • ksvg2/svg/SVGTransform.h:
  • rendering/RenderPath.cpp: (WebCore::RenderPath::layout):
  • rendering/RenderPath.h:
  • rendering/RenderSVGContainer.cpp: (WebCore::RenderSVGContainer::layout): (WebCore::RenderSVGContainer::selfWillPaint): return true if have a filter (WebCore::RenderSVGContainer::paint):
  • rendering/RenderSVGContainer.h:
  • rendering/RenderSVGHiddenContainer.cpp: (WebCore::RenderSVGHiddenContainer::layout):
  • rendering/RenderSVGRoot.cpp: (WebCore::RenderSVGRoot::layout):
  • rendering/RenderSVGViewportContainer.cpp: (WebCore::RenderSVGViewportContainer::layout): (WebCore::RenderSVGViewportContainer::calcViewport): use floats
Location:
branches/feature-branch/WebCore
Files:
21 edited

Legend:

Unmodified
Added
Removed
  • branches/feature-branch/WebCore/ChangeLog

    r26076 r26077  
     12007-10-06  Eric Seidel  <eric@webkit.org>
     2
     3        Reviewed by Oliver Hunt.
     4
     5        RenderSVGContainer (<g>) should not repaint when its bounds change (unless it has a filter)
     6        http://bugs.webkit.org/show_bug.cgi?id=15388
     7        This makes the Sun Lively Kernel invalidate only what it should!
     8       
     9        No tests possible in DRT.
     10
     11        * ksvg2/svg/SVGCircleElement.cpp:
     12        (WebCore::SVGCircleElement::notifyAttributeChange): replace call to rebuildRenderer
     13        * ksvg2/svg/SVGEllipseElement.cpp:
     14        (WebCore::SVGEllipseElement::notifyAttributeChange): replace call to rebuildRenderer
     15        * ksvg2/svg/SVGImageElement.cpp:
     16        (WebCore::SVGImageElement::notifyAttributeChange): replace call to rebuildRenderer
     17        (WebCore::SVGImageElement::hasRelativeValues): implemented
     18        * ksvg2/svg/SVGImageElement.h:
     19        * ksvg2/svg/SVGLineElement.cpp:
     20        (WebCore::SVGLineElement::notifyAttributeChange): replace call to rebuildRenderer
     21        * ksvg2/svg/SVGPathElement.cpp:
     22        (WebCore::SVGPathElement::notifyAttributeChange): replace call to rebuildRenderer
     23        * ksvg2/svg/SVGPolyElement.cpp:
     24        (WebCore::SVGPolyElement::notifyAttributeChange): replace call to rebuildRenderer
     25        * ksvg2/svg/SVGRectElement.cpp:
     26        (WebCore::SVGRectElement::notifyAttributeChange): replace call to rebuildRenderer
     27        * ksvg2/svg/SVGStyledElement.cpp:
     28        * ksvg2/svg/SVGStyledElement.h:
     29        (WebCore::SVGStyledElement::hasRelativeValues): default to true instead
     30        * ksvg2/svg/SVGStyledTransformableElement.cpp:
     31        (WebCore::SVGStyledTransformableElement::updateLocalTransform): don't layout if no change
     32        * ksvg2/svg/SVGStyledTransformableElement.h:
     33        * ksvg2/svg/SVGTransform.h:
     34        * rendering/RenderPath.cpp:
     35        (WebCore::RenderPath::layout):
     36        * rendering/RenderPath.h:
     37        * rendering/RenderSVGContainer.cpp:
     38        (WebCore::RenderSVGContainer::layout):
     39        (WebCore::RenderSVGContainer::selfWillPaint): return true if have a filter
     40        (WebCore::RenderSVGContainer::paint):
     41        * rendering/RenderSVGContainer.h:
     42        * rendering/RenderSVGHiddenContainer.cpp:
     43        (WebCore::RenderSVGHiddenContainer::layout):
     44        * rendering/RenderSVGRoot.cpp:
     45        (WebCore::RenderSVGRoot::layout):
     46        * rendering/RenderSVGViewportContainer.cpp:
     47        (WebCore::RenderSVGViewportContainer::layout):
     48        (WebCore::RenderSVGViewportContainer::calcViewport): use floats
     49
    1502007-10-06  Rob Buis  <buis@kde.org>
    251
  • branches/feature-branch/WebCore/ksvg2/svg/SVGCircleElement.cpp

    r26076 r26077  
    2727
    2828#include "FloatPoint.h"
     29#include "RenderPath.h"
    2930#include "SVGNames.h"
    3031
     
    7374void SVGCircleElement::notifyAttributeChange() const
    7475{
    75     if (!document()->parsing())
    76         rebuildRenderer();
     76    if (!document()->parsing() && renderer())
     77        renderer()->setNeedsLayout(true);
    7778
    7879    SVGStyledTransformableElement::notifyAttributeChange();
  • branches/feature-branch/WebCore/ksvg2/svg/SVGEllipseElement.cpp

    r26076 r26077  
    2727
    2828#include "FloatPoint.h"
     29#include "RenderPath.h"
    2930#include "SVGLength.h"
    3031#include "SVGNames.h"
     
    8081void SVGEllipseElement::notifyAttributeChange() const
    8182{
    82     if (!document()->parsing())
    83         rebuildRenderer();
     83    if (!document()->parsing() && renderer())
     84        renderer()->setNeedsLayout(true);
    8485
    8586    SVGStyledTransformableElement::notifyAttributeChange();
  • branches/feature-branch/WebCore/ksvg2/svg/SVGImageElement.cpp

    r26076 r26077  
    102102void SVGImageElement::notifyAttributeChange() const
    103103{
    104     if (!document()->parsing())
    105         rebuildRenderer();
     104    if (!document()->parsing() && renderer())
     105        renderer()->setNeedsLayout(true);
    106106
    107107    SVGStyledTransformableElement::notifyAttributeChange();
     108}
     109
     110bool SVGImageElement::hasRelativeValues() const
     111{
     112    return (x().isRelative() || width().isRelative() ||
     113            y().isRelative() || height().isRelative());
    108114}
    109115
  • branches/feature-branch/WebCore/ksvg2/svg/SVGImageElement.h

    r25754 r26077  
    6161    protected:
    6262        virtual bool haveLoadedRequiredResources();
     63       
     64        virtual bool hasRelativeValues() const;
    6365
    6466    protected:
  • branches/feature-branch/WebCore/ksvg2/svg/SVGLineElement.cpp

    r26076 r26077  
    2727
    2828#include "FloatPoint.h"
     29#include "RenderPath.h"
    2930#include "SVGLength.h"
    3031#include "SVGNames.h"
     
    7778void SVGLineElement::notifyAttributeChange() const
    7879{
    79     if (!document()->parsing())
    80         rebuildRenderer();
     80    if (!document()->parsing() && renderer())
     81        renderer()->setNeedsLayout(true);
    8182
    8283    SVGStyledTransformableElement::notifyAttributeChange();
  • branches/feature-branch/WebCore/ksvg2/svg/SVGPathElement.cpp

    r26076 r26077  
    2626#include "SVGPathElement.h"
    2727
     28#include "RenderPath.h"
    2829#include "SVGNames.h"
    2930#include "SVGParserUtilities.h"
     
    195196void SVGPathElement::notifyAttributeChange() const
    196197{
    197     if (!document()->parsing())
    198         rebuildRenderer();
     198    if (!document()->parsing() && renderer())
     199        renderer()->setNeedsLayout(true);
    199200
    200201    SVGStyledTransformableElement::notifyAttributeChange();
  • branches/feature-branch/WebCore/ksvg2/svg/SVGPolyElement.cpp

    r26076 r26077  
    2828#include "Document.h"
    2929#include "FloatPoint.h"
     30#include "RenderPath.h"
    3031#include "SVGNames.h"
    3132#include "SVGParserUtilities.h"
     
    8990
    9091    m_ignoreAttributeChanges = true;
    91     rebuildRenderer();
    92 
     92    if (renderer())
     93        renderer()->setNeedsLayout(true);
     94   
    9395    ExceptionCode ec = 0;
    9496
  • branches/feature-branch/WebCore/ksvg2/svg/SVGRectElement.cpp

    r26076 r26077  
    2525#include "SVGRectElement.h"
    2626
     27#include "RenderPath.h"
    2728#include "SVGLength.h"
    2829#include "SVGNames.h"
     
    9091void SVGRectElement::notifyAttributeChange() const
    9192{
    92     if (!document()->parsing())
    93         rebuildRenderer();
    94 
     93    if (!document()->parsing() && renderer())
     94        renderer()->setNeedsLayout(true);
     95   
    9596    SVGStyledTransformableElement::notifyAttributeChange();
    9697}
  • branches/feature-branch/WebCore/ksvg2/svg/SVGStyledElement.cpp

    r25884 r26077  
    275275}
    276276
    277 void SVGStyledElement::rebuildRenderer() const
    278 {
    279     if (!renderer() || !renderer()->isRenderPath())
    280         return;
    281 
    282     RenderPath* renderPath = static_cast<RenderPath*>(renderer());
    283     SVGElement* parentElement = svg_dynamic_cast(parentNode());
    284     if (parentElement && parentElement->renderer() && parentElement->isStyled() &&
    285         parentElement->childShouldCreateRenderer(const_cast<SVGStyledElement*>(this)))
    286         renderPath->setNeedsLayout(true);
    287 }
    288 
    289277}
    290278
  • branches/feature-branch/WebCore/ksvg2/svg/SVGStyledElement.h

    r25884 r26077  
    6464        // Centralized place to force a manual style resolution. Hacky but needed for now.
    6565        RenderStyle* resolveStyle(RenderStyle* parentStyle);
    66 
     66       
    6767    protected:
    68         friend class RenderPath;
    69         void rebuildRenderer() const;
    70 
    71         virtual bool hasRelativeValues() const { return false; }
     68        virtual bool hasRelativeValues() const { return true; }
    7269       
    7370        static int cssPropertyIdForSVGAttributeName(const QualifiedName&);
  • branches/feature-branch/WebCore/ksvg2/svg/SVGStyledTransformableElement.cpp

    r25873 r26077  
    6767void SVGStyledTransformableElement::updateLocalTransform(SVGTransformList* localTransforms)
    6868{
    69     // Update cached local matrix
    7069    SVGTransform localTransform = localTransforms->concatenate();
    71     if (localTransform.isValid())
    72         m_localMatrix = localTransform.matrix();
    73     else
    74         m_localMatrix = AffineTransform();
     70    if (localTransform.matrix() == m_localMatrix)
     71        return;
     72   
     73    m_localMatrix = localTransform.matrix();
    7574    if (renderer()) {
    7675        renderer()->setLocalTransform(m_localMatrix);
  • branches/feature-branch/WebCore/ksvg2/svg/SVGStyledTransformableElement.h

    r25852 r26077  
    5454        virtual FloatRect getBBox() const;
    5555
    56         virtual void parseMappedAttribute(MappedAttribute* attr);
     56        virtual void parseMappedAttribute(MappedAttribute*);
    5757
    58         void updateLocalTransform(SVGTransformList* localTransforms);
     58        void updateLocalTransform(SVGTransformList*);
    5959       
    6060        virtual void attach();
  • branches/feature-branch/WebCore/ksvg2/svg/SVGTransform.h

    r25754 r26077  
    4747 
    4848        SVGTransform();
    49         SVGTransform(SVGTransformType type);
     49        SVGTransform(SVGTransformType);
    5050        explicit SVGTransform(const AffineTransform&);
    5151        virtual ~SVGTransform();
  • branches/feature-branch/WebCore/rendering/RenderPath.cpp

    r25879 r26077  
    121121    IntRect oldBounds;
    122122    IntRect oldOutlineBox;
    123     bool checkForRepaint = checkForRepaintDuringLayout();
    124     if (selfNeedsLayout() && checkForRepaint) {
     123    bool checkForRepaint = checkForRepaintDuringLayout() && selfNeedsLayout();
     124    if (checkForRepaint) {
    125125        oldBounds = m_absoluteBounds;
    126126        oldOutlineBox = absoluteOutlineBox();
     
    134134    setHeight(m_absoluteBounds.height());
    135135
    136     if (selfNeedsLayout() && checkForRepaint)
     136    if (checkForRepaint)
    137137        repaintAfterLayoutIfNeeded(oldBounds, oldOutlineBox);
    138138
     
    438438}
    439439
    440 bool RenderPath::hasRelativeValues() const
    441 {
    442     return static_cast<SVGStyledElement*>(element())->hasRelativeValues();
    443 }
    444 
    445440}
    446441
  • branches/feature-branch/WebCore/rendering/RenderPath.h

    r25839 r26077  
    7676    FloatRect drawMarkersIfNeeded(GraphicsContext*, const FloatRect&, const Path&) const;
    7777    virtual FloatRect strokeBBox() const;
    78 
    79     bool hasRelativeValues() const;
    80  
     78   
    8179private:
    8280    FloatPoint mapAbsolutePointToLocal(const FloatPoint&) const;
  • branches/feature-branch/WebCore/rendering/RenderSVGContainer.cpp

    r26075 r26077  
    234234    IntRect oldBounds;
    235235    IntRect oldOutlineBox;
    236     bool checkForRepaint = checkForRepaintDuringLayout();
     236    bool checkForRepaint = checkForRepaintDuringLayout() && selfWillPaint();
    237237    if (checkForRepaint) {
    238238        oldBounds = m_absoluteBounds;
     
    240240    }
    241241
    242     RenderObject* child = firstChild();
    243     while (child) {
     242    for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
    244243        // Only force our kids to layout if we're being asked to relayout as a result of a parent changing
    245         if (selfNeedsLayout() && (!child->isRenderPath() || static_cast<RenderPath*>(child)->hasRelativeValues()))
     244        // FIXME: We should be able to skip relayout of non-relative kids when only bounds have changed
     245        // however, we can't tell the difference between bounds changing and transform changing.
     246        // http://bugs.webkit.org/show_bug.cgi?id=15391
     247        if (selfNeedsLayout())
    246248            child->setNeedsLayout(true);
    247249
    248250        child->layoutIfNeeded();
    249251        ASSERT(!child->needsLayout());
    250         child = child->nextSibling();
    251252    }
    252253
     
    304305}
    305306
     307bool RenderSVGContainer::selfWillPaint() const
     308{
     309#if ENABLE(SVG_EXPERIMENTAL_FEATURES)
     310    const SVGRenderStyle* svgStyle = style()->svgStyle();
     311    AtomicString filterId(SVGURIReference::getTarget(svgStyle->filter()));
     312    SVGResourceFilter* filter = getFilterById(document(), filterId);
     313    if (filter)
     314        return true;
     315#endif
     316    return false;
     317}
     318
    306319void RenderSVGContainer::paint(PaintInfo& paintInfo, int parentX, int parentY)
    307320{
     
    309322        return;
    310323
    311     if (!firstChild()) {
    312 #if ENABLE(SVG_EXPERIMENTAL_FEATURES)
    313         // Spec: groups w/o children still may render filter content.
    314         const SVGRenderStyle* svgStyle = style()->svgStyle();
    315         AtomicString filterId(SVGURIReference::getTarget(svgStyle->filter()));
    316         SVGResourceFilter* filter = getFilterById(document(), filterId);
    317         if (!filter)
    318 #endif
    319             return;
    320     }
     324     // Spec: groups w/o children still may render filter content.
     325    if (!firstChild() && !selfWillPaint())
     326        return;
    321327   
    322328    paintInfo.context->save();
  • branches/feature-branch/WebCore/rendering/RenderSVGContainer.h

    r25880 r26077  
    103103    int m_width;
    104104    int m_height;
     105   
     106    bool selfWillPaint() const;
    105107
    106108    bool m_drawsContents : 1;
  • branches/feature-branch/WebCore/rendering/RenderSVGHiddenContainer.cpp

    r25866 r26077  
    6161    // Layout our kids to prevent a kid from being marked as needing layout
    6262    // then never being asked to layout.
    63     RenderObject* child = firstChild();
    64     while (child) {
    65         if (!child->isRenderPath() || static_cast<RenderPath*>(child)->hasRelativeValues())
     63    for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
     64        if (selfNeedsLayout())
    6665            child->setNeedsLayout(true);
    6766       
    6867        child->layoutIfNeeded();
    6968        ASSERT(!child->needsLayout());
    70         child = child->nextSibling();
    7169    }
    7270   
  • branches/feature-branch/WebCore/rendering/RenderSVGRoot.cpp

    r26075 r26077  
    7373    IntRect oldBounds = m_absoluteBounds;
    7474    IntRect oldOutlineBox;
    75     bool checkForRepaint = checkForRepaintDuringLayout();
    76     if (selfNeedsLayout() && checkForRepaint)
     75    bool checkForRepaint = checkForRepaintDuringLayout() && selfNeedsLayout();
     76    if (checkForRepaint)
    7777        oldOutlineBox = absoluteOutlineBox();
    7878
     
    8585    m_height = m_height * svg->currentScale();
    8686   
    87     bool boundsChanged = m_absoluteBounds != oldBounds;
    88    
    89     if (boundsChanged || normalChildNeedsLayout() || posChildNeedsLayout()) {
    90         for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
    91             if (boundsChanged && (!child->isRenderPath() || static_cast<RenderPath*>(child)->hasRelativeValues()))
    92                 child->setNeedsLayout(true);
    93            
    94             child->layoutIfNeeded();
    95             ASSERT(!child->needsLayout());
    96         }
    97     }
    98 
    99     if (selfNeedsLayout() && checkForRepaint)
     87    for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
     88        if (selfNeedsLayout()) // either bounds or transform changed, force kids to relayout
     89            child->setNeedsLayout(true);
     90       
     91        child->layoutIfNeeded();
     92        ASSERT(!child->needsLayout());
     93    }
     94
     95    if (checkForRepaint)
    10096        repaintAfterLayoutIfNeeded(oldBounds, oldOutlineBox);
    10197
  • branches/feature-branch/WebCore/rendering/RenderSVGViewportContainer.cpp

    r26075 r26077  
    5656    IntRect oldBounds = m_absoluteBounds;
    5757    IntRect oldOutlineBox;
    58     bool checkForRepaint = checkForRepaintDuringLayout();
    59     if (selfNeedsLayout() && checkForRepaint)
     58    bool checkForRepaint = checkForRepaintDuringLayout() && selfNeedsLayout();
     59    if (checkForRepaint)
    6060        oldOutlineBox = absoluteOutlineBox();
    6161   
     
    6363   
    6464    m_absoluteBounds = absoluteClippedOverflowRect();
    65     bool boundsChanged = m_absoluteBounds != oldBounds;
    66    
    67     if (boundsChanged || normalChildNeedsLayout() || posChildNeedsLayout()) {
    68         for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
    69             if (boundsChanged && (!child->isRenderPath() || static_cast<RenderPath*>(child)->hasRelativeValues()))
    70                 child->setNeedsLayout(true);
    71            
    72             child->layoutIfNeeded();
    73             ASSERT(!child->needsLayout());
    74         }
    75     }
    76    
    77     if (selfNeedsLayout() && checkForRepaint)
     65   
     66    for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
     67        if (selfNeedsLayout())
     68            child->setNeedsLayout(true);
     69       
     70        child->layoutIfNeeded();
     71        ASSERT(!child->needsLayout());
     72    }
     73   
     74    if (checkForRepaint)
    7875        repaintAfterLayoutIfNeeded(oldBounds, oldOutlineBox);
    7976   
     
    123120            return;
    124121
    125         double x = svg->x().value();
    126         double y = svg->y().value();
    127         double w = svg->width().value();
    128         double h = svg->height().value();
     122        float x = svg->x().value();
     123        float y = svg->y().value();
     124        float w = svg->width().value();
     125        float h = svg->height().value();
    129126        m_viewport = FloatRect(x, y, w, h);
    130127    } else if (svgelem->hasTagName(SVGNames::markerTag)) {
     
    133130
    134131        SVGMarkerElement* svg = static_cast<SVGMarkerElement*>(element());
    135         double w = svg->markerWidth().value();
    136         double h = svg->markerHeight().value();
     132        float w = svg->markerWidth().value();
     133        float h = svg->markerHeight().value();
    137134        m_viewport = FloatRect(0, 0, w, h);
    138135    }
Note: See TracChangeset for help on using the changeset viewer.