// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef GPU_COMMAND_BUFFER_CLIENT_TRANSFER_BUFFER_H_
#define GPU_COMMAND_BUFFER_CLIENT_TRANSFER_BUFFER_H_

#include <stddef.h>
#include <stdint.h>

#include <memory>

#include "base/compiler_specific.h"
#include "base/containers/circular_deque.h"
#include "base/macros.h"
#include "base/unguessable_token.h"
#include "gpu/command_buffer/client/ring_buffer.h"
#include "gpu/command_buffer/common/buffer.h"
#include "gpu/gpu_export.h"

namespace gpu {

class CommandBufferHelper;
template <typename>
class ScopedResultPtr;

// Interface for managing the transfer buffer.
class GPU_EXPORT TransferBufferInterface {
 public:
  TransferBufferInterface() = default;
  virtual ~TransferBufferInterface() = default;

  // Returns 128-bit GUID of the shared memory's region when the back end is
  // base::UnsafeSharedMemoryRegion. Otherwise, this returns an empty GUID.
  virtual base::UnguessableToken shared_memory_guid() const = 0;

  virtual bool Initialize(unsigned int buffer_size,
                          unsigned int result_size,
                          unsigned int min_buffer_size,
                          unsigned int max_buffer_size,
                          unsigned int alignment) = 0;

  virtual int GetShmId() = 0;

  virtual void Free() = 0;

  virtual bool HaveBuffer() const = 0;

  // Allocates up to size bytes.
  virtual void* AllocUpTo(unsigned int size, unsigned int* size_allocated) = 0;

  // Allocates size bytes.
  // Note: Alloc will fail if it can not return size bytes.
  virtual void* Alloc(unsigned int size) = 0;

  virtual RingBuffer::Offset GetOffset(void* pointer) const = 0;

  virtual void DiscardBlock(void* p) = 0;

  virtual void FreePendingToken(void* p, unsigned int token) = 0;

  virtual unsigned int GetSize() const = 0;

  virtual unsigned int GetFreeSize() const = 0;

  virtual unsigned int GetFragmentedFreeSize() const = 0;

  virtual void ShrinkLastBlock(unsigned int new_size) = 0;

 protected:
  template <typename>
  friend class ScopedResultPtr;
  // Use ScopedResultPtr instead of calling these directly. The acquire/release
  // semantics allow TransferBuffer to detect if there is an outstanding result
  // pointer when the buffer is resized, which would otherwise cause a
  // use-after-free bug.
  virtual void* AcquireResultBuffer() = 0;
  virtual void ReleaseResultBuffer() = 0;
  virtual int GetResultOffset() = 0;
};

// Class that manages the transfer buffer.
class GPU_EXPORT TransferBuffer : public TransferBufferInterface {
 public:
  TransferBuffer(CommandBufferHelper* helper);
  ~TransferBuffer() override;

  // Overridden from TransferBufferInterface.
  base::UnguessableToken shared_memory_guid() const override;
  bool Initialize(unsigned int default_buffer_size,
                  unsigned int result_size,
                  unsigned int min_buffer_size,
                  unsigned int max_buffer_size,
                  unsigned int alignment) override;
  int GetShmId() override;
  void* AcquireResultBuffer() override;
  void ReleaseResultBuffer() override;
  int GetResultOffset() override;
  void Free() override;
  bool HaveBuffer() const override;
  void* AllocUpTo(unsigned int size, unsigned int* size_allocated) override;
  void* Alloc(unsigned int size) override;
  RingBuffer::Offset GetOffset(void* pointer) const override;
  void DiscardBlock(void* p) override;
  void FreePendingToken(void* p, unsigned int token) override;
  unsigned int GetSize() const override;
  unsigned int GetFreeSize() const override;
  unsigned int GetFragmentedFreeSize() const override;
  void ShrinkLastBlock(unsigned int new_size) override;

  // These are for testing.
  unsigned int GetCurrentMaxAllocationWithoutRealloc() const;
  unsigned int GetMaxAllocation() const;

  // We will attempt to shrink the ring buffer once the number of bytes
  // allocated reaches this threshold times the high water mark.
  static const int kShrinkThreshold = 120;

 private:
  // Tries to reallocate the ring buffer if it's not large enough for size.
  void ReallocateRingBuffer(unsigned int size, bool shrink = false);

  void AllocateRingBuffer(unsigned int size);

  void ShrinkOrExpandRingBufferIfNecessary(unsigned int size);

  // Returns the number of bytes that are still in use in ring buffers that we
  // previously freed.
  unsigned int GetPreviousRingBufferUsedBytes();

  CommandBufferHelper* helper_;
  std::unique_ptr<RingBuffer> ring_buffer_;
  base::circular_deque<std::unique_ptr<RingBuffer>> previous_ring_buffers_;

  // size reserved for results
  unsigned int result_size_;

