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

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

Issue 1822643002: [Command buffer] Enable primitive restart for WebGL 2 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix coding style and update webgl2_conformance_expectations.py Created 4 years, 8 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_fixed_index_(0),
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, bool primitive_restart_enabled,
217 Range range(offset, count, type); 222 GLuint* max_value) {
223 GLuint primitive_restart_index = 0;
224 if (primitive_restart_enabled) {
225 switch (type) {
226 case GL_UNSIGNED_BYTE:
227 primitive_restart_index = 0xFF;
228 break;
229 case GL_UNSIGNED_SHORT:
230 primitive_restart_index = 0xFFFF;
231 break;
232 case GL_UNSIGNED_INT:
233 primitive_restart_index = 0xFFFFFFFF;
234 break;
235 default:
236 NOTREACHED(); // should never get here by validation.
237 break;
238 }
239 }
240
241 Range range(offset, count, type, primitive_restart_enabled);
218 RangeToMaxValueMap::iterator it = range_set_.find(range); 242 RangeToMaxValueMap::iterator it = range_set_.find(range);
219 if (it != range_set_.end()) { 243 if (it != range_set_.end()) {
220 *max_value = it->second; 244 *max_value = it->second;
221 return true; 245 return true;
222 } 246 }
247 // Optimization. If:
248 // - primitive restart is enabled
249 // - we don't have an entry in the range set for these parameters
250 // for the situation when primitive restart is enabled
251 // - we do have an entry in the range set for these parameters for
252 // the situation when primitive restart is disabled
253 // - this entry is less than the primitive restart index
254 // Then we can repurpose this entry for the situation when primitive
255 // restart is enabled. Otherwise, we need to compute the max index
256 // from scratch.
257 if (primitive_restart_enabled) {
258 Range disabled_range(offset, count, type, false);
259 RangeToMaxValueMap::iterator it = range_set_.find(disabled_range);
260 if (it != range_set_.end() && it->second < primitive_restart_index) {
261 // This reuses the max value for the case where primitive
262 // restart is enabled.
263 range_set_.insert(std::make_pair(range, it->second));
264 *max_value = it->second;
265 return true;
266 }
267 }
223 268
224 uint32_t size; 269 uint32_t size;
225 if (!SafeMultiplyUint32( 270 if (!SafeMultiplyUint32(
226 count, GLES2Util::GetGLTypeSizeForBuffers(type), &size)) { 271 count, GLES2Util::GetGLTypeSizeForBuffers(type), &size)) {
227 return false; 272 return false;
228 } 273 }
229 274
230 if (!SafeAddUint32(offset, size, &size)) { 275 if (!SafeAddUint32(offset, size, &size)) {
231 return false; 276 return false;
232 } 277 }
233 278
234 if (size > static_cast<uint32_t>(size_)) { 279 if (size > static_cast<uint32_t>(size_)) {
235 return false; 280 return false;
236 } 281 }
237 282
238 if (!shadowed_) { 283 if (!shadowed_) {
239 return false; 284 return false;
240 } 285 }
241 286
242 // Scan the range for the max value and store 287 // Scan the range for the max value and store
243 GLuint max_v = 0; 288 GLuint max_v = 0;
244 switch (type) { 289 switch (type) {
245 case GL_UNSIGNED_BYTE: 290 case GL_UNSIGNED_BYTE:
246 max_v = GetMaxValue<uint8_t>(shadow_.get(), offset, count); 291 max_v = GetMaxValue<uint8_t>(shadow_.get(), offset, count,
292 primitive_restart_index);
247 break; 293 break;
248 case GL_UNSIGNED_SHORT: 294 case GL_UNSIGNED_SHORT:
249 // Check we are not accessing an odd byte for a 2 byte value. 295 // Check we are not accessing an odd byte for a 2 byte value.
250 if ((offset & 1) != 0) { 296 if ((offset & 1) != 0) {
251 return false; 297 return false;
252 } 298 }
253 max_v = GetMaxValue<uint16_t>(shadow_.get(), offset, count); 299 max_v = GetMaxValue<uint16_t>(shadow_.get(), offset, count,
300 primitive_restart_index);
254 break; 301 break;
255 case GL_UNSIGNED_INT: 302 case GL_UNSIGNED_INT:
256 // Check we are not accessing a non aligned address for a 4 byte value. 303 // Check we are not accessing a non aligned address for a 4 byte value.
257 if ((offset & 3) != 0) { 304 if ((offset & 3) != 0) {
258 return false; 305 return false;
259 } 306 }
260 max_v = GetMaxValue<uint32_t>(shadow_.get(), offset, count); 307 max_v = GetMaxValue<uint32_t>(shadow_.get(), offset, count,
308 primitive_restart_index);
261 break; 309 break;
262 default: 310 default:
263 NOTREACHED(); // should never get here by validation. 311 NOTREACHED(); // should never get here by validation.
264 break; 312 break;
265 } 313 }
266 range_set_.insert(std::make_pair(range, max_v)); 314 range_set_.insert(std::make_pair(range, max_v));
267 *max_value = max_v; 315 *max_value = max_v;
268 return true; 316 return true;
269 } 317 }
270 318
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 case GL_TRANSFORM_FEEDBACK_BUFFER: 577 case GL_TRANSFORM_FEEDBACK_BUFFER:
530 return state->bound_transform_feedback_buffer.get(); 578 return state->bound_transform_feedback_buffer.get();
531 case GL_UNIFORM_BUFFER: 579 case GL_UNIFORM_BUFFER:
532 return state->bound_uniform_buffer.get(); 580 return state->bound_uniform_buffer.get();
533 default: 581 default:
534 NOTREACHED(); 582 NOTREACHED();
535 return nullptr; 583 return nullptr;
536 } 584 }
537 } 585 }
538 586
587 void BufferManager::SetPrimitiveRestartFixedIndexIfNecessary(GLenum type) {
588 GLuint index = 0;
589 switch (type) {
590 case GL_UNSIGNED_BYTE:
591 index = 0xFF;
592 break;
593 case GL_UNSIGNED_SHORT:
594 index = 0xFFFF;
595 break;
596 case GL_UNSIGNED_INT:
597 index = 0xFFFFFFFF;
598 break;
599 default:
600 NOTREACHED(); // should never get here by validation.
601 break;
602 }
603 if (primitive_restart_fixed_index_ != index) {
604 glPrimitiveRestartIndex(index);
605 primitive_restart_fixed_index_ = index;
606 }
607 }
608
539 bool BufferManager::OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, 609 bool BufferManager::OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
540 base::trace_event::ProcessMemoryDump* pmd) { 610 base::trace_event::ProcessMemoryDump* pmd) {
541 const int client_id = memory_tracker_->ClientId(); 611 const int client_id = memory_tracker_->ClientId();
542 for (const auto& buffer_entry : buffers_) { 612 for (const auto& buffer_entry : buffers_) {
543 const auto& client_buffer_id = buffer_entry.first; 613 const auto& client_buffer_id = buffer_entry.first;
544 const auto& buffer = buffer_entry.second; 614 const auto& buffer = buffer_entry.second;
545 615
546 std::string dump_name = base::StringPrintf( 616 std::string dump_name = base::StringPrintf(
547 "gpu/gl/buffers/client_%d/buffer_%d", client_id, client_buffer_id); 617 "gpu/gl/buffers/client_%d/buffer_%d", client_id, client_buffer_id);
548 base::trace_event::MemoryAllocatorDump* dump = 618 base::trace_event::MemoryAllocatorDump* dump =
549 pmd->CreateAllocatorDump(dump_name); 619 pmd->CreateAllocatorDump(dump_name);
550 dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, 620 dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
551 base::trace_event::MemoryAllocatorDump::kUnitsBytes, 621 base::trace_event::MemoryAllocatorDump::kUnitsBytes,
552 static_cast<uint64_t>(buffer->size())); 622 static_cast<uint64_t>(buffer->size()));
553 623
554 auto guid = gfx::GetGLBufferGUIDForTracing( 624 auto guid = gfx::GetGLBufferGUIDForTracing(
555 memory_tracker_->ShareGroupTracingGUID(), client_buffer_id); 625 memory_tracker_->ShareGroupTracingGUID(), client_buffer_id);
556 pmd->CreateSharedGlobalAllocatorDump(guid); 626 pmd->CreateSharedGlobalAllocatorDump(guid);
557 pmd->AddOwnershipEdge(dump->guid(), guid); 627 pmd->AddOwnershipEdge(dump->guid(), guid);
558 } 628 }
559 return true; 629 return true;
560 } 630 }
561 631
562 } // namespace gles2 632 } // namespace gles2
563 } // namespace gpu 633 } // namespace gpu
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