Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(843)

Side by Side Diff: gpu/command_buffer/service/buffer_manager.cc

Issue 12494005: Use client side arrays for GL_STREAM_DRAW attributes (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/gles2_cmd_decoder.h" 11 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
11 #include "gpu/command_buffer/service/memory_tracking.h" 12 #include "gpu/command_buffer/service/memory_tracking.h"
13 #include "ui/gl/gl_bindings.h"
12 14
13 namespace gpu { 15 namespace gpu {
14 namespace gles2 { 16 namespace gles2 {
15 17
16 BufferManager::BufferManager(MemoryTracker* memory_tracker) 18 BufferManager::BufferManager(
19 MemoryTracker* memory_tracker,
20 FeatureInfo* feature_info)
17 : memory_tracker_( 21 : memory_tracker_(
18 new MemoryTypeTracker(memory_tracker, MemoryTracker::kManaged)), 22 new MemoryTypeTracker(memory_tracker, MemoryTracker::kManaged)),
23 feature_info_(feature_info),
19 allow_buffers_on_multiple_targets_(false), 24 allow_buffers_on_multiple_targets_(false),
20 buffer_info_count_(0), 25 buffer_info_count_(0),
21 have_context_(true) { 26 have_context_(true),
27 use_client_side_arrays_for_stream_buffers_(
28 feature_info ? feature_info->workarounds(
29 ).use_client_side_arrays_for_stream_buffers : 0) {
22 } 30 }
23 31
24 BufferManager::~BufferManager() { 32 BufferManager::~BufferManager() {
25 DCHECK(buffer_infos_.empty()); 33 DCHECK(buffer_infos_.empty());
26 CHECK_EQ(buffer_info_count_, 0u); 34 CHECK_EQ(buffer_info_count_, 0u);
27 } 35 }
28 36
29 void BufferManager::Destroy(bool have_context) { 37 void BufferManager::Destroy(bool have_context) {
30 have_context_ = have_context; 38 have_context_ = have_context;
31 buffer_infos_.clear(); 39 buffer_infos_.clear();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 --buffer_info_count_; 71 --buffer_info_count_;
64 } 72 }
65 73
66 Buffer::Buffer(BufferManager* manager, GLuint service_id) 74 Buffer::Buffer(BufferManager* manager, GLuint service_id)
67 : manager_(manager), 75 : manager_(manager),
68 deleted_(false), 76 deleted_(false),
69 service_id_(service_id), 77 service_id_(service_id),
70 target_(0), 78 target_(0),
71 size_(0), 79 size_(0),
72 usage_(GL_STATIC_DRAW), 80 usage_(GL_STATIC_DRAW),
73 shadowed_(false) { 81 shadowed_(false),
82 is_client_side_array_(false) {
74 manager_->StartTracking(this); 83 manager_->StartTracking(this);
75 } 84 }
76 85
77 Buffer::~Buffer() { 86 Buffer::~Buffer() {
78 if (manager_) { 87 if (manager_) {
79 if (manager_->have_context_) { 88 if (manager_->have_context_) {
80 GLuint id = service_id(); 89 GLuint id = service_id();
81 glDeleteBuffersARB(1, &id); 90 glDeleteBuffersARB(1, &id);
82 } 91 }
83 manager_->StopTracking(this); 92 manager_->StopTracking(this);
84 manager_ = NULL; 93 manager_ = NULL;
85 } 94 }
86 } 95 }
87 96
88 void Buffer::SetInfo( 97 void Buffer::SetInfo(
89 GLsizeiptr size, GLenum usage, bool shadow) { 98 GLsizeiptr size, GLenum usage, bool shadow, const GLvoid* data,
99 bool is_client_side_array) {
90 usage_ = usage; 100 usage_ = usage;
101 is_client_side_array_ = is_client_side_array;
91 if (size != size_ || shadow != shadowed_) { 102 if (size != size_ || shadow != shadowed_) {
92 shadowed_ = shadow; 103 shadowed_ = shadow;
93 size_ = size; 104 size_ = size;
94 ClearCache(); 105 ClearCache();
95 if (shadowed_) { 106 if (shadowed_) {
96 shadow_.reset(new int8[size]); 107 shadow_.reset(new int8[size]);
108 } else {
109 shadow_.reset();
110 }
111 }
112 if (shadowed_) {
113 if (data) {
114 memcpy(shadow_.get(), data, size);
115 } else {
97 memset(shadow_.get(), 0, size); 116 memset(shadow_.get(), 0, size);
98 } 117 }
99 } 118 }
100 } 119 }
101 120
102 bool Buffer::CheckRange( 121 bool Buffer::CheckRange(
103 GLintptr offset, GLsizeiptr size) const { 122 GLintptr offset, GLsizeiptr size) const {
104 int32 end = 0; 123 int32 end = 0;
105 return offset >= 0 && size >= 0 && 124 return offset >= 0 && size >= 0 &&
106 offset <= std::numeric_limits<int32>::max() && 125 offset <= std::numeric_limits<int32>::max() &&
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 for (BufferInfoMap::const_iterator it = buffer_infos_.begin(); 229 for (BufferInfoMap::const_iterator it = buffer_infos_.begin();
211 it != buffer_infos_.end(); ++it) { 230 it != buffer_infos_.end(); ++it) {
212 if (it->second->service_id() == service_id) { 231 if (it->second->service_id() == service_id) {
213 *client_id = it->first; 232 *client_id = it->first;
214 return true; 233 return true;
215 } 234 }
216 } 235 }
217 return false; 236 return false;
218 } 237 }
219 238
239 bool BufferManager::IsUsageClientSideArray(GLenum usage) {
240 return usage == GL_STREAM_DRAW && use_client_side_arrays_for_stream_buffers_;
241 }
242
220 void BufferManager::SetInfo( 243 void BufferManager::SetInfo(
221 Buffer* info, GLsizeiptr size, GLenum usage) { 244 Buffer* info, GLsizeiptr size, GLenum usage, const GLvoid* data) {
222 DCHECK(info); 245 DCHECK(info);
223 memory_tracker_->TrackMemFree(info->size()); 246 memory_tracker_->TrackMemFree(info->size());
224 info->SetInfo(size, 247 bool is_client_side_array = IsUsageClientSideArray(usage);
225 usage, 248 bool shadow = info->target() == GL_ELEMENT_ARRAY_BUFFER ||
226 info->target() == GL_ELEMENT_ARRAY_BUFFER || 249 allow_buffers_on_multiple_targets_ ||
227 allow_buffers_on_multiple_targets_); 250 is_client_side_array;
251 info->SetInfo(size, usage, shadow, data, is_client_side_array);
228 memory_tracker_->TrackMemAlloc(info->size()); 252 memory_tracker_->TrackMemAlloc(info->size());
229 } 253 }
230 254
255 void BufferManager::DoBufferData(
256 GLES2Decoder* decoder,
257 Buffer* buffer,
258 GLsizeiptr size,
259 GLenum usage,
260 const GLvoid* data) {
261 // Clear the buffer to 0 if no initial data was passed in.
262 scoped_array<int8> zero;
263 if (!data) {
264 zero.reset(new int8[size]);
265 memset(zero.get(), 0, size);
266 data = zero.get();
267 }
268
269 decoder->CopyRealGLErrorsToWrapper();
270 if (IsUsageClientSideArray(usage)) {
271 glBufferData(buffer->target(), 0, NULL, usage);
272 } else {
273 glBufferData(buffer->target(), size, data, usage);
274 }
275 GLenum error = decoder->PeekGLError();
276 if (error == GL_NO_ERROR) {
277 SetInfo(buffer, size, usage, data);
278 } else {
279 SetInfo(buffer, 0, usage, NULL);
280 }
281 }
282
283 void BufferManager::DoBufferSubData(
284 GLES2Decoder* decoder,
285 Buffer* buffer,
286 GLintptr offset,
287 GLsizeiptr size,
288 const GLvoid* data) {
289 if (!buffer->SetRange(offset, size, data)) {
290 decoder->SetGLError(GL_INVALID_VALUE, "glBufferSubData", "out of range");
291 return;
292 }
293
294 if (!buffer->IsClientSideArray()) {
295 glBufferSubData(buffer->target(), offset, size, data);
296 }
297 }
298
231 bool BufferManager::SetTarget(Buffer* info, GLenum target) { 299 bool BufferManager::SetTarget(Buffer* info, GLenum target) {
232 // 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.
233 if (info->target() != 0 && info->target() != target && 301 if (info->target() != 0 && info->target() != target &&
234 !allow_buffers_on_multiple_targets_) { 302 !allow_buffers_on_multiple_targets_) {
235 return false; 303 return false;
236 } 304 }
237 if (info->target() == 0) { 305 if (info->target() == 0) {
238 info->set_target(target); 306 info->set_target(target);
239 } 307 }
240 return true; 308 return true;
241 } 309 }
242 310
243 } // namespace gles2 311 } // namespace gles2
244 } // namespace gpu 312 } // namespace gpu
245 313
246 314
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/buffer_manager.h ('k') | gpu/command_buffer/service/buffer_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698