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