• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 #include <android-base/thread_annotations.h>
18 #include <android/gui/ISurfaceComposer.h>
19 #include <gui/Choreographer.h>
20 #include <jni.h>
21 #include <private/android/choreographer.h>
22 #include <utils/Looper.h>
23 #include <utils/Timers.h>
24 
25 #include <cinttypes>
26 #include <mutex>
27 #include <optional>
28 #include <queue>
29 #include <thread>
30 
31 #undef LOG_TAG
32 #define LOG_TAG "AChoreographer"
33 
34 using namespace android;
35 
AChoreographer_to_Choreographer(AChoreographer * choreographer)36 static inline Choreographer* AChoreographer_to_Choreographer(AChoreographer* choreographer) {
37     return reinterpret_cast<Choreographer*>(choreographer);
38 }
39 
AChoreographer_to_Choreographer(const AChoreographer * choreographer)40 static inline const Choreographer* AChoreographer_to_Choreographer(
41         const AChoreographer* choreographer) {
42     return reinterpret_cast<const Choreographer*>(choreographer);
43 }
44 
45 static inline const ChoreographerFrameCallbackDataImpl*
AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(const AChoreographerFrameCallbackData * data)46 AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(
47         const AChoreographerFrameCallbackData* data) {
48     return reinterpret_cast<const ChoreographerFrameCallbackDataImpl*>(data);
49 }
50 
51 // Glue for private C api
52 namespace android {
AChoreographer_signalRefreshRateCallbacks(nsecs_t vsyncPeriod)53 void AChoreographer_signalRefreshRateCallbacks(nsecs_t vsyncPeriod) {
54     Choreographer::signalRefreshRateCallbacks(vsyncPeriod);
55 }
56 
AChoreographer_initJVM(JNIEnv * env)57 void AChoreographer_initJVM(JNIEnv* env) {
58     Choreographer::initJVM(env);
59 }
60 
AChoreographer_routeGetInstance()61 AChoreographer* AChoreographer_routeGetInstance() {
62     return AChoreographer_getInstance();
63 }
AChoreographer_routePostFrameCallback(AChoreographer * choreographer,AChoreographer_frameCallback callback,void * data)64 void AChoreographer_routePostFrameCallback(AChoreographer* choreographer,
65                                            AChoreographer_frameCallback callback, void* data) {
66 #pragma clang diagnostic push
67 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
68     return AChoreographer_postFrameCallback(choreographer, callback, data);
69 #pragma clang diagnostic pop
70 }
AChoreographer_routePostFrameCallbackDelayed(AChoreographer * choreographer,AChoreographer_frameCallback callback,void * data,long delayMillis)71 void AChoreographer_routePostFrameCallbackDelayed(AChoreographer* choreographer,
72                                                   AChoreographer_frameCallback callback, void* data,
73                                                   long delayMillis) {
74 #pragma clang diagnostic push
75 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
76     return AChoreographer_postFrameCallbackDelayed(choreographer, callback, data, delayMillis);
77 #pragma clang diagnostic pop
78 }
AChoreographer_routePostFrameCallback64(AChoreographer * choreographer,AChoreographer_frameCallback64 callback,void * data)79 void AChoreographer_routePostFrameCallback64(AChoreographer* choreographer,
80                                              AChoreographer_frameCallback64 callback, void* data) {
81     return AChoreographer_postFrameCallback64(choreographer, callback, data);
82 }
AChoreographer_routePostFrameCallbackDelayed64(AChoreographer * choreographer,AChoreographer_frameCallback64 callback,void * data,uint32_t delayMillis)83 void AChoreographer_routePostFrameCallbackDelayed64(AChoreographer* choreographer,
84                                                     AChoreographer_frameCallback64 callback,
85                                                     void* data, uint32_t delayMillis) {
86     return AChoreographer_postFrameCallbackDelayed64(choreographer, callback, data, delayMillis);
87 }
AChoreographer_routePostVsyncCallback(AChoreographer * choreographer,AChoreographer_vsyncCallback callback,void * data)88 void AChoreographer_routePostVsyncCallback(AChoreographer* choreographer,
89                                            AChoreographer_vsyncCallback callback, void* data) {
90     return AChoreographer_postVsyncCallback(choreographer, callback, data);
91 }
AChoreographer_routeRegisterRefreshRateCallback(AChoreographer * choreographer,AChoreographer_refreshRateCallback callback,void * data)92 void AChoreographer_routeRegisterRefreshRateCallback(AChoreographer* choreographer,
93                                                      AChoreographer_refreshRateCallback callback,
94                                                      void* data) {
95     return AChoreographer_registerRefreshRateCallback(choreographer, callback, data);
96 }
AChoreographer_routeUnregisterRefreshRateCallback(AChoreographer * choreographer,AChoreographer_refreshRateCallback callback,void * data)97 void AChoreographer_routeUnregisterRefreshRateCallback(AChoreographer* choreographer,
98                                                        AChoreographer_refreshRateCallback callback,
99                                                        void* data) {
100     return AChoreographer_unregisterRefreshRateCallback(choreographer, callback, data);
101 }
AChoreographerFrameCallbackData_routeGetFrameTimeNanos(const AChoreographerFrameCallbackData * data)102 int64_t AChoreographerFrameCallbackData_routeGetFrameTimeNanos(
103         const AChoreographerFrameCallbackData* data) {
104     return AChoreographerFrameCallbackData_getFrameTimeNanos(data);
105 }
AChoreographerFrameCallbackData_routeGetFrameTimelinesLength(const AChoreographerFrameCallbackData * data)106 size_t AChoreographerFrameCallbackData_routeGetFrameTimelinesLength(
107         const AChoreographerFrameCallbackData* data) {
108     return AChoreographerFrameCallbackData_getFrameTimelinesLength(data);
109 }
AChoreographerFrameCallbackData_routeGetPreferredFrameTimelineIndex(const AChoreographerFrameCallbackData * data)110 size_t AChoreographerFrameCallbackData_routeGetPreferredFrameTimelineIndex(
111         const AChoreographerFrameCallbackData* data) {
112     return AChoreographerFrameCallbackData_getPreferredFrameTimelineIndex(data);
113 }
AChoreographerFrameCallbackData_routeGetFrameTimelineVsyncId(const AChoreographerFrameCallbackData * data,size_t index)114 AVsyncId AChoreographerFrameCallbackData_routeGetFrameTimelineVsyncId(
115         const AChoreographerFrameCallbackData* data, size_t index) {
116     return AChoreographerFrameCallbackData_getFrameTimelineVsyncId(data, index);
117 }
AChoreographerFrameCallbackData_routeGetFrameTimelineExpectedPresentationTimeNanos(const AChoreographerFrameCallbackData * data,size_t index)118 int64_t AChoreographerFrameCallbackData_routeGetFrameTimelineExpectedPresentationTimeNanos(
119         const AChoreographerFrameCallbackData* data, size_t index) {
120     return AChoreographerFrameCallbackData_getFrameTimelineExpectedPresentationTimeNanos(data,
121                                                                                          index);
122 }
AChoreographerFrameCallbackData_routeGetFrameTimelineDeadlineNanos(const AChoreographerFrameCallbackData * data,size_t index)123 int64_t AChoreographerFrameCallbackData_routeGetFrameTimelineDeadlineNanos(
124         const AChoreographerFrameCallbackData* data, size_t index) {
125     return AChoreographerFrameCallbackData_getFrameTimelineDeadlineNanos(data, index);
126 }
127 
AChoreographer_getFrameInterval(const AChoreographer * choreographer)128 int64_t AChoreographer_getFrameInterval(const AChoreographer* choreographer) {
129     return AChoreographer_to_Choreographer(choreographer)->getFrameInterval();
130 }
131 
AChoreographer_getStartTimeNanosForVsyncId(AVsyncId vsyncId)132 int64_t AChoreographer_getStartTimeNanosForVsyncId(AVsyncId vsyncId) {
133     return Choreographer::getStartTimeNanosForVsyncId(vsyncId);
134 }
135 
136 } // namespace android
137 
138 /* Glue for the NDK interface */
139 
Choreographer_to_AChoreographer(Choreographer * choreographer)140 static inline AChoreographer* Choreographer_to_AChoreographer(Choreographer* choreographer) {
141     return reinterpret_cast<AChoreographer*>(choreographer);
142 }
143 
AChoreographer_getInstance()144 AChoreographer* AChoreographer_getInstance() {
145     return Choreographer_to_AChoreographer(Choreographer::getForThread());
146 }
147 
AChoreographer_postFrameCallback(AChoreographer * choreographer,AChoreographer_frameCallback callback,void * data)148 void AChoreographer_postFrameCallback(AChoreographer* choreographer,
149                                       AChoreographer_frameCallback callback, void* data) {
150     AChoreographer_to_Choreographer(choreographer)
151             ->postFrameCallbackDelayed(callback, nullptr, nullptr, data, 0);
152 }
AChoreographer_postFrameCallbackDelayed(AChoreographer * choreographer,AChoreographer_frameCallback callback,void * data,long delayMillis)153 void AChoreographer_postFrameCallbackDelayed(AChoreographer* choreographer,
154                                              AChoreographer_frameCallback callback, void* data,
155                                              long delayMillis) {
156     AChoreographer_to_Choreographer(choreographer)
157             ->postFrameCallbackDelayed(callback, nullptr, nullptr, data, ms2ns(delayMillis));
158 }
AChoreographer_postVsyncCallback(AChoreographer * choreographer,AChoreographer_vsyncCallback callback,void * data)159 void AChoreographer_postVsyncCallback(AChoreographer* choreographer,
160                                       AChoreographer_vsyncCallback callback, void* data) {
161     AChoreographer_to_Choreographer(choreographer)
162             ->postFrameCallbackDelayed(nullptr, nullptr, callback, data, 0);
163 }
AChoreographer_postFrameCallback64(AChoreographer * choreographer,AChoreographer_frameCallback64 callback,void * data)164 void AChoreographer_postFrameCallback64(AChoreographer* choreographer,
165                                         AChoreographer_frameCallback64 callback, void* data) {
166     AChoreographer_to_Choreographer(choreographer)
167             ->postFrameCallbackDelayed(nullptr, callback, nullptr, data, 0);
168 }
AChoreographer_postFrameCallbackDelayed64(AChoreographer * choreographer,AChoreographer_frameCallback64 callback,void * data,uint32_t delayMillis)169 void AChoreographer_postFrameCallbackDelayed64(AChoreographer* choreographer,
170                                                AChoreographer_frameCallback64 callback, void* data,
171                                                uint32_t delayMillis) {
172     AChoreographer_to_Choreographer(choreographer)
173             ->postFrameCallbackDelayed(nullptr, callback, nullptr, data, ms2ns(delayMillis));
174 }
AChoreographer_registerRefreshRateCallback(AChoreographer * choreographer,AChoreographer_refreshRateCallback callback,void * data)175 void AChoreographer_registerRefreshRateCallback(AChoreographer* choreographer,
176                                                 AChoreographer_refreshRateCallback callback,
177                                                 void* data) {
178     AChoreographer_to_Choreographer(choreographer)->registerRefreshRateCallback(callback, data);
179 }
AChoreographer_unregisterRefreshRateCallback(AChoreographer * choreographer,AChoreographer_refreshRateCallback callback,void * data)180 void AChoreographer_unregisterRefreshRateCallback(AChoreographer* choreographer,
181                                                   AChoreographer_refreshRateCallback callback,
182                                                   void* data) {
183     AChoreographer_to_Choreographer(choreographer)->unregisterRefreshRateCallback(callback, data);
184 }
185 
AChoreographerFrameCallbackData_getFrameTimeNanos(const AChoreographerFrameCallbackData * data)186 int64_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 }
AChoreographerFrameCallbackData_getFrameTimelinesLength(const AChoreographerFrameCallbackData * data)194 size_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");
200     return frameCallbackData->vsyncEventData.frameTimelinesLength;
201 }
AChoreographerFrameCallbackData_getPreferredFrameTimelineIndex(const AChoreographerFrameCallbackData * data)202 size_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");
208     return frameCallbackData->vsyncEventData.preferredFrameTimelineIndex;
209 }
AChoreographerFrameCallbackData_getFrameTimelineVsyncId(const AChoreographerFrameCallbackData * data,size_t index)210 AVsyncId AChoreographerFrameCallbackData_getFrameTimelineVsyncId(
211         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");
216     LOG_ALWAYS_FATAL_IF(index >= VsyncEventData::kFrameTimelinesCapacity, "Index out of bounds");
217     return frameCallbackData->vsyncEventData.frameTimelines[index].vsyncId;
218 }
AChoreographerFrameCallbackData_getFrameTimelineExpectedPresentationTimeNanos(const AChoreographerFrameCallbackData * data,size_t index)219 int64_t AChoreographerFrameCallbackData_getFrameTimelineExpectedPresentationTimeNanos(
220         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");
225     LOG_ALWAYS_FATAL_IF(index >= VsyncEventData::kFrameTimelinesCapacity, "Index out of bounds");
226     return frameCallbackData->vsyncEventData.frameTimelines[index].expectedPresentationTime;
227 }
AChoreographerFrameCallbackData_getFrameTimelineDeadlineNanos(const AChoreographerFrameCallbackData * data,size_t index)228 int64_t AChoreographerFrameCallbackData_getFrameTimelineDeadlineNanos(
229         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");
234     LOG_ALWAYS_FATAL_IF(index >= VsyncEventData::kFrameTimelinesCapacity, "Index out of bounds");
235     return frameCallbackData->vsyncEventData.frameTimelines[index].deadlineTimestamp;
236 }
237 
AChoreographer_create()238 AChoreographer* 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 
AChoreographer_destroy(AChoreographer * choreographer)248 void AChoreographer_destroy(AChoreographer* choreographer) {
249     if (choreographer == nullptr) {
250         return;
251     }
252 
253     delete AChoreographer_to_Choreographer(choreographer);
254 }
255 
AChoreographer_getFd(const AChoreographer * choreographer)256 int AChoreographer_getFd(const AChoreographer* choreographer) {
257     return AChoreographer_to_Choreographer(choreographer)->getFd();
258 }
259 
AChoreographer_handlePendingEvents(AChoreographer * choreographer,void * data)260 void 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.
264     Choreographer* impl = AChoreographer_to_Choreographer(choreographer);
265     impl->handleEvent(-1, Looper::EVENT_INPUT, data);
266 }
267