Użyj tych funkcji, aby używać Android Frame Pacing z silnikiem renderowania opartym na interfejsie Vulkan API.
Wskaż rozszerzenia wymagane do utworzenia
Aby zebrać zestaw rozszerzeń niezbędnych do utworzenia instancji Android Frame Pacing w interfejsie Vulkan, wykonaj czynności podane 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ć Android Frame Pacing, wywołując vkCreateDevice()
. Drugi argument, czyli struktura typu VkDeviceCreateInfo*
, powinien mieć element enabledExtensionCount
ustawiony na liczbę wymaganych rozszerzeń.
Określ rodzinę kolejek
Aby wyświetlić prawidłową kolejkę wyświetlania, Android Frame Pacing musi wiedzieć, której rodziny kolejek używa Vulkan. Aby określić prawidłową rodzinę, wykonaj czynności opisane 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śl liczbę klatek na potrzeby swapchain
Aby zainicjować Android Frame Pacing dla danego urządzenia fizycznego i swapchain, wykonaj czynności opisane we 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 polu swappy_common.h
znajdują się makra pomocnicze dla typowych czasów wymiany (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 interfejsu ANativeWindow
Funkcja Zamień, potrzebuje uchwytu ANativeWindow
, aby wykonywać działania charakterystyczne dla ANativeWindow
, np. wywoływać metodę ANativeWindow_setFrameRate()
.
Wywołaj metodę SwappyVk_setWindow()
, gdy wyświetlacz w Androidzie ulegnie zmianie i będziesz mieć nowy uchwyt ANativeWindow
(przykład znajdziesz w przykładzie Cube).
Tryby automatyczne
Android Frame Pacing dostosowuje czas trwania zamiany 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);
Pokaż ramkę
Aby zaprezentować kadr z gry w Android Frame Pacing, wywołaj SwappyVk_queuePresent()
.
Ta funkcja wywołuje polecenie vkQueuePresentKHR()
w imieniu Twojej gry.
Zniszcz łańcuch wymiany
Aby zniszczyć dane SwappyVk
powiązane z danym łańcuchem wymiany, wykonaj czynności opisane poniżej:
// Reusing local variables from previous snippets: // VkDevice device; // VkSwapchainKHR swapchain; // const VkAllocationCallbacks allocator; SwappyVk_destroySwapchain(device, swapchain); vkDestroySwapchainKHR(device, swapchain, &allocator);