// 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_METAL_DEVICEMTL_H_
#define DAWNNATIVE_METAL_DEVICEMTL_H_

#include "dawn_native/dawn_platform.h"

#include "dawn_native/Commands.h"
#include "dawn_native/Device.h"
#include "dawn_native/metal/CommandRecordingContext.h"
#include "dawn_native/metal/Forward.h"

#import <IOSurface/IOSurfaceRef.h>
#import <Metal/Metal.h>
#import <QuartzCore/QuartzCore.h>

#include <atomic>
#include <memory>
#include <mutex>

namespace dawn_native { namespace metal {

    namespace {
        struct KalmanInfo;
    }

    class Device : public DeviceBase {
      public:
        static ResultOrError<Device*> Create(AdapterBase* adapter,
                                             NSPRef<id<MTLDevice>> mtlDevice,
                                             const DeviceDescriptor* descriptor);
        ~Device() override;

        MaybeError Initialize();

        MaybeError TickImpl() override;

        id<MTLDevice> GetMTLDevice();
        id<MTLCommandQueue> GetMTLQueue();

        CommandRecordingContext* GetPendingCommandContext();
        MaybeError SubmitPendingCommandBuffer();

        Ref<Texture> CreateTextureWrappingIOSurface(const ExternalImageDescriptor* descriptor,
                                                    IOSurfaceRef ioSurface,
                                                    uint32_t plane);
        void WaitForCommandsToBeScheduled();

        ResultOrError<std::unique_ptr<StagingBufferBase>> CreateStagingBuffer(size_t size) override;
        MaybeError CopyFromStagingToBuffer(StagingBufferBase* source,
                                           uint64_t sourceOffset,
                                           BufferBase* destination,
                                           uint64_t destinationOffset,
                                           uint64_t size) override;
        MaybeError CopyFromStagingToTexture(const StagingBufferBase* source,
                                            const TextureDataLayout& dataLayout,
                                            TextureCopy* dst,
                                            const Extent3D& copySizePixels) override;

        uint32_t GetOptimalBytesPerRowAlignment() const override;
        uint64_t GetOptimalBufferToTextureCopyOffsetAlignment() const override;

        float GetTimestampPeriodInNS() const override;

      private:
        Device(AdapterBase* adapter,
               NSPRef<id<MTLDevice>> mtlDevice,
               const DeviceDescriptor* descriptor);

        ResultOrError<Ref<BindGroupBase>> CreateBindGroupImpl(
            const BindGroupDescriptor* descriptor) override;
        ResultOrError<Ref<BindGroupLayoutBase>> CreateBindGroupLayoutImpl(
            const BindGroupLayoutDescriptor* descriptor,
            PipelineCompatibilityToken pipelineCompatibilityToken) override;
        ResultOrError<Ref<BufferBase>> CreateBufferImpl(
            const BufferDescriptor* descriptor) override;
        ResultOrError<Ref<CommandBufferBase>> CreateCommandBuffer(
            CommandEncoder* encoder,
            const CommandBufferDescriptor* descriptor) override;
        ResultOrError<Ref<ComputePipelineBase>> CreateComputePipelineImpl(
            const ComputePipelineDescriptor* descriptor) override;
        ResultOrError<Ref<PipelineLayoutBase>> CreatePipelineLayoutImpl(
            const PipelineLayoutDescriptor* descriptor) override;
        ResultOrError<Ref<QuerySetBase>> CreateQuerySetImpl(
            const QuerySetDescriptor* descriptor) override;
        ResultOrError<Ref<RenderPipelineBase>> CreateRenderPipelineImpl(
            const RenderPipelineDescriptor* descriptor) override;
        ResultOrError<Ref<SamplerBase>> CreateSamplerImpl(
            const SamplerDescriptor* descriptor) override;
        ResultOrError<Ref<ShaderModuleBase>> CreateShaderModuleImpl(
            const ShaderModuleDescriptor* descriptor,
            ShaderModuleParseResult* parseResult) override;
        ResultOrError<Ref<SwapChainBase>> CreateSwapChainImpl(
            const SwapChainDescriptor* descriptor) override;
        ResultOrError<Ref<NewSwapChainBase>> CreateSwapChainImpl(
            Surface* surface,
            NewSwapChainBase* previousSwapChain,
            const SwapChainDescriptor* descriptor) override;
        ResultOrError<Ref<TextureBase>> CreateTextureImpl(
            const TextureDescriptor* descriptor) override;
        ResultOrError<Ref<TextureViewBase>> CreateTextureViewImpl(
            TextureBase* texture,
            const TextureViewDescriptor* descriptor) override;
        void CreateComputePipelineAsyncImpl(const ComputePipelineDescriptor* descriptor,
                                            size_t blueprintHash,
                                            WGPUCreateComputePipelineAsyncCallback callback,
                                            void* userdata) override;

        void InitTogglesFromDriver();
        void ShutDownImpl() override;
        MaybeError WaitForIdleForDestruction() override;
        ResultOrError<ExecutionSerial> CheckAndUpdateCompletedSerials() override;

        NSPRef<id<MTLDevice>> mMtlDevice;
        NSPRef<id<MTLCommandQueue>> mCommandQueue;

        CommandRecordingContext mCommandContext;

        // The completed serial is updated in a Metal completion handler that can be fired on a
        // different thread, so it needs to be atomic.
        std::atomic<uint64_t> mCompletedSerial;

        // mLastSubmittedCommands will be accessed in a Metal schedule handler that can be fired on
        // a different thread so we guard access to it with a mutex.
        std::mutex mLastSubmittedCommandsMutex;
        NSPRef<id<MTLCommandBuffer>> mLastSubmittedCommands;

        // The current estimation of timestamp period
        float mTimestampPeriod = 1.0f;
        // The base of CPU timestamp and GPU timestamp to measure the linear regression between GPU
        // and CPU timestamps.
        MTLTimestamp mCpuTimestamp API_AVAILABLE(macos(10.15), ios(14.0)) = 0;
        MTLTimestamp mGpuTimestamp API_AVAILABLE(macos(10.15), ios(14.0)) = 0;
        // The parameters for kalman filter
        std::unique_ptr<KalmanInfo> mKalmanInfo;
    };

}}  // namespace dawn_native::metal

#endif  // DAWNNATIVE_METAL_DEVICEMTL_H_
