Index: gpu/command_buffer/client/gles2_implementation.cc |
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc |
index 7ef54448b6182b75e13c2295d96cb7d5258334c3..30f92692f9527fc0ea2d7e9c9cb66208d3654040 100644 |
--- a/gpu/command_buffer/client/gles2_implementation.cc |
+++ b/gpu/command_buffer/client/gles2_implementation.cc |
@@ -702,6 +702,15 @@ bool GLES2Implementation::GetHelper(GLenum pname, GLint* params) { |
return true; |
} |
return false; |
+ case GL_MAX_UNIFORM_BUFFER_BINDINGS: |
+ *params = capabilities_.max_uniform_buffer_bindings; |
+ return true; |
+ case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: |
+ *params = capabilities_.max_transform_feedback_separate_attribs; |
+ return true; |
+ case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: |
+ *params = capabilities_.uniform_buffer_offset_alignment; |
+ return true; |
default: |
return false; |
} |
@@ -834,6 +843,13 @@ void GLES2Implementation::ShallowFlushCHROMIUM() { |
// TODO(piman): Add the FreeEverything() logic here. |
} |
+void GLES2Implementation::OrderingBarrierCHROMIUM() { |
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glOrderingBarrierCHROMIUM"); |
+ // Flush command buffer at the GPU channel level. May be implemented as |
+ // Flush(). |
+ helper_->CommandBufferHelper::OrderingBarrier(); |
+} |
+ |
void GLES2Implementation::Finish() { |
GPU_CLIENT_SINGLE_THREAD_CHECK(); |
FinishHelper(); |
@@ -1091,6 +1107,35 @@ GLint GLES2Implementation::GetFragDataLocation( |
return loc; |
} |
+GLuint GLES2Implementation::GetUniformBlockIndexHelper( |
+ GLuint program, const char* name) { |
+ typedef cmds::GetUniformBlockIndex::Result Result; |
+ Result* result = GetResultAs<Result*>(); |
+ if (!result) { |
+ return GL_INVALID_INDEX; |
+ } |
+ *result = GL_INVALID_INDEX; |
+ SetBucketAsCString(kResultBucketId, name); |
+ helper_->GetUniformBlockIndex( |
+ program, kResultBucketId, GetResultShmId(), GetResultShmOffset()); |
+ WaitForCmd(); |
+ helper_->SetBucketSize(kResultBucketId, 0); |
+ return *result; |
+} |
+ |
+GLuint GLES2Implementation::GetUniformBlockIndex( |
+ GLuint program, const char* name) { |
+ GPU_CLIENT_SINGLE_THREAD_CHECK(); |
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetUniformBlockIndex(" |
+ << program << ", " << name << ")"); |
+ TRACE_EVENT0("gpu", "GLES2::GetUniformBlockIndex"); |
+ GLuint index = share_group_->program_info_manager()->GetUniformBlockIndex( |
+ this, program, name); |
+ GPU_CLIENT_LOG("returned " << index); |
+ CheckGLError(); |
+ return index; |
+} |
+ |
void GLES2Implementation::LinkProgram(GLuint program) { |
GPU_CLIENT_SINGLE_THREAD_CHECK(); |
GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glLinkProgram(" << program << ")"); |
@@ -2272,6 +2317,69 @@ void GLES2Implementation::GetActiveUniform( |
CheckGLError(); |
} |
+bool GLES2Implementation::GetActiveUniformBlockNameHelper( |
+ GLuint program, GLuint index, GLsizei bufsize, |
+ GLsizei* length, char* name) { |
+ DCHECK_LE(0, bufsize); |
+ // Clear the bucket so if the command fails nothing will be in it. |
+ helper_->SetBucketSize(kResultBucketId, 0); |
+ typedef cmds::GetActiveUniformBlockName::Result Result; |
+ Result* result = GetResultAs<Result*>(); |
+ if (!result) { |
+ return false; |
+ } |
+ // Set as failed so if the command fails we'll recover. |
+ *result = 0; |
+ helper_->GetActiveUniformBlockName(program, index, kResultBucketId, |
+ GetResultShmId(), GetResultShmOffset()); |
+ WaitForCmd(); |
+ if (*result) { |
+ if (bufsize == 0) { |
+ if (length) { |
+ *length = 0; |
+ } |
+ } else if (length || name) { |
+ std::vector<int8> str; |
+ GetBucketContents(kResultBucketId, &str); |
+ DCHECK(str.size() > 0); |
+ GLsizei max_size = |
+ std::min(bufsize, static_cast<GLsizei>(str.size())) - 1; |
+ if (length) { |
+ *length = max_size; |
+ } |
+ if (name) { |
+ memcpy(name, &str[0], max_size); |
+ name[max_size] = '\0'; |
+ } |
+ } |
+ } |
+ return *result != 0; |
+} |
+ |
+void GLES2Implementation::GetActiveUniformBlockName( |
+ GLuint program, GLuint index, GLsizei bufsize, |
+ GLsizei* length, char* name) { |
+ GPU_CLIENT_SINGLE_THREAD_CHECK(); |
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetActiveUniformBlockName(" |
+ << program << ", " << index << ", " << bufsize << ", " |
+ << static_cast<const void*>(length) << ", " |
+ << static_cast<const void*>(name) << ", "); |
+ if (bufsize < 0) { |
+ SetGLError(GL_INVALID_VALUE, "glGetActiveUniformBlockName", "bufsize < 0"); |
+ return; |
+ } |
+ TRACE_EVENT0("gpu", "GLES2::GetActiveUniformBlockName"); |
+ bool success = |
+ share_group_->program_info_manager()->GetActiveUniformBlockName( |
+ this, program, index, bufsize, length, name); |
+ if (success) { |
+ if (name) { |
+ GPU_CLIENT_LOG(" name: " << name); |
+ } |
+ } |
+ CheckGLError(); |
+} |
+ |
void GLES2Implementation::GetAttachedShaders( |
GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) { |
GPU_CLIENT_SINGLE_THREAD_CHECK(); |
@@ -2638,6 +2746,10 @@ void GLES2Implementation::GenTransformFeedbacksHelper( |
// the old model but possibly not true in the new model if another context has |
// deleted the resource. |
+// NOTE #2: There is a bug in some BindXXXHelpers, that IDs might be marked as |
+// used even when Bind has failed. However, the bug is minor compared to the |
+// overhead & duplicated checking in client side. |
+ |
void GLES2Implementation::BindBufferHelper( |
GLenum target, GLuint buffer_id) { |
// TODO(gman): See note #1 above. |
@@ -2662,8 +2774,7 @@ void GLES2Implementation::BindBufferHelper( |
changed = true; |
break; |
} |
- // TODO(gman): There's a bug here. If the target is invalid the ID will not be |
- // used even though it's marked it as used here. |
+ // TODO(gman): See note #2 above. |
if (changed) { |
GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind( |
this, target, buffer_id, &GLES2Implementation::BindBufferStub); |
@@ -2679,8 +2790,7 @@ void GLES2Implementation::BindBufferStub(GLenum target, GLuint buffer) { |
void GLES2Implementation::BindBufferBaseHelper( |
GLenum target, GLuint index, GLuint buffer_id) { |
// TODO(zmo): See note #1 above. |
- // TODO(zmo): There's a bug here. If the target or index is invalid the ID |
- // will not be used even though it's marked it as used here. |
+ // TODO(zmo): See note #2 above. |
GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind( |
this, target, index, buffer_id, &GLES2Implementation::BindBufferBaseStub); |
} |
@@ -2696,8 +2806,7 @@ void GLES2Implementation::BindBufferRangeHelper( |
GLenum target, GLuint index, GLuint buffer_id, |
GLintptr offset, GLsizeiptr size) { |
// TODO(zmo): See note #1 above. |
- // TODO(zmo): There's a bug here. If an arguments is invalid the ID will not |
- // be used even though it's marked it as used here. |
+ // TODO(zmo): See note #2 above. |
GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind( |
this, target, index, buffer_id, offset, size, |
&GLES2Implementation::BindBufferRangeStub); |
@@ -2777,8 +2886,7 @@ void GLES2Implementation::BindRenderbufferHelper( |
changed = true; |
break; |
} |
- // TODO(gman): There's a bug here. If the target is invalid the ID will not be |
- // used even though it's marked it as used here. |
+ // TODO(zmo): See note #2 above. |
if (changed) { |
GetIdHandler(id_namespaces::kRenderbuffers)->MarkAsUsedForBind( |
this, target, renderbuffer, |
@@ -2827,8 +2935,7 @@ void GLES2Implementation::BindTextureHelper(GLenum target, GLuint texture) { |
changed = true; |
break; |
} |
- // TODO(gman): There's a bug here. If the target is invalid the ID will not be |
- // used. even though it's marked it as used here. |
+ // TODO(gman): See note #2 above. |
if (changed) { |
GetIdHandler(id_namespaces::kTextures)->MarkAsUsedForBind( |
this, target, texture, &GLES2Implementation::BindTextureStub); |
@@ -2847,7 +2954,6 @@ void GLES2Implementation::BindTransformFeedbackHelper( |
} |
void GLES2Implementation::BindVertexArrayOESHelper(GLuint array) { |
- // TODO(gman): See note #1 above. |
bool changed = false; |
if (vertex_array_object_manager_->BindVertexArray(array, &changed)) { |
if (changed) { |
@@ -2878,8 +2984,7 @@ void GLES2Implementation::BindValuebufferCHROMIUMHelper(GLenum target, |
changed = true; |
break; |
} |
- // TODO(gman): There's a bug here. If the target is invalid the ID will not be |
- // used even though it's marked it as used here. |
+ // TODO(gman): See note #2 above. |
if (changed) { |
GetIdHandler(id_namespaces::kValuebuffers)->MarkAsUsedForBind( |
this, target, valuebuffer, |
@@ -3509,6 +3614,47 @@ void GLES2Implementation::GetProgramInfoCHROMIUM( |
memcpy(info, &result[0], result.size()); |
} |
+void GLES2Implementation::GetUniformBlocksCHROMIUMHelper( |
+ GLuint program, std::vector<int8>* result) { |
+ DCHECK(result); |
+ // Clear the bucket so if the command fails nothing will be in it. |
+ helper_->SetBucketSize(kResultBucketId, 0); |
+ helper_->GetUniformBlocksCHROMIUM(program, kResultBucketId); |
+ GetBucketContents(kResultBucketId, result); |
+} |
+ |
+void GLES2Implementation::GetUniformBlocksCHROMIUM( |
+ GLuint program, GLsizei bufsize, GLsizei* size, void* info) { |
+ GPU_CLIENT_SINGLE_THREAD_CHECK(); |
+ if (bufsize < 0) { |
+ SetGLError( |
+ GL_INVALID_VALUE, "glUniformBlocksCHROMIUM", "bufsize less than 0."); |
+ return; |
+ } |
+ if (size == NULL) { |
+ SetGLError(GL_INVALID_VALUE, "glUniformBlocksCHROMIUM", "size is null."); |
+ return; |
+ } |
+ // Make sure they've set size to 0 else the value will be undefined on |
+ // lost context. |
+ DCHECK_EQ(0, *size); |
+ std::vector<int8> result; |
+ GetUniformBlocksCHROMIUMHelper(program, &result); |
+ if (result.empty()) { |
+ return; |
+ } |
+ *size = result.size(); |
+ if (!info) { |
+ return; |
+ } |
+ if (static_cast<size_t>(bufsize) < result.size()) { |
+ SetGLError(GL_INVALID_OPERATION, |
+ "glUniformBlocksCHROMIUM", "bufsize is too small for result."); |
+ return; |
+ } |
+ memcpy(info, &result[0], result.size()); |
+} |
+ |
GLuint GLES2Implementation::CreateStreamTextureCHROMIUM(GLuint texture) { |
GPU_CLIENT_SINGLE_THREAD_CHECK(); |
GPU_CLIENT_LOG("[" << GetLogPrefix() << "] CreateStreamTextureCHROMIUM(" |