Aby używać funkcji Android Frame Pacing z silnikiem renderowania opartym na interfejsie Vulkan API, użyj tych funkcji.
Określanie rozszerzeń wymaganych do utworzenia
Aby zebrać zestaw rozszerzeń niezbędnych do utworzenia instancji Android Frame Pacing podczas korzystania z Vulkana, wykonaj czynności pokazane w tym fragmencie kodu:
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);
Następnie możesz uruchomić funkcję Android Frame Pacing, wywołując vkCreateDevice()
. Drugi argument, struktura typu VkDeviceCreateInfo*
, powinien mieć element enabledExtensionCount
ustawiony na liczbę wymaganych rozszerzeń.
Określanie rodziny kolejek
Aby wyświetlać prawidłową kolejkę, funkcja synchronizacji klatek Androida musi wiedzieć, której rodziny kolejek używa Vulkan. Aby określić prawidłową rodzinę, wykonaj czynności pokazane w tym fragmencie kodu:
// 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);
Określanie liczby klatek na sekundę dla łańcucha wymiany
Aby zainicjować synchronizację klatek na Androidzie na danym urządzeniu fizycznym i w łańcuchu buforów, wykonaj czynności pokazane w tym fragmencie kodu:
// 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);
Określa czas trwania zamiany w nanosekundach. W swappy_common.h
zdefiniowano makra pomocnicze
dla typowych czasów trwania zamiany (np. SWAPPY_SWAP_60FPS
).
Następnie musisz podać czas trwania zamiany w nanosekundach.
// 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);
Ustawianie ANativeWindow
Swappy potrzebuje uchwytu ANativeWindow
, aby wykonać operację
ANativeWindow
, np. wywołać funkcję
ANativeWindow_setFrameRate()
.
Wywołaj funkcję
SwappyVk_setWindow()
gdy zmieni się powierzchnia wyświetlania na Androidzie i masz nowy uchwyt ANativeWindow
(przykład znajdziesz w próbce Cube).
Tryby automatyczne
Funkcja synchronizacji klatek na Androidzie dostosowuje czas wymiany i tryb potoku na podstawie średniego czasu trwania poprzednich klatek. Możesz kontrolować to zachowanie za pomocą tych funkcji:
void SwappyVk_setAutoSwapInterval(bool enabled);
void SwappyVk_setMaxAutoSwapIntervalNS(uint64_t max_swap_ns);
void SwappyVk_setAutoPipelineMode(bool enabled);
Prezentowanie ramki
Aby zaprezentować klatkę gry w Android Frame Pacing, wywołaj funkcję
SwappyVk_queuePresent()
.
Ta funkcja wywołuje vkQueuePresentKHR()
w imieniu Twojej gry.
Zniszcz łańcuch wymiany
Aby usunąć dane SwappyVk
powiązane z danym łańcuchem wymiany, wykonaj czynności pokazane w tym fragmencie kodu:
// Reusing local variables from previous snippets: // VkDevice device; // VkSwapchainKHR swapchain; // const VkAllocationCallbacks allocator; SwappyVk_destroySwapchain(device, swapchain); vkDestroySwapchainKHR(device, swapchain, &allocator);