// 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 SRC_DAWN_NATIVE_COMMANDBUFFER_H_
#define SRC_DAWN_NATIVE_COMMANDBUFFER_H_

#include "dawn/native/dawn_platform.h"

#include "dawn/native/CommandAllocator.h"
#include "dawn/native/Error.h"
#include "dawn/native/Forward.h"
#include "dawn/native/ObjectBase.h"
#include "dawn/native/PassResourceUsage.h"
#include "dawn/native/Texture.h"

namespace dawn::native {

struct BeginRenderPassCmd;
struct CopyTextureToBufferCmd;
struct TextureCopy;

class CommandBufferBase : public ApiObjectBase {
  public:
    CommandBufferBase(CommandEncoder* encoder, const CommandBufferDescriptor* descriptor);

    static CommandBufferBase* MakeError(DeviceBase* device);

    ObjectType GetType() const override;

    MaybeError ValidateCanUseInSubmitNow() const;

    const CommandBufferResourceUsage& GetResourceUsages() const;

    CommandIterator* GetCommandIteratorForTesting();

  protected:
    // Constructor used only for mocking and testing.
    explicit CommandBufferBase(DeviceBase* device);
    void DestroyImpl() override;

    CommandIterator mCommands;

  private:
    CommandBufferBase(DeviceBase* device, ObjectBase::ErrorTag tag);

    CommandBufferResourceUsage mResourceUsages;
};

bool IsCompleteSubresourceCopiedTo(const TextureBase* texture,
                                   const Extent3D copySize,
                                   const uint32_t mipLevel);
SubresourceRange GetSubresourcesAffectedByCopy(const TextureCopy& copy, const Extent3D& copySize);

void LazyClearRenderPassAttachments(BeginRenderPassCmd* renderPass);

bool IsFullBufferOverwrittenInTextureToBufferCopy(const CopyTextureToBufferCmd* copy);

std::array<float, 4> ConvertToFloatColor(dawn::native::Color color);
std::array<int32_t, 4> ConvertToSignedIntegerColor(dawn::native::Color color);
std::array<uint32_t, 4> ConvertToUnsignedIntegerColor(dawn::native::Color color);

}  // namespace dawn::native

#endif  // SRC_DAWN_NATIVE_COMMANDBUFFER_H_
