Ajouter des fonctions de frame pacing

Utilisez les fonctions suivantes pour utiliser Android Frame Pacing avec un moteur de rendu basé sur l'API Vulkan.

Identifier les extensions requises pour la création

Pour collecter l'ensemble d'extensions nécessaire à la création d'une instance Android Frame Pacing lorsque vous utilisez Vulkan, suivez les étapes indiquées dans l'extrait de code ci-dessous :

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

Vous pouvez ensuite lancer Android Frame Pacing en appelant vkCreateDevice(). Le membre enabledExtensionCount du deuxième argument, un struct de type VkDeviceCreateInfo*, doit être défini sur le nombre d'extensions requises.

Identifier la famille de files d'attente

Pour présenter la file d'attente d'affichage appropriée, Android Frame Pacing doit savoir quelle famille de files d'attente utilise la technologie Vulkan. Pour ce faire, suivez les étapes indiquées dans l'extrait de code suivant :

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

Définir la fréquence de frames de la chaîne d'échange

Pour initialiser Android Frame Pacing pour un appareil physique et une chaîne d'échange donnés, suivez les étapes indiquées dans l'extrait de code ci-dessous :

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

Ce paramètre détermine la durée d'échange en nanosecondes. Il existe des macros d'assistance définies dans swappy_common.h pour les durées d'échange courantes (par exemple, SWAPPY_SWAP_60FPS).

Vous devez ensuite indiquer la durée d'échange en nanosecondes.

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

Définir la fenêtre ANativeWindow

Swappy a besoin du handle de ANativeWindow pour effectuer une opération spécifique sur ANativeWindow, telle que l'appel de ANativeWindow_setFrameRate(). Appelez SwappyVk_setWindow() lorsque votre surface d'affichage Android a changé et que vous avez un nouveau handle ANativeWindow (voir l'exemple Cube).

Modes automatiques

Android Frame Pacing ajuste la durée d'échange et le mode du pipeline en fonction de la durée moyenne des frames précédents. Vous pouvez contrôler ce comportement à l'aide des fonctions suivantes :

Présenter un frame

Pour présenter un frame de votre jeu sur Android Frame Pacing, appelez SwappyVk_queuePresent(). Cette fonction appelle vkQueuePresentKHR() au nom de votre jeu.

Détruire la chaîne d'échange

Pour détruire les données SwappyVk associées à une chaîne d'échange donnée, suivez les étapes indiquées dans l'extrait de code ci-dessous :

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

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