Chromium Code Reviews| Index: gpu/command_buffer/service/gles2_cmd_decoder.cc |
| diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| index ceabff8aaa3c69d74399d1b7d302a8c201b7bc25..cd5c8c20a5868e3368a106020dda388bdee3f706 100644 |
| --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| @@ -1101,6 +1101,9 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { |
| void DoScheduleCALayerInUseQueryCHROMIUM(GLsizei count, |
| const GLuint* textures); |
| + void DoFlushMappedBufferRange( |
| + GLenum target, GLintptr offset, GLsizeiptr size); |
| + |
| // Creates a Program for the given program. |
| Program* CreateProgram(GLuint client_id, GLuint service_id) { |
| return program_manager()->CreateProgram(client_id, service_id); |
| @@ -16465,13 +16468,13 @@ error::Error GLES2DecoderImpl::HandleMapBufferRange( |
| GLbitfield mask = GL_MAP_INVALIDATE_BUFFER_BIT; |
| if ((access & mask) == mask) { |
| - // TODO(zmo): To be on the safe side, always map |
| - // GL_MAP_INVALIDATE_BUFFER_BIT to GL_MAP_INVALIDATE_RANGE_BIT. |
| + // To be on the safe side, always map GL_MAP_INVALIDATE_BUFFER_BIT to |
| + // GL_MAP_INVALIDATE_RANGE_BIT. |
| access = (access & ~GL_MAP_INVALIDATE_BUFFER_BIT); |
| access = (access | GL_MAP_INVALIDATE_RANGE_BIT); |
| } |
| - // TODO(zmo): Always filter out GL_MAP_UNSYNCHRONIZED_BIT to get rid of |
| - // undefined behaviors. |
| + // Always filter out GL_MAP_UNSYNCHRONIZED_BIT to get rid of undefined |
| + // behaviors. |
| mask = GL_MAP_READ_BIT | GL_MAP_UNSYNCHRONIZED_BIT; |
| if ((access & mask) == mask) { |
| LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "MapBufferRange", |
| @@ -16500,6 +16503,7 @@ error::Error GLES2DecoderImpl::HandleMapBufferRange( |
| error::Error GLES2DecoderImpl::HandleUnmapBuffer( |
| uint32_t immediate_data_size, const void* cmd_data) { |
| + const char* func_name = "glUnmapBuffer"; |
| if (!unsafe_es3_apis_enabled()) { |
| return error::kUnknownCommand; |
| } |
| @@ -16508,19 +16512,18 @@ error::Error GLES2DecoderImpl::HandleUnmapBuffer( |
| GLenum target = static_cast<GLenum>(c.target); |
| if (!validators_->buffer_target.IsValid(target)) { |
| - LOCAL_SET_GL_ERROR_INVALID_ENUM("glMapBufferRange", target, "target"); |
| + LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, target, "target"); |
| return error::kNoError; |
| } |
| Buffer* buffer = buffer_manager()->GetBufferInfoForTarget(&state_, target); |
| if (!buffer) { |
| - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "UnmapBuffer", "no buffer bound"); |
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "no buffer bound"); |
| return error::kNoError; |
| } |
| const Buffer::MappedRange* mapped_range = buffer->GetMappedRange(); |
| if (!mapped_range) { |
| - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "UnmapBuffer", |
| - "buffer is unmapped"); |
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "buffer is unmapped"); |
| return error::kNoError; |
| } |
| if ((mapped_range->access & GL_MAP_WRITE_BIT) == 0 || |
| @@ -16553,6 +16556,39 @@ error::Error GLES2DecoderImpl::HandleUnmapBuffer( |
| return error::kNoError; |
| } |
| +void GLES2DecoderImpl::DoFlushMappedBufferRange( |
| + GLenum target, GLintptr offset, GLsizeiptr size) { |
| + const char* func_name = "glFlushMappedBufferRange"; |
| + if (offset < 0) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "offset < 0"); |
| + return; |
| + } |
| + Buffer* buffer = buffer_manager()->GetBufferInfoForTarget(&state_, target); |
| + if (!buffer) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "no buffer bound"); |
| + return; |
| + } |
| + const Buffer::MappedRange* mapped_range = buffer->GetMappedRange(); |
| + if (!mapped_range) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "buffer is unmapped"); |
| + return; |
| + } |
| + if ((mapped_range->access & GL_MAP_FLUSH_EXPLICIT_BIT) == 0) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, |
| + "buffer is mapped without MAP_FLUSH_EXPLICIT_BIT flag"); |
| + return; |
| + } |
| + base::CheckedNumeric<GLsizeiptr> range_size = size; |
| + range_size += offset; |
| + if (!range_size.IsValid() || |
| + range_size.ValueOrDefault(0) > mapped_range->size) { |
| + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, |
| + "offset + size out-of-bounds"); |
| + return; |
| + } |
| + glFlushMappedBufferRange(target, offset, size); |
|
piman
2016/08/08 22:55:22
This in itself won't do anything - the client side
|
| +} |
| + |
| // Note that GL_LOST_CONTEXT is specific to GLES. |
| // For desktop GL we have to query the reset status proactively. |
| void GLES2DecoderImpl::OnContextLostError() { |