| 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 288d7c98d2da4518d47bed697b79757e2db13dea..2ea2c03222aa6b569acb40100811b762f8b5243f 100644
|
| --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| @@ -573,12 +573,12 @@ class GLES2DecoderImpl : public GLES2Decoder {
|
| }
|
| virtual bool ProcessPendingQueries() OVERRIDE;
|
|
|
| - virtual void SetGLError(GLenum error,
|
| + virtual void SetGLError(unsigned error,
|
| const char* function_name,
|
| - const char* msg);
|
| + const char* msg) OVERRIDE;
|
| virtual void SetGLErrorInvalidEnum(const char* function_name,
|
| - GLenum value,
|
| - const char* label);
|
| + unsigned value,
|
| + const char* label) OVERRIDE;
|
| virtual void SetResizeCallback(
|
| const base::Callback<void(gfx::Size)>& callback) OVERRIDE;
|
|
|
| @@ -1239,6 +1239,10 @@ class GLES2DecoderImpl : public GLES2Decoder {
|
| GLuint DoGetMaxValueInBufferCHROMIUM(
|
| GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
|
|
|
| + // Wrapper for glGetBufferParameteriv.
|
| + void DoGetBufferParameteriv(
|
| + GLenum target, GLenum pname, GLint* params);
|
| +
|
| // Wrapper for glGetProgramiv.
|
| void DoGetProgramiv(
|
| GLuint program_id, GLenum pname, GLint* params);
|
| @@ -4319,6 +4323,24 @@ void GLES2DecoderImpl::DoGetProgramiv(
|
| info->GetProgramiv(pname, params);
|
| }
|
|
|
| +void GLES2DecoderImpl::DoGetBufferParameteriv(
|
| + GLenum target, GLenum pname, GLint* params) {
|
| + Buffer* buffer = GetBufferInfoForTarget(target);
|
| + if (!buffer) {
|
| + return;
|
| + }
|
| + switch (pname) {
|
| + case GL_BUFFER_SIZE:
|
| + *params = buffer->size();
|
| + break;
|
| + case GL_BUFFER_USAGE:
|
| + *params = buffer->usage();
|
| + break;
|
| + default:
|
| + NOTREACHED();
|
| + }
|
| +}
|
| +
|
| void GLES2DecoderImpl::DoBindAttribLocation(
|
| GLuint program, GLuint index, const char* name) {
|
| if (!StringIsValidForGLES(name)) {
|
| @@ -5519,7 +5541,7 @@ GLenum GLES2DecoderImpl::PeekGLError() {
|
| }
|
|
|
| void GLES2DecoderImpl::SetGLError(
|
| - GLenum error, const char* function_name, const char* msg) {
|
| + unsigned error, const char* function_name, const char* msg) {
|
| if (msg) {
|
| last_error_ = msg;
|
| LogMessage(GetLogPrefix() + ": " + std::string("GL ERROR :") +
|
| @@ -5530,7 +5552,7 @@ void GLES2DecoderImpl::SetGLError(
|
| }
|
|
|
| void GLES2DecoderImpl::SetGLErrorInvalidEnum(
|
| - const char* function_name, GLenum value, const char* label) {
|
| + const char* function_name, unsigned value, const char* label) {
|
| SetGLError(GL_INVALID_ENUM, function_name,
|
| (std::string(label) + " was " +
|
| GLES2Util::GetStringEnum(value)).c_str());
|
| @@ -5743,54 +5765,13 @@ bool GLES2DecoderImpl::IsDrawValid(
|
| return false;
|
| }
|
|
|
| - // true if any enabled, used divisor is zero
|
| - bool divisor0 = false;
|
| - // Validate all attribs currently enabled. If they are used by the current
|
| - // program then check that they have enough elements to handle the draw call.
|
| - // If they are not used by the current program check that they have a buffer
|
| - // assigned.
|
| - const VertexAttribManager::VertexAttribInfoList& infos =
|
| - state_.vertex_attrib_manager->GetEnabledVertexAttribInfos();
|
| - for (VertexAttribManager::VertexAttribInfoList::const_iterator it =
|
| - infos.begin(); it != infos.end(); ++it) {
|
| - const VertexAttrib* info = *it;
|
| - const Program::VertexAttrib* attrib_info =
|
| - state_.current_program->GetAttribInfoByLocation(info->index());
|
| - if (attrib_info) {
|
| - divisor0 |= (info->divisor() == 0);
|
| - GLuint count = info->MaxVertexAccessed(primcount, max_vertex_accessed);
|
| - // This attrib is used in the current program.
|
| - if (!info->CanAccess(count)) {
|
| - SetGLError(
|
| - GL_INVALID_OPERATION, function_name,
|
| - (std::string(
|
| - "attempt to access out of range vertices in attribute ") +
|
| - base::IntToString(info->index())).c_str());
|
| - return false;
|
| - }
|
| - } else {
|
| - // This attrib is not used in the current program.
|
| - if (!info->buffer()) {
|
| - SetGLError(
|
| - GL_INVALID_OPERATION, function_name,
|
| - (std::string(
|
| - "attempt to render with no buffer attached to "
|
| - "enabled attribute ") +
|
| - base::IntToString(info->index())).c_str());
|
| - return false;
|
| - }
|
| - }
|
| - }
|
| -
|
| - if (primcount && !divisor0) {
|
| - SetGLError(
|
| - GL_INVALID_OPERATION, function_name,
|
| - "attempt instanced render with all attributes having "
|
| - "non-zero divisors");
|
| - return false;
|
| - }
|
| -
|
| - return true;
|
| + return state_.vertex_attrib_manager->ValidateBindings(
|
| + function_name,
|
| + this,
|
| + feature_info_.get(),
|
| + state_.current_program,
|
| + max_vertex_accessed,
|
| + primcount);
|
| }
|
|
|
| bool GLES2DecoderImpl::SimulateAttrib0(
|
| @@ -6151,8 +6132,11 @@ error::Error GLES2DecoderImpl::DoDrawElements(
|
| }
|
|
|
| GLuint max_vertex_accessed;
|
| - if (!state_.vertex_attrib_manager->element_array_buffer()->
|
| - GetMaxValueForRange(offset, count, type, &max_vertex_accessed)) {
|
| + Buffer* element_array_buffer =
|
| + state_.vertex_attrib_manager->element_array_buffer();
|
| +
|
| + if (!element_array_buffer->GetMaxValueForRange(
|
| + offset, count, type, &max_vertex_accessed)) {
|
| SetGLError(GL_INVALID_OPERATION,
|
| function_name, "range out of bounds for buffer");
|
| return error::kNoError;
|
| @@ -6174,12 +6158,28 @@ error::Error GLES2DecoderImpl::DoDrawElements(
|
| primcount)) {
|
| bool textures_set = SetBlackTextureForNonRenderableTextures();
|
| ApplyDirtyState();
|
| + // REFACTOR BEFORE CHECK IN
|
| const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
|
| + bool used_client_side_array = false;
|
| + if (workarounds().use_client_side_arrays_for_stream_buffers) {
|
| + if (element_array_buffer->usage() == GL_STREAM_DRAW) {
|
| + used_client_side_array = true;
|
| + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
| + indices = element_array_buffer->GetRange(offset, 0);
|
| + }
|
| + }
|
| +
|
| if (!instanced) {
|
| glDrawElements(mode, count, type, indices);
|
| } else {
|
| glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
|
| }
|
| +
|
| + if (used_client_side_array) {
|
| + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
|
| + element_array_buffer->service_id());
|
| + }
|
| +
|
| ProcessPendingQueries();
|
| if (textures_set) {
|
| RestoreStateForNonRenderableTextures();
|
| @@ -7216,14 +7216,19 @@ void GLES2DecoderImpl::DoBufferData(
|
| data = zero.get();
|
| }
|
|
|
| + // TODO(gman): move to buffer manager BEFORE CHECK IN!
|
| CopyRealGLErrorsToWrapper();
|
| - glBufferData(target, size, data, usage);
|
| + if (workarounds().use_client_side_arrays_for_stream_buffers &&
|
| + usage == GL_STREAM_DRAW) {
|
| + glBufferData(target, 0, NULL, GL_STREAM_DRAW);
|
| + } else {
|
| + glBufferData(target, size, data, usage);
|
| + }
|
| GLenum error = PeekGLError();
|
| if (error == GL_NO_ERROR) {
|
| - buffer_manager()->SetInfo(info, size, usage);
|
| - info->SetRange(0, size, data);
|
| + buffer_manager()->SetInfo(info, size, usage, data);
|
| } else {
|
| - buffer_manager()->SetInfo(info, 0, usage);
|
| + buffer_manager()->SetInfo(info, 0, usage, NULL);
|
| }
|
| }
|
|
|
| @@ -7261,16 +7266,21 @@ error::Error GLES2DecoderImpl::HandleBufferDataImmediate(
|
|
|
| void GLES2DecoderImpl::DoBufferSubData(
|
| GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
|
| - Buffer* info = GetBufferInfoForTarget(target);
|
| - if (!info) {
|
| + Buffer* buffer = GetBufferInfoForTarget(target);
|
| + if (!buffer) {
|
| SetGLError(GL_INVALID_VALUE, "glBufferSubData", "unknown buffer");
|
| return;
|
| }
|
| - if (!info->SetRange(offset, size, data)) {
|
| + if (!buffer->SetRange(offset, size, data)) {
|
| SetGLError(GL_INVALID_VALUE, "glBufferSubData", "out of range");
|
| return;
|
| }
|
| - glBufferSubData(target, offset, size, data);
|
| +
|
| + // TODO(gman): move to buffer manager BEFORE CHECKIN!
|
| + if (!(workarounds().use_client_side_arrays_for_stream_buffers &&
|
| + buffer->usage() == GL_STREAM_DRAW)) {
|
| + glBufferSubData(target, offset, size, data);
|
| + }
|
| }
|
|
|
| bool GLES2DecoderImpl::ClearLevel(
|
|
|