使用下列函式,即可針對以 Vulkan API 為基礎的轉譯引擎使用 Android Frame Pacing。
找出要建立的必要擴充功能
如要收集使用 Vulkan 時建立 Android Frame Pacing 執行個體所需要的擴充功能集,請完成下列程式碼片段所示步驟:
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);
接著,請呼叫 vkCreateDevice()
來啟動 Android Frame Pacing。第 2 個引數 (類型 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()
。在 Android 顯示面已變更且您有新的 ANativeWindow
控制代碼時,呼叫 SwappyVk_setWindow()
(參閱 Cube 範例)。
自動模式
Android Frame Pacing 會根據前一個影格的平均時間長度調整交換時間長度和管道。您可以透過下列函式控管這個行為:
void SwappyVk_setAutoSwapInterval(bool enabled);
void SwappyVk_setMaxAutoSwapIntervalNS(uint64_t max_swap_ns);
void SwappyVk_setAutoPipelineMode(bool enabled);
成像影格
如要向 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);