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