프레임 속도 함수 추가

Vulkan API를 기반으로 한 렌더링 엔진에서 Android Frame Pacing을 사용하려면 다음 함수를 사용합니다.

생성에 필요한 확장 식별

Vulkan 사용 시 Android Frame Pacing 인스턴스를 생성하는 데 필요한 확장 세트를 수집하려면 다음 코드 스니펫에 나와 있는 단계를 완료합니다.

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

그런 다음, vkCreateDevice()를 호출하여 Android Frame Pacing을 시작할 수 있습니다. 두 번째 인수인 VkDeviceCreateInfo* 유형의 구조체에는 필요한 확장 수로 설정된 enabledExtensionCount 멤버가 있어야 합니다.

큐 패밀리 식별

올바른 디스플레이 큐를 표시하려면 Android Frame Pacing은 Vulkan에서 사용하는 큐 패밀리를 알아야 합니다. 올바른 패밀리를 결정하려면 다음 코드 스니펫에 나와 있는 단계를 완료합니다.

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

swapchain의 프레임 속도 정의

지정된 실제 기기 및 swapchain에 대한 Android Frame Pacing을 초기화하려면 다음 코드 스니펫에 나와 있는 단계를 완료합니다.

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

이 코드 스니펫에서는 스왑 기간을 나노초 단위로 결정합니다. swappy_common.h에는 일반적인 스왑 기간(예: SWAPPY_SWAP_60FPS)에 대해 정의된 도우미 매크로가 있습니다.

다음으로 스왑 기간을 나노초 단위로 제공해야 합니다.

// 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 설정

ANativeWindow_setFrameRate() 호출과 같은 ANativeWindow 관련 작업을 실행하기 위해서는 Swappy에 ANativeWindow 핸들이 필요합니다. Android 디스플레이 노출 영역이 변경되고 새로운 ANativeWindow 핸들이 있는 경우 SwappyVk_setWindow()를 호출합니다(예를 보려면 Cube 샘플 참고).

자동 모드

Android Frame Pacing은 이전 프레임의 평균 기간을 기반으로 스왑 기간 및 파이프라인 모드를 조정합니다. 다음 함수를 사용하여 이 동작을 제어할 수 있습니다.

프레임 표시

게임의 프레임을 Android Frame Pacing에 표시하려면 SwappyVk_queuePresent()를 호출합니다. 이 함수는 게임을 대신하여 vkQueuePresentKHR()을 호출합니다.

swapchain 소멸

특정 swapchain과 연결된 SwappyVk 데이터를 소멸하려면 다음 코드 스니펫에 나와 있는 단계를 완료하세요.

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

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