Home | History | Annotate | Download | only in service
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef GPU_COMMAND_BUFFER_SERVICE_BUFFER_MANAGER_H_
      6 #define GPU_COMMAND_BUFFER_SERVICE_BUFFER_MANAGER_H_
      7 
      8 #include <map>
      9 #include "base/basictypes.h"
     10 #include "base/containers/hash_tables.h"
     11 #include "base/logging.h"
     12 #include "base/memory/ref_counted.h"
     13 #include "base/memory/scoped_ptr.h"
     14 #include "gpu/command_buffer/service/gl_utils.h"
     15 #include "gpu/command_buffer/service/memory_tracking.h"
     16 #include "gpu/gpu_export.h"
     17 
     18 namespace gpu {
     19 namespace gles2 {
     20 
     21 class BufferManager;
     22 struct ContextState;
     23 class ErrorState;
     24 class FeatureInfo;
     25 class TestHelper;
     26 
     27 // Info about Buffers currently in the system.
     28 class GPU_EXPORT Buffer : public base::RefCounted<Buffer> {
     29  public:
     30   Buffer(BufferManager* manager, GLuint service_id);
     31 
     32   GLuint service_id() const {
     33     return service_id_;
     34   }
     35 
     36   GLenum target() const {
     37     return target_;
     38   }
     39 
     40   GLsizeiptr size() const {
     41     return size_;
     42   }
     43 
     44   GLenum usage() const {
     45     return usage_;
     46   }
     47 
     48   // Gets the maximum value in the buffer for the given range interpreted as
     49   // the given type. Returns false if offset and count are out of range.
     50   // offset is in bytes.
     51   // count is in elements of type.
     52   bool GetMaxValueForRange(GLuint offset, GLsizei count, GLenum type,
     53                            GLuint* max_value);
     54 
     55   // Returns a pointer to shadowed data.
     56   const void* GetRange(GLintptr offset, GLsizeiptr size) const;
     57 
     58   bool IsDeleted() const {
     59     return deleted_;
     60   }
     61 
     62   bool IsValid() const {
     63     return target() && !IsDeleted();
     64   }
     65 
     66   bool IsClientSideArray() const {
     67     return is_client_side_array_;
     68   }
     69 
     70  private:
     71   friend class BufferManager;
     72   friend class BufferManagerTestBase;
     73   friend class base::RefCounted<Buffer>;
     74 
     75   // Represents a range in a buffer.
     76   class Range {
     77    public:
     78     Range(GLuint offset, GLsizei count, GLenum type)
     79         : offset_(offset),
     80           count_(count),
     81           type_(type) {
     82     }
     83 
     84     // A less functor provided for std::map so it can find ranges.
     85     struct Less {
     86       bool operator() (const Range& lhs, const Range& rhs) const {
     87         if (lhs.offset_ != rhs.offset_) {
     88           return lhs.offset_ < rhs.offset_;
     89         }
     90         if (lhs.count_ != rhs.count_) {
     91           return lhs.count_ < rhs.count_;
     92         }
     93         return lhs.type_ < rhs.type_;
     94       }
     95     };
     96 
     97    private:
     98     GLuint offset_;
     99     GLsizei count_;
    100     GLenum type_;
    101   };
    102 
    103   ~Buffer();
    104 
    105   void set_target(GLenum target) {
    106     DCHECK_EQ(target_, 0u);  // you can only set this once.
    107     target_ = target;
    108   }
    109 
    110   bool shadowed() const {
    111     return shadowed_;
    112   }
    113 
    114   void MarkAsDeleted() {
    115     deleted_ = true;
    116   }
    117 
    118   // Sets the size, usage and initial data of a buffer.
    119   // If shadow is true then if data is NULL buffer will be initialized to 0.
    120   void SetInfo(
    121       GLsizeiptr size, GLenum usage, bool shadow, const GLvoid* data,
    122       bool is_client_side_array);
    123 
    124   // Sets a range of data for this buffer. Returns false if the offset or size
    125   // is out of range.
    126   bool SetRange(
    127     GLintptr offset, GLsizeiptr size, const GLvoid * data);
    128 
    129   // Clears any cache of index ranges.
    130   void ClearCache();
    131 
    132   // Check if an offset, size range is valid for the current buffer.
    133   bool CheckRange(GLintptr offset, GLsizeiptr size) const;
    134 
    135   // The manager that owns this Buffer.
    136   BufferManager* manager_;
    137 
    138   // A copy of the data in the buffer. This data is only kept if the target
    139   // is backed_ = true.
    140   scoped_ptr<int8[]> shadow_;
    141 
    142   // Size of buffer.
    143   GLsizeiptr size_;
    144 
    145   // True if deleted.
    146   bool deleted_;
    147 
    148   // Whether or not the data is shadowed.
    149   bool shadowed_;
    150 
    151   // Whether or not this Buffer is not uploaded to the GPU but just
    152   // sitting in local memory.
    153   bool is_client_side_array_;
    154 
    155   // Service side buffer id.
    156   GLuint service_id_;
    157 
    158   // The type of buffer. 0 = unset, GL_BUFFER_ARRAY = vertex data,
    159   // GL_ELEMENT_BUFFER_ARRAY = index data.
    160   // Once set a buffer can not be used for something else.
    161   GLenum target_;
    162 
    163   // Usage of buffer.
    164   GLenum usage_;
    165 
    166   // A map of ranges to the highest value in that range of a certain type.
    167   typedef std::map<Range, GLuint, Range::Less> RangeToMaxValueMap;
    168   RangeToMaxValueMap range_set_;
    169 };
    170 
    171 // This class keeps track of the buffers and their sizes so we can do
    172 // bounds checking.
    173 //
    174 // NOTE: To support shared resources an instance of this class will need to be
    175 // shared by multiple GLES2Decoders.
    176 class GPU_EXPORT BufferManager {
    177  public:
    178   BufferManager(MemoryTracker* memory_tracker, FeatureInfo* feature_info);
    179   ~BufferManager();
    180 
    181   // Must call before destruction.
    182   void Destroy(bool have_context);
    183 
    184   // Creates a Buffer for the given buffer.
    185   void CreateBuffer(GLuint client_id, GLuint service_id);
    186 
    187   // Gets the buffer info for the given buffer.
    188   Buffer* GetBuffer(GLuint client_id);
    189 
    190   // Removes a buffer info for the given buffer.
    191   void RemoveBuffer(GLuint client_id);
    192 
    193   // Gets a client id for a given service id.
    194   bool GetClientId(GLuint service_id, GLuint* client_id) const;
    195 
    196   // Validates a glBufferSubData, and then calls DoBufferData if validation was
    197   // successful.
    198   void ValidateAndDoBufferSubData(
    199       ContextState* context_state, GLenum target, GLintptr offset,
    200       GLsizeiptr size, const GLvoid * data);
    201 
    202   // Validates a glBufferData, and then calls DoBufferData if validation was
    203   // successful.
    204   void ValidateAndDoBufferData(
    205     ContextState* context_state, GLenum target, GLsizeiptr size,
    206     const GLvoid * data, GLenum usage);
    207 
    208   // Validates a glGetBufferParameteriv, and then calls GetBufferParameteriv if
    209   // validation was successful.
    210   void ValidateAndDoGetBufferParameteriv(
    211     ContextState* context_state, GLenum target, GLenum pname, GLint* params);
    212 
    213   // Sets the target of a buffer. Returns false if the target can not be set.
    214   bool SetTarget(Buffer* buffer, GLenum target);
    215 
    216   void set_allow_buffers_on_multiple_targets(bool allow) {
    217     allow_buffers_on_multiple_targets_ = allow;
    218   }
    219 
    220   size_t mem_represented() const {
    221     return memory_tracker_->GetMemRepresented();
    222   }
    223 
    224   // Tells for a given usage if this would be a client side array.
    225   bool IsUsageClientSideArray(GLenum usage);
    226 
    227   // Tells whether a buffer that is emulated using client-side arrays should be
    228   // set to a non-zero size.
    229   bool UseNonZeroSizeForClientSideArrayBuffer();
    230 
    231  private:
    232   friend class Buffer;
    233   friend class TestHelper;  // Needs access to DoBufferData.
    234   friend class BufferManagerTestBase;  // Needs access to DoBufferSubData.
    235   void StartTracking(Buffer* buffer);
    236   void StopTracking(Buffer* buffer);
    237 
    238   Buffer* GetBufferInfoForTarget(ContextState* state, GLenum target);
    239 
    240   // Does a glBufferSubData and updates the approriate accounting.
    241   // Assumes the values have already been validated.
    242   void DoBufferSubData(
    243       ErrorState* error_state,
    244       Buffer* buffer,
    245       GLintptr offset,
    246       GLsizeiptr size,
    247       const GLvoid* data);
    248 
    249   // Does a glBufferData and updates the approprate accounting. Currently
    250   // Assumes the values have already been validated.
    251   void DoBufferData(
    252       ErrorState* error_state,
    253       Buffer* buffer,
    254       GLsizeiptr size,
    255       GLenum usage,
    256       const GLvoid* data);
    257 
    258   // Sets the size, usage and initial data of a buffer.
    259   // If data is NULL buffer will be initialized to 0 if shadowed.
    260   void SetInfo(
    261       Buffer* buffer, GLsizeiptr size, GLenum usage, const GLvoid* data);
    262 
    263   scoped_ptr<MemoryTypeTracker> memory_tracker_;
    264   scoped_refptr<FeatureInfo> feature_info_;
    265 
    266   // Info for each buffer in the system.
    267   typedef base::hash_map<GLuint, scoped_refptr<Buffer> > BufferMap;
    268   BufferMap buffers_;
    269 
    270   // Whether or not buffers can be bound to multiple targets.
    271   bool allow_buffers_on_multiple_targets_;
    272 
    273   // Counts the number of Buffer allocated with 'this' as its manager.
    274   // Allows to check no Buffer will outlive this.
    275   unsigned int buffer_count_;
    276 
    277   bool have_context_;
    278   bool use_client_side_arrays_for_stream_buffers_;
    279 
    280   DISALLOW_COPY_AND_ASSIGN(BufferManager);
    281 };
    282 
    283 }  // namespace gles2
    284 }  // namespace gpu
    285 
    286 #endif  // GPU_COMMAND_BUFFER_SERVICE_BUFFER_MANAGER_H_
    287