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

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: Rebase 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
« no previous file with comments | « third_party/WebKit/Source/core/animation/InvalidatableStyleInterpolation.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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, nullptr); 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_isCached && 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 InterpolationValue* underlyingValue) const 27 PassOwnPtr<PairwisePrimitiveInterpolation> InvalidatableStyleInterpolation::mayb eConvertPairwise(const StyleResolverState* state, const InterpolationValue* unde rlyingValue) 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, m_conversio nCheckers); 33 OwnPtr<PairwisePrimitiveInterpolation> pairwiseConversion = interpolatio nType->maybeConvertPairwise(*m_startKeyframe, *m_endKeyframe, state, m_conversio nCheckers);
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 InterpolationValue* underlyingValue) const 40 PassOwnPtr<InterpolationValue> InvalidatableStyleInterpolation::convertSingleKey frame(const CSSPropertySpecificKeyframe& keyframe, const StyleResolverState& sta te, const InterpolationValue* 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 if (keyframe.isNeutral() && underlyingValue->type() != *interpolationTyp e) 45 if (keyframe.isNeutral() && underlyingValue->type() != *interpolationTyp e)
55 continue; 46 continue;
56 OwnPtr<InterpolationValue> result = interpolationType->maybeConvertSingl e(keyframe, &state, m_conversionCheckers); 47 OwnPtr<InterpolationValue> result = interpolationType->maybeConvertSingl e(keyframe, &state, m_conversionCheckers);
(...skipping 17 matching lines...) Expand all
74 bool InvalidatableStyleInterpolation::dependsOnUnderlyingValue() const 65 bool InvalidatableStyleInterpolation::dependsOnUnderlyingValue() const
75 { 66 {
76 return (m_startKeyframe->underlyingFraction() != 0 && m_currentFraction != 1 ) || (m_endKeyframe->underlyingFraction() != 0 && m_currentFraction != 0); 67 return (m_startKeyframe->underlyingFraction() != 0 && m_currentFraction != 1 ) || (m_endKeyframe->underlyingFraction() != 0 && m_currentFraction != 0);
77 } 68 }
78 69
79 bool InvalidatableStyleInterpolation::isNeutralKeyframeActive() const 70 bool InvalidatableStyleInterpolation::isNeutralKeyframeActive() const
80 { 71 {
81 return (m_startKeyframe->isNeutral() && m_currentFraction != 1) || (m_endKey frame->isNeutral() && m_currentFraction != 0); 72 return (m_startKeyframe->isNeutral() && m_currentFraction != 1) || (m_endKey frame->isNeutral() && m_currentFraction != 0);
82 } 73 }
83 74
75 void InvalidatableStyleInterpolation::clearCache() const
76 {
77 m_isCached = false;
78 m_cachedPairConversion.clear();
79 m_conversionCheckers.clear();
80 m_cachedValue.clear();
81 }
82
84 bool InvalidatableStyleInterpolation::isCacheValid(const StyleResolverState& sta te, const InterpolationValue* underlyingValue) const 83 bool InvalidatableStyleInterpolation::isCacheValid(const StyleResolverState& sta te, const InterpolationValue* underlyingValue) const
85 { 84 {
85 if (!m_isCached)
86 return false;
86 if (isNeutralKeyframeActive()) { 87 if (isNeutralKeyframeActive()) {
87 if (m_cachedConversion->isFlip()) 88 if (m_cachedPairConversion && m_cachedPairConversion->isFlip())
88 return false; 89 return false;
89 // Pairwise interpolation can never happen between different Interpolati onTypes, neutral values always represent the underlying value. 90 // Pairwise interpolation can never happen between different Interpolati onTypes, neutral values always represent the underlying value.
90 if (!underlyingValue || !m_cachedValue || m_cachedValue->type() != under lyingValue->type()) 91 if (!underlyingValue || !m_cachedValue || m_cachedValue->type() != under lyingValue->type())
91 return false; 92 return false;
92 } 93 }
93 for (const auto& checker : m_conversionCheckers) { 94 for (const auto& checker : m_conversionCheckers) {
94 if (!checker->isValid(state)) 95 if (!checker->isValid(state))
95 return false; 96 return false;
96 } 97 }
97 return true; 98 return true;
98 } 99 }
99 100
100 const InterpolationValue* InvalidatableStyleInterpolation::ensureValidInterpolat ion(const StyleResolverState& state, const InterpolationValue* underlyingValue) const 101 const InterpolationValue* InvalidatableStyleInterpolation::ensureValidInterpolat ion(const StyleResolverState& state, const InterpolationValue* underlyingValue) const
101 { 102 {
102 if (m_cachedConversion && isCacheValid(state, underlyingValue)) 103 ASSERT(!std::isnan(m_currentFraction));
104 if (isCacheValid(state, underlyingValue))
103 return m_cachedValue.get(); 105 return m_cachedValue.get();
104 m_conversionCheckers.clear(); 106 clearCache();
105 if (!maybeCachePairwiseConversion(&state, underlyingValue)) { 107 if (m_currentFraction == 0) {
106 m_cachedConversion = FlipPrimitiveInterpolation::create( 108 m_cachedValue = convertSingleKeyframe(*m_startKeyframe, state, underlyin gValue);
107 convertSingleKeyframe(*m_startKeyframe, state, underlyingValue), 109 } else if (m_currentFraction == 1) {
108 convertSingleKeyframe(*m_endKeyframe, state, underlyingValue)); 110 m_cachedValue = convertSingleKeyframe(*m_endKeyframe, state, underlyingV alue);
111 } else {
112 OwnPtr<PairwisePrimitiveInterpolation> pairwiseConversion = maybeConvert Pairwise(&state, underlyingValue);
113 if (pairwiseConversion) {
114 m_cachedValue = pairwiseConversion->initialValue();
115 m_cachedPairConversion = pairwiseConversion.release();
116 } else {
117 m_cachedPairConversion = FlipPrimitiveInterpolation::create(
118 convertSingleKeyframe(*m_startKeyframe, state, underlyingValue),
119 convertSingleKeyframe(*m_endKeyframe, state, underlyingValue));
120 }
121 m_cachedPairConversion->interpolateValue(m_currentFraction, m_cachedValu e);
109 } 122 }
110 m_cachedConversion->interpolateValue(m_currentFraction, m_cachedValue); 123 m_isCached = true;
111 return m_cachedValue.get(); 124 return m_cachedValue.get();
112 } 125 }
113 126
114 void InvalidatableStyleInterpolation::setFlagIfInheritUsed(StyleResolverState& s tate) const 127 void InvalidatableStyleInterpolation::setFlagIfInheritUsed(StyleResolverState& s tate) const
115 { 128 {
116 if (!state.parentStyle()) 129 if (!state.parentStyle())
117 return; 130 return;
118 if ((m_startKeyframe->value() && m_startKeyframe->value()->isInheritedValue( )) 131 if ((m_startKeyframe->value() && m_startKeyframe->value()->isInheritedValue( ))
119 || (m_endKeyframe->value() && m_endKeyframe->value()->isInheritedValue() )) { 132 || (m_endKeyframe->value() && m_endKeyframe->value()->isInheritedValue() )) {
120 state.parentStyle()->setHasExplicitlyInheritedProperties(); 133 state.parentStyle()->setHasExplicitlyInheritedProperties();
121 } 134 }
122 } 135 }
123 136
124 double InvalidatableStyleInterpolation::underlyingFraction() const 137 double InvalidatableStyleInterpolation::underlyingFraction() const
125 { 138 {
126 return m_cachedConversion->interpolateUnderlyingFraction(m_startKeyframe->un derlyingFraction(), m_endKeyframe->underlyingFraction(), m_currentFraction); 139 if (m_currentFraction == 0)
140 return m_startKeyframe->underlyingFraction();
141 if (m_currentFraction == 1)
142 return m_endKeyframe->underlyingFraction();
143 return m_cachedPairConversion->interpolateUnderlyingFraction(m_startKeyframe ->underlyingFraction(), m_endKeyframe->underlyingFraction(), m_currentFraction);
127 } 144 }
128 145
129 void InvalidatableStyleInterpolation::applyStack(const ActiveInterpolations& int erpolations, StyleResolverState& state) 146 void InvalidatableStyleInterpolation::applyStack(const ActiveInterpolations& int erpolations, StyleResolverState& state)
130 { 147 {
131 ASSERT(!interpolations.isEmpty()); 148 ASSERT(!interpolations.isEmpty());
132 size_t startingIndex = 0; 149 size_t startingIndex = 0;
133 150
134 // Compute the underlying value to composite onto. 151 // Compute the underlying value to composite onto.
135 UnderlyingValue underlyingValue; 152 UnderlyingValue underlyingValue;
136 const InvalidatableStyleInterpolation& firstInterpolation = toInvalidatableS tyleInterpolation(*interpolations.at(startingIndex)); 153 const InvalidatableStyleInterpolation& firstInterpolation = toInvalidatableS tyleInterpolation(*interpolations.at(startingIndex));
(...skipping 28 matching lines...) Expand all
165 underlyingValue.set(currentValue); 182 underlyingValue.set(currentValue);
166 else 183 else
167 currentValue->type().composite(underlyingValue, underlyingFraction, *currentValue); 184 currentValue->type().composite(underlyingValue, underlyingFraction, *currentValue);
168 } 185 }
169 186
170 if (shouldApply && underlyingValue) 187 if (shouldApply && underlyingValue)
171 underlyingValue->type().apply(underlyingValue->interpolableValue(), unde rlyingValue->nonInterpolableValue(), state); 188 underlyingValue->type().apply(underlyingValue->interpolableValue(), unde rlyingValue->nonInterpolableValue(), state);
172 } 189 }
173 190
174 } // namespace blink 191 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/animation/InvalidatableStyleInterpolation.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698