// Copyright (c) 2017 The Chromium Authors. All rights reserved.
// 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/scheduler.h"

#include <algorithm>

#include "base/bind.h"
#include "base/test/test_simple_task_runner.h"
#include "gpu/command_buffer/service/sync_point_manager.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace gpu {

template <typename T>
void RunFunctor(T functor) {
  functor();
}

template <typename T>
base::OnceClosure GetClosure(T functor) {
  return base::BindOnce(&RunFunctor<T>, functor);
}

class SchedulerTest : public testing::Test {
 public:
  SchedulerTest()
      : task_runner_(new base::TestSimpleTaskRunner()),
        sync_point_manager_(new SyncPointManager),
        scheduler_(new Scheduler(task_runner_, sync_point_manager_.get())) {}

 protected:
  base::TestSimpleTaskRunner* task_runner() const { return task_runner_.get(); }

  SyncPointManager* sync_point_manager() const {
    return sync_point_manager_.get();
  }

  Scheduler* scheduler() const { return scheduler_.get(); }

 private:
  scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
  std::unique_ptr<SyncPointManager> sync_point_manager_;
  std::unique_ptr<Scheduler> scheduler_;
};

TEST_F(SchedulerTest, ScheduledTasksRunInOrder) {
  SequenceId sequence_id =
      scheduler()->CreateSequence(SchedulingPriority::kNormal);

  bool ran1 = false;
  scheduler()->ScheduleTask(Scheduler::Task(
      sequence_id, GetClosure([&] { ran1 = true; }), std::vector<SyncToken>()));

  bool ran2 = false;
  scheduler()->ScheduleTask(Scheduler::Task(
      sequence_id, GetClosure([&] { ran2 = true; }), std::vector<SyncToken>()));

  task_runner()->RunPendingTasks();
  EXPECT_TRUE(ran1);

  task_runner()->RunPendingTasks();
  EXPECT_TRUE(ran2);
}

TEST_F(SchedulerTest, ContinuedTasksRunFirst) {
  SequenceId sequence_id =
      scheduler()->CreateSequence(SchedulingPriority::kNormal);

  bool ran1 = false;
  bool continued1 = false;
  scheduler()->ScheduleTask(Scheduler::Task(
      sequence_id, GetClosure([&] {
        scheduler()->ContinueTask(sequence_id,
                                  GetClosure([&] { continued1 = true; }));
        ran1 = true;
      }),
      std::vector<SyncToken>()));

  bool ran2 = false;
  scheduler()->ScheduleTask(Scheduler::Task(
      sequence_id, GetClosure([&] { ran2 = true; }), std::vector<SyncToken>()));

  task_runner()->RunPendingTasks();
  EXPECT_TRUE(ran1);
  EXPECT_FALSE(continued1);
  EXPECT_FALSE(ran2);

  task_runner()->RunPendingTasks();
  EXPECT_TRUE(continued1);
  EXPECT_FALSE(ran2);

  task_runner()->RunPendingTasks();
  EXPECT_TRUE(ran2);
}

class SchedulerTaskRunOrderTest : public SchedulerTest {
 public:
  SchedulerTaskRunOrderTest() = default;
  ~SchedulerTaskRunOrderTest() override {
    for (auto info_it : sequence_info_) {
      info_it.second.release_state->Destroy();
      scheduler()->DestroySequence(info_it.second.sequence_id);
    }
  }

 protected:
  void CreateSequence(int sequence_key, SchedulingPriority priority) {
    SequenceId sequence_id = scheduler()->CreateSequence(priority);
    CommandBufferId command_buffer_id =
        CommandBufferId::FromUnsafeValue(sequence_key);
    scoped_refptr<SyncPointClientState> release_state =
        sync_point_manager()->CreateSyncPointClientState(
            kNamespaceId, command_buffer_id, sequence_id);

    sequence_info_.emplace(std::make_pair(
        sequence_key,
        SequenceInfo(sequence_id, command_buffer_id, release_state)));
  }

  void DestroySequence(int sequence_key) {
    auto info_it = sequence_info_.find(sequence_key);
    ASSERT_TRUE(info_it != sequence_info_.end());

    info_it->second.release_state->Destroy();
    scheduler()->DestroySequence(info_it->second.sequence_id);

    sequence_info_.erase(info_it);
  }

