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

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

Issue 7845017: 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 3159 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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