| 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)
|
|
|