Frame-Taktungsfunktionen hinzufügen

Mit den folgenden Funktionen können Sie Android Frame Pacing mit einem Rendering-Modul verwenden, das auf der Vulkan API basiert.

Erforderliche Erweiterungen für die Erstellung ermitteln

Führen Sie die Schritte im folgenden Code-Snippet aus, um die Erweiterungen zu erfassen, die bei der Verwendung von Vulkan zum Erstellen einer Android Frame Pacing-Instanz erforderlich sind:

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);

Anschließend können Sie das Android Frame Pacing starten, indem Sie vkCreateDevice() aufrufen. Für das zweite Argument, eine Struktur vom Typ VkDeviceCreateInfo*, sollte das Element enabledExtensionCount auf die Anzahl der erforderlichen Erweiterungen festgelegt werden.

Warteschlangenfamilie identifizieren

Android Frame Pacing muss wissen, welche Warteschlangenfamilie Vulkan verwendet, um die richtige Warteschlange anzuzeigen. Führen Sie die Schritte im folgenden Code-Snippet aus, um die richtige Familie zu ermitteln:

// 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);

Framerate für Swapchain definieren

Führen Sie die im folgenden Code-Snippet aufgeführten Schritte aus, um das Android Frame Pacing für ein bestimmtes physisches Gerät und eine Swapchain zu initialisieren:

// 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);

Dadurch wird die Auslagerungsdauer in Nanosekunden festgelegt. In swappy_common.h sind Hilfsmakros für die gängige Auslagerungsdauer definiert (z. B. SWAPPY_SWAP_60FPS).

Als Nächstes müssen Sie die Auslagerungsdauer in Nanosekunden angeben.

// 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 festlegen

Swappy benötigt den Handle ANativeWindow, um ANativeWindow-spezifische Vorgänge wie das Aufrufen von ANativeWindow_setFrameRate() auszuführen. Rufe SwappyVk_setWindow() auf, wenn sich deine Android-Displayoberfläche verändert hat und du einen neuen ANativeWindow-Alias hast. Ein Beispiel findest du im Cube-Beispiel.

Automatische Modi

Die Android Frame Pacing passt die Auslagerungsdauer und den Pipelinemodus basierend auf der durchschnittlichen Dauer vorheriger Frames an. Sie können dieses Verhalten mit den folgenden Funktionen steuern:

Frame präsentieren

Rufen Sie SwappyVk_queuePresent() auf, um einen Frame Ihres Spiels für Android Frame Pacing zu präsentieren. Diese Funktion ruft vkQueuePresentKHR() im Namen deines Spiels auf.

Zerstöre die Swap-Kette

Wenn Sie die mit einer Swapchain verknüpften SwappyVk-Daten löschen möchten, führen Sie die im folgenden Code-Snippet gezeigten Schritte aus:

// Reusing local variables from previous snippets:
// VkDevice device;
// VkSwapchainKHR swapchain;
// const VkAllocationCallbacks allocator;

SwappyVk_destroySwapchain(device, swapchain);
vkDestroySwapchainKHR(device, swapchain, &allocator);