Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 8681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8692 if (!framebuffer->ValidateAndAdjustDrawBuffers( | 8692 if (!framebuffer->ValidateAndAdjustDrawBuffers( |
| 8693 fragment_output_type_mask, fragment_output_written_mask)) { | 8693 fragment_output_type_mask, fragment_output_written_mask)) { |
| 8694 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, | 8694 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, |
| 8695 "buffer format and fragment output variable type incompatible"); | 8695 "buffer format and fragment output variable type incompatible"); |
| 8696 return false; | 8696 return false; |
| 8697 } | 8697 } |
| 8698 return true; | 8698 return true; |
| 8699 } | 8699 } |
| 8700 | 8700 |
| 8701 bool GLES2DecoderImpl::ValidateUniformBlockBackings(const char* func_name) { | 8701 bool GLES2DecoderImpl::ValidateUniformBlockBackings(const char* func_name) { |
| 8702 if (feature_info_->IsWebGL1OrES2Context()) { | 8702 DCHECK(feature_info_->IsWebGL1OrES2Context()); |
|
piman
2016/11/01 22:26:39
Did you mean DCHECK(feature_info_->IsWebGL2OrES3Co
Zhenyao Mo
2016/11/01 22:33:40
Right. Thanks for catching this.
Let's see if any
| |
| 8703 // Uniform blocks do not exist in ES2 contexts. | 8703 DCHECK(state_.current_program.get()); |
| 8704 int32_t max_index = -1; | |
| 8705 for (auto info : state_.current_program->uniform_block_size_info()) { | |
| 8706 int32_t index = static_cast<int32_t>(info.binding); | |
| 8707 if (index > max_index) | |
| 8708 max_index = index; | |
| 8709 } | |
| 8710 if (max_index < 0) | |
| 8704 return true; | 8711 return true; |
| 8712 std::vector<GLsizeiptr> uniform_block_sizes(max_index + 1); | |
| 8713 for (int32_t ii = 0; ii <= max_index; ++ii) | |
| 8714 uniform_block_sizes[ii] = 0; | |
| 8715 for (auto info : state_.current_program->uniform_block_size_info()) { | |
| 8716 uint32_t index = info.binding; | |
| 8717 uniform_block_sizes[index] = | |
| 8718 state_.indexed_uniform_buffer_bindings->GetEffectiveBufferSize(index); | |
| 8705 } | 8719 } |
| 8706 DCHECK(state_.current_program.get()); | 8720 return buffer_manager()->RequestBuffersAccess( |
| 8707 for (auto info : state_.current_program->uniform_block_size_info()) { | 8721 state_.GetErrorState(), state_.indexed_uniform_buffer_bindings.get(), |
| 8708 uint32_t buffer_size = static_cast<uint32_t>( | 8722 uniform_block_sizes, 1, func_name, "uniform buffers"); |
| 8709 state_.indexed_uniform_buffer_bindings->GetEffectiveBufferSize( | |
| 8710 info.binding)); | |
| 8711 if (info.data_size > buffer_size) { | |
| 8712 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, | |
| 8713 "uniform blocks are not backed by a buffer with sufficient data"); | |
| 8714 return false; | |
| 8715 } | |
| 8716 } | |
| 8717 return true; | |
| 8718 } | 8723 } |
| 8719 | 8724 |
| 8720 bool GLES2DecoderImpl::CheckUniformForApiType( | 8725 bool GLES2DecoderImpl::CheckUniformForApiType( |
| 8721 const Program::UniformInfo* info, | 8726 const Program::UniformInfo* info, |
| 8722 const char* function_name, | 8727 const char* function_name, |
| 8723 Program::UniformApiType api_type) { | 8728 Program::UniformApiType api_type) { |
| 8724 DCHECK(info); | 8729 DCHECK(info); |
| 8725 if ((api_type & info->accepts_api_type) == 0) { | 8730 if ((api_type & info->accepts_api_type) == 0) { |
| 8726 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, | 8731 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, |
| 8727 "wrong uniform function for type"); | 8732 "wrong uniform function for type"); |
| (...skipping 1090 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9818 if (!buffer_manager()->RequestBuffersAccess( | 9823 if (!buffer_manager()->RequestBuffersAccess( |
| 9819 state_.GetErrorState(), | 9824 state_.GetErrorState(), |
| 9820 state_.bound_transform_feedback.get(), | 9825 state_.bound_transform_feedback.get(), |
| 9821 state_.current_program->GetTransformFeedbackVaryingSizes(), | 9826 state_.current_program->GetTransformFeedbackVaryingSizes(), |
| 9822 count, | 9827 count, |
| 9823 function_name, | 9828 function_name, |
| 9824 "transformfeedback buffers")) { | 9829 "transformfeedback buffers")) { |
| 9825 return error::kNoError; | 9830 return error::kNoError; |
| 9826 } | 9831 } |
| 9827 } | 9832 } |
| 9833 | |
| 9834 if (!ValidateUniformBlockBackings(function_name)) { | |
| 9835 return error::kNoError; | |
| 9836 } | |
| 9828 } | 9837 } |
| 9829 | 9838 |
| 9830 if (count == 0 || primcount == 0) { | 9839 if (count == 0 || primcount == 0) { |
| 9831 LOCAL_RENDER_WARNING("Render count or primcount is 0."); | 9840 LOCAL_RENDER_WARNING("Render count or primcount is 0."); |
| 9832 return error::kNoError; | 9841 return error::kNoError; |
| 9833 } | 9842 } |
| 9834 | 9843 |
| 9835 base::CheckedNumeric<GLuint> checked_max_vertex = first; | 9844 base::CheckedNumeric<GLuint> checked_max_vertex = first; |
| 9836 checked_max_vertex += count - 1; | 9845 checked_max_vertex += count - 1; |
| 9837 // first and count-1 are both a non-negative int, so their sum fits an | 9846 // first and count-1 are both a non-negative int, so their sum fits an |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 9854 } | 9863 } |
| 9855 bool simulated_fixed_attribs = false; | 9864 bool simulated_fixed_attribs = false; |
| 9856 if (SimulateFixedAttribs( | 9865 if (SimulateFixedAttribs( |
| 9857 function_name, max_vertex_accessed, &simulated_fixed_attribs, | 9866 function_name, max_vertex_accessed, &simulated_fixed_attribs, |
| 9858 primcount)) { | 9867 primcount)) { |
| 9859 bool textures_set = !PrepareTexturesForRender(); | 9868 bool textures_set = !PrepareTexturesForRender(); |
| 9860 ApplyDirtyState(); | 9869 ApplyDirtyState(); |
| 9861 if (!ValidateAndAdjustDrawBuffers(function_name)) { | 9870 if (!ValidateAndAdjustDrawBuffers(function_name)) { |
| 9862 return error::kNoError; | 9871 return error::kNoError; |
| 9863 } | 9872 } |
| 9864 if (!ValidateUniformBlockBackings(function_name)) { | |
| 9865 return error::kNoError; | |
| 9866 } | |
| 9867 if (!instanced) { | 9873 if (!instanced) { |
| 9868 glDrawArrays(mode, first, count); | 9874 glDrawArrays(mode, first, count); |
| 9869 } else { | 9875 } else { |
| 9870 glDrawArraysInstancedANGLE(mode, first, count, primcount); | 9876 glDrawArraysInstancedANGLE(mode, first, count, primcount); |
| 9871 } | 9877 } |
| 9872 if (textures_set) { | 9878 if (textures_set) { |
| 9873 RestoreStateForTextures(); | 9879 RestoreStateForTextures(); |
| 9874 } | 9880 } |
| 9875 if (simulated_fixed_attribs) { | 9881 if (simulated_fixed_attribs) { |
| 9876 RestoreStateForSimulatedFixedAttribs(); | 9882 RestoreStateForSimulatedFixedAttribs(); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9958 } | 9964 } |
| 9959 | 9965 |
| 9960 if (state_.bound_transform_feedback.get() && | 9966 if (state_.bound_transform_feedback.get() && |
| 9961 state_.bound_transform_feedback->active() && | 9967 state_.bound_transform_feedback->active() && |
| 9962 !state_.bound_transform_feedback->paused()) { | 9968 !state_.bound_transform_feedback->paused()) { |
| 9963 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, | 9969 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, |
| 9964 "transformfeedback is active and not paused"); | 9970 "transformfeedback is active and not paused"); |
| 9965 return error::kNoError; | 9971 return error::kNoError; |
| 9966 } | 9972 } |
| 9967 | 9973 |
| 9968 if (count == 0 || primcount == 0) { | |
| 9969 return error::kNoError; | |
| 9970 } | |
| 9971 | |
| 9972 if (feature_info_->IsWebGL2OrES3Context()) { | 9974 if (feature_info_->IsWebGL2OrES3Context()) { |
| 9973 if (!AttribsTypeMatch()) { | 9975 if (!AttribsTypeMatch()) { |
| 9974 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, | 9976 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, |
| 9975 "vertexAttrib function must match shader attrib type"); | 9977 "vertexAttrib function must match shader attrib type"); |
| 9976 return error::kNoError; | 9978 return error::kNoError; |
| 9977 } | 9979 } |
| 9980 if (!ValidateUniformBlockBackings(function_name)) { | |
| 9981 return error::kNoError; | |
| 9982 } | |
| 9983 } | |
| 9984 | |
| 9985 if (count == 0 || primcount == 0) { | |
| 9986 return error::kNoError; | |
| 9978 } | 9987 } |
| 9979 | 9988 |
| 9980 GLuint max_vertex_accessed; | 9989 GLuint max_vertex_accessed; |
| 9981 if (!element_array_buffer->GetMaxValueForRange( | 9990 if (!element_array_buffer->GetMaxValueForRange( |
| 9982 offset, count, type, | 9991 offset, count, type, |
| 9983 state_.enable_flags.primitive_restart_fixed_index, | 9992 state_.enable_flags.primitive_restart_fixed_index, |
| 9984 &max_vertex_accessed)) { | 9993 &max_vertex_accessed)) { |
| 9985 LOCAL_SET_GL_ERROR( | 9994 LOCAL_SET_GL_ERROR( |
| 9986 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer"); | 9995 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer"); |
| 9987 return error::kNoError; | 9996 return error::kNoError; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 10008 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset); | 10017 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset); |
| 10009 bool used_client_side_array = false; | 10018 bool used_client_side_array = false; |
| 10010 if (element_array_buffer->IsClientSideArray()) { | 10019 if (element_array_buffer->IsClientSideArray()) { |
| 10011 used_client_side_array = true; | 10020 used_client_side_array = true; |
| 10012 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); | 10021 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); |
| 10013 indices = element_array_buffer->GetRange(offset, 0); | 10022 indices = element_array_buffer->GetRange(offset, 0); |
| 10014 } | 10023 } |
| 10015 if (!ValidateAndAdjustDrawBuffers(function_name)) { | 10024 if (!ValidateAndAdjustDrawBuffers(function_name)) { |
| 10016 return error::kNoError; | 10025 return error::kNoError; |
| 10017 } | 10026 } |
| 10018 if (!ValidateUniformBlockBackings(function_name)) { | |
| 10019 return error::kNoError; | |
| 10020 } | |
| 10021 if (state_.enable_flags.primitive_restart_fixed_index && | 10027 if (state_.enable_flags.primitive_restart_fixed_index && |
| 10022 feature_info_->feature_flags(). | 10028 feature_info_->feature_flags(). |
| 10023 emulate_primitive_restart_fixed_index) { | 10029 emulate_primitive_restart_fixed_index) { |
| 10024 glEnable(GL_PRIMITIVE_RESTART); | 10030 glEnable(GL_PRIMITIVE_RESTART); |
| 10025 buffer_manager()->SetPrimitiveRestartFixedIndexIfNecessary(type); | 10031 buffer_manager()->SetPrimitiveRestartFixedIndexIfNecessary(type); |
| 10026 } | 10032 } |
| 10027 if (!instanced) { | 10033 if (!instanced) { |
| 10028 glDrawElements(mode, count, type, indices); | 10034 glDrawElements(mode, count, type, indices); |
| 10029 } else { | 10035 } else { |
| 10030 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount); | 10036 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount); |
| (...skipping 8739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 18770 } | 18776 } |
| 18771 | 18777 |
| 18772 // Include the auto-generated part of this file. We split this because it means | 18778 // Include the auto-generated part of this file. We split this because it means |
| 18773 // we can easily edit the non-auto generated parts right here in this file | 18779 // we can easily edit the non-auto generated parts right here in this file |
| 18774 // instead of having to edit some template or the code generator. | 18780 // instead of having to edit some template or the code generator. |
| 18775 #include "base/macros.h" | 18781 #include "base/macros.h" |
| 18776 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 18782 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
| 18777 | 18783 |
| 18778 } // namespace gles2 | 18784 } // namespace gles2 |
| 18779 } // namespace gpu | 18785 } // namespace gpu |
| OLD | NEW |