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 21 matching lines...) Expand all Loading... | |
| 32 #include "core/animation/AnimationPlayer.h" | 32 #include "core/animation/AnimationPlayer.h" |
| 33 | 33 |
| 34 #include "core/animation/Animation.h" | 34 #include "core/animation/Animation.h" |
| 35 #include "core/animation/AnimationTimeline.h" | 35 #include "core/animation/AnimationTimeline.h" |
| 36 #include "core/dom/Document.h" | 36 #include "core/dom/Document.h" |
| 37 #include "core/dom/ExceptionCode.h" | 37 #include "core/dom/ExceptionCode.h" |
| 38 #include "core/events/AnimationPlayerEvent.h" | 38 #include "core/events/AnimationPlayerEvent.h" |
| 39 #include "core/frame/UseCounter.h" | 39 #include "core/frame/UseCounter.h" |
| 40 #include "core/inspector/InspectorInstrumentation.h" | 40 #include "core/inspector/InspectorInstrumentation.h" |
| 41 #include "core/inspector/InspectorTraceEvents.h" | 41 #include "core/inspector/InspectorTraceEvents.h" |
| 42 #include "platform/RuntimeEnabledFeatures.h" | |
| 42 #include "platform/TraceEvent.h" | 43 #include "platform/TraceEvent.h" |
| 44 #include "public/platform/Platform.h" | |
| 45 #include "public/platform/WebCompositorAnimationPlayer.h" | |
| 46 #include "public/platform/WebCompositorSupport.h" | |
| 43 #include "wtf/MathExtras.h" | 47 #include "wtf/MathExtras.h" |
| 44 | 48 |
| 45 namespace blink { | 49 namespace blink { |
| 46 | 50 |
| 47 namespace { | 51 namespace { |
| 48 | 52 |
| 49 static unsigned nextSequenceNumber() | 53 static unsigned nextSequenceNumber() |
| 50 { | 54 { |
| 51 static unsigned next = 0; | 55 static unsigned next = 0; |
| 52 return ++next; | 56 return ++next; |
| 53 } | 57 } |
| 54 | 58 |
| 55 } | 59 } |
| 56 | 60 |
| 57 PassRefPtrWillBeRawPtr<AnimationPlayer> AnimationPlayer::create(AnimationNode* s ource, AnimationTimeline* timeline) | 61 PassRefPtrWillBeRawPtr<AnimationPlayer> AnimationPlayer::create(AnimationNode* s ource, AnimationTimeline* timeline) |
| 58 { | 62 { |
| 59 if (!timeline) { | 63 if (!timeline) { |
| 60 // FIXME: Support creating players without a timeline. | 64 // FIXME: Support creating players without a timeline. |
| 61 return nullptr; | 65 return nullptr; |
| 62 } | 66 } |
| 63 | 67 |
| 64 RefPtrWillBeRawPtr<AnimationPlayer> player = adoptRefWillBeNoop(new Animatio nPlayer(timeline->document()->contextDocument().get(), *timeline, source)); | 68 RefPtrWillBeRawPtr<AnimationPlayer> player = adoptRefWillBeNoop(new Animatio nPlayer(timeline->document()->contextDocument().get(), *timeline, source)); |
| 65 player->suspendIfNeeded(); | 69 player->suspendIfNeeded(); |
| 66 | 70 |
| 67 if (timeline) { | 71 if (timeline) { |
| 68 timeline->playerAttached(*player); | 72 timeline->playerAttached(*player); |
| 73 player->attachCompositorTimeline(); | |
| 69 } | 74 } |
| 70 | 75 |
| 71 return player.release(); | 76 return player.release(); |
| 72 } | 77 } |
| 73 | 78 |
| 74 AnimationPlayer::AnimationPlayer(ExecutionContext* executionContext, AnimationTi meline& timeline, AnimationNode* content) | 79 AnimationPlayer::AnimationPlayer(ExecutionContext* executionContext, AnimationTi meline& timeline, AnimationNode* content) |
| 75 : ActiveDOMObject(executionContext) | 80 : ActiveDOMObject(executionContext) |
| 76 , m_playState(Idle) | 81 , m_playState(Idle) |
| 77 , m_playbackRate(1) | 82 , m_playbackRate(1) |
| 78 , m_startTime(nullValue()) | 83 , m_startTime(nullValue()) |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 101 } | 106 } |
| 102 | 107 |
| 103 AnimationPlayer::~AnimationPlayer() | 108 AnimationPlayer::~AnimationPlayer() |
| 104 { | 109 { |
| 105 #if !ENABLE(OILPAN) | 110 #if !ENABLE(OILPAN) |
| 106 if (m_content) | 111 if (m_content) |
| 107 m_content->detach(); | 112 m_content->detach(); |
| 108 if (m_timeline) | 113 if (m_timeline) |
| 109 m_timeline->playerDestroyed(this); | 114 m_timeline->playerDestroyed(this); |
| 110 #endif | 115 #endif |
| 116 | |
| 117 detachCompositedLayers(); | |
| 118 destroyCompositorPlayer(); | |
| 111 } | 119 } |
| 112 | 120 |
| 113 double AnimationPlayer::sourceEnd() const | 121 double AnimationPlayer::sourceEnd() const |
| 114 { | 122 { |
| 115 return m_content ? m_content->endTimeInternal() : 0; | 123 return m_content ? m_content->endTimeInternal() : 0; |
| 116 } | 124 } |
| 117 | 125 |
| 118 bool AnimationPlayer::limited(double currentTime) const | 126 bool AnimationPlayer::limited(double currentTime) const |
| 119 { | 127 { |
| 120 return (m_playbackRate < 0 && currentTime <= 0) || (m_playbackRate > 0 && cu rrentTime >= sourceEnd()); | 128 return (m_playbackRate < 0 && currentTime <= 0) || (m_playbackRate > 0 && cu rrentTime >= sourceEnd()); |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 259 | 267 |
| 260 ASSERT(!m_compositorState || !std::isnan(m_compositorState->startTime)); | 268 ASSERT(!m_compositorState || !std::isnan(m_compositorState->startTime)); |
| 261 | 269 |
| 262 if (!shouldStart) { | 270 if (!shouldStart) { |
| 263 m_currentTimePending = false; | 271 m_currentTimePending = false; |
| 264 } | 272 } |
| 265 | 273 |
| 266 if (shouldStart) { | 274 if (shouldStart) { |
| 267 m_compositorGroup = compositorGroup; | 275 m_compositorGroup = compositorGroup; |
| 268 if (startOnCompositor) { | 276 if (startOnCompositor) { |
| 277 if (isCandidateForAnimationOnCompositor()) { | |
| 278 createCompositorPlayer(); | |
|
dstockwell
2015/03/31 02:13:01
It now seems like createCompositorPlayer/attachCom
loyso (OOO)
2015/03/31 02:30:27
Not always. AnimationPlayer::setSource uses attach
loyso (OOO)
2015/04/01 00:14:26
Done.
| |
| 279 attachCompositedLayers(); | |
| 280 } | |
| 281 | |
| 269 if (maybeStartAnimationOnCompositor()) | 282 if (maybeStartAnimationOnCompositor()) |
| 270 m_compositorState = adoptPtr(new CompositorState(*this)); | 283 m_compositorState = adoptPtr(new CompositorState(*this)); |
| 271 else | 284 else |
| 272 cancelIncompatibleAnimationsOnCompositor(); | 285 cancelIncompatibleAnimationsOnCompositor(); |
| 273 } | 286 } |
| 274 } | 287 } |
| 275 } | 288 } |
| 276 | 289 |
| 277 void AnimationPlayer::postCommit(double timelineTime) | 290 void AnimationPlayer::postCommit(double timelineTime) |
| 278 { | 291 { |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 421 } | 434 } |
| 422 | 435 |
| 423 void AnimationPlayer::setSource(AnimationNode* newSource) | 436 void AnimationPlayer::setSource(AnimationNode* newSource) |
| 424 { | 437 { |
| 425 if (m_content == newSource) | 438 if (m_content == newSource) |
| 426 return; | 439 return; |
| 427 | 440 |
| 428 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand, SetCompositorP endingWithSourceChanged); | 441 PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand, SetCompositorP endingWithSourceChanged); |
| 429 | 442 |
| 430 double storedCurrentTime = currentTimeInternal(); | 443 double storedCurrentTime = currentTimeInternal(); |
| 431 if (m_content) | 444 if (m_content) { |
| 445 detachCompositedLayers(); | |
| 432 m_content->detach(); | 446 m_content->detach(); |
| 447 } | |
| 433 m_content = newSource; | 448 m_content = newSource; |
| 434 if (newSource) { | 449 if (newSource) { |
| 435 // FIXME: This logic needs to be updated once groups are implemented | 450 // FIXME: This logic needs to be updated once groups are implemented |
| 436 if (newSource->player()) { | 451 if (newSource->player()) { |
| 437 newSource->player()->cancel(); | 452 newSource->player()->cancel(); |
| 438 newSource->player()->setSource(0); | 453 newSource->player()->setSource(0); |
| 439 } | 454 } |
| 440 newSource->attach(this); | 455 newSource->attach(this); |
| 456 attachCompositedLayers(); | |
|
dstockwell
2015/03/31 02:13:01
Shouldn't this be removed in favor of the call in
loyso (OOO)
2015/03/31 02:30:27
It's related to the comment above. Don't we call s
dstockwell
2015/03/31 03:27:32
Yes, but it can be called at any time, including b
loyso (OOO)
2015/03/31 04:43:31
Done.
| |
| 441 setOutdated(); | 457 setOutdated(); |
| 442 } | 458 } |
| 443 setCurrentTimeInternal(storedCurrentTime, TimingUpdateOnDemand); | 459 setCurrentTimeInternal(storedCurrentTime, TimingUpdateOnDemand); |
| 444 } | 460 } |
| 445 | 461 |
| 446 const char* AnimationPlayer::playStateString(AnimationPlayState playState) | 462 const char* AnimationPlayer::playStateString(AnimationPlayState playState) |
| 447 { | 463 { |
| 448 switch (playState) { | 464 switch (playState) { |
| 449 case Idle: | 465 case Idle: |
| 450 return "idle"; | 466 return "idle"; |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 658 setCurrentTimeInternal(storedCurrentTime, TimingUpdateOnDemand); | 674 setCurrentTimeInternal(storedCurrentTime, TimingUpdateOnDemand); |
| 659 } | 675 } |
| 660 | 676 |
| 661 void AnimationPlayer::setOutdated() | 677 void AnimationPlayer::setOutdated() |
| 662 { | 678 { |
| 663 m_outdated = true; | 679 m_outdated = true; |
| 664 if (m_timeline) | 680 if (m_timeline) |
| 665 m_timeline->setOutdatedAnimationPlayer(this); | 681 m_timeline->setOutdatedAnimationPlayer(this); |
| 666 } | 682 } |
| 667 | 683 |
| 668 bool AnimationPlayer::canStartAnimationOnCompositor() | 684 bool AnimationPlayer::canStartAnimationOnCompositor() const |
| 669 { | 685 { |
| 670 // FIXME: Timeline playback rates should be compositable | 686 // FIXME: Timeline playback rates should be compositable |
| 671 if (m_playbackRate == 0 || (std::isinf(sourceEnd()) && m_playbackRate < 0) | | (timeline() && timeline()->playbackRate() != 1)) | 687 if (m_playbackRate == 0 || (std::isinf(sourceEnd()) && m_playbackRate < 0) | | (timeline() && timeline()->playbackRate() != 1)) |
| 672 return false; | 688 return false; |
| 673 | 689 |
| 674 return m_timeline && m_content && m_content->isAnimation() && playing(); | 690 return m_timeline && m_content && m_content->isAnimation() && playing(); |
| 675 } | 691 } |
| 676 | 692 |
| 693 bool AnimationPlayer::isCandidateForAnimationOnCompositor() const | |
| 694 { | |
| 695 if (!canStartAnimationOnCompositor()) | |
| 696 return false; | |
| 697 | |
| 698 return toAnimation(m_content.get())->isCandidateForAnimationOnCompositor(m_p laybackRate); | |
| 699 } | |
| 700 | |
| 677 bool AnimationPlayer::maybeStartAnimationOnCompositor() | 701 bool AnimationPlayer::maybeStartAnimationOnCompositor() |
| 678 { | 702 { |
| 679 if (!canStartAnimationOnCompositor()) | 703 if (!canStartAnimationOnCompositor()) |
| 680 return false; | 704 return false; |
| 681 | 705 |
| 682 bool reversed = m_playbackRate < 0; | 706 bool reversed = m_playbackRate < 0; |
| 683 | 707 |
| 684 double startTime = timeline()->zeroTime() + startTimeInternal(); | 708 double startTime = timeline()->zeroTime() + startTimeInternal(); |
| 685 if (reversed) { | 709 if (reversed) { |
| 686 startTime -= sourceEnd() / fabs(m_playbackRate); | 710 startTime -= sourceEnd() / fabs(m_playbackRate); |
| 687 } | 711 } |
| 688 | 712 |
| 689 double timeOffset = 0; | 713 double timeOffset = 0; |
| 690 if (std::isnan(startTime)) { | 714 if (std::isnan(startTime)) { |
| 691 timeOffset = reversed ? sourceEnd() - currentTimeInternal() : currentTim eInternal(); | 715 timeOffset = reversed ? sourceEnd() - currentTimeInternal() : currentTim eInternal(); |
| 692 timeOffset = timeOffset / fabs(m_playbackRate); | 716 timeOffset = timeOffset / fabs(m_playbackRate); |
| 693 } | 717 } |
| 694 ASSERT(m_compositorGroup != 0); | 718 ASSERT(m_compositorGroup != 0); |
| 695 return toAnimation(m_content.get())->maybeStartAnimationOnCompositor(m_compo sitorGroup, startTime, timeOffset, m_playbackRate); | 719 return toAnimation(m_content.get())->maybeStartAnimationOnCompositor(m_compo sitorGroup, startTime, timeOffset, m_playbackRate); |
| 696 } | 720 } |
| 697 | 721 |
| 698 void AnimationPlayer::setCompositorPending(bool sourceChanged) | 722 void AnimationPlayer::setCompositorPending(bool sourceChanged) |
| 699 { | 723 { |
| 700 // FIXME: Animation could notify this directly? | 724 // FIXME: Animation could notify this directly? |
| 701 if (!hasActiveAnimationsOnCompositor()) { | 725 if (!hasActiveAnimationsOnCompositor()) { |
| 726 detachCompositedLayers(); | |
| 727 destroyCompositorPlayer(); | |
| 702 m_compositorState.release(); | 728 m_compositorState.release(); |
| 703 } | 729 } |
| 704 if (sourceChanged && m_compositorState) { | 730 if (sourceChanged && m_compositorState) { |
| 705 m_compositorState->sourceChanged = true; | 731 m_compositorState->sourceChanged = true; |
| 706 } | 732 } |
| 707 if (m_compositorPending || m_isPausedForTesting) { | 733 if (m_compositorPending || m_isPausedForTesting) { |
| 708 return; | 734 return; |
| 709 } | 735 } |
| 710 | 736 |
| 711 if (sourceChanged || !m_compositorState | 737 if (sourceChanged || !m_compositorState |
| 712 || !playing() || m_compositorState->playbackRate != m_playbackRate | 738 || !playing() || m_compositorState->playbackRate != m_playbackRate |
| 713 || m_compositorState->startTime != m_startTime) { | 739 || m_compositorState->startTime != m_startTime) { |
| 714 m_compositorPending = true; | 740 m_compositorPending = true; |
| 715 timeline()->document()->compositorPendingAnimations().add(this); | 741 timeline()->document()->compositorPendingAnimations().add(this); |
| 716 } | 742 } |
| 717 } | 743 } |
| 718 | 744 |
| 719 void AnimationPlayer::cancelAnimationOnCompositor() | 745 void AnimationPlayer::cancelAnimationOnCompositor() |
| 720 { | 746 { |
| 721 if (hasActiveAnimationsOnCompositor()) | 747 if (hasActiveAnimationsOnCompositor()) |
| 722 toAnimation(m_content.get())->cancelAnimationOnCompositor(); | 748 toAnimation(m_content.get())->cancelAnimationOnCompositor(); |
| 749 | |
| 750 detachCompositedLayers(); | |
| 751 destroyCompositorPlayer(); | |
| 723 } | 752 } |
| 724 | 753 |
| 725 void AnimationPlayer::restartAnimationOnCompositor() | 754 void AnimationPlayer::restartAnimationOnCompositor() |
| 726 { | 755 { |
| 727 if (hasActiveAnimationsOnCompositor()) | 756 if (hasActiveAnimationsOnCompositor()) |
| 728 toAnimation(m_content.get())->restartAnimationOnCompositor(); | 757 toAnimation(m_content.get())->restartAnimationOnCompositor(); |
| 729 } | 758 } |
| 730 | 759 |
| 731 void AnimationPlayer::cancelIncompatibleAnimationsOnCompositor() | 760 void AnimationPlayer::cancelIncompatibleAnimationsOnCompositor() |
| 732 { | 761 { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 815 ASSERT(!m_stateIsBeingUpdated); | 844 ASSERT(!m_stateIsBeingUpdated); |
| 816 m_stateIsBeingUpdated = true; | 845 m_stateIsBeingUpdated = true; |
| 817 } | 846 } |
| 818 | 847 |
| 819 void AnimationPlayer::endUpdatingState() | 848 void AnimationPlayer::endUpdatingState() |
| 820 { | 849 { |
| 821 ASSERT(m_stateIsBeingUpdated); | 850 ASSERT(m_stateIsBeingUpdated); |
| 822 m_stateIsBeingUpdated = false; | 851 m_stateIsBeingUpdated = false; |
| 823 } | 852 } |
| 824 | 853 |
| 854 void AnimationPlayer::createCompositorPlayer() | |
| 855 { | |
| 856 if (RuntimeEnabledFeatures::compositorAnimationTimelinesEnabled() && !m_comp ositorPlayer && Platform::current()->compositorSupport()) { | |
| 857 m_compositorPlayer = adoptPtr(Platform::current()->compositorSupport()-> createAnimationPlayer()); | |
| 858 ASSERT(m_compositorPlayer); | |
| 859 m_compositorPlayer->setAnimationDelegate(this); | |
| 860 attachCompositorTimeline(); | |
| 861 } | |
| 862 } | |
| 863 | |
| 864 void AnimationPlayer::destroyCompositorPlayer() | |
| 865 { | |
| 866 if (m_compositorPlayer) { | |
| 867 detachCompositorTimeline(); | |
| 868 m_compositorPlayer->setAnimationDelegate(nullptr); | |
| 869 } | |
| 870 m_compositorPlayer.clear(); | |
| 871 } | |
| 872 | |
| 873 void AnimationPlayer::attachCompositorTimeline() | |
| 874 { | |
| 875 if (m_compositorPlayer) { | |
| 876 WebCompositorAnimationTimeline* timeline = m_timeline ? m_timeline->comp ositorTimeline() : nullptr; | |
| 877 if (timeline) | |
| 878 timeline->playerAttached(*this); | |
| 879 } | |
| 880 } | |
| 881 | |
| 882 void AnimationPlayer::detachCompositorTimeline() | |
| 883 { | |
| 884 if (m_compositorPlayer) { | |
| 885 WebCompositorAnimationTimeline* timeline = m_timeline ? m_timeline->comp ositorTimeline() : nullptr; | |
| 886 if (timeline) | |
| 887 timeline->playerDestroyed(*this); | |
| 888 } | |
| 889 } | |
| 890 | |
| 891 void AnimationPlayer::attachCompositedLayers() | |
| 892 { | |
| 893 if (!RuntimeEnabledFeatures::compositorAnimationTimelinesEnabled() || !m_com positorPlayer) | |
| 894 return; | |
| 895 | |
| 896 ASSERT(m_content); | |
| 897 ASSERT(m_content->isAnimation()); | |
| 898 ASSERT(toAnimation(m_content.get())->canAttachCompositedLayers()); | |
| 899 | |
| 900 toAnimation(m_content.get())->attachCompositedLayers(); | |
| 901 } | |
| 902 | |
| 903 void AnimationPlayer::detachCompositedLayers() | |
| 904 { | |
| 905 if (m_compositorPlayer && m_compositorPlayer->isLayerAttached()) | |
| 906 m_compositorPlayer->detachLayer(); | |
| 907 } | |
| 908 | |
| 909 void AnimationPlayer::notifyAnimationStarted(double monotonicTime, int group) | |
| 910 { | |
| 911 ASSERT(RuntimeEnabledFeatures::compositorAnimationTimelinesEnabled()); | |
| 912 timeline()->document()->compositorPendingAnimations().notifyCompositorAnimat ionStarted(monotonicTime, group); | |
| 913 } | |
| 914 | |
| 825 AnimationPlayer::PlayStateUpdateScope::PlayStateUpdateScope(AnimationPlayer& pla yer, TimingUpdateReason reason, CompositorPendingChange compositorPendingChange) | 915 AnimationPlayer::PlayStateUpdateScope::PlayStateUpdateScope(AnimationPlayer& pla yer, TimingUpdateReason reason, CompositorPendingChange compositorPendingChange) |
| 826 : m_player(player) | 916 : m_player(player) |
| 827 , m_initialPlayState(m_player->playStateInternal()) | 917 , m_initialPlayState(m_player->playStateInternal()) |
| 828 , m_compositorPendingChange(compositorPendingChange) | 918 , m_compositorPendingChange(compositorPendingChange) |
| 829 { | 919 { |
| 830 m_player->beginUpdatingState(); | 920 m_player->beginUpdatingState(); |
| 831 m_player->updateCurrentTimingState(reason); | 921 m_player->updateCurrentTimingState(reason); |
| 832 } | 922 } |
| 833 | 923 |
| 834 AnimationPlayer::PlayStateUpdateScope::~PlayStateUpdateScope() | 924 AnimationPlayer::PlayStateUpdateScope::~PlayStateUpdateScope() |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 928 visitor->trace(m_content); | 1018 visitor->trace(m_content); |
| 929 visitor->trace(m_timeline); | 1019 visitor->trace(m_timeline); |
| 930 visitor->trace(m_pendingFinishedEvent); | 1020 visitor->trace(m_pendingFinishedEvent); |
| 931 visitor->trace(m_finishedPromise); | 1021 visitor->trace(m_finishedPromise); |
| 932 visitor->trace(m_readyPromise); | 1022 visitor->trace(m_readyPromise); |
| 933 EventTargetWithInlineData::trace(visitor); | 1023 EventTargetWithInlineData::trace(visitor); |
| 934 ActiveDOMObject::trace(visitor); | 1024 ActiveDOMObject::trace(visitor); |
| 935 } | 1025 } |
| 936 | 1026 |
| 937 } // namespace | 1027 } // namespace |
| OLD | NEW |