// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#define FML_USED_ON_EMBEDDER

#include "flutter/fml/raster_thread_merger.h"

#include <thread>

#include "flutter/fml/memory/ref_ptr.h"
#include "flutter/fml/message_loop.h"
#include "flutter/fml/synchronization/count_down_latch.h"
#include "flutter/fml/synchronization/waitable_event.h"
#include "flutter/fml/task_runner.h"
#include "flutter/fml/thread.h"
#include "gtest/gtest.h"

namespace fml {
namespace testing {

/// A mock task queue NOT calling MessageLoop->Run() in thread
struct TaskQueueWrapper {
  fml::MessageLoop* loop = nullptr;

  /// The waiter for message loop initialized ok
  fml::AutoResetWaitableEvent latch;

  /// The waiter for thread finished
  fml::AutoResetWaitableEvent term;

  /// This field must below latch and term member, because
  /// cpp standard reference:
  /// non-static data members are initialized in the order they were declared in
  /// the class definition
  std::thread thread;

  TaskQueueWrapper()
      : thread([this]() {
          fml::MessageLoop::EnsureInitializedForCurrentThread();
          loop = &fml::MessageLoop::GetCurrent();
          latch.Signal();
          term.Wait();
        }) {
    latch.Wait();
  }

  ~TaskQueueWrapper() {
    term.Signal();
    thread.join();
  }

