// 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_SERVICE_BUFFER_MANAGER_H_
#define GPU_COMMAND_BUFFER_SERVICE_BUFFER_MANAGER_H_

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

#include <map>
#include <memory>
#include <unordered_map>
#include <vector>

#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "gpu/command_buffer/common/buffer.h"
#include "gpu/command_buffer/service/gl_utils.h"
#include "gpu/command_buffer/service/memory_tracking.h"
#include "gpu/gpu_gles2_export.h"

namespace gpu {
namespace gles2 {

class BufferManager;
struct ContextState;
class ErrorState;
class FeatureInfo;
class IndexedBufferBindingHost;
class TestHelper;

// Info about Buffers currently in the system.
class GPU_GLES2_EXPORT Buffer : public base::RefCounted<Buffer> {
 public:
  struct MappedRange {
    GLintptr offset;
    GLsizeiptr size;
    GLenum access;
    void* pointer;  // Pointer returned by driver.
    scoped_refptr<gpu::Buffer> shm;  // Client side mem buffer.
    unsigned int shm_offset;  // Client side mem buffer offset.

    MappedRange(GLintptr offset, GLsizeiptr size, GLenum access, void* pointer,
                scoped_refptr<gpu::Buffer> shm, unsigned int shm_offset);
    ~MappedRange();
    void* GetShmPointer() const;
  };

  Buffer(BufferManager* manager, GLuint service_id);

  GLenum initial_target() const { return initial_target_; }

  GLuint service_id() const {
    return service_id_;
  }

  GLsizeiptr size() const {
    return size_;
  }

  GLenum usage() const {
    return usage_;
  }

  bool shadowed() const {
    return !shadow_.empty();
  }

  // Gets the maximum value in the buffer for the given range interpreted as
  // the given type. Returns false if offset and count are out of range.
  // offset is in bytes.
  // count is in elements of type.
  bool GetMaxValueForRange(GLuint offset, GLsizei count, GLenum type,
                           bool primitive_restart_enabled, GLuint* max_value);

  // Returns a pointer to shadowed data.
  const void* GetRange(GLintptr offset, GLsizeiptr size) const;

  // Check if an offset, size range is valid for the current buffer.
  bool CheckRange(GLintptr offset, GLsizeiptr size) const;

  // Sets a range of this buffer's shadowed data.
  void SetRange(GLintptr offset, GLsizeiptr size, const GLvoid * data);

  bool IsDeleted() const {
    return deleted_;
  }

  bool IsValid() const {
    return initial_target() && !IsDeleted();
  }

  bool IsClientSideArray() const {
    return is_client_side_array_;
  }

  void SetMappedRange(GLintptr offset, GLsizeiptr size, GLenum access,
                      void* pointer, scoped_refptr<gpu::Buffer> shm,
                      unsigned int shm_offset);
  void RemoveMappedRange();
  const MappedRange* GetMappedRange() const {
    return mapped_range_.get();
  }

  // These maintain the reference counts for checking whether a buffer is
  // double-bound to transform feedback and non-transform-feedback binding
  // points.
  void OnBind(GLenum target, bool indexed);
  void OnUnbind(GLenum target, bool indexed);

  bool IsBoundForTransformFeedbackAndOther() const {
    return transform_feedback_indexed_binding_count_ > 0 &&
           non_transform_feedback_binding_count_ > 0;
  }

  bool IsDoubleBoundForTransformFeedback() const {
    return transform_feedback_indexed_binding_count_ > 1;
  }

  void SetReadbackShadowAllocation(scoped_refptr<gpu::Buffer> shm,
                                   uint32_t shm_offset);
  scoped_refptr<gpu::Buffer> TakeReadbackShadowAllocation(void** data);

 private:
  friend class BufferManager;
  friend class BufferManagerTestBase;
  friend class base::RefCounted<Buffer>;

