הוספת פונקציות של קצב ניצול הפריימים

כדי להשתמש בקצב הפריימים של Android עם מנוע עיבוד, צריך להשתמש בפונקציות הבאות על סמך ממשק ה-API של Vulkan.

זיהוי התוספים הנדרשים ליצירה

כדי לאסוף את קבוצת התוספים הדרושים ליצירת מופע של Android Frame קצב השימוש ב-Vulkan צריך לבצע את השלבים שמופיעים בקוד הבא snippet:

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

לאחר מכן אפשר להפעיל את קצב הפריימים ב-Android על ידי התקשרות למספר vkCreateDevice(). השנייה ארגומנט, מבנה מסוג VkDeviceCreateInfo*, צריך להכיל מנוי enabledExtensionCount הוגדר למספר התוספים הנדרש.

זיהוי של משפחת תורים

כדי להציג את תור התצוגה הנכון, קצב הפריימים של Android צריך לדעת משפחת 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);

הגדרת קצב פריימים להחלפה

כדי לאתחל את קצב הפריימים ב-Android עבור מכשיר פיזי ושרשור החלפה מסוימים, השלימו את השלבים שמוצגים בקטע הקוד הבא:

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

ל-Swappy נדרשת מזהה של ANativeWindow כדי לבצע את הפעולה פעולה ספציפית ל-ANativeWindow, כמו התקשרות ANativeWindow_setFrameRate(). שיחת טלפון SwappyVk_setWindow() כשמסך ה-Android משתנה ויש לכם מכשיר ANativeWindow חדש (לדוגמה, אפשר לעיין בדוגמה של Cube).

מצבים אוטומטיים

קצב הפריימים ב-Android מתאים את משך ההחלפה ומצב צינור עיבוד הנתונים על סמך משך הזמן הממוצע של הפריימים הקודמים. אפשר לשלוט בהתנהגות הזו באמצעות את הפונקציות הבאות:

הצגה של מסגרת

כדי להציג מסגרת של המשחק ל-Android Frame Pacing, צריך להתקשר SwappyVk_queuePresent() הפונקציה הזו מפעילה את הפקודה vkQueuePresentKHR() בשם המשחק.

להרוס את שרשרת ההחלפה

כדי להשמיד את נתוני SwappyVk המשויכים לשרשור החלפה נתון, משלימים את את השלבים שמוצגים בקטע הקוד הבא:

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

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