/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <android/log.h>
#include <driver.h>
#include <gmock/gmock.h>
#include <graphicsenv/GraphicsEnv.h>
#include <gtest/gtest.h>
#include <media/NdkImageReader.h>
#include <system/window.h>
#include <vulkan/vulkan.h>

#define LOGI(...) \
    __android_log_print(ANDROID_LOG_INFO, "libvulkan_test", __VA_ARGS__)
#define LOGE(...) \
    __android_log_print(ANDROID_LOG_ERROR, "libvulkan_test", __VA_ARGS__)

#define VK_CHECK(result) ASSERT_EQ(VK_SUCCESS, result)

namespace android {

namespace libvulkantest {

class AImageReaderVulkanSwapchainTest : public ::testing::Test {
   public:
    AImageReaderVulkanSwapchainTest() {}

    AImageReader* mReader = nullptr;
    ANativeWindow* mWindow = nullptr;
    VkInstance mVkInstance = VK_NULL_HANDLE;
    VkPhysicalDevice mPhysicalDev = VK_NULL_HANDLE;
    VkDevice mDevice = VK_NULL_HANDLE;
    VkSurfaceKHR mSurface = VK_NULL_HANDLE;
    VkQueue mPresentQueue = VK_NULL_HANDLE;
    uint32_t mPresentQueueFamily = UINT32_MAX;
    VkSwapchainKHR mSwapchain = VK_NULL_HANDLE;

    void SetUp() override {
        // We need this to run before any other vulkan tests. Otherwise the
        // layers are already marked as loaded
        auto app_namespace =
            android::GraphicsEnv::getInstance().getAppNamespace();
        android::GraphicsEnv::getInstance().setLayerPaths(
            app_namespace,
            "/data/local/tmp/libvulkan_test/x86_64/:/data/local/tmp/"
            "libvulkan_test/arm64/");
    }

    void TearDown() override {}

    // ------------------------------------------------------
    // Helper methods
    // ------------------------------------------------------

    void createVulkanInstance(std::vector<const char*>& layers) {
        const char* extensions[] = {
            VK_KHR_SURFACE_EXTENSION_NAME,
            VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
            VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME,
            VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
        };

        VkApplicationInfo appInfo{};
        appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
        appInfo.pApplicationName = "AImageReader Vulkan Swapchain Test";
        appInfo.applicationVersion = 1;
        appInfo.pEngineName = "TestEngine";
        appInfo.engineVersion = 1;
        appInfo.apiVersion = VK_API_VERSION_1_0;

        VkInstanceCreateInfo instInfo{};
        instInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
        instInfo.pApplicationInfo = &appInfo;
        instInfo.enabledExtensionCount =
            sizeof(extensions) / sizeof(extensions[0]);
        instInfo.ppEnabledExtensionNames = extensions;
        instInfo.enabledLayerCount = layers.size();
        instInfo.ppEnabledLayerNames = layers.data();
        VkResult res = vkCreateInstance(&instInfo, nullptr, &mVkInstance);
        VK_CHECK(res);
        LOGE("Vulkan instance created");
    }

    void createAImageReader(int width,
                            int height,
                            int format,
                            int maxImages,
                            bool set_listener = true) {
        media_status_t status =
            AImageReader_new(width, height, format, maxImages, &mReader);
        ASSERT_EQ(AMEDIA_OK, status) << "Failed to create AImageReader";
        ASSERT_NE(nullptr, mReader) << "AImageReader is null";

        if (set_listener) {
            // Optionally set a listener
            AImageReader_ImageListener listener{};
            listener.context = this;
            listener.onImageAvailable =
                &AImageReaderVulkanSwapchainTest::onImageAvailable;
            AImageReader_setImageListener(mReader, &listener);

            LOGI("AImageReader created with %dx%d, format=%d", width, height,
                 format);
        }
    }

    void getANativeWindowFromReader() {
        ASSERT_NE(nullptr, mReader);

        media_status_t status = AImageReader_getWindow(mReader, &mWindow);
        ASSERT_EQ(AMEDIA_OK, status)
            << "Failed to get ANativeWindow from AImageReader";
        ASSERT_NE(nullptr, mWindow) << "ANativeWindow is null";
        LOGI("ANativeWindow obtained from AImageReader");
    }

    void createVulkanSurface() {
        ASSERT_NE((VkInstance)VK_NULL_HANDLE, mVkInstance);
        ASSERT_NE((ANativeWindow*)nullptr, mWindow);

        VkAndroidSurfaceCreateInfoKHR surfaceCreateInfo{};
        surfaceCreateInfo.sType =
            VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
        surfaceCreateInfo.window = mWindow;

        VkResult res = vkCreateAndroidSurfaceKHR(
            mVkInstance, &surfaceCreateInfo, nullptr, &mSurface);
        VK_CHECK(res);
        LOGI("Vulkan surface created from ANativeWindow");
    }

    void pickPhysicalDeviceAndQueueFamily() {
        ASSERT_NE((VkInstance)VK_NULL_HANDLE, mVkInstance);

        uint32_t deviceCount = 0;
        vkEnumeratePhysicalDevices(mVkInstance, &deviceCount, nullptr);
        ASSERT_GT(deviceCount, 0U) << "No Vulkan physical devices found!";

        std::vector<VkPhysicalDevice> devices(deviceCount);
        vkEnumeratePhysicalDevices(mVkInstance, &deviceCount, devices.data());

        for (auto& dev : devices) {
            uint32_t queueFamilyCount = 0;
            vkGetPhysicalDeviceQueueFamilyProperties(dev, &queueFamilyCount,
                                                     nullptr);
            std::vector<VkQueueFamilyProperties> queueProps(queueFamilyCount);
            vkGetPhysicalDeviceQueueFamilyProperties(dev, &queueFamilyCount,
                                                     queueProps.data());

            for (uint32_t i = 0; i < queueFamilyCount; i++) {
                VkBool32 support = VK_FALSE;
                vkGetPhysicalDeviceSurfaceSupportKHR(dev, i, mSurface,
                                                     &support);
                if (support == VK_TRUE) {
                    // Found a queue family that can present
                    mPhysicalDev = dev;
                    mPresentQueueFamily = i;

                    LOGI(
                        "Physical device found with queue family %u supporting "
                        "present",
                        i);
                    return;
                }
            }
        }

        FAIL()
            << "No physical device found that supports present to the surface!";
    }

    void createDeviceAndGetQueue(std::vector<const char*>& layers,
                                 std::vector<const char*> inExtensions = {},
                                 void* pNext = nullptr) {
        ASSERT_NE((void*)VK_NULL_HANDLE, mPhysicalDev);
        ASSERT_NE(UINT32_MAX, mPresentQueueFamily);

        float queuePriority = 1.0f;
        VkDeviceQueueCreateInfo queueInfo{};
        queueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
        queueInfo.queueFamilyIndex = mPresentQueueFamily;
        queueInfo.queueCount = 1;
        queueInfo.pQueuePriorities = &queuePriority;

        VkDeviceCreateInfo deviceInfo{};
        deviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
        deviceInfo.pNext = pNext;
        deviceInfo.queueCreateInfoCount = 1;
        deviceInfo.pQueueCreateInfos = &queueInfo;
        deviceInfo.enabledLayerCount = layers.size();
        deviceInfo.ppEnabledLayerNames = layers.data();

        std::vector<const char*> extensions = {
            VK_KHR_SWAPCHAIN_EXTENSION_NAME,
        };
        for (auto extension : inExtensions) {
            extensions.push_back(extension);
        }
        deviceInfo.enabledExtensionCount = extensions.size();
        deviceInfo.ppEnabledExtensionNames = extensions.data();

        VkResult res =
            vkCreateDevice(mPhysicalDev, &deviceInfo, nullptr, &mDevice);
        VK_CHECK(res);
        LOGI("Logical device created");

        vkGetDeviceQueue(mDevice, mPresentQueueFamily, 0, &mPresentQueue);
        ASSERT_NE((VkQueue)VK_NULL_HANDLE, mPresentQueue);
        LOGI("Acquired present-capable queue");
    }

    void createSwapchain() {
        ASSERT_NE((VkDevice)VK_NULL_HANDLE, mDevice);
        ASSERT_NE((VkSurfaceKHR)VK_NULL_HANDLE, mSurface);

        VkSurfaceCapabilitiesKHR surfaceCaps{};
        VK_CHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
            mPhysicalDev, mSurface, &surfaceCaps));

        uint32_t formatCount = 0;
        vkGetPhysicalDeviceSurfaceFormatsKHR(mPhysicalDev, mSurface,
                                             &formatCount, nullptr);
        ASSERT_GT(formatCount, 0U);
        std::vector<VkSurfaceFormatKHR> formats(formatCount);
        vkGetPhysicalDeviceSurfaceFormatsKHR(mPhysicalDev, mSurface,
                                             &formatCount, formats.data());

        VkSurfaceFormatKHR chosenFormat = formats[0];
        LOGI("Chosen surface format: %d", chosenFormat.format);

        uint32_t presentModeCount = 0;
        vkGetPhysicalDeviceSurfacePresentModesKHR(mPhysicalDev, mSurface,
                                                  &presentModeCount, nullptr);
        ASSERT_GT(presentModeCount, 0U);
        std::vector<VkPresentModeKHR> presentModes(presentModeCount);
        vkGetPhysicalDeviceSurfacePresentModesKHR(
            mPhysicalDev, mSurface, &presentModeCount, presentModes.data());

        VkPresentModeKHR chosenPresentMode = VK_PRESENT_MODE_FIFO_KHR;
        for (auto mode : presentModes) {
            if (mode == VK_PRESENT_MODE_FIFO_KHR) {
                chosenPresentMode = mode;
                break;
            }
        }
        LOGI("Chosen present mode: %d", chosenPresentMode);

        VkExtent2D swapchainExtent{};
        if (surfaceCaps.currentExtent.width == 0xFFFFFFFF) {
            swapchainExtent.width = 640;   // fallback
            swapchainExtent.height = 480;  // fallback
        } else {
            swapchainExtent = surfaceCaps.currentExtent;
        }
        LOGI("Swapchain extent: %d x %d", swapchainExtent.width,
             swapchainExtent.height);

        uint32_t desiredImageCount = surfaceCaps.minImageCount + 1;
        if (surfaceCaps.maxImageCount > 0 &&
            desiredImageCount > surfaceCaps.maxImageCount) {
            desiredImageCount = surfaceCaps.maxImageCount;
        }

        VkSwapchainCreateInfoKHR swapchainInfo{};
        swapchainInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
        swapchainInfo.surface = mSurface;
        swapchainInfo.minImageCount = desiredImageCount;
        swapchainInfo.imageFormat = chosenFormat.format;
        swapchainInfo.imageColorSpace = chosenFormat.colorSpace;
        swapchainInfo.imageExtent = swapchainExtent;
        swapchainInfo.imageArrayLayers = 1;
        swapchainInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
                                   VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
        swapchainInfo.preTransform = surfaceCaps.currentTransform;
        swapchainInfo.compositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
        swapchainInfo.presentMode = chosenPresentMode;
        swapchainInfo.clipped = VK_TRUE;
        swapchainInfo.oldSwapchain = VK_NULL_HANDLE;

        uint32_t queueFamilyIndices[] = {mPresentQueueFamily};
        swapchainInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
        swapchainInfo.queueFamilyIndexCount = 1;
        swapchainInfo.pQueueFamilyIndices = queueFamilyIndices;

