Use the following functions to use Android Frame Pacing with a rendering engine
based on the OpenGL ES API.

## Initialize and destroy

Use the following functions to initialize and destroy an instance of Android
Frame Pacing, respectively:

- [`void SwappyGL_init(JNIEnv *env, jobject jactivity);`](https://developer.android.com/games/sdk/reference/frame-pacing/group/swappy-g-l#group__swappy_g_l_1gad9a8392c399ae9b87a7bfe3f14678019)
- [`void SwappyGL_destroy();`](https://developer.android.com/games/sdk/reference/frame-pacing/group/swappy-g-l#group__swappy_g_l_1gaa8c4eac2519c1c0bede3e54d848ecd4c)

In general, you should call `SwappyGL_init()` as early as possible during the
engine startup sequence, and you should call `SwappyGL_destroy()` when the game
is exiting. You shouldn't need to call these methods at any other time.

## Configure swap interval and refresh period

Use the following functions to configure an instance of Android Frame Pacing:

- [`void SwappyGL_setSwapIntervalNS(uint64_t swap_ns);`](https://developer.android.com/games/sdk/reference/frame-pacing/group/swappy-g-l#swappygl_setswapintervalns)
- [`void SwappyGL_setFenceTimeoutNS(uint64_t fence_timeout_ns);`](https://developer.android.com/games/sdk/reference/frame-pacing/group/swappy-g-l#swappygl_setfencetimeoutns)
- [`void SwappyGL_setUseAffinity(bool tf);`](https://developer.android.com/games/sdk/reference/frame-pacing/group/swappy-g-l#swappygl_setuseaffinity)

| **Note:** Basic integrations usually don't require you to call `SwappyGL_setFenceTimeoutNS()` and `SwappyGL_setUseAffinity()`.

When calling `SwappyGL_setSwapIntervalNS()`, pass in the duration that a frame
should be presented. In most cases, you can use one of the following constants:
`SWAPPY_SWAP_60FPS`, `SWAPPY_SWAP_30FPS`, or `SWAPPY_SWAP_20FPS`.

In general, you should call these methods directly after a call to
`SwappyGL_init()`. However, you might also need to call these methods at other
times during your game's execution.

### Setting the ANativeWindow

Swappy needs the handle of `ANativeWindow` in order to perform
`ANativeWindow`-specific operation, such as calling
[`ANativeWindow_setFrameRate()`](https://developer.android.com/ndk/reference/group/a-native-window#anativewindow_setframerate).
Call
[`SwappyGL_setWindow()`](https://developer.android.com/games/sdk/reference/frame-pacing/group/swappy-g-l#swappygl_setwindow)
when your Android display surface has changed and you have a new `ANativeWindow`
handle (see the [Bouncyball sample](https://android.googlesource.com/platform/frameworks/opt/gamesdk/+/refs/heads/master/samples/bouncyball) for an example).

### Auto Modes

Android Frame Pacing adjusts the swap duration and pipeline mode based on the
average duration of previous frames. You can control this behavior with the
following functions:

- [`void SwappyGL_setAutoSwapInterval(bool enabled);`](https://developer.android.com/games/sdk/reference/frame-pacing/group/swappy-g-l-extra#swappygl_setautoswapinterval)
- [`void SwappyGL_setMaxAutoSwapIntervalNS(uint64_t max_swap_ns);`](https://developer.android.com/games/sdk/reference/frame-pacing/group/swappy-g-l-extra#swappygl_setmaxautoswapintervalns)
- [`void SwappyGL_setAutoPipelineMode(bool enabled);`](https://developer.android.com/games/sdk/reference/frame-pacing/group/swappy-g-l-extra#swappygl_setautopipelinemode)

## Perform per-frame swap

During each rendering frame, call
[`bool SwappyGL_swap(EGLDisplay display, EGLSurface surface)`](https://developer.android.com/games/sdk/reference/frame-pacing/group/swappy-g-l#swappygl_swap).
This method wraps the `eglSwapBuffers()` method from Open GL ES, so you should
replace all instances of `eglSwapBuffers()` in your game with `SwappyGL_swap()`.

## Utility functions

The following method checks whether Android Frame Pacing is enabled:

- [`bool SwappyGL_isEnabled();`](https://developer.android.com/games/sdk/reference/frame-pacing/group/swappy-g-l#swappygl_isenabled)

It's possible that an instance of Android Frame Pacing isn't able to initialize
itself for any of the following reasons:

- The necessary EGL functions are missing on the device.
- The system has set the `swappy.disable` property.

In either of these situations, `SwappyGL_isEnabled()` returns `false`, and it's
best for you to implement an alternative frame-pacing strategy.
| **Note:** Even if `SwappyGL_isEnabled()` returns `false`, the `SwappyGL_swap()` function still invokes `eglSwapBuffers()`.