  void CreateSyncToken(int sequence_key, int release_sync) {
    auto info_it = sequence_info_.find(sequence_key);
    ASSERT_TRUE(info_it != sequence_info_.end());

    uint64_t release = release_sync + 1;
    sync_tokens_.emplace(std::make_pair(
        release_sync,
        SyncToken(kNamespaceId, info_it->second.command_buffer_id, release)));
  }

  void ScheduleTask(int sequence_key, int wait_sync, int release_sync) {
    const int task_id = num_tasks_scheduled_++;

    std::vector<SyncToken> wait;
    if (wait_sync >= 0) {
      wait.push_back(sync_tokens_[wait_sync]);
    }

    uint64_t release = 0;
    if (release_sync >= 0) {
      CreateSyncToken(sequence_key, release_sync);
      release = release_sync + 1;
    }

    auto info_it = sequence_info_.find(sequence_key);
    ASSERT_TRUE(info_it != sequence_info_.end());

    scheduler()->ScheduleTask(Scheduler::Task(
        info_it->second.sequence_id,
        GetClosure([this, task_id, sequence_key, release] {
          if (release) {
            auto info_it = sequence_info_.find(sequence_key);
            ASSERT_TRUE(info_it != sequence_info_.end());
            info_it->second.release_state->ReleaseFenceSync(release);
          }
          this->tasks_executed_.push_back(task_id);
        }),
        wait));
  }

  void RunAllPendingTasks() {
    while (task_runner()->HasPendingTask())
      task_runner()->RunPendingTasks();
  }

  const std::vector<int>& tasks_executed() { return tasks_executed_; }

 private:
  const CommandBufferNamespace kNamespaceId = CommandBufferNamespace::GPU_IO;

  int num_tasks_scheduled_ = 0;

  struct SequenceInfo {
    SequenceInfo(SequenceId sequence_id,
                 CommandBufferId command_buffer_id,
                 scoped_refptr<SyncPointClientState> release_state)
        : sequence_id(sequence_id),
          command_buffer_id(command_buffer_id),
          release_state(release_state) {}

    SequenceId sequence_id;
    CommandBufferId command_buffer_id;
    scoped_refptr<SyncPointClientState> release_state;
  };

  std::map<int, const SequenceInfo> sequence_info_;
  std::map<int, const SyncToken> sync_tokens_;

  std::vector<int> tasks_executed_;
};

TEST_F(SchedulerTaskRunOrderTest, SequencesRunInPriorityOrder) {
  CreateSequence(0, SchedulingPriority::kLow);
  CreateSequence(1, SchedulingPriority::kNormal);
  CreateSequence(2, SchedulingPriority::kHigh);

  ScheduleTask(0, -1, -1);  // task 0: seq 0, no wait, no release
  ScheduleTask(1, -1, -1);  // task 1: seq 1, no wait, no release
  ScheduleTask(2, -1, -1);  // task 2: seq 2, no wait, no release

  RunAllPendingTasks();

  const int expected_task_order[] = {2, 1, 0};
  EXPECT_THAT(tasks_executed(), testing::ElementsAreArray(expected_task_order));
}

TEST_F(SchedulerTaskRunOrderTest, SequencesOfSamePriorityRunInOrder) {
  CreateSequence(0, SchedulingPriority::kNormal);
  CreateSequence(1, SchedulingPriority::kNormal);
  CreateSequence(2, SchedulingPriority::kNormal);
  CreateSequence(3, SchedulingPriority::kNormal);

  ScheduleTask(0, -1, -1);  // task 0: seq 0, no wait, no release
  ScheduleTask(1, -1, -1);  // task 1: seq 1, no wait, no release
  ScheduleTask(2, -1, -1);  // task 2: seq 2, no wait, no release
  ScheduleTask(3, -1, -1);  // task 3: seq 2, no wait, no release

  RunAllPendingTasks();

  const int expected_task_order[] = {0, 1, 2, 3};
  EXPECT_THAT(tasks_executed(), testing::ElementsAreArray(expected_task_order));
}

TEST_F(SchedulerTaskRunOrderTest, SequenceWaitsForFence) {
  CreateSequence(0, SchedulingPriority::kHigh);
  CreateSequence(1, SchedulingPriority::kNormal);

  ScheduleTask(1, -1, 0);  // task 0: seq 1, no wait, release 0
  ScheduleTask(0, 0, -1);  // task 1: seq 0, wait 0, no release

  RunAllPendingTasks();

  const int expected_task_order[] = {0, 1};
  EXPECT_THAT(tasks_executed(), testing::ElementsAreArray(expected_task_order));
}

