| 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 634cb74a949f18d6ae60c66159e02200684b34f6..f6c5916e198bec66ef77b65ba17b3988f8d5858c 100644
|
| --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| @@ -5349,11 +5349,6 @@
|
| buffer = GetBuffer(client_id);
|
| DCHECK(buffer);
|
| }
|
| - if (!buffer_manager()->SetTarget(buffer, target)) {
|
| - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
|
| - "buffer bound to more than 1 target");
|
| - return;
|
| - }
|
| service_id = buffer->service_id();
|
| }
|
| LogClientServiceForInfo(buffer, client_id, function_name);
|
| @@ -5800,7 +5795,6 @@
|
| }
|
| }
|
| transform_feedback->DoBeginTransformFeedback(primitive_mode);
|
| - DCHECK(transform_feedback->active());
|
| }
|
|
|
| void GLES2DecoderImpl::DoEndTransformFeedback() {
|
| @@ -9518,7 +9512,6 @@
|
| ->ValidateBindings(function_name,
|
| this,
|
| feature_info_.get(),
|
| - buffer_manager(),
|
| state_.current_program.get(),
|
| max_vertex_accessed,
|
| instanced,
|
| @@ -9840,18 +9833,19 @@
|
| "vertexAttrib function must match shader attrib type");
|
| return error::kNoError;
|
| }
|
| + if (state_.bound_array_buffer.get() &&
|
| + state_.bound_array_buffer->GetMappedRange()) {
|
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
|
| + "bound ARRAY_BUFFER is mapped");
|
| + return error::kNoError;
|
| + }
|
| }
|
|
|
| base::CheckedNumeric<GLuint> checked_max_vertex = first;
|
| checked_max_vertex += count - 1;
|
| // first and count-1 are both a non-negative int, so their sum fits an
|
| // unsigned int.
|
| - if (!checked_max_vertex.IsValid()) {
|
| - LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
|
| - "first + count overflow");
|
| - return error::kNoError;
|
| - }
|
| - GLuint max_vertex_accessed = checked_max_vertex.ValueOrDefault(0);
|
| + GLuint max_vertex_accessed = checked_max_vertex.ValueOrDie();
|
| if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
|
| if (!ClearUnclearedTextures()) {
|
| LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
|
| @@ -9936,6 +9930,11 @@
|
| error::Error error = WillAccessBoundFramebufferForDraw();
|
| if (error != error::kNoError)
|
| return error;
|
| + if (!state_.vertex_attrib_manager->element_array_buffer()) {
|
| + LOCAL_SET_GL_ERROR(
|
| + GL_INVALID_OPERATION, function_name, "No element array buffer bound");
|
| + return error::kNoError;
|
| + }
|
|
|
| if (count < 0) {
|
| LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
|
| @@ -9955,11 +9954,6 @@
|
| }
|
| if (primcount < 0) {
|
| LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
|
| - return error::kNoError;
|
| - }
|
| - Buffer* element_array_buffer = buffer_manager()->RequestBufferAccess(
|
| - &state_, GL_ELEMENT_ARRAY_BUFFER, function_name);
|
| - if (!element_array_buffer) {
|
| return error::kNoError;
|
| }
|
|
|
| @@ -9985,9 +9979,25 @@
|
| "vertexAttrib function must match shader attrib type");
|
| return error::kNoError;
|
| }
|
| + if (state_.bound_array_buffer.get() &&
|
| + state_.bound_array_buffer->GetMappedRange()) {
|
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
|
| + "bound ARRAY_BUFFER is mapped");
|
| + return error::kNoError;
|
| + }
|
| + if (state_.vertex_attrib_manager->element_array_buffer() &&
|
| + state_.vertex_attrib_manager->element_array_buffer()
|
| + ->GetMappedRange()) {
|
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
|
| + "bound ELEMENT_ARRAY_BUFFER is mapped");
|
| + return error::kNoError;
|
| + }
|
| }
|
|
|
| GLuint max_vertex_accessed;
|
| + Buffer* element_array_buffer =
|
| + state_.vertex_attrib_manager->element_array_buffer();
|
| +
|
| if (!element_array_buffer->GetMaxValueForRange(
|
| offset, count, type,
|
| state_.enable_flags.primitive_restart_fixed_index,
|
| @@ -11082,7 +11092,6 @@
|
|
|
| error::Error GLES2DecoderImpl::HandleReadPixels(uint32_t immediate_data_size,
|
| const volatile void* cmd_data) {
|
| - const char* func_name = "glReadPixels";
|
| const volatile gles2::cmds::ReadPixels& c =
|
| *static_cast<const volatile gles2::cmds::ReadPixels*>(cmd_data);
|
| TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleReadPixels");
|
| @@ -11101,7 +11110,7 @@
|
| uint32_t result_shm_offset = c.result_shm_offset;
|
| GLboolean async = static_cast<GLboolean>(c.async);
|
| if (width < 0 || height < 0) {
|
| - LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "dimensions < 0");
|
| + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
|
| return error::kNoError;
|
| }
|
| typedef cmds::ReadPixels::Result Result;
|
| @@ -11136,34 +11145,38 @@
|
| uint8_t* pixels = nullptr;
|
| Buffer* buffer = state_.bound_pixel_pack_buffer.get();
|
| if (pixels_shm_id == 0) {
|
| - if (!buffer) {
|
| + if (buffer) {
|
| + if (buffer->GetMappedRange()) {
|
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glReadPixels",
|
| + "pixel pack buffer should not be mapped to client memory");
|
| + return error::kNoError;
|
| + }
|
| + uint32_t size = 0;
|
| + if (!SafeAddUint32(pixels_size + skip_size, pixels_shm_offset, &size)) {
|
| + LOCAL_SET_GL_ERROR(
|
| + GL_INVALID_VALUE, "glReadPixels", "size + offset overflow");
|
| + return error::kNoError;
|
| + }
|
| + if (static_cast<uint32_t>(buffer->size()) < size) {
|
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glReadPixels",
|
| + "pixel pack buffer is not large enough");
|
| + return error::kNoError;
|
| + }
|
| + pixels = reinterpret_cast<uint8_t *>(pixels_shm_offset);
|
| + pixels += skip_size;
|
| + } else {
|
| return error::kInvalidArguments;
|
| }
|
| - if (!buffer_manager()->RequestBufferAccess(
|
| - state_.GetErrorState(), buffer, func_name, "pixel pack buffer")) {
|
| - return error::kNoError;
|
| - }
|
| - uint32_t size = 0;
|
| - if (!SafeAddUint32(pixels_size + skip_size, pixels_shm_offset, &size)) {
|
| - LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "size + offset overflow");
|
| - return error::kNoError;
|
| - }
|
| - if (static_cast<uint32_t>(buffer->size()) < size) {
|
| - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glReadPixels",
|
| - "pixel pack buffer is not large enough");
|
| - return error::kNoError;
|
| - }
|
| - pixels = reinterpret_cast<uint8_t *>(pixels_shm_offset);
|
| - pixels += skip_size;
|
| } else {
|
| if (buffer) {
|
| return error::kInvalidArguments;
|
| - }
|
| - DCHECK_EQ(0u, skip_size);
|
| - pixels = GetSharedMemoryAs<uint8_t*>(
|
| - pixels_shm_id, pixels_shm_offset, pixels_size);
|
| - if (!pixels) {
|
| - return error::kOutOfBounds;
|
| + } else {
|
| + DCHECK_EQ(0u, skip_size);
|
| + pixels = GetSharedMemoryAs<uint8_t*>(
|
| + pixels_shm_id, pixels_shm_offset, pixels_size);
|
| + if (!pixels) {
|
| + return error::kOutOfBounds;
|
| + }
|
| }
|
| }
|
|
|
| @@ -11180,21 +11193,22 @@
|
| }
|
|
|
| if (!validators_->read_pixel_format.IsValid(format)) {
|
| - LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, format, "format");
|
| + LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
|
| return error::kNoError;
|
| }
|
| if (!validators_->read_pixel_type.IsValid(type)) {
|
| - LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, type, "type");
|
| - return error::kNoError;
|
| - }
|
| -
|
| - if (!CheckBoundReadFramebufferValid(
|
| - func_name, GL_INVALID_FRAMEBUFFER_OPERATION)) {
|
| + LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + if (!CheckBoundReadFramebufferValid("glReadPixels",
|
| + GL_INVALID_FRAMEBUFFER_OPERATION)) {
|
| return error::kNoError;
|
| }
|
| GLenum src_internal_format = GetBoundReadFramebufferInternalFormat();
|
| if (src_internal_format == 0) {
|
| - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "no valid color image");
|
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glReadPixels",
|
| + "no valid color image");
|
| return error::kNoError;
|
| }
|
| std::vector<GLenum> accepted_formats;
|
| @@ -11276,7 +11290,7 @@
|
| }
|
| }
|
| if (!format_type_acceptable) {
|
| - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
|
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glReadPixels",
|
| "format and type incompatible with the current read framebuffer");
|
| return error::kNoError;
|
| }
|
| @@ -11293,11 +11307,12 @@
|
| int32_t max_x;
|
| int32_t max_y;
|
| if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
|
| - LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "dimensions out of range");
|
| - return error::kNoError;
|
| - }
|
| -
|
| - LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(func_name);
|
| + LOCAL_SET_GL_ERROR(
|
| + GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
|
| + return error::kNoError;
|
| + }
|
| +
|
| + LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixels");
|
|
|
| ScopedResolvedFramebufferBinder binder(this, false, true);
|
| GLenum read_format = GetBoundReadFramebufferInternalFormat();
|
| @@ -11400,7 +11415,7 @@
|
| }
|
| }
|
| if (pixels_shm_id != 0) {
|
| - GLenum error = LOCAL_PEEK_GL_ERROR(func_name);
|
| + GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
|
| if (error == GL_NO_ERROR) {
|
| if (result) {
|
| result->success = 1;
|
| @@ -12811,7 +12826,7 @@
|
| reinterpret_cast<GLintptr>(data));
|
| pbo_bytes_required += bytes_required;
|
| if (!pbo_bytes_required.IsValid() ||
|
| - pbo_bytes_required.ValueOrDefault(0) >
|
| + pbo_bytes_required.ValueOrDie() >
|
| state_.bound_pixel_unpack_buffer->size()) {
|
| LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
|
| "pixel unpack buffer is not large enough");
|
| @@ -17240,7 +17255,8 @@
|
| }
|
|
|
| error::Error GLES2DecoderImpl::HandleMapBufferRange(
|
| - uint32_t immediate_data_size, const volatile void* cmd_data) {
|
| + uint32_t immediate_data_size,
|
| + const volatile void* cmd_data) {
|
| if (!unsafe_es3_apis_enabled()) {
|
| return error::kUnknownCommand;
|
| }
|
| @@ -17269,27 +17285,25 @@
|
| 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, 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");
|
| + return error::kNoError;
|
| + }
|
| if (size == 0) {
|
| LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "size is zero");
|
| return error::kNoError;
|
| }
|
| - Buffer* buffer = buffer_manager()->RequestBufferAccess(
|
| - &state_, target, offset, size, func_name);
|
| - if (!buffer) {
|
| - return error::kNoError;
|
| - }
|
| - if (state_.bound_transform_feedback->active() &&
|
| - !state_.bound_transform_feedback->paused()) {
|
| - size_t used_binding_count =
|
| - state_.current_program->effective_transform_feedback_varyings().size();
|
| - if (state_.bound_transform_feedback->UsesBuffer(
|
| - used_binding_count, buffer)) {
|
| - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
|
| - "active transform feedback is using this buffer");
|
| - return error::kNoError;
|
| - }
|
| - }
|
| -
|
| + if (!buffer->CheckRange(offset, size)) {
|
| + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "invalid range");
|
| + return error::kNoError;
|
| + }
|
| int8_t* mem =
|
| GetSharedMemoryAs<int8_t*>(data_shm_id, data_shm_offset, size);
|
| if (!mem) {
|
| @@ -17321,6 +17335,12 @@
|
| !AllBitsSet(access, GL_MAP_WRITE_BIT)) {
|
| LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
|
| "MAP_FLUSH_EXPLICIT_BIT set without MAP_WRITE_BIT");
|
| + return error::kNoError;
|
| + }
|
| + if (target == GL_TRANSFORM_FEEDBACK_BUFFER &&
|
| + state_.bound_transform_feedback->active()) {
|
| + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
|
| + "transform feedback is active");
|
| return error::kNoError;
|
| }
|
| if (AllBitsSet(access, GL_MAP_INVALIDATE_BUFFER_BIT)) {
|
| @@ -17386,7 +17406,9 @@
|
| DCHECK(mapped_range->pointer);
|
| memcpy(mapped_range->pointer, mem, mapped_range->size);
|
| if (buffer->shadowed()) {
|
| - buffer->SetRange(mapped_range->offset, mapped_range->size, mem);
|
| + bool success = buffer->SetRange(
|
| + mapped_range->offset, mapped_range->size, mem);
|
| + DCHECK(success);
|
| }
|
| }
|
| buffer->RemoveMappedRange();
|
| @@ -17443,7 +17465,9 @@
|
| DCHECK(gpu_data);
|
| memcpy(gpu_data + offset, client_data + offset, size);
|
| if (buffer->shadowed()) {
|
| - buffer->SetRange(mapped_range->offset + offset, size, client_data + offset);
|
| + bool success = buffer->SetRange(
|
| + mapped_range->offset + offset, size, client_data + offset);
|
| + DCHECK(success);
|
| }
|
| glFlushMappedBufferRange(target, offset, size);
|
| }
|
| @@ -17830,7 +17854,7 @@
|
| }
|
|
|
| if (!num_coords_expected.IsValid() ||
|
| - num_coords != num_coords_expected.ValueOrDefault(0)) {
|
| + num_coords != num_coords_expected.ValueOrDie()) {
|
| LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName,
|
| "numCoords does not match commands");
|
| return error::kNoError;
|
|
|