swappy_common.h 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. /*
  2. * Copyright 2019 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. * @defgroup swappy_common Swappy common tools
  18. * Tools to be used with Swappy for OpenGL or Swappy for Vulkan.
  19. * @{
  20. */
  21. #pragma once
  22. #include <android/native_window.h>
  23. #include <stdint.h>
  24. #include "common/gamesdk_common.h"
  25. /** @brief Swap interval for 60fps, in nanoseconds. */
  26. #define SWAPPY_SWAP_60FPS (16666667L)
  27. /** @brief Swap interval for 30fps, in nanoseconds. */
  28. #define SWAPPY_SWAP_30FPS (33333333L)
  29. /** @brief Swap interval for 20fps, in nanoseconds. */
  30. #define SWAPPY_SWAP_20FPS (50000000L)
  31. /**
  32. * The longest duration, in refresh periods, represented by the statistics.
  33. * @see SwappyStats
  34. */
  35. #define MAX_FRAME_BUCKETS 6
  36. /** @cond INTERNAL */
  37. #define SWAPPY_SYSTEM_PROP_KEY_DISABLE "swappy.disable"
  38. // Internal macros to track Swappy version, do not use directly.
  39. #define SWAPPY_MAJOR_VERSION 2
  40. #define SWAPPY_MINOR_VERSION 0
  41. #define SWAPPY_BUGFIX_VERSION 0
  42. #define SWAPPY_PACKED_VERSION \
  43. ANDROID_GAMESDK_PACKED_VERSION(SWAPPY_MAJOR_VERSION, SWAPPY_MINOR_VERSION, \
  44. SWAPPY_BUGFIX_VERSION)
  45. // Internal macros to generate a symbol to track Swappy version, do not use
  46. // directly.
  47. #define SWAPPY_VERSION_CONCAT_NX(PREFIX, MAJOR, MINOR, BUGFIX, GITCOMMIT) \
  48. PREFIX##_##MAJOR##_##MINOR##_##BUGFIX##_##GITCOMMIT
  49. #define SWAPPY_VERSION_CONCAT(PREFIX, MAJOR, MINOR, BUGFIX, GITCOMMIT) \
  50. SWAPPY_VERSION_CONCAT_NX(PREFIX, MAJOR, MINOR, BUGFIX, GITCOMMIT)
  51. #define SWAPPY_VERSION_SYMBOL \
  52. SWAPPY_VERSION_CONCAT(Swappy_version, SWAPPY_MAJOR_VERSION, \
  53. SWAPPY_MINOR_VERSION, SWAPPY_BUGFIX_VERSION, \
  54. AGDK_GIT_COMMIT)
  55. // Define this to 1 to enable all logging from Swappy, by default it is
  56. // disabled in a release build and enabled in a debug build.
  57. #ifndef ENABLE_SWAPPY_LOGGING
  58. #define ENABLE_SWAPPY_LOGGING 0
  59. #endif
  60. /** @endcond */
  61. /** @brief Id of a thread returned by an external thread manager. */
  62. typedef uint64_t SwappyThreadId;
  63. /**
  64. * @brief A structure enabling you to set how Swappy starts and joins threads by
  65. * calling
  66. * ::Swappy_setThreadFunctions.
  67. *
  68. * Usage of this functionality is optional.
  69. */
  70. typedef struct SwappyThreadFunctions {
  71. /** @brief Thread start callback.
  72. *
  73. * This function is called by Swappy to start thread_func on a new thread.
  74. * @param user_data A value to be passed the thread function.
  75. * If the thread was started, this function should set the thread_id and
  76. * return 0. If the thread was not started, this function should return a
  77. * non-zero value.
  78. */
  79. int (*start)(SwappyThreadId* thread_id, void* (*thread_func)(void*),
  80. void* user_data);
  81. /** @brief Thread join callback.
  82. *
  83. * This function is called by Swappy to join the thread with given id.
  84. */
  85. void (*join)(SwappyThreadId thread_id);
  86. /** @brief Thread joinable callback.
  87. *
  88. * This function is called by Swappy to discover whether the thread with the
  89. * given id is joinable.
  90. */
  91. bool (*joinable)(SwappyThreadId thread_id);
  92. } SwappyThreadFunctions;
  93. #ifdef __cplusplus
  94. extern "C" {
  95. #endif
  96. /**
  97. * @brief Return the version of the Swappy library at runtime.
  98. */
  99. uint32_t Swappy_version();
  100. /**
  101. * @brief Call this before any other functions in order to use a custom thread
  102. * manager.
  103. *
  104. * Usage of this function is entirely optional. Swappy uses std::thread by
  105. * default.
  106. *
  107. */
  108. void Swappy_setThreadFunctions(const SwappyThreadFunctions* thread_functions);
  109. /**
  110. * @brief Return the full version of the Swappy library at runtime, e.g.
  111. * "1.9.0_8a85ab7c46"
  112. */
  113. const char* Swappy_versionString();
  114. /**
  115. * @brief Swappy frame statistics, collected if toggled on with
  116. * ::SwappyGL_enableStats or ::SwappyVk_enableStats.
  117. */
  118. typedef struct SwappyStats {
  119. /** @brief Total frames swapped by swappy */
  120. uint64_t totalFrames;
  121. /** @brief Histogram of the number of screen refreshes a frame waited in the
  122. * compositor queue after rendering was completed.
  123. *
  124. * For example:
  125. * if a frame waited 2 refresh periods in the compositor queue after
  126. * rendering was done, the frame will be counted in idleFrames[2]
  127. */
  128. uint64_t idleFrames[MAX_FRAME_BUCKETS];
  129. /** @brief Histogram of the number of screen refreshes passed between the
  130. * requested presentation time and the actual present time.
  131. *
  132. * For example:
  133. * if a frame was presented 2 refresh periods after the requested
  134. * timestamp swappy set, the frame will be counted in lateFrames[2]
  135. */
  136. uint64_t lateFrames[MAX_FRAME_BUCKETS];
  137. /** @brief Histogram of the number of screen refreshes passed between two
  138. * consecutive frames
  139. *
  140. * For example:
  141. * if frame N was presented 2 refresh periods after frame N-1
  142. * frame N will be counted in offsetFromPreviousFrame[2]
  143. */
  144. uint64_t offsetFromPreviousFrame[MAX_FRAME_BUCKETS];
  145. /** @brief Histogram of the number of screen refreshes passed between the
  146. * call to Swappy_recordFrameStart and the actual present time.
  147. *
  148. * For example:
  149. * if a frame was presented 2 refresh periods after the call to
  150. * `Swappy_recordFrameStart` the frame will be counted in latencyFrames[2]
  151. */
  152. uint64_t latencyFrames[MAX_FRAME_BUCKETS];
  153. } SwappyStats;
  154. #ifdef __cplusplus
  155. } // extern "C"
  156. #endif
  157. /**
  158. * Pointer to a function that can be attached to SwappyTracer::preWait
  159. * @param userData Pointer to arbitrary data, see SwappyTracer::userData.
  160. */
  161. typedef void (*SwappyPreWaitCallback)(void*);
  162. /**
  163. * Pointer to a function that can be attached to SwappyTracer::postWait.
  164. * @param userData Pointer to arbitrary data, see SwappyTracer::userData.
  165. * @param cpu_time_ns Time for CPU processing of this frame in nanoseconds.
  166. * @param gpu_time_ns Time for GPU processing of previous frame in nanoseconds.
  167. */
  168. typedef void (*SwappyPostWaitCallback)(void*, int64_t cpu_time_ns,
  169. int64_t gpu_time_ns);
  170. /**
  171. * Pointer to a function that can be attached to SwappyTracer::preSwapBuffers.
  172. * @param userData Pointer to arbitrary data, see SwappyTracer::userData.
  173. */
  174. typedef void (*SwappyPreSwapBuffersCallback)(void*);
  175. /**
  176. * Pointer to a function that can be attached to SwappyTracer::postSwapBuffers.
  177. * @param userData Pointer to arbitrary data, see SwappyTracer::userData.
  178. * @param desiredPresentationTimeMillis The target time, in milliseconds, at
  179. * which the frame would be presented on screen.
  180. */
  181. typedef void (*SwappyPostSwapBuffersCallback)(
  182. void*, int64_t desiredPresentationTimeMillis);
  183. /**
  184. * Pointer to a function that can be attached to SwappyTracer::startFrame.
  185. * @param userData Pointer to arbitrary data, see SwappyTracer::userData.
  186. * @param desiredPresentationTimeMillis The time, in milliseconds, at which the
  187. * frame is scheduled to be presented.
  188. */
  189. typedef void (*SwappyStartFrameCallback)(void*, int currentFrame,
  190. int64_t desiredPresentationTimeMillis);
  191. /**
  192. * Pointer to a function that can be attached to
  193. * SwappyTracer::swapIntervalChanged. Call ::SwappyGL_getSwapIntervalNS or
  194. * ::SwappyVk_getSwapIntervalNS to get the latest swapInterval.
  195. * @param userData Pointer to arbitrary data, see SwappyTracer::userData.
  196. */
  197. typedef void (*SwappySwapIntervalChangedCallback)(void*);
  198. /**
  199. * @brief Collection of callbacks to be called each frame to trace execution.
  200. *
  201. * Injection of these is optional.
  202. */
  203. typedef struct SwappyTracer {
  204. /**
  205. * Callback called before waiting to queue the frame to the composer.
  206. */
  207. SwappyPreWaitCallback preWait;
  208. /**
  209. * Callback called after wait to queue the frame to the composer is done.
  210. */
  211. SwappyPostWaitCallback postWait;
  212. /**
  213. * Callback called before calling the function to queue the frame to the
  214. * composer.
  215. */
  216. SwappyPreSwapBuffersCallback preSwapBuffers;
  217. /**
  218. * Callback called after calling the function to queue the frame to the
  219. * composer.
  220. */
  221. SwappyPostSwapBuffersCallback postSwapBuffers;
  222. /**
  223. * Callback called at the start of a frame.
  224. */
  225. SwappyStartFrameCallback startFrame;
  226. /**
  227. * Pointer to some arbitrary data that will be passed as the first argument
  228. * of callbacks.
  229. */
  230. void* userData;
  231. /**
  232. * Callback called when the swap interval was changed.
  233. */
  234. SwappySwapIntervalChangedCallback swapIntervalChanged;
  235. } SwappyTracer;
  236. /** @} */