// Copyright 2017 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#ifndef SRC_DAWN_NATIVE_COMMANDALLOCATOR_H_
#define SRC_DAWN_NATIVE_COMMANDALLOCATOR_H_

#include <cstddef>
#include <cstdint>
#include <limits>
#include <vector>

#include "dawn/common/Assert.h"
#include "dawn/common/Math.h"
#include "dawn/common/NonCopyable.h"
#include "partition_alloc/pointers/raw_ptr.h"

namespace dawn::native {

// Allocation for command buffers should be fast. To avoid doing an allocation per command
// or to avoid copying commands when reallocing, we use a linear allocator in a growing set
// of large memory blocks. We also use this to have the format to be (u32 commandId, command),
// so that iteration over the commands is easy.

// Usage of the allocator and iterator:
//     CommandAllocator allocator;
//     DrawCommand* cmd = allocator.Allocate<DrawCommand>(CommandType::Draw);
//     // Fill command
//     // Repeat allocation and filling commands
//
//     CommandIterator commands(allocator);
//     CommandType type;
//     while(commands.NextCommandId(&type)) {
//         switch(type) {
//              case CommandType::Draw:
//                  DrawCommand* draw = commands.NextCommand<DrawCommand>();
//                  // Do the draw
//                  break;
//              // other cases
//         }
//     }

// Note that you need to extract the commands from the CommandAllocator before destroying it
// and must tell the CommandIterator when the allocated commands have been processed for
// deletion.

// These are the lists of blocks, should not be used directly, only through CommandAllocator
// and CommandIterator
struct BlockDef {
    size_t size;
    raw_ptr<uint8_t> block;
};
using CommandBlocks = std::vector<BlockDef>;

namespace detail {
constexpr uint32_t kEndOfBlock = std::numeric_limits<uint32_t>::max();
constexpr uint32_t kAdditionalData = std::numeric_limits<uint32_t>::max() - 1;
}  // namespace detail

class CommandAllocator;

class CommandIterator : public NonCopyable {
  public:
    CommandIterator();
    ~CommandIterator();

    CommandIterator(CommandIterator&& other);
    CommandIterator& operator=(CommandIterator&& other);

    // Shorthand constructor for acquiring CommandBlocks from a single CommandAllocator.
    explicit CommandIterator(CommandAllocator allocator);

    void AcquireCommandBlocks(std::vector<CommandAllocator> allocators);

    template <typename E>
    bool NextCommandId(E* commandId) {
        return NextCommandId(reinterpret_cast<uint32_t*>(commandId));
    }
    template <typename T>
    T* NextCommand() {
        return static_cast<T*>(NextCommand(sizeof(T), alignof(T)));
    }
    template <typename T>
    T* NextData(size_t count) {
        return static_cast<T*>(NextData(sizeof(T) * count, alignof(T)));
    }

    // Sets iterator to the beginning of the commands without emptying the list. This method can
    // be used if iteration was stopped early and the iterator needs to be restarted.
    void Reset();

    // This method must to be called after commands have been deleted. This indicates that the
    // commands have been submitted and they are no longer valid.
    void MakeEmptyAsDataWasDestroyed();

  private:
    bool IsEmpty() const;

    DAWN_FORCE_INLINE bool NextCommandId(uint32_t* commandId) {
        uint8_t* idPtr = AlignPtr(mCurrentPtr.get(), alignof(uint32_t));
        DAWN_ASSERT(idPtr + sizeof(uint32_t) <=
                    mBlocks[mCurrentBlock].block.get() + mBlocks[mCurrentBlock].size);

        uint32_t id = *reinterpret_cast<uint32_t*>(idPtr);

        if (id != detail::kEndOfBlock) {
            mCurrentPtr = idPtr + sizeof(uint32_t);
            *commandId = id;
            return true;
        }
        return NextCommandIdInNewBlock(commandId);
    }

    bool NextCommandIdInNewBlock(uint32_t* commandId);

    DAWN_FORCE_INLINE void* NextCommand(size_t commandSize, size_t commandAlignment) {
        uint8_t* commandPtr = AlignPtr(mCurrentPtr.get(), commandAlignment);
        DAWN_ASSERT(commandPtr + sizeof(commandSize) <=
                    mBlocks[mCurrentBlock].block.get() + mBlocks[mCurrentBlock].size);

        mCurrentPtr = commandPtr + commandSize;
        return commandPtr;
    }

    DAWN_FORCE_INLINE void* NextData(size_t dataSize, size_t dataAlignment) {
        uint32_t id;
        bool hasId = NextCommandId(&id);
        DAWN_ASSERT(hasId);
        DAWN_ASSERT(id == detail::kAdditionalData);

        return NextCommand(dataSize, dataAlignment);
    }

    CommandBlocks mBlocks;
    raw_ptr<uint8_t> mCurrentPtr = nullptr;
    size_t mCurrentBlock = 0;
    // Used to avoid a special case for empty iterators.
    uint32_t mEndOfBlock = detail::kEndOfBlock;
};

class CommandAllocator : public NonCopyable {
  public:
    CommandAllocator();
    ~CommandAllocator();