        VkResult res =
            vkCreateSwapchainKHR(mDevice, &swapchainInfo, nullptr, &mSwapchain);
        if (res == VK_SUCCESS) {
            LOGI("Swapchain created successfully");

            uint32_t swapchainImageCount = 0;
            vkGetSwapchainImagesKHR(mDevice, mSwapchain, &swapchainImageCount,
                                    nullptr);
            std::vector<VkImage> swapchainImages(swapchainImageCount);
            vkGetSwapchainImagesKHR(mDevice, mSwapchain, &swapchainImageCount,
                                    swapchainImages.data());

            LOGI("Swapchain has %u images", swapchainImageCount);
        } else {
            LOGI("Swapchain creation failed");
        }
    }

    // Image available callback (AImageReader)
    static void onImageAvailable(void*, AImageReader* reader) {
        LOGI("onImageAvailable callback triggered");
        AImage* image = nullptr;
        media_status_t status = AImageReader_acquireLatestImage(reader, &image);
        if (status != AMEDIA_OK || !image) {
            LOGE("Failed to acquire latest image");
            return;
        }
        AImage_delete(image);
        LOGI("Released acquired image");
    }

    void cleanUpSwapchainForTest() {
        if (mSwapchain != VK_NULL_HANDLE) {
            vkDestroySwapchainKHR(mDevice, mSwapchain, nullptr);
            mSwapchain = VK_NULL_HANDLE;
        }
        if (mDevice != VK_NULL_HANDLE) {
            vkDestroyDevice(mDevice, nullptr);
            mDevice = VK_NULL_HANDLE;
        }
        if (mSurface != VK_NULL_HANDLE) {
            vkDestroySurfaceKHR(mVkInstance, mSurface, nullptr);
            mSurface = VK_NULL_HANDLE;
        }
        if (mVkInstance != VK_NULL_HANDLE) {
            vkDestroyInstance(mVkInstance, nullptr);
            mVkInstance = VK_NULL_HANDLE;
        }
        if (mReader) {
            // AImageReader_delete(mReader);
            mReader = nullptr;
        }
        // Note: The ANativeWindow from AImageReader is implicitly
        // managed by the reader, so we don't explicitly delete it.
        mWindow = nullptr;
    }

    void buildSwapchianForTest(std::vector<const char*>& instanceLayers,
                               std::vector<const char*>& deviceLayers) {
        createVulkanInstance(instanceLayers);

        // the "atest libvulkan_test" command will execute this test as a binary
        // (not apk) on the device. Consequently we can't render to the screen
        // and need to work around this by using AImageReader*
        createAImageReader(640, 480, AIMAGE_FORMAT_PRIVATE, 3);
        getANativeWindowFromReader();
        createVulkanSurface();
        pickPhysicalDeviceAndQueueFamily();

        createDeviceAndGetQueue(deviceLayers);
        createSwapchain();
    }
};

TEST_F(AImageReaderVulkanSwapchainTest, TestHelperMethods) {
    // Verify that the basic plumbing/helper functions of these tests is
    // working. This doesn't directly test any of the layer code. It only
    // verifies that we can successfully create a swapchain with an AImageReader

    std::vector<const char*> instanceLayers;
    std::vector<const char*> deviceLayers;
    buildSwapchianForTest(deviceLayers, instanceLayers);

    ASSERT_NE(mVkInstance, (VkInstance)VK_NULL_HANDLE);
    ASSERT_NE(mPhysicalDev, (VkPhysicalDevice)VK_NULL_HANDLE);
    ASSERT_NE(mDevice, (VkDevice)VK_NULL_HANDLE);
    ASSERT_NE(mSurface, (VkSurfaceKHR)VK_NULL_HANDLE);
    ASSERT_NE(mSwapchain, (VkSwapchainKHR)VK_NULL_HANDLE);
    cleanUpSwapchainForTest();
}

// Passing state in these tests requires global state. Wrap each test in an
// anonymous namespace to prevent conflicting names.
namespace {

VKAPI_ATTR VkResult VKAPI_CALL hookedGetPhysicalDeviceImageFormatProperties2KHR(
    VkPhysicalDevice,
    const VkPhysicalDeviceImageFormatInfo2*,
    VkImageFormatProperties2*) {
    return VK_ERROR_SURFACE_LOST_KHR;
}

static PFN_vkGetSwapchainGrallocUsage2ANDROID
    pfnNextGetSwapchainGrallocUsage2ANDROID = nullptr;

static bool g_grallocCalled = false;

VKAPI_ATTR VkResult VKAPI_CALL hookGetSwapchainGrallocUsage2ANDROID(
    VkDevice device,
    VkFormat format,
    VkImageUsageFlags imageUsage,
    VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,
    uint64_t* grallocConsumerUsage,
    uint64_t* grallocProducerUsage) {
    g_grallocCalled = true;
    if (pfnNextGetSwapchainGrallocUsage2ANDROID) {
        return pfnNextGetSwapchainGrallocUsage2ANDROID(
            device, format, imageUsage, swapchainImageUsage,
            grallocConsumerUsage, grallocProducerUsage);
    }

    return VK_ERROR_INITIALIZATION_FAILED;
}

TEST_F(AImageReaderVulkanSwapchainTest, getProducerUsageFallbackTest1) {
    // BUG: 379230826
    // Verify that getProducerUsage falls back to
    // GetSwapchainGrallocUsage*ANDROID if GPDIFP2 fails
    std::vector<const char*> instanceLayers = {};
    std::vector<const char*> deviceLayers = {};
    createVulkanInstance(instanceLayers);

    createAImageReader(640, 480, AIMAGE_FORMAT_PRIVATE, 3);
    getANativeWindowFromReader();
    createVulkanSurface();
    pickPhysicalDeviceAndQueueFamily();

    createDeviceAndGetQueue(deviceLayers);
    auto& pdev = vulkan::driver::GetData(mDevice).driver_physical_device;
    auto& pdevDispatchTable = vulkan::driver::GetData(pdev).driver;
    auto& deviceDispatchTable = vulkan::driver::GetData(mDevice).driver;

    ASSERT_NE(deviceDispatchTable.GetSwapchainGrallocUsage2ANDROID, nullptr);

    pdevDispatchTable.GetPhysicalDeviceImageFormatProperties2 =
        hookedGetPhysicalDeviceImageFormatProperties2KHR;
    deviceDispatchTable.GetSwapchainGrallocUsage2ANDROID =
        hookGetSwapchainGrallocUsage2ANDROID;

    ASSERT_FALSE(g_grallocCalled);

    createSwapchain();

    ASSERT_TRUE(g_grallocCalled);

    ASSERT_NE(mVkInstance, (VkInstance)VK_NULL_HANDLE);
    ASSERT_NE(mPhysicalDev, (VkPhysicalDevice)VK_NULL_HANDLE);
    ASSERT_NE(mDevice, (VkDevice)VK_NULL_HANDLE);
    ASSERT_NE(mSurface, (VkSurfaceKHR)VK_NULL_HANDLE);
    cleanUpSwapchainForTest();
}

}  // namespace

// Passing state in these tests requires global state. Wrap each test in an
// anonymous namespace to prevent conflicting names.
namespace {

static bool g_returnNotSupportedOnce = true;

VKAPI_ATTR VkResult VKAPI_CALL
Hook_GetPhysicalDeviceImageFormatProperties2_NotSupportedOnce(
    VkPhysicalDevice /*physicalDevice*/,
    const VkPhysicalDeviceImageFormatInfo2* /*pImageFormatInfo*/,
    VkImageFormatProperties2* /*pImageFormatProperties*/) {
    if (g_returnNotSupportedOnce) {
        g_returnNotSupportedOnce = false;
        return VK_ERROR_FORMAT_NOT_SUPPORTED;
    }
    return VK_SUCCESS;
}

TEST_F(AImageReaderVulkanSwapchainTest, SurfaceFormats2KHR_IgnoreNotSupported) {
    // BUG: 357903074
    // Verify that vkGetPhysicalDeviceSurfaceFormats2KHR properly
    // ignores VK_ERROR_FORMAT_NOT_SUPPORTED and continues enumerating formats.
    std::vector<const char*> instanceLayers;
    createVulkanInstance(instanceLayers);
    createAImageReader(640, 480, AIMAGE_FORMAT_PRIVATE, 3);
    getANativeWindowFromReader();
    createVulkanSurface();
    pickPhysicalDeviceAndQueueFamily();

    auto& pdevDispatchTable = vulkan::driver::GetData(mPhysicalDev).driver;
    pdevDispatchTable.GetPhysicalDeviceImageFormatProperties2 =
        Hook_GetPhysicalDeviceImageFormatProperties2_NotSupportedOnce;

    PFN_vkGetPhysicalDeviceSurfaceFormats2KHR
        pfnGetPhysicalDeviceSurfaceFormats2KHR =
            reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceFormats2KHR>(
                vkGetInstanceProcAddr(mVkInstance,
                                      "vkGetPhysicalDeviceSurfaceFormats2KHR"));
    ASSERT_NE(nullptr, pfnGetPhysicalDeviceSurfaceFormats2KHR)
        << "Could not get pointer to vkGetPhysicalDeviceSurfaceFormats2KHR";

    VkPhysicalDeviceSurfaceInfo2KHR surfaceInfo2{};
    surfaceInfo2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR;
    surfaceInfo2.pNext = nullptr;
    surfaceInfo2.surface = mSurface;

    uint32_t formatCount = 0;
    VkResult res = pfnGetPhysicalDeviceSurfaceFormats2KHR(
        mPhysicalDev, &surfaceInfo2, &formatCount, nullptr);

    // If the loader never tries a second format, it might fail or 0-out the
    // formatCount. The patch ensures it continues to the next format rather
    // than bailing out on the first NOT_SUPPORTED.
    ASSERT_EQ(VK_SUCCESS, res)
        << "vkGetPhysicalDeviceSurfaceFormats2KHR failed unexpectedly";
    ASSERT_GT(formatCount, 0U)
        << "No surface formats found; the loader may have bailed early.";

    std::vector<VkSurfaceFormat2KHR> formats(formatCount);
    for (auto& f : formats) {
        f.sType = VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR;
        f.pNext = nullptr;
    }
    res = pfnGetPhysicalDeviceSurfaceFormats2KHR(mPhysicalDev, &surfaceInfo2,
                                                 &formatCount, formats.data());
    ASSERT_EQ(VK_SUCCESS, res) << "Failed to retrieve surface formats";

    LOGI(
        "SurfaceFormats2KHR_IgnoreNotSupported test: found %u formats after "
        "ignoring NOT_SUPPORTED",
        formatCount);

    cleanUpSwapchainForTest();
}

}  // namespace

namespace {

TEST_F(AImageReaderVulkanSwapchainTest, MutableFormatSwapchainTest) {
    // Test swapchain with mutable format extension
    std::vector<const char*> instanceLayers;
    std::vector<const char*> deviceLayers;
    std::vector<const char*> deviceExtensions = {
        VK_KHR_SWAPCHAIN_EXTENSION_NAME,
        VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME,
        VK_KHR_MAINTENANCE2_EXTENSION_NAME,
        VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME};

    createVulkanInstance(instanceLayers);
    createAImageReader(640, 480, AIMAGE_FORMAT_PRIVATE, 3);
    getANativeWindowFromReader();
    createVulkanSurface();
    pickPhysicalDeviceAndQueueFamily();
    createDeviceAndGetQueue(deviceLayers, deviceExtensions);

    ASSERT_NE((VkDevice)VK_NULL_HANDLE, mDevice);
    ASSERT_NE((VkSurfaceKHR)VK_NULL_HANDLE, mSurface);

    VkSurfaceCapabilitiesKHR surfaceCaps{};
    VK_CHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(mPhysicalDev, mSurface,
                                                       &surfaceCaps));

