| Index: gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| index 465bff8f264d873d76fa8338c8555e8da3d5bbb5..b23e4ab5ea4a25da762e3069b2ef401424c72098 100644
|
| --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| @@ -1064,8 +1064,9 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
|
| // 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.
|
| @@ -4262,30 +4263,48 @@ bool GLES2DecoderImpl::IsDrawValid(GLuint max_vertex_accessed) {
|
| 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 &&
|
| @@ -4303,6 +4322,7 @@ bool GLES2DecoderImpl::SimulateAttrib0(GLuint max_vertex_accessed) {
|
|
|
| glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
|
|
|
| + *simulated = true;
|
| return true;
|
| }
|
|
|
| @@ -4337,8 +4357,13 @@ bool GLES2DecoderImpl::SimulateFixedAttribs(
|
| // 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 =
|
| @@ -4349,10 +4374,9 @@ bool GLES2DecoderImpl::SimulateFixedAttribs(
|
| 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;
|
| @@ -4360,17 +4384,24 @@ bool GLES2DecoderImpl::SimulateFixedAttribs(
|
| }
|
| }
|
|
|
| - 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 > 0x7FFFFFFFF) {
|
| 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
|
| @@ -4440,7 +4471,10 @@ error::Error GLES2DecoderImpl::HandleDrawArrays(
|
|
|
| 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();
|
| @@ -4511,7 +4545,10 @@ error::Error GLES2DecoderImpl::HandleDrawElements(
|
| }
|
|
|
| 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();
|
|
|