TEST_F(SchedulerTaskRunOrderTest, SequenceDoesNotWaitForInvalidFence) {
  CreateSequence(0, SchedulingPriority::kNormal);
  CreateSequence(1, SchedulingPriority::kNormal);

  CreateSyncToken(1, 0);  // declare sync_token 0 on seq 1

  ScheduleTask(0, 0, -1);  // task 0: seq 0, wait 0, no release
  ScheduleTask(1, -1, 0);  // task 1: seq 1, no wait, release 0

  RunAllPendingTasks();

  // Task 0 does not wait on unrelease sync token 0.
  const int expected_task_order[] = {0, 1};
  EXPECT_THAT(tasks_executed(), testing::ElementsAreArray(expected_task_order));
}

TEST_F(SchedulerTaskRunOrderTest, ReleaseSequenceIsPrioritized) {
  CreateSequence(0, SchedulingPriority::kNormal);
  CreateSequence(1, SchedulingPriority::kLow);
  CreateSequence(2, SchedulingPriority::kHigh);

  ScheduleTask(0, -1, -1);  // task 0: seq 0, no wait, no release
  ScheduleTask(1, -1, 0);   // task 1: seq 1, no wait, release 0
  ScheduleTask(2, 0, -1);   // task 2: seq 2, wait 0, no release

  RunAllPendingTasks();

  const int expected_task_order[] = {1, 2, 0};
  EXPECT_THAT(tasks_executed(), testing::ElementsAreArray(expected_task_order));
}

TEST_F(SchedulerTaskRunOrderTest, ReleaseSequenceHasPriorityOfWaiter) {
  CreateSequence(0, SchedulingPriority::kLow);
  CreateSequence(1, SchedulingPriority::kNormal);
  CreateSequence(2, SchedulingPriority::kHigh);

  ScheduleTask(0, -1, 0);   // task 0: seq 0, no wait, release 0
  ScheduleTask(1, 0, -1);   // task 1: seq 1, wait 0, no release
  ScheduleTask(2, -1, -1);  // task 2: seq 2, no wait, no release

  RunAllPendingTasks();

  const int expected_task_order[] = {2, 0, 1};
  EXPECT_THAT(tasks_executed(), testing::ElementsAreArray(expected_task_order));
}

TEST_F(SchedulerTaskRunOrderTest, ReleaseSequenceRevertsToDefaultPriority) {
  CreateSequence(0, SchedulingPriority::kNormal);
  CreateSequence(1, SchedulingPriority::kLow);
  CreateSequence(2, SchedulingPriority::kHigh);

  ScheduleTask(0, -1, -1);  // task 0: seq 0, no wait, no release
  ScheduleTask(1, -1, 0);   // task 1: seq 1, no wait, release 0
  ScheduleTask(2, 0, -1);   // task 2: seq 2, wait 0, no release

  DestroySequence(2);

  RunAllPendingTasks();

  const int expected_task_order[] = {0, 1};
  EXPECT_THAT(tasks_executed(), testing::ElementsAreArray(expected_task_order));
}

TEST_F(SchedulerTaskRunOrderTest, ReleaseSequenceCircularRelease) {
  CreateSequence(0, SchedulingPriority::kLow);
  CreateSequence(1, SchedulingPriority::kNormal);
  CreateSequence(2, SchedulingPriority::kHigh);

  ScheduleTask(0, -1, -1);  // task 0: seq 0, no wait, no release
  ScheduleTask(1, -1, -1);  // task 1: seq 1, no wait, no release
  ScheduleTask(2, -1, -1);  // task 2: seq 2, no wait, no release

  ScheduleTask(0, -1, 0);   // task 3: seq 0, no wait, release 0
  ScheduleTask(0, -1, -1);  // task 4: seq 0, no wait, no release

  ScheduleTask(1, 0, 1);    // task 5: seq 1, wait 0, release 1
  ScheduleTask(1, -1, -1);  // task 6: seq 1, no wait, no release

  ScheduleTask(2, 1, 2);    // task 7: seq 2, wait 1, release 2
  ScheduleTask(2, -1, -1);  // task 8: seq 2, no wait, no release

  ScheduleTask(0, 2, 3);   // task 9: seq 0, wait 2, releases 3
  ScheduleTask(1, 3, 4);   // task 10: seq 1, wait 3, releases 4
  ScheduleTask(2, 4, -1);  // task 11: seq 2, wait 4, no release

  ScheduleTask(0, -1, -1);  // task 12: seq 0, no wait, no release
  ScheduleTask(1, -1, -1);  // task 13: seq 1, no wait, no release
  ScheduleTask(2, -1, -1);  // task 14: seq 2, no wait, no release

  RunAllPendingTasks();

  const int expected_task_order[] = {0, 1, 2,  3,  4,  5,  6, 7,
                                     8, 9, 10, 11, 14, 13, 12};
  EXPECT_THAT(tasks_executed(), testing::ElementsAreArray(expected_task_order));
}

