| 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 successful, simulated will be true if attrib0 was | 1067 // Returns true if attrib0 was simulated. |
| 1068 // simulated. | 1068 bool SimulateAttrib0(GLuint max_vertex_accessed); |
| 1069 bool SimulateAttrib0(GLuint max_vertex_accessed, bool* simulated); | |
| 1070 void RestoreStateForSimulatedAttrib0(); | 1069 void RestoreStateForSimulatedAttrib0(); |
| 1071 | 1070 |
| 1072 // Returns true if textures were set. | 1071 // Returns true if textures were set. |
| 1073 bool SetBlackTextureForNonRenderableTextures(); | 1072 bool SetBlackTextureForNonRenderableTextures(); |
| 1074 void RestoreStateForNonRenderableTextures(); | 1073 void RestoreStateForNonRenderableTextures(); |
| 1075 | 1074 |
| 1076 // Returns true if GL_FIXED attribs were simulated. | 1075 // Returns true if GL_FIXED attribs were simulated. |
| 1077 bool SimulateFixedAttribs(GLuint max_vertex_accessed, bool* simulated); | 1076 bool SimulateFixedAttribs(GLuint max_vertex_accessed, bool* simulated); |
| 1078 void RestoreStateForSimulatedFixedAttribs(); | 1077 void RestoreStateForSimulatedFixedAttribs(); |
| 1079 | 1078 |
| (...skipping 3176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4256 GL_INVALID_OPERATION, | 4255 GL_INVALID_OPERATION, |
| 4257 "glDrawXXX: attempt to render with no buffer attached to enabled " | 4256 "glDrawXXX: attempt to render with no buffer attached to enabled " |
| 4258 "attrib"); | 4257 "attrib"); |
| 4259 return false; | 4258 return false; |
| 4260 } | 4259 } |
| 4261 } | 4260 } |
| 4262 } | 4261 } |
| 4263 return true; | 4262 return true; |
| 4264 } | 4263 } |
| 4265 | 4264 |
| 4266 bool GLES2DecoderImpl::SimulateAttrib0( | 4265 bool GLES2DecoderImpl::SimulateAttrib0(GLuint max_vertex_accessed) { |
| 4267 GLuint max_vertex_accessed, bool* simulated) { | |
| 4268 DCHECK(simulated); | |
| 4269 *simulated = false; | |
| 4270 | |
| 4271 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) | 4266 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) |
| 4272 return true; | 4267 return false; |
| 4273 | 4268 |
| 4274 const VertexAttribManager::VertexAttribInfo* info = | 4269 const VertexAttribManager::VertexAttribInfo* info = |
| 4275 vertex_attrib_manager_.GetVertexAttribInfo(0); | 4270 vertex_attrib_manager_.GetVertexAttribInfo(0); |
| 4276 // If it's enabled or it's not used then we don't need to do anything. | 4271 // If it's enabled or it's not used then we don't need to do anything. |
| 4277 bool attrib_0_used = current_program_->GetAttribInfoByLocation(0) != NULL; | 4272 bool attrib_0_used = current_program_->GetAttribInfoByLocation(0) != NULL; |
| 4278 if (info->enabled() && attrib_0_used) { | 4273 if (info->enabled() && attrib_0_used) { |
| 4279 return true; | 4274 return false; |
| 4280 } | 4275 } |
| 4281 | 4276 |
| 4277 typedef VertexAttribManager::VertexAttribInfo::Vec4 Vec4; |
| 4278 |
| 4279 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_); |
| 4280 |
| 4282 // Make a buffer with a single repeated vec4 value enough to | 4281 // Make a buffer with a single repeated vec4 value enough to |
| 4283 // simulate the constant value that is supposed to be here. | 4282 // simulate the constant value that is supposed to be here. |
| 4284 // This is required to emulate GLES2 on GL. | 4283 // This is required to emulate GLES2 on GL. |
| 4285 typedef VertexAttribManager::VertexAttribInfo::Vec4 Vec4; | |
| 4286 | |
| 4287 GLsizei num_vertices = max_vertex_accessed + 1; | 4284 GLsizei num_vertices = max_vertex_accessed + 1; |
| 4288 GLsizei size_needed = 0; | 4285 GLsizei size_needed = num_vertices * sizeof(Vec4); // NOLINT |
| 4289 | |
| 4290 if (num_vertices < 0 || !SafeMultiply( | |
| 4291 num_vertices, static_cast<GLsizei>(sizeof(Vec4)), &size_needed)) { | |
| 4292 SetGLError(GL_OUT_OF_MEMORY, "glDrawXXX: Simulating attrib 0"); | |
| 4293 return false; | |
| 4294 } | |
| 4295 | |
| 4296 CopyRealGLErrorsToWrapper(); | |
| 4297 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_); | |
| 4298 | |
| 4299 if (size_needed > attrib_0_size_) { | 4286 if (size_needed > attrib_0_size_) { |
| 4300 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW); | 4287 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW); |
| 4301 GLenum error = glGetError(); | 4288 // TODO(gman): check for error here? |
| 4302 if (error != GL_NO_ERROR) { | |
| 4303 SetGLError(GL_OUT_OF_MEMORY, "glDrawXXX: Simulating attrib 0"); | |
| 4304 return false; | |
| 4305 } | |
| 4306 attrib_0_buffer_matches_value_ = false; | 4289 attrib_0_buffer_matches_value_ = false; |
| 4307 } | 4290 } |
| 4308 if (attrib_0_used && | 4291 if (attrib_0_used && |
| 4309 (!attrib_0_buffer_matches_value_ || | 4292 (!attrib_0_buffer_matches_value_ || |
| 4310 (info->value().v[0] != attrib_0_value_.v[0] || | 4293 (info->value().v[0] != attrib_0_value_.v[0] || |
| 4311 info->value().v[1] != attrib_0_value_.v[1] || | 4294 info->value().v[1] != attrib_0_value_.v[1] || |
| 4312 info->value().v[2] != attrib_0_value_.v[2] || | 4295 info->value().v[2] != attrib_0_value_.v[2] || |
| 4313 info->value().v[3] != attrib_0_value_.v[3]))) { | 4296 info->value().v[3] != attrib_0_value_.v[3]))) { |
| 4314 std::vector<Vec4> temp(num_vertices, info->value()); | 4297 std::vector<Vec4> temp(num_vertices, info->value()); |
| 4315 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]); | 4298 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]); |
| 4316 attrib_0_buffer_matches_value_ = true; | 4299 attrib_0_buffer_matches_value_ = true; |
| 4317 attrib_0_value_ = info->value(); | 4300 attrib_0_value_ = info->value(); |
| 4318 attrib_0_size_ = size_needed; | 4301 attrib_0_size_ = size_needed; |
| 4319 } | 4302 } |
| 4320 | 4303 |
| 4321 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL); | 4304 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL); |
| 4322 | 4305 |
| 4323 *simulated = true; | |
| 4324 return true; | 4306 return true; |
| 4325 } | 4307 } |
| 4326 | 4308 |
| 4327 void GLES2DecoderImpl::RestoreStateForSimulatedAttrib0() { | 4309 void GLES2DecoderImpl::RestoreStateForSimulatedAttrib0() { |
| 4328 const VertexAttribManager::VertexAttribInfo* info = | 4310 const VertexAttribManager::VertexAttribInfo* info = |
| 4329 vertex_attrib_manager_.GetVertexAttribInfo(0); | 4311 vertex_attrib_manager_.GetVertexAttribInfo(0); |
| 4330 const void* ptr = reinterpret_cast<const void*>(info->offset()); | 4312 const void* ptr = reinterpret_cast<const void*>(info->offset()); |
| 4331 BufferManager::BufferInfo* buffer_info = info->buffer(); | 4313 BufferManager::BufferInfo* buffer_info = info->buffer(); |
| 4332 glBindBuffer(GL_ARRAY_BUFFER, buffer_info ? buffer_info->service_id() : 0); | 4314 glBindBuffer(GL_ARRAY_BUFFER, buffer_info ? buffer_info->service_id() : 0); |
| 4333 glVertexAttribPointer( | 4315 glVertexAttribPointer( |
| (...skipping 14 matching lines...) Expand all Loading... |
| 4348 return true; | 4330 return true; |
| 4349 } | 4331 } |
| 4350 | 4332 |
| 4351 // NOTE: we could be smart and try to check if a buffer is used | 4333 // NOTE: we could be smart and try to check if a buffer is used |
| 4352 // twice in 2 different attribs, find the overlapping parts and therefore | 4334 // twice in 2 different attribs, find the overlapping parts and therefore |
| 4353 // duplicate the minimum amount of data but this whole code path is not meant | 4335 // duplicate the minimum amount of data but this whole code path is not meant |
| 4354 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance | 4336 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance |
| 4355 // tests so we just add to the buffer attrib used. | 4337 // tests so we just add to the buffer attrib used. |
| 4356 | 4338 |
| 4357 // Compute the number of elements needed. | 4339 // Compute the number of elements needed. |
| 4358 GLsizei num_vertices = max_vertex_accessed + 1; | 4340 int num_vertices = max_vertex_accessed + 1; |
| 4359 if (num_vertices < 0) { | |
| 4360 SetGLError(GL_OUT_OF_MEMORY, "glDrawXXX: Simulating attrib 0"); | |
| 4361 return false; | |
| 4362 } | |
| 4363 | |
| 4364 int elements_needed = 0; | 4341 int elements_needed = 0; |
| 4365 const VertexAttribManager::VertexAttribInfoList& infos = | 4342 const VertexAttribManager::VertexAttribInfoList& infos = |
| 4366 vertex_attrib_manager_.GetEnabledVertexAttribInfos(); | 4343 vertex_attrib_manager_.GetEnabledVertexAttribInfos(); |
| 4367 for (VertexAttribManager::VertexAttribInfoList::const_iterator it = | 4344 for (VertexAttribManager::VertexAttribInfoList::const_iterator it = |
| 4368 infos.begin(); it != infos.end(); ++it) { | 4345 infos.begin(); it != infos.end(); ++it) { |
| 4369 const VertexAttribManager::VertexAttribInfo* info = *it; | 4346 const VertexAttribManager::VertexAttribInfo* info = *it; |
| 4370 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info = | 4347 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info = |
| 4371 current_program_->GetAttribInfoByLocation(info->index()); | 4348 current_program_->GetAttribInfoByLocation(info->index()); |
| 4372 if (attrib_info && | 4349 if (attrib_info && |
| 4373 info->CanAccess(max_vertex_accessed) && | 4350 info->CanAccess(max_vertex_accessed) && |
| 4374 info->type() == GL_FIXED) { | 4351 info->type() == GL_FIXED) { |
| 4375 int elements_used = 0; | 4352 int elements_used = 0; |
| 4376 if (!SafeMultiply( | 4353 if (!SafeMultiply( |
| 4377 static_cast<int>(num_vertices), | 4354 static_cast<int>(num_vertices), |
| 4378 info->size(), &elements_used) || | 4355 info->size(), &elements_used) || |
| 4379 !SafeAdd(elements_needed, elements_used, &elements_needed)) { | 4356 !SafeAdd(elements_needed, elements_used, &elements_needed)) { |
| 4380 SetGLError(GL_OUT_OF_MEMORY, "glDrawXXX: simulating GL_FIXED attribs"); | 4357 SetGLError(GL_OUT_OF_MEMORY, "glDrawXXX: simulating GL_FIXED attribs"); |
| 4381 return false; | 4358 return false; |
| 4382 } | 4359 } |
| 4383 } | 4360 } |
| 4384 } | 4361 } |
| 4385 | 4362 |
| 4386 const int kSizeOfFloat = sizeof(float); // NOLINT | 4363 const int kSizeOfFloat = sizeof(float); // NOLINT |
| 4387 int size_needed = 0; | 4364 int size_needed = 0; |
| 4388 if (!SafeMultiply(elements_needed, kSizeOfFloat, &size_needed)) { | 4365 if (!SafeMultiply(elements_needed, kSizeOfFloat, &size_needed)) { |
| 4389 SetGLError(GL_OUT_OF_MEMORY, "glDrawXXX: simulating GL_FIXED attribs"); | 4366 SetGLError(GL_OUT_OF_MEMORY, "glDrawXXX: simulating GL_FIXED attribs"); |
| 4390 return false; | 4367 return false; |
| 4391 } | 4368 } |
| 4392 | 4369 |
| 4393 CopyRealGLErrorsToWrapper(); | |
| 4394 | 4370 |
| 4395 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_); | 4371 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_); |
| 4396 if (size_needed > fixed_attrib_buffer_size_) { | 4372 if (size_needed > fixed_attrib_buffer_size_) { |
| 4397 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW); | 4373 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW); |
| 4398 GLenum error = glGetError(); | |
| 4399 if (error != GL_NO_ERROR) { | |
| 4400 SetGLError(GL_OUT_OF_MEMORY, "glDrawXXX: simulating GL_FIXED attribs"); | |
| 4401 return false; | |
| 4402 } | |
| 4403 } | 4374 } |
| 4404 | 4375 |
| 4405 // Copy the elements and convert to float | 4376 // Copy the elements and convert to float |
| 4406 GLintptr offset = 0; | 4377 GLintptr offset = 0; |
| 4407 for (VertexAttribManager::VertexAttribInfoList::const_iterator it = | 4378 for (VertexAttribManager::VertexAttribInfoList::const_iterator it = |
| 4408 infos.begin(); it != infos.end(); ++it) { | 4379 infos.begin(); it != infos.end(); ++it) { |
| 4409 const VertexAttribManager::VertexAttribInfo* info = *it; | 4380 const VertexAttribManager::VertexAttribInfo* info = *it; |
| 4410 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info = | 4381 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info = |
| 4411 current_program_->GetAttribInfoByLocation(info->index()); | 4382 current_program_->GetAttribInfoByLocation(info->index()); |
| 4412 if (attrib_info && | 4383 if (attrib_info && |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4462 SetGLError(GL_INVALID_VALUE, "glDrawArrays: first < 0"); | 4433 SetGLError(GL_INVALID_VALUE, "glDrawArrays: first < 0"); |
| 4463 return error::kNoError; | 4434 return error::kNoError; |
| 4464 } | 4435 } |
| 4465 | 4436 |
| 4466 if (count == 0) { | 4437 if (count == 0) { |
| 4467 return error::kNoError; | 4438 return error::kNoError; |
| 4468 } | 4439 } |
| 4469 | 4440 |
| 4470 GLuint max_vertex_accessed = first + count - 1; | 4441 GLuint max_vertex_accessed = first + count - 1; |
| 4471 if (IsDrawValid(max_vertex_accessed)) { | 4442 if (IsDrawValid(max_vertex_accessed)) { |
| 4472 bool simulated_attrib_0 = false; | 4443 bool simulated_attrib_0 = SimulateAttrib0(max_vertex_accessed); |
| 4473 if (!SimulateAttrib0(max_vertex_accessed, &simulated_attrib_0)) { | |
| 4474 return error::kNoError; | |
| 4475 } | |
| 4476 bool simulated_fixed_attribs = false; | 4444 bool simulated_fixed_attribs = false; |
| 4477 if (SimulateFixedAttribs(max_vertex_accessed, &simulated_fixed_attribs)) { | 4445 if (SimulateFixedAttribs(max_vertex_accessed, &simulated_fixed_attribs)) { |
| 4478 bool textures_set = SetBlackTextureForNonRenderableTextures(); | 4446 bool textures_set = SetBlackTextureForNonRenderableTextures(); |
| 4479 ApplyDirtyState(); | 4447 ApplyDirtyState(); |
| 4480 glDrawArrays(mode, first, count); | 4448 glDrawArrays(mode, first, count); |
| 4481 if (textures_set) { | 4449 if (textures_set) { |
| 4482 RestoreStateForNonRenderableTextures(); | 4450 RestoreStateForNonRenderableTextures(); |
| 4483 } | 4451 } |
| 4484 if (simulated_fixed_attribs) { | 4452 if (simulated_fixed_attribs) { |
| 4485 RestoreStateForSimulatedFixedAttribs(); | 4453 RestoreStateForSimulatedFixedAttribs(); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4536 | 4504 |
| 4537 GLuint max_vertex_accessed; | 4505 GLuint max_vertex_accessed; |
| 4538 if (!bound_element_array_buffer_->GetMaxValueForRange( | 4506 if (!bound_element_array_buffer_->GetMaxValueForRange( |
| 4539 offset, count, type, &max_vertex_accessed)) { | 4507 offset, count, type, &max_vertex_accessed)) { |
| 4540 SetGLError(GL_INVALID_OPERATION, | 4508 SetGLError(GL_INVALID_OPERATION, |
| 4541 "glDrawElements: range out of bounds for buffer"); | 4509 "glDrawElements: range out of bounds for buffer"); |
| 4542 return error::kNoError; | 4510 return error::kNoError; |
| 4543 } | 4511 } |
| 4544 | 4512 |
| 4545 if (IsDrawValid(max_vertex_accessed)) { | 4513 if (IsDrawValid(max_vertex_accessed)) { |
| 4546 bool simulated_attrib_0 = false; | 4514 bool simulated_attrib_0 = SimulateAttrib0(max_vertex_accessed); |
| 4547 if (!SimulateAttrib0(max_vertex_accessed, &simulated_attrib_0)) { | |
| 4548 return error::kNoError; | |
| 4549 } | |
| 4550 bool simulated_fixed_attribs = false; | 4515 bool simulated_fixed_attribs = false; |
| 4551 if (SimulateFixedAttribs(max_vertex_accessed, &simulated_fixed_attribs)) { | 4516 if (SimulateFixedAttribs(max_vertex_accessed, &simulated_fixed_attribs)) { |
| 4552 bool textures_set = SetBlackTextureForNonRenderableTextures(); | 4517 bool textures_set = SetBlackTextureForNonRenderableTextures(); |
| 4553 ApplyDirtyState(); | 4518 ApplyDirtyState(); |
| 4554 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset); | 4519 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset); |
| 4555 glDrawElements(mode, count, type, indices); | 4520 glDrawElements(mode, count, type, indices); |
| 4556 if (textures_set) { | 4521 if (textures_set) { |
| 4557 RestoreStateForNonRenderableTextures(); | 4522 RestoreStateForNonRenderableTextures(); |
| 4558 } | 4523 } |
| 4559 if (simulated_fixed_attribs) { | 4524 if (simulated_fixed_attribs) { |
| (...skipping 2312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6872 return false; | 6837 return false; |
| 6873 } | 6838 } |
| 6874 | 6839 |
| 6875 // Include the auto-generated part of this file. We split this because it means | 6840 // Include the auto-generated part of this file. We split this because it means |
| 6876 // we can easily edit the non-auto generated parts right here in this file | 6841 // we can easily edit the non-auto generated parts right here in this file |
| 6877 // instead of having to edit some template or the code generator. | 6842 // instead of having to edit some template or the code generator. |
| 6878 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 6843 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
| 6879 | 6844 |
| 6880 } // namespace gles2 | 6845 } // namespace gles2 |
| 6881 } // namespace gpu | 6846 } // namespace gpu |
| OLD | NEW |