xref: /aosp_15_r20/frameworks/native/include/gui/DisplayEventReceiver.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright (C) 2011 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #ifndef ANDROID_GUI_DISPLAY_EVENT_H
18*38e8c45fSAndroid Build Coastguard Worker #define ANDROID_GUI_DISPLAY_EVENT_H
19*38e8c45fSAndroid Build Coastguard Worker 
20*38e8c45fSAndroid Build Coastguard Worker #include <stdint.h>
21*38e8c45fSAndroid Build Coastguard Worker #include <sys/types.h>
22*38e8c45fSAndroid Build Coastguard Worker 
23*38e8c45fSAndroid Build Coastguard Worker #include <ftl/flags.h>
24*38e8c45fSAndroid Build Coastguard Worker 
25*38e8c45fSAndroid Build Coastguard Worker #include <utils/Errors.h>
26*38e8c45fSAndroid Build Coastguard Worker #include <utils/RefBase.h>
27*38e8c45fSAndroid Build Coastguard Worker #include <utils/Timers.h>
28*38e8c45fSAndroid Build Coastguard Worker 
29*38e8c45fSAndroid Build Coastguard Worker #include <android/gui/ISurfaceComposer.h>
30*38e8c45fSAndroid Build Coastguard Worker #include <binder/IInterface.h>
31*38e8c45fSAndroid Build Coastguard Worker #include <gui/VsyncEventData.h>
32*38e8c45fSAndroid Build Coastguard Worker 
33*38e8c45fSAndroid Build Coastguard Worker #include <ui/DisplayId.h>
34*38e8c45fSAndroid Build Coastguard Worker 
35*38e8c45fSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
36*38e8c45fSAndroid Build Coastguard Worker 
37*38e8c45fSAndroid Build Coastguard Worker namespace android {
38*38e8c45fSAndroid Build Coastguard Worker 
39*38e8c45fSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
40*38e8c45fSAndroid Build Coastguard Worker 
41*38e8c45fSAndroid Build Coastguard Worker using EventRegistrationFlags = ftl::Flags<gui::ISurfaceComposer::EventRegistration>;
42*38e8c45fSAndroid Build Coastguard Worker 
43*38e8c45fSAndroid Build Coastguard Worker using gui::IDisplayEventConnection;
44*38e8c45fSAndroid Build Coastguard Worker using gui::ParcelableVsyncEventData;
45*38e8c45fSAndroid Build Coastguard Worker using gui::VsyncEventData;
46*38e8c45fSAndroid Build Coastguard Worker 
47*38e8c45fSAndroid Build Coastguard Worker namespace gui {
48*38e8c45fSAndroid Build Coastguard Worker class BitTube;
49*38e8c45fSAndroid Build Coastguard Worker } // namespace gui
50*38e8c45fSAndroid Build Coastguard Worker 
fourcc(char c1,char c2,char c3,char c4)51*38e8c45fSAndroid Build Coastguard Worker static inline constexpr uint32_t fourcc(char c1, char c2, char c3, char c4) {
52*38e8c45fSAndroid Build Coastguard Worker     return static_cast<uint32_t>(c1) << 24 |
53*38e8c45fSAndroid Build Coastguard Worker         static_cast<uint32_t>(c2) << 16 |
54*38e8c45fSAndroid Build Coastguard Worker         static_cast<uint32_t>(c3) << 8 |
55*38e8c45fSAndroid Build Coastguard Worker         static_cast<uint32_t>(c4);
56*38e8c45fSAndroid Build Coastguard Worker }
57*38e8c45fSAndroid Build Coastguard Worker 
58*38e8c45fSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
59*38e8c45fSAndroid Build Coastguard Worker class DisplayEventReceiver {
60*38e8c45fSAndroid Build Coastguard Worker public:
61*38e8c45fSAndroid Build Coastguard Worker     enum {
62*38e8c45fSAndroid Build Coastguard Worker         DISPLAY_EVENT_VSYNC = fourcc('v', 's', 'y', 'n'),
63*38e8c45fSAndroid Build Coastguard Worker         DISPLAY_EVENT_HOTPLUG = fourcc('p', 'l', 'u', 'g'),
64*38e8c45fSAndroid Build Coastguard Worker         DISPLAY_EVENT_MODE_CHANGE = fourcc('m', 'o', 'd', 'e'),
65*38e8c45fSAndroid Build Coastguard Worker         DISPLAY_EVENT_MODE_REJECTION = fourcc('r', 'e', 'j', 'e'),
66*38e8c45fSAndroid Build Coastguard Worker         DISPLAY_EVENT_NULL = fourcc('n', 'u', 'l', 'l'),
67*38e8c45fSAndroid Build Coastguard Worker         DISPLAY_EVENT_FRAME_RATE_OVERRIDE = fourcc('r', 'a', 't', 'e'),
68*38e8c45fSAndroid Build Coastguard Worker         DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH = fourcc('f', 'l', 's', 'h'),
69*38e8c45fSAndroid Build Coastguard Worker         DISPLAY_EVENT_HDCP_LEVELS_CHANGE = fourcc('h', 'd', 'c', 'p'),
70*38e8c45fSAndroid Build Coastguard Worker     };
71*38e8c45fSAndroid Build Coastguard Worker 
72*38e8c45fSAndroid Build Coastguard Worker     struct Event {
73*38e8c45fSAndroid Build Coastguard Worker         // We add __attribute__((aligned(8))) for nsecs_t fields because
74*38e8c45fSAndroid Build Coastguard Worker         // we need to make sure all fields are aligned the same with x86
75*38e8c45fSAndroid Build Coastguard Worker         // and x64 (long long has different default alignment):
76*38e8c45fSAndroid Build Coastguard Worker         //
77*38e8c45fSAndroid Build Coastguard Worker         // https://en.wikipedia.org/wiki/Data_structure_alignment
78*38e8c45fSAndroid Build Coastguard Worker 
79*38e8c45fSAndroid Build Coastguard Worker         struct Header {
80*38e8c45fSAndroid Build Coastguard Worker             uint32_t type;
81*38e8c45fSAndroid Build Coastguard Worker             PhysicalDisplayId displayId __attribute__((aligned(8)));
82*38e8c45fSAndroid Build Coastguard Worker             nsecs_t timestamp __attribute__((aligned(8)));
83*38e8c45fSAndroid Build Coastguard Worker         };
84*38e8c45fSAndroid Build Coastguard Worker 
85*38e8c45fSAndroid Build Coastguard Worker         struct VSync {
86*38e8c45fSAndroid Build Coastguard Worker             uint32_t count;
87*38e8c45fSAndroid Build Coastguard Worker             VsyncEventData vsyncData;
88*38e8c45fSAndroid Build Coastguard Worker         };
89*38e8c45fSAndroid Build Coastguard Worker 
90*38e8c45fSAndroid Build Coastguard Worker         struct Hotplug {
91*38e8c45fSAndroid Build Coastguard Worker             bool connected;
92*38e8c45fSAndroid Build Coastguard Worker             int32_t connectionError __attribute__((aligned(4)));
93*38e8c45fSAndroid Build Coastguard Worker         };
94*38e8c45fSAndroid Build Coastguard Worker 
95*38e8c45fSAndroid Build Coastguard Worker         struct ModeChange {
96*38e8c45fSAndroid Build Coastguard Worker             int32_t modeId;
97*38e8c45fSAndroid Build Coastguard Worker             nsecs_t vsyncPeriod __attribute__((aligned(8)));
98*38e8c45fSAndroid Build Coastguard Worker         };
99*38e8c45fSAndroid Build Coastguard Worker 
100*38e8c45fSAndroid Build Coastguard Worker         struct ModeRejection {
101*38e8c45fSAndroid Build Coastguard Worker             int32_t modeId;
102*38e8c45fSAndroid Build Coastguard Worker         };
103*38e8c45fSAndroid Build Coastguard Worker 
104*38e8c45fSAndroid Build Coastguard Worker         struct FrameRateOverride {
105*38e8c45fSAndroid Build Coastguard Worker             uid_t uid __attribute__((aligned(8)));
106*38e8c45fSAndroid Build Coastguard Worker             float frameRateHz __attribute__((aligned(8)));
107*38e8c45fSAndroid Build Coastguard Worker         };
108*38e8c45fSAndroid Build Coastguard Worker 
109*38e8c45fSAndroid Build Coastguard Worker         /*
110*38e8c45fSAndroid Build Coastguard Worker          * The values are defined in aidl:
111*38e8c45fSAndroid Build Coastguard Worker          * hardware/interfaces/drm/aidl/android/hardware/drm/HdcpLevel.aidl
112*38e8c45fSAndroid Build Coastguard Worker          */
113*38e8c45fSAndroid Build Coastguard Worker         struct HdcpLevelsChange {
114*38e8c45fSAndroid Build Coastguard Worker             int32_t connectedLevel;
115*38e8c45fSAndroid Build Coastguard Worker             int32_t maxLevel;
116*38e8c45fSAndroid Build Coastguard Worker         };
117*38e8c45fSAndroid Build Coastguard Worker 
118*38e8c45fSAndroid Build Coastguard Worker         Header header;
119*38e8c45fSAndroid Build Coastguard Worker         union {
120*38e8c45fSAndroid Build Coastguard Worker             VSync vsync;
121*38e8c45fSAndroid Build Coastguard Worker             Hotplug hotplug;
122*38e8c45fSAndroid Build Coastguard Worker             ModeChange modeChange;
123*38e8c45fSAndroid Build Coastguard Worker             FrameRateOverride frameRateOverride;
124*38e8c45fSAndroid Build Coastguard Worker             HdcpLevelsChange hdcpLevelsChange;
125*38e8c45fSAndroid Build Coastguard Worker             ModeRejection modeRejection;
126*38e8c45fSAndroid Build Coastguard Worker         };
127*38e8c45fSAndroid Build Coastguard Worker     };
128*38e8c45fSAndroid Build Coastguard Worker     static_assert(sizeof(Event) == 224);
129*38e8c45fSAndroid Build Coastguard Worker 
130*38e8c45fSAndroid Build Coastguard Worker public:
131*38e8c45fSAndroid Build Coastguard Worker     /*
132*38e8c45fSAndroid Build Coastguard Worker      * DisplayEventReceiver creates and registers an event connection with
133*38e8c45fSAndroid Build Coastguard Worker      * SurfaceFlinger. VSync events are disabled by default. Call setVSyncRate
134*38e8c45fSAndroid Build Coastguard Worker      * or requestNextVsync to receive them.
135*38e8c45fSAndroid Build Coastguard Worker      * To receive ModeChanged and/or FrameRateOverrides events specify this in
136*38e8c45fSAndroid Build Coastguard Worker      * the constructor. Other events start being delivered immediately.
137*38e8c45fSAndroid Build Coastguard Worker      */
138*38e8c45fSAndroid Build Coastguard Worker     explicit DisplayEventReceiver(gui::ISurfaceComposer::VsyncSource vsyncSource =
139*38e8c45fSAndroid Build Coastguard Worker                                           gui::ISurfaceComposer::VsyncSource::eVsyncSourceApp,
140*38e8c45fSAndroid Build Coastguard Worker                                   EventRegistrationFlags eventRegistration = {},
141*38e8c45fSAndroid Build Coastguard Worker                                   const sp<IBinder>& layerHandle = nullptr);
142*38e8c45fSAndroid Build Coastguard Worker 
143*38e8c45fSAndroid Build Coastguard Worker     /*
144*38e8c45fSAndroid Build Coastguard Worker      * ~DisplayEventReceiver severs the connection with SurfaceFlinger, new events
145*38e8c45fSAndroid Build Coastguard Worker      * stop being delivered immediately. Note that the queue could have
146*38e8c45fSAndroid Build Coastguard Worker      * some events pending. These will be delivered.
147*38e8c45fSAndroid Build Coastguard Worker      */
148*38e8c45fSAndroid Build Coastguard Worker     ~DisplayEventReceiver();
149*38e8c45fSAndroid Build Coastguard Worker 
150*38e8c45fSAndroid Build Coastguard Worker     /*
151*38e8c45fSAndroid Build Coastguard Worker      * initCheck returns the state of DisplayEventReceiver after construction.
152*38e8c45fSAndroid Build Coastguard Worker      */
153*38e8c45fSAndroid Build Coastguard Worker     status_t initCheck() const;
154*38e8c45fSAndroid Build Coastguard Worker 
155*38e8c45fSAndroid Build Coastguard Worker     /*
156*38e8c45fSAndroid Build Coastguard Worker      * getFd returns the file descriptor to use to receive events.
157*38e8c45fSAndroid Build Coastguard Worker      * OWNERSHIP IS RETAINED by DisplayEventReceiver. DO NOT CLOSE this
158*38e8c45fSAndroid Build Coastguard Worker      * file-descriptor.
159*38e8c45fSAndroid Build Coastguard Worker      */
160*38e8c45fSAndroid Build Coastguard Worker     int getFd() const;
161*38e8c45fSAndroid Build Coastguard Worker 
162*38e8c45fSAndroid Build Coastguard Worker     /*
163*38e8c45fSAndroid Build Coastguard Worker      * getEvents reads events from the queue and returns how many events were
164*38e8c45fSAndroid Build Coastguard Worker      * read. Returns 0 if there are no more events or a negative error code.
165*38e8c45fSAndroid Build Coastguard Worker      * If NOT_ENOUGH_DATA is returned, the object has become invalid forever, it
166*38e8c45fSAndroid Build Coastguard Worker      * should be destroyed and getEvents() shouldn't be called again.
167*38e8c45fSAndroid Build Coastguard Worker      */
168*38e8c45fSAndroid Build Coastguard Worker     ssize_t getEvents(Event* events, size_t count);
169*38e8c45fSAndroid Build Coastguard Worker     static ssize_t getEvents(gui::BitTube* dataChannel, Event* events, size_t count);
170*38e8c45fSAndroid Build Coastguard Worker 
171*38e8c45fSAndroid Build Coastguard Worker     /*
172*38e8c45fSAndroid Build Coastguard Worker      * sendEvents write events to the queue and returns how many events were
173*38e8c45fSAndroid Build Coastguard Worker      * written.
174*38e8c45fSAndroid Build Coastguard Worker      */
175*38e8c45fSAndroid Build Coastguard Worker     ssize_t sendEvents(Event const* events, size_t count);
176*38e8c45fSAndroid Build Coastguard Worker     static ssize_t sendEvents(gui::BitTube* dataChannel, Event const* events, size_t count);
177*38e8c45fSAndroid Build Coastguard Worker 
178*38e8c45fSAndroid Build Coastguard Worker     /*
179*38e8c45fSAndroid Build Coastguard Worker      * setVsyncRate() sets the Event::VSync delivery rate. A value of
180*38e8c45fSAndroid Build Coastguard Worker      * 1 returns every Event::VSync. A value of 2 returns every other event,
181*38e8c45fSAndroid Build Coastguard Worker      * etc... a value of 0 returns no event unless  requestNextVsync() has
182*38e8c45fSAndroid Build Coastguard Worker      * been called.
183*38e8c45fSAndroid Build Coastguard Worker      */
184*38e8c45fSAndroid Build Coastguard Worker     status_t setVsyncRate(uint32_t count);
185*38e8c45fSAndroid Build Coastguard Worker 
186*38e8c45fSAndroid Build Coastguard Worker     /*
187*38e8c45fSAndroid Build Coastguard Worker      * requestNextVsync() schedules the next Event::VSync. It has no effect
188*38e8c45fSAndroid Build Coastguard Worker      * if the vsync rate is > 0.
189*38e8c45fSAndroid Build Coastguard Worker      */
190*38e8c45fSAndroid Build Coastguard Worker     status_t requestNextVsync();
191*38e8c45fSAndroid Build Coastguard Worker 
192*38e8c45fSAndroid Build Coastguard Worker     /**
193*38e8c45fSAndroid Build Coastguard Worker      * getLatestVsyncEventData() gets the latest vsync event data.
194*38e8c45fSAndroid Build Coastguard Worker      */
195*38e8c45fSAndroid Build Coastguard Worker     status_t getLatestVsyncEventData(ParcelableVsyncEventData* outVsyncEventData) const;
196*38e8c45fSAndroid Build Coastguard Worker 
197*38e8c45fSAndroid Build Coastguard Worker private:
198*38e8c45fSAndroid Build Coastguard Worker     sp<IDisplayEventConnection> mEventConnection;
199*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<gui::BitTube> mDataChannel;
200*38e8c45fSAndroid Build Coastguard Worker     std::optional<status_t> mInitError;
201*38e8c45fSAndroid Build Coastguard Worker };
202*38e8c45fSAndroid Build Coastguard Worker 
203*38e8c45fSAndroid Build Coastguard Worker inline bool operator==(DisplayEventReceiver::Event::FrameRateOverride lhs,
204*38e8c45fSAndroid Build Coastguard Worker                        DisplayEventReceiver::Event::FrameRateOverride rhs) {
205*38e8c45fSAndroid Build Coastguard Worker     return (lhs.uid == rhs.uid) && std::abs(lhs.frameRateHz - rhs.frameRateHz) < 0.001f;
206*38e8c45fSAndroid Build Coastguard Worker }
207*38e8c45fSAndroid Build Coastguard Worker 
208*38e8c45fSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
209*38e8c45fSAndroid Build Coastguard Worker }; // namespace android
210*38e8c45fSAndroid Build Coastguard Worker 
211*38e8c45fSAndroid Build Coastguard Worker #endif // ANDROID_GUI_DISPLAY_EVENT_H
212