• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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