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