TEST_F(SchedulerTaskRunOrderTest, WaitOnSelfShouldNotBlockSequence) {
  CreateSequence(0, SchedulingPriority::kHigh);
  CreateSyncToken(0, 0);  // declare sync_token 0 on seq 1

  // Dummy order number to avoid the wait_order_num <= processed_order_num + 1
  // check in SyncPointOrderData::ValidateReleaseOrderNum.
  sync_point_manager()->GenerateOrderNumber();

  ScheduleTask(0, 0, -1);  // task 0: seq 0, wait 0, no release

  RunAllPendingTasks();

  const int expected_task_order[] = {0};
  EXPECT_THAT(tasks_executed(), testing::ElementsAreArray(expected_task_order));
}

TEST_F(SchedulerTest, ReleaseSequenceShouldYield) {
  SequenceId sequence_id1 =
      scheduler()->CreateSequence(SchedulingPriority::kLow);
  CommandBufferNamespace namespace_id = CommandBufferNamespace::GPU_IO;
  CommandBufferId command_buffer_id = CommandBufferId::FromUnsafeValue(1);
  scoped_refptr<SyncPointClientState> release_state =
      sync_point_manager()->CreateSyncPointClientState(
          namespace_id, command_buffer_id, sequence_id1);

  uint64_t release = 1;
  bool ran1 = false;
  scheduler()->ScheduleTask(
      Scheduler::Task(sequence_id1, GetClosure([&] {
                        EXPECT_FALSE(scheduler()->ShouldYield(sequence_id1));
                        release_state->ReleaseFenceSync(release);
                        EXPECT_TRUE(scheduler()->ShouldYield(sequence_id1));
                        ran1 = true;
                      }),
                      std::vector<SyncToken>()));

  bool ran2 = false;
  SyncToken sync_token(namespace_id, command_buffer_id, release);
  SequenceId sequence_id2 =
      scheduler()->CreateSequence(SchedulingPriority::kHigh);
  scheduler()->ScheduleTask(Scheduler::Task(
      sequence_id2, GetClosure([&] { ran2 = true; }), {sync_token}));

  task_runner()->RunPendingTasks();
  EXPECT_TRUE(ran1);
  EXPECT_FALSE(ran2);
  EXPECT_TRUE(sync_point_manager()->IsSyncTokenReleased(sync_token));

  task_runner()->RunPendingTasks();
  EXPECT_TRUE(ran2);

  release_state->Destroy();
}

TEST_F(SchedulerTest, ReentrantEnableSequenceShouldNotDeadlock) {
  SequenceId sequence_id1 =
      scheduler()->CreateSequence(SchedulingPriority::kHigh);
  CommandBufferNamespace namespace_id = CommandBufferNamespace::GPU_IO;
  CommandBufferId command_buffer_id1 = CommandBufferId::FromUnsafeValue(1);
  scoped_refptr<SyncPointClientState> release_state1 =
      sync_point_manager()->CreateSyncPointClientState(
          namespace_id, command_buffer_id1, sequence_id1);

  SequenceId sequence_id2 =
      scheduler()->CreateSequence(SchedulingPriority::kNormal);
  CommandBufferId command_buffer_id2 = CommandBufferId::FromUnsafeValue(2);
  scoped_refptr<SyncPointClientState> release_state2 =
      sync_point_manager()->CreateSyncPointClientState(
          namespace_id, command_buffer_id2, sequence_id2);

  uint64_t release = 1;
  SyncToken sync_token(namespace_id, command_buffer_id2, release);

  bool ran1, ran2 = false;

  // Schedule task on sequence 2 first so that the sync token wait isn't a nop.
  // BeginProcessingOrderNumber for this task will run the EnableSequence
  // callback. This should not deadlock.
  scheduler()->ScheduleTask(Scheduler::Task(sequence_id2,
                                            GetClosure([&] { ran2 = true; }),
                                            std::vector<SyncToken>()));

  // This will run first because of the higher priority and no scheduling sync
  // token dependencies.
  scheduler()->ScheduleTask(Scheduler::Task(
      sequence_id1, GetClosure([&] {
        ran1 = true;
        release_state1->Wait(
            sync_token,
            base::Bind(&Scheduler::EnableSequence,
                       base::Unretained(scheduler()), sequence_id1));
        scheduler()->DisableSequence(sequence_id1);
      }),
      std::vector<SyncToken>()));

  task_runner()->RunPendingTasks();
  EXPECT_TRUE(ran1);
  EXPECT_FALSE(ran2);
  EXPECT_FALSE(sync_point_manager()->IsSyncTokenReleased(sync_token));

  task_runner()->RunPendingTasks();
  EXPECT_TRUE(ran2);
  EXPECT_FALSE(sync_point_manager()->IsSyncTokenReleased(sync_token));

  release_state1->Destroy();
  release_state2->Destroy();
}

