Simplify the paint invalidation bits.

The only thing they're used for now is to clear the
background obscuration state on RenderBox. They're
also used in RenderLayerModelObject::styleWillChange,
but that usage seems like a huge premature optimization.
Unfortunately, the RenderBox one walks up the ancestor
chain, so it's likely a necessary performance optimization.

R=esprehn@chromium.org

Review URL: https://codereview.chromium.org/851033002
This commit is contained in:
Ojan Vafai 2015-01-15 13:02:00 -08:00
parent 8a07e541a2
commit 6d49e56b24
5 changed files with 30 additions and 103 deletions

View File

@ -76,7 +76,7 @@ void RenderLayerModelObject::willBeDestroyed()
void RenderLayerModelObject::styleWillChange(StyleDifference diff, const RenderStyle& newStyle)
{
if (RenderStyle* oldStyle = style()) {
if (parent() && diff.needsPaintInvalidationLayer()) {
if (parent()) {
if (oldStyle->hasAutoClip() != newStyle.hasAutoClip()
|| oldStyle->clip() != newStyle.clip())
layer()->clipper().clearClipRectsIncludingDescendants();

View File

@ -1199,30 +1199,18 @@ void RenderObject::selectionStartEnd(int& spos, int& epos) const
StyleDifference RenderObject::adjustStyleDifference(StyleDifference diff) const
{
// If transform changed, and the layer does not paint into its own separate backing, then we need to invalidate paints.
if (diff.transformChanged()) {
// Text nodes share style with their parents but transforms don't apply to them,
// hence the !isText() check.
if (!isText())
diff.setNeedsPaintInvalidationLayer();
// If transform, opacity or zIndex changed, then we need to invalidate paints.
// Text nodes share style with their parents but transform/opacity/z-index don't apply to them,
if (!isText() &&
(diff.transformChanged() || diff.opacityChanged() || diff.zIndexChanged())) {
diff.setNeedsPaintInvalidation();
}
// If opacity or zIndex changed, and the layer does not paint into its own separate backing, then we need to invalidate paints (also
// ignoring text nodes)
if (diff.opacityChanged() || diff.zIndexChanged()) {
if (!isText())
diff.setNeedsPaintInvalidationLayer();
}
// If filter changed, and the layer does not paint into its own separate backing or it paints with filters, then we need to invalidate paints.
// If filter changed and it paints with filters, then we need to invalidate paints.
if (diff.filterChanged() && hasLayer()) {
diff.setNeedsPaintInvalidationLayer();
diff.setNeedsPaintInvalidation();
}
if (diff.textOrColorChanged() && !diff.needsPaintInvalidation()
&& hasImmediateNonWhitespaceTextChildOrPropertiesDependentOnColor())
diff.setNeedsPaintInvalidationObject();
// The answer to layerTypeRequired() for plugins, iframes, and canvas can change without the actual
// style changing, since it depends on whether we decide to composite these elements. When the
// layer status of one of these elements changes, we need to force a layout.
@ -1232,12 +1220,6 @@ StyleDifference RenderObject::adjustStyleDifference(StyleDifference diff) const
diff.setNeedsFullLayout();
}
// If we have no layer(), just treat a PaintInvalidationLayer hint as a normal paint invalidation.
if (diff.needsPaintInvalidationLayer() && !hasLayer()) {
diff.clearNeedsPaintInvalidation();
diff.setNeedsPaintInvalidationObject();
}
return diff;
}

View File

@ -286,12 +286,9 @@ StyleDifference RenderStyle::visualInvalidationDiff(const RenderStyle& other) co
StyleDifference diff;
if (diffNeedsFullLayoutAndPaintInvalidation(other)) {
diff.setNeedsFullLayout();
diff.setNeedsPaintInvalidationObject();
}
if (!diff.needsFullLayout() && diffNeedsFullLayout(other))
// FIXME(sky): Combine these two into one function call.
if (diffNeedsFullLayoutAndPaintInvalidation(other)
|| diffNeedsFullLayout(other))
diff.setNeedsFullLayout();
if (!diff.needsFullLayout() && position() != StaticPosition && surround->offset != other.surround->offset) {
@ -302,10 +299,8 @@ StyleDifference RenderStyle::visualInvalidationDiff(const RenderStyle& other) co
diff.setNeedsFullLayout();
}
if (diffNeedsPaintInvalidationLayer(other))
diff.setNeedsPaintInvalidationLayer();
else if (diffNeedsPaintInvalidationObject(other))
diff.setNeedsPaintInvalidationObject();
if (!diff.needsFullLayout() && diffNeedsPaintInvalidation(other))
diff.setNeedsPaintInvalidation();
updatePropertySpecificDifferences(other, diff);
@ -467,21 +462,7 @@ bool RenderStyle::diffNeedsFullLayout(const RenderStyle& other) const
return false;
}
bool RenderStyle::diffNeedsPaintInvalidationLayer(const RenderStyle& other) const
{
if (position() != StaticPosition && (visual->clip != other.visual->clip || visual->hasAutoClip != other.visual->hasAutoClip))
return true;
if (rareNonInheritedData.get() != other.rareNonInheritedData.get()) {
if (rareNonInheritedData->m_mask != other.rareNonInheritedData->m_mask
|| rareNonInheritedData->m_maskBoxImage != other.rareNonInheritedData->m_maskBoxImage)
return true;
}
return false;
}
bool RenderStyle::diffNeedsPaintInvalidationObject(const RenderStyle& other) const
bool RenderStyle::diffNeedsPaintInvalidation(const RenderStyle& other) const
{
if (inherited_flags._visibility != other.inherited_flags._visibility
|| !surround->border.visuallyEqual(other.surround->border)
@ -503,6 +484,15 @@ bool RenderStyle::diffNeedsPaintInvalidationObject(const RenderStyle& other) con
return true;
}
if (position() != StaticPosition && (visual->clip != other.visual->clip || visual->hasAutoClip != other.visual->hasAutoClip))
return true;
if (rareNonInheritedData.get() != other.rareNonInheritedData.get()) {
if (rareNonInheritedData->m_mask != other.rareNonInheritedData->m_mask
|| rareNonInheritedData->m_maskBoxImage != other.rareNonInheritedData->m_maskBoxImage)
return true;
}
return false;
}
@ -522,25 +512,6 @@ void RenderStyle::updatePropertySpecificDifferences(const RenderStyle& other, St
if (rareNonInheritedData->m_filter != other.rareNonInheritedData->m_filter)
diff.setFilterChanged();
}
if (!diff.needsPaintInvalidation()) {
if (inherited->color != other.inherited->color
|| inherited_flags.m_textUnderline != other.inherited_flags.m_textUnderline
|| visual->textDecoration != other.visual->textDecoration) {
diff.setTextOrColorChanged();
} else if (rareNonInheritedData.get() != other.rareNonInheritedData.get()) {
if (rareNonInheritedData->m_textDecorationStyle != other.rareNonInheritedData->m_textDecorationStyle
|| rareNonInheritedData->m_textDecorationColor != other.rareNonInheritedData->m_textDecorationColor)
diff.setTextOrColorChanged();
} else if (rareInheritedData.get() != other.rareInheritedData.get()) {
if (rareInheritedData->textFillColor() != other.rareInheritedData->textFillColor()
|| rareInheritedData->textStrokeColor() != other.rareInheritedData->textStrokeColor()
|| rareInheritedData->textEmphasisColor() != other.rareInheritedData->textEmphasisColor()
|| rareInheritedData->textEmphasisFill != other.rareInheritedData->textEmphasisFill
|| rareInheritedData->appliedTextDecorations != other.rareInheritedData->appliedTextDecorations)
diff.setTextOrColorChanged();
}
}
}
void RenderStyle::addCursor(PassRefPtr<StyleImage> image, const IntPoint& hotSpot)

View File

@ -1366,10 +1366,10 @@ private:
void addAppliedTextDecoration(const AppliedTextDecoration&);
// FIXME(sky): Combine these first two.
bool diffNeedsFullLayoutAndPaintInvalidation(const RenderStyle& other) const;
bool diffNeedsFullLayout(const RenderStyle& other) const;
bool diffNeedsPaintInvalidationLayer(const RenderStyle& other) const;
bool diffNeedsPaintInvalidationObject(const RenderStyle& other) const;
bool diffNeedsPaintInvalidation(const RenderStyle& other) const;
bool diffNeedsRecompositeLayer(const RenderStyle& other) const;
void updatePropertySpecificDifferences(const RenderStyle& other, StyleDifference&) const;
};

View File

@ -16,38 +16,20 @@ public:
OpacityChanged = 1 << 1,
ZIndexChanged = 1 << 2,
FilterChanged = 1 << 3,
// The object needs to issue paint invalidations if it contains text or properties dependent on color (e.g., border or outline).
TextOrColorChanged = 1 << 4,
};
StyleDifference()
: m_paintInvalidationType(NoPaintInvalidation)
: m_needsPaintInvalidation(false)
, m_layoutType(NoLayout)
, m_propertySpecificDifferences(0)
{ }
bool hasDifference() const { return m_paintInvalidationType || m_layoutType || m_propertySpecificDifferences; }
bool hasAtMostPropertySpecificDifferences(unsigned propertyDifferences) const
bool needsPaintInvalidation() const { return m_needsPaintInvalidation; }
void setNeedsPaintInvalidation()
{
return !m_paintInvalidationType && !m_layoutType && !(m_propertySpecificDifferences & ~propertyDifferences);
m_needsPaintInvalidation = true;
}
bool needsPaintInvalidation() const { return m_paintInvalidationType != NoPaintInvalidation; }
void clearNeedsPaintInvalidation() { m_paintInvalidationType = NoPaintInvalidation; }
// The object just needs to issue paint invalidations.
bool needsPaintInvalidationObject() const { return m_paintInvalidationType == PaintInvalidationObject; }
void setNeedsPaintInvalidationObject()
{
ASSERT(!needsPaintInvalidationLayer());
m_paintInvalidationType = PaintInvalidationObject;
}
// The layer and its descendant layers need to issue paint invalidations.
bool needsPaintInvalidationLayer() const { return m_paintInvalidationType == PaintInvalidationLayer; }
void setNeedsPaintInvalidationLayer() { m_paintInvalidationType = PaintInvalidationLayer; }
bool needsLayout() const { return m_layoutType != NoLayout; }
void clearNeedsLayout() { m_layoutType = NoLayout; }
@ -74,16 +56,8 @@ public:
bool filterChanged() const { return m_propertySpecificDifferences & FilterChanged; }
void setFilterChanged() { m_propertySpecificDifferences |= FilterChanged; }
bool textOrColorChanged() const { return m_propertySpecificDifferences & TextOrColorChanged; }
void setTextOrColorChanged() { m_propertySpecificDifferences |= TextOrColorChanged; }
private:
enum PaintInvalidationType {
NoPaintInvalidation = 0,
PaintInvalidationObject,
PaintInvalidationLayer
};
unsigned m_paintInvalidationType : 2;
unsigned m_needsPaintInvalidation : 1;
enum LayoutType {
NoLayout = 0,