OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 <stdio.h> | 7 #include <stdio.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <list> | 10 #include <list> |
(...skipping 1046 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1057 // command. | 1057 // command. |
1058 void CopyRealGLErrorsToWrapper(); | 1058 void CopyRealGLErrorsToWrapper(); |
1059 | 1059 |
1060 // Clear all real GL errors. This is to prevent the client from seeing any | 1060 // Clear all real GL errors. This is to prevent the client from seeing any |
1061 // errors caused by GL calls that it was not responsible for issuing. | 1061 // errors caused by GL calls that it was not responsible for issuing. |
1062 void ClearRealGLErrors(); | 1062 void ClearRealGLErrors(); |
1063 | 1063 |
1064 // Checks if the current program and vertex attributes are valid for drawing. | 1064 // Checks if the current program and vertex attributes are valid for drawing. |
1065 bool IsDrawValid(GLuint max_vertex_accessed); | 1065 bool IsDrawValid(GLuint max_vertex_accessed); |
1066 | 1066 |
1067 // Returns true if attrib0 was simulated. | 1067 // Returns true if successful, simulated will be true if attrib0 was |
1068 bool SimulateAttrib0(GLuint max_vertex_accessed); | 1068 // simulated. |
| 1069 bool SimulateAttrib0(GLuint max_vertex_accessed, bool* simulated); |
1069 void RestoreStateForSimulatedAttrib0(); | 1070 void RestoreStateForSimulatedAttrib0(); |
1070 | 1071 |
1071 // Returns true if textures were set. | 1072 // Returns true if textures were set. |
1072 bool SetBlackTextureForNonRenderableTextures(); | 1073 bool SetBlackTextureForNonRenderableTextures(); |
1073 void RestoreStateForNonRenderableTextures(); | 1074 void RestoreStateForNonRenderableTextures(); |
1074 | 1075 |
1075 // Returns true if GL_FIXED attribs were simulated. | 1076 // Returns true if GL_FIXED attribs were simulated. |
1076 bool SimulateFixedAttribs(GLuint max_vertex_accessed, bool* simulated); | 1077 bool SimulateFixedAttribs(GLuint max_vertex_accessed, bool* simulated); |
1077 void RestoreStateForSimulatedFixedAttribs(); | 1078 void RestoreStateForSimulatedFixedAttribs(); |
1078 | 1079 |
(...skipping 3159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4238 GL_INVALID_OPERATION, | 4239 GL_INVALID_OPERATION, |
4239 "glDrawXXX: attempt to render with no buffer attached to enabled " | 4240 "glDrawXXX: attempt to render with no buffer attached to enabled " |
4240 "attrib"); | 4241 "attrib"); |
4241 return false; | 4242 return false; |
4242 } | 4243 } |
4243 } | 4244 } |
4244 } | 4245 } |
4245 return true; | 4246 return true; |
4246 } | 4247 } |
4247 | 4248 |
4248 bool GLES2DecoderImpl::SimulateAttrib0(GLuint max_vertex_accessed) { | 4249 bool GLES2DecoderImpl::SimulateAttrib0( |
| 4250 GLuint max_vertex_accessed, bool* simulated) { |
| 4251 DCHECK(simulated); |
| 4252 *simulated = false; |
| 4253 |
4249 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) | 4254 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) |
4250 return false; | 4255 return true; |
4251 | 4256 |
4252 const VertexAttribManager::VertexAttribInfo* info = | 4257 const VertexAttribManager::VertexAttribInfo* info = |
4253 vertex_attrib_manager_.GetVertexAttribInfo(0); | 4258 vertex_attrib_manager_.GetVertexAttribInfo(0); |
4254 // If it's enabled or it's not used then we don't need to do anything. | 4259 // If it's enabled or it's not used then we don't need to do anything. |
4255 bool attrib_0_used = current_program_->GetAttribInfoByLocation(0) != NULL; | 4260 bool attrib_0_used = current_program_->GetAttribInfoByLocation(0) != NULL; |
4256 if (info->enabled() && attrib_0_used) { | 4261 if (info->enabled() && attrib_0_used) { |
4257 return false; | 4262 return true; |
4258 } | 4263 } |
4259 | 4264 |
4260 typedef VertexAttribManager::VertexAttribInfo::Vec4 Vec4; | |
4261 | |
4262 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_); | |
4263 | |
4264 // Make a buffer with a single repeated vec4 value enough to | 4265 // Make a buffer with a single repeated vec4 value enough to |
4265 // simulate the constant value that is supposed to be here. | 4266 // simulate the constant value that is supposed to be here. |
4266 // This is required to emulate GLES2 on GL. | 4267 // This is required to emulate GLES2 on GL. |
| 4268 typedef VertexAttribManager::VertexAttribInfo::Vec4 Vec4; |
| 4269 |
4267 GLsizei num_vertices = max_vertex_accessed + 1; | 4270 GLsizei num_vertices = max_vertex_accessed + 1; |
4268 GLsizei size_needed = num_vertices * sizeof(Vec4); // NOLINT | 4271 GLsizei size_needed = 0; |
| 4272 |
| 4273 if (num_vertices < 0 || !SafeMultiply( |
| 4274 num_vertices, static_cast<GLsizei>(sizeof(Vec4)), &size_needed)) { |
| 4275 SetGLError(GL_OUT_OF_MEMORY, "glDrawXXX: Simulating attrib 0"); |
| 4276 return false; |
| 4277 } |
| 4278 |
| 4279 CopyRealGLErrorsToWrapper(); |
| 4280 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_); |
| 4281 |
4269 if (size_needed > attrib_0_size_) { | 4282 if (size_needed > attrib_0_size_) { |
4270 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW); | 4283 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW); |
4271 // TODO(gman): check for error here? | 4284 GLenum error = glGetError(); |
| 4285 if (error != GL_NO_ERROR) { |
| 4286 SetGLError(GL_OUT_OF_MEMORY, "glDrawXXX: Simulating attrib 0"); |
| 4287 return false; |
| 4288 } |
4272 attrib_0_buffer_matches_value_ = false; | 4289 attrib_0_buffer_matches_value_ = false; |
4273 } | 4290 } |
4274 if (attrib_0_used && | 4291 if (attrib_0_used && |
4275 (!attrib_0_buffer_matches_value_ || | 4292 (!attrib_0_buffer_matches_value_ || |
4276 (info->value().v[0] != attrib_0_value_.v[0] || | 4293 (info->value().v[0] != attrib_0_value_.v[0] || |
4277 info->value().v[1] != attrib_0_value_.v[1] || | 4294 info->value().v[1] != attrib_0_value_.v[1] || |
4278 info->value().v[2] != attrib_0_value_.v[2] || | 4295 info->value().v[2] != attrib_0_value_.v[2] || |
4279 info->value().v[3] != attrib_0_value_.v[3]))) { | 4296 info->value().v[3] != attrib_0_value_.v[3]))) { |
4280 std::vector<Vec4> temp(num_vertices, info->value()); | 4297 std::vector<Vec4> temp(num_vertices, info->value()); |
4281 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]); | 4298 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]); |
4282 attrib_0_buffer_matches_value_ = true; | 4299 attrib_0_buffer_matches_value_ = true; |
4283 attrib_0_value_ = info->value(); | 4300 attrib_0_value_ = info->value(); |
4284 attrib_0_size_ = size_needed; | 4301 attrib_0_size_ = size_needed; |
4285 } | 4302 } |
4286 | 4303 |
4287 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL); | 4304 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL); |
4288 | 4305 |
| 4306 *simulated = true; |
4289 return true; | 4307 return true; |
4290 } | 4308 } |
4291 | 4309 |
4292 void GLES2DecoderImpl::RestoreStateForSimulatedAttrib0() { | 4310 void GLES2DecoderImpl::RestoreStateForSimulatedAttrib0() { |
4293 const VertexAttribManager::VertexAttribInfo* info = | 4311 const VertexAttribManager::VertexAttribInfo* info = |
4294 vertex_attrib_manager_.GetVertexAttribInfo(0); | 4312 vertex_attrib_manager_.GetVertexAttribInfo(0); |
4295 const void* ptr = reinterpret_cast<const void*>(info->offset()); | 4313 const void* ptr = reinterpret_cast<const void*>(info->offset()); |
4296 BufferManager::BufferInfo* buffer_info = info->buffer(); | 4314 BufferManager::BufferInfo* buffer_info = info->buffer(); |
4297 glBindBuffer(GL_ARRAY_BUFFER, buffer_info ? buffer_info->service_id() : 0); | 4315 glBindBuffer(GL_ARRAY_BUFFER, buffer_info ? buffer_info->service_id() : 0); |
4298 glVertexAttribPointer( | 4316 glVertexAttribPointer( |
(...skipping 14 matching lines...) Expand all Loading... |
4313 return true; | 4331 return true; |
4314 } | 4332 } |
4315 | 4333 |
4316 // NOTE: we could be smart and try to check if a buffer is used | 4334 // NOTE: we could be smart and try to check if a buffer is used |
4317 // twice in 2 different attribs, find the overlapping parts and therefore | 4335 // twice in 2 different attribs, find the overlapping parts and therefore |
4318 // duplicate the minimum amount of data but this whole code path is not meant | 4336 // duplicate the minimum amount of data but this whole code path is not meant |
4319 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance | 4337 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance |
4320 // tests so we just add to the buffer attrib used. | 4338 // tests so we just add to the buffer attrib used. |
4321 | 4339 |
4322 // Compute the number of elements needed. | 4340 // Compute the number of elements needed. |
4323 int num_vertices = max_vertex_accessed + 1; | 4341 GLsizei num_vertices = max_vertex_accessed + 1; |
| 4342 if (num_vertices < 0) { |
| 4343 SetGLError(GL_OUT_OF_MEMORY, "glDrawXXX: Simulating attrib 0"); |
| 4344 return false; |
| 4345 } |
| 4346 |
4324 int elements_needed = 0; | 4347 int elements_needed = 0; |
4325 const VertexAttribManager::VertexAttribInfoList& infos = | 4348 const VertexAttribManager::VertexAttribInfoList& infos = |
4326 vertex_attrib_manager_.GetEnabledVertexAttribInfos(); | 4349 vertex_attrib_manager_.GetEnabledVertexAttribInfos(); |
4327 for (VertexAttribManager::VertexAttribInfoList::const_iterator it = | 4350 for (VertexAttribManager::VertexAttribInfoList::const_iterator it = |
4328 infos.begin(); it != infos.end(); ++it) { | 4351 infos.begin(); it != infos.end(); ++it) { |
4329 const VertexAttribManager::VertexAttribInfo* info = *it; | 4352 const VertexAttribManager::VertexAttribInfo* info = *it; |
4330 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info = | 4353 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info = |
4331 current_program_->GetAttribInfoByLocation(info->index()); | 4354 current_program_->GetAttribInfoByLocation(info->index()); |
4332 if (attrib_info && | 4355 if (attrib_info && |
4333 info->CanAccess(max_vertex_accessed) && | 4356 info->CanAccess(max_vertex_accessed) && |
4334 info->type() == GL_FIXED) { | 4357 info->type() == GL_FIXED) { |
4335 int elements_used = 0; | 4358 int elements_used = 0; |
4336 if (!SafeMultiply( | 4359 if (!SafeMultiply( |
4337 static_cast<int>(num_vertices), | 4360 static_cast<int>(num_vertices), |
4338 info->size(), &elements_used) || | 4361 info->size(), &elements_used) || |
4339 !SafeAdd(elements_needed, elements_used, &elements_needed)) { | 4362 !SafeAdd(elements_needed, elements_used, &elements_needed)) { |
4340 SetGLError(GL_OUT_OF_MEMORY, "glDrawXXX: simulating GL_FIXED attribs"); | 4363 SetGLError(GL_OUT_OF_MEMORY, "glDrawXXX: simulating GL_FIXED attribs"); |
4341 return false; | 4364 return false; |
4342 } | 4365 } |
4343 } | 4366 } |
4344 } | 4367 } |
4345 | 4368 |
4346 const int kSizeOfFloat = sizeof(float); // NOLINT | 4369 const int kSizeOfFloat = sizeof(float); // NOLINT |
4347 int size_needed = 0; | 4370 int size_needed = 0; |
4348 if (!SafeMultiply(elements_needed, kSizeOfFloat, &size_needed)) { | 4371 if (!SafeMultiply(elements_needed, kSizeOfFloat, &size_needed)) { |
4349 SetGLError(GL_OUT_OF_MEMORY, "glDrawXXX: simulating GL_FIXED attribs"); | 4372 SetGLError(GL_OUT_OF_MEMORY, "glDrawXXX: simulating GL_FIXED attribs"); |
4350 return false; | 4373 return false; |
4351 } | 4374 } |
4352 | 4375 |
| 4376 CopyRealGLErrorsToWrapper(); |
4353 | 4377 |
4354 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_); | 4378 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_); |
4355 if (size_needed > fixed_attrib_buffer_size_) { | 4379 if (size_needed > fixed_attrib_buffer_size_) { |
4356 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW); | 4380 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW); |
| 4381 GLenum error = glGetError(); |
| 4382 if (error != GL_NO_ERROR) { |
| 4383 SetGLError(GL_OUT_OF_MEMORY, "glDrawXXX: simulating GL_FIXED attribs"); |
| 4384 return false; |
| 4385 } |
4357 } | 4386 } |
4358 | 4387 |
4359 // Copy the elements and convert to float | 4388 // Copy the elements and convert to float |
4360 GLintptr offset = 0; | 4389 GLintptr offset = 0; |
4361 for (VertexAttribManager::VertexAttribInfoList::const_iterator it = | 4390 for (VertexAttribManager::VertexAttribInfoList::const_iterator it = |
4362 infos.begin(); it != infos.end(); ++it) { | 4391 infos.begin(); it != infos.end(); ++it) { |
4363 const VertexAttribManager::VertexAttribInfo* info = *it; | 4392 const VertexAttribManager::VertexAttribInfo* info = *it; |
4364 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info = | 4393 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info = |
4365 current_program_->GetAttribInfoByLocation(info->index()); | 4394 current_program_->GetAttribInfoByLocation(info->index()); |
4366 if (attrib_info && | 4395 if (attrib_info && |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4416 SetGLError(GL_INVALID_VALUE, "glDrawArrays: first < 0"); | 4445 SetGLError(GL_INVALID_VALUE, "glDrawArrays: first < 0"); |
4417 return error::kNoError; | 4446 return error::kNoError; |
4418 } | 4447 } |
4419 | 4448 |
4420 if (count == 0) { | 4449 if (count == 0) { |
4421 return error::kNoError; | 4450 return error::kNoError; |
4422 } | 4451 } |
4423 | 4452 |
4424 GLuint max_vertex_accessed = first + count - 1; | 4453 GLuint max_vertex_accessed = first + count - 1; |
4425 if (IsDrawValid(max_vertex_accessed)) { | 4454 if (IsDrawValid(max_vertex_accessed)) { |
4426 bool simulated_attrib_0 = SimulateAttrib0(max_vertex_accessed); | 4455 bool simulated_attrib_0 = false; |
| 4456 if (!SimulateAttrib0(max_vertex_accessed, &simulated_attrib_0)) { |
| 4457 return error::kNoError; |
| 4458 } |
4427 bool simulated_fixed_attribs = false; | 4459 bool simulated_fixed_attribs = false; |
4428 if (SimulateFixedAttribs(max_vertex_accessed, &simulated_fixed_attribs)) { | 4460 if (SimulateFixedAttribs(max_vertex_accessed, &simulated_fixed_attribs)) { |
4429 bool textures_set = SetBlackTextureForNonRenderableTextures(); | 4461 bool textures_set = SetBlackTextureForNonRenderableTextures(); |
4430 ApplyDirtyState(); | 4462 ApplyDirtyState(); |
4431 glDrawArrays(mode, first, count); | 4463 glDrawArrays(mode, first, count); |
4432 if (textures_set) { | 4464 if (textures_set) { |
4433 RestoreStateForNonRenderableTextures(); | 4465 RestoreStateForNonRenderableTextures(); |
4434 } | 4466 } |
4435 if (simulated_fixed_attribs) { | 4467 if (simulated_fixed_attribs) { |
4436 RestoreStateForSimulatedFixedAttribs(); | 4468 RestoreStateForSimulatedFixedAttribs(); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4487 | 4519 |
4488 GLuint max_vertex_accessed; | 4520 GLuint max_vertex_accessed; |
4489 if (!bound_element_array_buffer_->GetMaxValueForRange( | 4521 if (!bound_element_array_buffer_->GetMaxValueForRange( |
4490 offset, count, type, &max_vertex_accessed)) { | 4522 offset, count, type, &max_vertex_accessed)) { |
4491 SetGLError(GL_INVALID_OPERATION, | 4523 SetGLError(GL_INVALID_OPERATION, |
4492 "glDrawElements: range out of bounds for buffer"); | 4524 "glDrawElements: range out of bounds for buffer"); |
4493 return error::kNoError; | 4525 return error::kNoError; |
4494 } | 4526 } |
4495 | 4527 |
4496 if (IsDrawValid(max_vertex_accessed)) { | 4528 if (IsDrawValid(max_vertex_accessed)) { |
4497 bool simulated_attrib_0 = SimulateAttrib0(max_vertex_accessed); | 4529 bool simulated_attrib_0 = false; |
| 4530 if (!SimulateAttrib0(max_vertex_accessed, &simulated_attrib_0)) { |
| 4531 return error::kNoError; |
| 4532 } |
4498 bool simulated_fixed_attribs = false; | 4533 bool simulated_fixed_attribs = false; |
4499 if (SimulateFixedAttribs(max_vertex_accessed, &simulated_fixed_attribs)) { | 4534 if (SimulateFixedAttribs(max_vertex_accessed, &simulated_fixed_attribs)) { |
4500 bool textures_set = SetBlackTextureForNonRenderableTextures(); | 4535 bool textures_set = SetBlackTextureForNonRenderableTextures(); |
4501 ApplyDirtyState(); | 4536 ApplyDirtyState(); |
4502 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset); | 4537 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset); |
4503 glDrawElements(mode, count, type, indices); | 4538 glDrawElements(mode, count, type, indices); |
4504 if (textures_set) { | 4539 if (textures_set) { |
4505 RestoreStateForNonRenderableTextures(); | 4540 RestoreStateForNonRenderableTextures(); |
4506 } | 4541 } |
4507 if (simulated_fixed_attribs) { | 4542 if (simulated_fixed_attribs) { |
(...skipping 2320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6828 return false; | 6863 return false; |
6829 } | 6864 } |
6830 | 6865 |
6831 // Include the auto-generated part of this file. We split this because it means | 6866 // Include the auto-generated part of this file. We split this because it means |
6832 // we can easily edit the non-auto generated parts right here in this file | 6867 // we can easily edit the non-auto generated parts right here in this file |
6833 // instead of having to edit some template or the code generator. | 6868 // instead of having to edit some template or the code generator. |
6834 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 6869 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
6835 | 6870 |
6836 } // namespace gles2 | 6871 } // namespace gles2 |
6837 } // namespace gpu | 6872 } // namespace gpu |
OLD | NEW |