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

#ifndef DAWNNATIVE_VULKAN_SWAPCHAINVK_H_
#define DAWNNATIVE_VULKAN_SWAPCHAINVK_H_

#include "dawn_native/SwapChain.h"

#include "common/vulkan_platform.h"

#include <vector>

namespace dawn::native::vulkan {

    class Device;
    class Texture;
    struct VulkanSurfaceInfo;

    class OldSwapChain : public OldSwapChainBase {
      public:
        static Ref<OldSwapChain> Create(Device* device, const SwapChainDescriptor* descriptor);

      protected:
        OldSwapChain(Device* device, const SwapChainDescriptor* descriptor);
        ~OldSwapChain() override;

        TextureBase* GetNextTextureImpl(const TextureDescriptor* descriptor) override;
        MaybeError OnBeforePresent(TextureViewBase* texture) override;

      private:
        wgpu::TextureUsage mTextureUsage;
    };

    class SwapChain : public NewSwapChainBase {
      public:
        static ResultOrError<Ref<SwapChain>> Create(Device* device,
                                                    Surface* surface,
                                                    NewSwapChainBase* previousSwapChain,
                                                    const SwapChainDescriptor* descriptor);
        ~SwapChain() override;

      private:
        using NewSwapChainBase::NewSwapChainBase;
        MaybeError Initialize(NewSwapChainBase* previousSwapChain);
        void DestroyImpl() override;

        struct Config {
            // Information that's passed to vulkan swapchain creation.
            VkPresentModeKHR presentMode;
            VkExtent2D extent;
            VkImageUsageFlags usage;
            VkFormat format;
            VkColorSpaceKHR colorSpace;
            uint32_t targetImageCount;
            VkSurfaceTransformFlagBitsKHR transform;
            VkCompositeAlphaFlagBitsKHR alphaMode;

            // Redundant information but as WebGPU enums to create the wgpu::Texture that
            // encapsulates the native swapchain texture.
            wgpu::TextureUsage wgpuUsage;
            wgpu::TextureFormat wgpuFormat;

            // Information about the blit workarounds we need to do (if any)
            bool needsBlit = false;
        };
        ResultOrError<Config> ChooseConfig(const VulkanSurfaceInfo& surfaceInfo) const;
        ResultOrError<TextureViewBase*> GetCurrentTextureViewInternal(bool isReentrant = false);

        // NewSwapChainBase implementation
        MaybeError PresentImpl() override;
        ResultOrError<TextureViewBase*> GetCurrentTextureViewImpl() override;
        void DetachFromSurfaceImpl() override;

        Config mConfig;

        VkSurfaceKHR mVkSurface = VK_NULL_HANDLE;
        VkSwapchainKHR mSwapChain = VK_NULL_HANDLE;
        std::vector<VkImage> mSwapChainImages;
        uint32_t mLastImageIndex = 0;

        Ref<Texture> mBlitTexture;
        Ref<Texture> mTexture;
    };

}  // namespace dawn::native::vulkan

#endif  // DAWNNATIVE_VULKAN_SWAPCHAINVK_H_