    uint32_t formatCount = 0;
    vkGetPhysicalDeviceSurfaceFormatsKHR(mPhysicalDev, mSurface, &formatCount,
                                         nullptr);
    ASSERT_GT(formatCount, 0U);
    std::vector<VkSurfaceFormatKHR> formats(formatCount);
    vkGetPhysicalDeviceSurfaceFormatsKHR(mPhysicalDev, mSurface, &formatCount,
                                         formats.data());

    VkFormat viewFormats[2] = {formats[0].format, formats[0].format};
    if (formatCount > 1) {
        viewFormats[1] = formats[1].format;
    }

    VkImageFormatListCreateInfoKHR formatList{};
    formatList.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR;
    formatList.viewFormatCount = 2;
    formatList.pViewFormats = viewFormats;

    VkSwapchainCreateInfoKHR swapchainInfo{};
    swapchainInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
    swapchainInfo.pNext = &formatList;
    swapchainInfo.surface = mSurface;
    swapchainInfo.minImageCount = surfaceCaps.minImageCount + 1;
    swapchainInfo.imageFormat = formats[0].format;
    swapchainInfo.imageColorSpace = formats[0].colorSpace;
    swapchainInfo.imageExtent = surfaceCaps.currentExtent;
    swapchainInfo.imageArrayLayers = 1;
    swapchainInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
    swapchainInfo.preTransform = surfaceCaps.currentTransform;
    swapchainInfo.compositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
    swapchainInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR;
    swapchainInfo.clipped = VK_TRUE;

    swapchainInfo.flags = VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR;

    uint32_t queueFamilyIndices[] = {mPresentQueueFamily};
    swapchainInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
    swapchainInfo.queueFamilyIndexCount = 1;
    swapchainInfo.pQueueFamilyIndices = queueFamilyIndices;

    VkResult res =
        vkCreateSwapchainKHR(mDevice, &swapchainInfo, nullptr, &mSwapchain);
    if (res == VK_SUCCESS) {
        LOGI("Mutable format swapchain created successfully");

        uint32_t imageCount = 0;
        vkGetSwapchainImagesKHR(mDevice, mSwapchain, &imageCount, nullptr);
        ASSERT_GT(imageCount, 0U);
    } else {
        LOGI(
            "Mutable format swapchain creation failed (extension may not be "
            "supported)");
    }

    cleanUpSwapchainForTest();
}

}  // namespace

int Hook_ANativeWindow_Perform_FakeTimestamps(ANativeWindow* window,
                                              ANativeWindow_performFn perform,
                                              void*,
                                              int operation,
                                              va_list args) {
    if (operation == NATIVE_WINDOW_GET_FRAME_TIMESTAMPS) {
        ALOGI("Intercepted NATIVE_WINDOW_GET_FRAME_TIMESTAMPS");
        uint64_t frameId = va_arg(args, uint64_t);
        int64_t* outRequestedPresentTime = va_arg(args, int64_t*);
        int64_t* outAcquireTime = va_arg(args, int64_t*);
        int64_t* outLatchTime = va_arg(args, int64_t*);
        int64_t* outFirstRefreshStartTime = va_arg(args, int64_t*);
        int64_t* outLastRefreshStartTime = va_arg(args, int64_t*);
        int64_t* outGpuCompositionDoneTime = va_arg(args, int64_t*);
        int64_t* outDisplayPresentTime = va_arg(args, int64_t*);
        int64_t* outDequeueReadyTime = va_arg(args, int64_t*);
        int64_t* outReleaseTime = va_arg(args, int64_t*);

        if (outRequestedPresentTime)
            *outRequestedPresentTime = frameId;
        if (outAcquireTime)
            *outAcquireTime = frameId;
        if (outLatchTime)
            *outLatchTime = frameId;
        if (outFirstRefreshStartTime)
            *outFirstRefreshStartTime = frameId;
        if (outLastRefreshStartTime)
            *outLastRefreshStartTime = frameId;
        if (outGpuCompositionDoneTime)
            *outGpuCompositionDoneTime = frameId;
        if (outDisplayPresentTime)
            *outDisplayPresentTime = frameId;
        if (outDequeueReadyTime)
            *outDequeueReadyTime = frameId;
        if (outReleaseTime)
            *outReleaseTime = frameId;

        return 0;
    }

    return perform(window, operation, args);
}

TEST_F(AImageReaderVulkanSwapchainTest, FrameTimestampInterceptorTest) {
    // verify native_window_get_frame_timestamp can be intercepted
    std::vector<const char*> instanceLayers;
    std::vector<const char*> deviceLayers;

    createVulkanInstance(instanceLayers);
    createAImageReader(640, 480, AIMAGE_FORMAT_PRIVATE, 3);
    getANativeWindowFromReader();
    ASSERT_NE(mWindow, nullptr);

    int result = mWindow->perform(
        mWindow, NATIVE_WINDOW_SET_PERFORM_INTERCEPTOR,
        Hook_ANativeWindow_Perform_FakeTimestamps, nullptr /* data */);
    ASSERT_EQ(result, 0);

    int64_t latchTime = 0;
    native_window_get_frame_timestamps(mWindow, 123, nullptr, nullptr,
                                       &latchTime, nullptr, nullptr, nullptr,
                                       nullptr, nullptr, nullptr);

    ASSERT_EQ(latchTime, 123);

    cleanUpSwapchainForTest();
}

TEST_F(AImageReaderVulkanSwapchainTest, StandardPresentTimingCountTest) {
    // verify we only wait 1 frame for timing results b/440824659
    std::vector<const char*> instanceLayers = {};
    std::vector<const char*> deviceLayers = {};
    std::vector<const char*> deviceExtensions = {
        VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME,
    };

    createVulkanInstance(instanceLayers);
    createAImageReader(640, 480, AIMAGE_FORMAT_PRIVATE, 3);
    getANativeWindowFromReader();

    int result = mWindow->perform(
        mWindow, NATIVE_WINDOW_SET_PERFORM_INTERCEPTOR,
        Hook_ANativeWindow_Perform_FakeTimestamps, nullptr /* data */);
    createVulkanSurface();
    pickPhysicalDeviceAndQueueFamily();

    // Check if the required display timing extension is supported by the
    // device.
    uint32_t extensionCount = 0;
    vkEnumerateDeviceExtensionProperties(mPhysicalDev, nullptr, &extensionCount,
                                         nullptr);
    std::vector<VkExtensionProperties> availableExtensions(extensionCount);
    vkEnumerateDeviceExtensionProperties(mPhysicalDev, nullptr, &extensionCount,
                                         availableExtensions.data());

    bool timingExtSupported = false;
    for (const auto& extension : availableExtensions) {
        if (strcmp(extension.extensionName,
                   VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME) == 0) {
            timingExtSupported = true;
            break;
        }
    }

    if (!timingExtSupported) {
        GTEST_SKIP() << "Vulkan extension "
                     << VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME
                     << " not supported.";
    }

    createDeviceAndGetQueue(deviceLayers, deviceExtensions);

    VkSurfaceCapabilitiesKHR surfaceCaps{};
    VK_CHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(mPhysicalDev, mSurface,
                                                       &surfaceCaps));

    uint32_t imageCount = surfaceCaps.minImageCount + 1;
    if (surfaceCaps.maxImageCount > 0 &&
        imageCount > surfaceCaps.maxImageCount) {
        imageCount = surfaceCaps.maxImageCount;
    }

    VkSwapchainCreateInfoKHR swapchainInfo{};
    swapchainInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
    swapchainInfo.surface = mSurface;
    swapchainInfo.minImageCount = imageCount;
    swapchainInfo.imageFormat = VK_FORMAT_R8G8B8A8_UNORM;
    swapchainInfo.imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
    swapchainInfo.imageExtent = surfaceCaps.currentExtent;
    swapchainInfo.imageArrayLayers = 1;
    swapchainInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
    swapchainInfo.preTransform = surfaceCaps.currentTransform;
    swapchainInfo.compositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
    swapchainInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR;
    swapchainInfo.clipped = VK_TRUE;

    VkResult res =
        vkCreateSwapchainKHR(mDevice, &swapchainInfo, nullptr, &mSwapchain);
    VK_CHECK(res);
    ASSERT_NE(mSwapchain, (VkSwapchainKHR)VK_NULL_HANDLE);

    uint32_t imageIndex;
    res = vkAcquireNextImageKHR(mDevice, mSwapchain, UINT64_MAX, VK_NULL_HANDLE,
                                VK_NULL_HANDLE, &imageIndex);
    VK_CHECK(res);

    VkPresentTimeGOOGLE presentTime = {1, 1000};
    VkPresentTimesInfoGOOGLE presentTimesInfo = {};
    presentTimesInfo.sType = VK_STRUCTURE_TYPE_PRESENT_TIMES_INFO_GOOGLE;
    presentTimesInfo.swapchainCount = 1;
    presentTimesInfo.pTimes = &presentTime;

    VkPresentInfoKHR presentInfo = {};
    presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
    presentInfo.pNext = &presentTimesInfo;
    presentInfo.swapchainCount = 1;
    presentInfo.pSwapchains = &mSwapchain;
    presentInfo.pImageIndices = &imageIndex;

    res = vkQueuePresentKHR(mPresentQueue, &presentInfo);
    VK_CHECK(res);
    auto pfnGetPastPresentationTimingGOOGLE =
        (PFN_vkGetPastPresentationTimingGOOGLE)vkGetDeviceProcAddr(
            mDevice, "vkGetPastPresentationTimingGOOGLE");
    ASSERT_NE(pfnGetPastPresentationTimingGOOGLE,
              (PFN_vkGetPastPresentationTimingGOOGLE) nullptr);

    uint32_t timingCount = 0;
    res = pfnGetPastPresentationTimingGOOGLE(mDevice, mSwapchain, &timingCount,
                                             nullptr);
    VK_CHECK(res);

    ASSERT_TRUE(timingCount == 1)
        << "Expected one timing record to be available.";

    cleanUpSwapchainForTest();
}

