diff options
author | Dan Albert <danalbert@google.com> | 2024-05-08 22:03:34 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2024-05-08 22:03:34 +0000 |
commit | abb750fe27022b09cd5c40ce39a110b02d22bdd8 (patch) | |
tree | 4506de42b7b882bbb05aa96bf9c687fa9d41194f | |
parent | 17af17462772b1cde025ae8c99d4d80fd6d9f3d0 (diff) | |
parent | dc9c4118732034f71aa275843d4c09ee78536829 (diff) | |
download | native-abb750fe27022b09cd5c40ce39a110b02d22bdd8.tar.gz |
Merge changes I48490112,I4227ce3f,I020a2803 into main
* changes:
Expand Choreographer docs.
Restore docs for deprecated Choreographer APIs.
Improve ALooper_pollAll/ALooper_pollOnce docs.
-rw-r--r-- | include/android/choreographer.h | 85 | ||||
-rw-r--r-- | include/android/looper.h | 43 |
2 files changed, 102 insertions, 26 deletions
diff --git a/include/android/choreographer.h b/include/android/choreographer.h index c4d1ca65be..6a91d9836e 100644 --- a/include/android/choreographer.h +++ b/include/android/choreographer.h @@ -17,8 +17,20 @@ /** * @addtogroup Choreographer * - * Choreographer coordinates the timing of frame rendering. This is the C version of the - * android.view.Choreographer object in Java. + * Choreographer coordinates the timing of frame rendering. This is the C + * version of the android.view.Choreographer object in Java. If you do not use + * Choreographer to pace your render loop, you may render too quickly for the + * display, increasing latency between frame submission and presentation. + * + * Input events are guaranteed to be processed before the frame callback is + * called, and will not be run concurrently. Input and sensor events should not + * be handled in the Choregrapher callback. + * + * The frame callback is also the appropriate place to run any per-frame state + * update logic. For example, in a game, the frame callback should be + * responsible for updating things like physics, AI, game state, and rendering + * the frame. Input and sensors should be handled separately via callbacks + * registered with AInputQueue and ASensorManager. * * As of API level 33, apps can follow proper frame pacing and even choose a future frame to render. * The API is used as follows: @@ -38,6 +50,11 @@ * 4. SurfaceFlinger attempts to follow the chosen frame timeline, by not applying transactions or * latching buffers before the desired presentation time. * + * On older devices, AChoreographer_postFrameCallback64 or + * AChoreographer_postFrameCallback can be used to lesser effect. They cannot be + * used to precisely plan your render timeline, but will rate limit to avoid + * overloading the display pipeline and increasing frame latency. + * * @{ */ @@ -119,14 +136,46 @@ typedef void (*AChoreographer_refreshRateCallback)(int64_t vsyncPeriodNanos, voi AChoreographer* AChoreographer_getInstance() __INTRODUCED_IN(24); /** - * Deprecated: Use AChoreographer_postFrameCallback64 instead. + * Post a callback to be run when the application should begin rendering the + * next frame. The data pointer provided will be passed to the callback function + * when it's called. + * + * The callback will only be run for the next frame, not all subsequent frames, + * so to render continuously the callback should itself call + * AChoreographer_postFrameCallback. + * + * \bug The callback receives the frame time in nanoseconds as a long. On 32-bit + * systems, long is 32-bit, so the frame time will roll over roughly every two + * seconds. If your minSdkVersion is 29 or higher, switch to + * AChoreographer_postFrameCallback64, which uses a 64-bit frame time for all + * platforms. For older OS versions, you must combine the argument with the + * upper bits of clock_gettime(CLOCK_MONOTONIC, ...) on 32-bit systems. + * + * \deprecated Use AChoreographer_postFrameCallback64, which does not have the + * bug described above. */ void AChoreographer_postFrameCallback(AChoreographer* choreographer, AChoreographer_frameCallback callback, void* data) __INTRODUCED_IN(24) __DEPRECATED_IN(29, "Use AChoreographer_postFrameCallback64 instead"); /** - * Deprecated: Use AChoreographer_postFrameCallbackDelayed64 instead. + * Post a callback to be run when the application should begin rendering the + * next frame following the specified delay. The data pointer provided will be + * passed to the callback function when it's called. + * + * The callback will only be run for the next frame after the delay, not all + * subsequent frames, so to render continuously the callback should itself call + * AChoreographer_postFrameCallbackDelayed. + * + * \bug The callback receives the frame time in nanoseconds as a long. On 32-bit + * systems, long is 32-bit, so the frame time will roll over roughly every two + * seconds. If your minSdkVersion is 29 or higher, switch to + * AChoreographer_postFrameCallbackDelayed64, which uses a 64-bit frame time for + * all platforms. For older OS versions, you must combine the argument with the + * upper bits of clock_gettime(CLOCK_MONOTONIC, ...) on 32-bit systems. + * + * \deprecated Use AChoreographer_postFrameCallbackDelayed64, which does not + * have the bug described above. */ void AChoreographer_postFrameCallbackDelayed(AChoreographer* choreographer, AChoreographer_frameCallback callback, void* data, @@ -134,8 +183,13 @@ void AChoreographer_postFrameCallbackDelayed(AChoreographer* choreographer, __DEPRECATED_IN(29, "Use AChoreographer_postFrameCallbackDelayed64 instead"); /** - * Post a callback to be run on the next frame. The data pointer provided will - * be passed to the callback function when it's called. + * Post a callback to be run when the application should begin rendering the + * next frame. The data pointer provided will be passed to the callback function + * when it's called. + * + * The callback will only be run on the next frame, not all subsequent frames, + * so to render continuously the callback should itself call + * AChoreographer_postFrameCallback64. * * Available since API level 29. */ @@ -144,9 +198,13 @@ void AChoreographer_postFrameCallback64(AChoreographer* choreographer, __INTRODUCED_IN(29); /** - * Post a callback to be run on the frame following the specified delay. The - * data pointer provided will be passed to the callback function when it's - * called. + * Post a callback to be run when the application should begin rendering the + * next frame following the specified delay. The data pointer provided will be + * passed to the callback function when it's called. + * + * The callback will only be run for the next frame after the delay, not all + * subsequent frames, so to render continuously the callback should itself call + * AChoreographer_postFrameCallbackDelayed64. * * Available since API level 29. */ @@ -155,8 +213,13 @@ void AChoreographer_postFrameCallbackDelayed64(AChoreographer* choreographer, uint32_t delayMillis) __INTRODUCED_IN(29); /** - * Posts a callback to be run on the next frame. The data pointer provided will - * be passed to the callback function when it's called. + * Posts a callback to be run when the application should begin rendering the + * next frame. The data pointer provided will be passed to the callback function + * when it's called. + * + * The callback will only be run for the next frame, not all subsequent frames, + * so to render continuously the callback should itself call + * AChoreographer_postVsyncCallback. * * Available since API level 33. */ diff --git a/include/android/looper.h b/include/android/looper.h index 6a02916fb3..dba2e89942 100644 --- a/include/android/looper.h +++ b/include/android/looper.h @@ -182,23 +182,26 @@ typedef int (*ALooper_callbackFunc)(int fd, int events, void* data); * If the timeout is zero, returns immediately without blocking. * If the timeout is negative, waits indefinitely until an event appears. * - * Returns ALOOPER_POLL_WAKE if the poll was awoken using wake() before + * Returns ALOOPER_POLL_WAKE if the poll was awoken using ALooper_wake() before * the timeout expired and no callbacks were invoked and no other file - * descriptors were ready. + * descriptors were ready. **All return values may also imply + * ALOOPER_POLL_WAKE.** * - * Returns ALOOPER_POLL_CALLBACK if one or more callbacks were invoked. + * Returns ALOOPER_POLL_CALLBACK if one or more callbacks were invoked. The poll + * may also have been explicitly woken by ALooper_wake. * - * Returns ALOOPER_POLL_TIMEOUT if there was no data before the given - * timeout expired. + * Returns ALOOPER_POLL_TIMEOUT if there was no data before the given timeout + * expired. The poll may also have been explicitly woken by ALooper_wake. * - * Returns ALOOPER_POLL_ERROR if an error occurred. + * Returns ALOOPER_POLL_ERROR if an error occurred. The poll may also have been + * explicitly woken by ALooper_wake. * - * Returns a value >= 0 containing an identifier (the same identifier - * `ident` passed to ALooper_addFd()) if its file descriptor has data - * and it has no callback function (requiring the caller here to - * handle it). In this (and only this) case outFd, outEvents and - * outData will contain the poll events and data associated with the - * fd, otherwise they will be set to NULL. + * Returns a value >= 0 containing an identifier (the same identifier `ident` + * passed to ALooper_addFd()) if its file descriptor has data and it has no + * callback function (requiring the caller here to handle it). In this (and + * only this) case outFd, outEvents and outData will contain the poll events and + * data associated with the fd, otherwise they will be set to NULL. The poll may + * also have been explicitly woken by ALooper_wake. * * This method does not return until it has finished invoking the appropriate callbacks * for all file descriptors that were signalled. @@ -210,11 +213,21 @@ int ALooper_pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outDa * data has been consumed or a file descriptor is available with no callback. * This function will never return ALOOPER_POLL_CALLBACK. * - * Removed in API 34 as ALooper_pollAll can swallow ALooper_wake calls. - * Use ALooper_pollOnce instead. + * This API cannot be used safely, but a safe alternative exists (see below). As + * such, new builds will not be able to call this API and must migrate to the + * safe API. Binary compatibility is preserved to support already-compiled apps. + * + * \bug ALooper_pollAll will not wake in response to ALooper_wake calls if it + * also handles another event at the same time. + * + * \deprecated Calls to ALooper_pollAll should be replaced with + * ALooper_pollOnce. If you call ALooper_pollOnce in a loop, you *must* treat + * all return values as if they also indicate ALOOPER_POLL_WAKE. */ int ALooper_pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData) - __REMOVED_IN(1, "ALooper_pollAll may ignore wakes. Use ALooper_pollOnce instead. See https://github.com/android/ndk/discussions/2020 for more information"); + __REMOVED_IN(1, + "ALooper_pollAll may ignore wakes. Use ALooper_pollOnce instead. See " + "The API documentation for more information"); /** * Wakes the poll asynchronously. |