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

Side by Side Diff: gpu/command_buffer/service/gles2_cmd_decoder.cc

Issue 2399113003: Add gl tests to make sure when a buffer is unmapped, all access path generates an INVALID_OPERATION. (Closed)
Patch Set: fix 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 unified diff | Download patch
« no previous file with comments | « gpu/BUILD.gn ('k') | gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
6 6
7 #include <limits.h> 7 #include <limits.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <stdint.h> 9 #include <stdint.h>
10 #include <stdio.h> 10 #include <stdio.h>
(...skipping 3905 matching lines...) Expand 10 before | Expand all | Expand 10 after
3916 } 3916 }
3917 3917
3918 void GLES2DecoderImpl::DeleteBuffersHelper(GLsizei n, 3918 void GLES2DecoderImpl::DeleteBuffersHelper(GLsizei n,
3919 const volatile GLuint* client_ids) { 3919 const volatile GLuint* client_ids) {
3920 for (GLsizei ii = 0; ii < n; ++ii) { 3920 for (GLsizei ii = 0; ii < n; ++ii) {
3921 GLuint client_id = client_ids[ii]; 3921 GLuint client_id = client_ids[ii];
3922 Buffer* buffer = GetBuffer(client_id); 3922 Buffer* buffer = GetBuffer(client_id);
3923 if (buffer && !buffer->IsDeleted()) { 3923 if (buffer && !buffer->IsDeleted()) {
3924 buffer->RemoveMappedRange(); 3924 buffer->RemoveMappedRange();
3925 state_.RemoveBoundBuffer(buffer); 3925 state_.RemoveBoundBuffer(buffer);
3926 transform_feedback_manager_->RemoveBoundBuffer(buffer);
3927 RemoveBuffer(client_id); 3926 RemoveBuffer(client_id);
3928 } 3927 }
3929 } 3928 }
3930 } 3929 }
3931 3930
3932 void GLES2DecoderImpl::DeleteFramebuffersHelper( 3931 void GLES2DecoderImpl::DeleteFramebuffersHelper(
3933 GLsizei n, 3932 GLsizei n,
3934 const volatile GLuint* client_ids) { 3933 const volatile GLuint* client_ids) {
3935 bool supports_separate_framebuffer_binds = 3934 bool supports_separate_framebuffer_binds =
3936 features().chromium_framebuffer_multisample; 3935 features().chromium_framebuffer_multisample;
(...skipping 1758 matching lines...) Expand 10 before | Expand all | Expand 10 after
5695 "currently bound transform feedback is active"); 5694 "currently bound transform feedback is active");
5696 return; 5695 return;
5697 } 5696 }
5698 LogClientServiceForInfo(transform_feedback, client_id, function_name); 5697 LogClientServiceForInfo(transform_feedback, client_id, function_name);
5699 transform_feedback->DoBindTransformFeedback(target); 5698 transform_feedback->DoBindTransformFeedback(target);
5700 state_.bound_transform_feedback = transform_feedback; 5699 state_.bound_transform_feedback = transform_feedback;
5701 } 5700 }
5702 5701
5703 void GLES2DecoderImpl::DoBeginTransformFeedback(GLenum primitive_mode) { 5702 void GLES2DecoderImpl::DoBeginTransformFeedback(GLenum primitive_mode) {
5704 const char* function_name = "glBeginTransformFeedback"; 5703 const char* function_name = "glBeginTransformFeedback";
5705 DCHECK(state_.bound_transform_feedback.get()); 5704 TransformFeedback* transform_feedback = state_.bound_transform_feedback.get();
5706 if (state_.bound_transform_feedback->active()) { 5705 DCHECK(transform_feedback);
5706 if (transform_feedback->active()) {
5707 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, 5707 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
5708 "transform feedback is already active"); 5708 "transform feedback is already active");
5709 return; 5709 return;
5710 } 5710 }
5711 state_.bound_transform_feedback->DoBeginTransformFeedback(primitive_mode); 5711 if (!CheckCurrentProgram(function_name)) {
5712 return;
5713 }
5714 Program* program = state_.current_program.get();
5715 DCHECK(program);
5716 size_t required_buffer_count =
5717 program->effective_transform_feedback_varyings().size();
5718 if (required_buffer_count == 0) {
5719 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
5720 "no active transform feedback varyings");
5721 return;
5722 }
5723 if (required_buffer_count > 1 &&
5724 GL_INTERLEAVED_ATTRIBS ==
5725 program->effective_transform_feedback_buffer_mode()) {
5726 required_buffer_count = 1;
5727 }
5728 for (size_t ii = 0; ii < required_buffer_count; ++ii) {
5729 Buffer* buffer = transform_feedback->GetBufferBinding(ii);
5730 if (!buffer) {
5731 std::string msg = base::StringPrintf("missing buffer bound at index %i",
5732 static_cast<int>(ii));
5733 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, msg.c_str());
5734 return;
5735 }
5736 if (buffer->GetMappedRange()) {
5737 std::string msg = base::StringPrintf(
5738 "bound buffer bound at index %i is mapped", static_cast<int>(ii));
5739 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, msg.c_str());
5740 return;
5741 }
5742 }
5743 transform_feedback->DoBeginTransformFeedback(primitive_mode);
5712 } 5744 }
5713 5745
5714 void GLES2DecoderImpl::DoEndTransformFeedback() { 5746 void GLES2DecoderImpl::DoEndTransformFeedback() {
5715 const char* function_name = "glEndTransformFeedback"; 5747 const char* function_name = "glEndTransformFeedback";
5716 DCHECK(state_.bound_transform_feedback.get()); 5748 DCHECK(state_.bound_transform_feedback.get());
5717 if (!state_.bound_transform_feedback->active()) { 5749 if (!state_.bound_transform_feedback->active()) {
5718 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, 5750 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
5719 "transform feedback is not active"); 5751 "transform feedback is not active");
5720 return; 5752 return;
5721 } 5753 }
(...skipping 3767 matching lines...) Expand 10 before | Expand all | Expand 10 after
9489 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, 9521 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
9490 "mode is not identical with active transformfeedback's primitiveMode"); 9522 "mode is not identical with active transformfeedback's primitiveMode");
9491 return error::kNoError; 9523 return error::kNoError;
9492 } 9524 }
9493 9525
9494 if (count == 0 || primcount == 0) { 9526 if (count == 0 || primcount == 0) {
9495 LOCAL_RENDER_WARNING("Render count or primcount is 0."); 9527 LOCAL_RENDER_WARNING("Render count or primcount is 0.");
9496 return error::kNoError; 9528 return error::kNoError;
9497 } 9529 }
9498 9530
9499 if (feature_info_->IsWebGL2OrES3Context() && !AttribsTypeMatch()) { 9531 if (feature_info_->IsWebGL2OrES3Context()) {
9500 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, 9532 if (!AttribsTypeMatch()) {
9501 "vertexAttrib function must match shader attrib type"); 9533 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
9502 return error::kNoError; 9534 "vertexAttrib function must match shader attrib type");
9535 return error::kNoError;
9536 }
9537 if (state_.bound_array_buffer.get() &&
9538 state_.bound_array_buffer->GetMappedRange()) {
9539 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
9540 "bound ARRAY_BUFFER is mapped");
9541 return error::kNoError;
9542 }
9503 } 9543 }
9504 9544
9505 base::CheckedNumeric<GLuint> checked_max_vertex = first; 9545 base::CheckedNumeric<GLuint> checked_max_vertex = first;
9506 checked_max_vertex += count - 1; 9546 checked_max_vertex += count - 1;
9507 // first and count-1 are both a non-negative int, so their sum fits an 9547 // first and count-1 are both a non-negative int, so their sum fits an
9508 // unsigned int. 9548 // unsigned int.
9509 GLuint max_vertex_accessed = checked_max_vertex.ValueOrDie(); 9549 GLuint max_vertex_accessed = checked_max_vertex.ValueOrDie();
9510 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) { 9550 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
9511 if (!ClearUnclearedTextures()) { 9551 if (!ClearUnclearedTextures()) {
9512 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory"); 9552 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
9627 !state_.bound_transform_feedback->paused()) { 9667 !state_.bound_transform_feedback->paused()) {
9628 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, 9668 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
9629 "transformfeedback is active and not paused"); 9669 "transformfeedback is active and not paused");
9630 return error::kNoError; 9670 return error::kNoError;
9631 } 9671 }
9632 9672
9633 if (count == 0 || primcount == 0) { 9673 if (count == 0 || primcount == 0) {
9634 return error::kNoError; 9674 return error::kNoError;
9635 } 9675 }
9636 9676
9637 if (feature_info_->IsWebGL2OrES3Context() && !AttribsTypeMatch()) { 9677 if (feature_info_->IsWebGL2OrES3Context()) {
9638 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, 9678 if (!AttribsTypeMatch()) {
9639 "vertexAttrib function must match shader attrib type"); 9679 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
9640 return error::kNoError; 9680 "vertexAttrib function must match shader attrib type");
9681 return error::kNoError;
9682 }
9683 if (state_.bound_array_buffer.get() &&
9684 state_.bound_array_buffer->GetMappedRange()) {
9685 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
9686 "bound ARRAY_BUFFER is mapped");
9687 return error::kNoError;
9688 }
9689 if (state_.vertex_attrib_manager->element_array_buffer() &&
9690 state_.vertex_attrib_manager->element_array_buffer()
9691 ->GetMappedRange()) {
9692 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
9693 "bound ELEMENT_ARRAY_BUFFER is mapped");
9694 return error::kNoError;
9695 }
9641 } 9696 }
9642 9697
9643 GLuint max_vertex_accessed; 9698 GLuint max_vertex_accessed;
9644 Buffer* element_array_buffer = 9699 Buffer* element_array_buffer =
9645 state_.vertex_attrib_manager->element_array_buffer(); 9700 state_.vertex_attrib_manager->element_array_buffer();
9646 9701
9647 if (!element_array_buffer->GetMaxValueForRange( 9702 if (!element_array_buffer->GetMaxValueForRange(
9648 offset, count, type, 9703 offset, count, type,
9649 state_.enable_flags.primitive_restart_fixed_index, 9704 state_.enable_flags.primitive_restart_fixed_index,
9650 &max_vertex_accessed)) { 9705 &max_vertex_accessed)) {
(...skipping 7266 matching lines...) Expand 10 before | Expand all | Expand 10 after
16917 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, 16972 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
16918 "Incompatible access bits with MAP_READ_BIT"); 16973 "Incompatible access bits with MAP_READ_BIT");
16919 return error::kNoError; 16974 return error::kNoError;
16920 } 16975 }
16921 if (AllBitsSet(access, GL_MAP_FLUSH_EXPLICIT_BIT) && 16976 if (AllBitsSet(access, GL_MAP_FLUSH_EXPLICIT_BIT) &&
16922 !AllBitsSet(access, GL_MAP_WRITE_BIT)) { 16977 !AllBitsSet(access, GL_MAP_WRITE_BIT)) {
16923 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, 16978 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
16924 "MAP_FLUSH_EXPLICIT_BIT set without MAP_WRITE_BIT"); 16979 "MAP_FLUSH_EXPLICIT_BIT set without MAP_WRITE_BIT");
16925 return error::kNoError; 16980 return error::kNoError;
16926 } 16981 }
16982 if (target == GL_TRANSFORM_FEEDBACK_BUFFER &&
16983 state_.bound_transform_feedback->active()) {
16984 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
16985 "transform feedback is active");
16986 return error::kNoError;
16987 }
16927 if (AllBitsSet(access, GL_MAP_INVALIDATE_BUFFER_BIT)) { 16988 if (AllBitsSet(access, GL_MAP_INVALIDATE_BUFFER_BIT)) {
16928 // To be on the safe side, always map GL_MAP_INVALIDATE_BUFFER_BIT to 16989 // To be on the safe side, always map GL_MAP_INVALIDATE_BUFFER_BIT to
16929 // GL_MAP_INVALIDATE_RANGE_BIT. 16990 // GL_MAP_INVALIDATE_RANGE_BIT.
16930 access = (access & ~GL_MAP_INVALIDATE_BUFFER_BIT); 16991 access = (access & ~GL_MAP_INVALIDATE_BUFFER_BIT);
16931 access = (access | GL_MAP_INVALIDATE_RANGE_BIT); 16992 access = (access | GL_MAP_INVALIDATE_RANGE_BIT);
16932 } 16993 }
16933 // Always filter out GL_MAP_UNSYNCHRONIZED_BIT to get rid of undefined 16994 // Always filter out GL_MAP_UNSYNCHRONIZED_BIT to get rid of undefined
16934 // behaviors. 16995 // behaviors.
16935 access = (access & ~GL_MAP_UNSYNCHRONIZED_BIT); 16996 access = (access & ~GL_MAP_UNSYNCHRONIZED_BIT);
16936 if (AllBitsSet(access, GL_MAP_WRITE_BIT) && 16997 if (AllBitsSet(access, GL_MAP_WRITE_BIT) &&
(...skipping 1309 matching lines...) Expand 10 before | Expand all | Expand 10 after
18246 } 18307 }
18247 18308
18248 // Include the auto-generated part of this file. We split this because it means 18309 // Include the auto-generated part of this file. We split this because it means
18249 // we can easily edit the non-auto generated parts right here in this file 18310 // we can easily edit the non-auto generated parts right here in this file
18250 // instead of having to edit some template or the code generator. 18311 // instead of having to edit some template or the code generator.
18251 #include "base/macros.h" 18312 #include "base/macros.h"
18252 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" 18313 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
18253 18314
18254 } // namespace gles2 18315 } // namespace gles2
18255 } // namespace gpu 18316 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/BUILD.gn ('k') | gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698