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

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

Issue 1329843002: Support per property CSS Animation stacks (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Lint Created 5 years, 3 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 | Annotate | Revision Log
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
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 if (!underlyingValue || !m_cachedValue || m_cachedValue->type() != under lyingValue->type()) 90 if (!underlyingValue || !m_cachedValue || m_cachedValue->type() != under lyingValue->type())
91 return false; 91 return false;
92 } 92 }
93 for (const auto& checker : m_conversionCheckers) { 93 for (const auto& checker : m_conversionCheckers) {
94 if (!checker->isValid(state)) 94 if (!checker->isValid(state))
95 return false; 95 return false;
96 } 96 }
97 return true; 97 return true;
98 } 98 }
99 99
100 void InvalidatableStyleInterpolation::ensureValidInterpolation(const StyleResolv erState& state, const InterpolationValue* underlyingValue) const 100 const InterpolationValue* InvalidatableStyleInterpolation::ensureValidInterpolat ion(const StyleResolverState& state, const InterpolationValue* underlyingValue) const
101 { 101 {
102 if (m_cachedConversion && isCacheValid(state, underlyingValue)) 102 if (m_cachedConversion && isCacheValid(state, underlyingValue))
103 return; 103 return m_cachedValue.get();
104 m_conversionCheckers.clear(); 104 m_conversionCheckers.clear();
105 if (!maybeCachePairwiseConversion(&state, underlyingValue)) { 105 if (!maybeCachePairwiseConversion(&state, underlyingValue)) {
106 m_cachedConversion = FlipPrimitiveInterpolation::create( 106 m_cachedConversion = FlipPrimitiveInterpolation::create(
107 convertSingleKeyframe(*m_startKeyframe, state, underlyingValue), 107 convertSingleKeyframe(*m_startKeyframe, state, underlyingValue),
108 convertSingleKeyframe(*m_endKeyframe, state, underlyingValue)); 108 convertSingleKeyframe(*m_endKeyframe, state, underlyingValue));
109 } 109 }
110 m_cachedConversion->interpolateValue(m_currentFraction, m_cachedValue); 110 m_cachedConversion->interpolateValue(m_currentFraction, m_cachedValue);
111 return m_cachedValue.get();
111 } 112 }
112 113
113 void InvalidatableStyleInterpolation::setFlagIfInheritUsed(StyleResolverState& s tate) const 114 void InvalidatableStyleInterpolation::setFlagIfInheritUsed(StyleResolverState& s tate) const
114 { 115 {
115 if (!state.parentStyle()) 116 if (!state.parentStyle())
116 return; 117 return;
117 if ((m_startKeyframe->value() && m_startKeyframe->value()->isInheritedValue( )) 118 if ((m_startKeyframe->value() && m_startKeyframe->value()->isInheritedValue( ))
118 || (m_endKeyframe->value() && m_endKeyframe->value()->isInheritedValue() )) { 119 || (m_endKeyframe->value() && m_endKeyframe->value()->isInheritedValue() )) {
119 state.parentStyle()->setHasExplicitlyInheritedProperties(); 120 state.parentStyle()->setHasExplicitlyInheritedProperties();
120 } 121 }
121 } 122 }
122 123
123 void InvalidatableStyleInterpolation::apply(StyleResolverState& state) const 124 // Handles memory management of underlying InterpolationValues in applyStack()
125 // Ensures we perform copy on write if we are not the owner of an underlying Int erpolationValue.
126 // This functions similar to a DataRef except on OwnPtr'd objects.
127 class UnderlyingValue {
128 STACK_ALLOCATED();
129 public:
130 UnderlyingValue()
131 : m_owner()
132 , m_pointer(nullptr)
133 { }
134
135 void set(const InterpolationValue* interpolationValue)
136 {
137 // By clearing m_owner we will perform a copy when attempting to access( )
138 // m_pointer as a mutable reference, thus upholding the const contract f or
139 // this instance of interpolationValue despite the const_cast.
140 m_owner.clear();
141 m_pointer = const_cast<InterpolationValue*>(interpolationValue);
142 }
143 void set(PassOwnPtr<InterpolationValue> interpolationValue)
144 {
145 m_owner = interpolationValue;
146 m_pointer = m_owner.get();
147 }
148 InterpolationValue& access()
149 {
150 ASSERT(m_pointer);
151 if (!m_owner)
152 set(m_pointer->clone());
153 return *m_pointer;
154 }
155 const InterpolationValue* get() const { return m_pointer; }
156 operator bool() const { return m_pointer; }
157 const InterpolationValue* operator->() const
158 {
159 ASSERT(m_pointer);
160 return m_pointer;
161 }
162
163 private:
164 OwnPtr<InterpolationValue> m_owner;
165 InterpolationValue* m_pointer;
166 };
167
168 void InvalidatableStyleInterpolation::applyStack(const ActiveInterpolations& int erpolations, StyleResolverState& state)
124 { 169 {
125 OwnPtr<InterpolationValue> underlyingValue = dependsOnUnderlyingValue() ? ma ybeConvertUnderlyingValue(state) : nullptr; 170 ASSERT(!interpolations.isEmpty());
126 ensureValidInterpolation(state, underlyingValue.get()); 171 size_t startingIndex = 0;
127 if (!m_cachedValue) 172
128 return; 173 // Compute the underlying value to composite onto.
129 const InterpolableValue* appliedInterpolableValue = &m_cachedValue->interpol ableValue(); 174 UnderlyingValue underlyingValue;
130 if (underlyingValue && m_cachedValue->type() == underlyingValue->type()) { 175 const InvalidatableStyleInterpolation& firstInterpolation = toInvalidatableS tyleInterpolation(*interpolations.at(startingIndex));
131 double underlyingFraction = m_cachedConversion->interpolateUnderlyingFra ction(m_startKeyframe->underlyingFraction(), m_endKeyframe->underlyingFraction() , m_currentFraction); 176 if (firstInterpolation.dependsOnUnderlyingValue()) {
132 underlyingValue->interpolableValue().scaleAndAdd(underlyingFraction, m_c achedValue->interpolableValue()); 177 underlyingValue.set(firstInterpolation.maybeConvertUnderlyingValue(state ));
133 appliedInterpolableValue = &underlyingValue->interpolableValue(); 178 } else {
179 const InterpolationValue* firstValue = firstInterpolation.ensureValidInt erpolation(state, nullptr);
180 // Fast path for replace interpolations that are the only one to apply.
181 if (interpolations.size() == 1) {
182 if (firstValue) {
183 firstInterpolation.setFlagIfInheritUsed(state);
184 firstValue->type().apply(firstValue->interpolableValue(), firstV alue->nonInterpolableValue(), state);
185 }
186 return;
187 }
188 underlyingValue.set(firstValue);
189 startingIndex++;
134 } 190 }
135 m_cachedValue->type().apply(*appliedInterpolableValue, m_cachedValue->nonInt erpolableValue(), state); 191
136 setFlagIfInheritUsed(state); 192 // Composite interpolations onto the underlying value.
193 bool shouldApply = false;
194 for (size_t i = startingIndex; i < interpolations.size(); i++) {
195 const InvalidatableStyleInterpolation& currentInterpolation = toInvalida tableStyleInterpolation(*interpolations.at(i));
196 ASSERT(currentInterpolation.dependsOnUnderlyingValue());
197 const InterpolationValue* currentValue = currentInterpolation.ensureVali dInterpolation(state, underlyingValue.get());
198 if (!currentValue)
199 continue;
200 shouldApply = true;
201 currentInterpolation.setFlagIfInheritUsed(state);
202 if (!underlyingValue || underlyingValue->type() != currentValue->type()) {
203 underlyingValue.set(currentValue);
204 } else {
205 double underlyingFraction = currentInterpolation.m_cachedConversion- >interpolateUnderlyingFraction(
206 currentInterpolation.m_startKeyframe->underlyingFraction(),
207 currentInterpolation.m_endKeyframe->underlyingFraction(),
208 currentInterpolation.m_currentFraction);
209 underlyingValue.access().interpolableValue().scaleAndAdd(underlyingF raction, currentInterpolation.m_cachedValue->interpolableValue());
210 }
211 }
212
213 if (shouldApply && underlyingValue)
214 underlyingValue->type().apply(underlyingValue->interpolableValue(), unde rlyingValue->nonInterpolableValue(), state);
137 } 215 }
138 216
139 } // namespace blink 217 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/animation/InvalidatableStyleInterpolation.h ('k') | Source/core/animation/css/CSSAnimationUpdate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698