TEST_F(SchedulerTest, ClientWaitIsPrioritized) {
  SequenceId sequence_id1 =
      scheduler()->CreateSequence(SchedulingPriority::kNormal);

  bool ran1 = false;
  scheduler()->ScheduleTask(Scheduler::Task(sequence_id1,
                                            GetClosure([&] { ran1 = true; }),
                                            std::vector<SyncToken>()));

  SequenceId sequence_id2 =
      scheduler()->CreateSequence(SchedulingPriority::kLow);
  CommandBufferId command_buffer_id = CommandBufferId::FromUnsafeValue(1);
  bool ran2 = false;
  scheduler()->ScheduleTask(Scheduler::Task(sequence_id2,
                                            GetClosure([&] { ran2 = true; }),
                                            std::vector<SyncToken>()));

  bool ran3 = false;
  SequenceId sequence_id3 =
      scheduler()->CreateSequence(SchedulingPriority::kHigh);
  scheduler()->ScheduleTask(Scheduler::Task(sequence_id3,
                                            GetClosure([&] { ran3 = true; }),
                                            std::vector<SyncToken>()));

  scheduler()->RaisePriorityForClientWait(sequence_id2, command_buffer_id);

  task_runner()->RunPendingTasks();
  EXPECT_FALSE(ran1);
  EXPECT_TRUE(ran2);
  EXPECT_FALSE(ran3);

  task_runner()->RunPendingTasks();
  EXPECT_FALSE(ran1);
  EXPECT_TRUE(ran3);

  task_runner()->RunPendingTasks();
  EXPECT_TRUE(ran1);

  ran1 = ran2 = ran3 = false;
  scheduler()->ScheduleTask(Scheduler::Task(sequence_id1,
                                            GetClosure([&] { ran1 = true; }),
                                            std::vector<SyncToken>()));
  scheduler()->ScheduleTask(Scheduler::Task(sequence_id2,
                                            GetClosure([&] { ran2 = true; }),
                                            std::vector<SyncToken>()));
  scheduler()->ScheduleTask(Scheduler::Task(sequence_id3,
                                            GetClosure([&] { ran3 = true; }),
                                            std::vector<SyncToken>()));

  scheduler()->ResetPriorityForClientWait(sequence_id2, command_buffer_id);

  task_runner()->RunPendingTasks();
  EXPECT_FALSE(ran1);
  EXPECT_FALSE(ran2);
  EXPECT_TRUE(ran3);

  task_runner()->RunPendingTasks();
  EXPECT_TRUE(ran1);
  EXPECT_FALSE(ran2);

  task_runner()->RunPendingTasks();
  EXPECT_TRUE(ran2);
}

