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:
void SwappyVk_setAutoSwapInterval(bool enabled);
void SwappyVk_setMaxAutoSwapIntervalNS(uint64_t max_swap_ns);
void SwappyVk_setAutoPipelineMode(bool enabled);
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);