// Copyright 2017 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_D3D12_SWAPCHAIND3D12_H_
#define DAWNNATIVE_D3D12_SWAPCHAIND3D12_H_

#include "dawn/native/SwapChain.h"

#include "dawn/native/IntegerTypes.h"
#include "dawn/native/d3d12/d3d12_platform.h"

namespace dawn::native::d3d12 {

    class Device;
    class Texture;

    class OldSwapChain final : 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* view) override;

        wgpu::TextureUsage mTextureUsage;
    };

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

      private:
        ~SwapChain() override;

        void DestroyImpl() override;

        using NewSwapChainBase::NewSwapChainBase;
        MaybeError Initialize(NewSwapChainBase* previousSwapChain);

        struct Config {
            // Information that's passed to the D3D12 swapchain creation call.
            UINT bufferCount;
            UINT swapChainFlags;
            DXGI_FORMAT format;
            DXGI_USAGE usage;
        };

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

        // Does the swapchain initialization steps assuming there is nothing we can reuse.
        MaybeError InitializeSwapChainFromScratch();
        // Does the swapchain initialization step of gathering the buffers.
        MaybeError CollectSwapChainBuffers();
        // Calls DetachFromSurface but also synchronously waits until all references to the
        // swapchain and buffers are removed, as that's a constraint for some DXGI operations.
        MaybeError DetachAndWaitForDeallocation();

        Config mConfig;

        ComPtr<IDXGISwapChain3> mDXGISwapChain;
        std::vector<ComPtr<ID3D12Resource>> mBuffers;
        std::vector<ExecutionSerial> mBufferLastUsedSerials;
        uint32_t mCurrentBuffer = 0;

        Ref<Texture> mApiTexture;
    };

}  // namespace dawn::native::d3d12

#endif  // DAWNNATIVE_D3D12_SWAPCHAIN_D3D12_H_
