// Copyright 2019 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_COMMANDENCODER_H_
#define DAWNNATIVE_COMMANDENCODER_H_

#include "dawn_native/dawn_platform.h"

#include "dawn_native/CommandAllocator.h"
#include "dawn_native/Error.h"
#include "dawn_native/ObjectBase.h"
#include "dawn_native/PassResourceUsage.h"

#include <string>

namespace dawn_native {

    struct BeginRenderPassCmd;
    class CommandBufferBuilder;

    // CommandEncoder is temporarily a wrapper around CommandBufferBuilder so the two can coexist
    // while code is migrated to the new shiny CommandEncoder interface. It captures any command
    // buffer builder error and defers to trigger a device error when "Finish" is called.
    class CommandEncoderBase : public ObjectBase {
      public:
        CommandEncoderBase(DeviceBase* device);
        ~CommandEncoderBase();

        CommandIterator AcquireCommands();
        CommandBufferResourceUsage AcquireResourceUsages();

        // Dawn API
        ComputePassEncoderBase* BeginComputePass();
        RenderPassEncoderBase* BeginRenderPass(const RenderPassDescriptor* info);
        void CopyBufferToBuffer(BufferBase* source,
                                uint32_t sourceOffset,
                                BufferBase* destination,
                                uint32_t destinationOffset,
                                uint32_t size);
        void CopyBufferToTexture(const BufferCopyView* source,
                                 const TextureCopyView* destination,
                                 const Extent3D* copySize);
        void CopyTextureToBuffer(const TextureCopyView* source,
                                 const BufferCopyView* destination,
                                 const Extent3D* copySize);
        void CopyTextureToTexture(const TextureCopyView* source,
                                  const TextureCopyView* destination,
                                  const Extent3D* copySize);
        CommandBufferBase* Finish();

        // Functions to interact with the encoders
        void HandleError(const char* message);
        void ConsumeError(ErrorData* error);
        bool ConsumedError(MaybeError maybeError) {
            if (DAWN_UNLIKELY(maybeError.IsError())) {
                ConsumeError(maybeError.AcquireError());
                return true;
            }
            return false;
        }

        void PassEnded();

      private:
        MaybeError ValidateFinish();
        MaybeError ValidateComputePass();
        MaybeError ValidateRenderPass(BeginRenderPassCmd* renderPass);
        MaybeError ValidateCanRecordTopLevelCommands() const;

        enum class EncodingState : uint8_t;
        EncodingState mEncodingState;

        void MoveToIterator();
        CommandAllocator mAllocator;
        CommandIterator mIterator;
        bool mWasMovedToIterator = false;
        bool mWereCommandsAcquired = false;

        bool mWereResourceUsagesAcquired = false;
        CommandBufferResourceUsage mResourceUsages;

        unsigned int mDebugGroupStackSize = 0;

        bool mGotError = false;
        std::string mErrorMessage;
    };

}  // namespace dawn_native

#endif  // DAWNNATIVE_COMMANDENCODER_H_
