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 service_id()32 GLuint service_id() const { 33 return service_id_; 34 } 35 target()36 GLenum target() const { 37 return target_; 38 } 39 size()40 GLsizeiptr size() const { 41 return size_; 42 } 43 usage()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 IsDeleted()58 bool IsDeleted() const { 59 return deleted_; 60 } 61 IsValid()62 bool IsValid() const { 63 return target() && !IsDeleted(); 64 } 65 IsClientSideArray()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: Range(GLuint offset,GLsizei count,GLenum type)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 { operatorLess86 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 set_target(GLenum target)105 void set_target(GLenum target) { 106 DCHECK_EQ(target_, 0u); // you can only set this once. 107 target_ = target; 108 } 109 shadowed()110 bool shadowed() const { 111 return shadowed_; 112 } 113 MarkAsDeleted()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 set_allow_buffers_on_multiple_targets(bool allow)216 void set_allow_buffers_on_multiple_targets(bool allow) { 217 allow_buffers_on_multiple_targets_ = allow; 218 } 219 mem_represented()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