  // Represents a range in a buffer.
  class Range {
   public:
    Range(GLuint offset, GLsizei count, GLenum type,
          bool primitive_restart_enabled)
        : offset_(offset),
          count_(count),
          type_(type),
          primitive_restart_enabled_(primitive_restart_enabled) {
    }

    // A less functor provided for std::map so it can find ranges.
    struct Less {
      bool operator() (const Range& lhs, const Range& rhs) const {
        if (lhs.offset_ != rhs.offset_) {
          return lhs.offset_ < rhs.offset_;
        }
        if (lhs.count_ != rhs.count_) {
          return lhs.count_ < rhs.count_;
        }
        if (lhs.type_ != rhs.type_) {
          return lhs.type_ < rhs.type_;
        }
        return lhs.primitive_restart_enabled_ < rhs.primitive_restart_enabled_;
      }
    };

   private:
    GLuint offset_;
    GLsizei count_;
    GLenum type_;
    bool primitive_restart_enabled_;
  };

  ~Buffer();

  void set_initial_target(GLenum target) {
    DCHECK_EQ(0u, initial_target_);
    initial_target_ = target;
  }

  void MarkAsDeleted() {
    deleted_ = true;
  }

  // Setup the shadow buffer. This will either initialize the shadow buffer
  // with the passed data or clear the shadow buffer if no shadow required. This
  // will return a pointer to the shadowed data if using shadow, otherwise will
  // return the original data pointer.
  const GLvoid* StageShadow(bool use_shadow,
                            GLsizeiptr size,
                            const GLvoid* data);

  // Sets the size, usage and initial data of a buffer.
  // If shadow is true then if data is NULL buffer will be initialized to 0.
  void SetInfo(GLsizeiptr size,
               GLenum usage,
               bool use_shadow,
               bool is_client_side_array);

  // Clears any cache of index ranges.
  void ClearCache();

  // The manager that owns this Buffer.
  BufferManager* manager_;

  // A copy of the data in the buffer. This data is only kept if the conditions
  // checked in UseShadowBuffer() are true.
  std::vector<uint8_t> shadow_;

  // Size of buffer.
  GLsizeiptr size_;

  // True if deleted.
  bool deleted_;

  // Whether or not this Buffer is not uploaded to the GPU but just
  // sitting in local memory.
  bool is_client_side_array_;

  // Keeps track of whether this buffer is currently bound for transform
  // feedback in a WebGL context. Used as an optimization when validating WebGL
  // draw calls for compliance with binding restrictions.
  // http://crbug.com/696345
  int non_transform_feedback_binding_count_ = 0;
  int transform_feedback_indexed_binding_count_ = 0;

  // Service side buffer id.
  GLuint service_id_;

  // The first target of buffer. 0 = unset.
  // It is set the first time bindBuffer() is called and cannot be changed.
  GLenum initial_target_;

  // Usage of buffer.
  GLenum usage_;

  // Data cached from last glMapBufferRange call.
  std::unique_ptr<MappedRange> mapped_range_;

  // A map of ranges to the highest value in that range of a certain type.
  typedef std::map<Range, GLuint, Range::Less> RangeToMaxValueMap;
  RangeToMaxValueMap range_set_;

