| 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 | 
|  |