TEST_F(SchedulerTest, StreamPriorities) {
  SequenceId seq_id1 = scheduler()->CreateSequence(SchedulingPriority::kLow);
  SequenceId seq_id2 = scheduler()->CreateSequence(SchedulingPriority::kNormal);
  SequenceId seq_id3 = scheduler()->CreateSequence(SchedulingPriority::kHigh);

  CommandBufferNamespace namespace_id = CommandBufferNamespace::GPU_IO;
  CommandBufferId command_buffer_id1 = CommandBufferId::FromUnsafeValue(1);
  CommandBufferId command_buffer_id2 = CommandBufferId::FromUnsafeValue(2);

  base::AutoLock auto_lock(scheduler()->lock_);

  Scheduler::Sequence* seq1 = scheduler()->GetSequence(seq_id1);
  Scheduler::Sequence* seq2 = scheduler()->GetSequence(seq_id2);
  Scheduler::Sequence* seq3 = scheduler()->GetSequence(seq_id3);

  // Initial default priorities.
  EXPECT_EQ(SchedulingPriority::kLow, seq1->current_priority());
  EXPECT_EQ(SchedulingPriority::kNormal, seq2->current_priority());
  EXPECT_EQ(SchedulingPriority::kHigh, seq3->current_priority());

  SyncToken sync_token1(namespace_id, command_buffer_id1, 1);
  SyncToken sync_token2(namespace_id, command_buffer_id2, 1);

  // Wait priorities propagate.
  seq2->AddWaitFence(sync_token1, 1, seq_id1, seq1);
  EXPECT_EQ(SchedulingPriority::kNormal, seq1->current_priority());
  EXPECT_EQ(SchedulingPriority::kNormal, seq2->current_priority());
  EXPECT_EQ(SchedulingPriority::kHigh, seq3->current_priority());

  seq2->AddWaitFence(sync_token1, 1, seq_id1, seq1);
  EXPECT_EQ(SchedulingPriority::kNormal, seq1->current_priority());
  EXPECT_EQ(SchedulingPriority::kNormal, seq2->current_priority());
  EXPECT_EQ(SchedulingPriority::kHigh, seq3->current_priority());

  seq3->AddWaitFence(sync_token2, 2, seq_id2, seq2);
  EXPECT_EQ(SchedulingPriority::kHigh, seq1->current_priority());
  EXPECT_EQ(SchedulingPriority::kHigh, seq2->current_priority());
  EXPECT_EQ(SchedulingPriority::kHigh, seq3->current_priority());

  // Release priority propagate.
  seq2->RemoveWaitFence(sync_token1, 1, seq_id1);
  EXPECT_EQ(SchedulingPriority::kLow, seq1->current_priority());
  EXPECT_EQ(SchedulingPriority::kHigh, seq2->current_priority());
  EXPECT_EQ(SchedulingPriority::kHigh, seq3->current_priority());

  seq2->RemoveWaitFence(sync_token1, 1, seq_id1);
  EXPECT_EQ(SchedulingPriority::kLow, seq1->current_priority());
  EXPECT_EQ(SchedulingPriority::kHigh, seq2->current_priority());
  EXPECT_EQ(SchedulingPriority::kHigh, seq3->current_priority());

  seq3->RemoveWaitFence(sync_token2, 2, seq_id2);
  EXPECT_EQ(SchedulingPriority::kLow, seq1->current_priority());
  EXPECT_EQ(SchedulingPriority::kNormal, seq2->current_priority());
  EXPECT_EQ(SchedulingPriority::kHigh, seq3->current_priority());

  {
    base::AutoUnlock auto_unlock(scheduler()->lock_);
    scheduler()->DestroySequence(seq_id1);
    scheduler()->DestroySequence(seq_id2);
    scheduler()->DestroySequence(seq_id3);
  }
}

TEST_F(SchedulerTest, StreamDestroyRemovesPriorities) {
  SequenceId seq_id1 = scheduler()->CreateSequence(SchedulingPriority::kLow);
  SequenceId seq_id2 = scheduler()->CreateSequence(SchedulingPriority::kNormal);
  SequenceId seq_id3 = scheduler()->CreateSequence(SchedulingPriority::kHigh);

  CommandBufferNamespace namespace_id = CommandBufferNamespace::GPU_IO;
  CommandBufferId command_buffer_id1 = CommandBufferId::FromUnsafeValue(1);
  CommandBufferId command_buffer_id2 = CommandBufferId::FromUnsafeValue(2);

  base::AutoLock auto_lock(scheduler()->lock_);

  Scheduler::Sequence* seq1 = scheduler()->GetSequence(seq_id1);
  Scheduler::Sequence* seq2 = scheduler()->GetSequence(seq_id2);
  Scheduler::Sequence* seq3 = scheduler()->GetSequence(seq_id3);

  SyncToken sync_token1(namespace_id, command_buffer_id1, 1);
  SyncToken sync_token2(namespace_id, command_buffer_id2, 1);

  // Wait priorities propagate.
  seq2->AddWaitFence(sync_token1, 1, seq_id1, seq1);
  seq2->AddWaitFence(sync_token1, 1, seq_id1, seq1);
  seq3->AddWaitFence(sync_token2, 2, seq_id2, seq2);

  EXPECT_EQ(SchedulingPriority::kHigh, seq1->current_priority());
  EXPECT_EQ(SchedulingPriority::kHigh, seq2->current_priority());
  EXPECT_EQ(SchedulingPriority::kHigh, seq3->current_priority());

  // Deleting waiting sequences removes priorities.
  {
    base::AutoUnlock auto_unlock(scheduler()->lock_);
    scheduler()->DestroySequence(seq_id3);
  }

  EXPECT_EQ(SchedulingPriority::kHigh, seq1->current_priority());
  EXPECT_EQ(SchedulingPriority::kNormal, seq2->current_priority());

  {
    base::AutoUnlock auto_unlock(scheduler()->lock_);
    scheduler()->DestroySequence(seq_id2);
  }

  EXPECT_EQ(SchedulingPriority::kLow, seq1->current_priority());

  {
    base::AutoUnlock auto_unlock(scheduler()->lock_);
    scheduler()->DestroySequence(seq_id1);
  }
}

