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 <utils/Looper.h>
25 #include <utils/Timers.h>
26 #include <utils/threads.h>
27 
28 #include <gui/IDisplayEventConnection.h>
29 #include <private/gui/BitTube.h>
30 
31 #include "EventThread.h"
32 
33 namespace android {
34 
35 class SurfaceFlinger;
36 
37 template <typename F>
38 class Task : public MessageHandler {
39     template <typename G>
40     friend auto makeTask(G&&);
41 
Task(F && f)42     explicit Task(F&& f) : mTask(std::move(f)) {}
43 
handleMessage(const Message &)44     void handleMessage(const Message&) override { mTask(); }
45 
46     using T = std::invoke_result_t<F>;
47     std::packaged_task<T()> mTask;
48 };
49 
50 template <typename F>
makeTask(F && f)51 inline 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 }
55 
56 class MessageQueue {
57 public:
58     enum {
59         INVALIDATE = 0,
60         REFRESH = 1,
61     };
62 
63     virtual ~MessageQueue() = default;
64 
65     virtual void init(const sp<SurfaceFlinger>& flinger) = 0;
66     virtual void setEventConnection(const sp<EventThreadConnection>& connection) = 0;
67     virtual void waitMessage() = 0;
68     virtual void postMessage(sp<MessageHandler>&&) = 0;
69     virtual void invalidate() = 0;
70     virtual void refresh() = 0;
71 };
72 
73 // ---------------------------------------------------------------------------
74 
75 namespace impl {
76 
77 class MessageQueue final : public android::MessageQueue {
78     class Handler : public MessageHandler {
79         enum { eventMaskInvalidate = 0x1, eventMaskRefresh = 0x2, eventMaskTransaction = 0x4 };
80         MessageQueue& mQueue;
81         int32_t mEventMask;
82         std::atomic<nsecs_t> mExpectedVSyncTime;
83 
84     public:
Handler(MessageQueue & queue)85         explicit Handler(MessageQueue& queue) : mQueue(queue), mEventMask(0) {}
86         virtual void handleMessage(const Message& message);
87         void dispatchRefresh();
88         void dispatchInvalidate(nsecs_t expectedVSyncTimestamp);
89     };
90 
91     friend class Handler;
92 
93     sp<SurfaceFlinger> mFlinger;
94     sp<Looper> mLooper;
95     sp<EventThreadConnection> mEvents;
96     gui::BitTube mEventTube;
97     sp<Handler> mHandler;
98 
99     static int cb_eventReceiver(int fd, int events, void* data);
100     int eventReceiver(int fd, int events);
101 
102 public:
103     ~MessageQueue() override = default;
104     void init(const sp<SurfaceFlinger>& flinger) override;
105     void setEventConnection(const sp<EventThreadConnection>& connection) override;
106 
107     void waitMessage() override;
108     void postMessage(sp<MessageHandler>&&) override;
109 
110     // sends INVALIDATE message at next VSYNC
111     void invalidate() override;
112 
113     // sends REFRESH message at next VSYNC
114     void refresh() override;
115 };
116 
117 } // namespace impl
118 } // namespace android
119