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