// crbug.com/781585#5: Test RemoveWait/AddWait/RemoveWait sequence.
TEST_F(SchedulerTest, StreamPriorityChangeWhileReleasing) {
  SequenceId seq_id1 = scheduler()->CreateSequence(SchedulingPriority::kLow);
  SequenceId seq_id2 = scheduler()->CreateSequence(SchedulingPriority::kNormal);
  SequenceId seq_id3 = scheduler()->CreateSequence(SchedulingPriority::kHigh);

  CommandBufferNamespace namespace_id = CommandBufferNamespace::GPU_IO;
  CommandBufferId command_buffer_id1 = CommandBufferId::FromUnsafeValue(1);
  CommandBufferId command_buffer_id2 = CommandBufferId::FromUnsafeValue(2);

  base::AutoLock auto_lock(scheduler()->lock_);

  Scheduler::Sequence* seq1 = scheduler()->GetSequence(seq_id1);
  Scheduler::Sequence* seq2 = scheduler()->GetSequence(seq_id2);
  Scheduler::Sequence* seq3 = scheduler()->GetSequence(seq_id3);

  SyncToken sync_token1(namespace_id, command_buffer_id1, 1);
  SyncToken sync_token2(namespace_id, command_buffer_id2, 2);

  // Wait on same fence multiple times.
  seq2->AddWaitFence(sync_token1, 1, seq_id1, seq1);
  seq2->AddWaitFence(sync_token1, 1, seq_id1, seq1);

  EXPECT_EQ(SchedulingPriority::kNormal, seq1->current_priority());
  EXPECT_EQ(SchedulingPriority::kNormal, seq2->current_priority());
  EXPECT_EQ(SchedulingPriority::kHigh, seq3->current_priority());

  // All matching wait fences are removed together.
  seq2->RemoveWaitFence(sync_token1, 1, seq_id1);
  EXPECT_EQ(SchedulingPriority::kLow, seq1->current_priority());
  EXPECT_EQ(SchedulingPriority::kNormal, seq2->current_priority());
  EXPECT_EQ(SchedulingPriority::kHigh, seq3->current_priority());

  // Add wait fence with higher priority.  This replicates a possible race.
  seq3->AddWaitFence(sync_token2, 2, seq_id2, seq2);
  EXPECT_EQ(SchedulingPriority::kLow, seq1->current_priority());
  EXPECT_EQ(SchedulingPriority::kHigh, seq2->current_priority());
  EXPECT_EQ(SchedulingPriority::kHigh, seq3->current_priority());

  // This should be a No-op.
  seq2->RemoveWaitFence(sync_token1, 1, seq_id1);
  EXPECT_EQ(SchedulingPriority::kLow, seq1->current_priority());
  EXPECT_EQ(SchedulingPriority::kHigh, seq2->current_priority());
  EXPECT_EQ(SchedulingPriority::kHigh, seq3->current_priority());

  seq3->RemoveWaitFence(sync_token2, 2, seq_id2);
  EXPECT_EQ(SchedulingPriority::kLow, seq1->current_priority());
  EXPECT_EQ(SchedulingPriority::kNormal, seq2->current_priority());
  EXPECT_EQ(SchedulingPriority::kHigh, seq3->current_priority());

  {
    base::AutoUnlock auto_unlock(scheduler()->lock_);
    scheduler()->DestroySequence(seq_id1);
    scheduler()->DestroySequence(seq_id2);
    scheduler()->DestroySequence(seq_id3);
  }
}

