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 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 166 default: | 166 default: |
| 167 return false; | 167 return false; |
| 168 } | 168 } |
| 169 } | 169 } |
| 170 } | 170 } |
| 171 | 171 |
| 172 CompositorAnimationsImpl::CompositorTiming out; | 172 CompositorAnimationsImpl::CompositorTiming out; |
| 173 if (!CompositorAnimationsImpl::convertTimingForCompositor(timing, 0, out, pl ayerPlaybackRate)) | 173 if (!CompositorAnimationsImpl::convertTimingForCompositor(timing, 0, out, pl ayerPlaybackRate)) |
| 174 return false; | 174 return false; |
| 175 | 175 |
| 176 if (timing.timingFunction->type() != TimingFunction::LinearFunction) { | 176 if (timing.timingFunction->type() == TimingFunction::CubicBezierFunction) { |
| 177 // Checks the of size of KeyframeVector instead of PropertySpecificKeyfr ameVector. | 177 // FIXME: Fix compositor timing functions to accept inputs outside of |
|
dstockwell
2015/01/05 23:13:24
Does this fixme apply to line 187? Should be moved
loyso (OOO)
2015/01/06 00:45:29
It's related to the whole block. See my comment be
| |
| 178 // [0,1]. | |
| 179 const CubicBezierTimingFunction& cubic = toCubicBezierTimingFunction(*ti ming.timingFunction); | |
| 178 const KeyframeVector& keyframes = keyframeEffect.getFrames(); | 180 const KeyframeVector& keyframes = keyframeEffect.getFrames(); |
| 179 if (keyframes.size() == 2 && keyframes.first()->easing().type() == Timin gFunction::LinearFunction) | 181 double startRange = 0; |
|
dstockwell
2015/01/05 23:13:24
start/end should be min/max
loyso (OOO)
2015/01/06 00:45:29
Agreed. In fact, this code is deleted in the upcom
| |
| 180 return true; | 182 double endRange = 1; |
| 183 cubic.range(&startRange, &endRange); | |
| 181 | 184 |
| 182 // FIXME: Support non-linear timing functions in the compositor for | 185 ASSERT(keyframes.size() >= 2); |
| 183 // more than two keyframes. | 186 if ((startRange < 0 || endRange > 1) && (keyframes.first()->easing().typ e() != TimingFunction::LinearFunction || keyframes[keyframes.size() - 2]->easing ().type() != TimingFunction::LinearFunction)) |
|
dstockwell
2015/01/05 23:13:24
Can you add a comment to explain this? If it's rel
loyso (OOO)
2015/01/06 00:45:29
Yes, this whole block is related to FIXME from abo
dstockwell
2015/01/06 03:33:49
Ahh, yes makes sense.
| |
| 184 return false; | 187 return false; |
| 185 } | 188 } |
| 186 | 189 |
| 187 return true; | 190 return true; |
| 188 } | 191 } |
| 189 | 192 |
| 190 bool CompositorAnimations::canStartAnimationOnCompositor(const Element& element) | 193 bool CompositorAnimations::canStartAnimationOnCompositor(const Element& element) |
| 191 { | 194 { |
| 192 return element.renderer() && element.renderer()->compositingState() == Paint sIntoOwnBacking; | 195 return element.renderer() && element.renderer()->compositingState() == Paint sIntoOwnBacking; |
| 193 } | 196 } |
| 194 | 197 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 270 out.scaledTimeOffset = -timing.startDelay + timeOffset; | 273 out.scaledTimeOffset = -timing.startDelay + timeOffset; |
| 271 out.playbackRate = timing.playbackRate * playerPlaybackRate; | 274 out.playbackRate = timing.playbackRate * playerPlaybackRate; |
| 272 out.fillMode = timing.fillMode == Timing::FillModeAuto ? Timing::FillModeNon e : timing.fillMode; | 275 out.fillMode = timing.fillMode == Timing::FillModeAuto ? Timing::FillModeNon e : timing.fillMode; |
| 273 out.iterationStart = timing.iterationStart; | 276 out.iterationStart = timing.iterationStart; |
| 274 out.assertValid(); | 277 out.assertValid(); |
| 275 return true; | 278 return true; |
| 276 } | 279 } |
| 277 | 280 |
| 278 namespace { | 281 namespace { |
| 279 | 282 |
| 283 void getCubicBezierTimingFunctionParameters(const TimingFunction& timingFunction , bool& outCustom, | |
| 284 WebCompositorAnimationCurve::TimingFunctionType& outEaseSubType, | |
| 285 double& outX1, double& outY1, double& outX2, double& outY2) | |
| 286 { | |
| 287 const CubicBezierTimingFunction& cubic = toCubicBezierTimingFunction(timingF unction); | |
| 288 outCustom = false; | |
| 289 | |
| 290 switch (cubic.subType()) { | |
| 291 case CubicBezierTimingFunction::Ease: | |
| 292 outEaseSubType = WebCompositorAnimationCurve::TimingFunctionTypeEase; | |
| 293 break; | |
| 294 case CubicBezierTimingFunction::EaseIn: | |
| 295 outEaseSubType = WebCompositorAnimationCurve::TimingFunctionTypeEaseIn; | |
| 296 break; | |
| 297 case CubicBezierTimingFunction::EaseOut: | |
| 298 outEaseSubType = WebCompositorAnimationCurve::TimingFunctionTypeEaseOut; | |
| 299 break; | |
| 300 case CubicBezierTimingFunction::EaseInOut: | |
| 301 outEaseSubType = WebCompositorAnimationCurve::TimingFunctionTypeEaseInOu t; | |
| 302 break; | |
| 303 case CubicBezierTimingFunction::Custom: | |
| 304 outCustom = true; | |
| 305 outX1 = cubic.x1(); | |
| 306 outY1 = cubic.y1(); | |
| 307 outX2 = cubic.x2(); | |
| 308 outY2 = cubic.y2(); | |
| 309 break; | |
| 310 default: | |
| 311 ASSERT_NOT_REACHED(); | |
| 312 } | |
| 313 } | |
| 314 | |
| 315 void getStepsTimingFunctionParameters(const TimingFunction& timingFunction, int& outSteps, float& outStepsStartOffset) | |
| 316 { | |
| 317 const StepsTimingFunction& steps = toStepsTimingFunction(timingFunction); | |
| 318 | |
| 319 outSteps = steps.numberOfSteps(); | |
| 320 switch (steps.stepAtPosition()) { | |
| 321 case StepsTimingFunction::Start: | |
| 322 outStepsStartOffset = 1; | |
| 323 break; | |
| 324 case StepsTimingFunction::Middle: | |
| 325 outStepsStartOffset = 0.5; | |
| 326 break; | |
| 327 case StepsTimingFunction::End: | |
| 328 outStepsStartOffset = 0; | |
| 329 break; | |
| 330 default: | |
| 331 ASSERT_NOT_REACHED(); | |
| 332 } | |
| 333 } | |
| 334 | |
| 280 template<typename PlatformAnimationCurveType, typename PlatformAnimationKeyframe Type> | 335 template<typename PlatformAnimationCurveType, typename PlatformAnimationKeyframe Type> |
| 281 void addKeyframeWithTimingFunction(PlatformAnimationCurveType& curve, const Plat formAnimationKeyframeType& keyframe, const TimingFunction* timingFunction) | 336 void addKeyframeWithTimingFunction(PlatformAnimationCurveType& curve, const Plat formAnimationKeyframeType& keyframe, const TimingFunction* timingFunction) |
| 282 { | 337 { |
| 283 if (!timingFunction) { | 338 if (!timingFunction) { |
| 284 curve.add(keyframe); | 339 curve.add(keyframe); |
| 285 return; | 340 return; |
| 286 } | 341 } |
| 287 | 342 |
| 288 switch (timingFunction->type()) { | 343 switch (timingFunction->type()) { |
| 289 case TimingFunction::LinearFunction: | 344 case TimingFunction::LinearFunction: |
| 290 curve.add(keyframe, WebCompositorAnimationCurve::TimingFunctionTypeLinea r); | 345 curve.add(keyframe, WebCompositorAnimationCurve::TimingFunctionTypeLinea r); |
| 291 return; | 346 break; |
| 292 | 347 |
| 293 case TimingFunction::CubicBezierFunction: { | 348 case TimingFunction::CubicBezierFunction: { |
| 294 const CubicBezierTimingFunction* cubic = toCubicBezierTimingFunction(tim ingFunction); | 349 bool custom; |
| 350 WebCompositorAnimationCurve::TimingFunctionType easeSubType; | |
| 351 double x1, y1; | |
| 352 double x2, y2; | |
| 353 getCubicBezierTimingFunctionParameters(*timingFunction, custom, easeSubT ype, x1, y1, x2, y2); | |
| 295 | 354 |
| 296 if (cubic->subType() == CubicBezierTimingFunction::Custom) { | 355 if (custom) |
| 297 curve.add(keyframe, cubic->x1(), cubic->y1(), cubic->x2(), cubic->y2 ()); | 356 curve.add(keyframe, x1, y1, x2, y2); |
| 298 } else { | 357 else |
| 358 curve.add(keyframe, easeSubType); | |
|
dstockwell
2015/01/05 23:13:24
Why not always specify the control points?
loyso (OOO)
2015/01/06 00:45:29
That would be a lose of information. At this stage
| |
| 359 break; | |
| 360 } | |
| 299 | 361 |
| 300 WebCompositorAnimationCurve::TimingFunctionType easeType; | 362 case TimingFunction::StepsFunction: { |
| 301 switch (cubic->subType()) { | 363 int steps; |
| 302 case CubicBezierTimingFunction::Ease: | 364 float stepsStartOffset; |
| 303 easeType = WebCompositorAnimationCurve::TimingFunctionTypeEase; | 365 getStepsTimingFunctionParameters(*timingFunction, steps, stepsStartOffse t); |
| 304 break; | |
| 305 case CubicBezierTimingFunction::EaseIn: | |
| 306 easeType = WebCompositorAnimationCurve::TimingFunctionTypeEaseIn ; | |
| 307 break; | |
| 308 case CubicBezierTimingFunction::EaseOut: | |
| 309 easeType = WebCompositorAnimationCurve::TimingFunctionTypeEaseOu t; | |
| 310 break; | |
| 311 case CubicBezierTimingFunction::EaseInOut: | |
| 312 easeType = WebCompositorAnimationCurve::TimingFunctionTypeEaseIn Out; | |
| 313 break; | |
| 314 | 366 |
| 315 // Custom Bezier are handled seperately. | 367 curve.add(keyframe, steps, stepsStartOffset); |
| 316 case CubicBezierTimingFunction::Custom: | 368 break; |
| 317 default: | 369 } |
| 318 ASSERT_NOT_REACHED(); | |
| 319 return; | |
| 320 } | |
| 321 | 370 |
| 322 curve.add(keyframe, easeType); | 371 default: |
| 323 } | 372 ASSERT_NOT_REACHED(); |
| 373 } | |
| 374 } | |
| 375 | |
| 376 template <typename PlatformAnimationCurveType> | |
| 377 void setTimingFunctionOnCurve(PlatformAnimationCurveType& curve, TimingFunction* timingFunction) | |
| 378 { | |
| 379 if (!timingFunction) { | |
| 380 curve.setLinearTimingFunction(); | |
| 324 return; | 381 return; |
| 325 } | 382 } |
| 326 | 383 |
| 327 case TimingFunction::StepsFunction: | 384 switch (timingFunction->type()) { |
| 328 const StepsTimingFunction* steps = toStepsTimingFunction(timingFunction) ; | 385 case TimingFunction::LinearFunction: |
| 386 curve.setLinearTimingFunction(); | |
| 387 break; | |
| 329 | 388 |
| 389 case TimingFunction::CubicBezierFunction: { | |
| 390 bool custom; | |
| 391 WebCompositorAnimationCurve::TimingFunctionType easeSubType; | |
| 392 double x1, y1; | |
| 393 double x2, y2; | |
| 394 getCubicBezierTimingFunctionParameters(*timingFunction, custom, easeSubT ype, x1, y1, x2, y2); | |
| 395 | |
| 396 if (custom) | |
| 397 curve.setCubicBezierTimingFunction(x1, y1, x2, y2); | |
| 398 else | |
| 399 curve.setCubicBezierTimingFunction(easeSubType); | |
| 400 break; | |
| 401 } | |
| 402 | |
| 403 case TimingFunction::StepsFunction: { | |
| 404 int steps; | |
| 330 float stepsStartOffset; | 405 float stepsStartOffset; |
| 331 switch (steps->stepAtPosition()) { | 406 getStepsTimingFunctionParameters(*timingFunction, steps, stepsStartOffse t); |
| 332 case StepsTimingFunction::Start: | 407 |
| 333 stepsStartOffset = 1; | 408 curve.setStepsTimingFunction(steps, stepsStartOffset); |
| 334 break; | 409 break; |
| 335 case StepsTimingFunction::Middle: | 410 } |
| 336 stepsStartOffset = 0.5; | 411 |
| 337 break; | 412 default: |
| 338 case StepsTimingFunction::End: | 413 ASSERT_NOT_REACHED(); |
| 339 stepsStartOffset = 0; | |
| 340 break; | |
| 341 default: | |
| 342 ASSERT_NOT_REACHED(); | |
| 343 return; | |
| 344 } | |
| 345 curve.add(keyframe, steps->numberOfSteps(), stepsStartOffset); | |
| 346 return; | |
| 347 } | 414 } |
| 348 } | 415 } |
| 349 | 416 |
| 350 } // namespace anoymous | 417 } // namespace anoymous |
| 351 | 418 |
| 352 void CompositorAnimationsImpl::addKeyframesToCurve(WebCompositorAnimationCurve& curve, const PropertySpecificKeyframeVector& keyframes, const Timing& timing) | 419 void CompositorAnimationsImpl::addKeyframesToCurve(WebCompositorAnimationCurve& curve, const PropertySpecificKeyframeVector& keyframes, const Timing& timing) |
| 353 { | 420 { |
| 354 auto* lastKeyframe = keyframes.last().get(); | 421 auto* lastKeyframe = keyframes.last().get(); |
| 355 for (const auto& keyframe : keyframes) { | 422 for (const auto& keyframe : keyframes) { |
| 356 const TimingFunction* keyframeTimingFunction = 0; | 423 const TimingFunction* keyframeTimingFunction = 0; |
| 357 if (keyframe != lastKeyframe) { // Ignore timing function of last frame. | 424 if (keyframe != lastKeyframe) { // Ignore timing function of last frame. |
| 358 if (keyframes.size() == 2 && keyframes.first()->easing().type() == T imingFunction::LinearFunction) | 425 keyframeTimingFunction = &keyframe->easing(); |
| 359 keyframeTimingFunction = timing.timingFunction.get(); | |
| 360 else | |
| 361 keyframeTimingFunction = &keyframe->easing(); | |
| 362 } | 426 } |
| 363 | 427 |
| 364 // FIXME: This relies on StringKeyframes being eagerly evaluated, which will | 428 // FIXME: This relies on StringKeyframes being eagerly evaluated, which will |
| 365 // not happen eventually. Instead we should extract the CSSValue here | 429 // not happen eventually. Instead we should extract the CSSValue here |
| 366 // and convert using another set of toAnimatableXXXOperations functions. | 430 // and convert using another set of toAnimatableXXXOperations functions. |
| 367 const AnimatableValue* value = keyframe->getAnimatableValue().get(); | 431 const AnimatableValue* value = keyframe->getAnimatableValue().get(); |
| 368 | 432 |
| 369 switch (curve.type()) { | 433 switch (curve.type()) { |
| 370 case WebCompositorAnimationCurve::AnimationCurveTypeFilter: { | 434 case WebCompositorAnimationCurve::AnimationCurveTypeFilter: { |
| 371 OwnPtr<WebFilterOperations> ops = adoptPtr(Platform::current()->comp ositorSupport()->createFilterOperations()); | 435 OwnPtr<WebFilterOperations> ops = adoptPtr(Platform::current()->comp ositorSupport()->createFilterOperations()); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 411 getKeyframeValuesForProperty(&effect, property, compositorTiming.scaledD uration, values); | 475 getKeyframeValuesForProperty(&effect, property, compositorTiming.scaledD uration, values); |
| 412 | 476 |
| 413 WebCompositorAnimation::TargetProperty targetProperty; | 477 WebCompositorAnimation::TargetProperty targetProperty; |
| 414 OwnPtr<WebCompositorAnimationCurve> curve; | 478 OwnPtr<WebCompositorAnimationCurve> curve; |
| 415 switch (property) { | 479 switch (property) { |
| 416 case CSSPropertyOpacity: { | 480 case CSSPropertyOpacity: { |
| 417 targetProperty = WebCompositorAnimation::TargetPropertyOpacity; | 481 targetProperty = WebCompositorAnimation::TargetPropertyOpacity; |
| 418 | 482 |
| 419 WebFloatAnimationCurve* floatCurve = Platform::current()->compositor Support()->createFloatAnimationCurve(); | 483 WebFloatAnimationCurve* floatCurve = Platform::current()->compositor Support()->createFloatAnimationCurve(); |
| 420 addKeyframesToCurve(*floatCurve, values, timing); | 484 addKeyframesToCurve(*floatCurve, values, timing); |
| 485 setTimingFunctionOnCurve(*floatCurve, timing.timingFunction.get()); | |
| 421 curve = adoptPtr(floatCurve); | 486 curve = adoptPtr(floatCurve); |
| 422 break; | 487 break; |
| 423 } | 488 } |
| 424 case CSSPropertyWebkitFilter: { | 489 case CSSPropertyWebkitFilter: { |
| 425 targetProperty = WebCompositorAnimation::TargetPropertyFilter; | 490 targetProperty = WebCompositorAnimation::TargetPropertyFilter; |
| 426 WebFilterAnimationCurve* filterCurve = Platform::current()->composit orSupport()->createFilterAnimationCurve(); | 491 WebFilterAnimationCurve* filterCurve = Platform::current()->composit orSupport()->createFilterAnimationCurve(); |
| 427 addKeyframesToCurve(*filterCurve, values, timing); | 492 addKeyframesToCurve(*filterCurve, values, timing); |
| 493 setTimingFunctionOnCurve(*filterCurve, timing.timingFunction.get()); | |
| 428 curve = adoptPtr(filterCurve); | 494 curve = adoptPtr(filterCurve); |
| 429 break; | 495 break; |
| 430 } | 496 } |
| 431 case CSSPropertyTransform: { | 497 case CSSPropertyTransform: { |
| 432 targetProperty = WebCompositorAnimation::TargetPropertyTransform; | 498 targetProperty = WebCompositorAnimation::TargetPropertyTransform; |
| 433 WebTransformAnimationCurve* transformCurve = Platform::current()->co mpositorSupport()->createTransformAnimationCurve(); | 499 WebTransformAnimationCurve* transformCurve = Platform::current()->co mpositorSupport()->createTransformAnimationCurve(); |
| 434 addKeyframesToCurve(*transformCurve, values, timing); | 500 addKeyframesToCurve(*transformCurve, values, timing); |
| 501 setTimingFunctionOnCurve(*transformCurve, timing.timingFunction.get( )); | |
| 435 curve = adoptPtr(transformCurve); | 502 curve = adoptPtr(transformCurve); |
| 436 break; | 503 break; |
| 437 } | 504 } |
| 438 default: | 505 default: |
| 439 ASSERT_NOT_REACHED(); | 506 ASSERT_NOT_REACHED(); |
| 440 continue; | 507 continue; |
| 441 } | 508 } |
| 442 ASSERT(curve.get()); | 509 ASSERT(curve.get()); |
| 443 | 510 |
| 444 OwnPtr<WebCompositorAnimation> animation = adoptPtr(Platform::current()- >compositorSupport()->createAnimation(*curve, targetProperty, group, 0)); | 511 OwnPtr<WebCompositorAnimation> animation = adoptPtr(Platform::current()- >compositorSupport()->createAnimation(*curve, targetProperty, group, 0)); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 483 break; | 550 break; |
| 484 default: | 551 default: |
| 485 ASSERT_NOT_REACHED(); | 552 ASSERT_NOT_REACHED(); |
| 486 } | 553 } |
| 487 animations.append(animation.release()); | 554 animations.append(animation.release()); |
| 488 } | 555 } |
| 489 ASSERT(!animations.isEmpty()); | 556 ASSERT(!animations.isEmpty()); |
| 490 } | 557 } |
| 491 | 558 |
| 492 } // namespace blink | 559 } // namespace blink |
| OLD | NEW |