1 /*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #pragma once
18
19 #include <cstdint>
20 #include <future>
21 #include <type_traits>
22 #include <utility>
23
24 #include <android-base/thread_annotations.h>
25 #include <android/gui/IDisplayEventConnection.h>
26 #include <private/gui/BitTube.h>
27 #include <utils/Looper.h>
28 #include <utils/Timers.h>
29
30 #include "EventThread.h"
31 #include "TracedOrdinal.h"
32 #include "VSyncDispatch.h"
33
34 namespace android {
35
36 struct ICompositor {
37 virtual bool commit(nsecs_t frameTime, int64_t vsyncId, nsecs_t expectedVsyncTime) = 0;
38 virtual void composite(nsecs_t frameTime, int64_t vsyncId) = 0;
39 virtual void sample() = 0;
40
41 protected:
42 ~ICompositor() = default;
43 };
44
45 template <typename F>
46 class Task : public MessageHandler {
47 template <typename G>
48 friend auto makeTask(G&&);
49
Task(F && f)50 explicit Task(F&& f) : mTask(std::move(f)) {}
51
handleMessage(const Message &)52 void handleMessage(const Message&) override { mTask(); }
53
54 using T = std::invoke_result_t<F>;
55 std::packaged_task<T()> mTask;
56 };
57
58 template <typename F>
makeTask(F && f)59 inline auto makeTask(F&& f) {
60 sp<Task<F>> task = new Task<F>(std::move(f));
61 return std::make_pair(task, task->mTask.get_future());
62 }
63
64 class MessageQueue {
65 public:
66 virtual ~MessageQueue() = default;
67
68 virtual void initVsync(scheduler::VSyncDispatch&, frametimeline::TokenManager&,
69 std::chrono::nanoseconds workDuration) = 0;
70 virtual void setDuration(std::chrono::nanoseconds workDuration) = 0;
71 virtual void setInjector(sp<EventThreadConnection>) = 0;
72 virtual void waitMessage() = 0;
73 virtual void postMessage(sp<MessageHandler>&&) = 0;
74 virtual void scheduleFrame() = 0;
75
76 using Clock = std::chrono::steady_clock;
77 virtual std::optional<Clock::time_point> getScheduledFrameTime() const = 0;
78 };
79
80 namespace impl {
81
82 class MessageQueue : public android::MessageQueue {
83 protected:
84 class Handler : public MessageHandler {
85 MessageQueue& mQueue;
86 std::atomic_bool mFramePending = false;
87 std::atomic<int64_t> mVsyncId = 0;
88 std::atomic<nsecs_t> mExpectedVsyncTime = 0;
89
90 public:
Handler(MessageQueue & queue)91 explicit Handler(MessageQueue& queue) : mQueue(queue) {}
92 void handleMessage(const Message& message) override;
93
94 bool isFramePending() const;
95
96 virtual void dispatchFrame(int64_t vsyncId, nsecs_t expectedVsyncTime);
97 };
98
99 friend class Handler;
100
101 // For tests.
102 MessageQueue(ICompositor&, sp<Handler>);
103
104 void vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, nsecs_t readyTime);
105
106 private:
107 ICompositor& mCompositor;
108 const sp<Looper> mLooper;
109 const sp<Handler> mHandler;
110
111 struct Vsync {
112 frametimeline::TokenManager* tokenManager = nullptr;
113 std::unique_ptr<scheduler::VSyncCallbackRegistration> registration;
114
115 mutable std::mutex mutex;
116 TracedOrdinal<std::chrono::nanoseconds> workDuration
117 GUARDED_BY(mutex) = {"VsyncWorkDuration-sf", std::chrono::nanoseconds(0)};
GUARDED_BYVsync118 std::chrono::nanoseconds lastCallbackTime GUARDED_BY(mutex) = std::chrono::nanoseconds{0};
119 std::optional<nsecs_t> scheduledFrameTime GUARDED_BY(mutex);
120 TracedOrdinal<int> value = {"VSYNC-sf", 0};
121 };
122
123 struct Injector {
124 gui::BitTube tube;
125 std::mutex mutex;
126 sp<EventThreadConnection> connection GUARDED_BY(mutex);
127 };
128
129 Vsync mVsync;
130 Injector mInjector;
131
132 void injectorCallback();
133
134 public:
135 explicit MessageQueue(ICompositor&);
136
137 void initVsync(scheduler::VSyncDispatch&, frametimeline::TokenManager&,
138 std::chrono::nanoseconds workDuration) override;
139 void setDuration(std::chrono::nanoseconds workDuration) override;
140 void setInjector(sp<EventThreadConnection>) override;
141
142 void waitMessage() override;
143 void postMessage(sp<MessageHandler>&&) override;
144
145 void scheduleFrame() override;
146
147 std::optional<Clock::time_point> getScheduledFrameTime() const override;
148 };
149
150 } // namespace impl
151 } // namespace android
152