TEST_F(AImageReaderVulkanSwapchainTest, SharedPresentTimingZeroedTest) {
    // Verifies that for shared present modes, vkGetPastPresentationTimingGOOGLE
    // returns a record with zeroed-out timing values, as per the change in
    // get_num_ready_timings.
    std::vector<const char*> instanceLayers = {};
    std::vector<const char*> deviceLayers = {};
    std::vector<const char*> deviceExtensions = {
        VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME,
    };

    createVulkanInstance(instanceLayers);
    createAImageReader(640, 480, AIMAGE_FORMAT_PRIVATE, 3);
    getANativeWindowFromReader();
    createVulkanSurface();
    pickPhysicalDeviceAndQueueFamily();

    uint32_t extensionCount = 0;
    vkEnumerateDeviceExtensionProperties(mPhysicalDev, nullptr, &extensionCount,
                                         nullptr);
    std::vector<VkExtensionProperties> availableExtensions(extensionCount);
    vkEnumerateDeviceExtensionProperties(mPhysicalDev, nullptr, &extensionCount,
                                         availableExtensions.data());

    bool timingExtSupported = false;
    for (const auto& extension : availableExtensions) {
        if (strcmp(extension.extensionName,
                   VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME) == 0) {
            timingExtSupported = true;
            break;
        }
    }

    if (!timingExtSupported) {
        GTEST_SKIP() << "Vulkan extension "
                     << VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME
                     << " not supported.";
    }

    uint32_t presentModeCount = 0;
    vkGetPhysicalDeviceSurfacePresentModesKHR(mPhysicalDev, mSurface,
                                              &presentModeCount, nullptr);
    ASSERT_GT(presentModeCount, 0U);
    std::vector<VkPresentModeKHR> presentModes(presentModeCount);
    vkGetPhysicalDeviceSurfacePresentModesKHR(
        mPhysicalDev, mSurface, &presentModeCount, presentModes.data());

    bool sharedPresentSupported = false;
    for (const auto& mode : presentModes) {
        if (mode == VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR) {
            sharedPresentSupported = true;
            break;
        }
    }

    if (!sharedPresentSupported) {
        GTEST_SKIP()
            << "VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR not supported.";
    }

    createDeviceAndGetQueue(deviceLayers, deviceExtensions);

    VkSurfaceCapabilitiesKHR surfaceCaps{};
    VK_CHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(mPhysicalDev, mSurface,
                                                       &surfaceCaps));

    uint32_t imageCount = 1;

    VkSwapchainCreateInfoKHR swapchainInfo{};
    swapchainInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
    swapchainInfo.surface = mSurface;
    swapchainInfo.minImageCount = imageCount;
    swapchainInfo.imageFormat = VK_FORMAT_R8G8B8A8_UNORM;
    swapchainInfo.imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
    swapchainInfo.imageExtent = surfaceCaps.currentExtent;
    swapchainInfo.imageArrayLayers = 1;
    swapchainInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
    swapchainInfo.preTransform = surfaceCaps.currentTransform;
    swapchainInfo.compositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
    swapchainInfo.presentMode = VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR;
    swapchainInfo.clipped = VK_TRUE;

    VkResult res =
        vkCreateSwapchainKHR(mDevice, &swapchainInfo, nullptr, &mSwapchain);
    VK_CHECK(res);
    ASSERT_NE(mSwapchain, (VkSwapchainKHR)VK_NULL_HANDLE);

    uint32_t imageIndex;
    res = vkAcquireNextImageKHR(mDevice, mSwapchain, UINT64_MAX, VK_NULL_HANDLE,
                                VK_NULL_HANDLE, &imageIndex);
    VK_CHECK(res);
    ASSERT_EQ(imageIndex, 0U);

    VkPresentTimeGOOGLE presentTime = {123, 456};
    VkPresentTimesInfoGOOGLE presentTimesInfo = {};
    presentTimesInfo.sType = VK_STRUCTURE_TYPE_PRESENT_TIMES_INFO_GOOGLE;
    presentTimesInfo.swapchainCount = 1;
    presentTimesInfo.pTimes = &presentTime;

    VkPresentInfoKHR presentInfo = {};
    presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
    presentInfo.pNext = &presentTimesInfo;
    presentInfo.swapchainCount = 1;
    presentInfo.pSwapchains = &mSwapchain;
    presentInfo.pImageIndices = &imageIndex;

    res = vkQueuePresentKHR(mPresentQueue, &presentInfo);
    VK_CHECK(res);

    auto pfnGetPastPresentationTimingGOOGLE =
        (PFN_vkGetPastPresentationTimingGOOGLE)vkGetDeviceProcAddr(
            mDevice, "vkGetPastPresentationTimingGOOGLE");
    ASSERT_NE(pfnGetPastPresentationTimingGOOGLE,
              (PFN_vkGetPastPresentationTimingGOOGLE) nullptr);

    uint32_t timingCount = 0;
    res = pfnGetPastPresentationTimingGOOGLE(mDevice, mSwapchain, &timingCount,
                                             nullptr);
    VK_CHECK(res);
    ASSERT_EQ(timingCount, 1U);

    VkPastPresentationTimingGOOGLE timing;
    timingCount = 1;
    res = pfnGetPastPresentationTimingGOOGLE(mDevice, mSwapchain, &timingCount,
                                             &timing);
    VK_CHECK(res);
    ASSERT_EQ(timingCount, 1U);

    // Verify the new behavior: present ID is preserved, but times are zero.
    EXPECT_EQ(timing.presentID, presentTime.presentID);
    EXPECT_EQ(timing.actualPresentTime, 0U);
    EXPECT_EQ(timing.earliestPresentTime, 0U);
    EXPECT_EQ(timing.presentMargin, 0U);

    cleanUpSwapchainForTest();
}

TEST_F(AImageReaderVulkanSwapchainTest, LoadInstanceLayerAndDeviceLayer) {
    // Verify our layer works as both a device and instance layer
    // building the swapchain will fail if the layer is not loaded

    std::vector<const char*> instanceLayers = {
        "VK_LAYER_libVulkanTestLayer",
    };
    std::vector<const char*> deviceLayers = {
        "VK_LAYER_libVulkanTestLayer",
    };
    buildSwapchianForTest(deviceLayers, instanceLayers);
    ASSERT_NE(mVkInstance, (VkInstance)VK_NULL_HANDLE);
    ASSERT_NE(mPhysicalDev, (VkPhysicalDevice)VK_NULL_HANDLE);
    ASSERT_NE(mDevice, (VkDevice)VK_NULL_HANDLE);
    ASSERT_NE(mSurface, (VkSurfaceKHR)VK_NULL_HANDLE);
    ASSERT_NE(mSwapchain, (VkSwapchainKHR)VK_NULL_HANDLE);
    cleanUpSwapchainForTest();
}

TEST_F(AImageReaderVulkanSwapchainTest,
       FailToLoadInstanceLayerAndDeviceLayerWithBadName) {
    // Verify .so files without "libVkLayer_" prefix are not loaded
    // building the swapchain will fail if the layer is not loaded

    std::vector<const char*> instanceLayers = {
        "VK_LAYER_libVulkanTestLayer_without_libVkLayer_prefix",
    };

    const char* extensions[] = {
        VK_KHR_SURFACE_EXTENSION_NAME,
        VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
    };

    VkApplicationInfo appInfo{};
    appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
    appInfo.pApplicationName = "AImageReader Vulkan Swapchain Test";
    appInfo.applicationVersion = 1;
    appInfo.pEngineName = "TestEngine";
    appInfo.engineVersion = 1;
    appInfo.apiVersion = VK_API_VERSION_1_0;

    VkInstanceCreateInfo instInfo{};
    instInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    instInfo.pApplicationInfo = &appInfo;
    instInfo.enabledExtensionCount = sizeof(extensions) / sizeof(extensions[0]);
    instInfo.ppEnabledExtensionNames = extensions;
    instInfo.enabledLayerCount = instanceLayers.size();
    instInfo.ppEnabledLayerNames = instanceLayers.data();
    VkResult res = vkCreateInstance(&instInfo, nullptr, &mVkInstance);

    EXPECT_EQ(res, VK_ERROR_LAYER_NOT_PRESENT);
}

TEST_F(AImageReaderVulkanSwapchainTest, PresentWait2Test) {
    std::vector<const char*> instanceLayers = {};
    std::vector<const char*> deviceLayers = {};
    std::vector<const char*> deviceExtensions = {
        VK_KHR_SWAPCHAIN_EXTENSION_NAME,
        VK_KHR_PRESENT_ID_2_EXTENSION_NAME,
        VK_KHR_PRESENT_WAIT_2_EXTENSION_NAME,
    };

    createVulkanInstance(instanceLayers);
    createAImageReader(640, 480, AIMAGE_FORMAT_PRIVATE, 1, false);
    getANativeWindowFromReader();
    createVulkanSurface();
    pickPhysicalDeviceAndQueueFamily();

    uint32_t extensionCount = 0;
    vkEnumerateDeviceExtensionProperties(mPhysicalDev, nullptr, &extensionCount,
                                         nullptr);
    std::vector<VkExtensionProperties> availableExtensions(extensionCount);
    vkEnumerateDeviceExtensionProperties(mPhysicalDev, nullptr, &extensionCount,
                                         availableExtensions.data());

    bool presentId2Supported = false;
    bool presentWait2Supported = false;
    for (const auto& extension : availableExtensions) {
        if (strcmp(extension.extensionName,
                   VK_KHR_PRESENT_ID_2_EXTENSION_NAME) == 0) {
            presentId2Supported = true;
        }
        if (strcmp(extension.extensionName,
                   VK_KHR_PRESENT_WAIT_2_EXTENSION_NAME) == 0) {
            presentWait2Supported = true;
        }
    }

    if (!presentId2Supported || !presentWait2Supported) {
        GTEST_SKIP()
            << "VK_KHR_present_id2 or VK_KHR_present_wait2 not supported";
    }

    createDeviceAndGetQueue(deviceLayers, deviceExtensions);

    VkSurfaceCapabilitiesKHR surfaceCaps{};
    VK_CHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(mPhysicalDev, mSurface,
                                                       &surfaceCaps));

    uint32_t imageCount = surfaceCaps.minImageCount + 1;
    if (surfaceCaps.maxImageCount > 0 &&
        imageCount > surfaceCaps.maxImageCount) {
        imageCount = surfaceCaps.maxImageCount;
    }

    VkSwapchainCreateInfoKHR swapchainInfo{};
    swapchainInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
    swapchainInfo.surface = mSurface;
    swapchainInfo.minImageCount = imageCount;
    swapchainInfo.imageFormat = VK_FORMAT_R8G8B8A8_UNORM;
    swapchainInfo.imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
    swapchainInfo.imageExtent = surfaceCaps.currentExtent;
    swapchainInfo.imageArrayLayers = 1;
    swapchainInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
    swapchainInfo.preTransform = surfaceCaps.currentTransform;
    swapchainInfo.compositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
    swapchainInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR;
    swapchainInfo.clipped = VK_TRUE;
    swapchainInfo.flags = VK_SWAPCHAIN_CREATE_PRESENT_WAIT_2_BIT_KHR;

    VkResult res =
        vkCreateSwapchainKHR(mDevice, &swapchainInfo, nullptr, &mSwapchain);
    VK_CHECK(res);
    ASSERT_NE(mSwapchain, (VkSwapchainKHR)VK_NULL_HANDLE);

    auto pfnWaitForPresent2KHR = (PFN_vkWaitForPresent2KHR)vkGetDeviceProcAddr(
        mDevice, "vkWaitForPresent2KHR");
    ASSERT_NE(pfnWaitForPresent2KHR, (PFN_vkWaitForPresent2KHR) nullptr);

    uint64_t presentId = 1;

    VkPresentWait2InfoKHR presentWaitInfo{};
    presentWaitInfo.sType = VK_STRUCTURE_TYPE_PRESENT_WAIT_2_INFO_KHR;
    presentWaitInfo.presentId = 1;
    presentWaitInfo.timeout = 10000;

    // Wait for a present that hasn't been queued. Counterintuitively this
    // should pass as we assume any unseen frames are past prevented frames
    res = pfnWaitForPresent2KHR(mDevice, mSwapchain, &presentWaitInfo);
    ASSERT_EQ(res, VK_SUCCESS);

    uint32_t imageIndex;
    res = vkAcquireNextImageKHR(mDevice, mSwapchain, UINT64_MAX, VK_NULL_HANDLE,
                                VK_NULL_HANDLE, &imageIndex);
    VK_CHECK(res);

    VkPresentId2KHR presentIdInfo = {};
    presentIdInfo.sType = VK_STRUCTURE_TYPE_PRESENT_ID_2_KHR;
    presentIdInfo.swapchainCount = 1;
    presentIdInfo.pPresentIds = &presentId;

    VkPresentInfoKHR presentInfo = {};
    presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
    presentInfo.pNext = &presentIdInfo;
    presentInfo.swapchainCount = 1;
    presentInfo.pSwapchains = &mSwapchain;
    presentInfo.pImageIndices = &imageIndex;

    res = vkQueuePresentKHR(mPresentQueue, &presentInfo);
    VK_CHECK(res);

    // Make sure we get a timeout for a frame which remains in flight
    res = pfnWaitForPresent2KHR(mDevice, mSwapchain, &presentWaitInfo);
    ASSERT_EQ(res, VK_TIMEOUT);

    // Call this to trigger the frame acquired callback in
    // BufferQueueConsumer::acquireBufer
    AImage* image = nullptr;
    media_status_t status = AImageReader_acquireLatestImage(mReader, &image);

    // Wait for the presentId we just submitted. Should succeed.
    res = pfnWaitForPresent2KHR(mDevice, mSwapchain, &presentWaitInfo);
    ASSERT_EQ(res, VK_SUCCESS);

    cleanUpSwapchainForTest();
}

