1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef FLUTTER_SHELL_COMMON_VSYNC_WAITER_H_
6#define FLUTTER_SHELL_COMMON_VSYNC_WAITER_H_
7
8#include <functional>
9#include <memory>
10#include <mutex>
11#include <unordered_map>
12
13#include "flutter/common/task_runners.h"
14#include "flutter/flow/frame_timings.h"
15#include "flutter/fml/time/time_point.h"
16
17namespace flutter {
18
19/// Abstract Base Class that represents a platform specific mechanism for
20/// getting callbacks when a vsync event happens.
21class VsyncWaiter : public std::enable_shared_from_this<VsyncWaiter> {
22 public:
23 using Callback = std::function<void(std::unique_ptr<FrameTimingsRecorder>)>;
24
25 virtual ~VsyncWaiter();
26
27 void AsyncWaitForVsync(const Callback& callback);
28
29 /// Add a secondary callback for key |id| for the next vsync.
30 ///
31 /// See also |PointerDataDispatcher::ScheduleSecondaryVsyncCallback| and
32 /// |Animator::ScheduleMaybeClearTraceFlowIds|.
33 void ScheduleSecondaryCallback(uintptr_t id, const fml::closure& callback);
34
35 protected:
36 // On some backends, the |FireCallback| needs to be made from a static C
37 // method.
38 friend class VsyncWaiterAndroid;
39 friend class VsyncWaiterEmbedder;
40
41 const TaskRunners task_runners_;
42
43 explicit VsyncWaiter(const TaskRunners& task_runners);
44
45 // There are two distinct situations where VsyncWaiter wishes to awaken at
46 // the next vsync. Although the functionality can be the same, the intent is
47 // different, therefore it makes sense to have a method for each intent.
48
49 // The intent of AwaitVSync() is that the Animator wishes to produce a frame.
50 // The underlying implementation can choose to be aware of this intent when
51 // it comes to implementing backpressure and other scheduling invariants.
52 //
53 // Implementations are meant to override this method and arm their vsync
54 // latches when in response to this invocation. On vsync, they are meant to
55 // invoke the |FireCallback| method once (and only once) with the appropriate
56 // arguments. This method should not block the current thread.
57 virtual void AwaitVSync() = 0;
58
59 // The intent of AwaitVSyncForSecondaryCallback() is simply to wake up at the
60 // next vsync.
61 //
62 // Because there is no association with frame scheduling, underlying
63 // implementations do not need to worry about maintaining invariants or
64 // backpressure. The default implementation is to simply follow the same logic
65 // as AwaitVSync().
66 virtual void AwaitVSyncForSecondaryCallback() { AwaitVSync(); }
67
68 // Schedules the callback on the UI task runner. Needs to be invoked as close
69 // to the `frame_start_time` as possible.
70 void FireCallback(fml::TimePoint frame_start_time,
71 fml::TimePoint frame_target_time,
72 bool pause_secondary_tasks = true);
73
74 private:
75 std::mutex callback_mutex_;
76 Callback callback_;
77 std::unordered_map<uintptr_t, fml::closure> secondary_callbacks_;
78
79 void PauseDartMicroTasks();
80 static void ResumeDartMicroTasks(fml::TaskQueueId ui_task_queue_id);
81
82 FML_DISALLOW_COPY_AND_ASSIGN(VsyncWaiter);
83};
84
85} // namespace flutter
86
87#endif // FLUTTER_SHELL_COMMON_VSYNC_WAITER_H_
88

source code of flutter_engine/flutter/shell/common/vsync_waiter.h