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

Side by Side Diff: third_party/WebKit/Source/core/animation/InvalidatableStyleInterpolation.cpp

Issue 1379263002: Don't use pairwise keyframe interpolation at fractions 0 and 1. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@_listInterpolationFunctions
Patch Set: Created 5 years, 2 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "config.h" 5 #include "config.h"
6 #include "core/animation/InvalidatableStyleInterpolation.h" 6 #include "core/animation/InvalidatableStyleInterpolation.h"
7 7
8 #include "core/animation/StringKeyframe.h" 8 #include "core/animation/StringKeyframe.h"
9 #include "core/css/resolver/StyleResolverState.h" 9 #include "core/css/resolver/StyleResolverState.h"
10 10
11 namespace blink { 11 namespace blink {
12 12
13 InvalidatableStyleInterpolation::InvalidatableStyleInterpolation( 13 void InvalidatableStyleInterpolation::interpolate(int, double fraction)
14 const Vector<const InterpolationType*>& interpolationTypes,
15 const CSSPropertySpecificKeyframe& startKeyframe,
16 const CSSPropertySpecificKeyframe& endKeyframe)
17 : StyleInterpolation(nullptr, nullptr, interpolationTypes.first()->property( ))
18 , m_interpolationTypes(interpolationTypes)
19 , m_startKeyframe(&startKeyframe)
20 , m_endKeyframe(&endKeyframe)
21 { 14 {
22 maybeCachePairwiseConversion(nullptr, UnderlyingValue()); 15 if (fraction == m_currentFraction)
23 interpolate(0, 0); 16 return;
17
18 if (m_currentFraction == 0 || m_currentFraction == 1 || fraction == 0 || fra ction == 1)
19 clearCache();
20
21 m_currentFraction = fraction;
22 if (!m_isCachePending && m_cachedPairConversion)
23 m_cachedPairConversion->interpolateValue(fraction, m_cachedValue);
24 // We defer the interpolation to ensureValidInterpolation() if m_cachedPairC onversion is null.
24 } 25 }
25 26
26 bool InvalidatableStyleInterpolation::maybeCachePairwiseConversion(const StyleRe solverState* state, const UnderlyingValue& underlyingValue) const 27 PassOwnPtr<PairwisePrimitiveInterpolation> InvalidatableStyleInterpolation::mayb eConvertPairwise(const StyleResolverState* state, const UnderlyingValue& underly ingValue) const
27 { 28 {
29 ASSERT(m_currentFraction != 0 && m_currentFraction != 1);
28 for (const auto& interpolationType : m_interpolationTypes) { 30 for (const auto& interpolationType : m_interpolationTypes) {
29 if ((m_startKeyframe->isNeutral() || m_endKeyframe->isNeutral()) && (!un derlyingValue || underlyingValue->type() != *interpolationType)) 31 if ((m_startKeyframe->isNeutral() || m_endKeyframe->isNeutral()) && (!un derlyingValue || underlyingValue->type() != *interpolationType))
30 continue; 32 continue;
31 OwnPtr<PairwisePrimitiveInterpolation> pairwiseConversion = interpolatio nType->maybeConvertPairwise(*m_startKeyframe, *m_endKeyframe, state, underlyingV alue, m_conversionCheckers); 33 OwnPtr<PairwisePrimitiveInterpolation> pairwiseConversion = interpolatio nType->maybeConvertPairwise(*m_startKeyframe, *m_endKeyframe, state, underlyingV alue, m_conversionCheckers);
32 if (pairwiseConversion) { 34 if (pairwiseConversion)
33 m_cachedValue = pairwiseConversion->initialValue(); 35 return pairwiseConversion.release();
34 m_cachedConversion = pairwiseConversion.release();
35 return true;
36 }
37 } 36 }
38 return false; 37 return nullptr;
39 }
40
41 void InvalidatableStyleInterpolation::interpolate(int, double fraction)
42 {
43 m_currentFraction = fraction;
44 if (m_cachedConversion)
45 m_cachedConversion->interpolateValue(fraction, m_cachedValue);
46 // We defer the interpolation to ensureValidInterpolation() if m_cachedConve rsion is null.
47 } 38 }
48 39
49 PassOwnPtr<InterpolationValue> InvalidatableStyleInterpolation::convertSingleKey frame(const CSSPropertySpecificKeyframe& keyframe, const StyleResolverState& sta te, const UnderlyingValue& underlyingValue) const 40 PassOwnPtr<InterpolationValue> InvalidatableStyleInterpolation::convertSingleKey frame(const CSSPropertySpecificKeyframe& keyframe, const StyleResolverState& sta te, const UnderlyingValue& underlyingValue) const
50 { 41 {
51 if (keyframe.isNeutral() && !underlyingValue) 42 if (keyframe.isNeutral() && !underlyingValue)
52 return nullptr; 43 return nullptr;
53 for (const auto& interpolationType : m_interpolationTypes) { 44 for (const auto& interpolationType : m_interpolationTypes) {
54 UnderlyingValue conversionUnderlyingValue; 45 UnderlyingValue conversionUnderlyingValue;
55 if (underlyingValue && underlyingValue->type() == *interpolationType) 46 if (underlyingValue && underlyingValue->type() == *interpolationType)
56 conversionUnderlyingValue.set(underlyingValue.get()); 47 conversionUnderlyingValue.set(underlyingValue.get());
(...skipping 20 matching lines...) Expand all
77 bool InvalidatableStyleInterpolation::dependsOnUnderlyingValue() const 68 bool InvalidatableStyleInterpolation::dependsOnUnderlyingValue() const
78 { 69 {
79 return (m_startKeyframe->underlyingFraction() != 0 && m_currentFraction != 1 ) || (m_endKeyframe->underlyingFraction() != 0 && m_currentFraction != 0); 70 return (m_startKeyframe->underlyingFraction() != 0 && m_currentFraction != 1 ) || (m_endKeyframe->underlyingFraction() != 0 && m_currentFraction != 0);
80 } 71 }
81 72
82 bool InvalidatableStyleInterpolation::isNeutralKeyframeActive() const 73 bool InvalidatableStyleInterpolation::isNeutralKeyframeActive() const
83 { 74 {
84 return (m_startKeyframe->isNeutral() && m_currentFraction != 1) || (m_endKey frame->isNeutral() && m_currentFraction != 0); 75 return (m_startKeyframe->isNeutral() && m_currentFraction != 1) || (m_endKey frame->isNeutral() && m_currentFraction != 0);
85 } 76 }
86 77
78 void InvalidatableStyleInterpolation::clearCache() const
79 {
80 m_isCachePending = true;
81 m_cachedPairConversion.clear();
82 m_conversionCheckers.clear();
83 m_cachedValue.clear();
84 }
85
87 bool InvalidatableStyleInterpolation::isCacheValid(const StyleResolverState& sta te, const UnderlyingValue& underlyingValue) const 86 bool InvalidatableStyleInterpolation::isCacheValid(const StyleResolverState& sta te, const UnderlyingValue& underlyingValue) const
88 { 87 {
88 if (m_isCachePending)
89 return false;
89 if (isNeutralKeyframeActive()) { 90 if (isNeutralKeyframeActive()) {
90 if (m_cachedConversion->isFlip()) 91 if (m_cachedPairConversion && m_cachedPairConversion->isFlip())
91 return false; 92 return false;
92 // Pairwise interpolation can never happen between different Interpolati onTypes, neutral values always represent the underlying value. 93 // Pairwise interpolation can never happen between different Interpolati onTypes, neutral values always represent the underlying value.
93 if (!underlyingValue || !m_cachedValue || m_cachedValue->type() != under lyingValue->type()) 94 if (!underlyingValue || !m_cachedValue || m_cachedValue->type() != under lyingValue->type())
94 return false; 95 return false;
95 } 96 }
96 for (const auto& checker : m_conversionCheckers) { 97 for (const auto& checker : m_conversionCheckers) {
97 UnderlyingValue checkedUnderlyingValue; 98 UnderlyingValue checkedUnderlyingValue;
98 if (underlyingValue && underlyingValue->type() == checker->type()) 99 if (underlyingValue && underlyingValue->type() == checker->type())
99 checkedUnderlyingValue.set(underlyingValue.get()); 100 checkedUnderlyingValue.set(underlyingValue.get());
100 if (!checker->isValid(state, checkedUnderlyingValue)) 101 if (!checker->isValid(state, checkedUnderlyingValue))
101 return false; 102 return false;
102 } 103 }
103 return true; 104 return true;
104 } 105 }
105 106
106 const InterpolationValue* InvalidatableStyleInterpolation::ensureValidInterpolat ion(const StyleResolverState& state, const UnderlyingValue& underlyingValue) con st 107 const InterpolationValue* InvalidatableStyleInterpolation::ensureValidInterpolat ion(const StyleResolverState& state, const UnderlyingValue& underlyingValue) con st
107 { 108 {
108 if (m_cachedConversion && isCacheValid(state, underlyingValue)) 109 if (isCacheValid(state, underlyingValue))
109 return m_cachedValue.get(); 110 return m_cachedValue.get();
110 m_conversionCheckers.clear(); 111 clearCache();
111 if (!maybeCachePairwiseConversion(&state, underlyingValue)) { 112 if (m_currentFraction == 0) {
112 m_cachedConversion = FlipPrimitiveInterpolation::create( 113 m_cachedValue = convertSingleKeyframe(*m_startKeyframe, state, underlyin gValue);
113 convertSingleKeyframe(*m_startKeyframe, state, underlyingValue), 114 } else if (m_currentFraction == 1) {
114 convertSingleKeyframe(*m_endKeyframe, state, underlyingValue)); 115 m_cachedValue = convertSingleKeyframe(*m_endKeyframe, state, underlyingV alue);
116 } else {
117 OwnPtr<PairwisePrimitiveInterpolation> pairwiseConversion = maybeConvert Pairwise(&state, underlyingValue);
118 if (pairwiseConversion) {
119 m_cachedValue = pairwiseConversion->initialValue();
120 m_cachedPairConversion = pairwiseConversion.release();
121 } else {
122 m_cachedPairConversion = FlipPrimitiveInterpolation::create(
123 convertSingleKeyframe(*m_startKeyframe, state, underlyingValue),
124 convertSingleKeyframe(*m_endKeyframe, state, underlyingValue));
125 }
126 m_cachedPairConversion->interpolateValue(m_currentFraction, m_cachedValu e);
115 } 127 }
116 m_cachedConversion->interpolateValue(m_currentFraction, m_cachedValue); 128 m_isCachePending = false;
117 return m_cachedValue.get(); 129 return m_cachedValue.get();
118 } 130 }
119 131
120 void InvalidatableStyleInterpolation::setFlagIfInheritUsed(StyleResolverState& s tate) const 132 void InvalidatableStyleInterpolation::setFlagIfInheritUsed(StyleResolverState& s tate) const
121 { 133 {
122 if (!state.parentStyle()) 134 if (!state.parentStyle())
123 return; 135 return;
124 if ((m_startKeyframe->value() && m_startKeyframe->value()->isInheritedValue( )) 136 if ((m_startKeyframe->value() && m_startKeyframe->value()->isInheritedValue( ))
125 || (m_endKeyframe->value() && m_endKeyframe->value()->isInheritedValue() )) { 137 || (m_endKeyframe->value() && m_endKeyframe->value()->isInheritedValue() )) {
126 state.parentStyle()->setHasExplicitlyInheritedProperties(); 138 state.parentStyle()->setHasExplicitlyInheritedProperties();
127 } 139 }
128 } 140 }
129 141
130 double InvalidatableStyleInterpolation::underlyingFraction() const 142 double InvalidatableStyleInterpolation::underlyingFraction() const
131 { 143 {
132 return m_cachedConversion->interpolateUnderlyingFraction(m_startKeyframe->un derlyingFraction(), m_endKeyframe->underlyingFraction(), m_currentFraction); 144 if (m_currentFraction == 0)
145 return m_startKeyframe->underlyingFraction();
146 if (m_currentFraction == 1)
147 return m_endKeyframe->underlyingFraction();
148 return m_cachedPairConversion->interpolateUnderlyingFraction(m_startKeyframe ->underlyingFraction(), m_endKeyframe->underlyingFraction(), m_currentFraction);
133 } 149 }
134 150
135 void InvalidatableStyleInterpolation::applyStack(const ActiveInterpolations& int erpolations, StyleResolverState& state) 151 void InvalidatableStyleInterpolation::applyStack(const ActiveInterpolations& int erpolations, StyleResolverState& state)
136 { 152 {
137 ASSERT(!interpolations.isEmpty()); 153 ASSERT(!interpolations.isEmpty());
138 size_t startingIndex = 0; 154 size_t startingIndex = 0;
139 155
140 // Compute the underlying value to composite onto. 156 // Compute the underlying value to composite onto.
141 UnderlyingValue underlyingValue; 157 UnderlyingValue underlyingValue;
142 const InvalidatableStyleInterpolation& firstInterpolation = toInvalidatableS tyleInterpolation(*interpolations.at(startingIndex)); 158 const InvalidatableStyleInterpolation& firstInterpolation = toInvalidatableS tyleInterpolation(*interpolations.at(startingIndex));
(...skipping 28 matching lines...) Expand all
171 underlyingValue.set(currentValue); 187 underlyingValue.set(currentValue);
172 else 188 else
173 currentValue->type().composite(underlyingValue, underlyingFraction, *currentValue); 189 currentValue->type().composite(underlyingValue, underlyingFraction, *currentValue);
174 } 190 }
175 191
176 if (shouldApply && underlyingValue) 192 if (shouldApply && underlyingValue)
177 underlyingValue->type().apply(underlyingValue->interpolableValue(), unde rlyingValue->nonInterpolableValue(), state); 193 underlyingValue->type().apply(underlyingValue->interpolableValue(), unde rlyingValue->nonInterpolableValue(), state);
178 } 194 }
179 195
180 } // namespace blink 196 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698