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 BackRenderbuffer::AllocateStorage(const gfx::Size& size,
                                       GLenum format,
                                       GLsizei samples) {
  ScopedGLErrorSuppressor suppressor("BackRenderbuffer::AllocateStorage",
                                     decoder_->error_state_.get());
  ScopedRenderBufferBinder binder(&decoder_->state_,
                                  decoder_->error_state_.get(), id_);

  uint32_t estimated_size = 0;
  if (!decoder_->renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
          size.width(), size.height(), samples, format, &estimated_size)) {
    return false;
  }

  decoder_->RenderbufferStorageMultisampleHelper(GL_RENDERBUFFER, samples,
                                                 format, size.width(),
                                                 size.height(), kDoNotForce);

  bool alpha_channel_needs_clear =
      (format == GL_RGBA || format == GL_RGBA8) &&
      !decoder_->offscreen_buffer_should_have_alpha_;
  if (alpha_channel_needs_clear) {
    GLuint fbo;
    api()->glGenFramebuffersEXTFn(1, &fbo);
    {
      ScopedFramebufferBinder binder(decoder_, fbo);
      api()->glFramebufferRenderbufferEXTFn(
          GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, id_);
      api()->glClearColorFn(0, 0, 0, decoder_->BackBufferAlphaClearColor());
      decoder_->state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
      decoder_->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
      decoder_->ClearDeviceWindowRectangles();
      api()->glClearFn(GL_COLOR_BUFFER_BIT);
      decoder_->RestoreClearState();
    }
    api()->glDeleteFramebuffersEXTFn(1, &fbo);
  }

  bool success = api()->glGetErrorFn() == GL_NO_ERROR;
  if (success) {
    memory_tracker_.TrackMemFree(bytes_allocated_);
    bytes_allocated_ = estimated_size;
    memory_tracker_.TrackMemAlloc(bytes_allocated_);
  }
  return success;
}

bool BackRenderbuffer::AllocateStorage(const gfx::Size& size,
                                       GLenum format,
                                       GLsizei samples) {
  ScopedGLErrorSuppressor suppressor("BackRenderbuffer::AllocateStorage",
                                     decoder_->error_state_.get());
  ScopedRenderBufferBinder binder(&decoder_->state_,
                                  decoder_->error_state_.get(), id_);

  uint32_t estimated_size = 0;
  if (!decoder_->renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
          size.width(), size.height(), samples, format, &estimated_size)) {
    return false;
  }

  decoder_->RenderbufferStorageMultisampleHelper(GL_RENDERBUFFER, samples,
                                                 format, size.width(),
                                                 size.height(), kDoNotForce);

  bool alpha_channel_needs_clear =
      (format == GL_RGBA || format == GL_RGBA8) &&
      !decoder_->offscreen_buffer_should_have_alpha_;
  if (alpha_channel_needs_clear) {
    GLuint fbo;
    api()->glGenFramebuffersEXTFn(1, &fbo);
    {
      ScopedFramebufferBinder binder(decoder_, fbo);
      api()->glFramebufferRenderbufferEXTFn(
          GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, id_);
      api()->glClearColorFn(0, 0, 0, decoder_->BackBufferAlphaClearColor());
      decoder_->state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
      decoder_->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
      decoder_->ClearDeviceWindowRectangles();
      api()->glClearFn(GL_COLOR_BUFFER_BIT);
      decoder_->RestoreClearState();
    }
    api()->glDeleteFramebuffersEXTFn(1, &fbo);
  }

  bool success = api()->glGetErrorFn() == GL_NO_ERROR;
  if (success) {
    memory_tracker_.TrackMemFree(bytes_allocated_);
    bytes_allocated_ = estimated_size;
    memory_tracker_.TrackMemAlloc(bytes_allocated_);
  }
  return success;
}
