Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(201)

Unified Diff: gpu/command_buffer/service/gles2_cmd_decoder.cc

Issue 2435803004: Initialize buffers before allowing access to them. (Closed)
Patch Set: win failure Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 f6c5916e198bec66ef77b65ba17b3988f8d5858c..634cb74a949f18d6ae60c66159e02200684b34f6 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -5349,6 +5349,11 @@ void GLES2DecoderImpl::BindIndexedBufferImpl(
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);
@@ -5795,6 +5800,7 @@ void GLES2DecoderImpl::DoBeginTransformFeedback(GLenum primitive_mode) {
}
}
transform_feedback->DoBeginTransformFeedback(primitive_mode);
+ DCHECK(transform_feedback->active());
}
void GLES2DecoderImpl::DoEndTransformFeedback() {
@@ -9512,6 +9518,7 @@ bool GLES2DecoderImpl::IsDrawValid(
->ValidateBindings(function_name,
this,
feature_info_.get(),
+ buffer_manager(),
state_.current_program.get(),
max_vertex_accessed,
instanced,
@@ -9833,19 +9840,18 @@ error::Error GLES2DecoderImpl::DoDrawArrays(
"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.
- GLuint max_vertex_accessed = checked_max_vertex.ValueOrDie();
+ 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);
if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
if (!ClearUnclearedTextures()) {
LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
@@ -9930,11 +9936,6 @@ error::Error GLES2DecoderImpl::DoDrawElements(const char* function_name,
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");
@@ -9956,6 +9957,11 @@ error::Error GLES2DecoderImpl::DoDrawElements(const char* function_name,
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;
+ }
if (!CheckBoundDrawFramebufferValid(function_name)) {
return error::kNoError;
@@ -9979,25 +9985,9 @@ error::Error GLES2DecoderImpl::DoDrawElements(const char* function_name,
"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,
@@ -11092,6 +11082,7 @@ void GLES2DecoderImpl::FinishReadPixels(GLsizei width,
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");
@@ -11110,7 +11101,7 @@ error::Error GLES2DecoderImpl::HandleReadPixels(uint32_t immediate_data_size,
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, "glReadPixels", "dimensions < 0");
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "dimensions < 0");
return error::kNoError;
}
typedef cmds::ReadPixels::Result Result;
@@ -11145,38 +11136,34 @@ error::Error GLES2DecoderImpl::HandleReadPixels(uint32_t immediate_data_size,
uint8_t* pixels = nullptr;
Buffer* buffer = state_.bound_pixel_pack_buffer.get();
if (pixels_shm_id == 0) {
- 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 {
+ if (!buffer) {
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;
- } else {
- DCHECK_EQ(0u, skip_size);
- pixels = GetSharedMemoryAs<uint8_t*>(
- pixels_shm_id, pixels_shm_offset, pixels_size);
- if (!pixels) {
- return error::kOutOfBounds;
- }
+ }
+ DCHECK_EQ(0u, skip_size);
+ pixels = GetSharedMemoryAs<uint8_t*>(
+ pixels_shm_id, pixels_shm_offset, pixels_size);
+ if (!pixels) {
+ return error::kOutOfBounds;
}
}
@@ -11193,22 +11180,21 @@ error::Error GLES2DecoderImpl::HandleReadPixels(uint32_t immediate_data_size,
}
if (!validators_->read_pixel_format.IsValid(format)) {
- LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
+ LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, format, "format");
return error::kNoError;
}
if (!validators_->read_pixel_type.IsValid(type)) {
- LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
+ LOCAL_SET_GL_ERROR_INVALID_ENUM(func_name, type, "type");
return error::kNoError;
}
- if (!CheckBoundReadFramebufferValid("glReadPixels",
- GL_INVALID_FRAMEBUFFER_OPERATION)) {
+ if (!CheckBoundReadFramebufferValid(
+ func_name, GL_INVALID_FRAMEBUFFER_OPERATION)) {
return error::kNoError;
}
GLenum src_internal_format = GetBoundReadFramebufferInternalFormat();
if (src_internal_format == 0) {
- LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glReadPixels",
- "no valid color image");
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "no valid color image");
return error::kNoError;
}
std::vector<GLenum> accepted_formats;
@@ -11290,7 +11276,7 @@ error::Error GLES2DecoderImpl::HandleReadPixels(uint32_t immediate_data_size,
}
}
if (!format_type_acceptable) {
- LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glReadPixels",
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
"format and type incompatible with the current read framebuffer");
return error::kNoError;
}
@@ -11307,12 +11293,11 @@ error::Error GLES2DecoderImpl::HandleReadPixels(uint32_t immediate_data_size,
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, "glReadPixels", "dimensions out of range");
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "dimensions out of range");
return error::kNoError;
}
- LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixels");
+ LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(func_name);
ScopedResolvedFramebufferBinder binder(this, false, true);
GLenum read_format = GetBoundReadFramebufferInternalFormat();
@@ -11415,7 +11400,7 @@ error::Error GLES2DecoderImpl::HandleReadPixels(uint32_t immediate_data_size,
}
}
if (pixels_shm_id != 0) {
- GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
+ GLenum error = LOCAL_PEEK_GL_ERROR(func_name);
if (error == GL_NO_ERROR) {
if (result) {
result->success = 1;
@@ -12826,7 +12811,7 @@ bool GLES2DecoderImpl::ValidateCompressedTexFuncData(const char* function_name,
reinterpret_cast<GLintptr>(data));
pbo_bytes_required += bytes_required;
if (!pbo_bytes_required.IsValid() ||
- pbo_bytes_required.ValueOrDie() >
+ pbo_bytes_required.ValueOrDefault(0) >
state_.bound_pixel_unpack_buffer->size()) {
LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
"pixel unpack buffer is not large enough");
@@ -17255,8 +17240,7 @@ error::Error GLES2DecoderImpl::HandleGetInternalformativ(
}
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;
}
@@ -17285,25 +17269,27 @@ error::Error GLES2DecoderImpl::HandleMapBufferRange(
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;
}
- if (!buffer->CheckRange(offset, size)) {
- LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "invalid range");
+ 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;
+ }
+ }
+
int8_t* mem =
GetSharedMemoryAs<int8_t*>(data_shm_id, data_shm_offset, size);
if (!mem) {
@@ -17337,12 +17323,6 @@ error::Error GLES2DecoderImpl::HandleMapBufferRange(
"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)) {
// To be on the safe side, always map GL_MAP_INVALIDATE_BUFFER_BIT to
// GL_MAP_INVALIDATE_RANGE_BIT.
@@ -17406,9 +17386,7 @@ 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->SetRange(mapped_range->offset, mapped_range->size, mem);
}
}
buffer->RemoveMappedRange();
@@ -17465,9 +17443,7 @@ void GLES2DecoderImpl::DoFlushMappedBufferRange(
DCHECK(gpu_data);
memcpy(gpu_data + offset, client_data + offset, size);
if (buffer->shadowed()) {
- bool success = buffer->SetRange(
- mapped_range->offset + offset, size, client_data + offset);
- DCHECK(success);
+ buffer->SetRange(mapped_range->offset + offset, size, client_data + offset);
}
glFlushMappedBufferRange(target, offset, size);
}
@@ -17854,7 +17830,7 @@ error::Error GLES2DecoderImpl::HandlePathCommandsCHROMIUM(
}
if (!num_coords_expected.IsValid() ||
- num_coords != num_coords_expected.ValueOrDie()) {
+ num_coords != num_coords_expected.ValueOrDefault(0)) {
LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName,
"numCoords does not match commands");
return error::kNoError;

Powered by Google App Engine
This is Rietveld 408576698