TEST_F(SchedulerTest, CircularPriorities) {
  SequenceId seq_id1 = scheduler()->CreateSequence(SchedulingPriority::kHigh);
  SequenceId seq_id2 = scheduler()->CreateSequence(SchedulingPriority::kLow);
  SequenceId seq_id3 = scheduler()->CreateSequence(SchedulingPriority::kNormal);

  CommandBufferNamespace namespace_id = CommandBufferNamespace::GPU_IO;
  CommandBufferId command_buffer_id2 = CommandBufferId::FromUnsafeValue(2);
  CommandBufferId command_buffer_id3 = CommandBufferId::FromUnsafeValue(3);

  base::AutoLock auto_lock(scheduler()->lock_);

  Scheduler::Sequence* seq1 = scheduler()->GetSequence(seq_id1);
  Scheduler::Sequence* seq2 = scheduler()->GetSequence(seq_id2);
  Scheduler::Sequence* seq3 = scheduler()->GetSequence(seq_id3);

  EXPECT_EQ(SchedulingPriority::kHigh, seq1->current_priority());
  EXPECT_EQ(SchedulingPriority::kLow, seq2->current_priority());
  EXPECT_EQ(SchedulingPriority::kNormal, seq3->current_priority());

  SyncToken sync_token_seq2_1(namespace_id, command_buffer_id2, 1);
  SyncToken sync_token_seq2_2(namespace_id, command_buffer_id2, 2);
  SyncToken sync_token_seq2_3(namespace_id, command_buffer_id2, 3);
  SyncToken sync_token_seq3_1(namespace_id, command_buffer_id3, 1);

  seq3->AddWaitFence(sync_token_seq2_1, 1, seq_id2, seq2);
  EXPECT_EQ(SchedulingPriority::kHigh, seq1->current_priority());
  EXPECT_EQ(SchedulingPriority::kNormal, seq2->current_priority());
  EXPECT_EQ(SchedulingPriority::kNormal, seq3->current_priority());

  seq1->AddWaitFence(sync_token_seq2_2, 2, seq_id2, seq2);
  EXPECT_EQ(SchedulingPriority::kHigh, seq1->current_priority());
  EXPECT_EQ(SchedulingPriority::kHigh, seq2->current_priority());
  EXPECT_EQ(SchedulingPriority::kNormal, seq3->current_priority());

  seq3->AddWaitFence(sync_token_seq2_3, 3, seq_id2, seq2);
  EXPECT_EQ(SchedulingPriority::kHigh, seq1->current_priority());
  EXPECT_EQ(SchedulingPriority::kHigh, seq2->current_priority());
  EXPECT_EQ(SchedulingPriority::kNormal, seq3->current_priority());

  seq2->AddWaitFence(sync_token_seq3_1, 4, seq_id3, seq3);
  EXPECT_EQ(SchedulingPriority::kHigh, seq1->current_priority());
  EXPECT_EQ(SchedulingPriority::kHigh, seq2->current_priority());
  EXPECT_EQ(SchedulingPriority::kNormal, seq3->current_priority());

  seq3->RemoveWaitFence(sync_token_seq2_1, 1, seq_id2);
  EXPECT_EQ(SchedulingPriority::kHigh, seq1->current_priority());
  EXPECT_EQ(SchedulingPriority::kHigh, seq2->current_priority());
  EXPECT_EQ(SchedulingPriority::kNormal, seq3->current_priority());

  seq1->RemoveWaitFence(sync_token_seq2_2, 2, seq_id2);
  EXPECT_EQ(SchedulingPriority::kHigh, seq1->current_priority());
  EXPECT_EQ(SchedulingPriority::kNormal, seq2->current_priority());
  EXPECT_EQ(SchedulingPriority::kNormal, seq3->current_priority());

  seq3->RemoveWaitFence(sync_token_seq2_3, 3, seq_id2);
  EXPECT_EQ(SchedulingPriority::kHigh, seq1->current_priority());
  EXPECT_EQ(SchedulingPriority::kLow, seq2->current_priority());
  EXPECT_EQ(SchedulingPriority::kNormal, seq3->current_priority());

  {
    base::AutoUnlock auto_unlock(scheduler()->lock_);
    scheduler()->DestroySequence(seq_id1);
    scheduler()->DestroySequence(seq_id2);
    scheduler()->DestroySequence(seq_id3);
  }
}

}  // namespace gpu
