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

Unified Diff: Source/core/rendering/style/RenderStyle.cpp

Issue 236203020: Separate repaint and layout requirements of StyleDifference (Step 1) (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Update layout test expectations 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 side-by-side diff with in-line comments
Download patch
Index: Source/core/rendering/style/RenderStyle.cpp
diff --git a/Source/core/rendering/style/RenderStyle.cpp b/Source/core/rendering/style/RenderStyle.cpp
index 8accb94d73609b0186a0da53fcf963a1286545f0..0d0e226896a254b53e12a639b798e7f003349b87 100644
--- a/Source/core/rendering/style/RenderStyle.cpp
+++ b/Source/core/rendering/style/RenderStyle.cpp
@@ -366,21 +366,73 @@ static bool positionedObjectMovedOnly(const LengthBox& a, const LengthBox& b, co
return true;
}
-StyleDifference RenderStyle::visualInvalidationDiff(const RenderStyle& other, unsigned& changedContextSensitiveProperties) const
+StyleDifference RenderStyle::visualInvalidationDiff(const RenderStyle& other) const
{
- changedContextSensitiveProperties = ContextSensitivePropertyNone;
-
// Note, we use .get() on each DataRef below because DataRef::operator== will do a deep
// compare, which is duplicate work when we're going to compare each property inside
// this function anyway.
- StyleDifference svgChange = StyleDifferenceEqual;
- if (m_svgStyle.get() != other.m_svgStyle.get()) {
- svgChange = m_svgStyle->diff(other.m_svgStyle.get());
- if (svgChange == StyleDifferenceLayout)
- return svgChange;
+ StyleDifference diff;
+ if (m_svgStyle.get() != other.m_svgStyle.get())
+ diff = m_svgStyle->diff(other.m_svgStyle.get());
+
+ if ((!diff.needsRepaintLayer() || !diff.needsFullLayout()) && diffNeedsLayoutAndRepaintLayer(other)) {
+ diff.setNeedsFullLayout();
+ diff.setNeedsRepaintLayer();
+ }
+
+ if ((!diff.needsRepaint() || !diff.needsFullLayout()) && diffNeedsLayoutAndRepaintSelf(other)) {
+ diff.setNeedsFullLayout();
+ diff.setNeedsRepaintSelf();
+ }
+
+ if (!diff.needsFullLayout() && diffNeedsLayoutOnly(other))
+ diff.setNeedsFullLayout();
+
+ if (!diff.needsFullLayout() && position() != StaticPosition && surround->offset != other.surround->offset) {
+ // Optimize for the case where a positioned layer is moving but not changing size.
+ if ((position() == AbsolutePosition || position() == FixedPosition)
+ && positionedObjectMovedOnly(surround->offset, other.surround->offset, m_box->width())) {
+ diff.setNeedsPositionedMovementLayout();
+ } else {
+ // FIXME: We would like to use SimplifiedLayout for relative positioning, but we can't quite do that yet.
+ // We need to make sure SimplifiedLayout can operate correctly on RenderInlines (we will need
+ // to add a selfNeedsSimplifiedLayout bit in order to not get confused and taint every line).
+ diff.setNeedsFullLayout();
+ diff.setNeedsRepaintSelf();
+ }
}
+ if (!diff.needsRepaintLayer() && diffNeedsRepaintLayerOnly(other))
+ diff.setNeedsRepaintLayer();
+
+ if (!diff.needsRepaint() && diffNeedsRepaintOnly(other))
+ diff.setNeedsRepaintSelf();
+
+ addContextSensitiveDiffFlags(other, diff);
+
+ if (diff.noChange() && diffNeedsRecompositeLayerOnly(other))
+ diff.setNeedsRecompositeLayer();
+
+ // Cursors are not checked, since they will be set appropriately in response to mouse events,
+ // so they don't need to cause any repaint or layout.
+
+ // Animations don't need to be checked either. We always set the new style on the RenderObject, so we will get a chance to fire off
+ // the resulting transition properly.
+
+ return diff;
+}
+
+bool RenderStyle::diffNeedsLayoutAndRepaintLayer(const RenderStyle& other) const
+{
+ if (position() != other.position())
+ return true;
+
+ return false;
+}
+
+bool RenderStyle::diffNeedsLayoutAndRepaintSelf(const RenderStyle& other) const
+{
if (m_box.get() != other.m_box.get()) {
if (m_box->width() != other.m_box->width()
|| m_box->minWidth() != other.m_box->minWidth()
@@ -388,28 +440,28 @@ StyleDifference RenderStyle::visualInvalidationDiff(const RenderStyle& other, un
|| m_box->height() != other.m_box->height()
|| m_box->minHeight() != other.m_box->minHeight()
|| m_box->maxHeight() != other.m_box->maxHeight())
- return StyleDifferenceLayout;
+ return true;
if (m_box->verticalAlign() != other.m_box->verticalAlign())
- return StyleDifferenceLayout;
+ return true;
if (m_box->boxSizing() != other.m_box->boxSizing())
- return StyleDifferenceLayout;
+ return true;
}
if (surround.get() != other.surround.get()) {
if (surround->margin != other.surround->margin)
- return StyleDifferenceLayout;
+ return true;
if (surround->padding != other.surround->padding)
- return StyleDifferenceLayout;
+ return true;
// If our border widths change, then we need to layout. Other changes to borders only necessitate a repaint.
if (borderLeftWidth() != other.borderLeftWidth()
|| borderTopWidth() != other.borderTopWidth()
|| borderBottomWidth() != other.borderBottomWidth()
|| borderRightWidth() != other.borderRightWidth())
- return StyleDifferenceLayout;
+ return true;
}
if (rareNonInheritedData.get() != other.rareNonInheritedData.get()) {
@@ -430,38 +482,32 @@ StyleDifference RenderStyle::visualInvalidationDiff(const RenderStyle& other, un
|| rareNonInheritedData->m_gridItem.get() != other.rareNonInheritedData->m_gridItem.get()
|| rareNonInheritedData->m_textCombine != other.rareNonInheritedData->m_textCombine
|| rareNonInheritedData->hasFilters() != other.rareNonInheritedData->hasFilters())
- return StyleDifferenceLayout;
+ return true;
if (rareNonInheritedData->m_deprecatedFlexibleBox.get() != other.rareNonInheritedData->m_deprecatedFlexibleBox.get()
&& *rareNonInheritedData->m_deprecatedFlexibleBox.get() != *other.rareNonInheritedData->m_deprecatedFlexibleBox.get())
- return StyleDifferenceLayout;
+ return true;
if (rareNonInheritedData->m_flexibleBox.get() != other.rareNonInheritedData->m_flexibleBox.get()
&& *rareNonInheritedData->m_flexibleBox.get() != *other.rareNonInheritedData->m_flexibleBox.get())
- return StyleDifferenceLayout;
+ return true;
// FIXME: We should add an optimized form of layout that just recomputes visual overflow.
if (!rareNonInheritedData->shadowDataEquivalent(*other.rareNonInheritedData.get()))
- return StyleDifferenceLayout;
+ return true;
if (!rareNonInheritedData->reflectionDataEquivalent(*other.rareNonInheritedData.get()))
- return StyleDifferenceLayout;
+ return true;
if (rareNonInheritedData->m_multiCol.get() != other.rareNonInheritedData->m_multiCol.get()
&& *rareNonInheritedData->m_multiCol.get() != *other.rareNonInheritedData->m_multiCol.get())
- return StyleDifferenceLayout;
-
- if (!transformDataEquivalent(other)) {
- // Don't return early here; instead take note of the type of
- // change, and deal with it when looking at compositing.
- changedContextSensitiveProperties |= ContextSensitivePropertyTransform;
- }
+ return true;
// If the counter directives change, trigger a relayout to re-calculate counter values and rebuild the counter node tree.
const CounterDirectiveMap* mapA = rareNonInheritedData->m_counterDirectives.get();
const CounterDirectiveMap* mapB = other.rareNonInheritedData->m_counterDirectives.get();
if (!(mapA == mapB || (mapA && mapB && *mapA == *mapB)))
- return StyleDifferenceLayout;
+ return true;
// We only need do layout for opacity changes if adding or losing opacity could trigger a change
// in us being a stacking context.
@@ -471,7 +517,7 @@ StyleDifference RenderStyle::visualInvalidationDiff(const RenderStyle& other, un
// to add a selfNeedsSimplifiedLayout bit in order to not get confused and taint every line).
// In addition we need to solve the floating object issue when layers come and go. Right now
// a full layout is necessary to keep floating object lists sane.
- return StyleDifferenceLayout;
+ return true;
}
}
@@ -500,24 +546,24 @@ StyleDifference RenderStyle::visualInvalidationDiff(const RenderStyle& other, un
|| rareInheritedData->m_lineBoxContain != other.rareInheritedData->m_lineBoxContain
|| rareInheritedData->listStyleImage != other.rareInheritedData->listStyleImage
|| rareInheritedData->textStrokeWidth != other.rareInheritedData->textStrokeWidth)
- return StyleDifferenceLayout;
+ return true;
if (!rareInheritedData->shadowDataEquivalent(*other.rareInheritedData.get()))
- return StyleDifferenceLayout;
+ return true;
if (rareInheritedData->quotes.get() != other.rareInheritedData->quotes.get())
- return StyleDifferenceLayout;
+ return true;
}
if (visual->m_textAutosizingMultiplier != other.visual->m_textAutosizingMultiplier)
- return StyleDifferenceLayout;
+ return true;
if (inherited.get() != other.inherited.get()) {
if (inherited->line_height != other.inherited->line_height
|| inherited->font != other.inherited->font
|| inherited->horizontal_border_spacing != other.inherited->horizontal_border_spacing
|| inherited->vertical_border_spacing != other.inherited->vertical_border_spacing)
- return StyleDifferenceLayout;
+ return true;
}
if (inherited_flags._box_direction != other.inherited_flags._box_direction
@@ -527,7 +573,7 @@ StyleDifference RenderStyle::visualInvalidationDiff(const RenderStyle& other, un
|| inherited_flags._direction != other.inherited_flags._direction
|| inherited_flags._white_space != other.inherited_flags._white_space
|| inherited_flags.m_writingMode != other.inherited_flags.m_writingMode)
- return StyleDifferenceLayout;
+ return true;
if (noninherited_flags._overflowX != other.noninherited_flags._overflowX
|| noninherited_flags._overflowY != other.noninherited_flags._overflowY
@@ -537,14 +583,14 @@ StyleDifference RenderStyle::visualInvalidationDiff(const RenderStyle& other, un
|| noninherited_flags._floating != other.noninherited_flags._floating
|| noninherited_flags._originalDisplay != other.noninherited_flags._originalDisplay
|| noninherited_flags._vertical_align != other.noninherited_flags._vertical_align)
- return StyleDifferenceLayout;
+ return true;
if (noninherited_flags._effectiveDisplay >= FIRST_TABLE_DISPLAY && noninherited_flags._effectiveDisplay <= LAST_TABLE_DISPLAY) {
if (inherited_flags._border_collapse != other.inherited_flags._border_collapse
|| inherited_flags._empty_cells != other.inherited_flags._empty_cells
|| inherited_flags._caption_side != other.inherited_flags._caption_side
|| noninherited_flags._table_layout != other.noninherited_flags._table_layout)
- return StyleDifferenceLayout;
+ return true;
// In the collapsing border model, 'hidden' suppresses other borders, while 'none'
// does not, so these style differences can be width differences.
@@ -557,74 +603,51 @@ StyleDifference RenderStyle::visualInvalidationDiff(const RenderStyle& other, un
|| (borderLeftStyle() == BNONE && other.borderLeftStyle() == BHIDDEN)
|| (borderRightStyle() == BHIDDEN && other.borderRightStyle() == BNONE)
|| (borderRightStyle() == BNONE && other.borderRightStyle() == BHIDDEN)))
- return StyleDifferenceLayout;
+ return true;
} else if (noninherited_flags._effectiveDisplay == LIST_ITEM) {
if (inherited_flags._list_style_type != other.inherited_flags._list_style_type
|| inherited_flags._list_style_position != other.inherited_flags._list_style_position)
- return StyleDifferenceLayout;
+ return true;
}
if ((visibility() == COLLAPSE) != (other.visibility() == COLLAPSE))
- return StyleDifferenceLayout;
+ return true;
if (!m_background->outline().visuallyEqual(other.m_background->outline())) {
// FIXME: We only really need to recompute the overflow but we don't have an optimized layout for it.
- return StyleDifferenceLayout;
+ return true;
}
- // SVGRenderStyle::diff() might have returned StyleDifferenceRepaint, eg. if fill changes.
- // If eg. the font-size changed at the same time, we're not allowed to return StyleDifferenceRepaint,
- // but have to return StyleDifferenceLayout, that's why this if branch comes after all branches
- // that are relevant for SVG and might return StyleDifferenceLayout.
- if (svgChange != StyleDifferenceEqual)
- return svgChange;
+ // Movement of non-static-positioned object is special cased in RenderStyle::visualInvalidationDiff().
- // NOTE: This block must be last in this function for the StyleDifferenceLayoutPositionedMovementOnly
- // optimization to work properly.
- if (position() != StaticPosition && surround->offset != other.surround->offset) {
- // Optimize for the case where a positioned layer is moving but not changing size.
- if ((position() == AbsolutePosition || position() == FixedPosition)
- && positionedObjectMovedOnly(surround->offset, other.surround->offset, m_box->width())
- && repaintOnlyDiff(other, changedContextSensitiveProperties) == StyleDifferenceEqual)
- return StyleDifferenceLayoutPositionedMovementOnly;
- // FIXME: We would like to use SimplifiedLayout for relative positioning, but we can't quite do that yet.
- // We need to make sure SimplifiedLayout can operate correctly on RenderInlines (we will need
- // to add a selfNeedsSimplifiedLayout bit in order to not get confused and taint every line).
- return StyleDifferenceLayout;
- }
+ return false;
+}
- StyleDifference repaintDifference = repaintOnlyDiff(other, changedContextSensitiveProperties);
- ASSERT(repaintDifference <= StyleDifferenceRepaintLayer);
- return repaintDifference;
+bool RenderStyle::diffNeedsLayoutOnly(const RenderStyle& other) const
+{
+ // FIXME: Examine cases in needsFullLayoutAndRepaintLayer() and needsFullLayoutAndRepaintSelf()
+ // and move cases that don't need repaint into this method.
+ return false;
}
-StyleDifference RenderStyle::repaintOnlyDiff(const RenderStyle& other, unsigned& changedContextSensitiveProperties) const
+bool RenderStyle::diffNeedsRepaintLayerOnly(const RenderStyle& other) const
{
- if (position() != StaticPosition && (m_box->zIndex() != other.m_box->zIndex() || m_box->hasAutoZIndex() != other.m_box->hasAutoZIndex()
- || visual->clip != other.visual->clip || visual->hasClip != other.visual->hasClip))
- return StyleDifferenceRepaintLayer;
+ if (position() != StaticPosition && (visual->clip != other.visual->clip || visual->hasClip != other.visual->hasClip))
+ return true;
if (RuntimeEnabledFeatures::cssCompositingEnabled() && (rareNonInheritedData->m_effectiveBlendMode != other.rareNonInheritedData->m_effectiveBlendMode
|| rareNonInheritedData->m_isolation != other.rareNonInheritedData->m_isolation))
- return StyleDifferenceRepaintLayer;
-
- if (rareNonInheritedData->opacity != other.rareNonInheritedData->opacity) {
- // Don't return early here; instead take note of the type of change,
- // and deal with it when looking at compositing.
- changedContextSensitiveProperties |= ContextSensitivePropertyOpacity;
- }
-
- if (rareNonInheritedData->m_filter.get() != other.rareNonInheritedData->m_filter.get()
- && *rareNonInheritedData->m_filter.get() != *other.rareNonInheritedData->m_filter.get()) {
- // Don't return early here; instead take note of the type of change,
- // and deal with it when looking at compositing.
- changedContextSensitiveProperties |= ContextSensitivePropertyFilter;
- }
+ return true;
if (rareNonInheritedData->m_mask != other.rareNonInheritedData->m_mask
|| rareNonInheritedData->m_maskBoxImage != other.rareNonInheritedData->m_maskBoxImage)
- return StyleDifferenceRepaintLayer;
+ return true;
+ return false;
+}
+
+bool RenderStyle::diffNeedsRepaintOnly(const RenderStyle& other) const
+{
if (inherited_flags._visibility != other.inherited_flags._visibility
|| inherited_flags.m_printColorAdjust != other.inherited_flags.m_printColorAdjust
|| inherited_flags._insideLink != other.inherited_flags._insideLink
@@ -637,14 +660,19 @@ StyleDifference RenderStyle::repaintOnlyDiff(const RenderStyle& other, unsigned&
|| rareNonInheritedData->m_objectFit != other.rareNonInheritedData->m_objectFit
|| rareNonInheritedData->m_objectPosition != other.rareNonInheritedData->m_objectPosition
|| rareInheritedData->m_imageRendering != other.rareInheritedData->m_imageRendering)
- return StyleDifferenceRepaint;
+ return true;
+
+ if (rareNonInheritedData->m_shapeOutside != other.rareNonInheritedData->m_shapeOutside)
+ return true;
- if (rareNonInheritedData->m_shapeOutside != other.rareNonInheritedData->m_shapeOutside)
- return StyleDifferenceRepaint;
+ if (rareNonInheritedData->m_clipPath != other.rareNonInheritedData->m_clipPath)
+ return true;
- if (rareNonInheritedData->m_clipPath != other.rareNonInheritedData->m_clipPath)
- return StyleDifferenceRepaint;
+ return false;
+}
+bool RenderStyle::diffNeedsRecompositeLayerOnly(const RenderStyle& other) const
+{
if (rareNonInheritedData.get() != other.rareNonInheritedData.get()) {
if (rareNonInheritedData->m_transformStyle3D != other.rareNonInheritedData->m_transformStyle3D
|| rareNonInheritedData->m_backfaceVisibility != other.rareNonInheritedData->m_backfaceVisibility
@@ -653,26 +681,41 @@ StyleDifference RenderStyle::repaintOnlyDiff(const RenderStyle& other, unsigned&
|| rareNonInheritedData->m_perspectiveOriginY != other.rareNonInheritedData->m_perspectiveOriginY
|| hasWillChangeCompositingHint() != other.hasWillChangeCompositingHint()
|| hasWillChangeGpuRasterizationHint() != other.hasWillChangeGpuRasterizationHint())
- return StyleDifferenceRecompositeLayer;
+ return true;
}
- if (inherited->color != other.inherited->color
- || inherited_flags._text_decorations != other.inherited_flags._text_decorations
- || visual->textDecoration != other.visual->textDecoration
- || rareNonInheritedData->m_textDecorationStyle != other.rareNonInheritedData->m_textDecorationStyle
- || rareNonInheritedData->m_textDecorationColor != other.rareNonInheritedData->m_textDecorationColor
- || rareInheritedData->textFillColor() != other.rareInheritedData->textFillColor()
- || rareInheritedData->textStrokeColor() != other.rareInheritedData->textStrokeColor()
- || rareInheritedData->textEmphasisColor() != other.rareInheritedData->textEmphasisColor()
- || rareInheritedData->textEmphasisFill != other.rareInheritedData->textEmphasisFill)
- changedContextSensitiveProperties |= ContextSensitivePropertyTextOrColor;
+ return false;
+}
- // Cursors are not checked, since they will be set appropriately in response to mouse events,
- // so they don't need to cause any repaint or layout.
+void RenderStyle::addContextSensitiveDiffFlags(const RenderStyle& other, StyleDifference& diff) const
+{
+ if (position() != StaticPosition && (m_box->zIndex() != other.m_box->zIndex() || m_box->hasAutoZIndex() != other.m_box->hasAutoZIndex()))
+ diff.setZIndexChanged();
- // Animations don't need to be checked either. We always set the new style on the RenderObject, so we will get a chance to fire off
- // the resulting transition properly.
- return StyleDifferenceEqual;
+ if (rareNonInheritedData.get() != other.rareNonInheritedData.get()) {
+ if (!transformDataEquivalent(other))
+ diff.setTransformChanged();
+
+ if (rareNonInheritedData->opacity != other.rareNonInheritedData->opacity)
+ diff.setOpacityChanged();
+
+ if (rareNonInheritedData->m_filter.get() != other.rareNonInheritedData->m_filter.get()
+ && *rareNonInheritedData->m_filter.get() != *other.rareNonInheritedData->m_filter.get())
+ diff.setFilterChanged();
+ }
+
+ if (!diff.needsRepaint()) {
+ if (inherited->color != other.inherited->color
+ || inherited_flags._text_decorations != other.inherited_flags._text_decorations
+ || visual->textDecoration != other.visual->textDecoration
+ || rareNonInheritedData->m_textDecorationStyle != other.rareNonInheritedData->m_textDecorationStyle
+ || rareNonInheritedData->m_textDecorationColor != other.rareNonInheritedData->m_textDecorationColor
+ || rareInheritedData->textFillColor() != other.rareInheritedData->textFillColor()
+ || rareInheritedData->textStrokeColor() != other.rareInheritedData->textStrokeColor()
+ || rareInheritedData->textEmphasisColor() != other.rareInheritedData->textEmphasisColor()
+ || rareInheritedData->textEmphasisFill != other.rareInheritedData->textEmphasisFill)
+ diff.setTextOrColorChanged();
+ }
}
void RenderStyle::setClip(Length top, Length right, Length bottom, Length left)

Powered by Google App Engine
This is Rietveld 408576698