新增影格使用速度函式

使用下列函式,即可針對以 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 會根據前一個影格的平均時間長度調整交換時間長度和管道。您可以透過下列函式控管這個行為:

成像影格

如要向 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);