| Index: gpu/command_buffer/service/buffer_manager.cc
|
| diff --git a/gpu/command_buffer/service/buffer_manager.cc b/gpu/command_buffer/service/buffer_manager.cc
|
| index 8c470fc1063300010b73a8e2ebc4d92534ed3443..e1a2171e1bd122f16e261b7a66fe072f1464f9b1 100644
|
| --- a/gpu/command_buffer/service/buffer_manager.cc
|
| +++ b/gpu/command_buffer/service/buffer_manager.cc
|
| @@ -47,8 +47,7 @@
|
| feature_info
|
| ? feature_info->workarounds()
|
| .use_client_side_arrays_for_stream_buffers
|
| - : 0),
|
| - mapped_buffer_count_(0) {
|
| + : 0) {
|
| // When created from InProcessCommandBuffer, we won't have a |memory_tracker_|
|
| // so don't register a dump provider.
|
| if (memory_tracker_) {
|
| @@ -143,9 +142,8 @@
|
| GLuint id = service_id();
|
| glDeleteBuffersARB(1, &id);
|
| }
|
| - RemoveMappedRange();
|
| manager_->StopTracking(this);
|
| - manager_ = nullptr;
|
| + manager_ = NULL;
|
| }
|
| }
|
|
|
| @@ -160,7 +158,6 @@
|
| static_cast<const uint8_t*>(data) + size);
|
| } else {
|
| shadow_.resize(size);
|
| - memset(shadow_.data(), 0, static_cast<size_t>(size));
|
| }
|
| return shadow_.data();
|
| } else {
|
| @@ -193,13 +190,16 @@
|
| return max.IsValid() && max.ValueOrDefault(0) <= size_;
|
| }
|
|
|
| -void Buffer::SetRange(GLintptr offset, GLsizeiptr size, const GLvoid * data) {
|
| - DCHECK(CheckRange(offset, size));
|
| +bool Buffer::SetRange(GLintptr offset, GLsizeiptr size, const GLvoid * data) {
|
| + if (!CheckRange(offset, size)) {
|
| + return false;
|
| + }
|
| if (!shadow_.empty()) {
|
| DCHECK_LE(static_cast<size_t>(offset + size), shadow_.size());
|
| memcpy(shadow_.data() + offset, data, size);
|
| ClearCache();
|
| }
|
| + return true;
|
| }
|
|
|
| const void* Buffer::GetRange(GLintptr offset, GLsizeiptr size) const {
|
| @@ -334,20 +334,6 @@
|
| return true;
|
| }
|
|
|
| -void Buffer::SetMappedRange(GLintptr offset, GLsizeiptr size, GLenum access,
|
| - void* pointer, scoped_refptr<gpu::Buffer> shm,
|
| - unsigned int shm_offset) {
|
| - mapped_range_.reset(
|
| - new MappedRange(offset, size, access, pointer, shm, shm_offset));
|
| - manager_->IncreaseMappedBufferCount();
|
| -}
|
| -
|
| -void Buffer::RemoveMappedRange() {
|
| - if (mapped_range_.get())
|
| - manager_->DecreaseMappedBufferCount();
|
| - mapped_range_.reset(nullptr);
|
| -}
|
| -
|
| bool BufferManager::GetClientId(GLuint service_id, GLuint* client_id) const {
|
| // This doesn't need to be fast. It's only used during slow queries.
|
| for (BufferMap::const_iterator it = buffers_.begin();
|
| @@ -457,24 +443,14 @@
|
| ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state, "glBufferData");
|
| if (IsUsageClientSideArray(usage)) {
|
| GLsizei empty_size = UseNonZeroSizeForClientSideArrayBuffer() ? 1 : 0;
|
| - glBufferData(target, empty_size, nullptr, usage);
|
| + glBufferData(target, empty_size, NULL, usage);
|
| } else {
|
| - if (data || !size) {
|
| - glBufferData(target, size, data, usage);
|
| - } else {
|
| - std::unique_ptr<char[]> zero(new char[size]);
|
| - memset(zero.get(), 0, size);
|
| - glBufferData(target, size, zero.get(), usage);
|
| - }
|
| + glBufferData(target, size, data, usage);
|
| }
|
| GLenum error = ERRORSTATE_PEEK_GL_ERROR(error_state, "glBufferData");
|
| if (error != GL_NO_ERROR) {
|
| - DCHECK_EQ(static_cast<GLenum>(GL_OUT_OF_MEMORY), error);
|
| size = 0;
|
| - // TODO(zmo): This doesn't seem correct. There might be shadow data from
|
| - // a previous successful BufferData() call.
|
| buffer->StageShadow(false, 0, nullptr); // Also clear the shadow.
|
| - return;
|
| }
|
|
|
| SetInfo(buffer, target, size, usage, use_shadow);
|
| @@ -483,18 +459,37 @@
|
| void BufferManager::ValidateAndDoBufferSubData(
|
| ContextState* context_state, GLenum target, GLintptr offset, GLsizeiptr size,
|
| const GLvoid * data) {
|
| - Buffer* buffer = RequestBufferAccess(
|
| - context_state, target, offset, size, "glBufferSubData");
|
| + const char* func_name = "glBufferSubData";
|
| +
|
| + ErrorState* error_state = context_state->GetErrorState();
|
| + Buffer* buffer = GetBufferInfoForTarget(context_state, target);
|
| if (!buffer) {
|
| - return;
|
| - }
|
| - DoBufferSubData(buffer, target, offset, size, data);
|
| + ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, func_name,
|
| + "unknown buffer");
|
| + return;
|
| + }
|
| +
|
| + if (buffer->GetMappedRange()) {
|
| + ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, func_name,
|
| + "buffer is mapped");
|
| + return;
|
| + }
|
| +
|
| + DoBufferSubData(error_state, buffer, target, offset, size, data);
|
| }
|
|
|
| void BufferManager::DoBufferSubData(
|
| - Buffer* buffer, GLenum target, GLintptr offset, GLsizeiptr size,
|
| + ErrorState* error_state,
|
| + Buffer* buffer,
|
| + GLenum target,
|
| + GLintptr offset,
|
| + GLsizeiptr size,
|
| const GLvoid* data) {
|
| - buffer->SetRange(offset, size, data);
|
| + if (!buffer->SetRange(offset, size, data)) {
|
| + ERRORSTATE_SET_GL_ERROR(
|
| + error_state, GL_INVALID_VALUE, "glBufferSubData", "out of range");
|
| + return;
|
| + }
|
|
|
| if (!buffer->IsClientSideArray()) {
|
| glBufferSubData(target, offset, size, data);
|
| @@ -505,16 +500,42 @@
|
| ContextState* context_state, GLenum readtarget, GLenum writetarget,
|
| GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size) {
|
| const char* func_name = "glCopyBufferSubData";
|
| - Buffer* readbuffer = RequestBufferAccess(
|
| - context_state, readtarget, readoffset, size, func_name);
|
| - if (!readbuffer)
|
| - return;
|
| - Buffer* writebuffer = RequestBufferAccess(
|
| - context_state, writetarget, writeoffset, size, func_name);
|
| - if (!writebuffer)
|
| - return;
|
| -
|
| ErrorState* error_state = context_state->GetErrorState();
|
| +
|
| + Buffer* readbuffer = GetBufferInfoForTarget(context_state, readtarget);
|
| + if (!readbuffer) {
|
| + ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, func_name,
|
| + "no buffer is bound to readtarget");
|
| + return;
|
| + }
|
| + if (readbuffer->GetMappedRange()) {
|
| + ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, func_name,
|
| + "buffer bound to readtarget is mapped");
|
| + return;
|
| + }
|
| + if (!readbuffer->CheckRange(readoffset, size)) {
|
| + ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, func_name,
|
| + "readoffset/size out of range");
|
| + return;
|
| + }
|
| +
|
| + Buffer* writebuffer = GetBufferInfoForTarget(context_state, writetarget);
|
| + if (!writebuffer) {
|
| + ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, func_name,
|
| + "no buffer is bound to writetarget");
|
| + return;
|
| + }
|
| + if (writebuffer->GetMappedRange()) {
|
| + ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, func_name,
|
| + "buffer bound to writetarget is mapped");
|
| + return;
|
| + }
|
| + if (!writebuffer->CheckRange(writeoffset, size)) {
|
| + ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, func_name,
|
| + "writeoffset/size out of range");
|
| + return;
|
| + }
|
| +
|
| if (readbuffer == writebuffer &&
|
| ((writeoffset >= readoffset && writeoffset < readoffset + size) ||
|
| (readoffset >= writeoffset && readoffset < writeoffset + size))) {
|
| @@ -551,7 +572,8 @@
|
| if (writebuffer->shadowed()) {
|
| const void* data = readbuffer->GetRange(readoffset, size);
|
| DCHECK(data);
|
| - writebuffer->SetRange(writeoffset, size, data);
|
| + bool success = writebuffer->SetRange(writeoffset, size, data);
|
| + DCHECK(success);
|
| }
|
|
|
| glCopyBufferSubData(readtarget, writetarget, readoffset, writeoffset, size);
|
| @@ -735,71 +757,5 @@
|
| return true;
|
| }
|
|
|
| -Buffer* BufferManager::RequestBufferAccess(ContextState* context_state,
|
| - GLenum target,
|
| - GLintptr offset,
|
| - GLsizeiptr size,
|
| - const char* func_name) {
|
| - DCHECK(context_state);
|
| - ErrorState* error_state = context_state->GetErrorState();
|
| -
|
| - std::string msg_tag = base::StringPrintf("bound to target 0x%04x", target);
|
| - Buffer* buffer = GetBufferInfoForTarget(context_state, target);
|
| - if (!RequestBufferAccess(error_state, buffer, func_name, msg_tag.c_str())) {
|
| - return nullptr;
|
| - }
|
| - if (!buffer->CheckRange(offset, size)) {
|
| - std::string msg = base::StringPrintf(
|
| - "%s : offset/size out of range", msg_tag.c_str());
|
| - ERRORSTATE_SET_GL_ERROR(
|
| - error_state, GL_INVALID_VALUE, func_name, msg.c_str());
|
| - return nullptr;
|
| - }
|
| - return buffer;
|
| -}
|
| -
|
| -Buffer* BufferManager::RequestBufferAccess(ContextState* context_state,
|
| - GLenum target,
|
| - const char* func_name) {
|
| - DCHECK(context_state);
|
| - ErrorState* error_state = context_state->GetErrorState();
|
| -
|
| - std::string msg_tag = base::StringPrintf("bound to target 0x%04x", target);
|
| - Buffer* buffer = GetBufferInfoForTarget(context_state, target);
|
| - return RequestBufferAccess(
|
| - error_state, buffer, func_name, msg_tag.c_str()) ? buffer : nullptr;
|
| -}
|
| -
|
| -bool BufferManager::RequestBufferAccess(ErrorState* error_state,
|
| - Buffer* buffer,
|
| - const char* func_name,
|
| - const char* message_tag) {
|
| - DCHECK(error_state);
|
| -
|
| - if (!buffer || buffer->IsDeleted()) {
|
| - std::string msg = base::StringPrintf("%s : no buffer", message_tag);
|
| - ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, func_name,
|
| - msg.c_str());
|
| - return false;
|
| - }
|
| - if (buffer->GetMappedRange()) {
|
| - std::string msg = base::StringPrintf("%s : buffer is mapped", message_tag);
|
| - ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, func_name,
|
| - msg.c_str());
|
| - return false;
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -void BufferManager::IncreaseMappedBufferCount() {
|
| - DCHECK_GT(std::numeric_limits<uint32_t>::max(), mapped_buffer_count_);
|
| - mapped_buffer_count_++;
|
| -}
|
| -
|
| -void BufferManager::DecreaseMappedBufferCount() {
|
| - DCHECK_LT(0u, mapped_buffer_count_);
|
| - mapped_buffer_count_--;
|
| -}
|
| -
|
| } // namespace gles2
|
| } // namespace gpu
|
|
|