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 419b6d6853e1d442710914c55f204e30dad863d5..85b7df82f8ca9908ac73845b9a4515c343df7495 100644 |
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc |
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
@@ -12856,6 +12856,7 @@ void GLES2DecoderImpl::DoCompressedTexSubImage3D( |
error::Error GLES2DecoderImpl::HandleTexImage2D(uint32_t immediate_data_size, |
const volatile void* cmd_data) { |
+ const char* func_name = "glTexImage2D"; |
const volatile gles2::cmds::TexImage2D& c = |
*static_cast<const volatile gles2::cmds::TexImage2D*>(cmd_data); |
TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage2D", |
@@ -12874,14 +12875,20 @@ error::Error GLES2DecoderImpl::HandleTexImage2D(uint32_t immediate_data_size, |
uint32_t pixels_shm_offset = static_cast<uint32_t>(c.pixels_shm_offset); |
if (width < 0 || height < 0) { |
- LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexImage2D", "dimensions < 0"); |
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "dimensions < 0"); |
return error::kNoError; |
} |
PixelStoreParams params; |
- if (state_.bound_pixel_unpack_buffer.get()) { |
+ Buffer* buffer = state_.bound_pixel_unpack_buffer.get(); |
+ if (buffer) { |
if (pixels_shm_id) |
return error::kInvalidArguments; |
+ if (buffer->GetMappedRange()) { |
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, |
+ "pixel unpack buffer should not be mapped to client memory"); |
+ return error::kNoError; |
+ } |
params = state_.GetUnpackParams(ContextState::k2D); |
} else { |
if (!pixels_shm_id && pixels_shm_offset) |
@@ -12921,9 +12928,7 @@ error::Error GLES2DecoderImpl::HandleTexImage2D(uint32_t immediate_data_size, |
// For testing only. Allows us to stress the ability to respond to OOM errors. |
if (workarounds().simulate_out_of_memory_on_large_textures && |
(width * height >= 4096 * 4096)) { |
- LOCAL_SET_GL_ERROR( |
- GL_OUT_OF_MEMORY, |
- "glTexImage2D", "synthetic out of memory"); |
+ LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, func_name, "synthetic out of memory"); |
return error::kNoError; |
} |
@@ -12932,7 +12937,7 @@ error::Error GLES2DecoderImpl::HandleTexImage2D(uint32_t immediate_data_size, |
pixels, pixels_size, padding, |
TextureManager::DoTexImageArguments::kTexImage2D }; |
texture_manager()->ValidateAndDoTexImage( |
- &texture_state_, &state_, &framebuffer_state_, "glTexImage2D", args); |
+ &texture_state_, &state_, &framebuffer_state_, func_name, args); |
// This may be a slow command. Exit command processing to allow for |
// context preemption and GPU watchdog checks. |
@@ -12945,6 +12950,7 @@ error::Error GLES2DecoderImpl::HandleTexImage3D(uint32_t immediate_data_size, |
if (!unsafe_es3_apis_enabled()) |
return error::kUnknownCommand; |
+ const char* func_name = "glTexImage3D"; |
const volatile gles2::cmds::TexImage3D& c = |
*static_cast<const volatile gles2::cmds::TexImage3D*>(cmd_data); |
TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage3D", |
@@ -12964,14 +12970,20 @@ error::Error GLES2DecoderImpl::HandleTexImage3D(uint32_t immediate_data_size, |
uint32_t pixels_shm_offset = static_cast<uint32_t>(c.pixels_shm_offset); |
if (width < 0 || height < 0 || depth < 0) { |
- LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexImage3D", "dimensions < 0"); |
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "dimensions < 0"); |
return error::kNoError; |
} |
PixelStoreParams params; |
- if (state_.bound_pixel_unpack_buffer.get()) { |
+ Buffer* buffer = state_.bound_pixel_unpack_buffer.get(); |
+ if (buffer) { |
if (pixels_shm_id) |
return error::kInvalidArguments; |
+ if (buffer->GetMappedRange()) { |
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, |
+ "pixel unpack buffer should not be mapped to client memory"); |
+ return error::kNoError; |
+ } |
params = state_.GetUnpackParams(ContextState::k3D); |
} else { |
if (!pixels_shm_id && pixels_shm_offset) |
@@ -13011,9 +13023,7 @@ error::Error GLES2DecoderImpl::HandleTexImage3D(uint32_t immediate_data_size, |
// For testing only. Allows us to stress the ability to respond to OOM errors. |
if (workarounds().simulate_out_of_memory_on_large_textures && |
(width * height * depth >= 4096 * 4096)) { |
- LOCAL_SET_GL_ERROR( |
- GL_OUT_OF_MEMORY, |
- "glTexImage3D", "synthetic out of memory"); |
+ LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, func_name, "synthetic out of memory"); |
return error::kNoError; |
} |
@@ -13022,7 +13032,7 @@ error::Error GLES2DecoderImpl::HandleTexImage3D(uint32_t immediate_data_size, |
pixels, pixels_size, padding, |
TextureManager::DoTexImageArguments::kTexImage3D }; |
texture_manager()->ValidateAndDoTexImage( |
- &texture_state_, &state_, &framebuffer_state_, "glTexImage3D", args); |
+ &texture_state_, &state_, &framebuffer_state_, func_name, args); |
// This may be a slow command. Exit command processing to allow for |
// context preemption and GPU watchdog checks. |
@@ -13625,8 +13635,8 @@ void GLES2DecoderImpl::DoCopyTexSubImage3D( |
} |
error::Error GLES2DecoderImpl::HandleTexSubImage2D( |
- uint32_t immediate_data_size, |
- const volatile void* cmd_data) { |
+ uint32_t immediate_data_size, const volatile void* cmd_data) { |
+ const char* func_name = "glTexSubImage2D"; |
const volatile gles2::cmds::TexSubImage2D& c = |
*static_cast<const volatile gles2::cmds::TexSubImage2D*>(cmd_data); |
TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage2D", |
@@ -13647,14 +13657,20 @@ error::Error GLES2DecoderImpl::HandleTexSubImage2D( |
uint32_t pixels_shm_offset = static_cast<uint32_t>(c.pixels_shm_offset); |
if (width < 0 || height < 0) { |
- LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexSubImage2D", "dimensions < 0"); |
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "dimensions < 0"); |
return error::kNoError; |
} |
PixelStoreParams params; |
- if (state_.bound_pixel_unpack_buffer.get()) { |
+ Buffer* buffer = state_.bound_pixel_unpack_buffer.get(); |
+ if (buffer) { |
if (pixels_shm_id) |
return error::kInvalidArguments; |
+ if (buffer->GetMappedRange()) { |
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, |
+ "pixel unpack buffer should not be mapped to client memory"); |
+ return error::kNoError; |
+ } |
params = state_.GetUnpackParams(ContextState::k2D); |
} else { |
// When reading from client buffer, the command buffer client side took |
@@ -13695,7 +13711,7 @@ error::Error GLES2DecoderImpl::HandleTexSubImage2D( |
TextureManager::DoTexSubImageArguments::kTexSubImage2D}; |
texture_manager()->ValidateAndDoTexSubImage(this, &texture_state_, &state_, |
&framebuffer_state_, |
- "glTexSubImage2D", args); |
+ func_name, args); |
// This may be a slow command. Exit command processing to allow for |
// context preemption and GPU watchdog checks. |
@@ -13709,6 +13725,7 @@ error::Error GLES2DecoderImpl::HandleTexSubImage3D( |
if (!unsafe_es3_apis_enabled()) |
return error::kUnknownCommand; |
+ const char* func_name = "glTexSubImage3D"; |
const volatile gles2::cmds::TexSubImage3D& c = |
*static_cast<const volatile gles2::cmds::TexSubImage3D*>(cmd_data); |
TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage3D", |
@@ -13731,14 +13748,20 @@ error::Error GLES2DecoderImpl::HandleTexSubImage3D( |
uint32_t pixels_shm_offset = static_cast<uint32_t>(c.pixels_shm_offset); |
if (width < 0 || height < 0 || depth < 0) { |
- LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexSubImage3D", "dimensions < 0"); |
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "dimensions < 0"); |
return error::kNoError; |
} |
PixelStoreParams params; |
- if (state_.bound_pixel_unpack_buffer.get()) { |
+ Buffer* buffer = state_.bound_pixel_unpack_buffer.get(); |
+ if (buffer) { |
if (pixels_shm_id) |
return error::kInvalidArguments; |
+ if (buffer->GetMappedRange()) { |
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, |
+ "pixel unpack buffer should not be mapped to client memory"); |
+ return error::kNoError; |
+ } |
params = state_.GetUnpackParams(ContextState::k3D); |
} else { |
// When reading from client buffer, the command buffer client side took |
@@ -13779,7 +13802,7 @@ error::Error GLES2DecoderImpl::HandleTexSubImage3D( |
TextureManager::DoTexSubImageArguments::kTexSubImage3D}; |
texture_manager()->ValidateAndDoTexSubImage(this, &texture_state_, &state_, |
&framebuffer_state_, |
- "glTexSubImage3D", args); |
+ func_name, args); |
// This may be a slow command. Exit command processing to allow for |
// context preemption and GPU watchdog checks. |
@@ -16787,6 +16810,8 @@ error::Error GLES2DecoderImpl::HandleMapBufferRange( |
if (!unsafe_es3_apis_enabled()) { |
return error::kUnknownCommand; |
} |
+ |
+ const char* func_name = "glMapBufferRange"; |
const volatile gles2::cmds::MapBufferRange& c = |
*static_cast<const volatile gles2::cmds::MapBufferRange*>(cmd_data); |
GLenum target = static_cast<GLenum>(c.target); |
@@ -16794,6 +16819,7 @@ error::Error GLES2DecoderImpl::HandleMapBufferRange( |
GLintptr offset = static_cast<GLintptr>(c.offset); |
GLsizeiptr size = static_cast<GLsizeiptr>(c.size); |
uint32_t data_shm_id = static_cast<uint32_t>(c.data_shm_id); |
+ uint32_t data_shm_offset = static_cast<uint32_t>(c.data_shm_offset); |
typedef cmds::MapBufferRange::Result Result; |
Result* result = GetSharedMemoryAs<Result*>( |
@@ -16806,13 +16832,13 @@ error::Error GLES2DecoderImpl::HandleMapBufferRange( |
return error::kInvalidArguments; |
} |
int8_t* mem = |
- GetSharedMemoryAs<int8_t*>(data_shm_id, c.data_shm_offset, size); |
+ GetSharedMemoryAs<int8_t*>(data_shm_id, data_shm_offset, size); |
if (!mem) { |
return error::kOutOfBounds; |
} |
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; |
} |
@@ -16827,8 +16853,8 @@ error::Error GLES2DecoderImpl::HandleMapBufferRange( |
// undefined behaviors. |
mask = GL_MAP_READ_BIT | GL_MAP_UNSYNCHRONIZED_BIT; |
if ((access & mask) == mask) { |
- LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "MapBufferRange", |
- "incompatible access bits"); |
+ LOCAL_SET_GL_ERROR( |
+ GL_INVALID_OPERATION, func_name, "incompatible access bits"); |
return error::kNoError; |
} |
access = (access & ~GL_MAP_UNSYNCHRONIZED_BIT); |
@@ -16838,13 +16864,16 @@ error::Error GLES2DecoderImpl::HandleMapBufferRange( |
} |
Buffer* buffer = buffer_manager()->GetBufferInfoForTarget(&state_, target); |
if (!buffer) { |
- LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "MapBufferRange", |
- "no buffer bound to target"); |
+ LOCAL_SET_GL_ERROR( |
+ GL_INVALID_OPERATION, func_name, "no buffer bound to target"); |
return error::kNoError; |
} |
+ if (buffer->GetMappedRange()) { |
+ LOCAL_SET_GL_ERROR( |
+ GL_INVALID_OPERATION, func_name, "buffer is already mapped"); |
+ } |
if (!buffer->CheckRange(offset, size)) { |
- LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "MapBufferRange", |
- "invalid range"); |
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "invalid range"); |
return error::kNoError; |
} |
void* ptr = glMapBufferRange(target, offset, size, access); |
@@ -16852,7 +16881,8 @@ error::Error GLES2DecoderImpl::HandleMapBufferRange( |
return error::kNoError; |
} |
buffer->SetMappedRange(offset, size, access, ptr, |
- GetSharedMemoryBuffer(data_shm_id)); |
+ GetSharedMemoryBuffer(data_shm_id), |
+ static_cast<unsigned int>(data_shm_offset)); |
if ((access & GL_MAP_INVALIDATE_RANGE_BIT) == 0) { |
memcpy(mem, ptr, size); |
} |
@@ -16898,6 +16928,11 @@ error::Error GLES2DecoderImpl::HandleUnmapBuffer( |
} |
DCHECK(mapped_range->pointer); |
memcpy(mapped_range->pointer, mem, mapped_range->size); |
+ if (buffer->shadowed()) { |
+ bool success = buffer->SetRange( |
+ mapped_range->offset, mapped_range->size, mem); |
+ DCHECK(success); |
+ } |
} |
buffer->RemoveMappedRange(); |
GLboolean rt = glUnmapBuffer(target); |