blob: 99ce3a64a73f9031d6d27f3099b4042940d9903b [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
Mathias Agopianf61c57f2011-11-23 16:49:10 -080024#include <utils/Looper.h>
Lloyd Pique78ce4182018-01-31 16:39:51 -080025#include <utils/Timers.h>
26#include <utils/threads.h>
Mathias Agopianf1d8e872009-04-20 19:39:12 -070027
Lloyd Pique3fcdef12018-01-22 17:14:00 -080028#include <gui/IDisplayEventConnection.h>
Lloyd Pique78ce4182018-01-31 16:39:51 -080029#include <private/gui/BitTube.h>
Mathias Agopian8aedd472012-01-24 16:39:14 -080030
Dominik Laskowskif654d572018-12-20 11:03:06 -080031#include "EventThread.h"
Ady Abraham55fa7272020-09-30 19:19:27 -070032#include "TracedOrdinal.h"
33#include "VSyncDispatch.h"
Mathias Agopianf1d8e872009-04-20 19:39:12 -070034
35namespace android {
36
Mathias Agopian99ce5cd2012-01-31 18:24:27 -080037class SurfaceFlinger;
Mathias Agopian8aedd472012-01-24 16:39:14 -080038
Dominik Laskowskidd4ef272020-04-23 14:02:12 -070039template <typename F>
40class Task : public MessageHandler {
41 template <typename G>
42 friend auto makeTask(G&&);
Mathias Agopianf1d8e872009-04-20 19:39:12 -070043
Dominik Laskowskidd4ef272020-04-23 14:02:12 -070044 explicit Task(F&& f) : mTask(std::move(f)) {}
Lloyd Pique78ce4182018-01-31 16:39:51 -080045
Dominik Laskowskidd4ef272020-04-23 14:02:12 -070046 void handleMessage(const Message&) override { mTask(); }
Mathias Agopianbb641242010-05-18 17:06:55 -070047
Dominik Laskowskidd4ef272020-04-23 14:02:12 -070048 using T = std::invoke_result_t<F>;
49 std::packaged_task<T()> mTask;
Mathias Agopianf61c57f2011-11-23 16:49:10 -080050};
Mathias Agopianf1d8e872009-04-20 19:39:12 -070051
Dominik Laskowskidd4ef272020-04-23 14:02:12 -070052template <typename F>
53inline auto makeTask(F&& f) {
54 sp<Task<F>> task = new Task<F>(std::move(f));
55 return std::make_pair(task, task->mTask.get_future());
56}
Mathias Agopianf1d8e872009-04-20 19:39:12 -070057
Mathias Agopianf61c57f2011-11-23 16:49:10 -080058class MessageQueue {
Lloyd Pique3fcdef12018-01-22 17:14:00 -080059public:
60 enum {
61 INVALIDATE = 0,
62 REFRESH = 1,
63 };
64
Dominik Laskowskidd4ef272020-04-23 14:02:12 -070065 virtual ~MessageQueue() = default;
Lloyd Pique3fcdef12018-01-22 17:14:00 -080066
67 virtual void init(const sp<SurfaceFlinger>& flinger) = 0;
Ady Abraham55fa7272020-09-30 19:19:27 -070068 virtual void initVsync(scheduler::VSyncDispatch&, frametimeline::TokenManager&,
69 std::chrono::nanoseconds workDuration) = 0;
70 virtual void setDuration(std::chrono::nanoseconds workDuration) = 0;
Ana Krulec85c39af2018-12-26 17:29:57 -080071 virtual void setEventConnection(const sp<EventThreadConnection>& connection) = 0;
Lloyd Pique3fcdef12018-01-22 17:14:00 -080072 virtual void waitMessage() = 0;
Dominik Laskowskidd4ef272020-04-23 14:02:12 -070073 virtual void postMessage(sp<MessageHandler>&&) = 0;
Lloyd Pique3fcdef12018-01-22 17:14:00 -080074 virtual void invalidate() = 0;
75 virtual void refresh() = 0;
76};
77
78// ---------------------------------------------------------------------------
79
80namespace impl {
81
Ady Abraham55fa7272020-09-30 19:19:27 -070082class MessageQueue : public android::MessageQueue {
83protected:
Mathias Agopian99ce5cd2012-01-31 18:24:27 -080084 class Handler : public MessageHandler {
Lloyd Pique78ce4182018-01-31 16:39:51 -080085 enum { eventMaskInvalidate = 0x1, eventMaskRefresh = 0x2, eventMaskTransaction = 0x4 };
Mathias Agopian99ce5cd2012-01-31 18:24:27 -080086 MessageQueue& mQueue;
87 int32_t mEventMask;
Adithya Srinivasan5f683cf2020-09-15 14:21:04 -070088 std::atomic<int64_t> mVsyncId;
Ady Abraham5facfb12020-04-22 15:18:31 -070089 std::atomic<nsecs_t> mExpectedVSyncTime;
Lloyd Pique78ce4182018-01-31 16:39:51 -080090
Mathias Agopian99ce5cd2012-01-31 18:24:27 -080091 public:
Lloyd Pique78ce4182018-01-31 16:39:51 -080092 explicit Handler(MessageQueue& queue) : mQueue(queue), mEventMask(0) {}
Ady Abraham55fa7272020-09-30 19:19:27 -070093 void handleMessage(const Message& message) override;
94 virtual void dispatchRefresh();
95 virtual void dispatchInvalidate(int64_t vsyncId, nsecs_t expectedVSyncTimestamp);
Mathias Agopian99ce5cd2012-01-31 18:24:27 -080096 };
97
98 friend class Handler;
99
100 sp<SurfaceFlinger> mFlinger;
Mathias Agopianf61c57f2011-11-23 16:49:10 -0800101 sp<Looper> mLooper;
Ana Krulec85c39af2018-12-26 17:29:57 -0800102 sp<EventThreadConnection> mEvents;
Ady Abraham55fa7272020-09-30 19:19:27 -0700103
104 struct Vsync {
105 frametimeline::TokenManager* tokenManager = nullptr;
106 std::unique_ptr<scheduler::VSyncCallbackRegistration> registration;
107
108 std::mutex mutex;
109 TracedOrdinal<std::chrono::nanoseconds> workDuration
110 GUARDED_BY(mutex) = {"VsyncWorkDuration-sf", std::chrono::nanoseconds(0)};
111 std::chrono::nanoseconds lastCallbackTime GUARDED_BY(mutex) = std::chrono::nanoseconds{0};
Ady Abraham326ecde2020-11-06 15:05:53 -0800112 bool mScheduled GUARDED_BY(mutex) = false;
Ady Abraham55fa7272020-09-30 19:19:27 -0700113 TracedOrdinal<int> value = {"VSYNC-sf", 0};
114 };
115
116 Vsync mVsync;
117
Dan Stoza6b698e42017-04-03 13:09:08 -0700118 gui::BitTube mEventTube;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800119 sp<Handler> mHandler;
120
Mathias Agopian8aedd472012-01-24 16:39:14 -0800121 static int cb_eventReceiver(int fd, int events, void* data);
122 int eventReceiver(int fd, int events);
Ady Abraham55fa7272020-09-30 19:19:27 -0700123 void vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, nsecs_t readyTime);
Mathias Agopianf1d8e872009-04-20 19:39:12 -0700124
Mathias Agopianf61c57f2011-11-23 16:49:10 -0800125public:
Lloyd Pique3fcdef12018-01-22 17:14:00 -0800126 ~MessageQueue() override = default;
127 void init(const sp<SurfaceFlinger>& flinger) override;
Ady Abraham55fa7272020-09-30 19:19:27 -0700128 void initVsync(scheduler::VSyncDispatch&, frametimeline::TokenManager&,
129 std::chrono::nanoseconds workDuration) override;
130 void setDuration(std::chrono::nanoseconds workDuration) override;
Ana Krulec85c39af2018-12-26 17:29:57 -0800131 void setEventConnection(const sp<EventThreadConnection>& connection) override;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800132
Lloyd Pique3fcdef12018-01-22 17:14:00 -0800133 void waitMessage() override;
Dominik Laskowskidd4ef272020-04-23 14:02:12 -0700134 void postMessage(sp<MessageHandler>&&) override;
Mathias Agopian9eb1f052013-04-10 16:27:17 -0700135
136 // sends INVALIDATE message at next VSYNC
Lloyd Pique3fcdef12018-01-22 17:14:00 -0800137 void invalidate() override;
Ana Krulec7d1d6832018-12-27 11:10:09 -0800138
Mathias Agopian9eb1f052013-04-10 16:27:17 -0700139 // sends REFRESH message at next VSYNC
Lloyd Pique3fcdef12018-01-22 17:14:00 -0800140 void refresh() override;
Mathias Agopianf1d8e872009-04-20 19:39:12 -0700141};
142
Lloyd Pique3fcdef12018-01-22 17:14:00 -0800143} // namespace impl
144} // namespace android