Add GL_PROGRAM_COMPLETION_QUERY_CHROMIUM

This makes the query of GL_COMPLETION_STATUS_KHR to programs much
cheaper by minimizing the round-trip to the GPU thread.

Bug: 881152, 957001
Change-Id: Iadfa798af29225e752c710ca5c25f50b3dd3101a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1586630
Commit-Queue: Kenneth Russell <kbr@chromium.org>
Reviewed-by: Kentaro Hara <haraken@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#657568}
bool GLES2Implementation::GetActiveUniformsivHelper(GLuint program,
                                                    GLsizei count,
                                                    const GLuint* indices,
                                                    GLenum pname,
                                                    GLint* params) {
  base::CheckedNumeric<uint32_t> bytes = count;
  bytes *= sizeof(GLuint);
  if (!bytes.IsValid()) {
    SetGLError(GL_INVALID_VALUE, "glGetActiveUniformsiv", "count overflow");
    return false;
  }
  SetBucketContents(kResultBucketId, indices, bytes.ValueOrDefault(0));
  typedef cmds::GetActiveUniformsiv::Result Result;
  auto result = GetResultAs<Result>();
  if (!result) {
    return false;
  }
  result->SetNumResults(0);
  helper_->GetActiveUniformsiv(program, kResultBucketId, pname,
                               GetResultShmId(), result.offset());
  WaitForCmd();
  bool success = result->GetNumResults() == count;
  if (success) {
    if (params) {
      result->CopyResult(params);
    }
    GPU_CLIENT_LOG_CODE_BLOCK({
      for (int32_t i = 0; i < result->GetNumResults(); ++i) {
        GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
      }
    });
  }
  helper_->SetBucketSize(kResultBucketId, 0);
  return success;
}

bool GLES2Implementation::GetActiveUniformsivHelper(GLuint program,
                                                    GLsizei count,
                                                    const GLuint* indices,
                                                    GLenum pname,
                                                    GLint* params) {
  base::CheckedNumeric<uint32_t> bytes = count;
  bytes *= sizeof(GLuint);
  if (!bytes.IsValid()) {
    SetGLError(GL_INVALID_VALUE, "glGetActiveUniformsiv", "count overflow");
    return false;
  }
  SetBucketContents(kResultBucketId, indices, bytes.ValueOrDefault(0));
  typedef cmds::GetActiveUniformsiv::Result Result;
  auto result = GetResultAs<Result>();
  if (!result) {
    return false;
  }
  result->SetNumResults(0);
  helper_->GetActiveUniformsiv(program, kResultBucketId, pname,
                               GetResultShmId(), result.offset());
  WaitForCmd();
  bool success = result->GetNumResults() == count;
  if (success) {
    if (params) {
      result->CopyResult(params);
    }
    GPU_CLIENT_LOG_CODE_BLOCK({
      for (int32_t i = 0; i < result->GetNumResults(); ++i) {
        GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
      }
    });
  }
  helper_->SetBucketSize(kResultBucketId, 0);
  return success;
}
