// Copyright 2024 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/blocking_sequence_runner.h"

#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "base/trace_event/trace_event.h"
#include "gpu/command_buffer/service/scheduler.h"

namespace gpu {

BlockingSequenceRunner::BlockingSequenceRunner(Scheduler* scheduler)
    : task_graph_(scheduler->task_graph()) {
  auto sequence = std::make_unique<Sequence>(scheduler);
  sequence_ = sequence.get();

  task_graph_->AddSequence(std::move(sequence));
}

BlockingSequenceRunner::~BlockingSequenceRunner() {
  SequenceId id = GetSequenceId();
  sequence_ = nullptr;
  task_graph_->DestroySequence(id);
}

SequenceId BlockingSequenceRunner::GetSequenceId() const {
  return sequence_->sequence_id();
}

bool BlockingSequenceRunner::HasTasks() const {
  base::AutoLock locker(lock());
  return sequence_->HasTasks();
}

uint32_t BlockingSequenceRunner::AddTask(TaskCallback task_callback,
                                         std::vector<SyncToken> wait_fences,
                                         const SyncToken& release,
                                         ReportingCallback report_callback) {
  base::AutoLock auto_lock(lock());
  return sequence_->AddTask(std::move(task_callback), std::move(wait_fences),
                            release, std::move(report_callback));
}

uint32_t BlockingSequenceRunner::AddTask(base::OnceClosure task_closure,
                                         std::vector<SyncToken> wait_fences,
                                         const SyncToken& release,
                                         ReportingCallback report_callback) {
  base::AutoLock auto_lock(lock());
  return sequence_->AddTask(std::move(task_closure), std::move(wait_fences),
                            release, std::move(report_callback));
}

ScopedSyncPointClientState BlockingSequenceRunner::CreateSyncPointClientState(
    CommandBufferNamespace namespace_id,
    CommandBufferId command_buffer_id) {
  base::AutoLock auto_lock(lock());
  return sequence_->CreateSyncPointClientState(namespace_id, command_buffer_id);
}

void BlockingSequenceRunner::RunAllTasks() {
  base::AutoLock auto_lock(lock());
  sequence_->RunAllTasks();
}

BlockingSequenceRunner::Sequence::Sequence(Scheduler* scheduler)
    : TaskGraph::Sequence(scheduler->task_graph(),
                          base::DoNothing(),
                          /*validation_runner=*/{}),
      scheduler_(scheduler) {}

void BlockingSequenceRunner::Sequence::RunAllTasks() {
  while (!tasks_.empty()) {
    // Synchronously wait for the fences of the front task.
    while (!IsFrontTaskUnblocked()) {
      gpu::SyncToken sync_token = wait_fences_.begin()->sync_token;
      uint32_t order_num = wait_fences_.begin()->order_num;
      gpu::SequenceId release_sequence_id =
          wait_fences_.begin()->release_sequence_id;

      // Must unlock the task graph lock, otherwise it will deadlock when
      // calling into scheduler to update sequence priority, or when blocking on
      // `completion` waiting for other tasks to release fences.
      //
      // Manually release and re-acquire the lock, because locking annotation
      // used on ValidateSequenceTaskFenceDeps() doesn't recognize
      // base::AutoUnlock.
      lock().Release();

      base::WaitableEvent completion;
      if (task_graph_->sync_point_manager()->Wait(
              sync_token, sequence_id_, order_num,
              base::BindOnce(&base::WaitableEvent::Signal,
                             base::Unretained(&completion)))) {
        TRACE_EVENT1(
            "gpu",
            "BlockingSequenceRunner::Sequence::RunAllTasks::WaitSyncToken",
            "sequence_id", release_sequence_id.value());
        gpu::Scheduler::ScopedSetSequencePriority waiting(
            scheduler_, release_sequence_id, gpu::SchedulingPriority::kHigh);

        if (task_graph_->graph_validation_enabled()) {
          while (!completion.TimedWait(gpu::TaskGraph::kMinValidationDelay)) {
            task_graph_->ValidateSequenceTaskFenceDeps(this);
          }
        } else {
          completion.Wait();
        }
      }

      lock().Acquire();
    }

    // Run the front task.
    base::OnceClosure task_closure;
    uint32_t order_num = BeginTask(&task_closure);
    gpu::SyncToken release = current_task_release_;

    {
      base::AutoUnlock auto_unlock(lock());
      order_data()->BeginProcessingOrderNumber(order_num);

      std::move(task_closure).Run();

      if (order_data()->IsProcessingOrderNumber()) {
        if (release.HasData()) {
          task_graph_->sync_point_manager()->EnsureFenceSyncReleased(
              release, gpu::ReleaseCause::kTaskCompletionRelease);
        }

        order_data()->FinishProcessingOrderNumber(order_num);
      }
    }

    FinishTask();
  }
}

}  // namespace gpu
