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

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

Issue 2469803003: Revert of Initialize buffers before allowing access to them. (Closed)
Patch Set: Created 4 years, 1 month 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 29 matching lines...) Expand all
40 max_buffer_size_(kDefaultMaxBufferSize), 40 max_buffer_size_(kDefaultMaxBufferSize),
41 allow_buffers_on_multiple_targets_(false), 41 allow_buffers_on_multiple_targets_(false),
42 allow_fixed_attribs_(false), 42 allow_fixed_attribs_(false),
43 buffer_count_(0), 43 buffer_count_(0),
44 primitive_restart_fixed_index_(0), 44 primitive_restart_fixed_index_(0),
45 lost_context_(false), 45 lost_context_(false),
46 use_client_side_arrays_for_stream_buffers_( 46 use_client_side_arrays_for_stream_buffers_(
47 feature_info 47 feature_info
48 ? feature_info->workarounds() 48 ? feature_info->workarounds()
49 .use_client_side_arrays_for_stream_buffers 49 .use_client_side_arrays_for_stream_buffers
50 : 0), 50 : 0) {
51 mapped_buffer_count_(0) {
52 // When created from InProcessCommandBuffer, we won't have a |memory_tracker_| 51 // When created from InProcessCommandBuffer, we won't have a |memory_tracker_|
53 // so don't register a dump provider. 52 // so don't register a dump provider.
54 if (memory_tracker_) { 53 if (memory_tracker_) {
55 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( 54 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
56 this, "gpu::BufferManager", base::ThreadTaskRunnerHandle::Get()); 55 this, "gpu::BufferManager", base::ThreadTaskRunnerHandle::Get());
57 } 56 }
58 } 57 }
59 58
60 BufferManager::~BufferManager() { 59 BufferManager::~BufferManager() {
61 DCHECK(buffers_.empty()); 60 DCHECK(buffers_.empty());
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 usage_(GL_STATIC_DRAW) { 135 usage_(GL_STATIC_DRAW) {
137 manager_->StartTracking(this); 136 manager_->StartTracking(this);
138 } 137 }
139 138
140 Buffer::~Buffer() { 139 Buffer::~Buffer() {
141 if (manager_) { 140 if (manager_) {
142 if (!manager_->lost_context_) { 141 if (!manager_->lost_context_) {
143 GLuint id = service_id(); 142 GLuint id = service_id();
144 glDeleteBuffersARB(1, &id); 143 glDeleteBuffersARB(1, &id);
145 } 144 }
146 RemoveMappedRange();
147 manager_->StopTracking(this); 145 manager_->StopTracking(this);
148 manager_ = nullptr; 146 manager_ = NULL;
149 } 147 }
150 } 148 }
151 149
152 const GLvoid* Buffer::StageShadow(bool use_shadow, 150 const GLvoid* Buffer::StageShadow(bool use_shadow,
153 GLsizeiptr size, 151 GLsizeiptr size,
154 const GLvoid* data) { 152 const GLvoid* data) {
155 shadow_.clear(); 153 shadow_.clear();
156 if (use_shadow) { 154 if (use_shadow) {
157 if (data) { 155 if (data) {
158 shadow_.insert(shadow_.begin(), 156 shadow_.insert(shadow_.begin(),
159 static_cast<const uint8_t*>(data), 157 static_cast<const uint8_t*>(data),
160 static_cast<const uint8_t*>(data) + size); 158 static_cast<const uint8_t*>(data) + size);
161 } else { 159 } else {
162 shadow_.resize(size); 160 shadow_.resize(size);
163 memset(shadow_.data(), 0, static_cast<size_t>(size));
164 } 161 }
165 return shadow_.data(); 162 return shadow_.data();
166 } else { 163 } else {
167 return data; 164 return data;
168 } 165 }
169 } 166 }
170 167
171 void Buffer::SetInfo(GLsizeiptr size, 168 void Buffer::SetInfo(GLsizeiptr size,
172 GLenum usage, 169 GLenum usage,
173 bool use_shadow, 170 bool use_shadow,
(...skipping 12 matching lines...) Expand all
186 bool Buffer::CheckRange(GLintptr offset, GLsizeiptr size) const { 183 bool Buffer::CheckRange(GLintptr offset, GLsizeiptr size) const {
187 if (offset < 0 || offset > std::numeric_limits<int32_t>::max() || 184 if (offset < 0 || offset > std::numeric_limits<int32_t>::max() ||
188 size < 0 || size > std::numeric_limits<int32_t>::max()) { 185 size < 0 || size > std::numeric_limits<int32_t>::max()) {
189 return false; 186 return false;
190 } 187 }
191 base::CheckedNumeric<int32_t> max = offset; 188 base::CheckedNumeric<int32_t> max = offset;
192 max += size; 189 max += size;
193 return max.IsValid() && max.ValueOrDefault(0) <= size_; 190 return max.IsValid() && max.ValueOrDefault(0) <= size_;
194 } 191 }
195 192
196 void Buffer::SetRange(GLintptr offset, GLsizeiptr size, const GLvoid * data) { 193 bool Buffer::SetRange(GLintptr offset, GLsizeiptr size, const GLvoid * data) {
197 DCHECK(CheckRange(offset, size)); 194 if (!CheckRange(offset, size)) {
195 return false;
196 }
198 if (!shadow_.empty()) { 197 if (!shadow_.empty()) {
199 DCHECK_LE(static_cast<size_t>(offset + size), shadow_.size()); 198 DCHECK_LE(static_cast<size_t>(offset + size), shadow_.size());
200 memcpy(shadow_.data() + offset, data, size); 199 memcpy(shadow_.data() + offset, data, size);
201 ClearCache(); 200 ClearCache();
202 } 201 }
202 return true;
203 } 203 }
204 204
205 const void* Buffer::GetRange(GLintptr offset, GLsizeiptr size) const { 205 const void* Buffer::GetRange(GLintptr offset, GLsizeiptr size) const {
206 if (shadow_.empty()) { 206 if (shadow_.empty()) {
207 return NULL; 207 return NULL;
208 } 208 }
209 if (!CheckRange(offset, size)) { 209 if (!CheckRange(offset, size)) {
210 return NULL; 210 return NULL;
211 } 211 }
212 DCHECK_LE(static_cast<size_t>(offset + size), shadow_.size()); 212 DCHECK_LE(static_cast<size_t>(offset + size), shadow_.size());
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 break; 327 break;
328 default: 328 default:
329 NOTREACHED(); // should never get here by validation. 329 NOTREACHED(); // should never get here by validation.
330 break; 330 break;
331 } 331 }
332 range_set_.insert(std::make_pair(range, max_v)); 332 range_set_.insert(std::make_pair(range, max_v));
333 *max_value = max_v; 333 *max_value = max_v;
334 return true; 334 return true;
335 } 335 }
336 336
337 void Buffer::SetMappedRange(GLintptr offset, GLsizeiptr size, GLenum access,
338 void* pointer, scoped_refptr<gpu::Buffer> shm,
339 unsigned int shm_offset) {
340 mapped_range_.reset(
341 new MappedRange(offset, size, access, pointer, shm, shm_offset));
342 manager_->IncreaseMappedBufferCount();
343 }
344
345 void Buffer::RemoveMappedRange() {
346 if (mapped_range_.get())
347 manager_->DecreaseMappedBufferCount();
348 mapped_range_.reset(nullptr);
349 }
350
351 bool BufferManager::GetClientId(GLuint service_id, GLuint* client_id) const { 337 bool BufferManager::GetClientId(GLuint service_id, GLuint* client_id) const {
352 // This doesn't need to be fast. It's only used during slow queries. 338 // This doesn't need to be fast. It's only used during slow queries.
353 for (BufferMap::const_iterator it = buffers_.begin(); 339 for (BufferMap::const_iterator it = buffers_.begin();
354 it != buffers_.end(); ++it) { 340 it != buffers_.end(); ++it) {
355 if (it->second->service_id() == service_id) { 341 if (it->second->service_id() == service_id) {
356 *client_id = it->first; 342 *client_id = it->first;
357 return true; 343 return true;
358 } 344 }
359 } 345 }
360 return false; 346 return false;
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 GLenum usage, 436 GLenum usage,
451 const GLvoid* data) { 437 const GLvoid* data) {
452 // Stage the shadow buffer first if we are using a shadow buffer so that we 438 // Stage the shadow buffer first if we are using a shadow buffer so that we
453 // validate what we store internally. 439 // validate what we store internally.
454 const bool use_shadow = UseShadowBuffer(buffer->initial_target(), usage); 440 const bool use_shadow = UseShadowBuffer(buffer->initial_target(), usage);
455 data = buffer->StageShadow(use_shadow, size, data); 441 data = buffer->StageShadow(use_shadow, size, data);
456 442
457 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state, "glBufferData"); 443 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state, "glBufferData");
458 if (IsUsageClientSideArray(usage)) { 444 if (IsUsageClientSideArray(usage)) {
459 GLsizei empty_size = UseNonZeroSizeForClientSideArrayBuffer() ? 1 : 0; 445 GLsizei empty_size = UseNonZeroSizeForClientSideArrayBuffer() ? 1 : 0;
460 glBufferData(target, empty_size, nullptr, usage); 446 glBufferData(target, empty_size, NULL, usage);
461 } else { 447 } else {
462 if (data || !size) { 448 glBufferData(target, size, data, usage);
463 glBufferData(target, size, data, usage);
464 } else {
465 std::unique_ptr<char[]> zero(new char[size]);
466 memset(zero.get(), 0, size);
467 glBufferData(target, size, zero.get(), usage);
468 }
469 } 449 }
470 GLenum error = ERRORSTATE_PEEK_GL_ERROR(error_state, "glBufferData"); 450 GLenum error = ERRORSTATE_PEEK_GL_ERROR(error_state, "glBufferData");
471 if (error != GL_NO_ERROR) { 451 if (error != GL_NO_ERROR) {
472 DCHECK_EQ(static_cast<GLenum>(GL_OUT_OF_MEMORY), error);
473 size = 0; 452 size = 0;
474 // TODO(zmo): This doesn't seem correct. There might be shadow data from
475 // a previous successful BufferData() call.
476 buffer->StageShadow(false, 0, nullptr); // Also clear the shadow. 453 buffer->StageShadow(false, 0, nullptr); // Also clear the shadow.
477 return;
478 } 454 }
479 455
480 SetInfo(buffer, target, size, usage, use_shadow); 456 SetInfo(buffer, target, size, usage, use_shadow);
481 } 457 }
482 458
483 void BufferManager::ValidateAndDoBufferSubData( 459 void BufferManager::ValidateAndDoBufferSubData(
484 ContextState* context_state, GLenum target, GLintptr offset, GLsizeiptr size, 460 ContextState* context_state, GLenum target, GLintptr offset, GLsizeiptr size,
485 const GLvoid * data) { 461 const GLvoid * data) {
486 Buffer* buffer = RequestBufferAccess( 462 const char* func_name = "glBufferSubData";
487 context_state, target, offset, size, "glBufferSubData"); 463
464 ErrorState* error_state = context_state->GetErrorState();
465 Buffer* buffer = GetBufferInfoForTarget(context_state, target);
488 if (!buffer) { 466 if (!buffer) {
467 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, func_name,
468 "unknown buffer");
489 return; 469 return;
490 } 470 }
491 DoBufferSubData(buffer, target, offset, size, data); 471
472 if (buffer->GetMappedRange()) {
473 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, func_name,
474 "buffer is mapped");
475 return;
476 }
477
478 DoBufferSubData(error_state, buffer, target, offset, size, data);
492 } 479 }
493 480
494 void BufferManager::DoBufferSubData( 481 void BufferManager::DoBufferSubData(
495 Buffer* buffer, GLenum target, GLintptr offset, GLsizeiptr size, 482 ErrorState* error_state,
483 Buffer* buffer,
484 GLenum target,
485 GLintptr offset,
486 GLsizeiptr size,
496 const GLvoid* data) { 487 const GLvoid* data) {
497 buffer->SetRange(offset, size, data); 488 if (!buffer->SetRange(offset, size, data)) {
489 ERRORSTATE_SET_GL_ERROR(
490 error_state, GL_INVALID_VALUE, "glBufferSubData", "out of range");
491 return;
492 }
498 493
499 if (!buffer->IsClientSideArray()) { 494 if (!buffer->IsClientSideArray()) {
500 glBufferSubData(target, offset, size, data); 495 glBufferSubData(target, offset, size, data);
501 } 496 }
502 } 497 }
503 498
504 void BufferManager::ValidateAndDoCopyBufferSubData( 499 void BufferManager::ValidateAndDoCopyBufferSubData(
505 ContextState* context_state, GLenum readtarget, GLenum writetarget, 500 ContextState* context_state, GLenum readtarget, GLenum writetarget,
506 GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size) { 501 GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size) {
507 const char* func_name = "glCopyBufferSubData"; 502 const char* func_name = "glCopyBufferSubData";
508 Buffer* readbuffer = RequestBufferAccess( 503 ErrorState* error_state = context_state->GetErrorState();
509 context_state, readtarget, readoffset, size, func_name); 504
510 if (!readbuffer) 505 Buffer* readbuffer = GetBufferInfoForTarget(context_state, readtarget);
506 if (!readbuffer) {
507 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, func_name,
508 "no buffer is bound to readtarget");
511 return; 509 return;
512 Buffer* writebuffer = RequestBufferAccess( 510 }
513 context_state, writetarget, writeoffset, size, func_name); 511 if (readbuffer->GetMappedRange()) {
514 if (!writebuffer) 512 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, func_name,
513 "buffer bound to readtarget is mapped");
515 return; 514 return;
515 }
516 if (!readbuffer->CheckRange(readoffset, size)) {
517 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, func_name,
518 "readoffset/size out of range");
519 return;
520 }
516 521
517 ErrorState* error_state = context_state->GetErrorState(); 522 Buffer* writebuffer = GetBufferInfoForTarget(context_state, writetarget);
523 if (!writebuffer) {
524 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, func_name,
525 "no buffer is bound to writetarget");
526 return;
527 }
528 if (writebuffer->GetMappedRange()) {
529 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, func_name,
530 "buffer bound to writetarget is mapped");
531 return;
532 }
533 if (!writebuffer->CheckRange(writeoffset, size)) {
534 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, func_name,
535 "writeoffset/size out of range");
536 return;
537 }
538
518 if (readbuffer == writebuffer && 539 if (readbuffer == writebuffer &&
519 ((writeoffset >= readoffset && writeoffset < readoffset + size) || 540 ((writeoffset >= readoffset && writeoffset < readoffset + size) ||
520 (readoffset >= writeoffset && readoffset < writeoffset + size))) { 541 (readoffset >= writeoffset && readoffset < writeoffset + size))) {
521 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, func_name, 542 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, func_name,
522 "read/write ranges overlap"); 543 "read/write ranges overlap");
523 return; 544 return;
524 } 545 }
525 546
526 if (!allow_buffers_on_multiple_targets_) { 547 if (!allow_buffers_on_multiple_targets_) {
527 if ((readbuffer->initial_target() == GL_ELEMENT_ARRAY_BUFFER && 548 if ((readbuffer->initial_target() == GL_ELEMENT_ARRAY_BUFFER &&
(...skipping 16 matching lines...) Expand all
544 GLintptr readoffset, 565 GLintptr readoffset,
545 Buffer* writebuffer, 566 Buffer* writebuffer,
546 GLenum writetarget, 567 GLenum writetarget,
547 GLintptr writeoffset, 568 GLintptr writeoffset,
548 GLsizeiptr size) { 569 GLsizeiptr size) {
549 DCHECK(readbuffer); 570 DCHECK(readbuffer);
550 DCHECK(writebuffer); 571 DCHECK(writebuffer);
551 if (writebuffer->shadowed()) { 572 if (writebuffer->shadowed()) {
552 const void* data = readbuffer->GetRange(readoffset, size); 573 const void* data = readbuffer->GetRange(readoffset, size);
553 DCHECK(data); 574 DCHECK(data);
554 writebuffer->SetRange(writeoffset, size, data); 575 bool success = writebuffer->SetRange(writeoffset, size, data);
576 DCHECK(success);
555 } 577 }
556 578
557 glCopyBufferSubData(readtarget, writetarget, readoffset, writeoffset, size); 579 glCopyBufferSubData(readtarget, writetarget, readoffset, writeoffset, size);
558 } 580 }
559 581
560 void BufferManager::ValidateAndDoGetBufferParameteri64v( 582 void BufferManager::ValidateAndDoGetBufferParameteri64v(
561 ContextState* context_state, GLenum target, GLenum pname, GLint64* params) { 583 ContextState* context_state, GLenum target, GLenum pname, GLint64* params) {
562 Buffer* buffer = GetBufferInfoForTarget(context_state, target); 584 Buffer* buffer = GetBufferInfoForTarget(context_state, target);
563 if (!buffer) { 585 if (!buffer) {
564 ERRORSTATE_SET_GL_ERROR( 586 ERRORSTATE_SET_GL_ERROR(
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
728 static_cast<uint64_t>(buffer->size())); 750 static_cast<uint64_t>(buffer->size()));
729 751
730 auto guid = gl::GetGLBufferGUIDForTracing(share_group_tracing_guid, 752 auto guid = gl::GetGLBufferGUIDForTracing(share_group_tracing_guid,
731 client_buffer_id); 753 client_buffer_id);
732 pmd->CreateSharedGlobalAllocatorDump(guid); 754 pmd->CreateSharedGlobalAllocatorDump(guid);
733 pmd->AddOwnershipEdge(dump->guid(), guid); 755 pmd->AddOwnershipEdge(dump->guid(), guid);
734 } 756 }
735 return true; 757 return true;
736 } 758 }
737 759
738 Buffer* BufferManager::RequestBufferAccess(ContextState* context_state,
739 GLenum target,
740 GLintptr offset,
741 GLsizeiptr size,
742 const char* func_name) {
743 DCHECK(context_state);
744 ErrorState* error_state = context_state->GetErrorState();
745
746 std::string msg_tag = base::StringPrintf("bound to target 0x%04x", target);
747 Buffer* buffer = GetBufferInfoForTarget(context_state, target);
748 if (!RequestBufferAccess(error_state, buffer, func_name, msg_tag.c_str())) {
749 return nullptr;
750 }
751 if (!buffer->CheckRange(offset, size)) {
752 std::string msg = base::StringPrintf(
753 "%s : offset/size out of range", msg_tag.c_str());
754 ERRORSTATE_SET_GL_ERROR(
755 error_state, GL_INVALID_VALUE, func_name, msg.c_str());
756 return nullptr;
757 }
758 return buffer;
759 }
760
761 Buffer* BufferManager::RequestBufferAccess(ContextState* context_state,
762 GLenum target,
763 const char* func_name) {
764 DCHECK(context_state);
765 ErrorState* error_state = context_state->GetErrorState();
766
767 std::string msg_tag = base::StringPrintf("bound to target 0x%04x", target);
768 Buffer* buffer = GetBufferInfoForTarget(context_state, target);
769 return RequestBufferAccess(
770 error_state, buffer, func_name, msg_tag.c_str()) ? buffer : nullptr;
771 }
772
773 bool BufferManager::RequestBufferAccess(ErrorState* error_state,
774 Buffer* buffer,
775 const char* func_name,
776 const char* message_tag) {
777 DCHECK(error_state);
778
779 if (!buffer || buffer->IsDeleted()) {
780 std::string msg = base::StringPrintf("%s : no buffer", message_tag);
781 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, func_name,
782 msg.c_str());
783 return false;
784 }
785 if (buffer->GetMappedRange()) {
786 std::string msg = base::StringPrintf("%s : buffer is mapped", message_tag);
787 ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, func_name,
788 msg.c_str());
789 return false;
790 }
791 return true;
792 }
793
794 void BufferManager::IncreaseMappedBufferCount() {
795 DCHECK_GT(std::numeric_limits<uint32_t>::max(), mapped_buffer_count_);
796 mapped_buffer_count_++;
797 }
798
799 void BufferManager::DecreaseMappedBufferCount() {
800 DCHECK_LT(0u, mapped_buffer_count_);
801 mapped_buffer_count_--;
802 }
803
804 } // namespace gles2 760 } // namespace gles2
805 } // namespace gpu 761 } // 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