blob: 66a40f127843687930a9210ef66ab883036dcedb [file] [log] [blame]
Alec Mouricc445222019-10-22 10:19:17 -07001/*
2 * Copyright (C) 2015 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
Alec Mouri271de042020-04-27 22:38:19 -070017#include <android-base/thread_annotations.h>
Huihong Luo1b0c49f2022-03-15 19:18:21 -070018#include <android/gui/ISurfaceComposer.h>
Rachel Lee273c18c2022-12-13 14:35:07 -080019#include <gui/Choreographer.h>
Orion Hodsone53587b2021-02-02 15:33:33 +000020#include <jni.h>
Alec Mouri271de042020-04-27 22:38:19 -070021#include <private/android/choreographer.h>
Alec Mouricc445222019-10-22 10:19:17 -070022#include <utils/Looper.h>
Alec Mouricc445222019-10-22 10:19:17 -070023#include <utils/Timers.h>
24
Alec Mouri60aee1c2019-10-28 16:18:59 -070025#include <cinttypes>
Alec Mouri271de042020-04-27 22:38:19 -070026#include <mutex>
Alec Mouri60aee1c2019-10-28 16:18:59 -070027#include <optional>
28#include <queue>
29#include <thread>
30
Rachel Leeace701c2022-10-05 10:23:47 -070031#undef LOG_TAG
32#define LOG_TAG "AChoreographer"
Alec Mouricc445222019-10-22 10:19:17 -070033
Alec Mouri50a931d2019-11-19 16:23:59 -080034using namespace android;
Alec Mouricc445222019-10-22 10:19:17 -070035
36static inline Choreographer* AChoreographer_to_Choreographer(AChoreographer* choreographer) {
37 return reinterpret_cast<Choreographer*>(choreographer);
38}
39
Ady Abraham74e17562020-08-24 18:18:19 -070040static inline const Choreographer* AChoreographer_to_Choreographer(
41 const AChoreographer* choreographer) {
42 return reinterpret_cast<const Choreographer*>(choreographer);
43}
44
Rachel Lee4879d812021-08-25 11:50:11 -070045static inline const ChoreographerFrameCallbackDataImpl*
46AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(
47 const AChoreographerFrameCallbackData* data) {
48 return reinterpret_cast<const ChoreographerFrameCallbackDataImpl*>(data);
49}
50
Alec Mouri271de042020-04-27 22:38:19 -070051// Glue for private C api
52namespace android {
Rachel Leeace701c2022-10-05 10:23:47 -070053void AChoreographer_signalRefreshRateCallbacks(nsecs_t vsyncPeriod) {
54 Choreographer::signalRefreshRateCallbacks(vsyncPeriod);
Alec Mouri271de042020-04-27 22:38:19 -070055}
56
57void AChoreographer_initJVM(JNIEnv* env) {
Rachel Leeace701c2022-10-05 10:23:47 -070058 Choreographer::initJVM(env);
Alec Mouri271de042020-04-27 22:38:19 -070059}
60
61AChoreographer* AChoreographer_routeGetInstance() {
62 return AChoreographer_getInstance();
63}
64void AChoreographer_routePostFrameCallback(AChoreographer* choreographer,
65 AChoreographer_frameCallback callback, void* data) {
Jiyong Park8cdf0762020-08-13 20:21:57 +090066#pragma clang diagnostic push
67#pragma clang diagnostic ignored "-Wdeprecated-declarations"
Alec Mouri271de042020-04-27 22:38:19 -070068 return AChoreographer_postFrameCallback(choreographer, callback, data);
Jiyong Park8cdf0762020-08-13 20:21:57 +090069#pragma clang diagnostic pop
Alec Mouri271de042020-04-27 22:38:19 -070070}
71void AChoreographer_routePostFrameCallbackDelayed(AChoreographer* choreographer,
72 AChoreographer_frameCallback callback, void* data,
73 long delayMillis) {
Jiyong Park8cdf0762020-08-13 20:21:57 +090074#pragma clang diagnostic push
75#pragma clang diagnostic ignored "-Wdeprecated-declarations"
Alec Mouri271de042020-04-27 22:38:19 -070076 return AChoreographer_postFrameCallbackDelayed(choreographer, callback, data, delayMillis);
Jiyong Park8cdf0762020-08-13 20:21:57 +090077#pragma clang diagnostic pop
Alec Mouri271de042020-04-27 22:38:19 -070078}
79void AChoreographer_routePostFrameCallback64(AChoreographer* choreographer,
80 AChoreographer_frameCallback64 callback, void* data) {
81 return AChoreographer_postFrameCallback64(choreographer, callback, data);
82}
83void AChoreographer_routePostFrameCallbackDelayed64(AChoreographer* choreographer,
84 AChoreographer_frameCallback64 callback,
85 void* data, uint32_t delayMillis) {
86 return AChoreographer_postFrameCallbackDelayed64(choreographer, callback, data, delayMillis);
87}
Rachel Leef4dc39f2022-02-15 18:30:59 -080088void AChoreographer_routePostVsyncCallback(AChoreographer* choreographer,
89 AChoreographer_vsyncCallback callback, void* data) {
90 return AChoreographer_postVsyncCallback(choreographer, callback, data);
Rachel Lee4879d812021-08-25 11:50:11 -070091}
Alec Mouri271de042020-04-27 22:38:19 -070092void AChoreographer_routeRegisterRefreshRateCallback(AChoreographer* choreographer,
93 AChoreographer_refreshRateCallback callback,
94 void* data) {
95 return AChoreographer_registerRefreshRateCallback(choreographer, callback, data);
96}
97void AChoreographer_routeUnregisterRefreshRateCallback(AChoreographer* choreographer,
98 AChoreographer_refreshRateCallback callback,
99 void* data) {
100 return AChoreographer_unregisterRefreshRateCallback(choreographer, callback, data);
101}
Rachel Lee4879d812021-08-25 11:50:11 -0700102int64_t AChoreographerFrameCallbackData_routeGetFrameTimeNanos(
103 const AChoreographerFrameCallbackData* data) {
104 return AChoreographerFrameCallbackData_getFrameTimeNanos(data);
105}
106size_t AChoreographerFrameCallbackData_routeGetFrameTimelinesLength(
107 const AChoreographerFrameCallbackData* data) {
108 return AChoreographerFrameCallbackData_getFrameTimelinesLength(data);
109}
110size_t AChoreographerFrameCallbackData_routeGetPreferredFrameTimelineIndex(
111 const AChoreographerFrameCallbackData* data) {
112 return AChoreographerFrameCallbackData_getPreferredFrameTimelineIndex(data);
113}
Rachel Lee1fb2ddc2022-01-12 14:33:07 -0800114AVsyncId AChoreographerFrameCallbackData_routeGetFrameTimelineVsyncId(
Rachel Lee4879d812021-08-25 11:50:11 -0700115 const AChoreographerFrameCallbackData* data, size_t index) {
116 return AChoreographerFrameCallbackData_getFrameTimelineVsyncId(data, index);
117}
Rachel Leef4dc39f2022-02-15 18:30:59 -0800118int64_t AChoreographerFrameCallbackData_routeGetFrameTimelineExpectedPresentationTimeNanos(
Rachel Lee4879d812021-08-25 11:50:11 -0700119 const AChoreographerFrameCallbackData* data, size_t index) {
Rachel Leef4dc39f2022-02-15 18:30:59 -0800120 return AChoreographerFrameCallbackData_getFrameTimelineExpectedPresentationTimeNanos(data,
121 index);
Rachel Lee4879d812021-08-25 11:50:11 -0700122}
Rachel Lee2825fa22022-01-12 17:35:16 -0800123int64_t AChoreographerFrameCallbackData_routeGetFrameTimelineDeadlineNanos(
Rachel Lee4879d812021-08-25 11:50:11 -0700124 const AChoreographerFrameCallbackData* data, size_t index) {
Rachel Lee2825fa22022-01-12 17:35:16 -0800125 return AChoreographerFrameCallbackData_getFrameTimelineDeadlineNanos(data, index);
Rachel Lee4879d812021-08-25 11:50:11 -0700126}
Alec Mouri271de042020-04-27 22:38:19 -0700127
Jorim Jaggic0086af2021-02-12 18:18:11 +0100128int64_t AChoreographer_getFrameInterval(const AChoreographer* choreographer) {
129 return AChoreographer_to_Choreographer(choreographer)->getFrameInterval();
130}
131
Rachel Lee103a58a2022-02-22 15:51:05 -0800132int64_t AChoreographer_getStartTimeNanosForVsyncId(AVsyncId vsyncId) {
Rachel Leeace701c2022-10-05 10:23:47 -0700133 return Choreographer::getStartTimeNanosForVsyncId(vsyncId);
Rachel Lee103a58a2022-02-22 15:51:05 -0800134}
135
Alec Mouri271de042020-04-27 22:38:19 -0700136} // namespace android
137
138/* Glue for the NDK interface */
139
Alec Mouricc445222019-10-22 10:19:17 -0700140static inline AChoreographer* Choreographer_to_AChoreographer(Choreographer* choreographer) {
141 return reinterpret_cast<AChoreographer*>(choreographer);
142}
143
144AChoreographer* AChoreographer_getInstance() {
145 return Choreographer_to_AChoreographer(Choreographer::getForThread());
146}
147
148void AChoreographer_postFrameCallback(AChoreographer* choreographer,
Rachel Lee4879d812021-08-25 11:50:11 -0700149 AChoreographer_frameCallback callback, void* data) {
150 AChoreographer_to_Choreographer(choreographer)
151 ->postFrameCallbackDelayed(callback, nullptr, nullptr, data, 0);
Alec Mouricc445222019-10-22 10:19:17 -0700152}
153void AChoreographer_postFrameCallbackDelayed(AChoreographer* choreographer,
Rachel Lee4879d812021-08-25 11:50:11 -0700154 AChoreographer_frameCallback callback, void* data,
155 long delayMillis) {
156 AChoreographer_to_Choreographer(choreographer)
157 ->postFrameCallbackDelayed(callback, nullptr, nullptr, data, ms2ns(delayMillis));
158}
Rachel Leef4dc39f2022-02-15 18:30:59 -0800159void AChoreographer_postVsyncCallback(AChoreographer* choreographer,
160 AChoreographer_vsyncCallback callback, void* data) {
Rachel Lee4879d812021-08-25 11:50:11 -0700161 AChoreographer_to_Choreographer(choreographer)
162 ->postFrameCallbackDelayed(nullptr, nullptr, callback, data, 0);
Alec Mouricc445222019-10-22 10:19:17 -0700163}
164void AChoreographer_postFrameCallback64(AChoreographer* choreographer,
Rachel Lee4879d812021-08-25 11:50:11 -0700165 AChoreographer_frameCallback64 callback, void* data) {
166 AChoreographer_to_Choreographer(choreographer)
167 ->postFrameCallbackDelayed(nullptr, callback, nullptr, data, 0);
Alec Mouricc445222019-10-22 10:19:17 -0700168}
169void AChoreographer_postFrameCallbackDelayed64(AChoreographer* choreographer,
Rachel Lee4879d812021-08-25 11:50:11 -0700170 AChoreographer_frameCallback64 callback, void* data,
171 uint32_t delayMillis) {
172 AChoreographer_to_Choreographer(choreographer)
173 ->postFrameCallbackDelayed(nullptr, callback, nullptr, data, ms2ns(delayMillis));
Alec Mouricc445222019-10-22 10:19:17 -0700174}
Alec Mouri60aee1c2019-10-28 16:18:59 -0700175void AChoreographer_registerRefreshRateCallback(AChoreographer* choreographer,
176 AChoreographer_refreshRateCallback callback,
177 void* data) {
178 AChoreographer_to_Choreographer(choreographer)->registerRefreshRateCallback(callback, data);
179}
180void AChoreographer_unregisterRefreshRateCallback(AChoreographer* choreographer,
Alec Mouri33682e92020-01-10 15:11:15 -0800181 AChoreographer_refreshRateCallback callback,
182 void* data) {
183 AChoreographer_to_Choreographer(choreographer)->unregisterRefreshRateCallback(callback, data);
Alec Mouri60aee1c2019-10-28 16:18:59 -0700184}
Alec Mouri50a931d2019-11-19 16:23:59 -0800185
Rachel Lee4879d812021-08-25 11:50:11 -0700186int64_t AChoreographerFrameCallbackData_getFrameTimeNanos(
187 const AChoreographerFrameCallbackData* data) {
188 const ChoreographerFrameCallbackDataImpl* frameCallbackData =
189 AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
190 LOG_ALWAYS_FATAL_IF(!frameCallbackData->choreographer->inCallback(),
191 "Data is only valid in callback");
192 return frameCallbackData->frameTimeNanos;
193}
194size_t AChoreographerFrameCallbackData_getFrameTimelinesLength(
195 const AChoreographerFrameCallbackData* data) {
196 const ChoreographerFrameCallbackDataImpl* frameCallbackData =
197 AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
198 LOG_ALWAYS_FATAL_IF(!frameCallbackData->choreographer->inCallback(),
199 "Data is only valid in callback");
Rachel Leeb9c5a772022-02-04 21:17:37 -0800200 return VsyncEventData::kFrameTimelinesLength;
Rachel Lee4879d812021-08-25 11:50:11 -0700201}
202size_t AChoreographerFrameCallbackData_getPreferredFrameTimelineIndex(
203 const AChoreographerFrameCallbackData* data) {
204 const ChoreographerFrameCallbackDataImpl* frameCallbackData =
205 AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
206 LOG_ALWAYS_FATAL_IF(!frameCallbackData->choreographer->inCallback(),
207 "Data is only valid in callback");
Rachel Leeb9c5a772022-02-04 21:17:37 -0800208 return frameCallbackData->vsyncEventData.preferredFrameTimelineIndex;
Rachel Lee4879d812021-08-25 11:50:11 -0700209}
Rachel Lee1fb2ddc2022-01-12 14:33:07 -0800210AVsyncId AChoreographerFrameCallbackData_getFrameTimelineVsyncId(
Rachel Lee4879d812021-08-25 11:50:11 -0700211 const AChoreographerFrameCallbackData* data, size_t index) {
212 const ChoreographerFrameCallbackDataImpl* frameCallbackData =
213 AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
214 LOG_ALWAYS_FATAL_IF(!frameCallbackData->choreographer->inCallback(),
215 "Data is only valid in callback");
Rachel Leeb9c5a772022-02-04 21:17:37 -0800216 LOG_ALWAYS_FATAL_IF(index >= VsyncEventData::kFrameTimelinesLength, "Index out of bounds");
217 return frameCallbackData->vsyncEventData.frameTimelines[index].vsyncId;
Rachel Lee4879d812021-08-25 11:50:11 -0700218}
Rachel Leef4dc39f2022-02-15 18:30:59 -0800219int64_t AChoreographerFrameCallbackData_getFrameTimelineExpectedPresentationTimeNanos(
Rachel Lee4879d812021-08-25 11:50:11 -0700220 const AChoreographerFrameCallbackData* data, size_t index) {
221 const ChoreographerFrameCallbackDataImpl* frameCallbackData =
222 AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
223 LOG_ALWAYS_FATAL_IF(!frameCallbackData->choreographer->inCallback(),
224 "Data is only valid in callback");
Rachel Leeb9c5a772022-02-04 21:17:37 -0800225 LOG_ALWAYS_FATAL_IF(index >= VsyncEventData::kFrameTimelinesLength, "Index out of bounds");
226 return frameCallbackData->vsyncEventData.frameTimelines[index].expectedPresentationTime;
Rachel Lee4879d812021-08-25 11:50:11 -0700227}
Rachel Lee2825fa22022-01-12 17:35:16 -0800228int64_t AChoreographerFrameCallbackData_getFrameTimelineDeadlineNanos(
Rachel Lee4879d812021-08-25 11:50:11 -0700229 const AChoreographerFrameCallbackData* data, size_t index) {
230 const ChoreographerFrameCallbackDataImpl* frameCallbackData =
231 AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
232 LOG_ALWAYS_FATAL_IF(!frameCallbackData->choreographer->inCallback(),
233 "Data is only valid in callback");
Rachel Leeb9c5a772022-02-04 21:17:37 -0800234 LOG_ALWAYS_FATAL_IF(index >= VsyncEventData::kFrameTimelinesLength, "Index out of bounds");
235 return frameCallbackData->vsyncEventData.frameTimelines[index].deadlineTimestamp;
Rachel Lee4879d812021-08-25 11:50:11 -0700236}
237
Alec Mouri50a931d2019-11-19 16:23:59 -0800238AChoreographer* AChoreographer_create() {
239 Choreographer* choreographer = new Choreographer(nullptr);
240 status_t result = choreographer->initialize();
241 if (result != OK) {
242 ALOGW("Failed to initialize");
243 return nullptr;
244 }
245 return Choreographer_to_AChoreographer(choreographer);
246}
247
248void AChoreographer_destroy(AChoreographer* choreographer) {
249 if (choreographer == nullptr) {
250 return;
251 }
252
253 delete AChoreographer_to_Choreographer(choreographer);
254}
255
Alec Mouri921b2772020-02-05 19:03:28 -0800256int AChoreographer_getFd(const AChoreographer* choreographer) {
Alec Mouri50a931d2019-11-19 16:23:59 -0800257 return AChoreographer_to_Choreographer(choreographer)->getFd();
258}
259
260void AChoreographer_handlePendingEvents(AChoreographer* choreographer, void* data) {
261 // Pass dummy fd and events args to handleEvent, since the underlying
262 // DisplayEventDispatcher doesn't need them outside of validating that a
263 // Looper instance didn't break, but these args circumvent those checks.
Alec Mouri271de042020-04-27 22:38:19 -0700264 Choreographer* impl = AChoreographer_to_Choreographer(choreographer);
265 impl->handleEvent(-1, Looper::EVENT_INPUT, data);
Alec Mouri50a931d2019-11-19 16:23:59 -0800266}