Changeset 40863 in webkit


Ignore:
Timestamp:
Feb 11, 2009 12:48:19 PM (15 years ago)
Author:
Simon Fraser
Message:

2009-02-11 Simon Fraser <Simon Fraser>

Reviewed by Dave Hyatt

https://bugs.webkit.org/show_bug.cgi?id=23548

When opacity or transform change on an object which has a compositing layer,
avoid repainting the layer.

Added a new StyleDifference value, StyleDifferenceRecompositeLayer, which indicates
that the only thing styleChanged() has to do is to update composited properties of
the layer. RenderStyle::diff() now has an out param for a bitmask of "context sensitive"
properties, currently for opacity and transform. When one of these changes, we need
to see if we have a compositing layer before we decide whether to layout/repaint,
or just update the composited layer, via adjustStyleDifference().

Location:
trunk/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r40862 r40863  
     12009-02-11  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Reviewed by Dave Hyatt
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=23548
     6
     7        When opacity or transform change on an object which has a compositing layer,
     8        avoid repainting the layer.
     9       
     10        Added a new StyleDifference value, StyleDifferenceRecompositeLayer, which indicates
     11        that the only thing styleChanged() has to do is to update composited properties of
     12        the layer. RenderStyle::diff() now has an out param for a bitmask of "context sensitive"
     13        properties, currently for opacity and transform. When one of these changes, we need
     14        to see if we have a compositing layer before we decide whether to layout/repaint,
     15        or just update the composited layer, via adjustStyleDifference().
     16       
     17        * rendering/RenderObject.cpp:
     18        (WebCore::RenderObject::adjustStyleDifference):
     19        (WebCore::RenderObject::setStyle):
     20        (WebCore::RenderObject::styleDidChange):
     21        * rendering/RenderObject.h:
     22        * rendering/style/RenderStyle.cpp:
     23        (WebCore::RenderStyle::diff):
     24        * rendering/style/RenderStyle.h:
     25        * rendering/style/RenderStyleConstants.h:
     26        (WebCore::):
     27
    1282009-02-11  Alexey Proskuryakov  <ap@webkit.org>
    229
  • trunk/WebCore/rendering/RenderObject.cpp

    r40860 r40863  
    4848#include <stdio.h>
    4949#include <wtf/RefCountedLeakCounter.h>
     50
     51#if USE(ACCELERATED_COMPOSITING)
     52#include "RenderLayerCompositor.h"
     53#endif
    5054
    5155#if ENABLE(WML)
     
    19661970}
    19671971
    1968 void RenderObject::setStyle(PassRefPtr<RenderStyle> style)
    1969 {
    1970     if (m_style == style)
    1971         return;
    1972 
    1973     StyleDifference diff = StyleDifferenceEqual;
    1974     if (m_style)
    1975         diff = m_style->diff(style.get());
     1972StyleDifference RenderObject::adjustStyleDifference(StyleDifference diff, unsigned contextSensitiveProperties) const
     1973{
     1974#if USE(ACCELERATED_COMPOSITING)
     1975    // If transform changed, and we are not composited, need to do a layout.
     1976    if (contextSensitiveProperties & ContextSensitivePropertyTransform)
     1977        // Text nodes share style with their parents but transforms don't apply to them,
     1978        // hence the !isText() check.
     1979        // FIXME: when transforms are taken into account for overflow, we will need to do a layout.
     1980        if (!isText() && (!hasLayer() || !toRenderBoxModelObject(this)->layer()->isComposited()))
     1981            diff = StyleDifferenceLayout;
     1982        else if (diff < StyleDifferenceRecompositeLayer)
     1983            diff = StyleDifferenceRecompositeLayer;
     1984
     1985    // If opacity changed, and we are not composited, need to repaint (also
     1986    // ignoring text nodes)
     1987    if (contextSensitiveProperties & ContextSensitivePropertyOpacity)
     1988        if (!isText() && (!hasLayer() || !toRenderBoxModelObject(this)->layer()->isComposited()))
     1989            diff = StyleDifferenceRepaintLayer;
     1990        else if (diff < StyleDifferenceRecompositeLayer)
     1991            diff = StyleDifferenceRecompositeLayer;
     1992#else
     1993    UNUSED_PARAM(contextSensitiveProperties);
     1994#endif
    19761995
    19771996    // If we have no layer(), just treat a RepaintLayer hint as a normal Repaint.
    19781997    if (diff == StyleDifferenceRepaintLayer && !hasLayer())
    19791998        diff = StyleDifferenceRepaint;
     1999
     2000    return diff;
     2001}
     2002
     2003void RenderObject::setStyle(PassRefPtr<RenderStyle> style)
     2004{
     2005    if (m_style == style)
     2006        return;
     2007
     2008    StyleDifference diff = StyleDifferenceEqual;
     2009    unsigned contextSensitiveProperties = ContextSensitivePropertyNone;
     2010    if (m_style)
     2011        diff = m_style->diff(style.get(), contextSensitiveProperties);
     2012
     2013    diff = adjustStyleDifference(diff, contextSensitiveProperties);
    19802014
    19812015    styleWillChange(diff, style.get());
     
    19962030
    19972031    styleDidChange(diff, oldStyle.get());
     2032
     2033    if (!m_parent || isText())
     2034        return;
     2035
     2036    // Now that the layer (if any) has been updated, we need to adjust the diff again,
     2037    // check whether we should layout now, and decide if we need to repaint.
     2038    StyleDifference updatedDiff = adjustStyleDifference(diff, contextSensitiveProperties);
     2039   
     2040    if (diff <= StyleDifferenceLayoutPositionedMovementOnly) {
     2041        if (updatedDiff == StyleDifferenceLayout)
     2042            setNeedsLayoutAndPrefWidthsRecalc();
     2043        else if (updatedDiff == StyleDifferenceLayoutPositionedMovementOnly)
     2044            setNeedsPositionedMovementLayout();
     2045    }
     2046   
     2047    if (updatedDiff == StyleDifferenceRepaintLayer || updatedDiff == StyleDifferenceRepaint) {
     2048        // Do a repaint with the new style now, e.g., for example if we go from
     2049        // not having an outline to having an outline.
     2050        repaint();
     2051    }
    19982052}
    19992053
     
    20842138    else if (diff == StyleDifferenceLayoutPositionedMovementOnly)
    20852139        setNeedsPositionedMovementLayout();
    2086     else if (diff == StyleDifferenceRepaintLayer || diff == StyleDifferenceRepaint)
    2087         // Do a repaint with the new style now, e.g., for example if we go from
    2088         // not having an outline to having an outline.
    2089         repaint();
     2140
     2141    // Don't check for repaint here; we need to wait until the layer has been
     2142    // updated by subclasses before we know if we have to repaint (in setStyle()).
    20902143}
    20912144
  • trunk/WebCore/rendering/RenderObject.h

    r40860 r40863  
    792792private:
    793793    RenderStyle* firstLineStyleSlowCase() const;
    794 
     794    StyleDifference adjustStyleDifference(StyleDifference, unsigned contextSensitiveProperties) const;
     795   
    795796    RefPtr<RenderStyle> m_style;
    796797
  • trunk/WebCore/rendering/style/RenderStyle.cpp

    r40734 r40863  
    272272  worst case result causing a relayout of the containing block.
    273273*/
    274 StyleDifference RenderStyle::diff(const RenderStyle* other) const
    275 {
     274StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedContextSensitiveProperties) const
     275{
     276    changedContextSensitiveProperties = ContextSensitivePropertyNone;
     277
    276278#if ENABLE(SVG)
    277279    // This is horribly inefficient.  Eventually we'll have to integrate
     
    325327
    326328        if (rareNonInheritedData->m_transform.get() != other->rareNonInheritedData->m_transform.get() &&
    327             *rareNonInheritedData->m_transform.get() != *other->rareNonInheritedData->m_transform.get())
    328             return StyleDifferenceLayout;
     329            *rareNonInheritedData->m_transform.get() != *other->rareNonInheritedData->m_transform.get()) {
     330#if USE(ACCELERATED_COMPOSITING)
     331            changedContextSensitiveProperties |= ContextSensitivePropertyTransform;
     332            // Don't return; keep looking for another change
     333#else
     334            return StyleDifferenceLayout;
     335#endif
     336        }
    329337
    330338#if ENABLE(DASHBOARD_SUPPORT)
     
    446454    }
    447455
    448     if (rareNonInheritedData->opacity != other->rareNonInheritedData->opacity ||
    449         rareNonInheritedData->m_mask != other->rareNonInheritedData->m_mask ||
     456    if (rareNonInheritedData->opacity != other->rareNonInheritedData->opacity) {
     457#if USE(ACCELERATED_COMPOSITING)
     458        changedContextSensitiveProperties |= ContextSensitivePropertyOpacity;
     459        // Don't return; keep looking for another change.
     460#else
     461        return StyleDifferenceRepaintLayer;
     462#endif
     463    }
     464
     465    if (rareNonInheritedData->m_mask != other->rareNonInheritedData->m_mask ||
    450466        rareNonInheritedData->m_maskBoxImage != other->rareNonInheritedData->m_maskBoxImage)
    451467        return StyleDifferenceRepaintLayer;
  • trunk/WebCore/rendering/style/RenderStyle.h

    r40734 r40863  
    983983    bool inheritedNotEqual(RenderStyle*) const;
    984984
    985     StyleDifference diff(const RenderStyle*) const;
     985    StyleDifference diff(const RenderStyle*, unsigned& changedContextSensitiveProperties) const;
    986986
    987987    bool isDisplayReplacedType() const
  • trunk/WebCore/rendering/style/RenderStyleConstants.h

    r40667 r40863  
    3939// The difference between two styles.  The following values are used:
    4040// (1) StyleDifferenceEqual - The two styles are identical
    41 // (2) StyleDifferenceRepaint - The object just needs to be repainted.
    42 // (3) StyleDifferenceRepaintLayer - The layer and its descendant layers needs to be repainted.
    43 // (4) StyleDifferenceLayout - A layout is required.
     41// (2) StyleDifferenceRecompositeLayer - The layer needs its position and transform updated, but no repaint
     42// (3) StyleDifferenceRepaint - The object just needs to be repainted.
     43// (4) StyleDifferenceRepaintLayer - The layer and its descendant layers needs to be repainted.
     44// (5) StyleDifferenceLayout - A layout is required.
    4445enum StyleDifference {
    4546    StyleDifferenceEqual,
     47#if USE(ACCELERATED_COMPOSITING)
     48    StyleDifferenceRecompositeLayer,
     49#endif
    4650    StyleDifferenceRepaint,
    4751    StyleDifferenceRepaintLayer,
    4852    StyleDifferenceLayoutPositionedMovementOnly,
    4953    StyleDifferenceLayout
     54};
     55
     56// When some style properties change, different amounts of work have to be done depending on
     57// context (e.g. whether the property is changing on an element which has a compositing layer).
     58// A simple StyleDifference does not provide enough information so we return a bit mask of
     59// StyleDifferenceContextSensitiveProperties from RenderStyle::diff() too.
     60enum StyleDifferenceContextSensitiveProperty {
     61    ContextSensitivePropertyNone = 0,
     62    ContextSensitivePropertyTransform = (1 << 0),
     63    ContextSensitivePropertyOpacity = (1 << 1)
    5064};
    5165
Note: See TracChangeset for help on using the changeset viewer.