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

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

Issue 1783763002: [WebGL 2] primitive restart should be always enabled (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix build failure on Windows platforms Created 4 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
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 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <limits> 9 #include <limits>
10 10
(...skipping 16 matching lines...) Expand all
27 27
28 BufferManager::BufferManager(MemoryTracker* memory_tracker, 28 BufferManager::BufferManager(MemoryTracker* memory_tracker,
29 FeatureInfo* feature_info) 29 FeatureInfo* feature_info)
30 : memory_type_tracker_( 30 : memory_type_tracker_(
31 new MemoryTypeTracker(memory_tracker)), 31 new MemoryTypeTracker(memory_tracker)),
32 memory_tracker_(memory_tracker), 32 memory_tracker_(memory_tracker),
33 feature_info_(feature_info), 33 feature_info_(feature_info),
34 allow_buffers_on_multiple_targets_(false), 34 allow_buffers_on_multiple_targets_(false),
35 allow_fixed_attribs_(false), 35 allow_fixed_attribs_(false),
36 buffer_count_(0), 36 buffer_count_(0),
37 primitive_restart_enabled_(false),
37 have_context_(true), 38 have_context_(true),
38 use_client_side_arrays_for_stream_buffers_( 39 use_client_side_arrays_for_stream_buffers_(
39 feature_info 40 feature_info
40 ? feature_info->workarounds() 41 ? feature_info->workarounds()
41 .use_client_side_arrays_for_stream_buffers 42 .use_client_side_arrays_for_stream_buffers
42 : 0) { 43 : 0) {
43 // When created from InProcessCommandBuffer, we won't have a |memory_tracker_| 44 // When created from InProcessCommandBuffer, we won't have a |memory_tracker_|
44 // so don't register a dump provider. 45 // so don't register a dump provider.
45 if (memory_tracker_) { 46 if (memory_tracker_) {
46 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( 47 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 return NULL; 193 return NULL;
193 } 194 }
194 return shadow_.get() + offset; 195 return shadow_.get() + offset;
195 } 196 }
196 197
197 void Buffer::ClearCache() { 198 void Buffer::ClearCache() {
198 range_set_.clear(); 199 range_set_.clear();
199 } 200 }
200 201
201 template <typename T> 202 template <typename T>
202 GLuint GetMaxValue(const void* data, GLuint offset, GLsizei count) { 203 GLuint GetMaxValue(const void* data, GLuint offset, GLsizei count,
204 GLuint primitive_restart_index) {
203 GLuint max_value = 0; 205 GLuint max_value = 0;
204 const T* element = 206 const T* element =
205 reinterpret_cast<const T*>(static_cast<const int8_t*>(data) + offset); 207 reinterpret_cast<const T*>(static_cast<const int8_t*>(data) + offset);
206 const T* end = element + count; 208 const T* end = element + count;
207 for (; element < end; ++element) { 209 for (; element < end; ++element) {
208 if (*element > max_value) { 210 if (*element > max_value) {
211 if (*element == primitive_restart_index) {
212 continue;
213 }
209 max_value = *element; 214 max_value = *element;
210 } 215 }
211 } 216 }
212 return max_value; 217 return max_value;
213 } 218 }
214 219
215 bool Buffer::GetMaxValueForRange( 220 bool Buffer::GetMaxValueForRange(
216 GLuint offset, GLsizei count, GLenum type, GLuint* max_value) { 221 GLuint offset, GLsizei count, GLenum type, GLuint* max_value) {
222 bool index_buffer =
223 this->initial_target() == GL_ELEMENT_ARRAY_BUFFER ? true : false;
224 GLuint primitive_restart_index = 0;
225 if (index_buffer && manager_->primitive_restart_enabled_) {
226 switch (type) {
227 case GL_UNSIGNED_BYTE:
228 primitive_restart_index = 0xFF;
229 break;
230 case GL_UNSIGNED_SHORT:
231 primitive_restart_index = 0xFFFF;
232 break;
233 case GL_UNSIGNED_INT:
234 primitive_restart_index = 0xFFFFFFFF;
235 break;
236 default:
237 NOTREACHED(); // should never get here by validation.
238 break;
239 }
240 }
241
217 Range range(offset, count, type); 242 Range range(offset, count, type);
Ken Russell (switch to Gerrit) 2016/03/16 16:18:07 The suggestion is to add the "primitive restart en
yunchao 2016/03/17 00:19:02 Ken, I tried this method at first. But the first e
Zhenyao Mo 2016/03/18 20:28:44 Yunchao, I think you misunderstood. The suggestio
218 RangeToMaxValueMap::iterator it = range_set_.find(range); 243 RangeToMaxValueMap::iterator it = range_set_.find(range);
219 if (it != range_set_.end()) { 244 if (it != range_set_.end()) {
220 *max_value = it->second; 245 if (!index_buffer || !it->second.primitive_restart_flipped_ ||
221 return true; 246 (manager_->primitive_restart_enabled_ &&
247 it->second.max_value_ < primitive_restart_index)) {
248 *max_value = it->second.max_value_;
249 it->second.primitive_restart_flipped_ = false;
250 return true;
251 }
222 } 252 }
223 253
224 uint32_t size; 254 uint32_t size;
225 if (!SafeMultiplyUint32( 255 if (!SafeMultiplyUint32(
226 count, GLES2Util::GetGLTypeSizeForBuffers(type), &size)) { 256 count, GLES2Util::GetGLTypeSizeForBuffers(type), &size)) {
227 return false; 257 return false;
228 } 258 }
229 259
230 if (!SafeAddUint32(offset, size, &size)) { 260 if (!SafeAddUint32(offset, size, &size)) {
231 return false; 261 return false;
232 } 262 }
233 263
234 if (size > static_cast<uint32_t>(size_)) { 264 if (size > static_cast<uint32_t>(size_)) {
235 return false; 265 return false;
236 } 266 }
237 267
238 if (!shadowed_) { 268 if (!shadowed_) {
239 return false; 269 return false;
240 } 270 }
241 271
242 // Scan the range for the max value and store 272 // Scan the range for the max value and store
243 GLuint max_v = 0; 273 GLuint max_v = 0;
244 switch (type) { 274 switch (type) {
245 case GL_UNSIGNED_BYTE: 275 case GL_UNSIGNED_BYTE:
246 max_v = GetMaxValue<uint8_t>(shadow_.get(), offset, count); 276 max_v = GetMaxValue<uint8_t>(shadow_.get(), offset, count,
277 primitive_restart_index);
247 break; 278 break;
248 case GL_UNSIGNED_SHORT: 279 case GL_UNSIGNED_SHORT:
249 // Check we are not accessing an odd byte for a 2 byte value. 280 // Check we are not accessing an odd byte for a 2 byte value.
250 if ((offset & 1) != 0) { 281 if ((offset & 1) != 0) {
251 return false; 282 return false;
252 } 283 }
253 max_v = GetMaxValue<uint16_t>(shadow_.get(), offset, count); 284 max_v = GetMaxValue<uint16_t>(shadow_.get(), offset, count,
285 primitive_restart_index);
254 break; 286 break;
255 case GL_UNSIGNED_INT: 287 case GL_UNSIGNED_INT:
256 // Check we are not accessing a non aligned address for a 4 byte value. 288 // Check we are not accessing a non aligned address for a 4 byte value.
257 if ((offset & 3) != 0) { 289 if ((offset & 3) != 0) {
258 return false; 290 return false;
259 } 291 }
260 max_v = GetMaxValue<uint32_t>(shadow_.get(), offset, count); 292 max_v = GetMaxValue<uint32_t>(shadow_.get(), offset, count,
293 primitive_restart_index);
261 break; 294 break;
262 default: 295 default:
263 NOTREACHED(); // should never get here by validation. 296 NOTREACHED(); // should never get here by validation.
264 break; 297 break;
265 } 298 }
266 range_set_.insert(std::make_pair(range, max_v)); 299 if (it != range_set_.end()) {
300 it->second.max_value_ = max_v;
301 it->second.primitive_restart_flipped_ = false;
302 } else {
303 struct MaxValue value(max_v);
304 range_set_.insert(std::make_pair(range, value));
305 }
267 *max_value = max_v; 306 *max_value = max_v;
268 return true; 307 return true;
269 } 308 }
270 309
271 bool BufferManager::GetClientId(GLuint service_id, GLuint* client_id) const { 310 bool BufferManager::GetClientId(GLuint service_id, GLuint* client_id) const {
272 // This doesn't need to be fast. It's only used during slow queries. 311 // This doesn't need to be fast. It's only used during slow queries.
273 for (BufferMap::const_iterator it = buffers_.begin(); 312 for (BufferMap::const_iterator it = buffers_.begin();
274 it != buffers_.end(); ++it) { 313 it != buffers_.end(); ++it) {
275 if (it->second->service_id() == service_id) { 314 if (it->second->service_id() == service_id) {
276 *client_id = it->first; 315 *client_id = it->first;
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 case GL_TRANSFORM_FEEDBACK_BUFFER: 568 case GL_TRANSFORM_FEEDBACK_BUFFER:
530 return state->bound_transform_feedback_buffer.get(); 569 return state->bound_transform_feedback_buffer.get();
531 case GL_UNIFORM_BUFFER: 570 case GL_UNIFORM_BUFFER:
532 return state->bound_uniform_buffer.get(); 571 return state->bound_uniform_buffer.get();
533 default: 572 default:
534 NOTREACHED(); 573 NOTREACHED();
535 return nullptr; 574 return nullptr;
536 } 575 }
537 } 576 }
538 577
578 void BufferManager::SetPrimitiveRestartState(bool enabled) {
579 if (primitive_restart_enabled_ != enabled) {
580 primitive_restart_enabled_ = enabled;
581
582 for (BufferMap::const_iterator it = buffers_.begin();
583 it != buffers_.end(); ++it) {
584 if (it->second->initial_target() == GL_ELEMENT_ARRAY_BUFFER) {
585 Buffer::RangeToMaxValueMap::iterator range_set_it;
586 for (range_set_it = it->second->range_set_.begin();
587 range_set_it != it->second->range_set_.end(); ++range_set_it) {
588 range_set_it->second.primitive_restart_flipped_ =
589 !range_set_it->second.primitive_restart_flipped_;
590 }
591 }
592 }
593 }
594 }
595
539 bool BufferManager::OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, 596 bool BufferManager::OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
540 base::trace_event::ProcessMemoryDump* pmd) { 597 base::trace_event::ProcessMemoryDump* pmd) {
541 const int client_id = memory_tracker_->ClientId(); 598 const int client_id = memory_tracker_->ClientId();
542 for (const auto& buffer_entry : buffers_) { 599 for (const auto& buffer_entry : buffers_) {
543 const auto& client_buffer_id = buffer_entry.first; 600 const auto& client_buffer_id = buffer_entry.first;
544 const auto& buffer = buffer_entry.second; 601 const auto& buffer = buffer_entry.second;
545 602
546 std::string dump_name = base::StringPrintf( 603 std::string dump_name = base::StringPrintf(
547 "gpu/gl/buffers/client_%d/buffer_%d", client_id, client_buffer_id); 604 "gpu/gl/buffers/client_%d/buffer_%d", client_id, client_buffer_id);
548 base::trace_event::MemoryAllocatorDump* dump = 605 base::trace_event::MemoryAllocatorDump* dump =
549 pmd->CreateAllocatorDump(dump_name); 606 pmd->CreateAllocatorDump(dump_name);
550 dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, 607 dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
551 base::trace_event::MemoryAllocatorDump::kUnitsBytes, 608 base::trace_event::MemoryAllocatorDump::kUnitsBytes,
552 static_cast<uint64_t>(buffer->size())); 609 static_cast<uint64_t>(buffer->size()));
553 610
554 auto guid = gfx::GetGLBufferGUIDForTracing( 611 auto guid = gfx::GetGLBufferGUIDForTracing(
555 memory_tracker_->ShareGroupTracingGUID(), client_buffer_id); 612 memory_tracker_->ShareGroupTracingGUID(), client_buffer_id);
556 pmd->CreateSharedGlobalAllocatorDump(guid); 613 pmd->CreateSharedGlobalAllocatorDump(guid);
557 pmd->AddOwnershipEdge(dump->guid(), guid); 614 pmd->AddOwnershipEdge(dump->guid(), guid);
558 } 615 }
559 return true; 616 return true;
560 } 617 }
561 618
562 } // namespace gles2 619 } // namespace gles2
563 } // namespace gpu 620 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/buffer_manager.h ('k') | gpu/command_buffer/service/gles2_cmd_decoder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698