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 1348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1359 // -1. If the current program is not valid generates the appropriate GL | 1359 // -1. If the current program is not valid generates the appropriate GL |
1360 // error. Returns true if the current program is in a usable state and | 1360 // error. Returns true if the current program is in a usable state and |
1361 // location is not -1. | 1361 // location is not -1. |
1362 bool CheckCurrentProgramForUniform(GLint location, const char* function_name); | 1362 bool CheckCurrentProgramForUniform(GLint location, const char* function_name); |
1363 | 1363 |
1364 // Checks if the current program samples a texture that is also the color | 1364 // Checks if the current program samples a texture that is also the color |
1365 // image of the current bound framebuffer, i.e., the source and destination | 1365 // image of the current bound framebuffer, i.e., the source and destination |
1366 // of the draw operation are the same. | 1366 // of the draw operation are the same. |
1367 bool CheckDrawingFeedbackLoops(); | 1367 bool CheckDrawingFeedbackLoops(); |
1368 | 1368 |
1369 // Checks if a draw buffer's format and its corresponding fragment shader | |
1370 // output's type are compatible, i.e., a signed integer typed variable is | |
1371 // incompatible with a float or unsigned integer buffer. | |
1372 // If incompaticle, generates an INVALID_OPERATION to avoid undefined buffer | |
1373 // contents and return false. | |
1374 // Otherwise, filter out the draw buffers that are not written to but are not | |
1375 // NONE through DrawBuffers, to be on the safe side; set |adjusted| to true | |
1376 // if such adjustments happen. Return true. | |
1377 bool ValidateAndAdjustDrawBuffers(const char* function_name, bool* adjusted); | |
1378 | |
1369 // Checks if |api_type| is valid for the given uniform | 1379 // Checks if |api_type| is valid for the given uniform |
1370 // If the api type is not valid generates the appropriate GL | 1380 // If the api type is not valid generates the appropriate GL |
1371 // error. Returns true if |api_type| is valid for the uniform | 1381 // error. Returns true if |api_type| is valid for the uniform |
1372 bool CheckUniformForApiType(const Program::UniformInfo* info, | 1382 bool CheckUniformForApiType(const Program::UniformInfo* info, |
1373 const char* function_name, | 1383 const char* function_name, |
1374 Program::UniformApiType api_type); | 1384 Program::UniformApiType api_type); |
1375 | 1385 |
1376 // Gets the type of a uniform for a location in the current program. Sets GL | 1386 // Gets the type of a uniform for a location in the current program. Sets GL |
1377 // errors if the current program is not valid. Returns true if the current | 1387 // errors if the current program is not valid. Returns true if the current |
1378 // program is valid and the location exists. Adjusts count so it | 1388 // program is valid and the location exists. Adjusts count so it |
(...skipping 5710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7089 // TODO(zmo): There is no guarantee that an FBO that is complete on the | 7099 // TODO(zmo): There is no guarantee that an FBO that is complete on the |
7090 // READ attachment will be complete as a DRAW attachment. | 7100 // READ attachment will be complete as a DRAW attachment. |
7091 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, framebuffer->service_id()); | 7101 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, framebuffer->service_id()); |
7092 } | 7102 } |
7093 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false); | 7103 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false); |
7094 glClear(clear_bits); | 7104 glClear(clear_bits); |
7095 } | 7105 } |
7096 | 7106 |
7097 if (cleared_int_renderbuffers || clear_bits) { | 7107 if (cleared_int_renderbuffers || clear_bits) { |
7098 if (reset_draw_buffers) | 7108 if (reset_draw_buffers) |
7099 framebuffer->RestoreDrawBuffersAfterClear(); | 7109 framebuffer->RestoreDrawBuffers(); |
7100 RestoreClearState(); | 7110 RestoreClearState(); |
7101 if (target == GL_READ_FRAMEBUFFER && draw_framebuffer != framebuffer) { | 7111 if (target == GL_READ_FRAMEBUFFER && draw_framebuffer != framebuffer) { |
7102 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() : | 7112 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() : |
7103 GetBackbufferServiceId(); | 7113 GetBackbufferServiceId(); |
7104 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id); | 7114 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id); |
7105 } | 7115 } |
7106 } | 7116 } |
7107 | 7117 |
7108 framebuffer_manager()->MarkAttachmentsAsCleared( | 7118 framebuffer_manager()->MarkAttachmentsAsCleared( |
7109 framebuffer, renderbuffer_manager(), texture_manager()); | 7119 framebuffer, renderbuffer_manager(), texture_manager()); |
(...skipping 909 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8019 TextureUnit& texture_unit = state_.texture_units[texture_unit_index]; | 8029 TextureUnit& texture_unit = state_.texture_units[texture_unit_index]; |
8020 TextureRef* texture_ref = | 8030 TextureRef* texture_ref = |
8021 texture_unit.GetInfoForSamplerType(uniform_info->type).get(); | 8031 texture_unit.GetInfoForSamplerType(uniform_info->type).get(); |
8022 if (attachment->IsTexture(texture_ref)) | 8032 if (attachment->IsTexture(texture_ref)) |
8023 return true; | 8033 return true; |
8024 } | 8034 } |
8025 } | 8035 } |
8026 return false; | 8036 return false; |
8027 } | 8037 } |
8028 | 8038 |
8039 bool GLES2DecoderImpl::ValidateAndAdjustDrawBuffers( | |
8040 const char* function_name, bool* adjusted) { | |
8041 bool validation = true; | |
8042 bool my_adjusted = false; | |
8043 switch (feature_info_->context_type()) { | |
8044 case CONTEXT_TYPE_OPENGLES2: | |
8045 case CONTEXT_TYPE_WEBGL1: | |
8046 // Int and unsigned int formats are not available in ES2/WebGL1. | |
8047 validation = false; | |
8048 break; | |
8049 default: | |
8050 break; | |
8051 } | |
8052 Framebuffer* framebuffer = framebuffer_state_.bound_draw_framebuffer.get(); | |
8053 if (!state_.current_program.get() || !framebuffer) { | |
8054 return true; | |
8055 } | |
8056 const std::vector<ShaderVariableBaseType>& fragment_output_base_types = | |
8057 state_.current_program->GetFragmentOutputBaseTypes(); | |
8058 const std::vector<ShaderVariableBaseType>& color_attachment_base_types = | |
8059 framebuffer->GetColorAttachmentBaseTypes(); | |
8060 DCHECK_EQ(fragment_output_base_types.size(), | |
8061 color_attachment_base_types.size()); | |
8062 size_t count = color_attachment_base_types.size(); | |
8063 std::unique_ptr<GLenum[]> adjusted_draw_buffers(new GLenum[count]); | |
8064 for (size_t ii = 0; ii < count; ++ii) { | |
8065 adjusted_draw_buffers[ii] = | |
8066 framebuffer->GetDrawBuffer(GL_DRAW_BUFFER0 + ii); | |
8067 if (adjusted_draw_buffers[ii] == GL_NONE) | |
8068 continue; | |
8069 if (fragment_output_base_types[ii] == SHADER_VARIABLE_UNDEFINED_TYPE) { | |
8070 adjusted_draw_buffers[ii] = GL_NONE; | |
Corentin Wallez
2016/07/13 14:50:07
This looks like it will be doing an allocation for
| |
8071 my_adjusted = true; | |
8072 continue; | |
8073 } | |
8074 if (!validation) | |
8075 continue; | |
8076 if (color_attachment_base_types[ii] == SHADER_VARIABLE_UNDEFINED_TYPE) | |
8077 continue; | |
8078 if (fragment_output_base_types[ii] != color_attachment_base_types[ii]) { | |
8079 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, | |
8080 "buffer format and fragment output variable type incompatible"); | |
8081 return false; | |
8082 } | |
8083 } | |
8084 if (my_adjusted) { | |
8085 glDrawBuffersARB(count, adjusted_draw_buffers.get()); | |
8086 } | |
8087 *adjusted = my_adjusted; | |
8088 return true; | |
8089 } | |
8090 | |
8029 bool GLES2DecoderImpl::CheckUniformForApiType( | 8091 bool GLES2DecoderImpl::CheckUniformForApiType( |
8030 const Program::UniformInfo* info, | 8092 const Program::UniformInfo* info, |
8031 const char* function_name, | 8093 const char* function_name, |
8032 Program::UniformApiType api_type) { | 8094 Program::UniformApiType api_type) { |
8033 DCHECK(info); | 8095 DCHECK(info); |
8034 if ((api_type & info->accepts_api_type) == 0) { | 8096 if ((api_type & info->accepts_api_type) == 0) { |
8035 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, | 8097 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, |
8036 "wrong uniform function for type"); | 8098 "wrong uniform function for type"); |
8037 return false; | 8099 return false; |
8038 } | 8100 } |
(...skipping 1007 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9046 if (!SimulateAttrib0( | 9108 if (!SimulateAttrib0( |
9047 function_name, max_vertex_accessed, &simulated_attrib_0)) { | 9109 function_name, max_vertex_accessed, &simulated_attrib_0)) { |
9048 return error::kNoError; | 9110 return error::kNoError; |
9049 } | 9111 } |
9050 bool simulated_fixed_attribs = false; | 9112 bool simulated_fixed_attribs = false; |
9051 if (SimulateFixedAttribs( | 9113 if (SimulateFixedAttribs( |
9052 function_name, max_vertex_accessed, &simulated_fixed_attribs, | 9114 function_name, max_vertex_accessed, &simulated_fixed_attribs, |
9053 primcount)) { | 9115 primcount)) { |
9054 bool textures_set = !PrepareTexturesForRender(); | 9116 bool textures_set = !PrepareTexturesForRender(); |
9055 ApplyDirtyState(); | 9117 ApplyDirtyState(); |
9118 bool adjusted = false; | |
9119 if (!ValidateAndAdjustDrawBuffers(function_name, &adjusted)) { | |
9120 return error::kNoError; | |
9121 } | |
9056 if (!instanced) { | 9122 if (!instanced) { |
9057 glDrawArrays(mode, first, count); | 9123 glDrawArrays(mode, first, count); |
9058 } else { | 9124 } else { |
9059 glDrawArraysInstancedANGLE(mode, first, count, primcount); | 9125 glDrawArraysInstancedANGLE(mode, first, count, primcount); |
9060 } | 9126 } |
9127 if (adjusted) { | |
9128 DCHECK(framebuffer_state_.bound_draw_framebuffer.get()); | |
9129 framebuffer_state_.bound_draw_framebuffer->RestoreDrawBuffers(); | |
9130 } | |
9061 if (textures_set) { | 9131 if (textures_set) { |
9062 RestoreStateForTextures(); | 9132 RestoreStateForTextures(); |
9063 } | 9133 } |
9064 if (simulated_fixed_attribs) { | 9134 if (simulated_fixed_attribs) { |
9065 RestoreStateForSimulatedFixedAttribs(); | 9135 RestoreStateForSimulatedFixedAttribs(); |
9066 } | 9136 } |
9067 } | 9137 } |
9068 if (simulated_attrib_0) { | 9138 if (simulated_attrib_0) { |
9069 // We don't have to restore attrib 0 generic data at the end of this | 9139 // We don't have to restore attrib 0 generic data at the end of this |
9070 // function even if it is simulated. This is because we will simulate | 9140 // function even if it is simulated. This is because we will simulate |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9187 ApplyDirtyState(); | 9257 ApplyDirtyState(); |
9188 // TODO(gman): Refactor to hide these details in BufferManager or | 9258 // TODO(gman): Refactor to hide these details in BufferManager or |
9189 // VertexAttribManager. | 9259 // VertexAttribManager. |
9190 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset); | 9260 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset); |
9191 bool used_client_side_array = false; | 9261 bool used_client_side_array = false; |
9192 if (element_array_buffer->IsClientSideArray()) { | 9262 if (element_array_buffer->IsClientSideArray()) { |
9193 used_client_side_array = true; | 9263 used_client_side_array = true; |
9194 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); | 9264 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); |
9195 indices = element_array_buffer->GetRange(offset, 0); | 9265 indices = element_array_buffer->GetRange(offset, 0); |
9196 } | 9266 } |
9197 | 9267 bool adjusted = false; |
9268 if (!ValidateAndAdjustDrawBuffers(function_name, &adjusted)) { | |
9269 return error::kNoError; | |
9270 } | |
9198 if (state_.enable_flags.primitive_restart_fixed_index && | 9271 if (state_.enable_flags.primitive_restart_fixed_index && |
9199 feature_info_->feature_flags(). | 9272 feature_info_->feature_flags(). |
9200 emulate_primitive_restart_fixed_index) { | 9273 emulate_primitive_restart_fixed_index) { |
9201 glEnable(GL_PRIMITIVE_RESTART); | 9274 glEnable(GL_PRIMITIVE_RESTART); |
9202 buffer_manager()->SetPrimitiveRestartFixedIndexIfNecessary(type); | 9275 buffer_manager()->SetPrimitiveRestartFixedIndexIfNecessary(type); |
9203 } | 9276 } |
9204 | |
9205 if (!instanced) { | 9277 if (!instanced) { |
9206 glDrawElements(mode, count, type, indices); | 9278 glDrawElements(mode, count, type, indices); |
9207 } else { | 9279 } else { |
9208 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount); | 9280 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount); |
9209 } | 9281 } |
9210 if (state_.enable_flags.primitive_restart_fixed_index && | 9282 if (state_.enable_flags.primitive_restart_fixed_index && |
9211 feature_info_->feature_flags(). | 9283 feature_info_->feature_flags(). |
9212 emulate_primitive_restart_fixed_index) { | 9284 emulate_primitive_restart_fixed_index) { |
9213 glDisable(GL_PRIMITIVE_RESTART); | 9285 glDisable(GL_PRIMITIVE_RESTART); |
9214 } | 9286 } |
9215 | 9287 if (adjusted) { |
9288 DCHECK(framebuffer_state_.bound_draw_framebuffer.get()); | |
9289 framebuffer_state_.bound_draw_framebuffer->RestoreDrawBuffers(); | |
9290 } | |
9216 if (used_client_side_array) { | 9291 if (used_client_side_array) { |
9217 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, | 9292 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, |
9218 element_array_buffer->service_id()); | 9293 element_array_buffer->service_id()); |
9219 } | 9294 } |
9220 | |
9221 if (textures_set) { | 9295 if (textures_set) { |
9222 RestoreStateForTextures(); | 9296 RestoreStateForTextures(); |
9223 } | 9297 } |
9224 if (simulated_fixed_attribs) { | 9298 if (simulated_fixed_attribs) { |
9225 RestoreStateForSimulatedFixedAttribs(); | 9299 RestoreStateForSimulatedFixedAttribs(); |
9226 } | 9300 } |
9227 } | 9301 } |
9228 if (simulated_attrib_0) { | 9302 if (simulated_attrib_0) { |
9229 // We don't have to restore attrib 0 generic data at the end of this | 9303 // We don't have to restore attrib 0 generic data at the end of this |
9230 // function even if it is simulated. This is because we will simulate | 9304 // function even if it is simulated. This is because we will simulate |
(...skipping 7875 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
17106 } | 17180 } |
17107 | 17181 |
17108 // Include the auto-generated part of this file. We split this because it means | 17182 // Include the auto-generated part of this file. We split this because it means |
17109 // we can easily edit the non-auto generated parts right here in this file | 17183 // we can easily edit the non-auto generated parts right here in this file |
17110 // instead of having to edit some template or the code generator. | 17184 // instead of having to edit some template or the code generator. |
17111 #include "base/macros.h" | 17185 #include "base/macros.h" |
17112 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 17186 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
17113 | 17187 |
17114 } // namespace gles2 | 17188 } // namespace gles2 |
17115 } // namespace gpu | 17189 } // namespace gpu |
OLD | NEW |