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( |