5#define FML_USED_ON_EMBEDDER
19#include "third_party/skia/include/core/SkColorSpace.h"
20#include "third_party/skia/include/core/SkSurface.h"
21#include "third_party/skia/include/gpu/ganesh/GrTypes.h"
22#include "third_party/skia/include/gpu/ganesh/SkSurfaceGanesh.h"
24#include "gmock/gmock.h"
28using testing::NiceMock;
30using testing::ReturnRef;
35constexpr float kDevicePixelRatio = 2.0f;
38std::vector<std::unique_ptr<LayerTreeTask>> SingleLayerTreeList(
40 std::unique_ptr<LayerTree> layer_tree,
42 std::vector<std::unique_ptr<LayerTreeTask>> tasks;
43 tasks.push_back(std::make_unique<LayerTreeTask>(
44 view_id, std::move(layer_tree), pixel_ratio));
48class MockDelegate :
public Rasterizer::Delegate {
52 (
const FrameTiming& frame_timing),
55 MOCK_METHOD(
fml::TimePoint, GetLatestFrameTargetTime, (), (
const,
override));
56 MOCK_METHOD(
const TaskRunners&, GetTaskRunners, (), (
const,
override));
58 GetParentRasterThreadMerger,
61 MOCK_METHOD(std::shared_ptr<const fml::SyncSwitch>,
62 GetIsGpuDisabledSyncSwitch,
65 MOCK_METHOD(
const Settings&, GetSettings, (), (
const,
override));
67 ShouldDiscardLayerTree,
74 MOCK_METHOD(
bool, IsValid, (), (
override));
75 MOCK_METHOD(std::unique_ptr<SurfaceFrame>,
79 MOCK_METHOD(
DlMatrix, GetRootTransformation, (), (
const,
override));
80 MOCK_METHOD(GrDirectContext*, GetContext, (), (
override));
81 MOCK_METHOD(std::unique_ptr<GLContextResult>,
82 MakeRenderContextCurrent,
85 MOCK_METHOD(
bool, ClearRenderContext, (), (
override));
86 MOCK_METHOD(
bool, AllowsDrawingWhenGpuDisabled, (), (
const,
override));
89class MockExternalViewEmbedder :
public ExternalViewEmbedder {
91 MOCK_METHOD(DlCanvas*, GetRootCanvas, (), (
override));
92 MOCK_METHOD(
void, CancelFrame, (), (
override));
96 (GrDirectContext * context,
101 (
DlISize frame_size,
double device_pixel_ratio),
104 PrerollCompositeEmbeddedView,
105 (int64_t
view_id, std::unique_ptr<EmbeddedViewParams>
params),
112 MOCK_METHOD(DlCanvas*, CompositeEmbeddedView, (int64_t
view_id), (
override));
115 (int64_t flutter_view_id,
116 GrDirectContext* context,
117 const std::shared_ptr<impeller::AiksContext>& aiks_context,
118 std::unique_ptr<SurfaceFrame> frame),
123 (
bool should_resubmit_frame,
126 MOCK_METHOD(
bool, SupportsDynamicThreadMerging, (), (
override));
131 NiceMock<MockDelegate> delegate;
133 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
134 auto rasterizer = std::make_unique<Rasterizer>(delegate);
135 EXPECT_TRUE(rasterizer !=
nullptr);
138TEST(RasterizerTest, isAiksContextInitialized) {
139 NiceMock<MockDelegate> delegate;
141 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
142 auto rasterizer = std::make_shared<Rasterizer>(delegate);
144 EXPECT_TRUE(rasterizer !=
nullptr);
145 std::shared_ptr<SnapshotController::Delegate> snapshot_delegate = rasterizer;
147 EXPECT_FALSE(snapshot_delegate->IsAiksContextInitialized());
152 std::unique_ptr<FrameTimingsRecorder> recorder =
153 std::make_unique<FrameTimingsRecorder>();
154 recorder->RecordVsync(timestamp, timestamp);
155 recorder->RecordBuildStart(timestamp);
156 recorder->RecordBuildEnd(timestamp);
164TEST(RasterizerTest, drawEmptyPipeline) {
165 std::string test_name =
166 ::testing::UnitTest::GetInstance()->current_test_info()->name();
167 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
175 NiceMock<MockDelegate> delegate;
177 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
178 ON_CALL(delegate, GetTaskRunners()).WillByDefault(ReturnRef(task_runners));
179 auto rasterizer = std::make_unique<Rasterizer>(delegate);
180 auto surface = std::make_unique<NiceMock<MockSurface>>();
181 EXPECT_CALL(*
surface, MakeRenderContextCurrent())
182 .WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(
true))));
183 rasterizer->Setup(std::move(
surface));
186 auto pipeline = std::make_shared<FramePipeline>(10);
187 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
188 rasterizer->Draw(pipeline);
195 drawWithExternalViewEmbedderExternalViewEmbedderSubmitFrameCalled) {
196 std::string test_name =
197 ::testing::UnitTest::GetInstance()->current_test_info()->name();
198 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
206 NiceMock<MockDelegate> delegate;
208 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
209 EXPECT_CALL(delegate, GetTaskRunners())
210 .WillRepeatedly(ReturnRef(task_runners));
211 EXPECT_CALL(delegate, OnFrameRasterized(_));
212 auto rasterizer = std::make_unique<Rasterizer>(delegate);
213 auto surface = std::make_unique<NiceMock<MockSurface>>();
215 std::shared_ptr<NiceMock<MockExternalViewEmbedder>> external_view_embedder =
216 std::make_shared<NiceMock<MockExternalViewEmbedder>>();
217 rasterizer->SetExternalViewEmbedder(external_view_embedder);
222 auto surface_frame = std::make_unique<SurfaceFrame>(
224 nullptr, framebuffer_info,
228 EXPECT_CALL(*
surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(
true));
230 .WillOnce(Return(ByMove(std::move(surface_frame))));
231 EXPECT_CALL(*
surface, MakeRenderContextCurrent())
232 .WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(
true))));
234 EXPECT_CALL(*external_view_embedder,
239 EXPECT_CALL(*external_view_embedder, PrepareFlutterView(
243 EXPECT_CALL(*external_view_embedder,
247 *external_view_embedder,
253 rasterizer->Setup(std::move(
surface));
256 auto pipeline = std::make_shared<FramePipeline>(10);
257 auto layer_tree = std::make_unique<LayerTree>(
nullptr,
259 auto layer_tree_item = std::make_unique<FrameItem>(
264 pipeline->Produce().Complete(std::move(layer_tree_item));
266 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
267 rasterizer->Draw(pipeline);
275 drawWithExternalViewEmbedderAndThreadMergerNotMergedExternalViewEmbedderSubmitFrameNotCalled) {
276 std::string test_name =
277 ::testing::UnitTest::GetInstance()->current_test_info()->name();
278 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
286 NiceMock<MockDelegate> delegate;
288 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
289 EXPECT_CALL(delegate, GetTaskRunners())
290 .WillRepeatedly(ReturnRef(task_runners));
291 EXPECT_CALL(delegate, OnFrameRasterized(_));
292 auto rasterizer = std::make_unique<Rasterizer>(delegate);
293 auto surface = std::make_unique<NiceMock<MockSurface>>();
294 std::shared_ptr<NiceMock<MockExternalViewEmbedder>> external_view_embedder =
295 std::make_shared<NiceMock<MockExternalViewEmbedder>>();
296 rasterizer->SetExternalViewEmbedder(external_view_embedder);
297 EXPECT_CALL(*external_view_embedder, SupportsDynamicThreadMerging)
298 .WillRepeatedly(Return(
true));
301 auto surface_frame = std::make_unique<SurfaceFrame>(
303 nullptr, framebuffer_info,
307 EXPECT_CALL(*
surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(
true));
309 .WillOnce(Return(ByMove(std::move(surface_frame))));
310 EXPECT_CALL(*
surface, MakeRenderContextCurrent())
311 .WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(
true))));
313 EXPECT_CALL(*external_view_embedder, BeginFrame(
nullptr,
316 EXPECT_CALL(*external_view_embedder, PrepareFlutterView(
320 EXPECT_CALL(*external_view_embedder,
323 EXPECT_CALL(*external_view_embedder, EndFrame(
false,
327 rasterizer->Setup(std::move(
surface));
330 auto pipeline = std::make_shared<FramePipeline>(10);
331 auto layer_tree = std::make_unique<LayerTree>(
333 auto layer_tree_item = std::make_unique<FrameItem>(
338 pipeline->Produce().Complete(std::move(layer_tree_item));
340 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
341 rasterizer->Draw(pipeline);
349 drawWithExternalViewEmbedderAndThreadsMergedExternalViewEmbedderSubmitFrameCalled) {
350 std::string test_name =
351 ::testing::UnitTest::GetInstance()->current_test_info()->name();
352 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
363 NiceMock<MockDelegate> delegate;
365 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
366 EXPECT_CALL(delegate, GetTaskRunners())
367 .WillRepeatedly(ReturnRef(task_runners));
368 EXPECT_CALL(delegate, OnFrameRasterized(_));
370 auto rasterizer = std::make_unique<Rasterizer>(delegate);
371 auto surface = std::make_unique<NiceMock<MockSurface>>();
373 std::shared_ptr<NiceMock<MockExternalViewEmbedder>> external_view_embedder =
374 std::make_shared<NiceMock<MockExternalViewEmbedder>>();
375 rasterizer->SetExternalViewEmbedder(external_view_embedder);
380 auto surface_frame = std::make_unique<SurfaceFrame>(
382 nullptr, framebuffer_info,
386 EXPECT_CALL(*
surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(
true));
388 .WillOnce(Return(ByMove(std::move(surface_frame))));
389 EXPECT_CALL(*
surface, MakeRenderContextCurrent())
390 .WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(
true))));
391 EXPECT_CALL(*external_view_embedder, SupportsDynamicThreadMerging)
392 .WillRepeatedly(Return(
true));
394 EXPECT_CALL(*external_view_embedder, BeginFrame(
nullptr,
397 EXPECT_CALL(*external_view_embedder, PrepareFlutterView(
401 EXPECT_CALL(*external_view_embedder,
404 EXPECT_CALL(*external_view_embedder, EndFrame(
false,
408 rasterizer->Setup(std::move(
surface));
410 auto pipeline = std::make_shared<FramePipeline>(10);
411 auto layer_tree = std::make_unique<LayerTree>(
nullptr,
413 auto layer_tree_item = std::make_unique<FrameItem>(
418 pipeline->Produce().Complete(std::move(layer_tree_item));
420 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
421 rasterizer->Draw(pipeline);
425 drawLastLayerTreeWithThreadsMergedExternalViewEmbedderAndEndFrameCalled) {
426 std::string test_name =
427 ::testing::UnitTest::GetInstance()->current_test_info()->name();
428 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
439 NiceMock<MockDelegate> delegate;
441 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
442 EXPECT_CALL(delegate, GetTaskRunners())
443 .WillRepeatedly(ReturnRef(task_runners));
444 EXPECT_CALL(delegate, OnFrameRasterized(_));
446 auto rasterizer = std::make_unique<Rasterizer>(delegate);
447 auto surface = std::make_unique<NiceMock<MockSurface>>();
449 std::shared_ptr<NiceMock<MockExternalViewEmbedder>> external_view_embedder =
450 std::make_shared<NiceMock<MockExternalViewEmbedder>>();
451 rasterizer->SetExternalViewEmbedder(external_view_embedder);
456 auto surface_frame1 = std::make_unique<SurfaceFrame>(
458 nullptr, framebuffer_info,
462 auto surface_frame2 = std::make_unique<SurfaceFrame>(
464 nullptr, framebuffer_info,
468 EXPECT_CALL(*
surface, AllowsDrawingWhenGpuDisabled())
469 .WillRepeatedly(Return(
true));
472 .WillOnce(Return(ByMove(std::move(surface_frame1))))
473 .WillOnce(Return(ByMove(std::move(surface_frame2))));
474 EXPECT_CALL(*
surface, MakeRenderContextCurrent())
475 .WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(
true))));
476 EXPECT_CALL(*external_view_embedder, SupportsDynamicThreadMerging)
477 .WillRepeatedly(Return(
true));
479 EXPECT_CALL(*external_view_embedder, BeginFrame(
nullptr,
482 EXPECT_CALL(*external_view_embedder, PrepareFlutterView(
486 EXPECT_CALL(*external_view_embedder,
489 EXPECT_CALL(*external_view_embedder, EndFrame(
false,
493 rasterizer->Setup(std::move(
surface));
495 auto pipeline = std::make_shared<FramePipeline>(10);
496 auto layer_tree = std::make_unique<LayerTree>(
nullptr,
498 auto layer_tree_item = std::make_unique<FrameItem>(
503 pipeline->Produce().Complete(std::move(layer_tree_item));
508 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
509 rasterizer->Draw(pipeline);
516TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNoSurfaceIsSet) {
517 std::string test_name =
518 ::testing::UnitTest::GetInstance()->current_test_info()->name();
519 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
527 NiceMock<MockDelegate> delegate;
529 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
530 EXPECT_CALL(delegate, GetTaskRunners())
531 .WillRepeatedly(ReturnRef(task_runners));
532 auto rasterizer = std::make_unique<Rasterizer>(delegate);
534 std::shared_ptr<NiceMock<MockExternalViewEmbedder>> external_view_embedder =
535 std::make_shared<NiceMock<MockExternalViewEmbedder>>();
536 rasterizer->SetExternalViewEmbedder(external_view_embedder);
539 *external_view_embedder,
547 auto pipeline = std::make_shared<FramePipeline>(10);
548 auto layer_tree = std::make_unique<LayerTree>(
550 auto layer_tree_item = std::make_unique<FrameItem>(
555 pipeline->Produce().Complete(std::move(layer_tree_item));
557 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
558 rasterizer->Draw(pipeline);
564TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNotUsedThisFrame) {
565 std::string test_name =
566 ::testing::UnitTest::GetInstance()->current_test_info()->name();
567 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
575 NiceMock<MockDelegate> delegate;
577 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
578 EXPECT_CALL(delegate, GetTaskRunners())
579 .WillRepeatedly(ReturnRef(task_runners));
580 auto is_gpu_disabled_sync_switch =
581 std::make_shared<const fml::SyncSwitch>(
false);
582 ON_CALL(delegate, GetIsGpuDisabledSyncSwitch())
583 .WillByDefault(Return(is_gpu_disabled_sync_switch));
585 auto rasterizer = std::make_unique<Rasterizer>(delegate);
586 auto surface = std::make_unique<NiceMock<MockSurface>>();
587 EXPECT_CALL(*
surface, MakeRenderContextCurrent())
588 .WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(
true))));
590 std::shared_ptr<NiceMock<MockExternalViewEmbedder>> external_view_embedder =
591 std::make_shared<NiceMock<MockExternalViewEmbedder>>();
592 rasterizer->SetExternalViewEmbedder(external_view_embedder);
593 rasterizer->Setup(std::move(
surface));
595 EXPECT_CALL(*external_view_embedder, BeginFrame(
nullptr,
598 EXPECT_CALL(*external_view_embedder, PrepareFlutterView(
603 *external_view_embedder,
611 auto pipeline = std::make_shared<FramePipeline>(10);
612 auto layer_tree = std::make_unique<LayerTree>(
614 auto layer_tree_item = std::make_unique<FrameItem>(
619 pipeline->Produce().Complete(std::move(layer_tree_item));
622 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
true));
623 DrawStatus status = rasterizer->Draw(pipeline);
632TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenPipelineIsEmpty) {
633 std::string test_name =
634 ::testing::UnitTest::GetInstance()->current_test_info()->name();
635 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
643 NiceMock<MockDelegate> delegate;
645 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
646 EXPECT_CALL(delegate, GetTaskRunners())
647 .WillRepeatedly(ReturnRef(task_runners));
649 auto rasterizer = std::make_unique<Rasterizer>(delegate);
650 auto surface = std::make_unique<NiceMock<MockSurface>>();
651 EXPECT_CALL(*
surface, MakeRenderContextCurrent())
652 .WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(
true))));
654 std::shared_ptr<NiceMock<MockExternalViewEmbedder>> external_view_embedder =
655 std::make_shared<NiceMock<MockExternalViewEmbedder>>();
656 rasterizer->SetExternalViewEmbedder(external_view_embedder);
657 rasterizer->Setup(std::move(
surface));
660 *external_view_embedder,
668 auto pipeline = std::make_shared<FramePipeline>(10);
669 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
670 DrawStatus status = rasterizer->Draw(pipeline);
677TEST(RasterizerTest, drawMultipleViewsWithExternalViewEmbedder) {
678 std::string test_name =
679 ::testing::UnitTest::GetInstance()->current_test_info()->name();
680 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
688 NiceMock<MockDelegate> delegate;
690 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
691 EXPECT_CALL(delegate, GetTaskRunners())
692 .WillRepeatedly(ReturnRef(task_runners));
693 EXPECT_CALL(delegate, OnFrameRasterized(_));
694 auto rasterizer = std::make_unique<Rasterizer>(delegate);
695 auto surface = std::make_unique<NiceMock<MockSurface>>();
696 std::shared_ptr<NiceMock<MockExternalViewEmbedder>> external_view_embedder =
697 std::make_shared<NiceMock<MockExternalViewEmbedder>>();
698 rasterizer->SetExternalViewEmbedder(external_view_embedder);
699 EXPECT_CALL(*external_view_embedder, SupportsDynamicThreadMerging)
700 .WillRepeatedly(Return(
false));
701 EXPECT_CALL(*
surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(
true));
706 return std::make_unique<SurfaceFrame>(
708 nullptr, framebuffer_info,
713 EXPECT_CALL(*
surface, MakeRenderContextCurrent())
714 .WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(
true))));
716 EXPECT_CALL(*external_view_embedder, BeginFrame(
nullptr,
719 EXPECT_CALL(*external_view_embedder,
723 EXPECT_CALL(*external_view_embedder,
724 SubmitFlutterView(0, _, _, _))
726 EXPECT_CALL(*external_view_embedder,
730 EXPECT_CALL(*external_view_embedder,
731 SubmitFlutterView(1, _, _, _))
733 EXPECT_CALL(*external_view_embedder, EndFrame(
false,
737 rasterizer->Setup(std::move(
surface));
740 auto pipeline = std::make_shared<FramePipeline>(10);
741 std::vector<std::unique_ptr<LayerTreeTask>> tasks;
742 tasks.push_back(std::make_unique<LayerTreeTask>(
743 0, std::make_unique<LayerTree>(
nullptr,
DlISize()), 1.5));
744 tasks.push_back(std::make_unique<LayerTreeTask>(
745 1, std::make_unique<LayerTree>(
nullptr,
DlISize()), 2.0));
746 auto layer_tree_item = std::make_unique<FrameItem>(
749 pipeline->Produce().Complete(std::move(layer_tree_item));
751 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
752 rasterizer->Draw(pipeline);
759 drawWithGpuEnabledAndSurfaceAllowsDrawingWhenGpuDisabledDoesAcquireFrame) {
760 std::string test_name =
761 ::testing::UnitTest::GetInstance()->current_test_info()->name();
762 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
770 NiceMock<MockDelegate> delegate;
772 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
773 EXPECT_CALL(delegate, GetTaskRunners())
774 .WillRepeatedly(ReturnRef(task_runners));
775 EXPECT_CALL(delegate, OnFrameRasterized(_));
777 auto rasterizer = std::make_unique<Rasterizer>(delegate);
778 auto surface = std::make_unique<NiceMock<MockSurface>>();
779 auto is_gpu_disabled_sync_switch =
780 std::make_shared<const fml::SyncSwitch>(
false);
784 auto surface_frame = std::make_unique<SurfaceFrame>(
786 nullptr, framebuffer_info,
790 EXPECT_CALL(*
surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(
true));
791 ON_CALL(delegate, GetIsGpuDisabledSyncSwitch())
792 .WillByDefault(Return(is_gpu_disabled_sync_switch));
793 EXPECT_CALL(delegate, GetIsGpuDisabledSyncSwitch()).Times(0);
795 .WillOnce(Return(ByMove(std::move(surface_frame))));
796 EXPECT_CALL(*
surface, MakeRenderContextCurrent())
797 .WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(
true))));
799 rasterizer->Setup(std::move(
surface));
802 auto pipeline = std::make_shared<FramePipeline>(10);
803 auto layer_tree = std::make_unique<LayerTree>(
805 auto layer_tree_item = std::make_unique<FrameItem>(
810 pipeline->Produce().Complete(std::move(layer_tree_item));
812 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
813 rasterizer->Draw(pipeline);
821 drawWithGpuDisabledAndSurfaceAllowsDrawingWhenGpuDisabledDoesAcquireFrame) {
822 std::string test_name =
823 ::testing::UnitTest::GetInstance()->current_test_info()->name();
824 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
832 NiceMock<MockDelegate> delegate;
834 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
835 EXPECT_CALL(delegate, GetTaskRunners())
836 .WillRepeatedly(ReturnRef(task_runners));
837 EXPECT_CALL(delegate, OnFrameRasterized(_));
838 auto rasterizer = std::make_unique<Rasterizer>(delegate);
839 auto surface = std::make_unique<NiceMock<MockSurface>>();
840 auto is_gpu_disabled_sync_switch =
841 std::make_shared<const fml::SyncSwitch>(
true);
846 auto surface_frame = std::make_unique<SurfaceFrame>(
848 nullptr, framebuffer_info,
852 EXPECT_CALL(*
surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(
true));
853 ON_CALL(delegate, GetIsGpuDisabledSyncSwitch())
854 .WillByDefault(Return(is_gpu_disabled_sync_switch));
855 EXPECT_CALL(delegate, GetIsGpuDisabledSyncSwitch()).Times(0);
857 .WillOnce(Return(ByMove(std::move(surface_frame))));
858 EXPECT_CALL(*
surface, MakeRenderContextCurrent())
859 .WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(
true))));
861 rasterizer->Setup(std::move(
surface));
864 auto pipeline = std::make_shared<FramePipeline>(10);
865 auto layer_tree = std::make_unique<LayerTree>(
867 auto layer_tree_item = std::make_unique<FrameItem>(
872 pipeline->Produce().Complete(std::move(layer_tree_item));
874 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
875 DrawStatus status = rasterizer->Draw(pipeline);
884 drawWithGpuEnabledAndSurfaceDisallowsDrawingWhenGpuDisabledDoesAcquireFrame) {
885 std::string test_name =
886 ::testing::UnitTest::GetInstance()->current_test_info()->name();
887 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
895 NiceMock<MockDelegate> delegate;
897 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
898 EXPECT_CALL(delegate, GetTaskRunners())
899 .WillRepeatedly(ReturnRef(task_runners));
900 EXPECT_CALL(delegate, OnFrameRasterized(_));
901 auto rasterizer = std::make_unique<Rasterizer>(delegate);
902 auto surface = std::make_unique<NiceMock<MockSurface>>();
903 auto is_gpu_disabled_sync_switch =
904 std::make_shared<const fml::SyncSwitch>(
false);
909 auto surface_frame = std::make_unique<SurfaceFrame>(
911 nullptr, framebuffer_info,
915 EXPECT_CALL(*
surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(
false));
916 EXPECT_CALL(delegate, GetIsGpuDisabledSyncSwitch())
917 .WillOnce(Return(is_gpu_disabled_sync_switch));
919 .WillOnce(Return(ByMove(std::move(surface_frame))));
920 EXPECT_CALL(*
surface, MakeRenderContextCurrent())
921 .WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(
true))));
923 rasterizer->Setup(std::move(
surface));
926 auto pipeline = std::make_shared<FramePipeline>(10);
927 auto layer_tree = std::make_unique<LayerTree>(
929 auto layer_tree_item = std::make_unique<FrameItem>(
934 pipeline->Produce().Complete(std::move(layer_tree_item));
936 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
937 DrawStatus status = rasterizer->Draw(pipeline);
946 drawWithGpuDisabledAndSurfaceDisallowsDrawingWhenGpuDisabledDoesntAcquireFrame) {
947 std::string test_name =
948 ::testing::UnitTest::GetInstance()->current_test_info()->name();
949 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
957 NiceMock<MockDelegate> delegate;
959 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
960 EXPECT_CALL(delegate, GetTaskRunners())
961 .WillRepeatedly(ReturnRef(task_runners));
962 EXPECT_CALL(delegate, OnFrameRasterized(_)).Times(0);
963 auto rasterizer = std::make_unique<Rasterizer>(delegate);
964 auto surface = std::make_unique<NiceMock<MockSurface>>();
965 auto is_gpu_disabled_sync_switch =
966 std::make_shared<const fml::SyncSwitch>(
true);
971 auto surface_frame = std::make_unique<SurfaceFrame>(
973 nullptr, framebuffer_info,
977 EXPECT_CALL(*
surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(
false));
978 EXPECT_CALL(delegate, GetIsGpuDisabledSyncSwitch())
979 .WillOnce(Return(is_gpu_disabled_sync_switch));
981 EXPECT_CALL(*
surface, MakeRenderContextCurrent())
982 .WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(
true))));
984 rasterizer->Setup(std::move(
surface));
987 auto pipeline = std::make_shared<FramePipeline>(10);
988 auto layer_tree = std::make_unique<LayerTree>(
990 auto layer_tree_item = std::make_unique<FrameItem>(
995 pipeline->Produce().Complete(std::move(layer_tree_item));
997 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
998 DrawStatus status = rasterizer->Draw(pipeline);
1007 FrameTimingRecorderShouldStartRecordingRasterTimeBeforeSurfaceAcquireFrame) {
1008 std::string test_name =
1009 ::testing::UnitTest::GetInstance()->current_test_info()->name();
1010 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
1017 thread_host.
io_thread->GetTaskRunner());
1018 NiceMock<MockDelegate> delegate;
1020 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
1021 EXPECT_CALL(delegate, GetTaskRunners())
1022 .WillRepeatedly(ReturnRef(task_runners));
1023 EXPECT_CALL(delegate, OnFrameRasterized(_))
1031 auto rasterizer = std::make_unique<Rasterizer>(delegate);
1032 auto surface = std::make_unique<NiceMock<MockSurface>>();
1033 auto is_gpu_disabled_sync_switch =
1034 std::make_shared<const fml::SyncSwitch>(
false);
1035 ON_CALL(delegate, GetIsGpuDisabledSyncSwitch())
1036 .WillByDefault(Return(is_gpu_disabled_sync_switch));
1038 .WillByDefault(::testing::Invoke([] {
return nullptr; }));
1040 EXPECT_CALL(*
surface, MakeRenderContextCurrent())
1041 .WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(
true))));
1042 rasterizer->Setup(std::move(
surface));
1045 auto pipeline = std::make_shared<FramePipeline>(10);
1046 auto layer_tree = std::make_unique<LayerTree>(
1048 auto layer_tree_item = std::make_unique<FrameItem>(
1053 pipeline->Produce().Complete(std::move(layer_tree_item));
1055 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
1056 DrawStatus status = rasterizer->Draw(pipeline);
1066 drawLayerTreeWithCorrectFrameTimingWhenPipelineIsMoreAvailable) {
1067 std::string test_name =
1068 ::testing::UnitTest::GetInstance()->current_test_info()->name();
1069 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
1076 thread_host.
io_thread->GetTaskRunner());
1077 NiceMock<MockDelegate> delegate;
1079 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
1080 ON_CALL(delegate, GetTaskRunners()).WillByDefault(ReturnRef(task_runners));
1083 std::unique_ptr<Rasterizer> rasterizer;
1085 rasterizer = std::make_unique<Rasterizer>(delegate);
1090 auto surface = std::make_unique<NiceMock<MockSurface>>();
1091 EXPECT_CALL(*
surface, AllowsDrawingWhenGpuDisabled())
1092 .WillRepeatedly(Return(
true));
1094 .WillByDefault(::testing::Invoke([] {
1097 return std::make_unique<SurfaceFrame>(
1099 nullptr, framebuffer_info,
1105 ON_CALL(*
surface, MakeRenderContextCurrent())
1106 .WillByDefault(::testing::Invoke(
1107 [] {
return std::make_unique<GLContextDefaultResult>(
true); }));
1112 std::vector<fml::TimePoint> timestamps = {first_timestamp, second_timestamp};
1113 int frame_rasterized_count = 0;
1114 EXPECT_CALL(delegate, OnFrameRasterized(_))
1116 .WillRepeatedly([&](
const FrameTiming& frame_timing) {
1117 EXPECT_EQ(timestamps[frame_rasterized_count],
1119 EXPECT_EQ(timestamps[frame_rasterized_count],
1121 EXPECT_EQ(timestamps[frame_rasterized_count],
1123 frame_rasterized_count++;
1128 rasterizer->Setup(std::move(
surface));
1129 auto pipeline = std::make_shared<FramePipeline>(10);
1130 for (
int i = 0;
i < 2;
i++) {
1131 auto layer_tree = std::make_unique<LayerTree>(
1133 auto layer_tree_item = std::make_unique<FrameItem>(
1138 pipeline->Produce().Complete(std::move(layer_tree_item));
1144 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
1145 rasterizer->Draw(pipeline);
1147 count_down_latch.
Wait();
1155TEST(RasterizerTest, TeardownFreesResourceCache) {
1156 std::string test_name =
1157 ::testing::UnitTest::GetInstance()->current_test_info()->name();
1158 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
1165 thread_host.
io_thread->GetTaskRunner());
1167 NiceMock<MockDelegate> delegate;
1169 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
1170 EXPECT_CALL(delegate, GetTaskRunners())
1171 .WillRepeatedly(ReturnRef(task_runners));
1173 auto rasterizer = std::make_unique<Rasterizer>(delegate);
1174 auto surface = std::make_unique<NiceMock<MockSurface>>();
1175 auto context = GrDirectContext::MakeMock(
nullptr);
1176 context->setResourceCacheLimit(0);
1178 EXPECT_CALL(*
surface, MakeRenderContextCurrent())
1179 .WillRepeatedly([]() -> std::unique_ptr<GLContextResult> {
1180 return std::make_unique<GLContextDefaultResult>(
true);
1182 EXPECT_CALL(*
surface, GetContext()).WillRepeatedly(Return(context.get()));
1184 rasterizer->Setup(std::move(
surface));
1185 EXPECT_EQ(context->getResourceCacheLimit(), 0ul);
1187 rasterizer->SetResourceCacheMaxBytes(10000000,
false);
1188 EXPECT_EQ(context->getResourceCacheLimit(), 10000000ul);
1189 EXPECT_EQ(context->getResourceCachePurgeableBytes(), 0ul);
1193 context->getResourceCacheUsage(&count, &bytes);
1194 EXPECT_EQ(bytes, 0ul);
1197 SkImageInfo::MakeN32Premul(500, 500, SkColorSpace::MakeSRGB());
1198 auto sk_surface = SkSurfaces::RenderTarget(context.get(),
1199 skgpu::Budgeted::kYes, image_info);
1200 EXPECT_TRUE(sk_surface);
1203 sk_surface->getCanvas()->drawPaint(paint);
1204 context->flushAndSubmit(GrSyncCpu::kYes);
1206 EXPECT_EQ(context->getResourceCachePurgeableBytes(), 0ul);
1210 context->getResourceCacheUsage(&count, &bytes);
1211 EXPECT_GT(bytes, 0ul);
1212 EXPECT_GT(context->getResourceCachePurgeableBytes(), 0ul);
1214 rasterizer->Teardown();
1215 EXPECT_EQ(context->getResourceCachePurgeableBytes(), 0ul);
1218TEST(RasterizerTest, TeardownNoSurface) {
1219 std::string test_name =
1220 ::testing::UnitTest::GetInstance()->current_test_info()->name();
1221 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
1228 thread_host.
io_thread->GetTaskRunner());
1230 NiceMock<MockDelegate> delegate;
1232 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
1233 EXPECT_CALL(delegate, GetTaskRunners())
1234 .WillRepeatedly(ReturnRef(task_runners));
1236 auto rasterizer = std::make_unique<Rasterizer>(delegate);
1238 EXPECT_TRUE(rasterizer);
1239 rasterizer->Teardown();
1242TEST(RasterizerTest, presentationTimeSetWhenVsyncTargetInFuture) {
1243 GTEST_SKIP() <<
"eglPresentationTime is disabled due to "
1244 "https://github.com/flutter/flutter/issues/112503";
1246 std::string test_name =
1247 ::testing::UnitTest::GetInstance()->current_test_info()->name();
1248 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
1254 thread_host.
io_thread->GetTaskRunner());
1256 NiceMock<MockDelegate> delegate;
1258 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
1259 ON_CALL(delegate, GetTaskRunners()).WillByDefault(ReturnRef(task_runners));
1262 std::unique_ptr<Rasterizer> rasterizer;
1264 rasterizer = std::make_unique<Rasterizer>(delegate);
1271 auto second_timestamp = first_timestamp + millis_16;
1272 std::vector<fml::TimePoint> timestamps = {first_timestamp, second_timestamp};
1274 int frames_submitted = 0;
1276 auto surface = std::make_unique<MockSurface>();
1277 ON_CALL(*
surface, AllowsDrawingWhenGpuDisabled()).WillByDefault(Return(
true));
1279 .WillByDefault(::testing::Invoke([&] {
1282 return std::make_unique<SurfaceFrame>(
1283 nullptr, framebuffer_info,
1286 const auto pres_time = *frame.
submit_info().presentation_time;
1287 const auto diff = pres_time - first_timestamp;
1288 int num_frames_submitted = frames_submitted++;
1289 EXPECT_EQ(diff.ToMilliseconds(),
1290 num_frames_submitted * millis_16.ToMilliseconds());
1297 ON_CALL(*
surface, MakeRenderContextCurrent())
1298 .WillByDefault(::testing::Invoke(
1299 [] {
return std::make_unique<GLContextDefaultResult>(
true); }));
1302 rasterizer->Setup(std::move(
surface));
1303 auto pipeline = std::make_shared<FramePipeline>(10);
1304 for (
int i = 0;
i < 2;
i++) {
1305 auto layer_tree = std::make_unique<LayerTree>(
1307 auto layer_tree_item = std::make_unique<FrameItem>(
1312 pipeline->Produce().Complete(std::move(layer_tree_item));
1318 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
1319 rasterizer->Draw(pipeline);
1322 submit_latch.
Wait();
1331TEST(RasterizerTest, presentationTimeNotSetWhenVsyncTargetInPast) {
1332 GTEST_SKIP() <<
"eglPresentationTime is disabled due to "
1333 "https://github.com/flutter/flutter/issues/112503";
1335 std::string test_name =
1336 ::testing::UnitTest::GetInstance()->current_test_info()->name();
1337 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
1343 thread_host.
io_thread->GetTaskRunner());
1345 NiceMock<MockDelegate> delegate;
1347 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
1348 ON_CALL(delegate, GetTaskRunners()).WillByDefault(ReturnRef(task_runners));
1351 std::unique_ptr<Rasterizer> rasterizer;
1353 rasterizer = std::make_unique<Rasterizer>(delegate);
1362 auto surface = std::make_unique<MockSurface>();
1363 ON_CALL(*
surface, AllowsDrawingWhenGpuDisabled()).WillByDefault(Return(
true));
1365 .WillByDefault(::testing::Invoke([&] {
1368 return std::make_unique<SurfaceFrame>(
1369 nullptr, framebuffer_info,
1372 const std::optional<fml::TimePoint> pres_time =
1374 EXPECT_EQ(pres_time, std::nullopt);
1381 ON_CALL(*
surface, MakeRenderContextCurrent())
1382 .WillByDefault(::testing::Invoke(
1383 [] {
return std::make_unique<GLContextDefaultResult>(
true); }));
1386 rasterizer->Setup(std::move(
surface));
1387 auto pipeline = std::make_shared<FramePipeline>(10);
1388 auto layer_tree = std::make_unique<LayerTree>(
1390 auto layer_tree_item = std::make_unique<FrameItem>(
1395 pipeline->Produce().Complete(std::move(layer_tree_item));
1398 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
1399 rasterizer->Draw(pipeline);
1402 submit_latch.
Wait();
Developer-facing API for rendering anything within the engine.
fml::TimePoint Get(Phase phase) const
const SubmitInfo & submit_info() const
static void EnsureInitializedForCurrentThread()
static FML_EMBEDDER_ONLY MessageLoop & GetCurrent()
static constexpr TimeDelta FromSecondsF(double seconds)
static constexpr TimeDelta FromMilliseconds(int64_t millis)
const EmbeddedViewParams * params
G_BEGIN_DECLS FlutterViewId view_id
static std::unique_ptr< FrameTimingsRecorder > CreateFinishedBuildRecorder()
TEST(FrameTimingsRecorderTest, RecordVsync)
impeller::Matrix DlMatrix
impeller::ISize32 DlISize
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
constexpr FlutterViewId kImplicitViewId
std::chrono::duration< double, std::milli > Milliseconds
The collection of all the threads used by the engine.
std::unique_ptr< fml::Thread > io_thread
std::unique_ptr< fml::Thread > platform_thread
std::unique_ptr< fml::Thread > raster_thread
std::unique_ptr< fml::Thread > ui_thread