| Index: gpu/command_buffer/client/gles2_implementation.cc | 
| diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc | 
| index cbbe0f49544afd6eacf12b52d410382726757db9..836cbde0d304806c6a164f48ea890275f5e19ef6 100644 | 
| --- a/gpu/command_buffer/client/gles2_implementation.cc | 
| +++ b/gpu/command_buffer/client/gles2_implementation.cc | 
| @@ -373,6 +373,10 @@ void GLES2Implementation::FreeEverything() { | 
| helper_->FreeRingBuffer(); | 
| } | 
|  | 
| +void GLES2Implementation::FreeSharedMemory(void* mem) { | 
| +  mapped_memory_->FreePendingToken(mem, helper_->InsertToken()); | 
| +} | 
| + | 
| void GLES2Implementation::RunIfContextNotLost(const base::Closure& callback) { | 
| if (!lost_context_callback_run_) | 
| callback.Run(); | 
| @@ -1640,6 +1644,54 @@ GLint GLES2Implementation::GetAttribLocation( | 
| return loc; | 
| } | 
|  | 
| +void* GLES2Implementation::GetBufferSubDataAsyncCHROMIUM( | 
| +    GLenum target, GLintptr offset, GLsizeiptr size) { | 
| +  const char* name = "glGetBufferSubDataAsyncCHROMIUM"; | 
| +  GPU_CLIENT_SINGLE_THREAD_CHECK(); | 
| +  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] " << name << "(" | 
| +      << GLES2Util::GetStringEnum(target) << ", " << offset << ", " | 
| +      << size << ")"); | 
| +  switch (target) { | 
| +    case GL_ARRAY_BUFFER: | 
| +    case GL_ELEMENT_ARRAY_BUFFER: | 
| +    case GL_COPY_READ_BUFFER: | 
| +    case GL_COPY_WRITE_BUFFER: | 
| +    case GL_PIXEL_PACK_BUFFER: | 
| +    case GL_PIXEL_UNPACK_BUFFER: | 
| +    case GL_TRANSFORM_FEEDBACK_BUFFER: | 
| +    case GL_UNIFORM_BUFFER: | 
| +      break; | 
| +    default: | 
| +      SetGLError(GL_INVALID_ENUM, name, "invalid target"); | 
| +      return nullptr; | 
| +  } | 
| + | 
| +  GLuint buffer = GetBoundBufferHelper(target); | 
| +  if (buffer == 0) { | 
| +    SetGLError(GL_INVALID_OPERATION, name, "no buffer bound"); | 
| +    return nullptr; | 
| +  } | 
| + | 
| +  if (!ValidateSize("glMapBufferRange", size) || | 
| +      !ValidateOffset("glMapBufferRange", offset)) { | 
| +    SetGLError(GL_INVALID_VALUE, name, "invalid size/offset"); | 
| +    return nullptr; | 
| +  } | 
| + | 
| +  int32_t shm_id; | 
| +  unsigned int shm_offset; | 
| +  void* shm_ptr = mapped_memory_->Alloc(size, &shm_id, &shm_offset); | 
| +  if (!shm_ptr) { | 
| +    SetGLError(GL_OUT_OF_MEMORY, name, "out of memory"); | 
| +    return nullptr; | 
| +  } | 
| + | 
| +  helper_->GetBufferSubDataAsyncCHROMIUM(target, offset, size, | 
| +      shm_id, shm_offset); | 
| + | 
| +  return shm_ptr; | 
| +} | 
| + | 
| GLint GLES2Implementation::GetUniformLocationHelper( | 
| GLuint program, const char* name) { | 
| typedef cmds::GetUniformLocation::Result Result; | 
|  |