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

Unified Diff: Source/core/css/invalidation/StyleInvalidator.cpp

Issue 1317533002: Sibling invalidation sets (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: CORE_EXPORT Created 5 years, 4 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/css/invalidation/StyleInvalidator.cpp
diff --git a/Source/core/css/invalidation/StyleInvalidator.cpp b/Source/core/css/invalidation/StyleInvalidator.cpp
index ddc28c70b6e8607355a4e9245bac2d1f5bca3d2d..d116bf5867fb7d1dd91ca06d4cea8e991d2248e6 100644
--- a/Source/core/css/invalidation/StyleInvalidator.cpp
+++ b/Source/core/css/invalidation/StyleInvalidator.cpp
@@ -33,36 +33,40 @@ static const unsigned char* s_tracingEnabled = nullptr;
void StyleInvalidator::invalidate(Document& document)
{
RecursionData recursionData;
+ SiblingData siblingData;
if (Element* documentElement = document.documentElement())
- invalidate(*documentElement, recursionData);
+ invalidate(*documentElement, recursionData, siblingData);
document.clearChildNeedsStyleInvalidation();
document.clearNeedsStyleInvalidation();
clearPendingInvalidations();
}
-void StyleInvalidator::scheduleInvalidation(PassRefPtrWillBeRawPtr<DescendantInvalidationSet> invalidationSet, Element& element)
+void StyleInvalidator::scheduleInvalidation(PassRefPtrWillBeRawPtr<DescendantInvalidationSet> invalidationSet, Element& element, InvalidateType type)
{
ASSERT(element.inActiveDocument());
- if (element.styleChangeType() >= SubtreeStyleChange)
- return;
- if (invalidationSet->wholeSubtreeInvalid()) {
- element.setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::StyleInvalidator));
- clearInvalidation(element);
- return;
- }
- if (invalidationSet->isEmpty()) {
- element.setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::StyleInvalidator));
- return;
+ if (type == InvalidateDescendants) {
+ if (element.styleChangeType() >= SubtreeStyleChange)
+ return;
+ if (invalidationSet->wholeSubtreeInvalid()) {
+ element.setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::StyleInvalidator));
+ clearInvalidation(element);
+ return;
+ }
+ if (invalidationSet->isEmpty()) {
+ element.setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::StyleInvalidator));
+ return;
+ }
+ element.setNeedsStyleInvalidation();
+ } else {
+ element.markAncestorsWithChildNeedsStyleInvalidation();
}
-
- InvalidationList& list = ensurePendingInvalidationList(element);
+ InvalidationList& list = ensurePendingInvalidationList(element, type);
list.append(invalidationSet);
- element.setNeedsStyleInvalidation();
}
-StyleInvalidator::InvalidationList& StyleInvalidator::ensurePendingInvalidationList(Element& element)
+StyleInvalidator::InvalidationList& StyleInvalidator::ensurePendingInvalidationList(Element& element, InvalidateType type)
{
- PendingInvalidationMap::AddResult addResult = m_pendingInvalidationMap.add(&element, nullptr);
+ PendingInvalidationMap::AddResult addResult = m_pendingInvalidationMap[type].add(&element, nullptr);
if (addResult.isNewEntry)
addResult.storedValue->value = adoptPtrWillBeNoop(new InvalidationList);
return *addResult.storedValue->value;
@@ -72,13 +76,15 @@ void StyleInvalidator::clearInvalidation(Element& element)
{
if (!element.needsStyleInvalidation())
return;
- m_pendingInvalidationMap.remove(&element);
+ m_pendingInvalidationMap[InvalidateDescendants].remove(&element);
+ m_pendingInvalidationMap[InvalidateSiblings].remove(&element);
element.clearNeedsStyleInvalidation();
}
void StyleInvalidator::clearPendingInvalidations()
{
- m_pendingInvalidationMap.clear();
+ m_pendingInvalidationMap[InvalidateDescendants].clear();
+ m_pendingInvalidationMap[InvalidateSiblings].clear();
}
StyleInvalidator::StyleInvalidator()
@@ -104,7 +110,7 @@ void StyleInvalidator::RecursionData::pushInvalidationSet(const DescendantInvali
m_invalidateCustomPseudo = invalidationSet.customPseudoInvalid();
}
-ALWAYS_INLINE bool StyleInvalidator::RecursionData::matchesCurrentInvalidationSets(Element& element)
+ALWAYS_INLINE bool StyleInvalidator::RecursionData::matchesCurrentInvalidationSets(Element& element) const
{
if (m_invalidateCustomPseudo && element.shadowPseudoId() != nullAtom) {
TRACE_STYLE_INVALIDATOR_INVALIDATION_IF_ENABLED(element, InvalidateCustomPseudo);
@@ -122,6 +128,30 @@ ALWAYS_INLINE bool StyleInvalidator::RecursionData::matchesCurrentInvalidationSe
return false;
}
+void StyleInvalidator::SiblingData::pushInvalidationSet(const DescendantInvalidationSet& invalidationSet)
+{
+ m_invalidationSets.append(&invalidationSet);
+ if (invalidationSet.maxDirectAdjacentSelectors() == std::numeric_limits<unsigned>::max())
+ m_invalidationLimits.append(std::numeric_limits<unsigned>::max());
+ else
+ m_invalidationLimits.append(m_elementIndex + invalidationSet.maxDirectAdjacentSelectors());
+}
+
+ALWAYS_INLINE bool StyleInvalidator::SiblingData::matchesCurrentInvalidationSets(Element& element)
+{
+ m_elementIndex++;
+
+ for (unsigned index = 0; index < m_invalidationLimits.size(); ++index) {
+ if (m_elementIndex > m_invalidationLimits[index])
+ continue;
+
+ if (m_invalidationSets[index]->wholeSubtreeInvalid() || m_invalidationSets[index]->invalidatesElement(element))
+ return true;
+ }
+
+ return false;
+}
+
ALWAYS_INLINE bool StyleInvalidator::checkInvalidationSetsAgainstElement(Element& element, StyleInvalidator::RecursionData& recursionData)
{
if (element.styleChangeType() >= SubtreeStyleChange || recursionData.wholeSubtreeInvalid()) {
@@ -129,7 +159,7 @@ ALWAYS_INLINE bool StyleInvalidator::checkInvalidationSetsAgainstElement(Element
return false;
}
if (element.needsStyleInvalidation()) {
- if (InvalidationList* invalidationList = m_pendingInvalidationMap.get(&element)) {
+ if (InvalidationList* invalidationList = m_pendingInvalidationMap[InvalidateDescendants].get(&element)) {
for (const auto& invalidationSet : *invalidationList)
recursionData.pushInvalidationSet(*invalidationSet);
if (UNLIKELY(*s_tracingEnabled)) {
@@ -147,28 +177,34 @@ ALWAYS_INLINE bool StyleInvalidator::checkInvalidationSetsAgainstElement(Element
bool StyleInvalidator::invalidateChildren(Element& element, StyleInvalidator::RecursionData& recursionData)
{
+ SiblingData siblingData;
+
bool someChildrenNeedStyleRecalc = false;
for (ShadowRoot* root = element.youngestShadowRoot(); root; root = root->olderShadowRoot()) {
if (!recursionData.treeBoundaryCrossing() && !root->childNeedsStyleInvalidation() && !root->needsStyleInvalidation())
continue;
for (Element* child = ElementTraversal::firstChild(*root); child; child = ElementTraversal::nextSibling(*child)) {
- bool childRecalced = invalidate(*child, recursionData);
+ bool childRecalced = invalidate(*child, recursionData, siblingData);
someChildrenNeedStyleRecalc = someChildrenNeedStyleRecalc || childRecalced;
}
root->clearChildNeedsStyleInvalidation();
root->clearNeedsStyleInvalidation();
}
for (Element* child = ElementTraversal::firstChild(element); child; child = ElementTraversal::nextSibling(*child)) {
- bool childRecalced = invalidate(*child, recursionData);
+ bool childRecalced = invalidate(*child, recursionData, siblingData);
someChildrenNeedStyleRecalc = someChildrenNeedStyleRecalc || childRecalced;
}
return someChildrenNeedStyleRecalc;
}
-bool StyleInvalidator::invalidate(Element& element, StyleInvalidator::RecursionData& recursionData)
+bool StyleInvalidator::invalidate(Element& element, StyleInvalidator::RecursionData& recursionData, SiblingData& siblingData)
{
RecursionCheckpoint checkpoint(&recursionData);
+ if (siblingData.matchesCurrentInvalidationSets(element)) {
+ element.setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::StyleInvalidator));
+ }
+
bool thisElementNeedsStyleRecalc = checkInvalidationSetsAgainstElement(element, recursionData);
bool someChildrenNeedStyleRecalc = false;
@@ -194,13 +230,20 @@ bool StyleInvalidator::invalidate(Element& element, StyleInvalidator::RecursionD
element.clearChildNeedsStyleInvalidation();
element.clearNeedsStyleInvalidation();
+ if (InvalidationList* invalidationList = m_pendingInvalidationMap[InvalidateSiblings].get(&element)) {
+ for (const auto& invalidationSet : *invalidationList) {
+ siblingData.pushInvalidationSet(*invalidationSet);
+ }
+ }
+
return thisElementNeedsStyleRecalc;
}
DEFINE_TRACE(StyleInvalidator)
{
#if ENABLE(OILPAN)
- visitor->trace(m_pendingInvalidationMap);
+ visitor->trace(m_pendingInvalidationMap[InvalidateDescendants]);
+ visitor->trace(m_pendingInvalidationMap[InvalidateSiblings]);
#endif
}

Powered by Google App Engine
This is Rietveld 408576698