// Copyright 2018 The Dawn Authors
//
// 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 "dawn_native/vulkan/NativeSwapChainImplVk.h"

#include "dawn_native/vulkan/DeviceVk.h"
#include "dawn_native/vulkan/FencedDeleter.h"
#include "dawn_native/vulkan/TextureVk.h"

#include <limits>

namespace dawn_native::vulkan {

    namespace {

        bool chooseSwapPresentMode(const std::vector<VkPresentModeKHR>& availablePresentModes,
                                   bool turnOffVsync,
                                   VkPresentModeKHR* presentMode) {
            if (turnOffVsync) {
                for (const auto& availablePresentMode : availablePresentModes) {
                    if (availablePresentMode == VK_PRESENT_MODE_IMMEDIATE_KHR) {
                        *presentMode = availablePresentMode;
                        return true;
                    }
                }
                return false;
            }

            *presentMode = VK_PRESENT_MODE_FIFO_KHR;
            return true;
        }

        bool ChooseSurfaceConfig(const VulkanSurfaceInfo& info,
                                 NativeSwapChainImpl::ChosenConfig* config,
                                 bool turnOffVsync) {
            VkPresentModeKHR presentMode;
            if (!chooseSwapPresentMode(info.presentModes, turnOffVsync, &presentMode)) {
                return false;
            }
            // TODO(crbug.com/dawn/269): For now this is hardcoded to what works with one NVIDIA
            // driver. Need to generalize
            config->nativeFormat = VK_FORMAT_B8G8R8A8_UNORM;
            config->colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
            config->format = wgpu::TextureFormat::BGRA8Unorm;
            config->minImageCount = 3;
            // TODO(crbug.com/dawn/269): This is upside down compared to what we want, at least
            // on Linux
            config->preTransform = info.capabilities.currentTransform;
            config->presentMode = presentMode;
            config->compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;

            return true;
        }
    }  // anonymous namespace

    NativeSwapChainImpl::NativeSwapChainImpl(Device* device, VkSurfaceKHR surface)
        : mSurface(surface), mDevice(device) {
        // Call this immediately, so that BackendBinding::GetPreferredSwapChainTextureFormat
        // will return a correct result before a SwapChain is created.
        UpdateSurfaceConfig();
    }

    NativeSwapChainImpl::~NativeSwapChainImpl() {
        if (mSwapChain != VK_NULL_HANDLE) {
            mDevice->GetFencedDeleter()->DeleteWhenUnused(mSwapChain);
            mSwapChain = VK_NULL_HANDLE;
        }
        if (mSurface != VK_NULL_HANDLE) {
            mDevice->GetFencedDeleter()->DeleteWhenUnused(mSurface);
            mSurface = VK_NULL_HANDLE;
        }
    }

    void NativeSwapChainImpl::UpdateSurfaceConfig() {
        if (mDevice->ConsumedError(GatherSurfaceInfo(*ToBackend(mDevice->GetAdapter()), mSurface),
                                   &mInfo)) {
            ASSERT(false);
        }

        if (!ChooseSurfaceConfig(mInfo, &mConfig, mDevice->IsToggleEnabled(Toggle::TurnOffVsync))) {
            ASSERT(false);
        }
    }

    void NativeSwapChainImpl::Init(DawnWSIContextVulkan* /*context*/) {
        UpdateSurfaceConfig();
    }