  scoped_refptr<gpu::Buffer> readback_shm_;
  uint32_t readback_shm_offset_ = 0;
};

// This class keeps track of the buffers and their sizes so we can do
// bounds checking.
//
// NOTE: To support shared resources an instance of this class will need to be
// shared by multiple GLES2Decoders.
class GPU_GLES2_EXPORT BufferManager
    : public base::trace_event::MemoryDumpProvider {
 public:
  BufferManager(MemoryTracker* memory_tracker, FeatureInfo* feature_info);
  ~BufferManager() override;

  void MarkContextLost();

  // Must call before destruction.
  void Destroy();

  // Creates a Buffer for the given buffer.
  void CreateBuffer(GLuint client_id, GLuint service_id);

  // Gets the buffer info for the given buffer.
  Buffer* GetBuffer(GLuint client_id);

  // Removes a buffer info for the given buffer.
  void RemoveBuffer(GLuint client_id);

  // Gets a client id for a given service id.
  bool GetClientId(GLuint service_id, GLuint* client_id) const;

  // Validates a glBufferSubData, and then calls DoBufferData if validation was
  // successful.
  void ValidateAndDoBufferSubData(ContextState* context_state,
                                  ErrorState* error_state,
                                  GLenum target,
                                  GLintptr offset,
                                  GLsizeiptr size,
                                  const GLvoid* data);

  // Validates a glBufferData, and then calls DoBufferData if validation was
  // successful.
  void ValidateAndDoBufferData(ContextState* context_state,
                               ErrorState* error_state,
                               GLenum target,
                               GLsizeiptr size,
                               const GLvoid* data,
                               GLenum usage);

  // Validates a glCopyBufferSubData, and then calls DoCopyBufferSubData if
  // validation was successful.
  void ValidateAndDoCopyBufferSubData(ContextState* context_state,
                                      ErrorState* error_state,
                                      GLenum readtarget,
                                      GLenum writetarget,
                                      GLintptr readoffset,
                                      GLintptr writeoffset,
                                      GLsizeiptr size);

  // Validates a glGetBufferParameteri64v, and then calls GetBufferParameteri64v
  // if validation was successful.
  void ValidateAndDoGetBufferParameteri64v(ContextState* context_state,
                                           ErrorState* error_state,
                                           GLenum target,
                                           GLenum pname,
                                           GLint64* params);

  // Validates a glGetBufferParameteriv, and then calls GetBufferParameteriv if
  // validation was successful.
  void ValidateAndDoGetBufferParameteriv(ContextState* context_state,
                                         ErrorState* error_state,
                                         GLenum target,
                                         GLenum pname,
                                         GLint* params);

  // Sets the target of a buffer. Returns false if the target can not be set.
  bool SetTarget(Buffer* buffer, GLenum target);

  void set_max_buffer_size(GLsizeiptr max_buffer_size) {
    max_buffer_size_ = max_buffer_size;
  }

  void set_allow_buffers_on_multiple_targets(bool allow) {
    allow_buffers_on_multiple_targets_ = allow;
  }

  void set_allow_fixed_attribs(bool allow) {
    allow_fixed_attribs_ = allow;
  }

  size_t mem_represented() const {
    return memory_type_tracker_->GetMemRepresented();
  }

  // Tells for a given usage if this would be a client side array.
  bool IsUsageClientSideArray(GLenum usage);

  // Tells whether a buffer that is emulated using client-side arrays should be
  // set to a non-zero size.
  bool UseNonZeroSizeForClientSideArrayBuffer();

  void SetPrimitiveRestartFixedIndexIfNecessary(GLenum type);

  Buffer* GetBufferInfoForTarget(ContextState* state, GLenum target) const;

  // base::trace_event::MemoryDumpProvider implementation.
  bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
                    base::trace_event::ProcessMemoryDump* pmd) override;

  // Validate if a buffer is bound at target, if it's unmapped, if it's
  // large enough. Return the buffer bound to |target| if access is granted;
  // return nullptr if a GL error is generated.
  // Generates INVALID_VALUE if offset + size is out of range.
  Buffer* RequestBufferAccess(ContextState* context_state,
                              ErrorState* error_state,
                              GLenum target,
                              GLintptr offset,
                              GLsizeiptr size,
                              const char* func_name);
  // Same as above, but assume to access the entire buffer.
  Buffer* RequestBufferAccess(ContextState* context_state,
                              ErrorState* error_state,
                              GLenum target,
                              const char* func_name);
  // Same as above, but it can be any buffer rather than the buffer bound to
  // |target|. Return true if access is granted; return false if a GL error is
  // generated.
  bool RequestBufferAccess(ErrorState* error_state,
                           Buffer* buffer,
                           const char* func_name,
                           const char* error_message_format,
                           ...);
  // Generates INVALID_OPERATION if offset + size is out of range.
  bool RequestBufferAccess(ErrorState* error_state,
                           Buffer* buffer,
                           GLintptr offset,
                           GLsizeiptr size,
                           const char* func_name,
                           const char* error_message);
  // Returns false and generates INVALID_OPERATION if buffer at binding |ii|
  // doesn't exist, is mapped, or smaller than |variable_sizes[ii]| * |count|.
  // Return true otherwise.
  bool RequestBuffersAccess(ErrorState* error_state,
                            const IndexedBufferBindingHost* bindings,
                            const std::vector<GLsizeiptr>& variable_sizes,
                            GLsizei count,
                            const char* func_name,
                            const char* message_tag);

