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