5#define FML_USED_ON_EMBEDDER
7#include "flutter/fml/raster_thread_merger.h"
11#include "flutter/fml/memory/ref_ptr.h"
12#include "flutter/fml/message_loop.h"
13#include "flutter/fml/synchronization/count_down_latch.h"
14#include "flutter/fml/synchronization/waitable_event.h"
15#include "flutter/fml/task_runner.h"
16#include "flutter/fml/thread.h"
17#include "gtest/gtest.h"
63 const auto raster_thread_merger =
64 fml::MakeRefCounted<fml::RasterThreadMerger>(qid1, qid2);
65 const size_t kNumFramesMerged = 5;
67 ASSERT_FALSE(raster_thread_merger->IsMerged());
69 raster_thread_merger->MergeWithLease(kNumFramesMerged);
71 for (
size_t i = 0;
i < kNumFramesMerged;
i++) {
72 ASSERT_TRUE(raster_thread_merger->IsMerged());
73 raster_thread_merger->DecrementLease();
76 ASSERT_FALSE(raster_thread_merger->IsMerged());
82 std::thread thread1([&
loop1, &latch1]() {
85 loop1->GetTaskRunner()->PostTask([&]() { latch1.
Signal(); });
91 std::thread thread2([&
loop2, &latch2]() {
94 loop2->GetTaskRunner()->PostTask([&]() { latch2.
Signal(); });
103 const auto raster_thread_merger =
104 fml::MakeRefCounted<fml::RasterThreadMerger>(qid1, qid2);
108 loop1->GetTaskRunner()->PostTask([&]() {
109 ASSERT_FALSE(raster_thread_merger->IsOnRasterizingThread());
110 ASSERT_TRUE(raster_thread_merger->IsOnPlatformThread());
112 pre_merge.CountDown();
115 loop2->GetTaskRunner()->PostTask([&]() {
116 ASSERT_TRUE(raster_thread_merger->IsOnRasterizingThread());
117 ASSERT_FALSE(raster_thread_merger->IsOnPlatformThread());
119 pre_merge.CountDown();
124 raster_thread_merger->MergeWithLease(1);
126 loop1->GetTaskRunner()->PostTask([&]() {
127 ASSERT_TRUE(raster_thread_merger->IsOnRasterizingThread());
128 ASSERT_TRUE(raster_thread_merger->IsOnPlatformThread());
130 post_merge.CountDown();
133 loop2->GetTaskRunner()->PostTask([&]() {
136 ASSERT_TRUE(raster_thread_merger->IsOnRasterizingThread());
137 ASSERT_TRUE(raster_thread_merger->IsOnPlatformThread());
139 post_merge.CountDown();
144 raster_thread_merger->DecrementLease();
146 loop1->GetTaskRunner()->PostTask([&]() {
147 ASSERT_FALSE(raster_thread_merger->IsOnRasterizingThread());
148 ASSERT_TRUE(raster_thread_merger->IsOnPlatformThread());
153 loop2->GetTaskRunner()->PostTask([&]() {
154 ASSERT_TRUE(raster_thread_merger->IsOnRasterizingThread());
155 ASSERT_FALSE(raster_thread_merger->IsOnPlatformThread());
162 loop1->GetTaskRunner()->PostTask([&]() {
loop1->Terminate(); });
164 loop2->GetTaskRunner()->PostTask([&]() {
loop2->Terminate(); });
176 const auto raster_thread_merger =
177 fml::MakeRefCounted<fml::RasterThreadMerger>(qid1, qid2);
178 const size_t kNumFramesMerged = 5;
180 ASSERT_FALSE(raster_thread_merger->IsMerged());
182 raster_thread_merger->MergeWithLease(kNumFramesMerged);
185 for (
size_t i = 0;
i < kNumFramesMerged - 1;
i++) {
186 ASSERT_TRUE(raster_thread_merger->IsMerged());
187 raster_thread_merger->DecrementLease();
191 raster_thread_merger->ExtendLeaseTo(kNumFramesMerged);
194 for (
size_t i = 0;
i < kNumFramesMerged;
i++) {
195 ASSERT_TRUE(raster_thread_merger->IsMerged());
196 raster_thread_merger->DecrementLease();
199 ASSERT_FALSE(raster_thread_merger->IsMerged());
210 std::thread thread_platform([&]() {
214 create_thread_merger_latch.
Wait();
217 term_platform.
Wait();
220 const size_t kNumFramesMerged = 5;
223 std::thread thread_raster([&]() {
226 latch_platform.
Wait();
231 raster_thread_merger =
232 fml::MakeRefCounted<fml::RasterThreadMerger>(qid_platform, qid_raster);
233 ASSERT_FALSE(raster_thread_merger->
IsMerged());
234 create_thread_merger_latch.
Signal();
240 ASSERT_TRUE(raster_thread_merger->
IsMerged());
242 for (
size_t i = 0;
i < kNumFramesMerged;
i++) {
243 ASSERT_TRUE(raster_thread_merger->
IsMerged());
247 ASSERT_FALSE(raster_thread_merger->
IsMerged());
251 thread_platform.join();
252 thread_raster.join();
259 const auto raster_thread_merger =
260 fml::MakeRefCounted<fml::RasterThreadMerger>(qid1, qid2);
262 ASSERT_TRUE(raster_thread_merger->IsMerged());
266 const size_t kNumFramesMerged = 5;
267 raster_thread_merger->MergeWithLease(kNumFramesMerged);
269 for (
size_t i = 0;
i < kNumFramesMerged;
i++) {
270 ASSERT_TRUE(raster_thread_merger->IsMerged());
271 raster_thread_merger->DecrementLease();
274 ASSERT_TRUE(raster_thread_merger->IsMerged());
277 raster_thread_merger->WaitUntilMerged();
278 ASSERT_TRUE(raster_thread_merger->IsMerged());
286 const auto raster_thread_merger =
287 fml::MakeRefCounted<fml::RasterThreadMerger>(qid1, qid2);
289 raster_thread_merger->Disable();
290 raster_thread_merger->MergeWithLease(1);
291 ASSERT_FALSE(raster_thread_merger->IsMerged());
293 raster_thread_merger->Enable();
294 ASSERT_FALSE(raster_thread_merger->IsMerged());
296 raster_thread_merger->MergeWithLease(1);
297 ASSERT_TRUE(raster_thread_merger->IsMerged());
299 raster_thread_merger->DecrementLease();
300 ASSERT_FALSE(raster_thread_merger->IsMerged());
308 const auto raster_thread_merger =
309 fml::MakeRefCounted<fml::RasterThreadMerger>(qid1, qid2);
311 raster_thread_merger->Disable();
312 ASSERT_FALSE(raster_thread_merger->IsMerged());
314 raster_thread_merger->MergeWithLease(1);
315 ASSERT_FALSE(raster_thread_merger->IsMerged());
317 raster_thread_merger->Enable();
318 raster_thread_merger->MergeWithLease(1);
319 ASSERT_TRUE(raster_thread_merger->IsMerged());
321 raster_thread_merger->Disable();
322 raster_thread_merger->UnMergeNowIfLastOne();
323 ASSERT_TRUE(raster_thread_merger->IsMerged());
326 auto decrement_result = raster_thread_merger->DecrementLease();
330 ASSERT_TRUE(raster_thread_merger->IsMerged());
332 raster_thread_merger->Enable();
333 raster_thread_merger->UnMergeNowIfLastOne();
334 ASSERT_FALSE(raster_thread_merger->IsMerged());
336 raster_thread_merger->MergeWithLease(1);
338 ASSERT_TRUE(raster_thread_merger->IsMerged());
341 auto decrement_result = raster_thread_merger->DecrementLease();
345 ASSERT_FALSE(raster_thread_merger->IsMerged());
353 const auto raster_thread_merger =
354 fml::MakeRefCounted<fml::RasterThreadMerger>(qid1, qid2);
355 ASSERT_TRUE(raster_thread_merger->IsEnabled());
357 raster_thread_merger->Disable();
358 ASSERT_FALSE(raster_thread_merger->IsEnabled());
360 raster_thread_merger->Enable();
361 ASSERT_TRUE(raster_thread_merger->IsEnabled());
373 ASSERT_TRUE(merger1->IsEnabled());
374 ASSERT_TRUE(merger2->IsEnabled());
377 ASSERT_FALSE(merger1->IsEnabled());
378 ASSERT_FALSE(merger2->IsEnabled());
381 ASSERT_TRUE(merger1->IsEnabled());
382 ASSERT_TRUE(merger2->IsEnabled());
388 std::thread thread_platform([&loop_platform, &latch1]() {
392 loop_platform->
Run();
397 std::thread thread_raster([&loop_raster, &loop_platform, &latch1, &latch2]() {
405 loop_raster->GetTaskRunner()->GetTaskQueueId();
407 const auto raster_thread_merger =
408 fml::MakeRefCounted<fml::RasterThreadMerger>(qid_platform, qid_raster);
409 loop_raster->GetTaskRunner()->PostTask([&]() {
410 ASSERT_TRUE(raster_thread_merger->IsOnRasterizingThread());
411 ASSERT_FALSE(raster_thread_merger->IsOnPlatformThread());
413 raster_thread_merger->MergeWithLease(1);
417 loop_raster->GetTaskRunner()->PostTask([&]() {
418 ASSERT_TRUE(raster_thread_merger->IsOnRasterizingThread());
419 ASSERT_TRUE(raster_thread_merger->IsOnPlatformThread());
421 raster_thread_merger->DecrementLease();
425 loop_raster->RunExpiredTasksNow();
434 thread_platform.join();
435 thread_raster.join();
439 fml::Thread platform_thread(
"test_platform_thread");
442 std::thread thread_raster([&]() {
452 const auto raster_thread_merger =
453 fml::MakeRefCounted<fml::RasterThreadMerger>(qid_platform, qid_raster);
455 raster_thread_merger->MergeWithLease(1);
465 ASSERT_TRUE(raster_thread_merger->IsOnRasterizingThread());
466 ASSERT_TRUE(raster_thread_merger->IsOnPlatformThread());
468 raster_thread_merger->DecrementLease();
474 ASSERT_TRUE(raster_thread_merger->IsOnRasterizingThread());
475 ASSERT_FALSE(raster_thread_merger->IsOnPlatformThread());
477 post_unmerge_latch.
Signal();
480 unmerge_latch.
Wait();
483 post_unmerge_latch.
Wait();
488 thread_raster.join();
497 const auto raster_thread_merger =
498 fml::MakeRefCounted<fml::RasterThreadMerger>(qid1, qid2);
501 raster_thread_merger->SetMergeUnmergeCallback(
502 [&callbacks]() { callbacks++; });
504 ASSERT_EQ(0, callbacks);
506 raster_thread_merger->MergeWithLease(1);
507 ASSERT_EQ(1, callbacks);
509 raster_thread_merger->DecrementLease();
510 ASSERT_EQ(2, callbacks);
519 const auto raster_thread_merger1 =
521 const auto raster_thread_merger2 =
524 const size_t kNumFramesMerged = 5;
525 ASSERT_FALSE(raster_thread_merger1->IsMerged());
526 ASSERT_FALSE(raster_thread_merger2->IsMerged());
529 raster_thread_merger1->MergeWithLease(kNumFramesMerged);
531 ASSERT_TRUE(raster_thread_merger1->IsMerged());
532 ASSERT_TRUE(raster_thread_merger2->IsMerged());
535 for (
size_t i = 0;
i < kNumFramesMerged - 1;
i++) {
537 ASSERT_TRUE(raster_thread_merger1->IsMerged());
538 ASSERT_TRUE(raster_thread_merger2->IsMerged());
539 raster_thread_merger1->DecrementLease();
542 ASSERT_TRUE(raster_thread_merger1->IsMerged());
543 ASSERT_TRUE(raster_thread_merger2->IsMerged());
546 raster_thread_merger1->ExtendLeaseTo(kNumFramesMerged);
549 for (
size_t i = 0;
i < kNumFramesMerged;
i++) {
551 ASSERT_TRUE(raster_thread_merger1->IsMerged());
552 ASSERT_TRUE(raster_thread_merger2->IsMerged());
553 raster_thread_merger1->DecrementLease();
556 ASSERT_FALSE(raster_thread_merger1->IsMerged());
557 ASSERT_FALSE(raster_thread_merger2->IsMerged());
566 const auto raster_thread_merger1 =
568 const auto raster_thread_merger2 =
571 const size_t kNumFramesMerged = 5;
572 ASSERT_FALSE(raster_thread_merger1->IsMerged());
573 ASSERT_FALSE(raster_thread_merger2->IsMerged());
576 raster_thread_merger1->MergeWithLease(kNumFramesMerged);
577 ASSERT_TRUE(raster_thread_merger1->IsMerged());
578 ASSERT_TRUE(raster_thread_merger2->IsMerged());
580 raster_thread_merger2->ExtendLeaseTo(kNumFramesMerged);
581 ASSERT_TRUE(raster_thread_merger1->IsMerged());
582 ASSERT_TRUE(raster_thread_merger2->IsMerged());
585 raster_thread_merger1->UnMergeNowIfLastOne();
587 ASSERT_TRUE(raster_thread_merger1->IsMerged());
588 ASSERT_TRUE(raster_thread_merger2->IsMerged());
591 raster_thread_merger2->UnMergeNowIfLastOne();
593 ASSERT_FALSE(raster_thread_merger1->IsMerged());
594 ASSERT_FALSE(raster_thread_merger2->IsMerged());
603 const auto raster_thread_merger1 =
606 const size_t kNumFramesMerged = 1;
607 ASSERT_FALSE(raster_thread_merger1->IsMerged());
610 raster_thread_merger1->MergeWithLease(kNumFramesMerged);
611 ASSERT_TRUE(raster_thread_merger1->IsMerged());
613 for (
size_t i = 0;
i < kNumFramesMerged;
i++) {
615 raster_thread_merger1->DecrementLease();
617 ASSERT_FALSE(raster_thread_merger1->IsMerged());
619 const auto raster_thread_merger2 =
622 ASSERT_FALSE(raster_thread_merger2->IsMerged());
623 raster_thread_merger2->MergeWithLease(kNumFramesMerged);
624 ASSERT_TRUE(raster_thread_merger2->IsMerged());
627 raster_thread_merger2->UnMergeNowIfLastOne();
629 ASSERT_FALSE(raster_thread_merger1->IsMerged());
630 ASSERT_FALSE(raster_thread_merger2->IsMerged());
636 TwoIndependentMergersCanMergeTwoDifferentThreadsIntoSamePlatformThread) {
645 const auto merger_from_2_to_1 =
647 const auto merger_from_3_to_1 =
650 const size_t kNumFramesMerged = 5;
651 ASSERT_FALSE(merger_from_2_to_1->IsMerged());
652 ASSERT_FALSE(merger_from_3_to_1->IsMerged());
655 merger_from_2_to_1->MergeWithLease(kNumFramesMerged);
657 merger_from_3_to_1->MergeWithLease(kNumFramesMerged);
659 ASSERT_TRUE(merger_from_2_to_1->IsMerged());
660 ASSERT_TRUE(merger_from_3_to_1->IsMerged());
662 for (
size_t i = 0;
i < kNumFramesMerged;
i++) {
663 ASSERT_TRUE(merger_from_2_to_1->IsMerged());
664 merger_from_2_to_1->DecrementLease();
667 ASSERT_FALSE(merger_from_2_to_1->IsMerged());
668 ASSERT_TRUE(merger_from_3_to_1->IsMerged());
670 for (
size_t i = 0;
i < kNumFramesMerged;
i++) {
671 ASSERT_TRUE(merger_from_3_to_1->IsMerged());
672 merger_from_3_to_1->DecrementLease();
675 ASSERT_FALSE(merger_from_2_to_1->IsMerged());
676 ASSERT_FALSE(merger_from_3_to_1->IsMerged());
678 merger_from_2_to_1->MergeWithLease(kNumFramesMerged);
679 ASSERT_TRUE(merger_from_2_to_1->IsMerged());
680 ASSERT_FALSE(merger_from_3_to_1->IsMerged());
681 merger_from_3_to_1->MergeWithLease(kNumFramesMerged);
682 ASSERT_TRUE(merger_from_2_to_1->IsMerged());
683 ASSERT_TRUE(merger_from_3_to_1->IsMerged());
686 merger_from_2_to_1->UnMergeNowIfLastOne();
687 ASSERT_FALSE(merger_from_2_to_1->IsMerged());
688 ASSERT_TRUE(merger_from_3_to_1->IsMerged());
691 merger_from_3_to_1->UnMergeNowIfLastOne();
692 ASSERT_FALSE(merger_from_2_to_1->IsMerged());
693 ASSERT_FALSE(merger_from_3_to_1->IsMerged());
static void loop1(skiatest::Reporter *reporter, const char *filename)
static void loop2(skiatest::Reporter *reporter, const char *filename)
static void EnsureInitializedForCurrentThread()
fml::RefPtr< fml::TaskRunner > GetTaskRunner() const
static FML_EMBEDDER_ONLY MessageLoop & GetCurrent()
static TaskQueueId GetCurrentTaskQueueId()
void RunExpiredTasksNow()
static fml::RefPtr< fml::RasterThreadMerger > CreateOrShareThreadMerger(const fml::RefPtr< fml::RasterThreadMerger > &parent_merger, TaskQueueId platform_id, TaskQueueId raster_id)
void MergeWithLease(size_t lease_term)
RasterThreadStatus DecrementLease()
virtual void PostTask(const fml::closure &task) override
virtual TaskQueueId GetTaskQueueId()
fml::RefPtr< fml::TaskRunner > GetTaskRunner() const
TEST(BacktraceTest, CanGatherBacktrace)
A mock task queue NOT calling MessageLoop->Run() in thread.
fml::AutoResetWaitableEvent term
The waiter for thread finished.
fml::AutoResetWaitableEvent latch
The waiter for message loop initialized ok.
fml::TaskQueueId GetTaskQueueId() const