 private:
  friend class Buffer;
  friend class TestHelper;  // Needs access to DoBufferData.
  friend class BufferManagerTestBase;  // Needs access to DoBufferSubData.
  friend class IndexedBufferBindingHostTest;  // Needs access to SetInfo.

  void StartTracking(Buffer* buffer);
  void StopTracking(Buffer* buffer);

  // Does a glBufferSubData and updates the appropriate accounting.
  // Assumes the values have already been validated.
  void DoBufferSubData(
      Buffer* buffer,
      GLenum target,
      GLintptr offset,
      GLsizeiptr size,
      const GLvoid* data);

  // Does a glBufferData and updates the appropriate accounting.
  // Assumes the values have already been validated.
  void DoBufferData(
      ErrorState* error_state,
      Buffer* buffer,
      GLenum target,
      GLsizeiptr size,
      GLenum usage,
      const GLvoid* data);

  // Does a glCopyBufferSubData and updates the appropriate accounting.
  // Assumes the values have already been validated.
  void DoCopyBufferSubData(
      Buffer* readbuffer,
      GLenum readtarget,
      GLintptr readoffset,
      Buffer* writebuffer,
      GLenum writetarget,
      GLintptr writeoffset,
      GLsizeiptr size);

  // Tests whether a shadow buffer needs to be used.
  bool UseShadowBuffer(GLenum target, GLenum usage);

  // Sets the size, usage and initial data of a buffer.
  // If data is NULL buffer will be initialized to 0 if shadowed.
  void SetInfo(Buffer* buffer,
               GLenum target,
               GLsizeiptr size,
               GLenum usage,
               bool use_shadow);

  // Same as public RequestBufferAccess taking similar arguments, but
  // allows caller to assemble the va_list.
  bool RequestBufferAccessV(ErrorState* error_state,
                            Buffer* buffer,
                            const char* func_name,
                            const char* error_message_format,
                            va_list varargs);

  std::unique_ptr<MemoryTypeTracker> memory_type_tracker_;
  MemoryTracker* memory_tracker_;
  scoped_refptr<FeatureInfo> feature_info_;

  // Info for each buffer in the system.
  typedef std::unordered_map<GLuint, scoped_refptr<Buffer>> BufferMap;
  BufferMap buffers_;

  // The maximum size of buffers.
  GLsizeiptr max_buffer_size_;

  // Whether or not buffers can be bound to multiple targets.
  bool allow_buffers_on_multiple_targets_;

  // Whether or not allow using GL_FIXED type for vertex attribs.
  bool allow_fixed_attribs_;

  // Counts the number of Buffer allocated with 'this' as its manager.
  // Allows to check no Buffer will outlive this.
  unsigned int buffer_count_;

  GLuint primitive_restart_fixed_index_;

  bool lost_context_;
  bool use_client_side_arrays_for_stream_buffers_;

  DISALLOW_COPY_AND_ASSIGN(BufferManager);
};

}  // namespace gles2
}  // namespace gpu

#endif  // GPU_COMMAND_BUFFER_SERVICE_BUFFER_MANAGER_H_
