OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gpu/command_buffer/service/buffer_manager.h" | 5 #include "gpu/command_buffer/service/buffer_manager.h" |
6 #include <limits> | 6 #include <limits> |
7 #include "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | 9 #include "gpu/command_buffer/common/gles2_cmd_utils.h" |
10 #include "gpu/command_buffer/service/feature_info.h" | 10 #include "gpu/command_buffer/service/feature_info.h" |
11 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 11 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
12 #include "gpu/command_buffer/service/memory_tracking.h" | 12 #include "gpu/command_buffer/service/memory_tracking.h" |
13 #include "ui/gl/gl_bindings.h" | 13 #include "ui/gl/gl_bindings.h" |
14 | 14 |
15 namespace gpu { | 15 namespace gpu { |
16 namespace gles2 { | 16 namespace gles2 { |
17 | 17 |
18 BufferManager::BufferManager( | 18 BufferManager::BufferManager( |
19 MemoryTracker* memory_tracker, | 19 MemoryTracker* memory_tracker, |
20 FeatureInfo* feature_info) | 20 FeatureInfo* feature_info) |
21 : memory_tracker_( | 21 : memory_tracker_( |
22 new MemoryTypeTracker(memory_tracker, MemoryTracker::kManaged)), | 22 new MemoryTypeTracker(memory_tracker, MemoryTracker::kManaged)), |
23 feature_info_(feature_info), | 23 feature_info_(feature_info), |
24 allow_buffers_on_multiple_targets_(false), | 24 allow_buffers_on_multiple_targets_(false), |
25 buffer_info_count_(0), | 25 buffer_count_(0), |
26 have_context_(true), | 26 have_context_(true), |
27 use_client_side_arrays_for_stream_buffers_( | 27 use_client_side_arrays_for_stream_buffers_( |
28 feature_info ? feature_info->workarounds( | 28 feature_info ? feature_info->workarounds( |
29 ).use_client_side_arrays_for_stream_buffers : 0) { | 29 ).use_client_side_arrays_for_stream_buffers : 0) { |
30 } | 30 } |
31 | 31 |
32 BufferManager::~BufferManager() { | 32 BufferManager::~BufferManager() { |
33 DCHECK(buffer_infos_.empty()); | 33 DCHECK(buffers_.empty()); |
34 CHECK_EQ(buffer_info_count_, 0u); | 34 CHECK_EQ(buffer_count_, 0u); |
35 } | 35 } |
36 | 36 |
37 void BufferManager::Destroy(bool have_context) { | 37 void BufferManager::Destroy(bool have_context) { |
38 have_context_ = have_context; | 38 have_context_ = have_context; |
39 buffer_infos_.clear(); | 39 buffers_.clear(); |
40 DCHECK_EQ(0u, memory_tracker_->GetMemRepresented()); | 40 DCHECK_EQ(0u, memory_tracker_->GetMemRepresented()); |
41 } | 41 } |
42 | 42 |
43 void BufferManager::CreateBuffer(GLuint client_id, GLuint service_id) { | 43 void BufferManager::CreateBuffer(GLuint client_id, GLuint service_id) { |
44 scoped_refptr<Buffer> buffer(new Buffer(this, service_id)); | 44 scoped_refptr<Buffer> buffer(new Buffer(this, service_id)); |
45 std::pair<BufferInfoMap::iterator, bool> result = | 45 std::pair<BufferMap::iterator, bool> result = |
46 buffer_infos_.insert(std::make_pair(client_id, buffer)); | 46 buffers_.insert(std::make_pair(client_id, buffer)); |
47 DCHECK(result.second); | 47 DCHECK(result.second); |
48 } | 48 } |
49 | 49 |
50 Buffer* BufferManager::GetBuffer( | 50 Buffer* BufferManager::GetBuffer( |
51 GLuint client_id) { | 51 GLuint client_id) { |
52 BufferInfoMap::iterator it = buffer_infos_.find(client_id); | 52 BufferMap::iterator it = buffers_.find(client_id); |
53 return it != buffer_infos_.end() ? it->second : NULL; | 53 return it != buffers_.end() ? it->second : NULL; |
54 } | 54 } |
55 | 55 |
56 void BufferManager::RemoveBuffer(GLuint client_id) { | 56 void BufferManager::RemoveBuffer(GLuint client_id) { |
57 BufferInfoMap::iterator it = buffer_infos_.find(client_id); | 57 BufferMap::iterator it = buffers_.find(client_id); |
58 if (it != buffer_infos_.end()) { | 58 if (it != buffers_.end()) { |
59 Buffer* buffer = it->second; | 59 Buffer* buffer = it->second; |
60 buffer->MarkAsDeleted(); | 60 buffer->MarkAsDeleted(); |
61 buffer_infos_.erase(it); | 61 buffers_.erase(it); |
62 } | 62 } |
63 } | 63 } |
64 | 64 |
65 void BufferManager::StartTracking(Buffer* /* buffer */) { | 65 void BufferManager::StartTracking(Buffer* /* buffer */) { |
66 ++buffer_info_count_; | 66 ++buffer_count_; |
67 } | 67 } |
68 | 68 |
69 void BufferManager::StopTracking(Buffer* buffer) { | 69 void BufferManager::StopTracking(Buffer* buffer) { |
70 memory_tracker_->TrackMemFree(buffer->size()); | 70 memory_tracker_->TrackMemFree(buffer->size()); |
71 --buffer_info_count_; | 71 --buffer_count_; |
72 } | 72 } |
73 | 73 |
74 Buffer::Buffer(BufferManager* manager, GLuint service_id) | 74 Buffer::Buffer(BufferManager* manager, GLuint service_id) |
75 : manager_(manager), | 75 : manager_(manager), |
76 deleted_(false), | 76 deleted_(false), |
77 service_id_(service_id), | 77 service_id_(service_id), |
78 target_(0), | 78 target_(0), |
79 size_(0), | 79 size_(0), |
80 usage_(GL_STATIC_DRAW), | 80 usage_(GL_STATIC_DRAW), |
81 shadowed_(false), | 81 shadowed_(false), |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 NOTREACHED(); // should never get here by validation. | 219 NOTREACHED(); // should never get here by validation. |
220 break; | 220 break; |
221 } | 221 } |
222 range_set_.insert(std::make_pair(range, max_v)); | 222 range_set_.insert(std::make_pair(range, max_v)); |
223 *max_value = max_v; | 223 *max_value = max_v; |
224 return true; | 224 return true; |
225 } | 225 } |
226 | 226 |
227 bool BufferManager::GetClientId(GLuint service_id, GLuint* client_id) const { | 227 bool BufferManager::GetClientId(GLuint service_id, GLuint* client_id) const { |
228 // This doesn't need to be fast. It's only used during slow queries. | 228 // This doesn't need to be fast. It's only used during slow queries. |
229 for (BufferInfoMap::const_iterator it = buffer_infos_.begin(); | 229 for (BufferMap::const_iterator it = buffers_.begin(); |
230 it != buffer_infos_.end(); ++it) { | 230 it != buffers_.end(); ++it) { |
231 if (it->second->service_id() == service_id) { | 231 if (it->second->service_id() == service_id) { |
232 *client_id = it->first; | 232 *client_id = it->first; |
233 return true; | 233 return true; |
234 } | 234 } |
235 } | 235 } |
236 return false; | 236 return false; |
237 } | 237 } |
238 | 238 |
239 bool BufferManager::IsUsageClientSideArray(GLenum usage) { | 239 bool BufferManager::IsUsageClientSideArray(GLenum usage) { |
240 return usage == GL_STREAM_DRAW && use_client_side_arrays_for_stream_buffers_; | 240 return usage == GL_STREAM_DRAW && use_client_side_arrays_for_stream_buffers_; |
241 } | 241 } |
242 | 242 |
243 void BufferManager::SetInfo( | 243 void BufferManager::SetInfo( |
244 Buffer* info, GLsizeiptr size, GLenum usage, const GLvoid* data) { | 244 Buffer* buffer, GLsizeiptr size, GLenum usage, const GLvoid* data) { |
245 DCHECK(info); | 245 DCHECK(buffer); |
246 memory_tracker_->TrackMemFree(info->size()); | 246 memory_tracker_->TrackMemFree(buffer->size()); |
247 bool is_client_side_array = IsUsageClientSideArray(usage); | 247 bool is_client_side_array = IsUsageClientSideArray(usage); |
248 bool shadow = info->target() == GL_ELEMENT_ARRAY_BUFFER || | 248 bool shadow = buffer->target() == GL_ELEMENT_ARRAY_BUFFER || |
249 allow_buffers_on_multiple_targets_ || | 249 allow_buffers_on_multiple_targets_ || |
250 is_client_side_array; | 250 is_client_side_array; |
251 info->SetInfo(size, usage, shadow, data, is_client_side_array); | 251 buffer->SetInfo(size, usage, shadow, data, is_client_side_array); |
252 memory_tracker_->TrackMemAlloc(info->size()); | 252 memory_tracker_->TrackMemAlloc(buffer->size()); |
253 } | 253 } |
254 | 254 |
255 void BufferManager::DoBufferData( | 255 void BufferManager::DoBufferData( |
256 GLES2Decoder* decoder, | 256 GLES2Decoder* decoder, |
257 Buffer* buffer, | 257 Buffer* buffer, |
258 GLsizeiptr size, | 258 GLsizeiptr size, |
259 GLenum usage, | 259 GLenum usage, |
260 const GLvoid* data) { | 260 const GLvoid* data) { |
261 // Clear the buffer to 0 if no initial data was passed in. | 261 // Clear the buffer to 0 if no initial data was passed in. |
262 scoped_array<int8> zero; | 262 scoped_array<int8> zero; |
(...skipping 26 matching lines...) Expand all Loading... |
289 if (!buffer->SetRange(offset, size, data)) { | 289 if (!buffer->SetRange(offset, size, data)) { |
290 decoder->SetGLError(GL_INVALID_VALUE, "glBufferSubData", "out of range"); | 290 decoder->SetGLError(GL_INVALID_VALUE, "glBufferSubData", "out of range"); |
291 return; | 291 return; |
292 } | 292 } |
293 | 293 |
294 if (!buffer->IsClientSideArray()) { | 294 if (!buffer->IsClientSideArray()) { |
295 glBufferSubData(buffer->target(), offset, size, data); | 295 glBufferSubData(buffer->target(), offset, size, data); |
296 } | 296 } |
297 } | 297 } |
298 | 298 |
299 bool BufferManager::SetTarget(Buffer* info, GLenum target) { | 299 bool BufferManager::SetTarget(Buffer* buffer, GLenum target) { |
300 // Check that we are not trying to bind it to a different target. | 300 // Check that we are not trying to bind it to a different target. |
301 if (info->target() != 0 && info->target() != target && | 301 if (buffer->target() != 0 && buffer->target() != target && |
302 !allow_buffers_on_multiple_targets_) { | 302 !allow_buffers_on_multiple_targets_) { |
303 return false; | 303 return false; |
304 } | 304 } |
305 if (info->target() == 0) { | 305 if (buffer->target() == 0) { |
306 info->set_target(target); | 306 buffer->set_target(target); |
307 } | 307 } |
308 return true; | 308 return true; |
309 } | 309 } |
310 | 310 |
311 } // namespace gles2 | 311 } // namespace gles2 |
312 } // namespace gpu | 312 } // namespace gpu |
313 | 313 |
314 | 314 |
OLD | NEW |