TEST_F(AImageReaderVulkanSwapchainTest, PresentWait2ManyFrames) {
    // Test vk_khr_present_wait2 with many frames. This also tests the
    // native_window_get_last_replaced_frame_id logic inside swapchain.cpp
    std::vector<const char*> instanceLayers = {};
    std::vector<const char*> deviceLayers = {};
    std::vector<const char*> deviceExtensions = {
        VK_KHR_SWAPCHAIN_EXTENSION_NAME,
        VK_KHR_PRESENT_ID_2_EXTENSION_NAME,
        VK_KHR_PRESENT_WAIT_2_EXTENSION_NAME,
    };

    createVulkanInstance(instanceLayers);
    createAImageReader(640, 480, AIMAGE_FORMAT_PRIVATE, 1, false);
    getANativeWindowFromReader();
    createVulkanSurface();
    pickPhysicalDeviceAndQueueFamily();

    uint32_t extensionCount = 0;
    vkEnumerateDeviceExtensionProperties(mPhysicalDev, nullptr, &extensionCount,
                                         nullptr);
    std::vector<VkExtensionProperties> availableExtensions(extensionCount);
    vkEnumerateDeviceExtensionProperties(mPhysicalDev, nullptr, &extensionCount,
                                         availableExtensions.data());

    bool presentId2Supported = false;
    bool presentWait2Supported = false;
    for (const auto& extension : availableExtensions) {
        if (strcmp(extension.extensionName,
                   VK_KHR_PRESENT_ID_2_EXTENSION_NAME) == 0) {
            presentId2Supported = true;
        }
        if (strcmp(extension.extensionName,
                   VK_KHR_PRESENT_WAIT_2_EXTENSION_NAME) == 0) {
            presentWait2Supported = true;
        }
    }

    if (!presentId2Supported || !presentWait2Supported) {
        GTEST_SKIP()
            << "VK_KHR_present_id2 or VK_KHR_present_wait2 not supported";
    }

    createDeviceAndGetQueue(deviceLayers, deviceExtensions);

    uint32_t presentModeCount = 0;
    vkGetPhysicalDeviceSurfacePresentModesKHR(mPhysicalDev, mSurface,
                                              &presentModeCount, nullptr);
    ASSERT_GT(presentModeCount, 0U);
    std::vector<VkPresentModeKHR> presentModes(presentModeCount);
    vkGetPhysicalDeviceSurfacePresentModesKHR(
        mPhysicalDev, mSurface, &presentModeCount, presentModes.data());

    bool mailboxSupported = false;
    for (const auto& mode : presentModes) {
        if (mode == VK_PRESENT_MODE_MAILBOX_KHR) {
            mailboxSupported = true;
            break;
        }
    }

    if (!mailboxSupported) {
        GTEST_SKIP() << "VK_PRESENT_MODE_MAILBOX_KHR not supported.";
    }

    VkSurfaceCapabilitiesKHR surfaceCaps{};
    VK_CHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(mPhysicalDev, mSurface,
                                                       &surfaceCaps));
    if (surfaceCaps.maxImageCount != 0 && surfaceCaps.maxImageCount < 2) {
        GTEST_SKIP() << "Swapchain doesn't support at least 2 images.";
    }
    uint32_t imageCount = std::max(2u, surfaceCaps.minImageCount);
    if (surfaceCaps.maxImageCount != 0) {
        imageCount = std::min(imageCount, surfaceCaps.maxImageCount);
    }

    VkSwapchainCreateInfoKHR swapchainInfo{};
    swapchainInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
    swapchainInfo.surface = mSurface;
    swapchainInfo.minImageCount = imageCount;
    swapchainInfo.imageFormat = VK_FORMAT_R8G8B8A8_UNORM;
    swapchainInfo.imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
    swapchainInfo.imageExtent = surfaceCaps.currentExtent;
    swapchainInfo.imageArrayLayers = 1;
    swapchainInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
    swapchainInfo.preTransform = surfaceCaps.currentTransform;
    swapchainInfo.compositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
    swapchainInfo.presentMode = VK_PRESENT_MODE_MAILBOX_KHR;
    swapchainInfo.clipped = VK_TRUE;
    swapchainInfo.flags = VK_SWAPCHAIN_CREATE_PRESENT_WAIT_2_BIT_KHR;

    VkResult res =
        vkCreateSwapchainKHR(mDevice, &swapchainInfo, nullptr, &mSwapchain);
    VK_CHECK(res);
    ASSERT_NE(mSwapchain, (VkSwapchainKHR)VK_NULL_HANDLE);

    auto pfnWaitForPresent2KHR = (PFN_vkWaitForPresent2KHR)vkGetDeviceProcAddr(
        mDevice, "vkWaitForPresent2KHR");
    ASSERT_NE(pfnWaitForPresent2KHR, (PFN_vkWaitForPresent2KHR) nullptr);

    uint32_t imageIndex1;
    res = vkAcquireNextImageKHR(mDevice, mSwapchain, UINT64_MAX, VK_NULL_HANDLE,
                                VK_NULL_HANDLE, &imageIndex1);
    VK_CHECK(res);

    uint64_t presentId1 = 1;
    VkPresentId2KHR presentIdInfo1 = {};
    presentIdInfo1.sType = VK_STRUCTURE_TYPE_PRESENT_ID_2_KHR;
    presentIdInfo1.swapchainCount = 1;
    presentIdInfo1.pPresentIds = &presentId1;

    VkPresentInfoKHR presentInfo1 = {};
    presentInfo1.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
    presentInfo1.pNext = &presentIdInfo1;
    presentInfo1.swapchainCount = 1;
    presentInfo1.pSwapchains = &mSwapchain;
    presentInfo1.pImageIndices = &imageIndex1;

    res = vkQueuePresentKHR(mPresentQueue, &presentInfo1);
    VK_CHECK(res);

    // Present with ID 2, this should replace/drop frame 1
    uint32_t imageIndex2;
    res = vkAcquireNextImageKHR(mDevice, mSwapchain, UINT64_MAX, VK_NULL_HANDLE,
                                VK_NULL_HANDLE, &imageIndex2);
    VK_CHECK(res);

    uint64_t presentId2 = 2;
    VkPresentId2KHR presentIdInfo2 = {};
    presentIdInfo2.sType = VK_STRUCTURE_TYPE_PRESENT_ID_2_KHR;
    presentIdInfo2.swapchainCount = 1;
    presentIdInfo2.pPresentIds = &presentId2;

    VkPresentInfoKHR presentInfo2 = {};
    presentInfo2.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
    presentInfo2.pNext = &presentIdInfo2;
    presentInfo2.swapchainCount = 1;
    presentInfo2.pSwapchains = &mSwapchain;
    presentInfo2.pImageIndices = &imageIndex2;

    res = vkQueuePresentKHR(mPresentQueue, &presentInfo2);
    VK_CHECK(res);

    // Present with ID 3, this should replace/drop frame 2
    uint32_t imageIndex3;
    res = vkAcquireNextImageKHR(mDevice, mSwapchain, UINT64_MAX, VK_NULL_HANDLE,
                                VK_NULL_HANDLE, &imageIndex3);
    VK_CHECK(res);

    uint64_t presentId3 = 3;
    VkPresentId2KHR presentIdInfo3 = {};
    presentIdInfo3.sType = VK_STRUCTURE_TYPE_PRESENT_ID_2_KHR;
    presentIdInfo3.swapchainCount = 1;
    presentIdInfo3.pPresentIds = &presentId3;

    VkPresentInfoKHR presentInfo3 = {};
    presentInfo3.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
    presentInfo3.pNext = &presentIdInfo3;
    presentInfo3.swapchainCount = 1;
    presentInfo3.pSwapchains = &mSwapchain;
    presentInfo3.pImageIndices = &imageIndex3;

    res = vkQueuePresentKHR(mPresentQueue, &presentInfo3);
    VK_CHECK(res);

    // Wait for present ID 2, which was dropped by present 3.
    VkPresentWait2InfoKHR presentWaitInfo2{};
    presentWaitInfo2.sType = VK_STRUCTURE_TYPE_PRESENT_WAIT_2_INFO_KHR;
    presentWaitInfo2.presentId = 2;
    presentWaitInfo2.timeout = 100000;

    res = pfnWaitForPresent2KHR(mDevice, mSwapchain, &presentWaitInfo2);
    ASSERT_EQ(res, VK_SUCCESS);

    // Wait for present ID 1, which was dropped by present 2
    VkPresentWait2InfoKHR presentWaitInfo1{};
    presentWaitInfo1.sType = VK_STRUCTURE_TYPE_PRESENT_WAIT_2_INFO_KHR;
    presentWaitInfo1.presentId = 1;
    presentWaitInfo1.timeout = 0;

    res = pfnWaitForPresent2KHR(mDevice, mSwapchain, &presentWaitInfo1);
    ASSERT_EQ(res, VK_SUCCESS);

    cleanUpSwapchainForTest();
}

TEST_F(AImageReaderVulkanSwapchainTest, TestFifoLatestReadySupport) {
    // Test if VK_PRESENT_MODE_FIFO_LATEST_READY_EXT is supported
    std::vector<const char*> instanceLayers;
    std::vector<const char*> deviceLayers;

    createVulkanInstance(instanceLayers);
    createAImageReader(640, 480, AIMAGE_FORMAT_PRIVATE, 3);
    getANativeWindowFromReader();
    createVulkanSurface();
    pickPhysicalDeviceAndQueueFamily();

    // Check if the physical device supports the extension
    uint32_t extensionCount = 0;
    vkEnumerateDeviceExtensionProperties(mPhysicalDev, nullptr, &extensionCount,
                                         nullptr);
    std::vector<VkExtensionProperties> extensions(extensionCount);
    vkEnumerateDeviceExtensionProperties(mPhysicalDev, nullptr, &extensionCount,
                                         extensions.data());

    bool extensionSupported = false;
    for (const auto& extension : extensions) {
        if (strcmp(extension.extensionName,
                   "VK_EXT_present_mode_fifo_latest_ready") == 0) {
            extensionSupported = true;
            break;
        }
    }

    LOGI("VK_EXT_present_mode_fifo_latest_ready extension supported: %s",
         extensionSupported ? "YES" : "NO");

    createDeviceAndGetQueue(deviceLayers);

    // Check if the present mode is supported
    uint32_t presentModeCount = 0;
    vkGetPhysicalDeviceSurfacePresentModesKHR(mPhysicalDev, mSurface,
                                              &presentModeCount, nullptr);
    std::vector<VkPresentModeKHR> presentModes(presentModeCount);
    vkGetPhysicalDeviceSurfacePresentModesKHR(
        mPhysicalDev, mSurface, &presentModeCount, presentModes.data());

    bool modeSupported = false;
    for (auto mode : presentModes) {
        if (mode == VK_PRESENT_MODE_FIFO_LATEST_READY_EXT) {
            modeSupported = true;
            break;
        }
    }

    LOGI(
        "VK_PRESENT_MODE_FIFO_LATEST_READY_EXT present mode supported "
        "natively: %s",
        modeSupported ? "YES" : "NO");

    cleanUpSwapchainForTest();
}

