Flutter Engine
flutter::Animator Class Referencefinal

#include <animator.h>

Classes

class  Delegate
 

Public Member Functions

 Animator (Delegate &delegate, TaskRunners task_runners, std::unique_ptr< VsyncWaiter > waiter)
 
 ~Animator ()
 
void RequestFrame (bool regenerate_layer_tree=true)
 
void Render (std::unique_ptr< flutter::LayerTree > layer_tree)
 
void ScheduleSecondaryVsyncCallback (const fml::closure &callback)
 Schedule a secondary callback to be executed right after the main VsyncWaiter::AsyncWaitForVsync callback (which is added by Animator::RequestFrame). More...
 
void Start ()
 
void Stop ()
 
void SetDimensionChangePending ()
 
void EnqueueTraceFlowId (uint64_t trace_flow_id)
 

Friends

class testing::ShellTest
 

Detailed Description

Executor of animations.

In conjunction with the |VsyncWaiter| it allows callers (typically Dart code) to schedule work that ends up generating a |LayerTree|.

Definition at line 29 of file animator.h.

Constructor & Destructor Documentation

◆ Animator()

flutter::Animator::Animator ( Delegate delegate,
TaskRunners  task_runners,
std::unique_ptr< VsyncWaiter waiter 
)

Definition at line 22 of file animator.cc.

References ~Animator().

25  : delegate_(delegate),
26  task_runners_(std::move(task_runners)),
27  waiter_(std::move(waiter)),
28  last_frame_begin_time_(),
29  last_vsync_start_time_(),
30  last_frame_target_time_(),
31  dart_frame_deadline_(0),
32 #if FLUTTER_SHELL_ENABLE_METAL
33  layer_tree_pipeline_(fml::MakeRefCounted<LayerTreePipeline>(2)),
34 #else // FLUTTER_SHELL_ENABLE_METAL
35  // TODO(dnfield): We should remove this logic and set the pipeline depth
36  // back to 2 in this case. See
37  // https://github.com/flutter/engine/pull/9132 for discussion.
38  layer_tree_pipeline_(fml::MakeRefCounted<LayerTreePipeline>(
39  task_runners.GetPlatformTaskRunner() ==
40  task_runners.GetRasterTaskRunner()
41  ? 1
42  : 2)),
43 #endif // FLUTTER_SHELL_ENABLE_METAL
44  pending_frame_semaphore_(1),
45  frame_number_(1),
46  paused_(false),
47  regenerate_layer_tree_(false),
48  frame_scheduled_(false),
49  notify_idle_task_id_(0),
50  dimension_change_pending_(false),
51  weak_factory_(this) {
52 }

◆ ~Animator()

flutter::Animator::~Animator ( )
default

Referenced by Animator().

Member Function Documentation

◆ EnqueueTraceFlowId()

void flutter::Animator::EnqueueTraceFlowId ( uint64_t  trace_flow_id)

Definition at line 75 of file animator.cc.

References flutter::TaskRunners::GetUITaskRunner(), and fml::TaskRunner::RunNowOrPostTask().

75  {
77  task_runners_.GetUITaskRunner(),
78  [self = weak_factory_.GetWeakPtr(), trace_flow_id] {
79  if (!self) {
80  return;
81  }
82  self->trace_flow_ids_.push_back(trace_flow_id);
83  });
84 }
static void RunNowOrPostTask(fml::RefPtr< fml::TaskRunner > runner, const fml::closure &task)
Definition: task_runner.cc:55
fml::RefPtr< fml::TaskRunner > GetUITaskRunner() const
Definition: task_runners.cc:34

◆ Render()

void flutter::Animator::Render ( std::unique_ptr< flutter::LayerTree layer_tree)

Definition at line 175 of file animator.cc.

References flutter::Pipeline< R >::ProducerContinuation::Complete(), FML_DLOG, flutter::Animator::Delegate::OnAnimatorDraw(), flutter::Animator::Delegate::OnAnimatorDrawLastLayerTree(), and fml::Semaphore::Signal().

