// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "gpu/command_buffer/service/query_manager.h"

#include <stddef.h>
#include <stdint.h>

#include "base/atomicops.h"
#include "base/check_op.h"
#include "base/functional/bind.h"
#include "base/notreached.h"
#include "base/time/time.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_fence.h"

namespace gpu {

namespace {

class CommandsIssuedQuery : public QueryManager::Query {
 public:
  CommandsIssuedQuery(QueryManager* manager,
                      GLenum target,
                      scoped_refptr<gpu::Buffer> buffer,
                      QuerySync* sync);

  void Begin() override;
  void End(base::subtle::Atomic32 submit_count) override;
  void QueryCounter(base::subtle::Atomic32 submit_count) override;
  void Pause() override;
  void Resume() override;
  void Process(bool did_finish) override;
  void Destroy(bool have_context) override;
  void BeginProcessingCommands() override;
  void EndProcessingCommands() override;

 protected:
  ~CommandsIssuedQuery() override;

 private:
  enum class CommandProcessingState {
    // Used prior to receiving the Begin notification and after End which
    // completes the query.
    kNotStarted,

    // Used when the query is active and the commands with the associated
    // context are being processed.
    kProcessingCommands,

    // Used when the query is active but the associated context has been
    // de-scheduled.
    kNotProcessingCommands
  };

  void Reset();

  CommandProcessingState command_processing_state_ =
      CommandProcessingState::kNotStarted;
  base::TimeDelta elapsed_time_;
  base::TimeTicks begin_command_processing_time_;
};

CommandsIssuedQuery::CommandsIssuedQuery(QueryManager* manager,
                                         GLenum target,
                                         scoped_refptr<gpu::Buffer> buffer,
                                         QuerySync* sync)
    : Query(manager, target, std::move(buffer), sync) {
  Reset();
}

void CommandsIssuedQuery::Begin() {
  DCHECK_EQ(command_processing_state_, CommandProcessingState::kNotStarted);

  MarkAsActive();
  BeginProcessingCommands();
}

void CommandsIssuedQuery::Pause() {
  MarkAsPaused();
}

void CommandsIssuedQuery::Resume() {
  MarkAsActive();
}

void CommandsIssuedQuery::End(base::subtle::Atomic32 submit_count) {
  base::TimeDelta elapsed = elapsed_time_;
  if (begin_command_processing_time_ != base::TimeTicks())
    elapsed += base::TimeTicks::Now() - begin_command_processing_time_;

  MarkAsPending(submit_count);
  MarkAsCompleted(elapsed.InMicroseconds());

  Reset();
}

void CommandsIssuedQuery::Reset() {
  command_processing_state_ = CommandProcessingState::kNotStarted;
  begin_command_processing_time_ = base::TimeTicks();
  elapsed_time_ = base::TimeDelta();
}

void CommandsIssuedQuery::QueryCounter(base::subtle::Atomic32 submit_count) {
  NOTREACHED();
}

void CommandsIssuedQuery::Process(bool did_finish) {
  NOTREACHED();
}

void CommandsIssuedQuery::Destroy(bool /* have_context */) {
  if (!IsDeleted()) {
    MarkAsDeleted();
  }
}

void CommandsIssuedQuery::BeginProcessingCommands() {
  DCHECK_NE(command_processing_state_,
            CommandProcessingState::kProcessingCommands);
  DCHECK_EQ(begin_command_processing_time_, base::TimeTicks());

  command_processing_state_ = CommandProcessingState::kProcessingCommands;
  begin_command_processing_time_ = base::TimeTicks::Now();
}

void CommandsIssuedQuery::EndProcessingCommands() {
  DCHECK_NE(command_processing_state_,
            CommandProcessingState::kNotProcessingCommands);

  // The query may been ended before all commands associated with the context
  // were processed.
  if (command_processing_state_ == CommandProcessingState::kNotStarted)
    return;

  command_processing_state_ = CommandProcessingState::kNotProcessingCommands;
  elapsed_time_ += base::TimeTicks::Now() - begin_command_processing_time_;
  begin_command_processing_time_ = base::TimeTicks();
}

CommandsIssuedQuery::~CommandsIssuedQuery() = default;

class CommandsIssuedTimestampQuery : public QueryManager::Query {
 public:
  CommandsIssuedTimestampQuery(QueryManager* manager,
                               GLenum target,
                               scoped_refptr<gpu::Buffer> buffer,
                               QuerySync* sync);

  // This query should only be used with QueryCounter(), so Begin() and End()
  // should not be reached.
  void Begin() override;
  void End(base::subtle::Atomic32 submit_count) override;
  void QueryCounter(base::subtle::Atomic32 submit_count) override;
  void Pause() override;
  void Resume() override;
  void Process(bool did_finish) override;
  void Destroy(bool have_context) override;

 protected:
  ~CommandsIssuedTimestampQuery() override;
};

CommandsIssuedTimestampQuery::CommandsIssuedTimestampQuery(
    QueryManager* manager,
    GLenum target,
    scoped_refptr<gpu::Buffer> buffer,
    QuerySync* sync)
    : Query(manager, target, std::move(buffer), sync) {}

void CommandsIssuedTimestampQuery::Begin() {
  NOTREACHED();
}

void CommandsIssuedTimestampQuery::Pause() {
  MarkAsPaused();
}

void CommandsIssuedTimestampQuery::Resume() {
  MarkAsActive();
}

void CommandsIssuedTimestampQuery::End(base::subtle::Atomic32 submit_count) {
  NOTREACHED();
}

void CommandsIssuedTimestampQuery::QueryCounter(
    base::subtle::Atomic32 submit_count) {
  const base::TimeDelta end_time = base::TimeTicks::Now().since_origin();
  DCHECK_GE(end_time.InMicroseconds(), 0);
  MarkAsActive();
  MarkAsPending(submit_count);
  MarkAsCompleted(end_time.InMicroseconds());
}

void CommandsIssuedTimestampQuery::Process(bool did_finish) {
  NOTREACHED();
}

void CommandsIssuedTimestampQuery::Destroy(bool /* have_context */) {
  if (!IsDeleted())
    MarkAsDeleted();
}

CommandsIssuedTimestampQuery::~CommandsIssuedTimestampQuery() = default;

class CommandsCompletedQuery : public QueryManager::Query {
 public:
  CommandsCompletedQuery(QueryManager* manager,
                         GLenum target,
                         scoped_refptr<gpu::Buffer> buffer,
                         QuerySync* sync);

  // Overridden from QueryManager::Query:
  void Begin() override;
  void End(base::subtle::Atomic32 submit_count) override;
  void QueryCounter(base::subtle::Atomic32 submit_count) override;
  void Pause() override;
  void Resume() override;
  void Process(bool did_finish) override;
  void Destroy(bool have_context) override;

 protected:
  ~CommandsCompletedQuery() override;

 private:
  std::unique_ptr<gl::GLFence> fence_;
  base::TimeTicks begin_time_;
};

CommandsCompletedQuery::CommandsCompletedQuery(
    QueryManager* manager,
    GLenum target,
    scoped_refptr<gpu::Buffer> buffer,
    QuerySync* sync)
    : Query(manager, target, std::move(buffer), sync) {}

void CommandsCompletedQuery::Begin() {
  MarkAsActive();
  begin_time_ = base::TimeTicks::Now();
}

void CommandsCompletedQuery::Pause() {
  MarkAsPaused();
}

void CommandsCompletedQuery::Resume() {
  MarkAsActive();
}

void CommandsCompletedQuery::End(base::subtle::Atomic32 submit_count) {
  if (fence_ && fence_->ResetSupported()) {
    fence_->ResetState();
  } else {
    fence_ = gl::GLFence::Create();
  }
  DCHECK(fence_);
  AddToPendingQueue(submit_count);
}

void CommandsCompletedQuery::QueryCounter(base::subtle::Atomic32 submit_count) {
  NOTREACHED();
}

void CommandsCompletedQuery::Process(bool did_finish) {
  // Note: |did_finish| guarantees that the GPU has passed the fence but
  // we cannot assume that GLFence::HasCompleted() will return true yet as
  // that's not guaranteed by all GLFence implementations.
  if (!did_finish && fence_ && !fence_->HasCompleted())
    return;

  const base::TimeDelta elapsed = base::TimeTicks::Now() - begin_time_;
  MarkAsCompleted(elapsed.InMicroseconds());
}

void CommandsCompletedQuery::Destroy(bool have_context) {
  if (have_context && !IsDeleted()) {
    fence_.reset();
    MarkAsDeleted();
  } else if (fence_ && !have_context) {
    fence_->Invalidate();
  }
}

CommandsCompletedQuery::~CommandsCompletedQuery() = default;

}  // namespace

QueryManager::QueryManager() : query_count_(0) {}

QueryManager::~QueryManager() {
  DCHECK(queries_.empty());

  // If this triggers, that means something is keeping a reference to
  // a Query belonging to this.
  CHECK_EQ(query_count_, 0u);
}

void QueryManager::Destroy(bool have_context) {
  active_queries_.clear();
  pending_queries_.clear();
  while (!queries_.empty()) {
    Query* query = queries_.begin()->second.get();
    query->Destroy(have_context);
    queries_.erase(queries_.begin());
  }
}

QueryManager::Query* QueryManager::CreateQuery(
    GLenum target,
    GLuint client_id,
    scoped_refptr<gpu::Buffer> buffer,
    QuerySync* sync) {
  scoped_refptr<Query> query;
  switch (target) {
    case GL_COMMANDS_ISSUED_CHROMIUM:
      query = new CommandsIssuedQuery(this, target, std::move(buffer), sync);
      break;
    case GL_COMMANDS_ISSUED_TIMESTAMP_CHROMIUM:
      query = new CommandsIssuedTimestampQuery(this, target, std::move(buffer),
                                               sync);
      break;
    case GL_READBACK_SHADOW_COPIES_UPDATED_CHROMIUM:
    case GL_COMMANDS_COMPLETED_CHROMIUM:
      query = new CommandsCompletedQuery(this, target, std::move(buffer), sync);
      break;
    default: {
      NOTREACHED();
    }
  }
  std::pair<QueryMap::iterator, bool> result =
      queries_.insert(std::make_pair(client_id, query));
  DCHECK(result.second);
  return query.get();
}

void QueryManager::GenQueries(GLsizei n, const GLuint* queries) {
  DCHECK_GE(n, 0);
  for (GLsizei i = 0; i < n; ++i) {
    generated_query_ids_.insert(queries[i]);
  }
}

bool QueryManager::IsValidQuery(GLuint id) {
  GeneratedQueryIds::iterator it = generated_query_ids_.find(id);
  return it != generated_query_ids_.end();
}

QueryManager::Query* QueryManager::GetQuery(GLuint client_id) {
  QueryMap::iterator it = queries_.find(client_id);
  return it != queries_.end() ? it->second.get() : nullptr;
}

QueryManager::Query* QueryManager::GetActiveQuery(GLenum target) {
  ActiveQueryMap::iterator it = active_queries_.find(target);
  return it != active_queries_.end() ? it->second.get() : nullptr;
}

void QueryManager::RemoveQuery(GLuint client_id) {
  QueryMap::iterator it = queries_.find(client_id);
  if (it != queries_.end()) {
    Query* query = it->second.get();

    // Remove from active query map if it is active.
    ActiveQueryMap::iterator active_it = active_queries_.find(query->target());
    bool is_active = (active_it != active_queries_.end() &&
                      query == active_it->second.get());
    DCHECK(is_active == query->IsActive());
    if (is_active)
      active_queries_.erase(active_it);

    query->Destroy(true);
    RemovePendingQuery(query);
    query->MarkAsDeleted();
    queries_.erase(it);
  }
  generated_query_ids_.erase(client_id);
}

void QueryManager::RemoveAllQueries() {
  queries_.clear();
}

void QueryManager::StartTracking(QueryManager::Query* /* query */) {
  ++query_count_;
}

void QueryManager::StopTracking(QueryManager::Query* /* query */) {
  --query_count_;
}

GLenum QueryManager::AdjustTargetForEmulation(GLenum target) {
  return target;
}

void QueryManager::BeginQueryHelper(GLenum target, GLuint id) {
  target = AdjustTargetForEmulation(target);
  glBeginQuery(target, id);
}

void QueryManager::EndQueryHelper(GLenum target) {
  target = AdjustTargetForEmulation(target);
  glEndQuery(target);
}

QueryManager::Query::Query(QueryManager* manager,
                           GLenum target,
                           scoped_refptr<gpu::Buffer> buffer,
                           QuerySync* sync)
    : manager_(manager),
      target_(target),
      buffer_(std::move(buffer)),
      sync_(sync),
      submit_count_(0),
      query_state_(kQueryState_Initialize),
      deleted_(false) {
  DCHECK(manager);
  manager_->StartTracking(this);
}

void QueryManager::Query::RunCallbacks() {
  for (size_t i = 0; i < callbacks_.size(); i++) {
    std::move(callbacks_[i]).Run();
  }
  callbacks_.clear();
}

void QueryManager::Query::AddCallback(base::OnceClosure callback) {
  if (query_state_ == kQueryState_Pending) {
    callbacks_.push_back(std::move(callback));
  } else {
    std::move(callback).Run();
  }
}

QueryManager::Query::~Query() {
  // The query is getting deleted, either by the client or
  // because the context was lost. Call any outstanding
  // callbacks to avoid leaks.
  RunCallbacks();
  if (manager_) {
    manager_->StopTracking(this);
    manager_ = nullptr;
  }
}

void QueryManager::Query::MarkAsCompleted(uint64_t result) {
  UnmarkAsPending();

  sync_->result = result;
  base::subtle::Release_Store(&sync_->process_count, submit_count_);
  RunCallbacks();
}

void QueryManager::ProcessPendingQueries(bool did_finish) {
  while (!pending_queries_.empty()) {
    Query* query = pending_queries_.front().get();
    query->Process(did_finish);
    if (query->IsPending()) {
      break;
    }
    pending_queries_.pop_front();
  }
  // If glFinish() has been called, all of our queries should be completed.
  DCHECK(!did_finish || pending_queries_.empty());
}

bool QueryManager::HavePendingQueries() {
  return !pending_queries_.empty();
}

void QueryManager::AddPendingQuery(Query* query,
                                   base::subtle::Atomic32 submit_count) {
  DCHECK(query);
  DCHECK(!query->IsDeleted());
  RemovePendingQuery(query);
  query->MarkAsPending(submit_count);
  pending_queries_.push_back(query);
}

void QueryManager::RemovePendingQuery(Query* query) {
  DCHECK(query);
  if (query->IsPending()) {
    // TODO(gman): Speed this up if this is a common operation. This would only
    // happen if you do being/end begin/end on the same query without waiting
    // for the first one to finish.
    for (QueryQueue::iterator it = pending_queries_.begin();
         it != pending_queries_.end(); ++it) {
      if (it->get() == query) {
        pending_queries_.erase(it);
        break;
      }
    }
    query->MarkAsCompleted(0);
  }
}

void QueryManager::BeginQuery(Query* query) {
  DCHECK(query);
  RemovePendingQuery(query);
  query->Begin();
  active_queries_[query->target()] = query;
}

void QueryManager::EndQuery(Query* query, base::subtle::Atomic32 submit_count) {
  DCHECK(query);
  RemovePendingQuery(query);

  // Remove from active query map if it is active.
  ActiveQueryMap::iterator active_it = active_queries_.find(query->target());
  DCHECK(active_it != active_queries_.end());
  DCHECK(query == active_it->second.get());
  active_queries_.erase(active_it);

  query->End(submit_count);
}

void QueryManager::QueryCounter(Query* query,
                                base::subtle::Atomic32 submit_count) {
  DCHECK(query);
  RemovePendingQuery(query);
  query->QueryCounter(submit_count);
}

void QueryManager::PauseQueries() {
  for (std::pair<const GLenum, scoped_refptr<Query> >& it : active_queries_) {
    if (it.second->IsActive()) {
      it.second->Pause();
      DCHECK(it.second->IsPaused());
    }
  }
}

void QueryManager::ResumeQueries() {
  for (std::pair<const GLenum, scoped_refptr<Query> >& it : active_queries_) {
    if (it.second->IsPaused()) {
      it.second->Resume();
      DCHECK(it.second->IsActive());
    }
  }
}

void QueryManager::BeginProcessingCommands() {
  for (std::pair<const GLenum, scoped_refptr<Query>>& it : active_queries_)
    it.second->BeginProcessingCommands();
}

void QueryManager::EndProcessingCommands() {
  for (std::pair<const GLenum, scoped_refptr<Query>>& it : active_queries_)
    it.second->EndProcessingCommands();
}

}  // namespace gpu
