This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Repository navigation
Expand file tree
/
Copy pathanimator.h
More file actions
137 lines (107 loc) · 4.88 KB
/
Copy pathanimator.h
File metadata and controls
137 lines (107 loc) · 4.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_SHELL_COMMON_ANIMATOR_H_
#define FLUTTER_SHELL_COMMON_ANIMATOR_H_
#include <deque>
#include "flutter/common/task_runners.h"
#include "flutter/flow/frame_timings.h"
#include "flutter/fml/memory/ref_ptr.h"
#include "flutter/fml/memory/weak_ptr.h"
#include "flutter/fml/synchronization/semaphore.h"
#include "flutter/fml/time/time_point.h"
#include "flutter/shell/common/pipeline.h"
#include "flutter/shell/common/rasterizer.h"
#include "flutter/shell/common/vsync_waiter.h"
namespace flutter {
namespace testing {
class ShellTest;
}
/// Executor of animations.
///
/// In conjunction with the |VsyncWaiter| it allows callers (typically Dart
/// code) to schedule work that ends up generating a |LayerTree|.
class Animator final {
public:
class Delegate {
public:
virtual void OnAnimatorBeginFrame(fml::TimePoint frame_target_time,
uint64_t frame_number) = 0;
virtual void OnAnimatorNotifyIdle(fml::TimeDelta deadline) = 0;
virtual void OnAnimatorUpdateLatestFrameTargetTime(
fml::TimePoint frame_target_time) = 0;
virtual void OnAnimatorDraw(std::shared_ptr<FramePipeline> pipeline) = 0;
virtual void OnAnimatorDrawLastLayerTrees(
std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder) = 0;
};
Animator(Delegate& delegate,
const TaskRunners& task_runners,
std::unique_ptr<VsyncWaiter> waiter);
~Animator();
void RequestFrame(bool regenerate_layer_trees = true);
//--------------------------------------------------------------------------
/// @brief Tells the Animator that this frame needs to render another view.
///
/// This method must be called during a vsync callback, or
/// technically, between Animator::BeginFrame and Animator::EndFrame
/// (both private methods). Otherwise, an assertion will be
/// triggered.
///
void Render(int64_t view_id,
std::unique_ptr<flutter::LayerTree> layer_tree,
float device_pixel_ratio);
const std::weak_ptr<VsyncWaiter> GetVsyncWaiter() const;
//--------------------------------------------------------------------------
/// @brief Schedule a secondary callback to be executed right after the
/// main `VsyncWaiter::AsyncWaitForVsync` callback (which is added
/// by `Animator::RequestFrame`).
///
/// Like the callback in `AsyncWaitForVsync`, this callback is
/// only scheduled to be called once, and it's supposed to be
/// called in the UI thread. If there is no AsyncWaitForVsync
/// callback (`Animator::RequestFrame` is not called), this
/// secondary callback will still be executed at vsync.
///
/// This callback is used to provide the vsync signal needed by
/// `SmoothPointerDataDispatcher`, and for our own flow events.
///
/// @see `PointerDataDispatcher::ScheduleSecondaryVsyncCallback`.
void ScheduleSecondaryVsyncCallback(uintptr_t id,
const fml::closure& callback);
// Enqueue |trace_flow_id| into |trace_flow_ids_|. The flow event will be
// ended at either the next frame, or the next vsync interval with no active
// rendering.
void EnqueueTraceFlowId(uint64_t trace_flow_id);
private:
// Animator's work during a vsync is split into two methods, BeginFrame and
// EndFrame. The two methods should be called synchronously back-to-back to
// avoid being interrupted by a regular vsync. The reason to split them is to
// allow ShellTest::PumpOneFrame to insert a Render in between.
void BeginFrame(std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder);
void EndFrame();
bool CanReuseLastLayerTrees();
void DrawLastLayerTrees(
std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder);
void AwaitVSync();
// Clear |trace_flow_ids_| if |frame_scheduled_| is false.
void ScheduleMaybeClearTraceFlowIds();
Delegate& delegate_;
TaskRunners task_runners_;
std::shared_ptr<VsyncWaiter> waiter_;
std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder_;
std::vector<std::unique_ptr<LayerTreeTask>> layer_trees_tasks_;
uint64_t frame_request_number_ = 1;
fml::TimeDelta dart_frame_deadline_;
std::shared_ptr<FramePipeline> layer_tree_pipeline_;
fml::Semaphore pending_frame_semaphore_;
FramePipeline::ProducerContinuation producer_continuation_;
bool regenerate_layer_trees_ = false;
bool frame_scheduled_ = false;
std::deque<uint64_t> trace_flow_ids_;
bool has_rendered_ = false;
fml::WeakPtrFactory<Animator> weak_factory_;
friend class testing::ShellTest;
FML_DISALLOW_COPY_AND_ASSIGN(Animator);
};
} // namespace flutter
#endif // FLUTTER_SHELL_COMMON_ANIMATOR_H_