Reviewers: dgozman,
Message:
WIP.
Incomplete tasks:
- Check properly attached to all new incoming frames (and set playback rate
on
them)
- on didCommitLoadForLocalFrame(), clear maps appropriately - this is
causing an
issue at the moment
- Update start times when IAA::setCurrentTime() is called (just need to the
callback)
Description:
Devtools Animations: Support multiple frames in the animation timeline
Currently, the animation timeline only works for animations attached to
the main document frame. This change ensures the inspector agent is properly
attached to all frames within the document. All start times sent to the
front-end are normalised to the monotonic time. As the playback rate or
current time of an animation timeline are manipulated, these monotonic
time values are invalidated. Since these methods are controlled from the
front-end, the normalised start times are updated. This has no visible UI
change.
BUG=466827
Please review this at
https://codereview.chromium.org/1042143005/
Base URL: svn://
svn.chromium.org/blink/trunk
Affected files (+79, -9 lines):
M Source/core/inspector/InspectorAnimationAgent.h
M Source/core/inspector/InspectorAnimationAgent.cpp
M Source/devtools/front_end/elements/AnimationTimeline.js
M Source/devtools/front_end/sdk/AnimationModel.js
M Source/devtools/protocol.json
Index: Source/core/inspector/InspectorAnimationAgent.cpp
diff --git a/Source/core/inspector/InspectorAnimationAgent.cpp
b/Source/core/inspector/InspectorAnimationAgent.cpp
index
7d3068ba83fd43dba20412ccbd001dd69b5cb3bb..67e54adeb094c0d601808e462528ae5c375f4604
100644
--- a/Source/core/inspector/InspectorAnimationAgent.cpp
+++ b/Source/core/inspector/InspectorAnimationAgent.cpp
@@ -162,6 +162,12 @@ static
PassRefPtr<TypeBuilder::Animation::KeyframesRule> buildObjectForAnimation
return keyframesObject.release();
}
+static double normalizedStartTime(AnimationPlayer& player)
+{
+ ASSERT(player.timeline());
+ return player.startTime() / player.timeline()->playbackRate() +
player.timeline()->zeroTime();
+}
+
PassRefPtr<TypeBuilder::Animation::AnimationPlayer>
InspectorAnimationAgent::buildObjectForAnimationPlayer(AnimationPlayer&
player)
{
// Find type of animation
@@ -195,7 +201,7 @@ PassRefPtr<TypeBuilder::Animation::AnimationPlayer>
InspectorAnimationAgent::bui
.setPausedState(player.paused())
.setPlayState(player.playState())
.setPlaybackRate(player.playbackRate())
- .setStartTime(player.startTime())
+ .setStartTime(normalizedStartTime(player))
.setCurrentTime(player.currentTime())
.setSource(animationObject.release())
.setType(animationType);
@@ -230,20 +236,41 @@ void
InspectorAnimationAgent::getAnimationPlayersForNode(ErrorString* errorStrin
void InspectorAnimationAgent::getPlaybackRate(ErrorString*, double*
playbackRate)
{
+ // All timelines should have the same playback rate
*playbackRate =
m_pageAgent->inspectedFrame()->document()->timeline().playbackRate();
}
-void InspectorAnimationAgent::setPlaybackRate(ErrorString*, double
playbackRate)
+void InspectorAnimationAgent::setPlaybackRate(ErrorString*, double
playbackRate,
RefPtr<TypeBuilder::Array<TypeBuilder::Animation::AnimationStartTime>>&
animationStartTimes)
{
for (Frame* frame = m_pageAgent->inspectedFrame(); frame; frame =
frame->tree().traverseNext(m_pageAgent->inspectedFrame())) {
if (frame->isLocalFrame())
toLocalFrame(frame)->document()->timeline().setPlaybackRate(playbackRate);
}
+ animationStartTimes = buildArrayForStartTimes();
+}
+
+void InspectorAnimationAgent::setCurrentTime(ErrorString*, double
normalisedCurrentTime,
RefPtr<TypeBuilder::Array<TypeBuilder::Animation::AnimationStartTime>>&
animationStartTimes)
+{
+ for (Frame* frame = m_pageAgent->inspectedFrame(); frame; frame =
frame->tree().traverseNext(m_pageAgent->inspectedFrame())) {
+ if (frame->isLocalFrame()) {
+ AnimationTimeline& timeline =
toLocalFrame(frame)->document()->timeline();
+ timeline.setCurrentTime((normalisedCurrentTime -
timeline.zeroTime()) * timeline.playbackRate());
+ }
+ }
+ animationStartTimes = buildArrayForStartTimes();
}
-void InspectorAnimationAgent::setCurrentTime(ErrorString*, double
currentTime)
+PassRefPtr<TypeBuilder::Array<TypeBuilder::Animation::AnimationStartTime>>
InspectorAnimationAgent::buildArrayForStartTimes()
{
-
m_pageAgent->inspectedFrame()->document()->timeline().setCurrentTime(currentTime);
+ RefPtr<TypeBuilder::Array<TypeBuilder::Animation::AnimationStartTime>>
animationStartTimes =
TypeBuilder::Array<TypeBuilder::Animation::AnimationStartTime>::create();
+ for (const auto& pair : m_idToAnimationPlayer) {
+ const RefPtr<AnimationPlayer> player = pair.value;
+ RefPtr<TypeBuilder::Animation::AnimationStartTime> startTimeObject
= TypeBuilder::Animation::AnimationStartTime::create()
+ .setId(pair.key)
+ .setStartTime(normalizedStartTime(*player.get()));
+ animationStartTimes->addItem(startTimeObject);
+ }
+ return animationStartTimes.release();
}
void InspectorAnimationAgent::setTiming(ErrorString* errorString, const
String& playerId, double duration, double delay)
Index: Source/core/inspector/InspectorAnimationAgent.h
diff --git a/Source/core/inspector/InspectorAnimationAgent.h
b/Source/core/inspector/InspectorAnimationAgent.h
index
9fc782d2301a7e0a638ac7be91a73ecb88a38663..430bed110b41b353801ab3835210f05e7024a347
100644
--- a/Source/core/inspector/InspectorAnimationAgent.h
+++ b/Source/core/inspector/InspectorAnimationAgent.h
@@ -35,8 +35,8 @@ public:
// Protocol method implementations
virtual void getAnimationPlayersForNode(ErrorString*, int nodeId, bool
includeSubtreeAnimations,
RefPtr<TypeBuilder::Array<TypeBuilder::Animation::AnimationPlayer> >&
animationPlayersArray) override;
virtual void getPlaybackRate(ErrorString*, double* playbackRate)
override;
- virtual void setPlaybackRate(ErrorString*, double playbackRate)
override;
- virtual void setCurrentTime(ErrorString*, double currentTime) override;
+ virtual void setPlaybackRate(ErrorString*, double playbackRate,
RefPtr<TypeBuilder::Array<TypeBuilder::Animation::AnimationStartTime>>&
animationStartTimes) override;
+ virtual void setCurrentTime(ErrorString*, double
normalisedCurrentTime,
RefPtr<TypeBuilder::Array<TypeBuilder::Animation::AnimationStartTime>>&
animationStartTimes) override;
virtual void setTiming(ErrorString*, const String& playerId, double
duration, double delay) override;
// API for InspectorInstrumentation
@@ -59,6 +59,7 @@ private:
PassRefPtr<TypeBuilder::Animation::AnimationPlayer>
buildObjectForAnimationPlayer(AnimationPlayer&);
PassRefPtr<TypeBuilder::Animation::AnimationPlayer>
buildObjectForAnimationPlayer(AnimationPlayer&, AnimationType,
PassRefPtr<TypeBuilder::Animation::KeyframesRule> keyframeRule = nullptr);
PassRefPtr<TypeBuilder::Array<TypeBuilder::Animation::AnimationPlayer>
> buildArrayForAnimationPlayers(Element&, const
WillBeHeapVector<RefPtrWillBeMember<AnimationPlayer> >);
+
PassRefPtr<TypeBuilder::Array<TypeBuilder::Animation::AnimationStartTime>>
buildArrayForStartTimes();
RawPtrWillBeMember<InspectorPageAgent> m_pageAgent;
RawPtrWillBeMember<InspectorDOMAgent> m_domAgent;
Index: Source/devtools/front_end/elements/AnimationTimeline.js
diff --git a/Source/devtools/front_end/elements/AnimationTimeline.js
b/Source/devtools/front_end/elements/AnimationTimeline.js
index
b8c496a74ba361ade64c588bb80aea30271c2c08..0ffba06a68aaf81119f04056c74b913c6db40016
100644
--- a/Source/devtools/front_end/elements/AnimationTimeline.js
+++ b/Source/devtools/front_end/elements/AnimationTimeline.js
@@ -46,7 +46,7 @@ WebInspector.AnimationTimeline.prototype = {
this._animationsPlaybackRate =
WebInspector.AnimationsSidebarPane.GlobalPlaybackRates[event.target.value];
var target = WebInspector.targetManager.mainTarget();
if (target)
-
target.animationAgent().setPlaybackRate(this._animationsPlaybackRate);
+
target.animationAgent().setPlaybackRate(this._animationsPlaybackRate,
this._updateStartTimes.bind(this));
this._playbackLabel.textContent = this._animationsPlaybackRate
+ "x";
WebInspector.userMetrics.AnimationsPlaybackRateChanged.record();
if (this._scrubberPlayer)
@@ -83,6 +83,25 @@ WebInspector.AnimationTimeline.prototype = {
return container;
},
+ /**
+ * @param {?Protocol.Error} error
+ * @param {!Array.<!AnimationAgent.AnimationStartTime>} startTimes
+ */
+ _updateStartTimes: function(error, startTimes)
+ {
+ if (error)
+ return;
+
+ delete this._startTime;
+ for (var player in startTimes) {
+ var animation = this._animationsMap.get(
player.id);
+ console.assert(animation);
+ animation.updateStartTime(player.startTime);
+ if (!this._startTime || player.startTime < this._startTime)
+ this._startTime = player.startTime;
+ }
+ },
+
_updateAnimationsPlaybackRate: function()
{
/**
Index: Source/devtools/front_end/sdk/AnimationModel.js
diff --git a/Source/devtools/front_end/sdk/AnimationModel.js
b/Source/devtools/front_end/sdk/AnimationModel.js
index
573293b402253abe935d0204af9832f2782d23e9..89e066f349b2eddfee87a10a3f947473d72ea66c
100644
--- a/Source/devtools/front_end/sdk/AnimationModel.js
+++ b/Source/devtools/front_end/sdk/AnimationModel.js
@@ -159,7 +159,15 @@ WebInspector.AnimationModel.AnimationPlayer.prototype
= {
*/
startTime: function()
{
- return this._payload.startTime;
+ return this._startTime === undefined ? this._payload.startTime :
this._startTime;
+ },
+
+ /**
+ * @param {number} startTime
+ */
+ updateStartTime: function(startTime)
+ {
+ this._startTime = startTime;
},
/**
Index: Source/devtools/protocol.json
diff --git a/Source/devtools/protocol.json b/Source/devtools/protocol.json
index
92bb2d92a9e9099cb327e4d55c9e51894ad32ced..f91508c7632dee990fa36d761b4d8506e0ebbba8
100644
--- a/Source/devtools/protocol.json
+++ b/Source/devtools/protocol.json
@@ -4871,6 +4871,15 @@
{ "name": "easing", "type": "string", "description": "<code>AnimationNode</code>'s
timing function." }
],
"description": "Keyframe Style"
+ },
+ {
+ "id": "AnimationStartTime",
+ "type": "object",
+ "properties": [
+
{ "name": "id", "type": "string", "description": "<code>AnimationPlayer</code>'s
id." },
+
{ "name": "startTime", "type": "number", "description": "Updated normalized
<code>AnimationPlayer</code>'s start time." }
+ ],
+ "description": "Map from animation id to animation start
time"
}
],
"commands": [
@@ -4902,12 +4911,18 @@
"parameters": [
{ "name": "playbackRate", "type": "number", "description": "Playback rate
for animations on page" }
],
+ "returns": [
+
{ "name": "animationStartTimes", "type": "array", "items":
{ "$ref": "AnimationStartTime" }, "description": "List of updated animation
start times." }
+ ],
"description": "Sets the playback rate of the document
timeline."
},
{
"name": "setCurrentTime",
"parameters": [
-
{ "name": "currentTime", "type": "number", "description": "Current time for
the page animation timeline" }
+
{ "name": "normalisedCurrentTime", "type": "number", "description": "Current
time for the page animation timeline" }
+ ],
+ "returns": [
+
{ "name": "animationStartTimes", "type": "array", "items":
{ "$ref": "AnimationStartTime" }, "description": "List of updated animation
start times." }
],
"description": "Sets the current time of the document
timeline."
},