  // default size. Size we want when starting or re-allocating
  unsigned int default_buffer_size_;

  // min size we'll consider successful
  unsigned int min_buffer_size_;

  // max size we'll let the buffer grow
  unsigned int max_buffer_size_;

  // Size of the currently allocated ring buffer.
  unsigned int last_allocated_size_ = 0;

  // The size to shrink the ring buffer to next time shrinking happens.
  unsigned int high_water_mark_ = 0;

  // alignment for allocations
  unsigned int alignment_;

  // Number of bytes since we last attempted to shrink the ring buffer.
  unsigned int bytes_since_last_shrink_ = 0;

  // the current buffer.
  scoped_refptr<gpu::Buffer> buffer_;

  // id of buffer. -1 = no buffer
  int32_t buffer_id_;

  // address of result area
  void* result_buffer_;

  // offset to result area
  uint32_t result_shm_offset_;

  // false if we failed to allocate min_buffer_size
  bool usable_;

  // While a ScopedResultPtr exists, we can't resize the transfer buffer. Only
  // one ScopedResultPtr should exist at a time. This tracks whether one exists.
  bool outstanding_result_pointer_ = false;
};

// A class that will manage the lifetime of a transferbuffer allocation.
class GPU_EXPORT ScopedTransferBufferPtr {
 public:
  ScopedTransferBufferPtr(unsigned int size,
                          CommandBufferHelper* helper,
                          TransferBufferInterface* transfer_buffer)
      : buffer_(nullptr),
        size_(0),
        helper_(helper),
        transfer_buffer_(transfer_buffer) {
    Reset(size);
  }

  // Constructs an empty and invalid allocation that should be Reset() later.
  ScopedTransferBufferPtr(CommandBufferHelper* helper,
                          TransferBufferInterface* transfer_buffer)
      : buffer_(nullptr),
        size_(0),
        helper_(helper),
        transfer_buffer_(transfer_buffer) {}

  ~ScopedTransferBufferPtr() {
    Release();
  }

  ScopedTransferBufferPtr(ScopedTransferBufferPtr&& other);

  bool valid() const { return buffer_ != nullptr; }

  unsigned int size() const {
    return size_;
  }

  int shm_id() const {
    return transfer_buffer_->GetShmId();
  }

  RingBuffer::Offset offset() const {
    return transfer_buffer_->GetOffset(buffer_);
  }

  void* address() const {
    return buffer_;
  }

  // Returns true if |memory| lies inside this buffer.
  bool BelongsToBuffer(char* memory) const;

  void Release();

  void Discard();

  void Reset(unsigned int new_size);

  // Shrinks this transfer buffer to a given size.
  void Shrink(unsigned int new_size);

 private:
  void* buffer_;
  unsigned int size_;
  CommandBufferHelper* helper_;
  TransferBufferInterface* transfer_buffer_;
  DISALLOW_COPY_AND_ASSIGN(ScopedTransferBufferPtr);
};

template <typename T>
class ScopedTransferBufferArray : public ScopedTransferBufferPtr {
 public:
  ScopedTransferBufferArray(
      unsigned int num_elements,
      CommandBufferHelper* helper, TransferBufferInterface* transfer_buffer)
      : ScopedTransferBufferPtr(
          num_elements * sizeof(T), helper, transfer_buffer) {
  }

  T* elements() {
    return static_cast<T*>(address());
  }

  unsigned int num_elements() const {
    return size() / sizeof(T);
  }
};

// ScopedResultPtr is a move-only smart pointer that calls AcquireResultBuffer
// and ReleaseResultBuffer for you.
template <typename T>
class ScopedResultPtr {
 public:
  explicit ScopedResultPtr(TransferBufferInterface* tb)
      : result_(static_cast<T*>(tb->AcquireResultBuffer())),
        transfer_buffer_(tb) {}
  ~ScopedResultPtr() {
    if (transfer_buffer_)
      transfer_buffer_->ReleaseResultBuffer();
  }

  int offset() const { return transfer_buffer_->GetResultOffset(); }

  // Make this a move-only class like unique_ptr.
  DISALLOW_COPY_AND_ASSIGN(ScopedResultPtr);
  ScopedResultPtr(ScopedResultPtr<T>&& other) { *this = std::move(other); }
  ScopedResultPtr& operator=(ScopedResultPtr<T>&& other) {
    this->result_ = other.result_;
    this->transfer_buffer_ = other.transfer_buffer_;
    other.result_ = nullptr;
    other.transfer_buffer_ = nullptr;
    return *this;
  };

  // Dereferencing behaviors
  T& operator*() const { return *result_; }
  T* operator->() const { return result_; }
  explicit operator bool() { return result_; }

 private:
  T* result_;
  TransferBufferInterface* transfer_buffer_;
};

}  // namespace gpu

#endif  // GPU_COMMAND_BUFFER_CLIENT_TRANSFER_BUFFER_H_
