// 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/macros.h"
#include "gpu/command_buffer/client/ring_buffer.h"
#include "gpu/command_buffer/common/buffer.h"
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
#include "gpu/gpu_export.h"

namespace gpu {

class CommandBufferHelper;

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

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

  virtual int GetShmId() = 0;
  virtual void* GetResultBuffer() = 0;
  virtual int GetResultOffset() = 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;
};

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

  // Overridden from TransferBufferInterface.
  bool Initialize(unsigned int default_buffer_size,
                  unsigned int result_size,
                  unsigned int min_buffer_size,
                  unsigned int max_buffer_size,
                  unsigned int alignment,
                  unsigned int size_to_flush) override;
  int GetShmId() override;
  void* GetResultBuffer() 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;

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

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

  void AllocateRingBuffer(unsigned int size);

  CommandBufferHelper* helper_;
  std::unique_ptr<RingBuffer> ring_buffer_;

  // 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_;

  // alignment for allocations
  unsigned int alignment_;

  // Size at which to do an async flush. 0 = never.
  unsigned int size_to_flush_;

  // Number of bytes since we last flushed.
  unsigned int bytes_since_last_flush_;

  // 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_;
};

// 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_(NULL),
        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_(NULL),
        size_(0),
        helper_(helper),
        transfer_buffer_(transfer_buffer) {}

  ~ScopedTransferBufferPtr() {
    Release();
  }

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

  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_;
  }

  void Release();

  void Discard();

  void Reset(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);
  }
};

}  // namespace gpu

#endif  // GPU_COMMAND_BUFFER_CLIENT_TRANSFER_BUFFER_H_
