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

Используйте следующие функции, чтобы использовать 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);

Определить частоту кадров для swapchain

Чтобы инициализировать 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);