// 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 { namespace 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<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_
