Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 36 #include "core/animation/AnimatableValue.h" | 36 #include "core/animation/AnimatableValue.h" |
| 37 #include "core/animation/CompositorAnimationsImpl.h" | 37 #include "core/animation/CompositorAnimationsImpl.h" |
| 38 #include "core/platform/animation/AnimationTranslationUtil.h" | 38 #include "core/platform/animation/AnimationTranslationUtil.h" |
| 39 #include "core/rendering/CompositedLayerMapping.h" | 39 #include "core/rendering/CompositedLayerMapping.h" |
| 40 #include "core/rendering/RenderBoxModelObject.h" | 40 #include "core/rendering/RenderBoxModelObject.h" |
| 41 #include "core/rendering/RenderLayer.h" | 41 #include "core/rendering/RenderLayer.h" |
| 42 #include "core/rendering/RenderObject.h" | 42 #include "core/rendering/RenderObject.h" |
| 43 #include "public/platform/Platform.h" | 43 #include "public/platform/Platform.h" |
| 44 #include "public/platform/WebAnimation.h" | 44 #include "public/platform/WebAnimation.h" |
| 45 #include "public/platform/WebCompositorSupport.h" | 45 #include "public/platform/WebCompositorSupport.h" |
| 46 #include "public/platform/WebFilterAnimationCurve.h" | |
| 47 #include "public/platform/WebFloatAnimationCurve.h" | 46 #include "public/platform/WebFloatAnimationCurve.h" |
| 48 #include "public/platform/WebFloatKeyframe.h" | 47 #include "public/platform/WebFloatKeyframe.h" |
| 49 #include "public/platform/WebTransformAnimationCurve.h" | |
| 50 #include "public/platform/WebTransformKeyframe.h" | |
| 51 #include "public/platform/WebTransformOperations.h" | |
| 52 | 48 |
| 53 #include <algorithm> | 49 #include <algorithm> |
| 54 #include <cmath> | 50 #include <cmath> |
| 55 | 51 |
| 56 | |
| 57 namespace WebCore { | 52 namespace WebCore { |
| 58 | 53 |
| 59 // ----------------------------------------------------------------------- | 54 // ----------------------------------------------------------------------- |
| 60 // TimingFunctionReverser methods | 55 // TimingFunctionReverser methods |
| 61 // ----------------------------------------------------------------------- | 56 // ----------------------------------------------------------------------- |
| 62 | 57 |
| 63 PassRefPtr<TimingFunction> CompositorAnimationsTimingFunctionReverser::reverse(c onst LinearTimingFunction* timefunc) | 58 PassRefPtr<TimingFunction> CompositorAnimationsTimingFunctionReverser::reverse(c onst LinearTimingFunction* timefunc) |
| 64 { | 59 { |
| 65 return const_cast<LinearTimingFunction*>(timefunc); | 60 return const_cast<LinearTimingFunction*>(timefunc); |
| 66 } | 61 } |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 167 PassOwnPtr<Vector<CSSPropertyID> > CompositorAnimationsKeyframeEffectHelper::get Properties( | 162 PassOwnPtr<Vector<CSSPropertyID> > CompositorAnimationsKeyframeEffectHelper::get Properties( |
| 168 const KeyframeAnimationEffect* effect) | 163 const KeyframeAnimationEffect* effect) |
| 169 { | 164 { |
| 170 const_cast<KeyframeAnimationEffect*>(effect)->ensureKeyframeGroups(); | 165 const_cast<KeyframeAnimationEffect*>(effect)->ensureKeyframeGroups(); |
| 171 OwnPtr<Vector<CSSPropertyID> > propertyIds = adoptPtr(new Vector<CSSProperty ID>(effect->m_keyframeGroups->size())); | 166 OwnPtr<Vector<CSSPropertyID> > propertyIds = adoptPtr(new Vector<CSSProperty ID>(effect->m_keyframeGroups->size())); |
| 172 copyKeysToVector(*(effect->m_keyframeGroups.get()), *propertyIds.get()); | 167 copyKeysToVector(*(effect->m_keyframeGroups.get()), *propertyIds.get()); |
| 173 return propertyIds.release(); | 168 return propertyIds.release(); |
| 174 } | 169 } |
| 175 | 170 |
| 176 PassOwnPtr<CompositorAnimationsKeyframeEffectHelper::KeyframeValues> CompositorA nimationsKeyframeEffectHelper::getKeyframeValuesForProperty( | 171 PassOwnPtr<CompositorAnimationsKeyframeEffectHelper::KeyframeValues> CompositorA nimationsKeyframeEffectHelper::getKeyframeValuesForProperty( |
| 177 const KeyframeAnimationEffect* effect, CSSPropertyID id, double zero, double scale, bool reverse) | 172 const KeyframeAnimationEffect* effect, CSSPropertyID id, double scale, bool reverse) |
| 178 { | 173 { |
| 179 const_cast<KeyframeAnimationEffect*>(effect)->ensureKeyframeGroups(); | 174 const_cast<KeyframeAnimationEffect*>(effect)->ensureKeyframeGroups(); |
| 180 return getKeyframeValuesForProperty(effect->m_keyframeGroups->get(id), zero, scale, reverse); | 175 return getKeyframeValuesForProperty(effect->m_keyframeGroups->get(id), scale , reverse); |
| 181 } | 176 } |
| 182 | 177 |
| 183 PassOwnPtr<CompositorAnimationsKeyframeEffectHelper::KeyframeValues> CompositorA nimationsKeyframeEffectHelper::getKeyframeValuesForProperty( | 178 PassOwnPtr<CompositorAnimationsKeyframeEffectHelper::KeyframeValues> CompositorA nimationsKeyframeEffectHelper::getKeyframeValuesForProperty( |
| 184 const KeyframeAnimationEffect::PropertySpecificKeyframeGroup* group, double zero, double scale, bool reverse) | 179 const KeyframeAnimationEffect::PropertySpecificKeyframeGroup* group, double scale, bool reverse) |
| 185 { | 180 { |
| 186 OwnPtr<CompositorAnimationsKeyframeEffectHelper::KeyframeValues> values = ad optPtr( | 181 OwnPtr<CompositorAnimationsKeyframeEffectHelper::KeyframeValues> values = ad optPtr( |
| 187 new CompositorAnimationsKeyframeEffectHelper::KeyframeValues()); | 182 new CompositorAnimationsKeyframeEffectHelper::KeyframeValues()); |
| 188 | 183 |
| 189 for (size_t i = 0; i < group->m_keyframes.size(); i++) { | 184 for (size_t i = 0; i < group->m_keyframes.size(); i++) { |
| 190 KeyframeAnimationEffect::PropertySpecificKeyframe* frame = group->m_keyf rames[i].get(); | 185 KeyframeAnimationEffect::PropertySpecificKeyframe* frame = group->m_keyf rames[i].get(); |
| 191 | 186 |
| 192 double offset = zero + frame->offset() * scale; | 187 double offset = (reverse ? (1 - frame->offset()) : frame->offset()) * sc ale; |
| 193 if (reverse) | |
| 194 offset = zero + (1 - frame->offset()) * scale; | |
| 195 | |
| 196 values->append(std::make_pair(offset, frame->value())); | 188 values->append(std::make_pair(offset, frame->value())); |
| 197 } | 189 } |
| 198 if (reverse) | 190 if (reverse) |
| 199 values->reverse(); | 191 values->reverse(); |
| 200 | 192 |
| 201 return values.release(); | 193 return values.release(); |
| 202 } | 194 } |
| 203 | 195 |
| 204 // ----------------------------------------------------------------------- | 196 // ----------------------------------------------------------------------- |
| 205 // CompositorAnimationsImpl | 197 // CompositorAnimationsImpl |
| 206 // ----------------------------------------------------------------------- | 198 // ----------------------------------------------------------------------- |
| 207 | 199 |
| 208 bool CompositorAnimationsImpl::isCandidateForCompositor(const Keyframe& keyframe ) | 200 bool CompositorAnimationsImpl::isCandidateForCompositor(const Keyframe& keyframe ) |
| 209 { | 201 { |
| 210 // Only replace mode can be accelerated | 202 // Only replace mode can be accelerated |
| 211 if (keyframe.composite() != AnimationEffect::CompositeReplace) | 203 if (keyframe.composite() != AnimationEffect::CompositeReplace) |
| 212 return false; | 204 return false; |
| 213 | 205 |
| 214 // Check all the properties can be accelerated | 206 // Check all the properties can be accelerated |
| 215 const PropertySet properties = keyframe.properties(); // FIXME: properties c reates a whole new PropertySet! | 207 const PropertySet properties = keyframe.properties(); // FIXME: properties c reates a whole new PropertySet! |
| 216 for (PropertySet::const_iterator it = properties.begin(); it != properties.e nd(); ++it) { | 208 for (PropertySet::const_iterator it = properties.begin(); it != properties.e nd(); ++it) { |
| 217 switch (*it) { | 209 switch (*it) { |
| 218 case CSSPropertyOpacity: | 210 case CSSPropertyOpacity: |
| 219 case CSSPropertyWebkitFilter: // FIXME: What about CSSPropertyFilter? | 211 case CSSPropertyWebkitFilter: // FIXME: What about CSSPropertyFilter? |
| 220 case CSSPropertyWebkitTransform: | 212 case CSSPropertyWebkitTransform: |
| 221 return true; | 213 continue; |
| 222 default: | 214 default: |
| 223 return false; | 215 return false; |
| 224 } | 216 } |
| 225 } | 217 } |
| 226 return true; | 218 return true; |
| 227 } | 219 } |
| 228 | 220 |
| 229 bool CompositorAnimationsImpl::isCandidateForCompositor(const KeyframeAnimationE ffect& effect) | 221 bool CompositorAnimationsImpl::isCandidateForCompositor(const KeyframeAnimationE ffect& effect) |
| 230 { | 222 { |
| 231 const KeyframeAnimationEffect::KeyframeVector frames = effect.getFrames(); | 223 const KeyframeAnimationEffect::KeyframeVector frames = effect.getFrames(); |
| 232 for (size_t i = 0; i < frames.size(); ++i) { | 224 for (size_t i = 0; i < frames.size(); ++i) { |
| 233 if (!isCandidateForCompositor(*frames[i].get())) | 225 if (!isCandidateForCompositor(*frames[i].get())) |
| 234 return false; | 226 return false; |
| 235 } | 227 } |
| 236 return true; | 228 return true; |
| 237 } | 229 } |
| 238 | 230 |
| 239 bool CompositorAnimationsImpl::isCandidateForCompositor(const Timing& timing, co nst KeyframeAnimationEffect::KeyframeVector& frames) | 231 bool CompositorAnimationsImpl::isCandidateForCompositor(const Timing& timing, co nst KeyframeAnimationEffect::KeyframeVector& frames) |
| 240 { | 232 { |
| 241 // FIXME: Support more then FillModeNone. | |
| 242 if (timing.fillMode != Timing::FillModeNone) | |
| 243 return false; | |
| 244 | 233 |
| 245 if (!timing.hasIterationDuration) | 234 CompositorTiming out; |
| 246 return false; | 235 if (!convertTimingForCompositor(timing, out)) |
| 247 | |
| 248 // FIXME: Support non-zero iteration start. | |
| 249 if (timing.iterationStart != 0.0) | |
| 250 return false; | |
| 251 | |
| 252 // FIXME: Compositor only supports integer iteration counts. | |
| 253 if (!std::isfinite(timing.iterationCount) || (timing.iterationCount < 0) || (std::floor(timing.iterationCount) != timing.iterationCount)) | |
| 254 return false; | |
| 255 | |
| 256 // FIXME: Support positive startDelay and iterations. | |
| 257 if (timing.iterationCount != 1 && timing.startDelay > 0.0) | |
| 258 return false; | 236 return false; |
| 259 | 237 |
| 260 return isCandidateForCompositor(*timing.timingFunction.get(), frames); | 238 return isCandidateForCompositor(*timing.timingFunction.get(), frames); |
| 261 } | 239 } |
| 262 | 240 |
| 263 bool CompositorAnimationsImpl::isCandidateForCompositor(const TimingFunction& ti mingFunction, const KeyframeAnimationEffect::KeyframeVector& frames, double fram eOffset) | 241 bool CompositorAnimationsImpl::isCandidateForCompositor(const TimingFunction& ti mingFunction, const KeyframeAnimationEffect::KeyframeVector& frames, bool isNest edCall) |
| 264 { | 242 { |
| 265 switch (timingFunction.type()) { | 243 switch (timingFunction.type()) { |
| 266 case TimingFunction::LinearFunction: | 244 case TimingFunction::LinearFunction: |
| 267 return true; | 245 return true; |
| 268 | 246 |
| 269 case TimingFunction::CubicBezierFunction: | 247 case TimingFunction::CubicBezierFunction: |
| 270 // Can have a cubic if we don't have to split it (IE only have two frame s). | 248 // Can have a cubic if we don't have to split it (IE only have two frame s). |
| 271 if (frames.size() != 2) | 249 if (!isNestedCall && (frames.size() != 2)) |
| 272 return false; | 250 return false; |
| 273 | 251 |
| 274 if (frames[0]->offset() - frameOffset) | 252 ASSERT(!frames.size() || (frames[0]->offset() == 0.0 && frames[1]->offse t() == 1.0)); |
| 275 return false; | |
| 276 | 253 |
| 277 return true; | 254 return true; |
| 278 | 255 |
| 279 case TimingFunction::StepsFunction: | 256 case TimingFunction::StepsFunction: |
| 280 return false; | 257 return false; |
| 281 | 258 |
| 282 case TimingFunction::ChainedFunction: { | 259 case TimingFunction::ChainedFunction: { |
| 283 // Currently we only support chained segments in the form the CSS code | 260 // Currently we only support chained segments in the form the CSS code |
| 284 // generates. These chained segments are only one level deep and have | 261 // generates. These chained segments are only one level deep and have |
| 285 // one timing function per frame. | 262 // one timing function per frame. |
| 286 const ChainedTimingFunction* chained = static_cast<const ChainedTimingFu nction*>(&timingFunction); | 263 const ChainedTimingFunction* chained = static_cast<const ChainedTimingFu nction*>(&timingFunction); |
| 287 if (frameOffset) | 264 if (isNestedCall) |
| 288 return false; | 265 return false; |
| 289 | 266 |
| 290 if (!chained->m_segments.size()) | 267 if (!chained->m_segments.size()) |
| 291 return false; | 268 return false; |
| 292 | 269 |
| 293 if (frames.size() != chained->m_segments.size() + 1) | 270 if (frames.size() != chained->m_segments.size() + 1) |
| 294 return false; | 271 return false; |
| 295 | 272 |
| 296 for (size_t timeIndex = 0; timeIndex < chained->m_segments.size(); timeI ndex++) { | 273 for (size_t timeIndex = 0; timeIndex < chained->m_segments.size(); timeI ndex++) { |
| 297 const ChainedTimingFunction::Segment& segment = chained->m_segments[ timeIndex]; | 274 const ChainedTimingFunction::Segment& segment = chained->m_segments[ timeIndex]; |
| 298 | 275 |
| 299 if (frames[timeIndex]->offset() != segment.m_min || frames[timeIndex + 1]->offset() != segment.m_max) | 276 if (frames[timeIndex]->offset() != segment.m_min || frames[timeIndex + 1]->offset() != segment.m_max) |
| 300 return false; | 277 return false; |
| 301 | 278 |
| 302 KeyframeAnimationEffect::KeyframeVector timingFrames; | 279 KeyframeAnimationEffect::KeyframeVector timingFrames; |
|
Steve Block
2013/11/13 23:17:01
Yes, I think we should convert this function to ta
mithro-old
2013/11/14 02:11:46
Done.
| |
| 303 timingFrames.append(frames[timeIndex]); | 280 if (!isCandidateForCompositor(*segment.m_timingFunction.get(), timin gFrames, true)) |
| 304 timingFrames.append(frames[timeIndex + 1]); | |
| 305 | |
| 306 if (!isCandidateForCompositor(*(segment.m_timingFunction.get()), tim ingFrames, segment.m_min)) | |
| 307 return false; | 281 return false; |
| 308 } | 282 } |
| 309 return true; | 283 return true; |
| 310 } | 284 } |
| 311 default: | 285 default: |
| 312 ASSERT_NOT_REACHED(); | 286 ASSERT_NOT_REACHED(); |
| 313 }; | 287 }; |
| 314 return false; | 288 return false; |
| 315 } | 289 } |
| 316 | 290 |
| 291 bool CompositorAnimationsImpl::convertTimingForCompositor(const Timing& timing, CompositorTiming& out) | |
| 292 { | |
| 293 timing.assertValid(); | |
| 294 // FIXME: Shouldn't this be asserted in timing.assertValid? | |
|
Steve Block
2013/11/13 23:17:01
Good question. It should always be true right now,
mithro-old
2013/11/14 02:11:46
Done.
| |
| 295 ASSERT(timing.timingFunction); | |
| 296 | |
| 297 // FIXME: Support positive startDelay | |
| 298 if (timing.startDelay > 0.0) | |
| 299 return false; | |
| 300 | |
| 301 // All fill modes are supported (the calling code handles them). | |
| 302 | |
| 303 // FIXME: Support non-zero iteration start. | |
| 304 if (timing.iterationStart != 0.0) | |
|
Steve Block
2013/11/13 23:17:01
if (timing.iterationStart)
Ugly I know, but that'
mithro-old
2013/11/14 02:11:46
Done.
Normally the style checker picks this up, w
| |
| 305 return false; | |
| 306 | |
| 307 // FIXME: Compositor only supports finite, integer iteration counts. | |
| 308 if (!std::isfinite(timing.iterationCount) || (std::floor(timing.iterationCou nt) != timing.iterationCount)) | |
| 309 return false; | |
| 310 | |
| 311 if (!timing.iterationDuration) | |
| 312 return false; | |
| 313 | |
| 314 if (timing.playbackRate <= 0) | |
|
Steve Block
2013/11/13 23:17:01
Why doesn't this one get a FIXME?
mithro-old
2013/11/14 02:11:46
Does now! Changed to == 1.0 as Doug requested.
| |
| 315 return false; | |
| 316 | |
| 317 // All directions are supported. | |
| 318 out.reverse = (timing.direction == Timing::PlaybackDirectionReverse | |
| 319 || timing.direction == Timing::PlaybackDirectionAlternateReverse); | |
| 320 out.alternate = (timing.direction == Timing::PlaybackDirectionAlternate | |
| 321 || timing.direction == Timing::PlaybackDirectionAlternateReverse); | |
|
Steve Block
2013/11/13 23:17:01
Move these down to line 334 where they're used, to
mithro-old
2013/11/14 02:11:46
Done.
| |
| 322 | |
| 323 out.scaledDuration = timing.iterationDuration / timing.playbackRate; | |
|
dstockwell
2013/11/13 11:54:04
I think we should just bail out if playbackRate is
mithro-old
2013/11/13 12:01:43
Trivial to implement, but can remove it you want.
dstockwell
2013/11/13 23:29:31
Remove it.
mithro-old
2013/11/14 02:11:46
Done.
| |
| 324 ASSERT(out.scaledDuration > 0); | |
| 325 | |
| 326 double scaledStartDelay = timing.startDelay / timing.playbackRate; | |
| 327 ASSERT(scaledStartDelay <= 0); | |
| 328 | |
| 329 int pastIterations = std::floor(std::abs(scaledStartDelay) / out.scaledDurat ion); | |
|
dstockwell
2013/11/13 11:54:04
It's not really clear to me what's going on here.
mithro-old
2013/11/13 12:01:43
When start delay greater than iteration duration m
dstockwell
2013/11/13 23:29:31
OK. Then I think something like skippedIterations
mithro-old
2013/11/14 02:11:46
Done.
| |
| 330 ASSERT(pastIterations >= 0); | |
| 331 if (pastIterations >= timing.iterationCount) | |
| 332 return false; | |
| 333 | |
| 334 if (out.alternate && (pastIterations % 2)) | |
| 335 out.reverse = !out.reverse; | |
| 336 | |
| 337 out.adjustedIterationCount = std::floor(timing.iterationCount) - pastIterati ons; | |
| 338 ASSERT(out.adjustedIterationCount > 0); | |
|
Steve Block
2013/11/13 23:17:01
What if timing.iterationCount is zero?
For exampl
dstockwell
2013/11/13 23:29:31
Right, bail out if iteration count is 0.
mithro-old
2013/11/14 02:11:46
Actually we'd bail at line 331, in the zero case s
Steve Block
2013/11/14 02:28:08
Sounds good. This will be required once we allow p
| |
| 339 | |
| 340 out.scaledTimeOffset = scaledStartDelay + pastIterations * out.scaledDuratio n; | |
| 341 ASSERT(out.scaledTimeOffset <= 0); | |
| 342 return true; | |
| 343 } | |
| 317 | 344 |
| 318 namespace { | 345 namespace { |
| 319 | 346 |
| 320 template<typename PlatformAnimationKeyframeType> | 347 template<typename PlatformAnimationKeyframeType> |
| 321 static PassOwnPtr<PlatformAnimationKeyframeType> createPlatformKeyframe(double o ffset, const AnimatableValue&) | 348 static PassOwnPtr<PlatformAnimationKeyframeType> createPlatformKeyframe(double o ffset, const AnimatableValue&) |
| 322 { | 349 { |
| 323 // Only the specialized versions of this templated function (found in | 350 // Only the specialized versions of this templated function (found in |
| 324 // the cpp file) should ever be called. | 351 // the cpp file) should ever be called. |
| 325 // FIXME: COMPILE_ASSERT(false, CompositorAnimationsNonSpecializedCreateKeyf rameShouldNeverBeUsed); | 352 // FIXME: COMPILE_ASSERT(false, CompositorAnimationsNonSpecializedCreateKeyf rameShouldNeverBeUsed); |
| 326 ASSERT_NOT_REACHED(); | 353 ASSERT_NOT_REACHED(); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 400 switch (timingFunction.type()) { | 427 switch (timingFunction.type()) { |
| 401 case TimingFunction::LinearFunction: | 428 case TimingFunction::LinearFunction: |
| 402 case TimingFunction::CubicBezierFunction: | 429 case TimingFunction::CubicBezierFunction: |
| 403 keyframeTimingFunction = &timingFunction; | 430 keyframeTimingFunction = &timingFunction; |
| 404 break; | 431 break; |
| 405 | 432 |
| 406 case TimingFunction::ChainedFunction: { | 433 case TimingFunction::ChainedFunction: { |
| 407 const ChainedTimingFunction* chained = static_cast<const Chained TimingFunction*>(&timingFunction); | 434 const ChainedTimingFunction* chained = static_cast<const Chained TimingFunction*>(&timingFunction); |
| 408 // ChainedTimingFunction criteria was checked in isCandidate, | 435 // ChainedTimingFunction criteria was checked in isCandidate, |
| 409 // assert it is valid. | 436 // assert it is valid. |
| 410 ASSERT(values.size() == chained->m_segments.size()+1); | 437 ASSERT(values.size() == chained->m_segments.size() + 1); |
| 411 ASSERT(values[i].first == chained->m_segments[i].m_min); | 438 ASSERT(values[i].first == chained->m_segments[i].m_min); |
| 412 | 439 |
| 413 keyframeTimingFunction = chained->m_segments[i].m_timingFunction .get(); | 440 keyframeTimingFunction = chained->m_segments[i].m_timingFunction .get(); |
| 414 break; | 441 break; |
| 415 } | 442 } |
| 416 case TimingFunction::StepsFunction: | 443 case TimingFunction::StepsFunction: |
| 417 default: | 444 default: |
| 418 ASSERT_NOT_REACHED(); | 445 ASSERT_NOT_REACHED(); |
| 419 } | 446 } |
| 420 } | 447 } |
| 421 | 448 |
| 422 ASSERT(!values[i].second->dependsOnUnderlyingValue()); | 449 ASSERT(!values[i].second->dependsOnUnderlyingValue()); |
| 423 RefPtr<AnimatableValue> value = values[i].second->compositeOnto(0); | 450 RefPtr<AnimatableValue> value = values[i].second->compositeOnto(0); |
| 424 OwnPtr<PlatformAnimationKeyframeType> keyframe = createPlatformKeyframe< PlatformAnimationKeyframeType>(values[i].first, *value.get()); | 451 OwnPtr<PlatformAnimationKeyframeType> keyframe = createPlatformKeyframe< PlatformAnimationKeyframeType>(values[i].first, *value.get()); |
| 425 addKeyframeWithTimingFunction(curve, *keyframe.get(), keyframeTimingFunc tion); | 452 addKeyframeWithTimingFunction(curve, *keyframe.get(), keyframeTimingFunc tion); |
| 426 } | 453 } |
| 427 } | 454 } |
| 428 | 455 |
| 429 void CompositorAnimationsImpl::getCompositorAnimations( | 456 void CompositorAnimationsImpl::getCompositorAnimations( |
| 430 const Timing& timing, const KeyframeAnimationEffect& effect, Vector<OwnPtr<b link::WebAnimation> >& animations) | 457 const Timing& timing, const KeyframeAnimationEffect& effect, Vector<OwnPtr<b link::WebAnimation> >& animations) |
| 431 { | 458 { |
| 432 | 459 CompositorTiming compositorTiming; |
| 433 bool reverse = (timing.direction == Timing::PlaybackDirectionReverse | 460 bool timingValid = convertTimingForCompositor(timing, compositorTiming); |
| 434 || timing.direction == Timing::PlaybackDirectionAlternateReverse); | 461 ASSERT(timingValid); |
|
Steve Block
2013/11/13 23:17:01
I think this will need to be an ASSERT_UNUSED for
mithro-old
2013/11/14 02:11:46
Done.
| |
| 435 | 462 |
| 436 RefPtr<TimingFunction> timingFunction = timing.timingFunction; | 463 RefPtr<TimingFunction> timingFunction = timing.timingFunction; |
| 437 if (reverse) { | 464 if (compositorTiming.reverse) |
| 438 timingFunction = CompositorAnimationsTimingFunctionReverser::reverse(tim ingFunction.get()); | 465 timingFunction = CompositorAnimationsTimingFunctionReverser::reverse(tim ingFunction.get()); |
|
dstockwell
2013/11/13 23:29:31
Hmm, why do we need to reverse the timing function
dstockwell
2013/11/13 23:41:05
Probably because reverse isn't passed through. Som
Steve Block
2013/11/13 23:56:23
That's my understanding too. The compositor interf
mithro-old
2013/11/14 02:11:46
Correct. If we could just pass reverse, life would
mithro-old
2013/11/14 02:11:46
Correct.
mithro-old
2013/11/14 02:11:46
Because it's not passed to the compositor.
To sim
| |
| 439 } | |
| 440 | 466 |
| 441 OwnPtr<Vector<CSSPropertyID> > properties = CompositorAnimationsKeyframeEffe ctHelper::getProperties(&effect); | 467 OwnPtr<Vector<CSSPropertyID> > properties = CompositorAnimationsKeyframeEffe ctHelper::getProperties(&effect); |
| 442 for (size_t i = 0; i < properties->size(); i++) { | 468 for (size_t i = 0; i < properties->size(); i++) { |
| 443 double iterationDuration = timing.iterationDuration / timing.playbackRat e; | |
| 444 | |
| 445 double zero = timing.startDelay / timing.playbackRate; | |
| 446 double keyframeZero = std::max(0.0, zero); | |
| 447 | 469 |
| 448 OwnPtr<CompositorAnimationsKeyframeEffectHelper::KeyframeValues> values = CompositorAnimationsKeyframeEffectHelper::getKeyframeValuesForProperty( | 470 OwnPtr<CompositorAnimationsKeyframeEffectHelper::KeyframeValues> values = CompositorAnimationsKeyframeEffectHelper::getKeyframeValuesForProperty( |
| 449 &effect, properties->at(i), keyframeZero, iterationDuration, reverse ); | 471 &effect, properties->at(i), compositorTiming.scaledDuration, composi torTiming.reverse); |
| 450 | 472 |
| 451 blink::WebAnimation::TargetProperty targetProperty; | 473 blink::WebAnimation::TargetProperty targetProperty; |
| 452 OwnPtr<blink::WebAnimationCurve> curve; | 474 OwnPtr<blink::WebAnimationCurve> curve; |
| 453 switch (properties->at(i)) { | 475 switch (properties->at(i)) { |
| 454 case CSSPropertyOpacity: { | 476 case CSSPropertyOpacity: { |
| 455 targetProperty = blink::WebAnimation::TargetPropertyOpacity; | 477 targetProperty = blink::WebAnimation::TargetPropertyOpacity; |
| 456 | 478 |
| 457 OwnPtr<blink::WebFloatAnimationCurve> floatCurve = adoptPtr(blink::P latform::current()->compositorSupport()->createFloatAnimationCurve()); | 479 OwnPtr<blink::WebFloatAnimationCurve> floatCurve = adoptPtr(blink::P latform::current()->compositorSupport()->createFloatAnimationCurve()); |
| 458 addKeyframesToCurve<blink::WebFloatAnimationCurve, blink::WebFloatKe yframe>(*floatCurve.get(), *values.get(), *timingFunction.get()); | 480 addKeyframesToCurve<blink::WebFloatAnimationCurve, blink::WebFloatKe yframe>(*floatCurve.get(), *values.get(), *timingFunction.get()); |
| 459 curve = floatCurve.release(); | 481 curve = floatCurve.release(); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 472 } | 494 } |
| 473 default: | 495 default: |
| 474 ASSERT_NOT_REACHED(); | 496 ASSERT_NOT_REACHED(); |
| 475 continue; | 497 continue; |
| 476 } | 498 } |
| 477 ASSERT(curve.get()); | 499 ASSERT(curve.get()); |
| 478 | 500 |
| 479 OwnPtr<blink::WebAnimation> animation = adoptPtr( | 501 OwnPtr<blink::WebAnimation> animation = adoptPtr( |
| 480 blink::Platform::current()->compositorSupport()->createAnimation(*cu rve, targetProperty)); | 502 blink::Platform::current()->compositorSupport()->createAnimation(*cu rve, targetProperty)); |
| 481 | 503 |
| 482 ASSERT(std::floor(timing.iterationCount) == timing.iterationCount); | 504 animation->setIterations(compositorTiming.adjustedIterationCount); |
| 483 ASSERT(std::isfinite(timing.iterationCount)); | 505 animation->setTimeOffset(compositorTiming.scaledTimeOffset); |
| 484 double iterationCount = std::floor(timing.iterationCount); | 506 animation->setAlternatesDirection(compositorTiming.alternate); |
| 485 if (zero < 0) { | |
| 486 int pastIterations = std::floor(std::abs(zero) / iterationDuration); | |
| 487 | |
| 488 iterationCount = iterationCount - pastIterations; | |
| 489 animation->setTimeOffset(zero + pastIterations * iterationDuration); | |
| 490 } | |
| 491 animation->setIterations(iterationCount); | |
| 492 | |
| 493 // PlaybackDirection direction | |
| 494 animation->setAlternatesDirection( | |
| 495 timing.direction == Timing::PlaybackDirectionAlternate || timing.dir ection == Timing::PlaybackDirectionAlternateReverse); | |
| 496 | 507 |
| 497 animations.append(animation.release()); | 508 animations.append(animation.release()); |
| 498 } | 509 } |
| 499 } | 510 } |
| 500 | 511 |
| 501 } // namespace WebCore | 512 } // namespace WebCore |
| OLD | NEW |