Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(753)

Side by Side Diff: Source/core/rendering/RenderObject.cpp

Issue 236203020: Separate repaint and layout requirements of StyleDifference (Step 1) (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebase, Fix break Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2000 Dirk Mueller (mueller@kde.org) 4 * (C) 2000 Dirk Mueller (mueller@kde.org)
5 * (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com) 5 * (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com)
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2011 Apple Inc. All rights reserv ed. 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2011 Apple Inc. All rights reserv ed.
7 * Copyright (C) 2009 Google Inc. All rights reserved. 7 * Copyright (C) 2009 Google Inc. All rights reserved.
8 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo bile.com/) 8 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo bile.com/)
9 * 9 *
10 * This library is free software; you can redistribute it and/or 10 * This library is free software; you can redistribute it and/or
(...skipping 1848 matching lines...) Expand 10 before | Expand all | Expand 10 after
1859 // not to layout for 3d transforms, but we should be invoking a simplified r elayout. Is it possible we are avoiding 1859 // not to layout for 3d transforms, but we should be invoking a simplified r elayout. Is it possible we are avoiding
1860 // doing this for some performance reason at this time? 1860 // doing this for some performance reason at this time?
1861 if (contextSensitiveProperties & ContextSensitivePropertyTransform) { 1861 if (contextSensitiveProperties & ContextSensitivePropertyTransform) {
1862 // Text nodes share style with their parents but transforms don't apply to them, 1862 // Text nodes share style with their parents but transforms don't apply to them,
1863 // hence the !isText() check. 1863 // hence the !isText() check.
1864 // FIXME: when transforms are taken into account for overflow, we will n eed to do a layout. 1864 // FIXME: when transforms are taken into account for overflow, we will n eed to do a layout.
1865 if (!isText() && (!hasLayer() || !toRenderLayerModelObject(this)->layer( )->hasDirectReasonsForCompositing())) { 1865 if (!isText() && (!hasLayer() || !toRenderLayerModelObject(this)->layer( )->hasDirectReasonsForCompositing())) {
1866 // We need to set at least SimplifiedLayout, but if PositionedMoveme ntOnly is already set 1866 // We need to set at least SimplifiedLayout, but if PositionedMoveme ntOnly is already set
1867 // then we actually need SimplifiedLayoutAndPositionedMovement. 1867 // then we actually need SimplifiedLayoutAndPositionedMovement.
1868 if (!hasLayer()) 1868 if (!hasLayer())
1869 diff = StyleDifferenceLayout; // FIXME: Do this for now since Si mplifiedLayout cannot handle updating floating objects lists. 1869 diff.setNeedsFullLayout(); // FIXME: Do this for now since Simpl ifiedLayout cannot handle updating floating objects lists.
1870 else if (diff < StyleDifferenceLayoutPositionedMovementOnly) 1870 else
1871 diff = StyleDifferenceSimplifiedLayout; 1871 diff.setNeedsSimplifiedLayout();
1872 else if (diff < StyleDifferenceSimplifiedLayout) 1872 } else {
1873 diff = StyleDifferenceSimplifiedLayoutAndPositionedMovement; 1873 diff.setNeedsRecompositeLayer();
1874 } else if (diff < StyleDifferenceRecompositeLayer) 1874 }
1875 diff = StyleDifferenceRecompositeLayer;
1876 } 1875 }
1877 1876
1878 // If opacity or filters changed, and the layer does not paint into its own separate backing, then we need to repaint (also 1877 // If opacity or filters changed, and the layer does not paint into its own separate backing, then we need to repaint (also
1879 // ignoring text nodes) 1878 // ignoring text nodes)
1880 if (contextSensitiveProperties & ContextSensitivePropertyOpacity && diff <= StyleDifferenceRepaintLayer) { 1879 if (contextSensitiveProperties & ContextSensitivePropertyOpacity && !diff.ne edsLayout()) {
1881 if (!isText() && (!hasLayer() || !toRenderLayerModelObject(this)->layer( )->hasDirectReasonsForCompositing())) 1880 if (!isText() && (!hasLayer() || !toRenderLayerModelObject(this)->layer( )->hasDirectReasonsForCompositing()))
1882 diff = StyleDifferenceRepaintLayer; 1881 diff.setNeedsRepaintLayer();
1883 else if (diff < StyleDifferenceRecompositeLayer) 1882 else
1884 diff = StyleDifferenceRecompositeLayer; 1883 diff.setNeedsRecompositeLayer();
1885 } 1884 }
1886 1885
1887 if ((contextSensitiveProperties & ContextSensitivePropertyFilter) && hasLaye r() && diff <= StyleDifferenceRepaintLayer) { 1886 if ((contextSensitiveProperties & ContextSensitivePropertyFilter) && hasLaye r() && !diff.needsLayout()) {
1888 RenderLayer* layer = toRenderLayerModelObject(this)->layer(); 1887 RenderLayer* layer = toRenderLayerModelObject(this)->layer();
1889 if (!layer->hasDirectReasonsForCompositing() || layer->paintsWithFilters ()) 1888 if (!layer->hasDirectReasonsForCompositing() || layer->paintsWithFilters ())
1890 diff = StyleDifferenceRepaintLayer; 1889 diff.setNeedsRepaintLayer();
1891 else if (diff < StyleDifferenceRecompositeLayer) 1890 else
1892 diff = StyleDifferenceRecompositeLayer; 1891 diff.setNeedsRecompositeLayer();
1893 } 1892 }
1894 1893
1895 if ((contextSensitiveProperties & ContextSensitivePropertyTextOrColor) && di ff < StyleDifferenceRepaint 1894 if ((contextSensitiveProperties & ContextSensitivePropertyTextOrColor) && !d iff.needsRepaint() && !diff.needsLayout()
1896 && hasImmediateNonWhitespaceTextChildOrPropertiesDependentOnColor()) 1895 && hasImmediateNonWhitespaceTextChildOrPropertiesDependentOnColor())
1897 diff = StyleDifferenceRepaint; 1896 diff.setNeedsRepaintObject();
1898 1897
1899 // The answer to layerTypeRequired() for plugins, iframes, and canvas can ch ange without the actual 1898 // The answer to layerTypeRequired() for plugins, iframes, and canvas can ch ange without the actual
1900 // style changing, since it depends on whether we decide to composite these elements. When the 1899 // style changing, since it depends on whether we decide to composite these elements. When the
1901 // layer status of one of these elements changes, we need to force a layout. 1900 // layer status of one of these elements changes, we need to force a layout.
1902 if (diff == StyleDifferenceEqual && style() && isLayerModelObject()) { 1901 if (diff.hasNoChange() && style() && isLayerModelObject()) {
1903 bool requiresLayer = toRenderLayerModelObject(this)->layerTypeRequired() != NoLayer; 1902 bool requiresLayer = toRenderLayerModelObject(this)->layerTypeRequired() != NoLayer;
1904 if (hasLayer() != requiresLayer) 1903 if (hasLayer() != requiresLayer)
1905 diff = StyleDifferenceLayout; 1904 diff.setNeedsFullLayout();
1906 } 1905 }
1907 1906
1908 // If we have no layer(), just treat a RepaintLayer hint as a normal Repaint . 1907 // If we have no layer(), just treat a RepaintLayer hint as a normal Repaint .
1909 if (diff == StyleDifferenceRepaintLayer && !hasLayer()) 1908 if (diff.needsRepaintLayer() && !hasLayer()) {
1910 diff = StyleDifferenceRepaint; 1909 diff.clearNeedsRepaint();
1910 diff.setNeedsRepaintObject();
1911 }
1911 1912
1912 return diff; 1913 return diff;
1913 } 1914 }
1914 1915
1915 void RenderObject::setPseudoStyle(PassRefPtr<RenderStyle> pseudoStyle) 1916 void RenderObject::setPseudoStyle(PassRefPtr<RenderStyle> pseudoStyle)
1916 { 1917 {
1917 ASSERT(pseudoStyle->styleType() == BEFORE || pseudoStyle->styleType() == AFT ER); 1918 ASSERT(pseudoStyle->styleType() == BEFORE || pseudoStyle->styleType() == AFT ER);
1918 1919
1919 // FIXME: We should consider just making all pseudo items use an inherited s tyle. 1920 // FIXME: We should consider just making all pseudo items use an inherited s tyle.
1920 1921
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1952 { 1953 {
1953 ASSERT(style); 1954 ASSERT(style);
1954 1955
1955 if (m_style == style) { 1956 if (m_style == style) {
1956 // We need to run through adjustStyleDifference() for iframes, plugins, and canvas so 1957 // We need to run through adjustStyleDifference() for iframes, plugins, and canvas so
1957 // style sharing is disabled for them. That should ensure that we never hit this code path. 1958 // style sharing is disabled for them. That should ensure that we never hit this code path.
1958 ASSERT(!isRenderIFrame() && !isEmbeddedObject() && !isCanvas()); 1959 ASSERT(!isRenderIFrame() && !isEmbeddedObject() && !isCanvas());
1959 return; 1960 return;
1960 } 1961 }
1961 1962
1962 StyleDifference diff = StyleDifferenceEqual; 1963 StyleDifference diff;
1963 unsigned contextSensitiveProperties = ContextSensitivePropertyNone; 1964 unsigned contextSensitiveProperties = ContextSensitivePropertyNone;
1964 if (m_style) 1965 if (m_style)
1965 diff = m_style->visualInvalidationDiff(*style, contextSensitivePropertie s); 1966 diff = m_style->visualInvalidationDiff(*style, contextSensitivePropertie s);
1966 1967
1967 diff = adjustStyleDifference(diff, contextSensitiveProperties); 1968 diff = adjustStyleDifference(diff, contextSensitiveProperties);
1968 1969
1969 styleWillChange(diff, *style); 1970 styleWillChange(diff, *style);
1970 1971
1971 RefPtr<RenderStyle> oldStyle = m_style.release(); 1972 RefPtr<RenderStyle> oldStyle = m_style.release();
1972 setStyleInternal(style); 1973 setStyleInternal(style);
(...skipping 14 matching lines...) Expand all
1987 // its first-letter block gets an update in RenderTextFragment::styleDidChan ge. For RenderTextFragment(s), 1988 // its first-letter block gets an update in RenderTextFragment::styleDidChan ge. For RenderTextFragment(s),
1988 // we will safely bail out with the doesNotNeedLayout flag. We might want to broaden this condition 1989 // we will safely bail out with the doesNotNeedLayout flag. We might want to broaden this condition
1989 // in the future as we move renderer changes out of layout and into style ch anges. 1990 // in the future as we move renderer changes out of layout and into style ch anges.
1990 if (doesNotNeedLayout) 1991 if (doesNotNeedLayout)
1991 return; 1992 return;
1992 1993
1993 // Now that the layer (if any) has been updated, we need to adjust the diff again, 1994 // Now that the layer (if any) has been updated, we need to adjust the diff again,
1994 // check whether we should layout now, and decide if we need to repaint. 1995 // check whether we should layout now, and decide if we need to repaint.
1995 StyleDifference updatedDiff = adjustStyleDifference(diff, contextSensitivePr operties); 1996 StyleDifference updatedDiff = adjustStyleDifference(diff, contextSensitivePr operties);
1996 1997
1997 if (diff <= StyleDifferenceLayoutPositionedMovementOnly) { 1998 if (!diff.needsFullLayout()) {
1998 if (updatedDiff == StyleDifferenceLayout) 1999 if (updatedDiff.needsFullLayout()) {
1999 setNeedsLayoutAndPrefWidthsRecalc(); 2000 setNeedsLayoutAndPrefWidthsRecalc();
2000 else if (updatedDiff == StyleDifferenceLayoutPositionedMovementOnly) 2001 } else {
2001 setNeedsPositionedMovementLayout(); 2002 if (updatedDiff.needsPositionedMovementLayout())
2002 else if (updatedDiff == StyleDifferenceSimplifiedLayoutAndPositionedMove ment) { 2003 setNeedsPositionedMovementLayout();
2003 setNeedsPositionedMovementLayout(); 2004 if (updatedDiff.needsSimplifiedLayout())
2004 setNeedsSimplifiedNormalFlowLayout(); 2005 setNeedsSimplifiedNormalFlowLayout();
2005 } else if (updatedDiff == StyleDifferenceSimplifiedLayout) 2006 }
2006 setNeedsSimplifiedNormalFlowLayout();
2007 } 2007 }
2008 2008
2009 if (updatedDiff == StyleDifferenceRepaint || updatedDiff == StyleDifferenceR epaintLayer) { 2009 if (updatedDiff.needsRepaint()) {
2010 // Do a repaint with the new style now, e.g., for example if we go from 2010 // Do a repaint with the new style now, e.g., for example if we go from
2011 // not having an outline to having an outline. 2011 // not having an outline to having an outline.
2012 repaint(); 2012 repaint();
2013 } 2013 }
2014 } 2014 }
2015 2015
2016 static inline bool rendererHasBackground(const RenderObject* renderer) 2016 static inline bool rendererHasBackground(const RenderObject* renderer)
2017 { 2017 {
2018 return renderer && renderer->hasBackground(); 2018 return renderer && renderer->hasBackground();
2019 } 2019 }
(...skipping 13 matching lines...) Expand all
2033 } 2033 }
2034 2034
2035 // Keep layer hierarchy visibility bits up to date if visibility changes . 2035 // Keep layer hierarchy visibility bits up to date if visibility changes .
2036 if (m_style->visibility() != newStyle.visibility()) { 2036 if (m_style->visibility() != newStyle.visibility()) {
2037 // We might not have an enclosing layer yet because we might not be in the tree. 2037 // We might not have an enclosing layer yet because we might not be in the tree.
2038 if (RenderLayer* layer = enclosingLayer()) { 2038 if (RenderLayer* layer = enclosingLayer()) {
2039 if (newStyle.visibility() == VISIBLE) { 2039 if (newStyle.visibility() == VISIBLE) {
2040 layer->setHasVisibleContent(); 2040 layer->setHasVisibleContent();
2041 } else if (layer->hasVisibleContent() && (this == layer->rendere r() || layer->renderer()->style()->visibility() != VISIBLE)) { 2041 } else if (layer->hasVisibleContent() && (this == layer->rendere r() || layer->renderer()->style()->visibility() != VISIBLE)) {
2042 layer->dirtyVisibleContentStatus(); 2042 layer->dirtyVisibleContentStatus();
2043 if (diff > StyleDifferenceRepaintLayer) 2043 if (diff.needsLayout())
2044 repaint(); 2044 repaint();
2045 } 2045 }
2046 } 2046 }
2047 } 2047 }
2048 2048
2049 if (m_parent && diff == StyleDifferenceRepaint) 2049 if (m_parent && diff.needsRepaintObjectOnly())
2050 repaint(); 2050 repaint();
2051 if (isFloating() && (m_style->floating() != newStyle.floating())) 2051 if (isFloating() && (m_style->floating() != newStyle.floating()))
2052 // For changes in float styles, we need to conceivably remove oursel ves 2052 // For changes in float styles, we need to conceivably remove oursel ves
2053 // from the floating objects list. 2053 // from the floating objects list.
2054 toRenderBox(this)->removeFloatingOrPositionedChildFromBlockLists(); 2054 toRenderBox(this)->removeFloatingOrPositionedChildFromBlockLists();
2055 else if (isOutOfFlowPositioned() && (m_style->position() != newStyle.pos ition())) 2055 else if (isOutOfFlowPositioned() && (m_style->position() != newStyle.pos ition()))
2056 // For changes in positioning styles, we need to conceivably remove ourselves 2056 // For changes in positioning styles, we need to conceivably remove ourselves
2057 // from the positioned objects list. 2057 // from the positioned objects list.
2058 toRenderBox(this)->removeFloatingOrPositionedChildFromBlockLists(); 2058 toRenderBox(this)->removeFloatingOrPositionedChildFromBlockLists();
2059 2059
2060 s_affectsParentBlock = isFloatingOrOutOfFlowPositioned() 2060 s_affectsParentBlock = isFloatingOrOutOfFlowPositioned()
2061 && (!newStyle.isFloating() && !newStyle.hasOutOfFlowPosition()) 2061 && (!newStyle.isFloating() && !newStyle.hasOutOfFlowPosition())
2062 && parent() && (parent()->isRenderBlockFlow() || parent()->isRenderI nline()); 2062 && parent() && (parent()->isRenderBlockFlow() || parent()->isRenderI nline());
2063 2063
2064 // Clearing these bits is required to avoid leaving stale renderers. 2064 // Clearing these bits is required to avoid leaving stale renderers.
2065 // FIXME: We shouldn't need that hack if our logic was totally correct. 2065 // FIXME: We shouldn't need that hack if our logic was totally correct.
2066 if (diff == StyleDifferenceLayout || diff == StyleDifferenceLayoutPositi onedMovementOnly) { 2066 if (diff.needsFullLayout() || diff.needsPositionedMovementLayout()) {
2067 setFloating(false); 2067 setFloating(false);
2068 clearPositionedState(); 2068 clearPositionedState();
2069 } 2069 }
2070 } else 2070 } else {
2071 s_affectsParentBlock = false; 2071 s_affectsParentBlock = false;
2072 }
2072 2073
2073 if (view()->frameView()) { 2074 if (view()->frameView()) {
2074 bool shouldBlitOnFixedBackgroundImage = false; 2075 bool shouldBlitOnFixedBackgroundImage = false;
2075 #if ENABLE(FAST_MOBILE_SCROLLING) 2076 #if ENABLE(FAST_MOBILE_SCROLLING)
2076 // On low-powered/mobile devices, preventing blitting on a scroll can ca use noticeable delays 2077 // On low-powered/mobile devices, preventing blitting on a scroll can ca use noticeable delays
2077 // when scrolling a page with a fixed background image. As an optimizati on, assuming there are 2078 // when scrolling a page with a fixed background image. As an optimizati on, assuming there are
2078 // no fixed positoned elements on the page, we can acclerate scrolling ( via blitting) if we 2079 // no fixed positoned elements on the page, we can acclerate scrolling ( via blitting) if we
2079 // ignore the CSS property "background-attachment: fixed". 2080 // ignore the CSS property "background-attachment: fixed".
2080 shouldBlitOnFixedBackgroundImage = true; 2081 shouldBlitOnFixedBackgroundImage = true;
2081 #endif 2082 #endif
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2129 } 2130 }
2130 2131
2131 void RenderObject::styleDidChange(StyleDifference diff, const RenderStyle* oldSt yle) 2132 void RenderObject::styleDidChange(StyleDifference diff, const RenderStyle* oldSt yle)
2132 { 2133 {
2133 if (s_affectsParentBlock) 2134 if (s_affectsParentBlock)
2134 handleDynamicFloatPositionChange(); 2135 handleDynamicFloatPositionChange();
2135 2136
2136 if (!m_parent) 2137 if (!m_parent)
2137 return; 2138 return;
2138 2139
2139 if (diff == StyleDifferenceLayout || diff == StyleDifferenceSimplifiedLayout ) { 2140 if (diff.needsFullLayout() || diff.needsSimplifiedLayout()) {
2140 RenderCounter::rendererStyleChanged(*this, oldStyle, m_style.get()); 2141 RenderCounter::rendererStyleChanged(*this, oldStyle, m_style.get());
2141 2142
2142 // If the object already needs layout, then setNeedsLayout won't do 2143 // If the object already needs layout, then setNeedsLayout won't do
2143 // any work. But if the containing block has changed, then we may need 2144 // any work. But if the containing block has changed, then we may need
2144 // to mark the new containing blocks for layout. The change that can 2145 // to mark the new containing blocks for layout. The change that can
2145 // directly affect the containing block of this object is a change to 2146 // directly affect the containing block of this object is a change to
2146 // the position style. 2147 // the position style.
2147 if (needsLayout() && oldStyle->position() != m_style->position()) 2148 if (needsLayout() && oldStyle->position() != m_style->position())
2148 markContainingBlocksForLayout(); 2149 markContainingBlocksForLayout();
2149 2150
2150 if (diff == StyleDifferenceLayout) 2151 if (diff.needsFullLayout())
2151 setNeedsLayoutAndPrefWidthsRecalc(); 2152 setNeedsLayoutAndPrefWidthsRecalc();
2152 else 2153 else
2153 setNeedsSimplifiedNormalFlowLayout(); 2154 setNeedsSimplifiedNormalFlowLayout();
2154 } else if (diff == StyleDifferenceSimplifiedLayoutAndPositionedMovement) { 2155 }
2155 setNeedsPositionedMovementLayout(); 2156 if (diff.needsPositionedMovementLayout())
2156 setNeedsSimplifiedNormalFlowLayout();
2157 } else if (diff == StyleDifferenceLayoutPositionedMovementOnly)
2158 setNeedsPositionedMovementLayout(); 2157 setNeedsPositionedMovementLayout();
2159 2158
2160 // Don't check for repaint here; we need to wait until the layer has been 2159 // Don't check for repaint here; we need to wait until the layer has been
2161 // updated by subclasses before we know if we have to repaint (in setStyle() ). 2160 // updated by subclasses before we know if we have to repaint (in setStyle() ).
2162 2161
2163 if (oldStyle && !areCursorsEqual(oldStyle, style())) { 2162 if (oldStyle && !areCursorsEqual(oldStyle, style())) {
2164 if (LocalFrame* frame = this->frame()) 2163 if (LocalFrame* frame = this->frame())
2165 frame->eventHandler().scheduleCursorUpdate(); 2164 frame->eventHandler().scheduleCursorUpdate();
2166 } 2165 }
2167 } 2166 }
(...skipping 1222 matching lines...) Expand 10 before | Expand all | Expand 10 after
3390 { 3389 {
3391 if (object1) { 3390 if (object1) {
3392 const WebCore::RenderObject* root = object1; 3391 const WebCore::RenderObject* root = object1;
3393 while (root->parent()) 3392 while (root->parent())
3394 root = root->parent(); 3393 root = root->parent();
3395 root->showRenderTreeAndMark(object1, "*", object2, "-", 0); 3394 root->showRenderTreeAndMark(object1, "*", object2, "-", 0);
3396 } 3395 }
3397 } 3396 }
3398 3397
3399 #endif 3398 #endif
OLDNEW
« no previous file with comments | « Source/core/rendering/RenderLayerModelObject.cpp ('k') | Source/core/rendering/RenderScrollbarPart.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698