Index: gpu/command_buffer/service/gles2_cmd_decoder.cc |
=================================================================== |
--- gpu/command_buffer/service/gles2_cmd_decoder.cc (revision 100614) |
+++ gpu/command_buffer/service/gles2_cmd_decoder.cc (working copy) |
@@ -1056,8 +1056,9 @@ |
// Checks if the current program and vertex attributes are valid for drawing. |
bool IsDrawValid(GLuint max_vertex_accessed); |
- // Returns true if attrib0 was simulated. |
- bool SimulateAttrib0(GLuint max_vertex_accessed); |
+ // Returns true if successful, simulated will be true if attrib0 was |
+ // simulated. |
+ bool SimulateAttrib0(GLuint max_vertex_accessed, bool* simulated); |
void RestoreStateForSimulatedAttrib0(); |
// Returns true if textures were set. |
@@ -4250,30 +4251,48 @@ |
return true; |
} |
-bool GLES2DecoderImpl::SimulateAttrib0(GLuint max_vertex_accessed) { |
+bool GLES2DecoderImpl::SimulateAttrib0( |
+ GLuint max_vertex_accessed, bool* simulated) { |
+ DCHECK(simulated); |
+ *simulated = false; |
+ |
if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) |
- return false; |
+ return true; |
const VertexAttribManager::VertexAttribInfo* info = |
vertex_attrib_manager_.GetVertexAttribInfo(0); |
// If it's enabled or it's not used then we don't need to do anything. |
bool attrib_0_used = current_program_->GetAttribInfoByLocation(0) != NULL; |
if (info->enabled() && attrib_0_used) { |
- return false; |
+ return true; |
} |
+ // Make a buffer with a single repeated vec4 value enough to |
+ // simulate the constant value that is supposed to be here. |
+ // This is required to emulate GLES2 on GL. |
typedef VertexAttribManager::VertexAttribInfo::Vec4 Vec4; |
+ GLuint num_vertices = max_vertex_accessed + 1; |
+ GLuint size_needed = 0; |
+ |
+ if (num_vertices == 0 || |
+ !SafeMultiply(num_vertices, static_cast<GLuint>(sizeof(Vec4)), |
+ &size_needed) || |
+ size_needed > 0x7FFFFFFFU) { |
+ SetGLError(GL_OUT_OF_MEMORY, "glDrawXXX: Simulating attrib 0"); |
+ return false; |
+ } |
+ |
+ CopyRealGLErrorsToWrapper(); |
glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_); |
- // Make a buffer with a single repeated vec4 value enough to |
- // simulate the constant value that is supposed to be here. |
- // This is required to emulate GLES2 on GL. |
- GLsizei num_vertices = max_vertex_accessed + 1; |
- GLsizei size_needed = num_vertices * sizeof(Vec4); // NOLINT |
- if (size_needed > attrib_0_size_) { |
+ if (static_cast<GLsizei>(size_needed) > attrib_0_size_) { |
glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW); |
- // TODO(gman): check for error here? |
+ GLenum error = glGetError(); |
+ if (error != GL_NO_ERROR) { |
+ SetGLError(GL_OUT_OF_MEMORY, "glDrawXXX: Simulating attrib 0"); |
+ return false; |
+ } |
attrib_0_buffer_matches_value_ = false; |
} |
if (attrib_0_used && |
@@ -4291,6 +4310,7 @@ |
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL); |
+ *simulated = true; |
return true; |
} |
@@ -4325,8 +4345,13 @@ |
// tests so we just add to the buffer attrib used. |
// Compute the number of elements needed. |
- int num_vertices = max_vertex_accessed + 1; |
- int elements_needed = 0; |
+ GLuint num_vertices = max_vertex_accessed + 1; |
+ if (num_vertices == 0) { |
+ SetGLError(GL_OUT_OF_MEMORY, "glDrawXXX: Simulating attrib 0"); |
+ return false; |
+ } |
+ |
+ GLuint elements_needed = 0; |
const VertexAttribManager::VertexAttribInfoList& infos = |
vertex_attrib_manager_.GetEnabledVertexAttribInfos(); |
for (VertexAttribManager::VertexAttribInfoList::const_iterator it = |
@@ -4337,10 +4362,9 @@ |
if (attrib_info && |
info->CanAccess(max_vertex_accessed) && |
info->type() == GL_FIXED) { |
- int elements_used = 0; |
- if (!SafeMultiply( |
- static_cast<int>(num_vertices), |
- info->size(), &elements_used) || |
+ GLuint elements_used = 0; |
+ if (!SafeMultiply(num_vertices, |
+ static_cast<GLuint>(info->size()), &elements_used) || |
!SafeAdd(elements_needed, elements_used, &elements_needed)) { |
SetGLError(GL_OUT_OF_MEMORY, "glDrawXXX: simulating GL_FIXED attribs"); |
return false; |
@@ -4348,17 +4372,24 @@ |
} |
} |
- const int kSizeOfFloat = sizeof(float); // NOLINT |
- int size_needed = 0; |
- if (!SafeMultiply(elements_needed, kSizeOfFloat, &size_needed)) { |
+ const GLuint kSizeOfFloat = sizeof(float); // NOLINT |
+ GLuint size_needed = 0; |
+ if (!SafeMultiply(elements_needed, kSizeOfFloat, &size_needed) || |
+ size_needed > 0x7FFFFFFFU) { |
SetGLError(GL_OUT_OF_MEMORY, "glDrawXXX: simulating GL_FIXED attribs"); |
return false; |
} |
+ CopyRealGLErrorsToWrapper(); |
glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_); |
- if (size_needed > fixed_attrib_buffer_size_) { |
+ if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) { |
glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW); |
+ GLenum error = glGetError(); |
+ if (error != GL_NO_ERROR) { |
+ SetGLError(GL_OUT_OF_MEMORY, "glDrawXXX: simulating GL_FIXED attribs"); |
+ return false; |
+ } |
} |
// Copy the elements and convert to float |
@@ -4428,7 +4459,10 @@ |
GLuint max_vertex_accessed = first + count - 1; |
if (IsDrawValid(max_vertex_accessed)) { |
- bool simulated_attrib_0 = SimulateAttrib0(max_vertex_accessed); |
+ bool simulated_attrib_0 = false; |
+ if (!SimulateAttrib0(max_vertex_accessed, &simulated_attrib_0)) { |
+ return error::kNoError; |
+ } |
bool simulated_fixed_attribs = false; |
if (SimulateFixedAttribs(max_vertex_accessed, &simulated_fixed_attribs)) { |
bool textures_set = SetBlackTextureForNonRenderableTextures(); |
@@ -4499,7 +4533,10 @@ |
} |
if (IsDrawValid(max_vertex_accessed)) { |
- bool simulated_attrib_0 = SimulateAttrib0(max_vertex_accessed); |
+ bool simulated_attrib_0 = false; |
+ if (!SimulateAttrib0(max_vertex_accessed, &simulated_attrib_0)) { |
+ return error::kNoError; |
+ } |
bool simulated_fixed_attribs = false; |
if (SimulateFixedAttribs(max_vertex_accessed, &simulated_fixed_attribs)) { |
bool textures_set = SetBlackTextureForNonRenderableTextures(); |