175  {
176  if (dimension_change_pending_ &&
177  layer_tree->frame_size() != last_layer_tree_size_) {
178  dimension_change_pending_ = false;
179  }
180  last_layer_tree_size_ = layer_tree->frame_size();
181 
182  // Note the frame time for instrumentation.
183  layer_tree->RecordBuildTime(last_vsync_start_time_, last_frame_begin_time_,
184  last_frame_target_time_);
185 
186  // Commit the pending continuation.
187  bool result = producer_continuation_.Complete(std::move(layer_tree));
188  if (!result) {
189  FML_DLOG(INFO) << "No pending continuation to commit";
190  }
191 
192  delegate_.OnAnimatorDraw(layer_tree_pipeline_, last_frame_target_time_);
193 }
virtual void OnAnimatorDraw(fml::RefPtr< Pipeline< flutter::LayerTree >> pipeline, fml::TimePoint frame_target_time)=0
bool Complete(ResourcePtr resource)
Definition: pipeline.h:63
#define FML_DLOG(severity)
Definition: logging.h:85

◆ RequestFrame()

void flutter::Animator::RequestFrame ( bool  regenerate_layer_tree = true)

Definition at line 204 of file animator.cc.

References flutter::TaskRunners::GetUITaskRunner(), flutter::Animator::Delegate::OnAnimatorNotifyIdle(), fml::TaskRunner::PostTask(), TRACE_EVENT_ASYNC_BEGIN0, and fml::Semaphore::TryWait().

Referenced by flutter::FxlToDartOrEarlier(), and Start().

204  {
205  if (regenerate_layer_tree) {
206  regenerate_layer_tree_ = true;
207  }
208  if (paused_ && !dimension_change_pending_) {
209  return;
210  }
211 
212  if (!pending_frame_semaphore_.TryWait()) {
213  // Multiple calls to Animator::RequestFrame will still result in a
214  // single request to the VsyncWaiter.
215  return;
216  }
217 
218  // The AwaitVSync is going to call us back at the next VSync. However, we want
219  // to be reasonably certain that the UI thread is not in the middle of a
220  // particularly expensive callout. We post the AwaitVSync to run right after
221  // an idle. This does NOT provide a guarantee that the UI thread has not
222  // started an expensive operation right after posting this message however.
223  // To support that, we need edge triggered wakes on VSync.
224 
225  task_runners_.GetUITaskRunner()->PostTask([self = weak_factory_.GetWeakPtr(),
226  frame_number = frame_number_]() {
227  if (!self) {
228  return;
229  }
230  TRACE_EVENT_ASYNC_BEGIN0("flutter", "Frame Request Pending", frame_number);
231  self->AwaitVSync();
232  });
233  frame_scheduled_ = true;
234 }
virtual void PostTask(const fml::closure &task)
Definition: task_runner.cc:24
#define TRACE_EVENT_ASYNC_BEGIN0(category_group, name, id)
Definition: trace_event.h:89
fml::RefPtr< fml::TaskRunner > GetUITaskRunner() const
Definition: task_runners.cc:34
bool TryWait()
Definition: semaphore.cc:157

◆ ScheduleSecondaryVsyncCallback()

void flutter::Animator::ScheduleSecondaryVsyncCallback ( const fml::closure callback)

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.

See also
PointerDataDispatcher::ScheduleSecondaryVsyncCallback.

Definition at line 252 of file animator.cc.

252  {
253  waiter_->ScheduleSecondaryCallback(callback);
254 }

◆ SetDimensionChangePending()

void flutter::Animator::SetDimensionChangePending ( )

Definition at line 71 of file animator.cc.

71  {
72  dimension_change_pending_ = true;
73 }

◆ Start()

void flutter::Animator::Start ( )

Definition at line 60 of file animator.cc.

References RequestFrame().

60  {
61  if (!paused_) {
62  return;
63  }
64 
65  paused_ = false;
66  RequestFrame();
67 }
void RequestFrame(bool regenerate_layer_tree=true)
Definition: animator.cc:204

◆ Stop()

void flutter::Animator::Stop ( )

Definition at line 56 of file animator.cc.

56  {
57  paused_ = true;
58 }

Friends And Related Function Documentation

◆ testing::ShellTest

friend class testing::ShellTest
friend

Definition at line 116 of file animator.h.


The documentation for this class was generated from the following files: