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}
void GLES2DecoderImpl::DoFramebufferTextureLayer(
    GLenum target, GLenum attachment, GLuint client_texture_id,
    GLint level, GLint layer) {
  const char* function_name = "glFramebufferTextureLayer";

  TextureRef* texture_ref = nullptr;
  Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
  if (!framebuffer) {
    LOCAL_SET_GL_ERROR(
        GL_INVALID_OPERATION, function_name, "no framebuffer bound.");
    return;
  }
  GLuint service_id = 0;
  GLenum texture_target = 0;
  if (client_texture_id) {
    texture_ref = GetTexture(client_texture_id);
    if (!texture_ref) {
      LOCAL_SET_GL_ERROR(
          GL_INVALID_VALUE, function_name, "unknown texture");
      return;
    }
    service_id = texture_ref->service_id();

    texture_target = texture_ref->texture()->target();
    switch (texture_target) {
      case GL_TEXTURE_3D:
      case GL_TEXTURE_2D_ARRAY:
        break;
      default:
        LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
            "texture is neither TEXTURE_3D nor TEXTURE_2D_ARRAY");
        return;
    }
    if (!texture_manager()->ValidForTarget(texture_target, level,
                                           0, 0, layer)) {
      LOCAL_SET_GL_ERROR(
          GL_INVALID_VALUE, function_name, "invalid level or layer");
      return;
    }
  }
  api()->glFramebufferTextureLayerFn(target, attachment, service_id, level,
                                     layer);
  if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
    framebuffer->AttachTextureLayer(
        GL_DEPTH_ATTACHMENT, texture_ref, texture_target, level, layer);
    framebuffer->AttachTextureLayer(
        GL_STENCIL_ATTACHMENT, texture_ref, texture_target, level, layer);
  } else {
    framebuffer->AttachTextureLayer(
        attachment, texture_ref, texture_target, level, layer);
  }
  if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
    framebuffer_state_.clear_state_dirty = true;
  }
}

void GLES2DecoderImpl::DoFramebufferTextureLayer(
    GLenum target, GLenum attachment, GLuint client_texture_id,
    GLint level, GLint layer) {
  const char* function_name = "glFramebufferTextureLayer";

  TextureRef* texture_ref = nullptr;
  Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
  if (!framebuffer) {
    LOCAL_SET_GL_ERROR(
        GL_INVALID_OPERATION, function_name, "no framebuffer bound.");
    return;
  }
  GLuint service_id = 0;
  GLenum texture_target = 0;
  if (client_texture_id) {
    texture_ref = GetTexture(client_texture_id);
    if (!texture_ref) {
      LOCAL_SET_GL_ERROR(
          GL_INVALID_VALUE, function_name, "unknown texture");
      return;
    }
    service_id = texture_ref->service_id();

    texture_target = texture_ref->texture()->target();
    switch (texture_target) {
      case GL_TEXTURE_3D:
      case GL_TEXTURE_2D_ARRAY:
        break;
      default:
        LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
            "texture is neither TEXTURE_3D nor TEXTURE_2D_ARRAY");
        return;
    }
    if (!texture_manager()->ValidForTarget(texture_target, level,
                                           0, 0, layer)) {
      LOCAL_SET_GL_ERROR(
          GL_INVALID_VALUE, function_name, "invalid level or layer");
      return;
    }
  }
  api()->glFramebufferTextureLayerFn(target, attachment, service_id, level,
                                     layer);
  if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
    framebuffer->AttachTextureLayer(
        GL_DEPTH_ATTACHMENT, texture_ref, texture_target, level, layer);
    framebuffer->AttachTextureLayer(
        GL_STENCIL_ATTACHMENT, texture_ref, texture_target, level, layer);
  } else {
    framebuffer->AttachTextureLayer(
        attachment, texture_ref, texture_target, level, layer);
  }
  if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
    framebuffer_state_.clear_state_dirty = true;
  }
}
