• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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