blob: c5fc371d3af5d229d43790114544d8b064c0dbb5 [file] [log] [blame]
Mathias Agopianf1d8e872009-04-20 19:39:12 -07001/*
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
Dominik Laskowskidd4ef272020-04-23 14:02:12 -070017#pragma once
Mathias Agopianf1d8e872009-04-20 19:39:12 -070018
Dominik Laskowskidd4ef272020-04-23 14:02:12 -070019#include <cstdint>
20#include <future>
21#include <type_traits>
22#include <utility>
Mathias Agopianf1d8e872009-04-20 19:39:12 -070023
Dominik Laskowski208235c2020-12-03 15:38:51 -080024#include <android-base/thread_annotations.h>
Huihong Luo6fac5232021-11-22 16:05:23 -080025#include <android/gui/IDisplayEventConnection.h>
Lloyd Pique78ce4182018-01-31 16:39:51 -080026#include <private/gui/BitTube.h>
Dominik Laskowski208235c2020-12-03 15:38:51 -080027#include <utils/Looper.h>
Ady Abrahamd11bade2022-08-01 16:18:03 -070028#include <utils/StrongPointer.h>
Dominik Laskowski208235c2020-12-03 15:38:51 -080029#include <utils/Timers.h>
Mathias Agopian8aedd472012-01-24 16:39:14 -080030
Dominik Laskowski08fbd852022-07-14 08:53:42 -070031#include <scheduler/Time.h>
32#include <scheduler/VsyncId.h>
33
Dominik Laskowskif654d572018-12-20 11:03:06 -080034#include "EventThread.h"
Ady Abraham55fa7272020-09-30 19:19:27 -070035#include "TracedOrdinal.h"
36#include "VSyncDispatch.h"
Mathias Agopianf1d8e872009-04-20 19:39:12 -070037
38namespace android {
39
Dominik Laskowski63f12792023-01-21 16:58:22 -050040struct ICompositor;
Mathias Agopian8aedd472012-01-24 16:39:14 -080041
Dominik Laskowskidd4ef272020-04-23 14:02:12 -070042template <typename F>
43class Task : public MessageHandler {
44 template <typename G>
45 friend auto makeTask(G&&);
Mathias Agopianf1d8e872009-04-20 19:39:12 -070046
Ady Abrahamd11bade2022-08-01 16:18:03 -070047 template <typename... Args>
48 friend sp<Task<F>> sp<Task<F>>::make(Args&&... args);
49
Dominik Laskowskidd4ef272020-04-23 14:02:12 -070050 explicit Task(F&& f) : mTask(std::move(f)) {}
Lloyd Pique78ce4182018-01-31 16:39:51 -080051
Dominik Laskowskidd4ef272020-04-23 14:02:12 -070052 void handleMessage(const Message&) override { mTask(); }
Mathias Agopianbb641242010-05-18 17:06:55 -070053
Dominik Laskowskidd4ef272020-04-23 14:02:12 -070054 using T = std::invoke_result_t<F>;
55 std::packaged_task<T()> mTask;
Mathias Agopianf61c57f2011-11-23 16:49:10 -080056};
Mathias Agopianf1d8e872009-04-20 19:39:12 -070057
Dominik Laskowskidd4ef272020-04-23 14:02:12 -070058template <typename F>
59inline auto makeTask(F&& f) {
Ady Abraham81015532022-08-02 16:27:53 +000060 sp<Task<F>> task = sp<Task<F>>::make(std::forward<F>(f));
Dominik Laskowskidd4ef272020-04-23 14:02:12 -070061 return std::make_pair(task, task->mTask.get_future());
62}
Mathias Agopianf1d8e872009-04-20 19:39:12 -070063
Mathias Agopianf61c57f2011-11-23 16:49:10 -080064class MessageQueue {
Lloyd Pique3fcdef12018-01-22 17:14:00 -080065public:
Dominik Laskowskidd4ef272020-04-23 14:02:12 -070066 virtual ~MessageQueue() = default;
Lloyd Pique3fcdef12018-01-22 17:14:00 -080067
Leon Scroggins IIIa7be94e2024-01-23 12:24:30 -050068 virtual void initVsyncInternal(std::shared_ptr<scheduler::VSyncDispatch>,
69 frametimeline::TokenManager&,
70 std::chrono::nanoseconds workDuration) = 0;
Ady Abraham011f8ba2022-11-22 15:09:07 -080071 virtual void destroyVsync() = 0;
Ady Abraham55fa7272020-09-30 19:19:27 -070072 virtual void setDuration(std::chrono::nanoseconds workDuration) = 0;
Lloyd Pique3fcdef12018-01-22 17:14:00 -080073 virtual void waitMessage() = 0;
Dominik Laskowskidd4ef272020-04-23 14:02:12 -070074 virtual void postMessage(sp<MessageHandler>&&) = 0;
Chavi Weingarten076acac2023-01-19 17:20:43 +000075 virtual void postMessageDelayed(sp<MessageHandler>&&, nsecs_t uptimeDelay) = 0;
Dominik Laskowskif11728a2022-07-28 13:07:42 -070076 virtual void scheduleConfigure() = 0;
Dominik Laskowski46f3e3b2021-08-10 11:44:24 -070077 virtual void scheduleFrame() = 0;
Lloyd Pique3fcdef12018-01-22 17:14:00 -080078
ramindani32a88b12024-01-31 18:45:30 -080079 virtual std::optional<scheduler::ScheduleResult> getScheduledFrameResult() const = 0;
Dominik Laskowskie0e0cde2021-07-30 10:42:05 -070080};
Lloyd Pique3fcdef12018-01-22 17:14:00 -080081
82namespace impl {
83
Ady Abraham55fa7272020-09-30 19:19:27 -070084class MessageQueue : public android::MessageQueue {
85protected:
Mathias Agopian99ce5cd2012-01-31 18:24:27 -080086 class Handler : public MessageHandler {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -080087 MessageQueue& mQueue;
Dominik Laskowski46f3e3b2021-08-10 11:44:24 -070088 std::atomic_bool mFramePending = false;
Dominik Laskowski08fbd852022-07-14 08:53:42 -070089
90 std::atomic<VsyncId> mVsyncId;
91 std::atomic<TimePoint> mExpectedVsyncTime;
Lloyd Pique78ce4182018-01-31 16:39:51 -080092
Mathias Agopian99ce5cd2012-01-31 18:24:27 -080093 public:
Dominik Laskowskie0e0cde2021-07-30 10:42:05 -070094 explicit Handler(MessageQueue& queue) : mQueue(queue) {}
Ady Abraham55fa7272020-09-30 19:19:27 -070095 void handleMessage(const Message& message) override;
Dominik Laskowskie0e0cde2021-07-30 10:42:05 -070096
ramindani32a88b12024-01-31 18:45:30 -080097 virtual TimePoint getExpectedVsyncTime() const { return mExpectedVsyncTime.load(); }
98
99 virtual bool isFramePending() const;
Dominik Laskowskie0e0cde2021-07-30 10:42:05 -0700100
Dominik Laskowski08fbd852022-07-14 08:53:42 -0700101 virtual void dispatchFrame(VsyncId, TimePoint expectedVsyncTime);
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800102 };
103
104 friend class Handler;
105
Dominik Laskowskie0e0cde2021-07-30 10:42:05 -0700106 // For tests.
107 MessageQueue(ICompositor&, sp<Handler>);
108
109 void vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, nsecs_t readyTime);
110
Leon Scroggins III67388622023-02-06 20:36:20 -0500111 void onNewVsyncSchedule(std::shared_ptr<scheduler::VSyncDispatch>) EXCLUDES(mVsync.mutex);
112
Dominik Laskowskie0e0cde2021-07-30 10:42:05 -0700113private:
Dominik Laskowski08fbd852022-07-14 08:53:42 -0700114 virtual void onFrameSignal(ICompositor&, VsyncId, TimePoint expectedVsyncTime) = 0;
115
Dominik Laskowskie0e0cde2021-07-30 10:42:05 -0700116 ICompositor& mCompositor;
117 const sp<Looper> mLooper;
118 const sp<Handler> mHandler;
Ady Abraham55fa7272020-09-30 19:19:27 -0700119
120 struct Vsync {
121 frametimeline::TokenManager* tokenManager = nullptr;
Ady Abraham55fa7272020-09-30 19:19:27 -0700122
Dominik Laskowskie0e0cde2021-07-30 10:42:05 -0700123 mutable std::mutex mutex;
Leon Scroggins IIIfb7ed562023-04-05 11:39:25 -0400124 std::unique_ptr<scheduler::VSyncCallbackRegistration> registration GUARDED_BY(mutex);
Ady Abraham55fa7272020-09-30 19:19:27 -0700125 TracedOrdinal<std::chrono::nanoseconds> workDuration
126 GUARDED_BY(mutex) = {"VsyncWorkDuration-sf", std::chrono::nanoseconds(0)};
Dominik Laskowski08fbd852022-07-14 08:53:42 -0700127 TimePoint lastCallbackTime GUARDED_BY(mutex);
ramindani32a88b12024-01-31 18:45:30 -0800128 std::optional<scheduler::ScheduleResult> scheduledFrameTimeOpt GUARDED_BY(mutex);
Ady Abraham55fa7272020-09-30 19:19:27 -0700129 TracedOrdinal<int> value = {"VSYNC-sf", 0};
130 };
131
Dominik Laskowski208235c2020-12-03 15:38:51 -0800132 Vsync mVsync;
Mathias Agopianf1d8e872009-04-20 19:39:12 -0700133
Leon Scroggins IIIfb7ed562023-04-05 11:39:25 -0400134 // 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);
Leon Scroggins III67388622023-02-06 20:36:20 -0500138
Mathias Agopianf61c57f2011-11-23 16:49:10 -0800139public:
Dominik Laskowskie0e0cde2021-07-30 10:42:05 -0700140 explicit MessageQueue(ICompositor&);
141
Leon Scroggins IIIa7be94e2024-01-23 12:24:30 -0500142 void initVsyncInternal(std::shared_ptr<scheduler::VSyncDispatch>, frametimeline::TokenManager&,
143 std::chrono::nanoseconds workDuration) override;
Ady Abraham011f8ba2022-11-22 15:09:07 -0800144 void destroyVsync() override;
Ady Abraham55fa7272020-09-30 19:19:27 -0700145 void setDuration(std::chrono::nanoseconds workDuration) override;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800146
Lloyd Pique3fcdef12018-01-22 17:14:00 -0800147 void waitMessage() override;
Dominik Laskowskidd4ef272020-04-23 14:02:12 -0700148 void postMessage(sp<MessageHandler>&&) override;
Chavi Weingarten076acac2023-01-19 17:20:43 +0000149 void postMessageDelayed(sp<MessageHandler>&&, nsecs_t uptimeDelay) override;
Mathias Agopian9eb1f052013-04-10 16:27:17 -0700150
Dominik Laskowskif11728a2022-07-28 13:07:42 -0700151 void scheduleConfigure() override;
Dominik Laskowski46f3e3b2021-08-10 11:44:24 -0700152 void scheduleFrame() override;
Ana Krulec7d1d6832018-12-27 11:10:09 -0800153
ramindani32a88b12024-01-31 18:45:30 -0800154 std::optional<scheduler::ScheduleResult> getScheduledFrameResult() const override;
Mathias Agopianf1d8e872009-04-20 19:39:12 -0700155};
156
Lloyd Pique3fcdef12018-01-22 17:14:00 -0800157} // namespace impl
158} // namespace android