    DawnSwapChainError NativeSwapChainImpl::Configure(WGPUTextureFormat format,
                                                      WGPUTextureUsage usage,
                                                      uint32_t width,
                                                      uint32_t height) {
        UpdateSurfaceConfig();

        ASSERT(mInfo.capabilities.minImageExtent.width <= width);
        ASSERT(mInfo.capabilities.maxImageExtent.width >= width);
        ASSERT(mInfo.capabilities.minImageExtent.height <= height);
        ASSERT(mInfo.capabilities.maxImageExtent.height >= height);

        ASSERT(format == static_cast<WGPUTextureFormat>(GetPreferredFormat()));
        // TODO(crbug.com/dawn/269): need to check usage works too

        // Create the swapchain with the configuration we chose
        VkSwapchainKHR oldSwapchain = mSwapChain;
        VkSwapchainCreateInfoKHR createInfo;
        createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
        createInfo.pNext = nullptr;
        createInfo.flags = 0;
        createInfo.surface = mSurface;
        createInfo.minImageCount = mConfig.minImageCount;
        createInfo.imageFormat = mConfig.nativeFormat;
        createInfo.imageColorSpace = mConfig.colorSpace;
        createInfo.imageExtent.width = width;
        createInfo.imageExtent.height = height;
        createInfo.imageArrayLayers = 1;
        createInfo.imageUsage = VulkanImageUsage(static_cast<wgpu::TextureUsage>(usage),
                                                 mDevice->GetValidInternalFormat(mConfig.format));
        createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
        createInfo.queueFamilyIndexCount = 0;
        createInfo.pQueueFamilyIndices = nullptr;
        createInfo.preTransform = mConfig.preTransform;
        createInfo.compositeAlpha = mConfig.compositeAlpha;
        createInfo.presentMode = mConfig.presentMode;
        createInfo.clipped = false;
        createInfo.oldSwapchain = oldSwapchain;

        if (mDevice->fn.CreateSwapchainKHR(mDevice->GetVkDevice(), &createInfo, nullptr,
                                           &*mSwapChain) != VK_SUCCESS) {
            ASSERT(false);
        }

        // Gather the swapchain's images. Implementations are allowed to return more images than the
        // number we asked for.
        uint32_t count = 0;
        if (mDevice->fn.GetSwapchainImagesKHR(mDevice->GetVkDevice(), mSwapChain, &count,
                                              nullptr) != VK_SUCCESS) {
            ASSERT(false);
        }

        ASSERT(count >= mConfig.minImageCount);
        mSwapChainImages.resize(count);
        if (mDevice->fn.GetSwapchainImagesKHR(mDevice->GetVkDevice(), mSwapChain, &count,
                                              AsVkArray(mSwapChainImages.data())) != VK_SUCCESS) {
            ASSERT(false);
        }

        if (oldSwapchain != VK_NULL_HANDLE) {
            mDevice->GetFencedDeleter()->DeleteWhenUnused(oldSwapchain);
        }

        return DAWN_SWAP_CHAIN_NO_ERROR;
    }

    DawnSwapChainError NativeSwapChainImpl::GetNextTexture(DawnSwapChainNextTexture* nextTexture) {
        // Transiently create a semaphore that will be signaled when the presentation engine is done
        // with the swapchain image. Further operations on the image will wait for this semaphore.
        VkSemaphore semaphore = VK_NULL_HANDLE;
        {
            VkSemaphoreCreateInfo createInfo;
            createInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
            createInfo.pNext = nullptr;
            createInfo.flags = 0;
            if (mDevice->fn.CreateSemaphore(mDevice->GetVkDevice(), &createInfo, nullptr,
                                            &*semaphore) != VK_SUCCESS) {
                ASSERT(false);
            }
        }

        if (mDevice->fn.AcquireNextImageKHR(mDevice->GetVkDevice(), mSwapChain,
                                            std::numeric_limits<uint64_t>::max(), semaphore,
                                            VkFence{}, &mLastImageIndex) != VK_SUCCESS) {
            ASSERT(false);
        }

        nextTexture->texture.u64 =
#if defined(DAWN_PLATFORM_64_BIT)
            reinterpret_cast<uint64_t>
#endif
            (*mSwapChainImages[mLastImageIndex]);
        mDevice->GetPendingRecordingContext()->waitSemaphores.push_back(semaphore);

        return DAWN_SWAP_CHAIN_NO_ERROR;
    }

    DawnSwapChainError NativeSwapChainImpl::Present() {
        // This assumes that the image has already been transitioned to the PRESENT layout and
        // writes were made available to the stage.

        // Assuming that the present queue is the same as the graphics queue, the proper
        // synchronization has already been done on the queue so we don't need to wait on any
        // semaphores.
        VkPresentInfoKHR presentInfo;
        presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
        presentInfo.pNext = nullptr;
        presentInfo.waitSemaphoreCount = 0;
        presentInfo.pWaitSemaphores = nullptr;
        presentInfo.swapchainCount = 1;
        presentInfo.pSwapchains = &*mSwapChain;
        presentInfo.pImageIndices = &mLastImageIndex;
        presentInfo.pResults = nullptr;

        VkQueue queue = mDevice->GetQueue();
        if (mDevice->fn.QueuePresentKHR(queue, &presentInfo) != VK_SUCCESS) {
            ASSERT(false);
        }

        return DAWN_SWAP_CHAIN_NO_ERROR;
    }

    wgpu::TextureFormat NativeSwapChainImpl::GetPreferredFormat() const {
        return mConfig.format;
    }

}  // namespace dawn_native::vulkan