static bool HasExtension(std::vector<VkExtensionProperties> const & extensions,
        char const *extensionName)
{
    for (auto const &ext : extensions)
        if (!strcmp(ext.extensionName, extensionName))
            return true;
    return false;
}

TEST_F(AImageReaderVulkanSwapchainTest, TestKhrFeaturesCorrectlyExposed) {
    std::vector<char const *> instanceExtensions10 = {
        VK_KHR_SURFACE_EXTENSION_NAME,
        VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
        VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME,
        VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
    };

    VkInstance instance10;

    VkApplicationInfo appInfo10 = {
        VK_STRUCTURE_TYPE_APPLICATION_INFO,
        nullptr,
        nullptr,
        0,
        nullptr,
        0,
        VK_API_VERSION_1_0,
    };

    VkInstanceCreateInfo ici10 = {
        VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
        nullptr,
        0,
        &appInfo10,
        0,
        nullptr,
        static_cast<uint32_t>(instanceExtensions10.size()),
        instanceExtensions10.data()
    };
    vkCreateInstance(&ici10, nullptr, &instance10);

    ASSERT_NE(instance10, nullptr);

    uint32_t deviceCount = 0;
    vkEnumeratePhysicalDevices(instance10, &deviceCount, nullptr);
    if (!deviceCount)
        GTEST_SKIP() << "No vulkan devices";

    VkPhysicalDevice physicalDevice;
    deviceCount = 1;   // only fetch first physical device.
    vkEnumeratePhysicalDevices(instance10, &deviceCount, &physicalDevice);

    ASSERT_NE(physicalDevice, nullptr);

    uint32_t deviceExtensionCount = 0;
    vkEnumerateDeviceExtensionProperties(physicalDevice, nullptr, &deviceExtensionCount, nullptr);
    std::vector<VkExtensionProperties> deviceExtensions(deviceExtensionCount);
    vkEnumerateDeviceExtensionProperties(physicalDevice, nullptr, &deviceExtensionCount, deviceExtensions.data());

    if (!HasExtension(deviceExtensions, VK_KHR_PRESENT_ID_EXTENSION_NAME))
        GTEST_SKIP() << "Device does not offer KHR_present_id";

    // Now deliberately use the _KHR_ version of the GPDF2 function to fetch the
    // features associated with this extension.
    VkPhysicalDevicePresentIdFeaturesKHR presentIdFeatures = {
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_FEATURES_KHR,
        nullptr,
        VK_FALSE,   /* present id */
    };
    VkPhysicalDeviceFeatures2KHR features2 = {
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR,
        &presentIdFeatures,

    };

    auto gpdf2 = (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(
            instance10, "vkGetPhysicalDeviceFeatures2KHR");
    gpdf2(physicalDevice, &features2);

    // Our feature should have been populated!
    ASSERT_EQ(presentIdFeatures.presentId, VK_TRUE);
}

namespace {

struct OnAcquiredCallbackData {
    ANativeWindow_OnAcquiredCallback callback = nullptr;
    void* data = nullptr;
};

int Hook_ANativeWindow_Perform_SetCallback(ANativeWindow* window,
                                           ANativeWindow_performFn perform,
                                           void* data,
                                           int operation,
                                           va_list args) {
    if (operation == NATIVE_WINDOW_API_SET_ON_ACQUIRED_CALLBACK) {
        ALOGI("Intercepted NATIVE_WINDOW_API_SET_ON_ACQUIRED_CALLBACK");
        if (data) {
            va_list args_copy;
            va_copy(args_copy, args);
            auto* captured = static_cast<OnAcquiredCallbackData*>(data);
            captured->callback = va_arg(args_copy, ANativeWindow_OnAcquiredCallback);
            captured->data = va_arg(args_copy, void*);
            va_end(args_copy);
        }
    }

    return perform(window, operation, args);
}

TEST_F(AImageReaderVulkanSwapchainTest, SurfaceDestroyedBeforeOnAcquiredCallback) {
    // Verify that the callback from the consumer (AImageReader) doesn't cause a
    // crash if the surface has already been destroyed.
    std::vector<const char*> instanceLayers = {};
    std::vector<const char*> deviceLayers = {};
    std::vector<const char*> deviceExtensions = {
        VK_KHR_SWAPCHAIN_EXTENSION_NAME,
        VK_KHR_PRESENT_ID_2_EXTENSION_NAME,
        VK_KHR_PRESENT_WAIT_2_EXTENSION_NAME,
        VK_EXT_PRESENT_TIMING_EXTENSION_NAME,
    };
    OnAcquiredCallbackData callbackData;

    createVulkanInstance(instanceLayers);
    // Don't set listener, we will acquire manually
    createAImageReader(640, 480, AIMAGE_FORMAT_PRIVATE, 1, false);
    getANativeWindowFromReader();


    int result = mWindow->perform(
        mWindow, NATIVE_WINDOW_SET_PERFORM_INTERCEPTOR,
        Hook_ANativeWindow_Perform_SetCallback, &callbackData);
    ASSERT_EQ(result, 0);

    createVulkanSurface();
    pickPhysicalDeviceAndQueueFamily();

    uint32_t extensionCount = 0;
    vkEnumerateDeviceExtensionProperties(mPhysicalDev, nullptr, &extensionCount,
                                         nullptr);
    std::vector<VkExtensionProperties> availableExtensions(extensionCount);
    vkEnumerateDeviceExtensionProperties(mPhysicalDev, nullptr, &extensionCount,
                                         availableExtensions.data());

    bool presentId2Supported = false;
    bool presentWait2Supported = false;
    bool presentTimingSupported = false;
    for (const auto& extension : availableExtensions) {
        if (strcmp(extension.extensionName,
                   VK_KHR_PRESENT_ID_2_EXTENSION_NAME) == 0) {
            presentId2Supported = true;
        }
        if (strcmp(extension.extensionName,
                   VK_KHR_PRESENT_WAIT_2_EXTENSION_NAME) == 0) {
            presentWait2Supported = true;
        }
        if (strcmp(extension.extensionName,
                   VK_EXT_PRESENT_TIMING_EXTENSION_NAME) == 0) {
            presentTimingSupported = true;
        }
    }

    if (!presentId2Supported || !presentWait2Supported ||
        !presentTimingSupported) {
        GTEST_SKIP() << "VK_KHR_present_id2, VK_KHR_present_wait2, or "
                        "VK_EXT_present_timing not supported";
    }

    VkPhysicalDevicePresentWait2FeaturesKHR presentWait2Features = {};
    presentWait2Features.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_2_FEATURES_KHR;
    presentWait2Features.presentWait2 = VK_TRUE;

    VkPhysicalDevicePresentId2FeaturesKHR presentId2Features = {};
    presentId2Features.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_2_FEATURES_KHR;
    presentId2Features.presentId2 = VK_TRUE;
    presentId2Features.pNext = &presentWait2Features;

    VkPhysicalDevicePresentTimingFeaturesEXT presentTimingFeatures = {};
    presentTimingFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_TIMING_FEATURES_EXT;
    presentTimingFeatures.presentTiming = VK_TRUE;
    presentTimingFeatures.presentAtAbsoluteTime = VK_TRUE;
    presentTimingFeatures.pNext = &presentId2Features;

    createDeviceAndGetQueue(deviceLayers, deviceExtensions,
                            &presentTimingFeatures);

    VkSurfaceCapabilitiesKHR surfaceCaps{};
    VK_CHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(mPhysicalDev, mSurface,
                                                       &surfaceCaps));

    uint32_t imageCount = surfaceCaps.minImageCount + 1;
    if (surfaceCaps.maxImageCount > 0 &&
        imageCount > surfaceCaps.maxImageCount) {
        imageCount = surfaceCaps.maxImageCount;
    }

    VkSwapchainCreateInfoKHR swapchainInfo{};
    swapchainInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
    swapchainInfo.surface = mSurface;
    swapchainInfo.minImageCount = imageCount;
    swapchainInfo.imageFormat = VK_FORMAT_R8G8B8A8_UNORM;
    swapchainInfo.imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
    swapchainInfo.imageExtent = surfaceCaps.currentExtent;
    swapchainInfo.imageArrayLayers = 1;
    swapchainInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
    swapchainInfo.preTransform = surfaceCaps.currentTransform;
    swapchainInfo.compositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
    swapchainInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR;
    swapchainInfo.clipped = VK_TRUE;
    swapchainInfo.flags = VK_SWAPCHAIN_CREATE_PRESENT_WAIT_2_BIT_KHR;

    VkResult res =
        vkCreateSwapchainKHR(mDevice, &swapchainInfo, nullptr, &mSwapchain);
    VK_CHECK(res);
    ASSERT_NE(mSwapchain, (VkSwapchainKHR)VK_NULL_HANDLE);

    uint32_t imageIndex;
    res = vkAcquireNextImageKHR(mDevice, mSwapchain, UINT64_MAX, VK_NULL_HANDLE,
                                VK_NULL_HANDLE, &imageIndex);
    VK_CHECK(res);

    uint64_t presentId = 1;
    VkPresentId2KHR presentIdInfo = {};
    presentIdInfo.sType = VK_STRUCTURE_TYPE_PRESENT_ID_2_KHR;
    presentIdInfo.swapchainCount = 1;
    presentIdInfo.pPresentIds = &presentId;

    VkPresentInfoKHR presentInfo = {};
    presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
    presentInfo.pNext = &presentIdInfo;
    presentInfo.swapchainCount = 1;
    presentInfo.pSwapchains = &mSwapchain;
    presentInfo.pImageIndices = &imageIndex;

    res = vkQueuePresentKHR(mPresentQueue, &presentInfo);
    VK_CHECK(res);

    // Destroy the swapchain and surface immediately after present
    vkDestroySwapchainKHR(mDevice, mSwapchain, nullptr);
    mSwapchain = VK_NULL_HANDLE;
    vkDestroySurfaceKHR(mVkInstance, mSurface, nullptr);
    mSurface = VK_NULL_HANDLE;

    // Trigger the callback manually (AImageReader acquire).
    // This used to crash if the surface was already destroyed.
    callbackData.callback(0 /*bufferId*/, 0 /*frameId*/, callbackData.data);
    cleanUpSwapchainForTest();
}

}  // namespace

