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.
5 #ifndef GPU_COMMAND_BUFFER_SERVICE_BUFFER_MANAGER_H_
6 #define GPU_COMMAND_BUFFER_SERVICE_BUFFER_MANAGER_H_
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/common/buffer.h"
15 #include "gpu/command_buffer/service/gl_utils.h"
16 #include "gpu/command_buffer/service/memory_tracking.h"
17 #include "gpu/gpu_export.h"
28 // Info about Buffers currently in the system.
29 class GPU_EXPORT Buffer
: public base::RefCounted
<Buffer
> {
35 void* pointer
; // Pointer returned by driver.
36 scoped_refptr
<gpu::Buffer
> shm
; // Client side mem.
38 MappedRange(GLintptr offset
, GLsizeiptr size
, GLenum access
,
39 void* pointer
, scoped_refptr
<gpu::Buffer
> shm
);
41 void* GetShmPointer() const;
44 Buffer(BufferManager
* manager
, GLuint service_id
);
46 GLuint
service_id() const {
50 GLsizeiptr
size() const {
54 GLenum
usage() const {
58 // Gets the maximum value in the buffer for the given range interpreted as
59 // the given type. Returns false if offset and count are out of range.
60 // offset is in bytes.
61 // count is in elements of type.
62 bool GetMaxValueForRange(GLuint offset
, GLsizei count
, GLenum type
,
65 // Returns a pointer to shadowed data.
66 const void* GetRange(GLintptr offset
, GLsizeiptr size
) const;
68 bool IsDeleted() const {
72 bool IsValid() const {
73 return initial_target() && !IsDeleted();
76 bool IsClientSideArray() const {
77 return is_client_side_array_
;
80 void SetMappedRange(GLintptr offset
, GLsizeiptr size
, GLenum access
,
81 void* pointer
, scoped_refptr
<gpu::Buffer
> shm
) {
82 mapped_range_
.reset(new MappedRange(offset
, size
, access
, pointer
, shm
));
85 void RemoveMappedRange() {
86 mapped_range_
.reset(nullptr);
89 const MappedRange
* GetMappedRange() const {
90 return mapped_range_
.get();
94 friend class BufferManager
;
95 friend class BufferManagerTestBase
;
96 friend class base::RefCounted
<Buffer
>;
98 // Represents a range in a buffer.
101 Range(GLuint offset
, GLsizei count
, GLenum type
)
107 // A less functor provided for std::map so it can find ranges.
109 bool operator() (const Range
& lhs
, const Range
& rhs
) const {
110 if (lhs
.offset_
!= rhs
.offset_
) {
111 return lhs
.offset_
< rhs
.offset_
;
113 if (lhs
.count_
!= rhs
.count_
) {
114 return lhs
.count_
< rhs
.count_
;
116 return lhs
.type_
< rhs
.type_
;
128 GLenum
initial_target() const {
129 return initial_target_
;
132 void set_initial_target(GLenum target
) {
133 DCHECK_EQ(0u, initial_target_
);
134 initial_target_
= target
;
137 bool shadowed() const {
141 void MarkAsDeleted() {
145 // Sets the size, usage and initial data of a buffer.
146 // If shadow is true then if data is NULL buffer will be initialized to 0.
148 GLsizeiptr size
, GLenum usage
, bool shadow
, const GLvoid
* data
,
149 bool is_client_side_array
);
151 // Sets a range of data for this buffer. Returns false if the offset or size
154 GLintptr offset
, GLsizeiptr size
, const GLvoid
* data
);
156 // Clears any cache of index ranges.
159 // Check if an offset, size range is valid for the current buffer.
160 bool CheckRange(GLintptr offset
, GLsizeiptr size
) const;
162 // The manager that owns this Buffer.
163 BufferManager
* manager_
;
165 // A copy of the data in the buffer. This data is only kept if the target
166 // is backed_ = true.
167 scoped_ptr
<int8
[]> shadow_
;
175 // Whether or not the data is shadowed.
178 // Whether or not this Buffer is not uploaded to the GPU but just
179 // sitting in local memory.
180 bool is_client_side_array_
;
182 // Service side buffer id.
185 // The first target of buffer. 0 = unset.
186 // It is set the first time bindBuffer() is called and cannot be changed.
187 GLenum initial_target_
;
192 // Data cached from last glMapBufferRange call.
193 scoped_ptr
<MappedRange
> mapped_range_
;
195 // A map of ranges to the highest value in that range of a certain type.
196 typedef std::map
<Range
, GLuint
, Range::Less
> RangeToMaxValueMap
;
197 RangeToMaxValueMap range_set_
;
200 // This class keeps track of the buffers and their sizes so we can do
203 // NOTE: To support shared resources an instance of this class will need to be
204 // shared by multiple GLES2Decoders.
205 class GPU_EXPORT BufferManager
: public base::trace_event::MemoryDumpProvider
{
207 BufferManager(MemoryTracker
* memory_tracker
, FeatureInfo
* feature_info
);
208 ~BufferManager() override
;
210 // Must call before destruction.
211 void Destroy(bool have_context
);
213 // Creates a Buffer for the given buffer.
214 void CreateBuffer(GLuint client_id
, GLuint service_id
);
216 // Gets the buffer info for the given buffer.
217 Buffer
* GetBuffer(GLuint client_id
);
219 // Removes a buffer info for the given buffer.
220 void RemoveBuffer(GLuint client_id
);
222 // Gets a client id for a given service id.
223 bool GetClientId(GLuint service_id
, GLuint
* client_id
) const;
225 // Validates a glBufferSubData, and then calls DoBufferData if validation was
227 void ValidateAndDoBufferSubData(
228 ContextState
* context_state
, GLenum target
, GLintptr offset
,
229 GLsizeiptr size
, const GLvoid
* data
);
231 // Validates a glBufferData, and then calls DoBufferData if validation was
233 void ValidateAndDoBufferData(
234 ContextState
* context_state
, GLenum target
, GLsizeiptr size
,
235 const GLvoid
* data
, GLenum usage
);
237 // Validates a glGetBufferParameteri64v, and then calls GetBufferParameteri64v
238 // if validation was successful.
239 void ValidateAndDoGetBufferParameteri64v(
240 ContextState
* context_state
, GLenum target
, GLenum pname
, GLint64
* params
);
242 // Validates a glGetBufferParameteriv, and then calls GetBufferParameteriv if
243 // validation was successful.
244 void ValidateAndDoGetBufferParameteriv(
245 ContextState
* context_state
, GLenum target
, GLenum pname
, GLint
* params
);
247 // Sets the target of a buffer. Returns false if the target can not be set.
248 bool SetTarget(Buffer
* buffer
, GLenum target
);
250 void set_allow_buffers_on_multiple_targets(bool allow
) {
251 allow_buffers_on_multiple_targets_
= allow
;
254 void set_allow_fixed_attribs(bool allow
) {
255 allow_fixed_attribs_
= allow
;
258 size_t mem_represented() const {
259 return memory_type_tracker_
->GetMemRepresented();
262 // Tells for a given usage if this would be a client side array.
263 bool IsUsageClientSideArray(GLenum usage
);
265 // Tells whether a buffer that is emulated using client-side arrays should be
266 // set to a non-zero size.
267 bool UseNonZeroSizeForClientSideArrayBuffer();
269 Buffer
* GetBufferInfoForTarget(ContextState
* state
, GLenum target
) const;
271 // base::trace_event::MemoryDumpProvider implementation.
272 bool OnMemoryDump(const base::trace_event::MemoryDumpArgs
& args
,
273 base::trace_event::ProcessMemoryDump
* pmd
) override
;
277 friend class TestHelper
; // Needs access to DoBufferData.
278 friend class BufferManagerTestBase
; // Needs access to DoBufferSubData.
280 void StartTracking(Buffer
* buffer
);
281 void StopTracking(Buffer
* buffer
);
283 // Does a glBufferSubData and updates the approriate accounting.
284 // Assumes the values have already been validated.
285 void DoBufferSubData(
286 ErrorState
* error_state
,
293 // Does a glBufferData and updates the approprate accounting. Currently
294 // Assumes the values have already been validated.
296 ErrorState
* error_state
,
303 // Sets the size, usage and initial data of a buffer.
304 // If data is NULL buffer will be initialized to 0 if shadowed.
305 void SetInfo(Buffer
* buffer
, GLenum target
, GLsizeiptr size
, GLenum usage
,
308 scoped_ptr
<MemoryTypeTracker
> memory_type_tracker_
;
309 MemoryTracker
* memory_tracker_
;
310 scoped_refptr
<FeatureInfo
> feature_info_
;
312 // Info for each buffer in the system.
313 typedef base::hash_map
<GLuint
, scoped_refptr
<Buffer
> > BufferMap
;
316 // Whether or not buffers can be bound to multiple targets.
317 bool allow_buffers_on_multiple_targets_
;
319 // Whether or not allow using GL_FIXED type for vertex attribs.
320 bool allow_fixed_attribs_
;
322 // Counts the number of Buffer allocated with 'this' as its manager.
323 // Allows to check no Buffer will outlive this.
324 unsigned int buffer_count_
;
327 bool use_client_side_arrays_for_stream_buffers_
;
329 DISALLOW_COPY_AND_ASSIGN(BufferManager
);
335 #endif // GPU_COMMAND_BUFFER_SERVICE_BUFFER_MANAGER_H_