  fml::TaskQueueId GetTaskQueueId() const {
    return loop->GetTaskRunner()->GetTaskQueueId();
  }
};

TEST(RasterThreadMerger, RemainMergedTillLeaseExpires) {
  TaskQueueWrapper queue1;
  TaskQueueWrapper queue2;
  fml::TaskQueueId qid1 = queue1.GetTaskQueueId();
  fml::TaskQueueId qid2 = queue2.GetTaskQueueId();
  const auto raster_thread_merger =
      fml::MakeRefCounted<fml::RasterThreadMerger>(qid1, qid2);
  const size_t kNumFramesMerged = 5;

  ASSERT_FALSE(raster_thread_merger->IsMerged());

  raster_thread_merger->MergeWithLease(kNumFramesMerged);

  for (size_t i = 0; i < kNumFramesMerged; i++) {
    ASSERT_TRUE(raster_thread_merger->IsMerged());
    raster_thread_merger->DecrementLease();
  }

  ASSERT_FALSE(raster_thread_merger->IsMerged());
}

TEST(RasterThreadMerger, IsNotOnRasterizingThread) {
  fml::MessageLoop* loop1 = nullptr;
  fml::AutoResetWaitableEvent latch1;
  std::thread thread1([&loop1, &latch1]() {
    fml::MessageLoop::EnsureInitializedForCurrentThread();
    loop1 = &fml::MessageLoop::GetCurrent();
    loop1->GetTaskRunner()->PostTask([&]() { latch1.Signal(); });
    loop1->Run();
  });

  fml::MessageLoop* loop2 = nullptr;
  fml::AutoResetWaitableEvent latch2;
  std::thread thread2([&loop2, &latch2]() {
    fml::MessageLoop::EnsureInitializedForCurrentThread();
    loop2 = &fml::MessageLoop::GetCurrent();
    loop2->GetTaskRunner()->PostTask([&]() { latch2.Signal(); });
    loop2->Run();
  });

  latch1.Wait();
  latch2.Wait();

  fml::TaskQueueId qid1 = loop1->GetTaskRunner()->GetTaskQueueId();
  fml::TaskQueueId qid2 = loop2->GetTaskRunner()->GetTaskQueueId();
  const auto raster_thread_merger =
      fml::MakeRefCounted<fml::RasterThreadMerger>(qid1, qid2);

  fml::CountDownLatch pre_merge(2), post_merge(2), post_unmerge(2);

  loop1->GetTaskRunner()->PostTask([&]() {
    ASSERT_FALSE(raster_thread_merger->IsOnRasterizingThread());
    ASSERT_TRUE(raster_thread_merger->IsOnPlatformThread());
    ASSERT_EQ(fml::MessageLoop::GetCurrentTaskQueueId(), qid1);
    pre_merge.CountDown();
  });

  loop2->GetTaskRunner()->PostTask([&]() {
    ASSERT_TRUE(raster_thread_merger->IsOnRasterizingThread());
    ASSERT_FALSE(raster_thread_merger->IsOnPlatformThread());
    ASSERT_EQ(fml::MessageLoop::GetCurrentTaskQueueId(), qid2);
    pre_merge.CountDown();
  });

  pre_merge.Wait();

  raster_thread_merger->MergeWithLease(1);

  loop1->GetTaskRunner()->PostTask([&]() {
    ASSERT_TRUE(raster_thread_merger->IsOnRasterizingThread());
    ASSERT_TRUE(raster_thread_merger->IsOnPlatformThread());
    ASSERT_EQ(fml::MessageLoop::GetCurrentTaskQueueId(), qid1);
    post_merge.CountDown();
  });

  loop2->GetTaskRunner()->PostTask([&]() {
    // this will be false since this is going to be run
    // on loop1 really.
    ASSERT_TRUE(raster_thread_merger->IsOnRasterizingThread());
    ASSERT_TRUE(raster_thread_merger->IsOnPlatformThread());
    ASSERT_EQ(fml::MessageLoop::GetCurrentTaskQueueId(), qid1);
    post_merge.CountDown();
  });

  post_merge.Wait();

  raster_thread_merger->DecrementLease();

  loop1->GetTaskRunner()->PostTask([&]() {
    ASSERT_FALSE(raster_thread_merger->IsOnRasterizingThread());
    ASSERT_TRUE(raster_thread_merger->IsOnPlatformThread());
    ASSERT_EQ(fml::MessageLoop::GetCurrentTaskQueueId(), qid1);
    post_unmerge.CountDown();
  });

  loop2->GetTaskRunner()->PostTask([&]() {
    ASSERT_TRUE(raster_thread_merger->IsOnRasterizingThread());
    ASSERT_FALSE(raster_thread_merger->IsOnPlatformThread());
    ASSERT_EQ(fml::MessageLoop::GetCurrentTaskQueueId(), qid2);
    post_unmerge.CountDown();
  });

  post_unmerge.Wait();

  loop1->GetTaskRunner()->PostTask([&]() { loop1->Terminate(); });

  loop2->GetTaskRunner()->PostTask([&]() { loop2->Terminate(); });

  thread1.join();
  thread2.join();
}

TEST(RasterThreadMerger, LeaseExtension) {
  TaskQueueWrapper queue1;
  TaskQueueWrapper queue2;

  fml::TaskQueueId qid1 = queue1.GetTaskQueueId();
  fml::TaskQueueId qid2 = queue2.GetTaskQueueId();
  const auto raster_thread_merger =
      fml::MakeRefCounted<fml::RasterThreadMerger>(qid1, qid2);
  const size_t kNumFramesMerged = 5;

  ASSERT_FALSE(raster_thread_merger->IsMerged());

  raster_thread_merger->MergeWithLease(kNumFramesMerged);

  // let there be one more turn till the leases expire.
  for (size_t i = 0; i < kNumFramesMerged - 1; i++) {
    ASSERT_TRUE(raster_thread_merger->IsMerged());
    raster_thread_merger->DecrementLease();
  }

  // extend the lease once.
  raster_thread_merger->ExtendLeaseTo(kNumFramesMerged);

  // we will NOT last for 1 extra turn, we just set it.
  for (size_t i = 0; i < kNumFramesMerged; i++) {
    ASSERT_TRUE(raster_thread_merger->IsMerged());
    raster_thread_merger->DecrementLease();
  }

  ASSERT_FALSE(raster_thread_merger->IsMerged());
}

TEST(RasterThreadMerger, WaitUntilMerged) {
  fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger;

  fml::AutoResetWaitableEvent create_thread_merger_latch;
  fml::MessageLoop* loop_platform = nullptr;
  fml::AutoResetWaitableEvent latch_platform;
  fml::AutoResetWaitableEvent term_platform;
  fml::AutoResetWaitableEvent latch_merged;
  std::thread thread_platform([&]() {
    fml::MessageLoop::EnsureInitializedForCurrentThread();
    loop_platform = &fml::MessageLoop::GetCurrent();
    latch_platform.Signal();
    create_thread_merger_latch.Wait();
    raster_thread_merger->WaitUntilMerged();
    latch_merged.Signal();
    term_platform.Wait();
  });

  const size_t kNumFramesMerged = 5;
  fml::MessageLoop* loop_raster = nullptr;
  fml::AutoResetWaitableEvent term_raster;
  std::thread thread_raster([&]() {
    fml::MessageLoop::EnsureInitializedForCurrentThread();
    loop_raster = &fml::MessageLoop::GetCurrent();
    latch_platform.Wait();
    fml::TaskQueueId qid_platform =
        loop_platform->GetTaskRunner()->GetTaskQueueId();
    fml::TaskQueueId qid_raster =
        loop_raster->GetTaskRunner()->GetTaskQueueId();
    raster_thread_merger =
        fml::MakeRefCounted<fml::RasterThreadMerger>(qid_platform, qid_raster);
    ASSERT_FALSE(raster_thread_merger->IsMerged());
    create_thread_merger_latch.Signal();
    raster_thread_merger->MergeWithLease(kNumFramesMerged);
    term_raster.Wait();
  });

  latch_merged.Wait();
  ASSERT_TRUE(raster_thread_merger->IsMerged());

  for (size_t i = 0; i < kNumFramesMerged; i++) {
    ASSERT_TRUE(raster_thread_merger->IsMerged());
    raster_thread_merger->DecrementLease();
  }

  ASSERT_FALSE(raster_thread_merger->IsMerged());

  term_platform.Signal();
  term_raster.Signal();
  thread_platform.join();
  thread_raster.join();
}

TEST(RasterThreadMerger, HandleTaskQueuesAreTheSame) {
  TaskQueueWrapper queue;
  fml::TaskQueueId qid1 = queue.GetTaskQueueId();
  fml::TaskQueueId qid2 = qid1;
  const auto raster_thread_merger =
      fml::MakeRefCounted<fml::RasterThreadMerger>(qid1, qid2);
  // Statically merged.
  ASSERT_TRUE(raster_thread_merger->IsMerged());

  // Test decrement lease and unmerge are both no-ops.
  // The task queues should be always merged.
  const size_t kNumFramesMerged = 5;
  raster_thread_merger->MergeWithLease(kNumFramesMerged);

  for (size_t i = 0; i < kNumFramesMerged; i++) {
    ASSERT_TRUE(raster_thread_merger->IsMerged());
    raster_thread_merger->DecrementLease();
  }

  ASSERT_TRUE(raster_thread_merger->IsMerged());

  // Wait until merged should also return immediately.
  raster_thread_merger->WaitUntilMerged();
  ASSERT_TRUE(raster_thread_merger->IsMerged());
}

TEST(RasterThreadMerger, Enable) {
  TaskQueueWrapper queue1;
  TaskQueueWrapper queue2;
  fml::TaskQueueId qid1 = queue1.GetTaskQueueId();
  fml::TaskQueueId qid2 = queue2.GetTaskQueueId();
  const auto raster_thread_merger =
      fml::MakeRefCounted<fml::RasterThreadMerger>(qid1, qid2);

  raster_thread_merger->Disable();
  raster_thread_merger->MergeWithLease(1);
  ASSERT_FALSE(raster_thread_merger->IsMerged());

  raster_thread_merger->Enable();
  ASSERT_FALSE(raster_thread_merger->IsMerged());

  raster_thread_merger->MergeWithLease(1);
  ASSERT_TRUE(raster_thread_merger->IsMerged());

  raster_thread_merger->DecrementLease();
  ASSERT_FALSE(raster_thread_merger->IsMerged());
}

TEST(RasterThreadMerger, Disable) {
  TaskQueueWrapper queue1;
  TaskQueueWrapper queue2;
  fml::TaskQueueId qid1 = queue1.GetTaskQueueId();
  fml::TaskQueueId qid2 = queue2.GetTaskQueueId();
  const auto raster_thread_merger =
      fml::MakeRefCounted<fml::RasterThreadMerger>(qid1, qid2);

  raster_thread_merger->Disable();
  ASSERT_FALSE(raster_thread_merger->IsMerged());

  raster_thread_merger->MergeWithLease(1);
  ASSERT_FALSE(raster_thread_merger->IsMerged());

  raster_thread_merger->Enable();
  raster_thread_merger->MergeWithLease(1);
  ASSERT_TRUE(raster_thread_merger->IsMerged());

  raster_thread_merger->Disable();
  raster_thread_merger->UnMergeNowIfLastOne();
  ASSERT_TRUE(raster_thread_merger->IsMerged());

  {
    auto decrement_result = raster_thread_merger->DecrementLease();
    ASSERT_EQ(fml::RasterThreadStatus::kRemainsMerged, decrement_result);
  }

  ASSERT_TRUE(raster_thread_merger->IsMerged());

  raster_thread_merger->Enable();
  raster_thread_merger->UnMergeNowIfLastOne();
  ASSERT_FALSE(raster_thread_merger->IsMerged());

  raster_thread_merger->MergeWithLease(1);

  ASSERT_TRUE(raster_thread_merger->IsMerged());

  {
    auto decrement_result = raster_thread_merger->DecrementLease();
    ASSERT_EQ(fml::RasterThreadStatus::kUnmergedNow, decrement_result);
  }

  ASSERT_FALSE(raster_thread_merger->IsMerged());
}

TEST(RasterThreadMerger, IsEnabled) {
  TaskQueueWrapper queue1;
  TaskQueueWrapper queue2;
  fml::TaskQueueId qid1 = queue1.GetTaskQueueId();
  fml::TaskQueueId qid2 = queue2.GetTaskQueueId();
  const auto raster_thread_merger =
      fml::MakeRefCounted<fml::RasterThreadMerger>(qid1, qid2);
  ASSERT_TRUE(raster_thread_merger->IsEnabled());

  raster_thread_merger->Disable();
  ASSERT_FALSE(raster_thread_merger->IsEnabled());

  raster_thread_merger->Enable();
  ASSERT_TRUE(raster_thread_merger->IsEnabled());
}

TEST(RasterThreadMerger, TwoMergersWithSameThreadPairShareEnabledState) {
  TaskQueueWrapper queue1;
  TaskQueueWrapper queue2;
  fml::TaskQueueId qid1 = queue1.GetTaskQueueId();
  fml::TaskQueueId qid2 = queue2.GetTaskQueueId();
  const auto merger1 =
      RasterThreadMerger::CreateOrShareThreadMerger(nullptr, qid1, qid2);
  const auto merger2 =
      RasterThreadMerger::CreateOrShareThreadMerger(merger1, qid1, qid2);
  ASSERT_TRUE(merger1->IsEnabled());
  ASSERT_TRUE(merger2->IsEnabled());

  merger1->Disable();
  ASSERT_FALSE(merger1->IsEnabled());
  ASSERT_FALSE(merger2->IsEnabled());

  merger2->Enable();
  ASSERT_TRUE(merger1->IsEnabled());
  ASSERT_TRUE(merger2->IsEnabled());
}

TEST(RasterThreadMerger, RunExpiredTasksWhileFirstTaskMergesThreads) {
  fml::MessageLoop* loop_platform = nullptr;
  fml::AutoResetWaitableEvent latch1;
  std::thread thread_platform([&loop_platform, &latch1]() {
    fml::MessageLoop::EnsureInitializedForCurrentThread();
    loop_platform = &fml::MessageLoop::GetCurrent();
    loop_platform->GetTaskRunner()->PostTask([&]() { latch1.Signal(); });
    loop_platform->Run();
  });

  fml::MessageLoop* loop_raster = nullptr;
  fml::AutoResetWaitableEvent latch2;
  std::thread thread_raster([&loop_raster, &loop_platform, &latch1, &latch2]() {
    latch1.Wait();

    fml::MessageLoop::EnsureInitializedForCurrentThread();
    loop_raster = &fml::MessageLoop::GetCurrent();
    fml::TaskQueueId qid_platform =
        loop_platform->GetTaskRunner()->GetTaskQueueId();
    fml::TaskQueueId qid_raster =
        loop_raster->GetTaskRunner()->GetTaskQueueId();
    fml::CountDownLatch post_merge(2);
    const auto raster_thread_merger =
        fml::MakeRefCounted<fml::RasterThreadMerger>(qid_platform, qid_raster);
    loop_raster->GetTaskRunner()->PostTask([&]() {
      ASSERT_TRUE(raster_thread_merger->IsOnRasterizingThread());
      ASSERT_FALSE(raster_thread_merger->IsOnPlatformThread());
      ASSERT_EQ(fml::MessageLoop::GetCurrentTaskQueueId(), qid_raster);
      raster_thread_merger->MergeWithLease(1);
      post_merge.CountDown();
    });

    loop_raster->GetTaskRunner()->PostTask([&]() {
      ASSERT_TRUE(raster_thread_merger->IsOnRasterizingThread());
      ASSERT_TRUE(raster_thread_merger->IsOnPlatformThread());
      ASSERT_EQ(fml::MessageLoop::GetCurrentTaskQueueId(), qid_platform);
      raster_thread_merger->DecrementLease();
      post_merge.CountDown();
    });

    loop_raster->RunExpiredTasksNow();
    post_merge.Wait();
    latch2.Signal();
  });

  latch2.Wait();
  loop_platform->GetTaskRunner()->PostTask(
      [&]() { loop_platform->Terminate(); });

  thread_platform.join();
  thread_raster.join();
}

TEST(RasterThreadMerger, RunExpiredTasksWhileFirstTaskUnMergesThreads) {
  fml::Thread platform_thread("test_platform_thread");

  fml::AutoResetWaitableEvent raster_latch;
  std::thread thread_raster([&]() {
    fml::MessageLoop::EnsureInitializedForCurrentThread();
    fml::MessageLoop* loop_raster = &fml::MessageLoop::GetCurrent();

    fml::TaskQueueId qid_platform =
        platform_thread.GetTaskRunner()->GetTaskQueueId();
    fml::TaskQueueId qid_raster =
        loop_raster->GetTaskRunner()->GetTaskQueueId();

    fml::AutoResetWaitableEvent merge_latch;
    const auto raster_thread_merger =
        fml::MakeRefCounted<fml::RasterThreadMerger>(qid_platform, qid_raster);
    loop_raster->GetTaskRunner()->PostTask([&]() {
      raster_thread_merger->MergeWithLease(1);
      merge_latch.Signal();
    });

    loop_raster->RunExpiredTasksNow();
    merge_latch.Wait();

    // threads should be merged at this point.
    fml::AutoResetWaitableEvent unmerge_latch;
    loop_raster->GetTaskRunner()->PostTask([&]() {
      ASSERT_TRUE(raster_thread_merger->IsOnRasterizingThread());
      ASSERT_TRUE(raster_thread_merger->IsOnPlatformThread());
      ASSERT_EQ(fml::MessageLoop::GetCurrentTaskQueueId(), qid_platform);
      raster_thread_merger->DecrementLease();
      unmerge_latch.Signal();
    });

    fml::AutoResetWaitableEvent post_unmerge_latch;
    loop_raster->GetTaskRunner()->PostTask([&]() {
      ASSERT_TRUE(raster_thread_merger->IsOnRasterizingThread());
      ASSERT_FALSE(raster_thread_merger->IsOnPlatformThread());
      ASSERT_EQ(fml::MessageLoop::GetCurrentTaskQueueId(), qid_raster);
      post_unmerge_latch.Signal();
    });

    unmerge_latch.Wait();
    loop_raster->RunExpiredTasksNow();

    post_unmerge_latch.Wait();
    raster_latch.Signal();
  });

  raster_latch.Wait();
  thread_raster.join();
}

TEST(RasterThreadMerger, SetMergeUnmergeCallback) {
  TaskQueueWrapper queue1;
  TaskQueueWrapper queue2;
  fml::TaskQueueId qid1 = queue1.GetTaskQueueId();
  fml::TaskQueueId qid2 = queue2.GetTaskQueueId();

  const auto raster_thread_merger =
      fml::MakeRefCounted<fml::RasterThreadMerger>(qid1, qid2);

  int callbacks = 0;
  raster_thread_merger->SetMergeUnmergeCallback(
      [&callbacks]() { callbacks++; });

  ASSERT_EQ(0, callbacks);

  raster_thread_merger->MergeWithLease(1);
  ASSERT_EQ(1, callbacks);

  raster_thread_merger->DecrementLease();
  ASSERT_EQ(2, callbacks);
}

TEST(RasterThreadMerger, MultipleMergersCanMergeSameThreadPair) {
  TaskQueueWrapper queue1;
  TaskQueueWrapper queue2;
  fml::TaskQueueId qid1 = queue1.GetTaskQueueId();
  fml::TaskQueueId qid2 = queue2.GetTaskQueueId();
  // Two mergers will share one same inner merger
  const auto raster_thread_merger1 =
      fml::RasterThreadMerger::CreateOrShareThreadMerger(nullptr, qid1, qid2);
  const auto raster_thread_merger2 =
      fml::RasterThreadMerger::CreateOrShareThreadMerger(raster_thread_merger1,
                                                         qid1, qid2);
  const size_t kNumFramesMerged = 5;
  ASSERT_FALSE(raster_thread_merger1->IsMerged());
  ASSERT_FALSE(raster_thread_merger2->IsMerged());

  // Merge using the first merger
  raster_thread_merger1->MergeWithLease(kNumFramesMerged);

  ASSERT_TRUE(raster_thread_merger1->IsMerged());
  ASSERT_TRUE(raster_thread_merger2->IsMerged());

  // let there be one more turn till the leases expire.
  for (size_t i = 0; i < kNumFramesMerged - 1; i++) {
    // Check merge state using the two merger
    ASSERT_TRUE(raster_thread_merger1->IsMerged());
    ASSERT_TRUE(raster_thread_merger2->IsMerged());
    raster_thread_merger1->DecrementLease();
  }

  ASSERT_TRUE(raster_thread_merger1->IsMerged());
  ASSERT_TRUE(raster_thread_merger2->IsMerged());

  // extend the lease once with the first merger
  raster_thread_merger1->ExtendLeaseTo(kNumFramesMerged);

  // we will NOT last for 1 extra turn, we just set it.
  for (size_t i = 0; i < kNumFramesMerged; i++) {
    // Check merge state using the two merger
    ASSERT_TRUE(raster_thread_merger1->IsMerged());
    ASSERT_TRUE(raster_thread_merger2->IsMerged());
    raster_thread_merger1->DecrementLease();
  }

  ASSERT_FALSE(raster_thread_merger1->IsMerged());
  ASSERT_FALSE(raster_thread_merger2->IsMerged());
}

TEST(RasterThreadMerger, TheLastCallerOfMultipleMergersCanUnmergeNow) {
  TaskQueueWrapper queue1;
  TaskQueueWrapper queue2;
  fml::TaskQueueId qid1 = queue1.GetTaskQueueId();
  fml::TaskQueueId qid2 = queue2.GetTaskQueueId();
  // Two mergers will share one same inner merger
  const auto raster_thread_merger1 =
      fml::RasterThreadMerger::CreateOrShareThreadMerger(nullptr, qid1, qid2);
  const auto raster_thread_merger2 =
      fml::RasterThreadMerger::CreateOrShareThreadMerger(raster_thread_merger1,
                                                         qid1, qid2);
  const size_t kNumFramesMerged = 5;
  ASSERT_FALSE(raster_thread_merger1->IsMerged());
  ASSERT_FALSE(raster_thread_merger2->IsMerged());

  // Merge using the mergers
  raster_thread_merger1->MergeWithLease(kNumFramesMerged);
  ASSERT_TRUE(raster_thread_merger1->IsMerged());
  ASSERT_TRUE(raster_thread_merger2->IsMerged());
  // Extend the second merger's lease
  raster_thread_merger2->ExtendLeaseTo(kNumFramesMerged);
  ASSERT_TRUE(raster_thread_merger1->IsMerged());
  ASSERT_TRUE(raster_thread_merger2->IsMerged());

  // Two callers state becomes one caller left.
  raster_thread_merger1->UnMergeNowIfLastOne();
  // Check if still merged
  ASSERT_TRUE(raster_thread_merger1->IsMerged());
  ASSERT_TRUE(raster_thread_merger2->IsMerged());

  // One caller state becomes no callers left.
  raster_thread_merger2->UnMergeNowIfLastOne();
  // Check if unmerged
  ASSERT_FALSE(raster_thread_merger1->IsMerged());
  ASSERT_FALSE(raster_thread_merger2->IsMerged());
}

/// This case tests multiple standalone engines using independent merger to
/// merge two different raster threads into the same platform thread.
TEST(RasterThreadMerger,
     TwoIndependentMergersCanMergeTwoDifferentThreadsIntoSamePlatformThread) {
  TaskQueueWrapper queue1;
  TaskQueueWrapper queue2;
  TaskQueueWrapper queue3;
  fml::TaskQueueId qid1 = queue1.GetTaskQueueId();
  fml::TaskQueueId qid2 = queue2.GetTaskQueueId();
  fml::TaskQueueId qid3 = queue3.GetTaskQueueId();

  // Two mergers will NOT share same inner merger
  const auto merger_from_2_to_1 =
      fml::RasterThreadMerger::CreateOrShareThreadMerger(nullptr, qid1, qid2);
  const auto merger_from_3_to_1 =
      fml::RasterThreadMerger::CreateOrShareThreadMerger(merger_from_2_to_1,
                                                         qid1, qid3);
  const size_t kNumFramesMerged = 5;
  ASSERT_FALSE(merger_from_2_to_1->IsMerged());
  ASSERT_FALSE(merger_from_3_to_1->IsMerged());

  // Merge thread2 into thread1
  merger_from_2_to_1->MergeWithLease(kNumFramesMerged);
  // Merge thread3 into thread1
  merger_from_3_to_1->MergeWithLease(kNumFramesMerged);

  ASSERT_TRUE(merger_from_2_to_1->IsMerged());
  ASSERT_TRUE(merger_from_3_to_1->IsMerged());

  for (size_t i = 0; i < kNumFramesMerged; i++) {
    ASSERT_TRUE(merger_from_2_to_1->IsMerged());
    merger_from_2_to_1->DecrementLease();
  }

  ASSERT_FALSE(merger_from_2_to_1->IsMerged());
  ASSERT_TRUE(merger_from_3_to_1->IsMerged());

  for (size_t i = 0; i < kNumFramesMerged; i++) {
    ASSERT_TRUE(merger_from_3_to_1->IsMerged());
    merger_from_3_to_1->DecrementLease();
  }

  ASSERT_FALSE(merger_from_2_to_1->IsMerged());
  ASSERT_FALSE(merger_from_3_to_1->IsMerged());

  merger_from_2_to_1->MergeWithLease(kNumFramesMerged);
  ASSERT_TRUE(merger_from_2_to_1->IsMerged());
  ASSERT_FALSE(merger_from_3_to_1->IsMerged());
  merger_from_3_to_1->MergeWithLease(kNumFramesMerged);
  ASSERT_TRUE(merger_from_2_to_1->IsMerged());
  ASSERT_TRUE(merger_from_3_to_1->IsMerged());

  // Can unmerge independently
  merger_from_2_to_1->UnMergeNowIfLastOne();
  ASSERT_FALSE(merger_from_2_to_1->IsMerged());
  ASSERT_TRUE(merger_from_3_to_1->IsMerged());

  // Can unmerge independently
  merger_from_3_to_1->UnMergeNowIfLastOne();
  ASSERT_FALSE(merger_from_2_to_1->IsMerged());
  ASSERT_FALSE(merger_from_3_to_1->IsMerged());
}

}  // namespace testing
}  // namespace fml
