Use as funções a seguir para usar o Android Frame Pacing com um mecanismo de renderização baseado na API Vulkan.
Identificar as extensões necessárias para a criação
Para coletar o conjunto de extensões necessárias para criar uma instância do Android Frame Pacing ao usar Vulkan, siga as etapas apresentadas no seguinte snippet de código:
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);
Em seguida, você pode iniciar o Android Frame Pacing chamando vkCreateDevice()
. O segundo
argumento, uma estrutura do tipo VkDeviceCreateInfo*
, precisa ter o membro enabledExtensionCount
definido como o número de extensões necessárias.
Identificar família de filas
Para apresentar a fila de exibição correta, o Android Frame Pacing precisa saber qual família de filas o Vulkan está usando. Para determinar a família correta, siga as etapas apresentadas neste snippet de código:
// 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);
Definir frame rate para cadeia de troca
Para inicializar o Android Frame Pacing para um dispositivo físico e uma cadeia de troca específicos, siga as etapas apresentadas neste snippet de código:
// 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);
Isso determina a duração da troca em nanossegundos. Há macros auxiliares
definidas em swappy_common.h
para durações de troca comuns (por exemplo,
SWAPPY_SWAP_60FPS
).
Em seguida, informe a duração da troca em nanossegundos.
// 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);
Configuração do ANativeWindoW
O Swappy precisa do handle de ANativeWindow
para executar
uma operação específica de ANativeWindow
, como chamar
ANativeWindow_setFrameRate()
.
Chame
SwappyVk_setWindow()
quando a superfície de exibição do Android mudar e você tiver um novo
identificador ANativeWindow
(consulte a amostra do Cube para ver um exemplo).
Modos automáticos
A Android Frame Pacing ajusta a duração da troca e o modo do pipeline com base na duração média dos frames anteriores. É possível controlar esse comportamento com as seguintes funções:
void SwappyVk_setAutoSwapInterval(bool enabled);
void SwappyVk_setMaxAutoSwapIntervalNS(uint64_t max_swap_ns);
void SwappyVk_setAutoPipelineMode(bool enabled);
Apresentar um frame
Para apresentar um frame do seu jogo à Android Frame Pacing, chame
SwappyVk_queuePresent()
.
Essa função chama vkQueuePresentKHR()
em nome do jogo.
Destruir a cadeia de troca
Para destruir os dados SwappyVk
associados a determinada cadeia de troca, siga as
etapas apresentadas neste snippet de código:
// Reusing local variables from previous snippets: // VkDevice device; // VkSwapchainKHR swapchain; // const VkAllocationCallbacks allocator; SwappyVk_destroySwapchain(device, swapchain); vkDestroySwapchainKHR(device, swapchain, &allocator);