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

Unified Diff: third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp

Issue 2309963002: Apply custom property animation (Closed)
Patch Set: Rebase Created 4 years, 1 month 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: third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp b/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp
index 5ee8e3fbd03d1f9930ae835c37194f631223bc20..afdc23d9e80316fd4e9f7493fb4e1f301c9ecf56 100644
--- a/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp
@@ -691,9 +691,18 @@ PassRefPtr<ComputedStyle> StyleResolver::styleForElement(
StyleResolverState state(document(), elementContext, defaultParent);
+ const ComputedStyle* baseComputedStyle = nullptr;
ElementAnimations* elementAnimations = element->elementAnimations();
- const ComputedStyle* baseComputedStyle =
- elementAnimations ? elementAnimations->baseComputedStyle() : nullptr;
+ if (elementAnimations) {
+ // TODO(alancutter): Use the base computed style optimisation in the
+ // presence of custom property animations that don't affect pre-animated
+ // computed values.
+ if (CSSAnimations::isAnimatingCustomProperties(elementAnimations)) {
+ state.setIsAnimatingCustomProperties(true);
+ } else {
+ baseComputedStyle = elementAnimations->baseComputedStyle();
+ }
+ }
if (baseComputedStyle) {
state.setStyle(ComputedStyle::clone(*baseComputedStyle));
@@ -776,7 +785,8 @@ PassRefPtr<ComputedStyle> StyleResolver::styleForElement(
if (state.hasDirAutoAttribute())
state.style()->setSelfOrAncestorHasDirAutoAttribute(true);
- applyMatchedProperties(state, collector.matchedResult());
+ applyMatchedPropertiesAndCustomPropertyAnimations(
+ state, collector.matchedResult(), element);
applyCallbackSelectors(state);
// Cache our original display.
@@ -784,7 +794,7 @@ PassRefPtr<ComputedStyle> StyleResolver::styleForElement(
adjustComputedStyle(state, element);
- if (elementAnimations)
+ if (elementAnimations && !state.isAnimatingCustomProperties())
elementAnimations->updateBaseComputedStyle(state.style());
} else {
INCREMENT_STYLE_STATS_COUNTER(document().styleEngine(), baseStylesUsed, 1);
@@ -794,7 +804,7 @@ PassRefPtr<ComputedStyle> StyleResolver::styleForElement(
// applied before important rules, but this currently happens here as we
// require adjustment to have happened before deciding which properties to
// transition.
- if (applyAnimatedProperties(state, element)) {
+ if (applyAnimatedStandardProperties(state, element)) {
INCREMENT_STYLE_STATS_COUNTER(document().styleEngine(), stylesAnimated, 1);
adjustComputedStyle(state, element);
}
@@ -941,7 +951,8 @@ bool StyleResolver::pseudoStyleForElementInternal(
if (!collector.matchedResult().hasMatchedProperties())
return false;
- applyMatchedProperties(state, collector.matchedResult());
+ applyMatchedPropertiesAndCustomPropertyAnimations(
+ state, collector.matchedResult(), pseudoElement);
applyCallbackSelectors(state);
// Cache our original display.
@@ -959,7 +970,7 @@ bool StyleResolver::pseudoStyleForElementInternal(
// applied before important rules, but this currently happens here as we
// require adjustment to have happened before deciding which properties to
// transition.
- if (applyAnimatedProperties(state, pseudoElement))
+ if (applyAnimatedStandardProperties(state, pseudoElement))
adjustComputedStyle(state, 0);
document().styleEngine().incStyleForElementCount();
@@ -1117,8 +1128,9 @@ void StyleResolver::collectPseudoRulesForElement(
}
}
-bool StyleResolver::applyAnimatedProperties(StyleResolverState& state,
- const Element* animatingElement) {
+bool StyleResolver::applyAnimatedStandardProperties(
+ StyleResolverState& state,
+ const Element* animatingElement) {
Element* element = state.element();
DCHECK(element);
@@ -1132,9 +1144,9 @@ bool StyleResolver::applyAnimatedProperties(StyleResolverState& state,
!state.style()->transitions() && !state.style()->animations())
return false;
- CSSAnimations::calculateUpdate(animatingElement, *element, *state.style(),
- state.parentStyle(), state.animationUpdate(),
- this);
+ CSSAnimations::calculateCompositorAndTransitionUpdate(
+ animatingElement, *element, *state.style(), state.parentStyle(),
+ state.animationUpdate());
CSSAnimations::snapshotCompositorKeyframes(
*element, state.animationUpdate(), *state.style(), state.parentStyle());
@@ -1602,20 +1614,46 @@ void StyleResolver::notifyResizeForViewportUnits() {
m_matchedPropertiesCache.clearViewportDependent();
}
-void StyleResolver::applyMatchedProperties(StyleResolverState& state,
- const MatchResult& matchResult) {
+void StyleResolver::applyMatchedPropertiesAndCustomPropertyAnimations(
+ StyleResolverState& state,
+ const MatchResult& matchResult,
+ const Element* animatingElement) {
+ CacheSuccess cacheSuccess = applyMatchedCache(state, matchResult);
+ NeedsApplyPass needsApplyPass;
+ if (!cacheSuccess.isFullCacheHit()) {
+ applyCustomProperties(state, matchResult, false, cacheSuccess,
+ needsApplyPass);
+ applyMatchedAnimationProperties(state, matchResult, cacheSuccess,
+ needsApplyPass);
+ }
+ if (state.style()->animations() ||
+ (state.element() && state.element()->hasAnimations())) {
+ calculateAnimationUpdate(state, animatingElement);
+ if (state.isAnimatingCustomProperties()) {
+ cacheSuccess.setFailed();
+ applyCustomProperties(state, matchResult, true, cacheSuccess,
+ needsApplyPass);
+ }
+ }
+ if (!cacheSuccess.isFullCacheHit()) {
+ applyMatchedStandardProperties(state, matchResult, cacheSuccess,
+ needsApplyPass);
+ }
+}
+
+StyleResolver::CacheSuccess StyleResolver::applyMatchedCache(
+ StyleResolverState& state,
+ const MatchResult& matchResult) {
const Element* element = state.element();
DCHECK(element);
- INCREMENT_STYLE_STATS_COUNTER(document().styleEngine(), matchedPropertyApply,
- 1);
-
unsigned cacheHash =
matchResult.isCacheable()
? computeMatchedPropertiesHash(matchResult.matchedProperties().data(),
matchResult.matchedProperties().size())
: 0;
- bool applyInheritedOnly = false;
+ bool isInheritedCacheHit = false;
+ bool isNonInheritedCacheHit = false;
const CachedMatchedProperties* cachedMatchedProperties =
cacheHash
? m_matchedPropertiesCache.find(cacheHash, state,
@@ -1651,22 +1689,36 @@ void StyleResolver::applyMatchedProperties(StyleResolverState& state,
state.style()->setInsideLink(linkStatus);
updateFont(state);
-
- return;
+ isInheritedCacheHit = true;
}
- applyInheritedOnly = true;
+
+ isNonInheritedCacheHit = true;
}
- NeedsApplyPass needsApplyPass;
+ return CacheSuccess(isInheritedCacheHit, isNonInheritedCacheHit, cacheHash,
+ cachedMatchedProperties);
+}
+
+void StyleResolver::applyCustomProperties(StyleResolverState& state,
+ const MatchResult& matchResult,
+ bool applyAnimations,
+ const CacheSuccess& cacheSuccess,
+ NeedsApplyPass& needsApplyPass) {
+ DCHECK(!cacheSuccess.isFullCacheHit());
+ bool applyInheritedOnly = cacheSuccess.shouldApplyInheritedOnly();
- // TODO(leviw): We need the proper bit for tracking whether we need to do this
- // work.
+ // TODO(leviw): We need the proper bit for tracking whether we need to do
+ // this work.
applyMatchedProperties<ResolveVariables, UpdateNeedsApplyPass>(
state, matchResult.authorRules(), false, applyInheritedOnly,
needsApplyPass);
applyMatchedProperties<ResolveVariables, CheckNeedsApplyPass>(
state, matchResult.authorRules(), true, applyInheritedOnly,
needsApplyPass);
+ if (applyAnimations) {
+ applyAnimatedProperties<ResolveVariables>(
+ state, state.animationUpdate().activeInterpolationsForAnimations());
+ }
// TODO(leviw): stop recalculating every time
CSSVariableResolver::resolveVariableDefinitions(state);
@@ -1679,15 +1731,59 @@ void StyleResolver::applyMatchedProperties(StyleResolverState& state,
applyMatchedProperties<ResolveVariables, CheckNeedsApplyPass>(
state, matchResult.authorRules(), true, applyInheritedOnly,
needsApplyPass);
+ if (applyAnimations) {
+ applyAnimatedProperties<ResolveVariables>(
+ state, state.animationUpdate().activeInterpolationsForAnimations());
+ }
CSSVariableResolver::resolveVariableDefinitions(state);
}
}
+}
+
+void StyleResolver::applyMatchedAnimationProperties(
+ StyleResolverState& state,
+ const MatchResult& matchResult,
+ const CacheSuccess& cacheSuccess,
+ NeedsApplyPass& needsApplyPass) {
+ DCHECK(!cacheSuccess.isFullCacheHit());
+ bool applyInheritedOnly = cacheSuccess.shouldApplyInheritedOnly();
- // Apply animation affecting properties.
applyMatchedProperties<AnimationPropertyPriority, UpdateNeedsApplyPass>(
state, matchResult.allRules(), false, applyInheritedOnly, needsApplyPass);
applyMatchedProperties<AnimationPropertyPriority, CheckNeedsApplyPass>(
state, matchResult.allRules(), true, applyInheritedOnly, needsApplyPass);
+}
+
+void StyleResolver::calculateAnimationUpdate(StyleResolverState& state,
+ const Element* animatingElement) {
+ Element* element = state.element();
+ DCHECK(state.style()->animations() || (element && element->hasAnimations()));
+
+ CSSAnimations::calculateAnimationUpdate(
+ state.animationUpdate(), animatingElement, *element, *state.style(),
+ state.parentStyle(), this);
+
+ if (state.isAnimatingCustomProperties())
+ return;
+ for (const auto& propertyHandle :
+ state.animationUpdate().activeInterpolationsForAnimations().keys()) {
+ if (CSSAnimations::isCustomPropertyHandle(propertyHandle)) {
+ state.setIsAnimatingCustomProperties(true);
+ return;
+ }
+ }
+}
+
+void StyleResolver::applyMatchedStandardProperties(
+ StyleResolverState& state,
+ const MatchResult& matchResult,
+ const CacheSuccess& cacheSuccess,
+ NeedsApplyPass& needsApplyPass) {
+ INCREMENT_STYLE_STATS_COUNTER(document().styleEngine(), matchedPropertyApply,
+ 1);
+
+ DCHECK(!cacheSuccess.isFullCacheHit());
+ bool applyInheritedOnly = cacheSuccess.shouldApplyInheritedOnly();
// Now we have all of the matched rules in the appropriate order. Walk the
// rules and apply high-priority properties first, i.e., those properties that
@@ -1703,7 +1799,7 @@ void StyleResolver::applyMatchedProperties(StyleResolverState& state,
applyMatchedProperties<HighPropertyPriority, CheckNeedsApplyPass>(
state, matchResult.uaRules(), true, applyInheritedOnly, needsApplyPass);
- if (UNLIKELY(isSVGForeignObjectElement(element))) {
+ if (UNLIKELY(isSVGForeignObjectElement(state.element()))) {
// LayoutSVGRoot handles zooming for the whole SVG subtree, so foreignObject
// content should not be scaled again.
//
@@ -1717,8 +1813,8 @@ void StyleResolver::applyMatchedProperties(StyleResolverState& state,
state.setEffectiveZoom(ComputedStyle::initialZoom());
}
- if (cachedMatchedProperties &&
- cachedMatchedProperties->computedStyle->effectiveZoom() !=
+ if (cacheSuccess.cachedMatchedProperties &&
+ cacheSuccess.cachedMatchedProperties->computedStyle->effectiveZoom() !=
state.style()->effectiveZoom()) {
state.fontBuilder().didChangeEffectiveZoom();
applyInheritedOnly = false;
@@ -1729,9 +1825,9 @@ void StyleResolver::applyMatchedProperties(StyleResolverState& state,
// Many properties depend on the font. If it changes we just apply all
// properties.
- if (cachedMatchedProperties &&
- cachedMatchedProperties->computedStyle->getFontDescription() !=
- state.style()->getFontDescription())
+ if (cacheSuccess.cachedMatchedProperties &&
+ cacheSuccess.cachedMatchedProperties->computedStyle
+ ->getFontDescription() != state.style()->getFontDescription())
applyInheritedOnly = false;
// Registered custom properties are computed after high priority properties.
@@ -1768,12 +1864,14 @@ void StyleResolver::applyMatchedProperties(StyleResolverState& state,
loadPendingResources(state);
- if (!cachedMatchedProperties && cacheHash &&
+ if (!state.isAnimatingCustomProperties() &&
+ !cacheSuccess.cachedMatchedProperties && cacheSuccess.cacheHash &&
MatchedPropertiesCache::isCacheable(state)) {
INCREMENT_STYLE_STATS_COUNTER(document().styleEngine(),
matchedPropertyCacheAdded, 1);
m_matchedPropertiesCache.add(*state.style(), *state.parentStyle(),
- cacheHash, matchResult.matchedProperties());
+ cacheSuccess.cacheHash,
+ matchResult.matchedProperties());
}
DCHECK(!state.fontBuilder().fontDirty());

Powered by Google App Engine
This is Rietveld 408576698