Добавьте функции изменения частоты кадров

Используйте следующие функции для использования Android Frame Pacing с движком рендеринга на основе API Vulkan.

Определите необходимые расширения для создания

Чтобы собрать набор расширений, необходимых для создания экземпляра Android Frame Pacing при использовании Vulkan, выполните шаги, показанные в следующем фрагменте кода:

VkPhysicalDevice physicalDevice;
uint32_t availableExtensionCount;
VkExtensionProperties* pAvailableExtensions;
uint32_t requiredExtensionCount;
char** pRequiredExtensions;

// Determine the number of extensions available for this device.
vkEnumerateDeviceExtensionProperties(physicalDevice, layerName, &availableExtensionCount,
    pAvailableExtensions);

// Determine the number of required extensions.
SwappyVk_determineDeviceExtensions(physicalDevice, availableExtensionCount,
    pAvailableExtensions, &requiredExtensionCount, nullptr);

// Determine the required extensions.
pRequiredExtensions = (char**)malloc(requiredExtensionCount * sizeof(char*));
pRequiredExtensionsData = (char*)malloc(requiredExtensionCount * (VK_MAX_EXTENSION_NAME_SIZE + 1));
for (uint32_t i = 0; i < requiredExtensionCount; i++) {
    pRequiredExtensions[i] = &pRequiredExtensionsData[i * (VK_MAX_EXTENSION_NAME_SIZE + 1)];
}
SwappyVk_determineDeviceExtensions(physicalDevice, availableExtensionCount,
    pAvailableExtensions, &requiredExtensionCount, pRequiredExtensions);

Затем можно запустить Android Frame Pacing, вызвав vkCreateDevice() . Второй аргумент, структура типа VkDeviceCreateInfo* , должен иметь член enabledExtensionCount , равный количеству требуемых расширений.

Определить семейство очередей

Для отображения правильной очереди отображения, Android Frame Pacing необходимо знать, какое семейство очередей использует Vulkan. Чтобы определить правильное семейство, выполните действия, показанные в следующем фрагменте кода:

// Reusing local variables from previous snippets:
// VkPhysicalDevice physicalDevice;

const VkDeviceCreateInfo createInfo;
const VkAllocationCallbacks allocator;
VkDevice device;
uint32_t queueFamilyIndex;
uint32_t queueIndex;
VkQueue deviceQueue;

// Values of "device" and "deviceQueue" set in the 1st and 2nd function
// calls, respectively.
vkCreateDevice(physicalDevice, &createInfo, &allocator, &device);
vkGetDeviceQueue(device, queueFamilyIndex, queueIndex, &deviceQueue);
SwappyVk_setQueueFamilyIndex(device, deviceQueue, queueFamilyIndex);

Определить частоту кадров для цепочки обмена

Чтобы инициализировать Android Frame Pacing для заданного физического устройства и цепочки обмена, выполните действия, показанные в следующем фрагменте кода:

// Reusing local variables from previous snippets:
// VkPhysicalDevice physicalDevice;
// VkDevice device;

// Assume that the JNI environment is available in:
// JNIEnv *env;
// jobject jactivity;

// Assume that swapchain is already known.
VkSwapchainKHR swapchain;
uint64_t refreshDuration; // in nanoseconds

// Determine duration between vertical-blanking periods.
// Example: 60 FPS sets "refreshDuration" to 16,666,666.
SwappyVk_initAndGetRefreshCycleDuration(env, jactivity, physicalDevice,
        device, swapchain, &refreshDuration);

Это определяет длительность подкачки в наносекундах. В swappy_common.h определены вспомогательные макросы для распространённых значений длительности подкачки (например, SWAPPY_SWAP_60FPS ).

Далее необходимо указать длительность обмена в наносекундах.

// Declare the periods in nanoseconds that should elapse before refreshing one
// image with the next image. There are helper macros defined in swappy_common.h
// for common swap durations.
// This example shows what to do when you want to render your game at 30 FPS.

SwappyVk_setSwapIntervalNS(device, swapchain, SWAPPY_SWAP_30FPS);

Настройка ANativeWindow

Swappy необходим дескриптор ANativeWindow для выполнения специфичной для ANativeWindow операции, например, вызова ANativeWindow_setFrameRate() . Вызывайте SwappyVk_setWindow() , когда поверхность дисплея Android изменилась и у вас появился новый дескриптор ANativeWindow (см. пример Cube ).

Автоматические режимы

Функция Android Frame Pacing регулирует длительность подкачки и режим конвейера на основе средней длительности предыдущих кадров. Вы можете управлять этим поведением с помощью следующих функций:

Представить кадр

Чтобы отобразить кадр вашей игры в Android Frame Pacing, вызовите SwappyVk_queuePresent() . Эта функция вызывает vkQueuePresentKHR() от имени вашей игры.

Уничтожить цепочку обмена

Чтобы уничтожить данные SwappyVk , связанные с заданной цепочкой обмена, выполните действия, показанные в следующем фрагменте кода:

// Reusing local variables from previous snippets:
// VkDevice device;
// VkSwapchainKHR swapchain;
// const VkAllocationCallbacks allocator;

SwappyVk_destroySwapchain(device, swapchain);
vkDestroySwapchainKHR(device, swapchain, &allocator);