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/StrongPointer.h>
29 #include <utils/Timers.h>
30 
31 #include <scheduler/Time.h>
32 #include <scheduler/VsyncId.h>
33 
34 #include "EventThread.h"
35 #include "TracedOrdinal.h"
36 #include "VSyncDispatch.h"
37 
38 namespace android {
39 
40 struct ICompositor;
41 
42 template <typename F>
43 class Task : public MessageHandler {
44     template <typename G>
45     friend auto makeTask(G&&);
46 
47     template <typename... Args>
48     friend sp<Task<F>> sp<Task<F>>::make(Args&&... args);
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 = sp<Task<F>>::make(std::forward<F>(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 initVsyncInternal(std::shared_ptr<scheduler::VSyncDispatch>,
69                                    frametimeline::TokenManager&,
70                                    std::chrono::nanoseconds workDuration) = 0;
71     virtual void destroyVsync() = 0;
72     virtual void setDuration(std::chrono::nanoseconds workDuration) = 0;
73     virtual void waitMessage() = 0;
74     virtual void postMessage(sp<MessageHandler>&&) = 0;
75     virtual void postMessageDelayed(sp<MessageHandler>&&, nsecs_t uptimeDelay) = 0;
76     virtual void scheduleConfigure() = 0;
77     virtual void scheduleFrame() = 0;
78 
79     virtual std::optional<scheduler::ScheduleResult> getScheduledFrameResult() const = 0;
80 };
81 
82 namespace impl {
83 
84 class MessageQueue : public android::MessageQueue {
85 protected:
86     class Handler : public MessageHandler {
87         MessageQueue& mQueue;
88         std::atomic_bool mFramePending = false;
89 
90         std::atomic<VsyncId> mVsyncId;
91         std::atomic<TimePoint> mExpectedVsyncTime;
92 
93     public:
Handler(MessageQueue & queue)94         explicit Handler(MessageQueue& queue) : mQueue(queue) {}
95         void handleMessage(const Message& message) override;
96 
getExpectedVsyncTime()97         virtual TimePoint getExpectedVsyncTime() const { return mExpectedVsyncTime.load(); }
98 
99         virtual bool isFramePending() const;
100 
101         virtual void dispatchFrame(VsyncId, TimePoint expectedVsyncTime);
102     };
103 
104     friend class Handler;
105 
106     // For tests.
107     MessageQueue(ICompositor&, sp<Handler>);
108 
109     void vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, nsecs_t readyTime);
110 
111     void onNewVsyncSchedule(std::shared_ptr<scheduler::VSyncDispatch>) EXCLUDES(mVsync.mutex);
112 
113 private:
114     virtual void onFrameSignal(ICompositor&, VsyncId, TimePoint expectedVsyncTime) = 0;
115 
116     ICompositor& mCompositor;
117     const sp<Looper> mLooper;
118     const sp<Handler> mHandler;
119 
120     struct Vsync {
121         frametimeline::TokenManager* tokenManager = nullptr;
122 
123         mutable std::mutex mutex;
124         std::unique_ptr<scheduler::VSyncCallbackRegistration> registration GUARDED_BY(mutex);
125         TracedOrdinal<std::chrono::nanoseconds> workDuration
126                 GUARDED_BY(mutex) = {"VsyncWorkDuration-sf", std::chrono::nanoseconds(0)};
127         TimePoint lastCallbackTime GUARDED_BY(mutex);
128         std::optional<scheduler::ScheduleResult> scheduledFrameTimeOpt GUARDED_BY(mutex);
129         TracedOrdinal<int> value = {"VSYNC-sf", 0};
130     };
131 
132     Vsync mVsync;
133 
134     // Returns the old registration so it can be destructed outside the lock to
135     // avoid deadlock.
136     std::unique_ptr<scheduler::VSyncCallbackRegistration> onNewVsyncScheduleLocked(
137             std::shared_ptr<scheduler::VSyncDispatch>) REQUIRES(mVsync.mutex);
138 
139 public:
140     explicit MessageQueue(ICompositor&);
141 
142     void initVsyncInternal(std::shared_ptr<scheduler::VSyncDispatch>, frametimeline::TokenManager&,
143                            std::chrono::nanoseconds workDuration) override;
144     void destroyVsync() override;
145     void setDuration(std::chrono::nanoseconds workDuration) override;
146 
147     void waitMessage() override;
148     void postMessage(sp<MessageHandler>&&) override;
149     void postMessageDelayed(sp<MessageHandler>&&, nsecs_t uptimeDelay) override;
150 
151     void scheduleConfigure() override;
152     void scheduleFrame() override;
153 
154     std::optional<scheduler::ScheduleResult> getScheduledFrameResult() const override;
155 };
156 
157 } // namespace impl
158 } // namespace android
159