Vulkan API'ye dayalı bir oluşturma motoruyla Android Frame Pacing'i kullanmak için aşağıdaki işlevleri kullanın.
Oluşturma için gerekli uzantıları belirleme
Vulkan kullanırken Android Frame Pacing örneği oluşturmak için gereken uzantı grubunu toplamak üzere aşağıdaki kod snippet'inde gösterilen adımları tamamlayın:
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);
Ardından vkCreateDevice()
işlevini çağırarak Android Frame Pacing'i başlatabilirsiniz. VkDeviceCreateInfo*
türünde bir yapı olan 2. bağımsız değişkenin enabledExtensionCount
üyesi, gerekli uzantıların sayısına ayarlanmalıdır.
Kuyruk ailesini tanımlama
Android Frame Pacing'in doğru görüntüleme sırasını sunabilmesi için Vulkan'ın hangi sıra ailesini kullandığını bilmesi gerekir. Doğru aileyi belirlemek için aşağıdaki kod snippet'inde gösterilen adımları tamamlayın:
// 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);
Takas zinciri için kare hızını tanımlama
Belirli bir fiziksel cihaz ve swapchain için Android Frame Pacing'i başlatmak üzere, aşağıdaki kod snippet'inde gösterilen adımları tamamlayın:
// 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);
Bu değer, takas süresini nanosaniye cinsinden belirler. swappy_common.h
içinde, yaygın takas süreleri için tanımlanmış yardımcı makrolar vardır (örneğin, SWAPPY_SWAP_60FPS
).
Ardından, değişim süresini nanosaniye cinsinden sağlamanız gerekir.
// 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'u ayarlama
Swappy, ANativeWindow
ile ilgili işlemleri (ör. ANativeWindow_setFrameRate()
'ı arama) gerçekleştirmek için ANativeWindow
'ın kullanıcı adını kullanır.
Android ekran yüzeyiniz değiştiğinde ve yeni bir ANativeWindow
tutma yeriniz olduğunda SwappyVk_setWindow()
çağrısı yapın (örnek için Cube örneğine bakın).
Otomatik Modlar
Android Frame Pacing, önceki karelerin ortalama süresine göre takas süresini ve işlem hattı modunu ayarlar. Bu davranışı aşağıdaki işlevlerle kontrol edebilirsiniz:
void SwappyVk_setAutoSwapInterval(bool enabled);
void SwappyVk_setMaxAutoSwapIntervalNS(uint64_t max_swap_ns);
void SwappyVk_setAutoPipelineMode(bool enabled);
Çerçeve sunma
Oyununuzun bir karesini Android Frame Pacing'e sunmak için SwappyVk_queuePresent()
işlevini çağırın.
Bu işlev, oyununuz adına vkQueuePresentKHR()
çağrısı yapar.
Takas zincirini yok edin.
Belirli bir takas zinciriyle ilişkili SwappyVk
verilerini yok etmek için aşağıdaki kod snippet'inde gösterilen adımları tamamlayın:
// Reusing local variables from previous snippets: // VkDevice device; // VkSwapchainKHR swapchain; // const VkAllocationCallbacks allocator; SwappyVk_destroySwapchain(device, swapchain); vkDestroySwapchainKHR(device, swapchain, &allocator);