blob: bed31e27a88123c83b05a468445f1494bced880a [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)
Chavi Weingarten475c4132024-02-29 15:56:15 +0000151 ->postFrameCallbackDelayed(callback, nullptr, nullptr, data, 0, CALLBACK_ANIMATION);
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)
Chavi Weingarten475c4132024-02-29 15:56:15 +0000157 ->postFrameCallbackDelayed(callback, nullptr, nullptr, data, ms2ns(delayMillis),
158 CALLBACK_ANIMATION);
Rachel Lee4879d812021-08-25 11:50:11 -0700159}
Rachel Leef4dc39f2022-02-15 18:30:59 -0800160void AChoreographer_postVsyncCallback(AChoreographer* choreographer,
161 AChoreographer_vsyncCallback callback, void* data) {
Rachel Lee4879d812021-08-25 11:50:11 -0700162 AChoreographer_to_Choreographer(choreographer)
Chavi Weingarten475c4132024-02-29 15:56:15 +0000163 ->postFrameCallbackDelayed(nullptr, nullptr, callback, data, 0, CALLBACK_ANIMATION);
Alec Mouricc445222019-10-22 10:19:17 -0700164}
165void AChoreographer_postFrameCallback64(AChoreographer* choreographer,
Rachel Lee4879d812021-08-25 11:50:11 -0700166 AChoreographer_frameCallback64 callback, void* data) {
167 AChoreographer_to_Choreographer(choreographer)
Chavi Weingarten475c4132024-02-29 15:56:15 +0000168 ->postFrameCallbackDelayed(nullptr, callback, nullptr, data, 0, CALLBACK_ANIMATION);
Alec Mouricc445222019-10-22 10:19:17 -0700169}
170void AChoreographer_postFrameCallbackDelayed64(AChoreographer* choreographer,
Rachel Lee4879d812021-08-25 11:50:11 -0700171 AChoreographer_frameCallback64 callback, void* data,
172 uint32_t delayMillis) {
173 AChoreographer_to_Choreographer(choreographer)
Chavi Weingarten475c4132024-02-29 15:56:15 +0000174 ->postFrameCallbackDelayed(nullptr, callback, nullptr, data, ms2ns(delayMillis),
175 CALLBACK_ANIMATION);
Alec Mouricc445222019-10-22 10:19:17 -0700176}
Alec Mouri60aee1c2019-10-28 16:18:59 -0700177void AChoreographer_registerRefreshRateCallback(AChoreographer* choreographer,
178 AChoreographer_refreshRateCallback callback,
179 void* data) {
180 AChoreographer_to_Choreographer(choreographer)->registerRefreshRateCallback(callback, data);
181}
182void AChoreographer_unregisterRefreshRateCallback(AChoreographer* choreographer,
Alec Mouri33682e92020-01-10 15:11:15 -0800183 AChoreographer_refreshRateCallback callback,
184 void* data) {
185 AChoreographer_to_Choreographer(choreographer)->unregisterRefreshRateCallback(callback, data);
Alec Mouri60aee1c2019-10-28 16:18:59 -0700186}
Alec Mouri50a931d2019-11-19 16:23:59 -0800187
Rachel Lee4879d812021-08-25 11:50:11 -0700188int64_t AChoreographerFrameCallbackData_getFrameTimeNanos(
189 const AChoreographerFrameCallbackData* data) {
190 const ChoreographerFrameCallbackDataImpl* frameCallbackData =
191 AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
192 LOG_ALWAYS_FATAL_IF(!frameCallbackData->choreographer->inCallback(),
193 "Data is only valid in callback");
194 return frameCallbackData->frameTimeNanos;
195}
196size_t AChoreographerFrameCallbackData_getFrameTimelinesLength(
197 const AChoreographerFrameCallbackData* data) {
198 const ChoreographerFrameCallbackDataImpl* frameCallbackData =
199 AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
200 LOG_ALWAYS_FATAL_IF(!frameCallbackData->choreographer->inCallback(),
201 "Data is only valid in callback");
Rachel Lee0655a912023-04-20 19:54:18 -0700202 return frameCallbackData->vsyncEventData.frameTimelinesLength;
Rachel Lee4879d812021-08-25 11:50:11 -0700203}
204size_t AChoreographerFrameCallbackData_getPreferredFrameTimelineIndex(
205 const AChoreographerFrameCallbackData* data) {
206 const ChoreographerFrameCallbackDataImpl* frameCallbackData =
207 AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
208 LOG_ALWAYS_FATAL_IF(!frameCallbackData->choreographer->inCallback(),
209 "Data is only valid in callback");
Rachel Leeb9c5a772022-02-04 21:17:37 -0800210 return frameCallbackData->vsyncEventData.preferredFrameTimelineIndex;
Rachel Lee4879d812021-08-25 11:50:11 -0700211}
Rachel Lee1fb2ddc2022-01-12 14:33:07 -0800212AVsyncId AChoreographerFrameCallbackData_getFrameTimelineVsyncId(
Rachel Lee4879d812021-08-25 11:50:11 -0700213 const AChoreographerFrameCallbackData* data, size_t index) {
214 const ChoreographerFrameCallbackDataImpl* frameCallbackData =
215 AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
216 LOG_ALWAYS_FATAL_IF(!frameCallbackData->choreographer->inCallback(),
217 "Data is only valid in callback");
Rachel Lee40aef422023-04-25 14:35:47 -0700218 LOG_ALWAYS_FATAL_IF(index >= VsyncEventData::kFrameTimelinesCapacity, "Index out of bounds");
Rachel Leeb9c5a772022-02-04 21:17:37 -0800219 return frameCallbackData->vsyncEventData.frameTimelines[index].vsyncId;
Rachel Lee4879d812021-08-25 11:50:11 -0700220}
Rachel Leef4dc39f2022-02-15 18:30:59 -0800221int64_t AChoreographerFrameCallbackData_getFrameTimelineExpectedPresentationTimeNanos(
Rachel Lee4879d812021-08-25 11:50:11 -0700222 const AChoreographerFrameCallbackData* data, size_t index) {
223 const ChoreographerFrameCallbackDataImpl* frameCallbackData =
224 AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
225 LOG_ALWAYS_FATAL_IF(!frameCallbackData->choreographer->inCallback(),
226 "Data is only valid in callback");
Rachel Lee40aef422023-04-25 14:35:47 -0700227 LOG_ALWAYS_FATAL_IF(index >= VsyncEventData::kFrameTimelinesCapacity, "Index out of bounds");
Rachel Leeb9c5a772022-02-04 21:17:37 -0800228 return frameCallbackData->vsyncEventData.frameTimelines[index].expectedPresentationTime;
Rachel Lee4879d812021-08-25 11:50:11 -0700229}
Rachel Lee2825fa22022-01-12 17:35:16 -0800230int64_t AChoreographerFrameCallbackData_getFrameTimelineDeadlineNanos(
Rachel Lee4879d812021-08-25 11:50:11 -0700231 const AChoreographerFrameCallbackData* data, size_t index) {
232 const ChoreographerFrameCallbackDataImpl* frameCallbackData =
233 AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
234 LOG_ALWAYS_FATAL_IF(!frameCallbackData->choreographer->inCallback(),
235 "Data is only valid in callback");
Rachel Lee40aef422023-04-25 14:35:47 -0700236 LOG_ALWAYS_FATAL_IF(index >= VsyncEventData::kFrameTimelinesCapacity, "Index out of bounds");
Rachel Leeb9c5a772022-02-04 21:17:37 -0800237 return frameCallbackData->vsyncEventData.frameTimelines[index].deadlineTimestamp;
Rachel Lee4879d812021-08-25 11:50:11 -0700238}
239
Alec Mouri50a931d2019-11-19 16:23:59 -0800240AChoreographer* AChoreographer_create() {
241 Choreographer* choreographer = new Choreographer(nullptr);
242 status_t result = choreographer->initialize();
243 if (result != OK) {
244 ALOGW("Failed to initialize");
245 return nullptr;
246 }
247 return Choreographer_to_AChoreographer(choreographer);
248}
249
250void AChoreographer_destroy(AChoreographer* choreographer) {
251 if (choreographer == nullptr) {
252 return;
253 }
254
255 delete AChoreographer_to_Choreographer(choreographer);
256}
257
Alec Mouri921b2772020-02-05 19:03:28 -0800258int AChoreographer_getFd(const AChoreographer* choreographer) {
Alec Mouri50a931d2019-11-19 16:23:59 -0800259 return AChoreographer_to_Choreographer(choreographer)->getFd();
260}
261
262void AChoreographer_handlePendingEvents(AChoreographer* choreographer, void* data) {
263 // Pass dummy fd and events args to handleEvent, since the underlying
264 // DisplayEventDispatcher doesn't need them outside of validating that a
265 // Looper instance didn't break, but these args circumvent those checks.
Alec Mouri271de042020-04-27 22:38:19 -0700266 Choreographer* impl = AChoreographer_to_Choreographer(choreographer);
267 impl->handleEvent(-1, Looper::EVENT_INPUT, data);
Alec Mouri50a931d2019-11-19 16:23:59 -0800268}