• 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 <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 class SurfaceFlinger;
37 
38 template <typename F>
39 class Task : public MessageHandler {
40     template <typename G>
41     friend auto makeTask(G&&);
42 
Task(F && f)43     explicit Task(F&& f) : mTask(std::move(f)) {}
44 
handleMessage(const Message &)45     void handleMessage(const Message&) override { mTask(); }
46 
47     using T = std::invoke_result_t<F>;
48     std::packaged_task<T()> mTask;
49 };
50 
51 template <typename F>
makeTask(F && f)52 inline auto makeTask(F&& f) {
53     sp<Task<F>> task = new Task<F>(std::move(f));
54     return std::make_pair(task, task->mTask.get_future());
55 }
56 
57 class MessageQueue {
58 public:
59     enum {
60         INVALIDATE = 0,
61         REFRESH = 1,
62     };
63 
64     virtual ~MessageQueue() = default;
65 
66     virtual void init(const sp<SurfaceFlinger>& flinger) = 0;
67     virtual void initVsync(scheduler::VSyncDispatch&, frametimeline::TokenManager&,
68                            std::chrono::nanoseconds workDuration) = 0;
69     virtual void setDuration(std::chrono::nanoseconds workDuration) = 0;
70     virtual void setInjector(sp<EventThreadConnection>) = 0;
71     virtual void waitMessage() = 0;
72     virtual void postMessage(sp<MessageHandler>&&) = 0;
73     virtual void invalidate() = 0;
74     virtual void refresh() = 0;
75     virtual std::optional<std::chrono::steady_clock::time_point> nextExpectedInvalidate() = 0;
76 };
77 
78 // ---------------------------------------------------------------------------
79 
80 namespace impl {
81 
82 class MessageQueue : public android::MessageQueue {
83 protected:
84     class Handler : public MessageHandler {
85         enum : uint32_t {
86             eventMaskInvalidate = 0x1,
87             eventMaskRefresh = 0x2,
88             eventMaskTransaction = 0x4
89         };
90         MessageQueue& mQueue;
91         std::atomic<uint32_t> mEventMask;
92         std::atomic<int64_t> mVsyncId;
93         std::atomic<nsecs_t> mExpectedVSyncTime;
94 
95     public:
Handler(MessageQueue & queue)96         explicit Handler(MessageQueue& queue) : mQueue(queue), mEventMask(0) {}
97         void handleMessage(const Message& message) override;
98         virtual void dispatchRefresh();
99         virtual void dispatchInvalidate(int64_t vsyncId, nsecs_t expectedVSyncTimestamp);
100         virtual bool invalidatePending();
101     };
102 
103     friend class Handler;
104 
105     sp<SurfaceFlinger> mFlinger;
106     sp<Looper> mLooper;
107 
108     struct Vsync {
109         frametimeline::TokenManager* tokenManager = nullptr;
110         std::unique_ptr<scheduler::VSyncCallbackRegistration> registration;
111 
112         std::mutex mutex;
113         TracedOrdinal<std::chrono::nanoseconds> workDuration
114                 GUARDED_BY(mutex) = {"VsyncWorkDuration-sf", std::chrono::nanoseconds(0)};
GUARDED_BYVsync115         std::chrono::nanoseconds lastCallbackTime GUARDED_BY(mutex) = std::chrono::nanoseconds{0};
116         bool scheduled GUARDED_BY(mutex) = false;
117         std::optional<nsecs_t> expectedWakeupTime GUARDED_BY(mutex);
118         TracedOrdinal<int> value = {"VSYNC-sf", 0};
119     };
120 
121     struct Injector {
122         gui::BitTube tube;
123         std::mutex mutex;
124         sp<EventThreadConnection> connection GUARDED_BY(mutex);
125     };
126 
127     Vsync mVsync;
128     Injector mInjector;
129 
130     sp<Handler> mHandler;
131 
132     void vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, nsecs_t readyTime);
133     void injectorCallback();
134 
135 public:
136     ~MessageQueue() override = default;
137     void init(const sp<SurfaceFlinger>& flinger) override;
138     void initVsync(scheduler::VSyncDispatch&, frametimeline::TokenManager&,
139                    std::chrono::nanoseconds workDuration) override;
140     void setDuration(std::chrono::nanoseconds workDuration) override;
141     void setInjector(sp<EventThreadConnection>) override;
142 
143     void waitMessage() override;
144     void postMessage(sp<MessageHandler>&&) override;
145 
146     // sends INVALIDATE message at next VSYNC
147     void invalidate() override;
148 
149     // sends REFRESH message at next VSYNC
150     void refresh() override;
151 
152     std::optional<std::chrono::steady_clock::time_point> nextExpectedInvalidate() override;
153 };
154 
155 } // namespace impl
156 } // namespace android
157