Frame-Taktungsfunktionen hinzufügen

Verwenden Sie die folgenden Funktionen, um Android Frame Pacing mit einer Rendering-Engine zu verwenden, die auf der Vulkan API basiert.

Erforderliche Erweiterungen für die Erstellung ermitteln

Wenn Sie Vulkan verwenden, müssen Sie die im folgenden Code-Snippet gezeigten Schritte ausführen, um die erforderlichen Erweiterungen zum Erstellen einer Instanz von Android Frame Pacing zu erfassen:

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 Android Frame Pacing durch Aufrufen von vkCreateDevice() starten. Das zweite Argument, eine Struktur vom Typ VkDeviceCreateInfo*, sollte das enabledExtensionCount-Element auf die Anzahl der erforderlichen Erweiterungen festlegen.

Warteschlangenfamilie identifizieren

Damit die richtige Anzeige-Warteschlange präsentiert werden kann, muss Android Frame Pacing wissen, welche Warteschlangenfamilie von Vulkan verwendet wird. 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 Schritte im folgenden Code-Snippet aus, um Android Frame Pacing für ein bestimmtes physisches Gerät und eine bestimmte 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);

Damit wird die Dauer des Tauschs in Nanosekunden festgelegt. In swappy_common.h sind Hilfsmakros für häufige Swap-Dauern definiert, z. B. SWAPPY_SWAP_60FPS.

Als Nächstes müssen Sie die Dauer des Tauschs 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 von ANativeWindow, um ANativeWindow-spezifische Vorgänge auszuführen, z. B. ANativeWindow_setFrameRate() aufzurufen. Rufen Sie SwappyVk_setWindow() auf, wenn sich die Android-Anzeigeoberfläche geändert hat und Sie ein neues ANativeWindow-Handle haben (ein Beispiel finden Sie im Cube-Beispiel).

Automatikmodi

Android Frame Pacing passt die Swap-Dauer und den Pipeline-Modus basierend auf der durchschnittlichen Dauer der vorherigen Frames an. Sie können dieses Verhalten mit den folgenden Funktionen steuern:

Frame präsentieren

Wenn Sie einen Frame Ihres Spiels an Android Frame Pacing übergeben möchten, rufen Sie SwappyVk_queuePresent() auf. Diese Funktion ruft vkQueuePresentKHR() im Namen Ihres Spiels auf.

Swapchain zerstören

Führen Sie die Schritte im folgenden Code-Snippet aus, um die SwappyVk-Daten zu löschen, die mit einer bestimmten Swapchain verknüpft sind:

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

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