    // NOTE: A moved-from CommandAllocator is reset to its initial empty state.
    CommandAllocator(CommandAllocator&&);
    CommandAllocator& operator=(CommandAllocator&&);

    // Frees all blocks held by the allocator and restores it to its initial empty state.
    void Reset();

    bool IsEmpty() const;

    template <typename T, typename E>
    T* Allocate(E commandId) {
        static_assert(sizeof(E) == sizeof(uint32_t));
        static_assert(alignof(E) == alignof(uint32_t));
        static_assert(alignof(T) <= kMaxSupportedAlignment);
        T* result =
            reinterpret_cast<T*>(Allocate(static_cast<uint32_t>(commandId), sizeof(T), alignof(T)));
        if (!result) {
            return nullptr;
        }
        new (result) T;
        return result;
    }

    template <typename T>
    T* AllocateData(size_t count) {
        static_assert(alignof(T) <= kMaxSupportedAlignment);
        T* result = reinterpret_cast<T*>(AllocateData(sizeof(T) * count, alignof(T)));
        if (!result) {
            return nullptr;
        }
        for (size_t i = 0; i < count; i++) {
            new (result + i) T;
        }
        return result;
    }

  private:
    // This is used for some internal computations and can be any power of two as long as code
    // using the CommandAllocator passes the static_asserts.
    static constexpr size_t kMaxSupportedAlignment = 8;

    // To avoid checking for overflows at every step of the computations we compute an upper
    // bound of the space that will be needed in addition to the command data.
    static constexpr size_t kWorstCaseAdditionalSize =
        sizeof(uint32_t) + kMaxSupportedAlignment + alignof(uint32_t) + sizeof(uint32_t);

    // The default value of mLastAllocationSize.
    static constexpr size_t kDefaultBaseAllocationSize = 2048;

    friend CommandIterator;
    CommandBlocks&& AcquireBlocks();

    DAWN_FORCE_INLINE uint8_t* Allocate(uint32_t commandId,
                                        size_t commandSize,
                                        size_t commandAlignment) {
        DAWN_ASSERT(mCurrentPtr != nullptr);
        DAWN_ASSERT(mEndPtr != nullptr);
        DAWN_ASSERT(commandId != detail::kEndOfBlock);

        // It should always be possible to allocate one id, for kEndOfBlock tagging,
        DAWN_ASSERT(IsPtrAligned(mCurrentPtr, alignof(uint32_t)));
        DAWN_ASSERT(mEndPtr >= mCurrentPtr);
        DAWN_ASSERT(static_cast<size_t>(mEndPtr - mCurrentPtr) >= sizeof(uint32_t));

        // The memory after the ID will contain the following:
        //   - the current ID
        //   - padding to align the command, maximum kMaxSupportedAlignment
        //   - the command of size commandSize
        //   - padding to align the next ID, maximum alignof(uint32_t)
        //   - the next ID of size sizeof(uint32_t)

        // This can't overflow because by construction mCurrentPtr always has space for the next
        // ID.
        size_t remainingSize = static_cast<size_t>(mEndPtr - mCurrentPtr);

        // The good case were we have enough space for the command data and upper bound of the
        // extra required space.
        if ((remainingSize >= kWorstCaseAdditionalSize) &&
            (remainingSize - kWorstCaseAdditionalSize >= commandSize)) {
            uint32_t* idAlloc = reinterpret_cast<uint32_t*>(mCurrentPtr.get());
            *idAlloc = commandId;

            uint8_t* commandAlloc =
                AlignPtr(mCurrentPtr.get() + sizeof(uint32_t), commandAlignment);
            mCurrentPtr = AlignPtr(commandAlloc + commandSize, alignof(uint32_t));

            return commandAlloc;
        }
        return AllocateInNewBlock(commandId, commandSize, commandAlignment);
    }

    uint8_t* AllocateInNewBlock(uint32_t commandId, size_t commandSize, size_t commandAlignment);

    DAWN_FORCE_INLINE uint8_t* AllocateData(size_t commandSize, size_t commandAlignment) {
        return Allocate(detail::kAdditionalData, commandSize, commandAlignment);
    }

    bool GetNewBlock(size_t minimumSize);

    void ResetPointers();

    CommandBlocks mBlocks;
    size_t mLastAllocationSize = kDefaultBaseAllocationSize;

    // Data used for the block range at initialization so that the first call to Allocate sees
    // there is not enough space and calls GetNewBlock. This avoids having to special case the
    // initialization in Allocate.
    uint32_t mPlaceholderEnum[1] = {0};

    // Pointers to the current range of allocation in the block. Guaranteed to allow for at
    // least one uint32_t if not nullptr, so that the special kEndOfBlock command id can always
    // be written. Nullptr iff the blocks were moved out.
    raw_ptr<uint8_t, AllowPtrArithmetic> mCurrentPtr = nullptr;
    raw_ptr<uint8_t, AllowPtrArithmetic> mEndPtr = nullptr;
};

}  // namespace dawn::native

#endif  // SRC_DAWN_NATIVE_COMMANDALLOCATOR_H_
