blob: 132b416c8812edf813f7fa414ccd1e45f8d4962b [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"
Mathias Agopianf1d8e872009-04-20 19:39:12 -070032
33namespace android {
34
Mathias Agopian99ce5cd2012-01-31 18:24:27 -080035class SurfaceFlinger;
Mathias Agopian8aedd472012-01-24 16:39:14 -080036
Dominik Laskowskidd4ef272020-04-23 14:02:12 -070037template <typename F>
38class Task : public MessageHandler {
39 template <typename G>
40 friend auto makeTask(G&&);
Mathias Agopianf1d8e872009-04-20 19:39:12 -070041
Dominik Laskowskidd4ef272020-04-23 14:02:12 -070042 explicit Task(F&& f) : mTask(std::move(f)) {}
Lloyd Pique78ce4182018-01-31 16:39:51 -080043
Dominik Laskowskidd4ef272020-04-23 14:02:12 -070044 void handleMessage(const Message&) override { mTask(); }
Mathias Agopianbb641242010-05-18 17:06:55 -070045
Dominik Laskowskidd4ef272020-04-23 14:02:12 -070046 using T = std::invoke_result_t<F>;
47 std::packaged_task<T()> mTask;
Mathias Agopianf61c57f2011-11-23 16:49:10 -080048};
Mathias Agopianf1d8e872009-04-20 19:39:12 -070049
Dominik Laskowskidd4ef272020-04-23 14:02:12 -070050template <typename F>
51inline auto makeTask(F&& f) {
52 sp<Task<F>> task = new Task<F>(std::move(f));
53 return std::make_pair(task, task->mTask.get_future());
54}
Mathias Agopianf1d8e872009-04-20 19:39:12 -070055
Mathias Agopianf61c57f2011-11-23 16:49:10 -080056class MessageQueue {
Lloyd Pique3fcdef12018-01-22 17:14:00 -080057public:
58 enum {
59 INVALIDATE = 0,
60 REFRESH = 1,
61 };
62
Dominik Laskowskidd4ef272020-04-23 14:02:12 -070063 virtual ~MessageQueue() = default;
Lloyd Pique3fcdef12018-01-22 17:14:00 -080064
65 virtual void init(const sp<SurfaceFlinger>& flinger) = 0;
Ana Krulec85c39af2018-12-26 17:29:57 -080066 virtual void setEventConnection(const sp<EventThreadConnection>& connection) = 0;
Lloyd Pique3fcdef12018-01-22 17:14:00 -080067 virtual void waitMessage() = 0;
Dominik Laskowskidd4ef272020-04-23 14:02:12 -070068 virtual void postMessage(sp<MessageHandler>&&) = 0;
Lloyd Pique3fcdef12018-01-22 17:14:00 -080069 virtual void invalidate() = 0;
70 virtual void refresh() = 0;
71};
72
73// ---------------------------------------------------------------------------
74
75namespace impl {
76
77class MessageQueue final : public android::MessageQueue {
Mathias Agopian99ce5cd2012-01-31 18:24:27 -080078 class Handler : public MessageHandler {
Lloyd Pique78ce4182018-01-31 16:39:51 -080079 enum { eventMaskInvalidate = 0x1, eventMaskRefresh = 0x2, eventMaskTransaction = 0x4 };
Mathias Agopian99ce5cd2012-01-31 18:24:27 -080080 MessageQueue& mQueue;
81 int32_t mEventMask;
Ady Abraham5facfb12020-04-22 15:18:31 -070082 std::atomic<nsecs_t> mExpectedVSyncTime;
Lloyd Pique78ce4182018-01-31 16:39:51 -080083
Mathias Agopian99ce5cd2012-01-31 18:24:27 -080084 public:
Lloyd Pique78ce4182018-01-31 16:39:51 -080085 explicit Handler(MessageQueue& queue) : mQueue(queue), mEventMask(0) {}
Mathias Agopian99ce5cd2012-01-31 18:24:27 -080086 virtual void handleMessage(const Message& message);
Mathias Agopian4fec8732012-06-29 14:12:52 -070087 void dispatchRefresh();
Ady Abraham5facfb12020-04-22 15:18:31 -070088 void dispatchInvalidate(nsecs_t expectedVSyncTimestamp);
Mathias Agopian99ce5cd2012-01-31 18:24:27 -080089 };
90
91 friend class Handler;
92
93 sp<SurfaceFlinger> mFlinger;
Mathias Agopianf61c57f2011-11-23 16:49:10 -080094 sp<Looper> mLooper;
Ana Krulec85c39af2018-12-26 17:29:57 -080095 sp<EventThreadConnection> mEvents;
Dan Stoza6b698e42017-04-03 13:09:08 -070096 gui::BitTube mEventTube;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -080097 sp<Handler> mHandler;
98
Mathias Agopian8aedd472012-01-24 16:39:14 -080099 static int cb_eventReceiver(int fd, int events, void* data);
100 int eventReceiver(int fd, int events);
Mathias Agopianf1d8e872009-04-20 19:39:12 -0700101
Mathias Agopianf61c57f2011-11-23 16:49:10 -0800102public:
Lloyd Pique3fcdef12018-01-22 17:14:00 -0800103 ~MessageQueue() override = default;
104 void init(const sp<SurfaceFlinger>& flinger) override;
Ana Krulec85c39af2018-12-26 17:29:57 -0800105 void setEventConnection(const sp<EventThreadConnection>& connection) override;
Mathias Agopian99ce5cd2012-01-31 18:24:27 -0800106
Lloyd Pique3fcdef12018-01-22 17:14:00 -0800107 void waitMessage() override;
Dominik Laskowskidd4ef272020-04-23 14:02:12 -0700108 void postMessage(sp<MessageHandler>&&) override;
Mathias Agopian9eb1f052013-04-10 16:27:17 -0700109
110 // sends INVALIDATE message at next VSYNC
Lloyd Pique3fcdef12018-01-22 17:14:00 -0800111 void invalidate() override;
Ana Krulec7d1d6832018-12-27 11:10:09 -0800112
Mathias Agopian9eb1f052013-04-10 16:27:17 -0700113 // sends REFRESH message at next VSYNC
Lloyd Pique3fcdef12018-01-22 17:14:00 -0800114 void refresh() override;
Mathias Agopianf1d8e872009-04-20 19:39:12 -0700115};
116
Lloyd Pique3fcdef12018-01-22 17:14:00 -0800117} // namespace impl
118} // namespace android