Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(42)

Side by Side Diff: gpu/command_buffer/service/gles2_cmd_decoder.cc

Issue 7841067: Revert "Revert 100384 - Fix bug in SimulateAttrib0 that did not check for out of memory." (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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.
4285 typedef VertexAttribManager::VertexAttribInfo::Vec4 Vec4;
4286
4284 GLsizei num_vertices = max_vertex_accessed + 1; 4287 GLsizei num_vertices = max_vertex_accessed + 1;
4285 GLsizei size_needed = num_vertices * sizeof(Vec4); // NOLINT 4288 GLsizei size_needed = 0;
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
4286 if (size_needed > attrib_0_size_) { 4299 if (size_needed > attrib_0_size_) {
4287 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW); 4300 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
4288 // TODO(gman): check for error here? 4301 GLenum error = glGetError();
4302 if (error != GL_NO_ERROR) {
4303 SetGLError(GL_OUT_OF_MEMORY, "glDrawXXX: Simulating attrib 0");
4304 return false;
4305 }
4289 attrib_0_buffer_matches_value_ = false; 4306 attrib_0_buffer_matches_value_ = false;
4290 } 4307 }
4291 if (attrib_0_used && 4308 if (attrib_0_used &&
4292 (!attrib_0_buffer_matches_value_ || 4309 (!attrib_0_buffer_matches_value_ ||
4293 (info->value().v[0] != attrib_0_value_.v[0] || 4310 (info->value().v[0] != attrib_0_value_.v[0] ||
4294 info->value().v[1] != attrib_0_value_.v[1] || 4311 info->value().v[1] != attrib_0_value_.v[1] ||
4295 info->value().v[2] != attrib_0_value_.v[2] || 4312 info->value().v[2] != attrib_0_value_.v[2] ||
4296 info->value().v[3] != attrib_0_value_.v[3]))) { 4313 info->value().v[3] != attrib_0_value_.v[3]))) {
4297 std::vector<Vec4> temp(num_vertices, info->value()); 4314 std::vector<Vec4> temp(num_vertices, info->value());
4298 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]); 4315 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
4299 attrib_0_buffer_matches_value_ = true; 4316 attrib_0_buffer_matches_value_ = true;
4300 attrib_0_value_ = info->value(); 4317 attrib_0_value_ = info->value();
4301 attrib_0_size_ = size_needed; 4318 attrib_0_size_ = size_needed;
4302 } 4319 }
4303 4320
4304 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL); 4321 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
4305 4322
4323 *simulated = true;
4306 return true; 4324 return true;
4307 } 4325 }
4308 4326
4309 void GLES2DecoderImpl::RestoreStateForSimulatedAttrib0() { 4327 void GLES2DecoderImpl::RestoreStateForSimulatedAttrib0() {
4310 const VertexAttribManager::VertexAttribInfo* info = 4328 const VertexAttribManager::VertexAttribInfo* info =
4311 vertex_attrib_manager_.GetVertexAttribInfo(0); 4329 vertex_attrib_manager_.GetVertexAttribInfo(0);
4312 const void* ptr = reinterpret_cast<const void*>(info->offset()); 4330 const void* ptr = reinterpret_cast<const void*>(info->offset());
4313 BufferManager::BufferInfo* buffer_info = info->buffer(); 4331 BufferManager::BufferInfo* buffer_info = info->buffer();
4314 glBindBuffer(GL_ARRAY_BUFFER, buffer_info ? buffer_info->service_id() : 0); 4332 glBindBuffer(GL_ARRAY_BUFFER, buffer_info ? buffer_info->service_id() : 0);
4315 glVertexAttribPointer( 4333 glVertexAttribPointer(
(...skipping 14 matching lines...) Expand all
4330 return true; 4348 return true;
4331 } 4349 }
4332 4350
4333 // NOTE: we could be smart and try to check if a buffer is used 4351 // 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 4352 // 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 4353 // 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 4354 // 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. 4355 // tests so we just add to the buffer attrib used.
4338 4356
4339 // Compute the number of elements needed. 4357 // Compute the number of elements needed.
4340 int num_vertices = max_vertex_accessed + 1; 4358 GLsizei 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
4341 int elements_needed = 0; 4364 int elements_needed = 0;
4342 const VertexAttribManager::VertexAttribInfoList& infos = 4365 const VertexAttribManager::VertexAttribInfoList& infos =
4343 vertex_attrib_manager_.GetEnabledVertexAttribInfos(); 4366 vertex_attrib_manager_.GetEnabledVertexAttribInfos();
4344 for (VertexAttribManager::VertexAttribInfoList::const_iterator it = 4367 for (VertexAttribManager::VertexAttribInfoList::const_iterator it =
4345 infos.begin(); it != infos.end(); ++it) { 4368 infos.begin(); it != infos.end(); ++it) {
4346 const VertexAttribManager::VertexAttribInfo* info = *it; 4369 const VertexAttribManager::VertexAttribInfo* info = *it;
4347 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info = 4370 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info =
4348 current_program_->GetAttribInfoByLocation(info->index()); 4371 current_program_->GetAttribInfoByLocation(info->index());
4349 if (attrib_info && 4372 if (attrib_info &&
4350 info->CanAccess(max_vertex_accessed) && 4373 info->CanAccess(max_vertex_accessed) &&
4351 info->type() == GL_FIXED) { 4374 info->type() == GL_FIXED) {
4352 int elements_used = 0; 4375 int elements_used = 0;
4353 if (!SafeMultiply( 4376 if (!SafeMultiply(
4354 static_cast<int>(num_vertices), 4377 static_cast<int>(num_vertices),
4355 info->size(), &elements_used) || 4378 info->size(), &elements_used) ||
4356 !SafeAdd(elements_needed, elements_used, &elements_needed)) { 4379 !SafeAdd(elements_needed, elements_used, &elements_needed)) {
4357 SetGLError(GL_OUT_OF_MEMORY, "glDrawXXX: simulating GL_FIXED attribs"); 4380 SetGLError(GL_OUT_OF_MEMORY, "glDrawXXX: simulating GL_FIXED attribs");
4358 return false; 4381 return false;
4359 } 4382 }
4360 } 4383 }
4361 } 4384 }
4362 4385
4363 const int kSizeOfFloat = sizeof(float); // NOLINT 4386 const int kSizeOfFloat = sizeof(float); // NOLINT
4364 int size_needed = 0; 4387 int size_needed = 0;
4365 if (!SafeMultiply(elements_needed, kSizeOfFloat, &size_needed)) { 4388 if (!SafeMultiply(elements_needed, kSizeOfFloat, &size_needed)) {
4366 SetGLError(GL_OUT_OF_MEMORY, "glDrawXXX: simulating GL_FIXED attribs"); 4389 SetGLError(GL_OUT_OF_MEMORY, "glDrawXXX: simulating GL_FIXED attribs");
4367 return false; 4390 return false;
4368 } 4391 }
4369 4392
4393 CopyRealGLErrorsToWrapper();
4370 4394
4371 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_); 4395 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
4372 if (size_needed > fixed_attrib_buffer_size_) { 4396 if (size_needed > fixed_attrib_buffer_size_) {
4373 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW); 4397 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 }
4374 } 4403 }
4375 4404
4376 // Copy the elements and convert to float 4405 // Copy the elements and convert to float
4377 GLintptr offset = 0; 4406 GLintptr offset = 0;
4378 for (VertexAttribManager::VertexAttribInfoList::const_iterator it = 4407 for (VertexAttribManager::VertexAttribInfoList::const_iterator it =
4379 infos.begin(); it != infos.end(); ++it) { 4408 infos.begin(); it != infos.end(); ++it) {
4380 const VertexAttribManager::VertexAttribInfo* info = *it; 4409 const VertexAttribManager::VertexAttribInfo* info = *it;
4381 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info = 4410 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info =
4382 current_program_->GetAttribInfoByLocation(info->index()); 4411 current_program_->GetAttribInfoByLocation(info->index());
4383 if (attrib_info && 4412 if (attrib_info &&
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
4433 SetGLError(GL_INVALID_VALUE, "glDrawArrays: first < 0"); 4462 SetGLError(GL_INVALID_VALUE, "glDrawArrays: first < 0");
4434 return error::kNoError; 4463 return error::kNoError;
4435 } 4464 }
4436 4465
4437 if (count == 0) { 4466 if (count == 0) {
4438 return error::kNoError; 4467 return error::kNoError;
4439 } 4468 }
4440 4469
4441 GLuint max_vertex_accessed = first + count - 1; 4470 GLuint max_vertex_accessed = first + count - 1;
4442 if (IsDrawValid(max_vertex_accessed)) { 4471 if (IsDrawValid(max_vertex_accessed)) {
4443 bool simulated_attrib_0 = SimulateAttrib0(max_vertex_accessed); 4472 bool simulated_attrib_0 = false;
4473 if (!SimulateAttrib0(max_vertex_accessed, &simulated_attrib_0)) {
4474 return error::kNoError;
4475 }
4444 bool simulated_fixed_attribs = false; 4476 bool simulated_fixed_attribs = false;
4445 if (SimulateFixedAttribs(max_vertex_accessed, &simulated_fixed_attribs)) { 4477 if (SimulateFixedAttribs(max_vertex_accessed, &simulated_fixed_attribs)) {
4446 bool textures_set = SetBlackTextureForNonRenderableTextures(); 4478 bool textures_set = SetBlackTextureForNonRenderableTextures();
4447 ApplyDirtyState(); 4479 ApplyDirtyState();
4448 glDrawArrays(mode, first, count); 4480 glDrawArrays(mode, first, count);
4449 if (textures_set) { 4481 if (textures_set) {
4450 RestoreStateForNonRenderableTextures(); 4482 RestoreStateForNonRenderableTextures();
4451 } 4483 }
4452 if (simulated_fixed_attribs) { 4484 if (simulated_fixed_attribs) {
4453 RestoreStateForSimulatedFixedAttribs(); 4485 RestoreStateForSimulatedFixedAttribs();
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
4504 4536
4505 GLuint max_vertex_accessed; 4537 GLuint max_vertex_accessed;
4506 if (!bound_element_array_buffer_->GetMaxValueForRange( 4538 if (!bound_element_array_buffer_->GetMaxValueForRange(
4507 offset, count, type, &max_vertex_accessed)) { 4539 offset, count, type, &max_vertex_accessed)) {
4508 SetGLError(GL_INVALID_OPERATION, 4540 SetGLError(GL_INVALID_OPERATION,
4509 "glDrawElements: range out of bounds for buffer"); 4541 "glDrawElements: range out of bounds for buffer");
4510 return error::kNoError; 4542 return error::kNoError;
4511 } 4543 }
4512 4544
4513 if (IsDrawValid(max_vertex_accessed)) { 4545 if (IsDrawValid(max_vertex_accessed)) {
4514 bool simulated_attrib_0 = SimulateAttrib0(max_vertex_accessed); 4546 bool simulated_attrib_0 = false;
4547 if (!SimulateAttrib0(max_vertex_accessed, &simulated_attrib_0)) {
4548 return error::kNoError;
4549 }
4515 bool simulated_fixed_attribs = false; 4550 bool simulated_fixed_attribs = false;
4516 if (SimulateFixedAttribs(max_vertex_accessed, &simulated_fixed_attribs)) { 4551 if (SimulateFixedAttribs(max_vertex_accessed, &simulated_fixed_attribs)) {
4517 bool textures_set = SetBlackTextureForNonRenderableTextures(); 4552 bool textures_set = SetBlackTextureForNonRenderableTextures();
4518 ApplyDirtyState(); 4553 ApplyDirtyState();
4519 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset); 4554 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
4520 glDrawElements(mode, count, type, indices); 4555 glDrawElements(mode, count, type, indices);
4521 if (textures_set) { 4556 if (textures_set) {
4522 RestoreStateForNonRenderableTextures(); 4557 RestoreStateForNonRenderableTextures();
4523 } 4558 }
4524 if (simulated_fixed_attribs) { 4559 if (simulated_fixed_attribs) {
(...skipping 2312 matching lines...) Expand 10 before | Expand all | Expand 10 after
6837 return false; 6872 return false;
6838 } 6873 }
6839 6874
6840 // Include the auto-generated part of this file. We split this because it means 6875 // 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 6876 // 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. 6877 // instead of having to edit some template or the code generator.
6843 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" 6878 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
6844 6879
6845 } // namespace gles2 6880 } // namespace gles2
6846 } // namespace gpu 6881 } // namespace gpu
OLDNEW
« no previous file with comments | « no previous file | gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698