namespace {

int Hook_ANativeWindow_Perform_ErrorTimestamps(ANativeWindow* window,
                                               ANativeWindow_performFn perform,
                                               void*,
                                               int operation,
                                               va_list args) {
    if (operation == NATIVE_WINDOW_GET_FRAME_TIMESTAMPS) {
        return -EINVAL;
    }
    return perform(window, operation, args);
}

int Hook_ANativeWindow_Perform_SuccessTimestamps_NonZero(
    ANativeWindow* window,
    ANativeWindow_performFn perform,
    void*,
    int operation,
    va_list args) {
    if (operation == NATIVE_WINDOW_GET_FRAME_TIMESTAMPS) {
        uint64_t frameId = va_arg(args, uint64_t);
        int64_t* outRequestedPresentTime = va_arg(args, int64_t*);
        int64_t* outAcquireTime = va_arg(args, int64_t*);
        int64_t* outLatchTime = va_arg(args, int64_t*);
        int64_t* outFirstRefreshStartTime = va_arg(args, int64_t*);
        int64_t* outLastRefreshStartTime = va_arg(args, int64_t*);
        int64_t* outGpuCompositionDoneTime = va_arg(args, int64_t*);
        int64_t* outDisplayPresentTime = va_arg(args, int64_t*);
        int64_t* outDequeueReadyTime = va_arg(args, int64_t*);
        int64_t* outReleaseTime = va_arg(args, int64_t*);

        if (outRequestedPresentTime)
            *outRequestedPresentTime = 12345;
        if (outAcquireTime)
            *outAcquireTime = 12345;
        if (outLatchTime)
            *outLatchTime = 12345;
        if (outFirstRefreshStartTime)
            *outFirstRefreshStartTime = 12345;
        if (outLastRefreshStartTime)
            *outLastRefreshStartTime = 12345;
        if (outGpuCompositionDoneTime)
            *outGpuCompositionDoneTime = 12345;
        if (outDisplayPresentTime)
            *outDisplayPresentTime = 12345;
        if (outDequeueReadyTime)
            *outDequeueReadyTime = 12345;
        if (outReleaseTime)
            *outReleaseTime = 12345;

        return 0;
    }

    return perform(window, operation, args);
}

TEST_F(AImageReaderVulkanSwapchainTest, ExtPresentTimingErrorTimestamps) {
    // verify we return 0 timestamps when NATIVE_WINDOW_GET_FRAME_TIMESTAMPS
    // returns an error.
    std::vector<const char*> instanceLayers = {};
    std::vector<const char*> deviceLayers = {};
    std::vector<const char*> deviceExtensions = {
        VK_EXT_PRESENT_TIMING_EXTENSION_NAME,
    };

    createVulkanInstance(instanceLayers);
    createAImageReader(640, 480, AIMAGE_FORMAT_PRIVATE, 3);
    getANativeWindowFromReader();
    createVulkanSurface();
    pickPhysicalDeviceAndQueueFamily();

    // Check if the required display timing extension is supported by the device
    uint32_t extensionCount = 0;
    vkEnumerateDeviceExtensionProperties(mPhysicalDev, nullptr, &extensionCount,
                                         nullptr);
    std::vector<VkExtensionProperties> availableExtensions(extensionCount);
    vkEnumerateDeviceExtensionProperties(mPhysicalDev, nullptr, &extensionCount,
                                         availableExtensions.data());

    bool timingExtSupported = false;
    for (const auto& extension : availableExtensions) {
        if (strcmp(extension.extensionName,
                   VK_EXT_PRESENT_TIMING_EXTENSION_NAME) == 0) {
            timingExtSupported = true;
            break;
        }
    }

    if (!timingExtSupported) {
        GTEST_SKIP() << "Vulkan extension "
                     << VK_EXT_PRESENT_TIMING_EXTENSION_NAME
                     << " not supported.";
    }

    VkPhysicalDevicePresentTimingFeaturesEXT presentTimingFeatures = {};
    presentTimingFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_TIMING_FEATURES_EXT;
    presentTimingFeatures.presentTiming = VK_TRUE;

    createDeviceAndGetQueue(deviceLayers, deviceExtensions,
                            &presentTimingFeatures);

    VkSurfaceCapabilitiesKHR surfaceCaps{};
    VK_CHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(mPhysicalDev, mSurface,
                                                       &surfaceCaps));

    uint32_t imageCount = surfaceCaps.minImageCount + 1;
    if (surfaceCaps.maxImageCount > 0 &&
        imageCount > surfaceCaps.maxImageCount) {
        imageCount = surfaceCaps.maxImageCount;
    }

    VkSwapchainCreateInfoKHR swapchainInfo{};
    swapchainInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
    swapchainInfo.surface = mSurface;
    swapchainInfo.minImageCount = imageCount;
    swapchainInfo.imageFormat = VK_FORMAT_R8G8B8A8_UNORM;
    swapchainInfo.imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
    swapchainInfo.imageExtent = surfaceCaps.currentExtent;
    swapchainInfo.imageArrayLayers = 1;
    swapchainInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
    swapchainInfo.preTransform = surfaceCaps.currentTransform;
    swapchainInfo.compositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
    swapchainInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR;
    swapchainInfo.clipped = VK_TRUE;

    // Set error interceptor
    int result = mWindow->perform(
        mWindow, NATIVE_WINDOW_SET_PERFORM_INTERCEPTOR,
        Hook_ANativeWindow_Perform_ErrorTimestamps, nullptr /* data */);
    ASSERT_EQ(result, 0);

    // Create Swapchain 1
    VkSwapchainKHR swapchain1 = VK_NULL_HANDLE;
    VkResult res =
        vkCreateSwapchainKHR(mDevice, &swapchainInfo, nullptr, &swapchain1);
    VK_CHECK(res);

    uint32_t imageIndex;
    res = vkAcquireNextImageKHR(mDevice, swapchain1, UINT64_MAX, VK_NULL_HANDLE,
                                VK_NULL_HANDLE, &imageIndex);
    VK_CHECK(res);

    VkPresentTimingInfoEXT presentTimingInfo = {};
    presentTimingInfo.presentStageQueries =
        VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_OUT_BIT_EXT;
    presentTimingInfo.targetTime = 0;

    VkPresentTimingsInfoEXT presentTimingsInfo = {};
    presentTimingsInfo.sType = VK_STRUCTURE_TYPE_PRESENT_TIMINGS_INFO_EXT;
    presentTimingsInfo.swapchainCount = 1;
    presentTimingsInfo.pTimingInfos = &presentTimingInfo;

    VkPresentInfoKHR presentInfo = {};
    presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
    presentInfo.pNext = &presentTimingsInfo;
    presentInfo.swapchainCount = 1;
    presentInfo.pSwapchains = &swapchain1;
    presentInfo.pImageIndices = &imageIndex;

    res = vkQueuePresentKHR(mPresentQueue, &presentInfo);
    VK_CHECK(res);

    auto pfnGetPastPresentationTimingEXT =
        (PFN_vkGetPastPresentationTimingEXT)vkGetDeviceProcAddr(
            mDevice, "vkGetPastPresentationTimingEXT");
    ASSERT_NE(pfnGetPastPresentationTimingEXT,
              (PFN_vkGetPastPresentationTimingEXT) nullptr);

    // Query timing on Swapchain 1
    VkPastPresentationTimingInfoEXT pastTimingInfo1 = {};
    pastTimingInfo1.sType = VK_STRUCTURE_TYPE_PAST_PRESENTATION_TIMING_INFO_EXT;
    pastTimingInfo1.swapchain = swapchain1;

    VkPastPresentationTimingPropertiesEXT pastTimingProps1 = {};
    pastTimingProps1.sType =
        VK_STRUCTURE_TYPE_PAST_PRESENTATION_TIMING_PROPERTIES_EXT;

    // First call to get count
    res = pfnGetPastPresentationTimingEXT(mDevice, &pastTimingInfo1,
                                          &pastTimingProps1);
    VK_CHECK(res);
    ASSERT_EQ(pastTimingProps1.presentationTimingCount, 1U);

    std::vector<VkPastPresentationTimingEXT> pastTimings1(1);
    std::vector<VkPresentStageTimeEXT> stages1(1);
    pastTimings1[0].sType = VK_STRUCTURE_TYPE_PAST_PRESENTATION_TIMING_EXT;
    pastTimings1[0].pPresentStages = stages1.data();
    pastTimingProps1.pPresentationTimings = pastTimings1.data();

    res = pfnGetPastPresentationTimingEXT(mDevice, &pastTimingInfo1,
                                          &pastTimingProps1);
    VK_CHECK(res);

    // Verify timestamps are 0 since interceptor returned error
    EXPECT_EQ(pastTimings1[0].presentStageCount, 1U);
    EXPECT_EQ(stages1[0].time, 0U);

    mSwapchain = swapchain1;
    cleanUpSwapchainForTest();
}

TEST_F(AImageReaderVulkanSwapchainTest,
       ExtPresentTimingSuccessTimestampsRetiredSwapchain) {
    // verify we return 0 timestamps when it returns success (with non-zero
    // values) but the swapchain is retired.
    std::vector<const char*> instanceLayers = {};
    std::vector<const char*> deviceLayers = {};
    std::vector<const char*> deviceExtensions = {
        VK_EXT_PRESENT_TIMING_EXTENSION_NAME,
    };

    createVulkanInstance(instanceLayers);
    createAImageReader(640, 480, AIMAGE_FORMAT_PRIVATE, 3);
    getANativeWindowFromReader();
    createVulkanSurface();
    pickPhysicalDeviceAndQueueFamily();

    // Check if the required display timing extension is supported by the device
    uint32_t extensionCount = 0;
    vkEnumerateDeviceExtensionProperties(mPhysicalDev, nullptr, &extensionCount,
                                         nullptr);
    std::vector<VkExtensionProperties> availableExtensions(extensionCount);
    vkEnumerateDeviceExtensionProperties(mPhysicalDev, nullptr, &extensionCount,
                                         availableExtensions.data());

    bool timingExtSupported = false;
    for (const auto& extension : availableExtensions) {
        if (strcmp(extension.extensionName,
                   VK_EXT_PRESENT_TIMING_EXTENSION_NAME) == 0) {
            timingExtSupported = true;
            break;
        }
    }

    if (!timingExtSupported) {
        GTEST_SKIP() << "Vulkan extension "
                     << VK_EXT_PRESENT_TIMING_EXTENSION_NAME
                     << " not supported.";
    }

    VkPhysicalDevicePresentTimingFeaturesEXT presentTimingFeatures = {};
    presentTimingFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_TIMING_FEATURES_EXT;
    presentTimingFeatures.presentTiming = VK_TRUE;

    createDeviceAndGetQueue(deviceLayers, deviceExtensions,
                            &presentTimingFeatures);

    VkSurfaceCapabilitiesKHR surfaceCaps{};
    VK_CHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(mPhysicalDev, mSurface,
                                                       &surfaceCaps));

    uint32_t imageCount = surfaceCaps.minImageCount + 1;
    if (surfaceCaps.maxImageCount > 0 &&
        imageCount > surfaceCaps.maxImageCount) {
        imageCount = surfaceCaps.maxImageCount;
    }

    VkSwapchainCreateInfoKHR swapchainInfo{};
    swapchainInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
    swapchainInfo.surface = mSurface;
    swapchainInfo.minImageCount = imageCount;
    swapchainInfo.imageFormat = VK_FORMAT_R8G8B8A8_UNORM;
    swapchainInfo.imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
    swapchainInfo.imageExtent = surfaceCaps.currentExtent;
    swapchainInfo.imageArrayLayers = 1;
    swapchainInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
    swapchainInfo.preTransform = surfaceCaps.currentTransform;
    swapchainInfo.compositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
    swapchainInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR;
    swapchainInfo.clipped = VK_TRUE;

    // Set success interceptor
    int result =
        mWindow->perform(mWindow, NATIVE_WINDOW_SET_PERFORM_INTERCEPTOR,
                         Hook_ANativeWindow_Perform_SuccessTimestamps_NonZero,
                         nullptr /* data */);
    ASSERT_EQ(result, 0);

    // Create Swapchain 1
    VkSwapchainKHR swapchain1 = VK_NULL_HANDLE;
    VkResult res =
        vkCreateSwapchainKHR(mDevice, &swapchainInfo, nullptr, &swapchain1);
    VK_CHECK(res);

    uint32_t imageIndex;
    res = vkAcquireNextImageKHR(mDevice, swapchain1, UINT64_MAX, VK_NULL_HANDLE,
                                VK_NULL_HANDLE, &imageIndex);
    VK_CHECK(res);

    VkPresentTimingInfoEXT presentTimingInfo = {};
    presentTimingInfo.presentStageQueries =
        VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_OUT_BIT_EXT;
    presentTimingInfo.targetTime = 0;

    VkPresentTimingsInfoEXT presentTimingsInfo = {};
    presentTimingsInfo.sType = VK_STRUCTURE_TYPE_PRESENT_TIMINGS_INFO_EXT;
    presentTimingsInfo.swapchainCount = 1;
    presentTimingsInfo.pTimingInfos = &presentTimingInfo;

    VkPresentInfoKHR presentInfo = {};
    presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
    presentInfo.pNext = &presentTimingsInfo;
    presentInfo.swapchainCount = 1;
    presentInfo.pSwapchains = &swapchain1;
    presentInfo.pImageIndices = &imageIndex;

    res = vkQueuePresentKHR(mPresentQueue, &presentInfo);
    VK_CHECK(res);

    // Retire Swapchain 1 with Swapchain 2
    VkSwapchainKHR swapchain2 = VK_NULL_HANDLE;
    swapchainInfo.oldSwapchain = swapchain1;
    res = vkCreateSwapchainKHR(mDevice, &swapchainInfo, nullptr, &swapchain2);
    VK_CHECK(res);

    auto pfnGetPastPresentationTimingEXT =
        (PFN_vkGetPastPresentationTimingEXT)vkGetDeviceProcAddr(
            mDevice, "vkGetPastPresentationTimingEXT");
    ASSERT_NE(pfnGetPastPresentationTimingEXT,
              (PFN_vkGetPastPresentationTimingEXT) nullptr);

    // Query timing on Swapchain 1 (it is retired, interceptor returns 12345, so
    // should be forced to 0)
    VkPastPresentationTimingInfoEXT pastTimingInfo1 = {};
    pastTimingInfo1.sType = VK_STRUCTURE_TYPE_PAST_PRESENTATION_TIMING_INFO_EXT;
    pastTimingInfo1.swapchain = swapchain1;

    VkPastPresentationTimingPropertiesEXT pastTimingProps1 = {};
    pastTimingProps1.sType =
        VK_STRUCTURE_TYPE_PAST_PRESENTATION_TIMING_PROPERTIES_EXT;

    res = pfnGetPastPresentationTimingEXT(mDevice, &pastTimingInfo1,
                                          &pastTimingProps1);
    VK_CHECK(res);
    ASSERT_EQ(pastTimingProps1.presentationTimingCount, 1U);

    std::vector<VkPastPresentationTimingEXT> pastTimings1(1);
    std::vector<VkPresentStageTimeEXT> stages1(1);
    pastTimings1[0].sType = VK_STRUCTURE_TYPE_PAST_PRESENTATION_TIMING_EXT;
    pastTimings1[0].pPresentStages = stages1.data();
    pastTimingProps1.pPresentationTimings = pastTimings1.data();

    res = pfnGetPastPresentationTimingEXT(mDevice, &pastTimingInfo1,
                                          &pastTimingProps1);
    VK_CHECK(res);

    EXPECT_EQ(pastTimings1[0].presentStageCount, 1U);
    EXPECT_EQ(stages1[0].time, 0U);

    // Clean up
    vkDestroySwapchainKHR(mDevice, swapchain1, nullptr);
    mSwapchain = swapchain2;

    cleanUpSwapchainForTest();
}

}  // namespace

