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 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 |