TEST_F(AImageReaderVulkanSwapchainTest,
       GetPastPresentationTimingEXT_IncompleteQueryTest) {
    // verify that returning VK_INCOMPLETE does not erase all ready timings
    std::vector<const char*> instanceLayers = {};
    std::vector<const char*> deviceLayers = {};
    std::vector<const char*> deviceExtensions = {
        VK_KHR_SWAPCHAIN_EXTENSION_NAME,
        VK_EXT_PRESENT_TIMING_EXTENSION_NAME,
        VK_KHR_PRESENT_ID_2_EXTENSION_NAME,
    };

    createVulkanInstance(instanceLayers);
    createAImageReader(640, 480, AIMAGE_FORMAT_PRIVATE, 4);
    getANativeWindowFromReader();

    int result = mWindow->perform(
        mWindow, NATIVE_WINDOW_SET_PERFORM_INTERCEPTOR,
        Hook_ANativeWindow_Perform_FakeTimestamps, nullptr /* data */);
    ASSERT_EQ(result, 0);

    createVulkanSurface();
    pickPhysicalDeviceAndQueueFamily();

    uint32_t extensionCount = 0;
    vkEnumerateDeviceExtensionProperties(mPhysicalDev, nullptr, &extensionCount,
                                         nullptr);
    std::vector<VkExtensionProperties> availableExtensions(extensionCount);
    vkEnumerateDeviceExtensionProperties(mPhysicalDev, nullptr, &extensionCount,
                                         availableExtensions.data());

    VkPhysicalDevicePresentId2FeaturesKHR presentId2Features = {};
    presentId2Features.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_2_FEATURES_KHR;
    presentId2Features.presentId2 = VK_TRUE;
    presentId2Features.pNext = nullptr;

    VkPhysicalDevicePresentTimingFeaturesEXT presentTimingFeatures = {};
    presentTimingFeatures.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_TIMING_FEATURES_EXT;
    presentTimingFeatures.presentTiming = VK_TRUE;
    presentTimingFeatures.presentAtAbsoluteTime = VK_TRUE;
    presentTimingFeatures.pNext = &presentId2Features;

    createDeviceAndGetQueue(deviceLayers, deviceExtensions,
                            &presentTimingFeatures);

    VkSurfaceCapabilitiesKHR surfaceCaps{};
    VK_CHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(mPhysicalDev, mSurface,
                                                       &surfaceCaps));

    uint32_t imageCount = surfaceCaps.minImageCount + 1;
    if (surfaceCaps.maxImageCount > 0 &&
        imageCount > surfaceCaps.maxImageCount) {
        imageCount = surfaceCaps.maxImageCount;
    }

    VkSwapchainCreateInfoKHR swapchainInfo{};
    swapchainInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
    swapchainInfo.surface = mSurface;
    swapchainInfo.minImageCount = imageCount;
    swapchainInfo.imageFormat = VK_FORMAT_R8G8B8A8_UNORM;
    swapchainInfo.imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
    swapchainInfo.imageExtent = surfaceCaps.currentExtent;
    swapchainInfo.imageArrayLayers = 1;
    swapchainInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
    swapchainInfo.preTransform = surfaceCaps.currentTransform;
    swapchainInfo.compositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
    swapchainInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR;
    swapchainInfo.clipped = VK_TRUE;

    VkResult res =
        vkCreateSwapchainKHR(mDevice, &swapchainInfo, nullptr, &mSwapchain);
    VK_CHECK(res);
    ASSERT_NE(mSwapchain, (VkSwapchainKHR)VK_NULL_HANDLE);

    typedef VkResult(VKAPI_PTR * PFN_vkGetPastPresentationTimingEXT_Local)(
        VkDevice, const VkPastPresentationTimingInfoEXT*,
        VkPastPresentationTimingPropertiesEXT*);
    auto pfnGetPastPresentationTimingEXT =
        reinterpret_cast<PFN_vkGetPastPresentationTimingEXT_Local>(
            vkGetDeviceProcAddr(mDevice, "vkGetPastPresentationTimingEXT"));
    ASSERT_NE(pfnGetPastPresentationTimingEXT, nullptr);

    // Queue 2 presents
    for (uint64_t i = 1; i <= 2; ++i) {
        uint32_t imageIndex;
        res =
            vkAcquireNextImageKHR(mDevice, mSwapchain, UINT64_MAX,
                                  VK_NULL_HANDLE, VK_NULL_HANDLE, &imageIndex);
        VK_CHECK(res);

        VkPresentTimingInfoEXT presentTimingInfo = {};
        presentTimingInfo.presentStageQueries =
            VK_PRESENT_STAGE_QUEUE_OPERATIONS_END_BIT_EXT |
            VK_PRESENT_STAGE_REQUEST_DEQUEUED_BIT_EXT;
        presentTimingInfo.targetTime = 1000 * i;

        VkPresentTimingsInfoEXT presentTimingsInfo = {};
        presentTimingsInfo.sType = VK_STRUCTURE_TYPE_PRESENT_TIMINGS_INFO_EXT;
        presentTimingsInfo.swapchainCount = 1;
        presentTimingsInfo.pTimingInfos = &presentTimingInfo;

        VkPresentId2KHR presentIdInfo = {};
        presentIdInfo.sType = VK_STRUCTURE_TYPE_PRESENT_ID_2_KHR;
        presentIdInfo.swapchainCount = 1;
        presentIdInfo.pPresentIds = &i;
        presentIdInfo.pNext = &presentTimingsInfo;

        VkPresentInfoKHR presentInfo = {};
        presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
        presentInfo.pNext = &presentIdInfo;
        presentInfo.swapchainCount = 1;
        presentInfo.pSwapchains = &mSwapchain;
        presentInfo.pImageIndices = &imageIndex;

        res = vkQueuePresentKHR(mPresentQueue, &presentInfo);
        VK_CHECK(res);
    }

    // Now query with count = 1
    VkPastPresentationTimingInfoEXT pastInfo = {};
    pastInfo.sType = VK_STRUCTURE_TYPE_PAST_PRESENTATION_TIMING_INFO_EXT;
    pastInfo.swapchain = mSwapchain;

    VkPastPresentationTimingPropertiesEXT pastProps = {};
    pastProps.sType = VK_STRUCTURE_TYPE_PAST_PRESENTATION_TIMING_PROPERTIES_EXT;

    // First query just the count
    res = pfnGetPastPresentationTimingEXT(mDevice, &pastInfo, &pastProps);
    VK_CHECK(res);
    ASSERT_EQ(pastProps.presentationTimingCount, 2);

    // Now query with 1 element array
    VkPastPresentationTimingEXT timing1[1] = {};
    timing1[0].sType = VK_STRUCTURE_TYPE_PAST_PRESENTATION_TIMING_EXT;

    VkPresentStageTimeEXT stages1[2] = {};
    timing1[0].pPresentStages = stages1;

    pastProps.presentationTimingCount = 1;
    pastProps.pPresentationTimings = timing1;

    res = pfnGetPastPresentationTimingEXT(mDevice, &pastInfo, &pastProps);
    ASSERT_EQ(res, VK_INCOMPLETE);
    ASSERT_EQ(pastProps.presentationTimingCount, 1);
    EXPECT_EQ(timing1[0].presentId, 1);

    // Query remaining elements
    pastProps.pPresentationTimings = nullptr;
    res = pfnGetPastPresentationTimingEXT(mDevice, &pastInfo, &pastProps);
    VK_CHECK(res);
    ASSERT_EQ(pastProps.presentationTimingCount, 1);

    VkPastPresentationTimingEXT timing2[1] = {};
    timing2[0].sType = VK_STRUCTURE_TYPE_PAST_PRESENTATION_TIMING_EXT;

    VkPresentStageTimeEXT stages2[2] = {};
    timing2[0].pPresentStages = stages2;

    pastProps.presentationTimingCount = 1;
    pastProps.pPresentationTimings = timing2;

    res = pfnGetPastPresentationTimingEXT(mDevice, &pastInfo, &pastProps);
    VK_CHECK(res);
    ASSERT_EQ(pastProps.presentationTimingCount, 1);
    EXPECT_EQ(timing2[0].presentId, 2);

    cleanUpSwapchainForTest();
}

}  // namespace libvulkantest

}  // namespace android
