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));
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,
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
1041 EXPECT_CALL(*
surface, MakeRenderContextCurrent())
1042 .WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(
true))));
1043 rasterizer->Setup(std::move(
surface));
1046 auto pipeline = std::make_shared<FramePipeline>(10);
1047 auto layer_tree = std::make_unique<LayerTree>(
1049 auto layer_tree_item = std::make_unique<FrameItem>(
1054 pipeline->Produce().Complete(std::move(layer_tree_item));
1056 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
1067 drawLayerTreeWithCorrectFrameTimingWhenPipelineIsMoreAvailable) {
1068 std::string test_name =
1069 ::testing::UnitTest::GetInstance()->current_test_info()->name();
1070 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
1077 thread_host.
io_thread->GetTaskRunner());
1078 NiceMock<MockDelegate> delegate;
1080 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
1081 ON_CALL(delegate, GetTaskRunners()).WillByDefault(ReturnRef(task_runners));
1084 std::unique_ptr<Rasterizer> rasterizer;
1086 rasterizer = std::make_unique<Rasterizer>(delegate);
1091 auto surface = std::make_unique<NiceMock<MockSurface>>();
1092 EXPECT_CALL(*
surface, AllowsDrawingWhenGpuDisabled())
1093 .WillRepeatedly(Return(
true));
1097 return std::make_unique<SurfaceFrame>(
1099 nullptr, framebuffer_info,
1105 ON_CALL(*
surface, MakeRenderContextCurrent()).WillByDefault([] {
1106 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));
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, TeardownClearsRenderContext) {
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());
1229 NiceMock<MockDelegate> delegate;
1231 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
1232 ON_CALL(delegate, GetTaskRunners()).WillByDefault(ReturnRef(task_runners));
1233 auto rasterizer = std::make_unique<Rasterizer>(delegate);
1234 auto surface = std::make_unique<NiceMock<MockSurface>>();
1235 bool render_context_is_current =
false;
1236 EXPECT_CALL(*
surface, MakeRenderContextCurrent()).WillRepeatedly([&]() {
1237 render_context_is_current =
true;
1238 return std::make_unique<GLContextDefaultResult>(
true);
1240 EXPECT_CALL(*
surface, ClearRenderContext()).WillRepeatedly([&]() {
1241 render_context_is_current =
false;
1245 rasterizer->Setup(std::move(
surface));
1246 EXPECT_TRUE(render_context_is_current);
1248 rasterizer->Teardown();
1249 EXPECT_FALSE(render_context_is_current);
1252TEST(RasterizerTest, TeardownNoSurface) {
1253 std::string test_name =
1254 ::testing::UnitTest::GetInstance()->current_test_info()->name();
1255 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
1262 thread_host.
io_thread->GetTaskRunner());
1264 NiceMock<MockDelegate> delegate;
1266 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
1267 EXPECT_CALL(delegate, GetTaskRunners())
1268 .WillRepeatedly(ReturnRef(task_runners));
1270 auto rasterizer = std::make_unique<Rasterizer>(delegate);
1272 EXPECT_TRUE(rasterizer);
1273 rasterizer->Teardown();
1276TEST(RasterizerTest, presentationTimeSetWhenVsyncTargetInFuture) {
1277 GTEST_SKIP() <<
"eglPresentationTime is disabled due to "
1278 "https://github.com/flutter/flutter/issues/112503";
1280 std::string test_name =
1281 ::testing::UnitTest::GetInstance()->current_test_info()->name();
1282 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
1288 thread_host.
io_thread->GetTaskRunner());
1290 NiceMock<MockDelegate> delegate;
1292 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
1293 ON_CALL(delegate, GetTaskRunners()).WillByDefault(ReturnRef(task_runners));
1296 std::unique_ptr<Rasterizer> rasterizer;
1298 rasterizer = std::make_unique<Rasterizer>(delegate);
1305 auto second_timestamp = first_timestamp + millis_16;
1306 std::vector<fml::TimePoint> timestamps = {first_timestamp, second_timestamp};
1308 int frames_submitted = 0;
1310 auto surface = std::make_unique<MockSurface>();
1311 ON_CALL(*
surface, AllowsDrawingWhenGpuDisabled()).WillByDefault(Return(
true));
1313 .WillByDefault([&] {
1316 return std::make_unique<SurfaceFrame>(
1317 nullptr, framebuffer_info,
1320 const auto pres_time = *frame.
submit_info().presentation_time;
1321 const auto diff = pres_time - first_timestamp;
1322 int num_frames_submitted = frames_submitted++;
1323 EXPECT_EQ(diff.ToMilliseconds(),
1324 num_frames_submitted * millis_16.ToMilliseconds());
1331 ON_CALL(*
surface, MakeRenderContextCurrent())
1333 [] {
return std::make_unique<GLContextDefaultResult>(
true); });
1336 rasterizer->Setup(std::move(
surface));
1337 auto pipeline = std::make_shared<FramePipeline>(10);
1338 for (
int i = 0;
i < 2;
i++) {
1339 auto layer_tree = std::make_unique<LayerTree>(
1341 auto layer_tree_item = std::make_unique<FrameItem>(
1346 pipeline->Produce().Complete(std::move(layer_tree_item));
1352 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
1356 submit_latch.
Wait();
1365TEST(RasterizerTest, presentationTimeNotSetWhenVsyncTargetInPast) {
1366 GTEST_SKIP() <<
"eglPresentationTime is disabled due to "
1367 "https://github.com/flutter/flutter/issues/112503";
1369 std::string test_name =
1370 ::testing::UnitTest::GetInstance()->current_test_info()->name();
1371 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
1377 thread_host.
io_thread->GetTaskRunner());
1379 NiceMock<MockDelegate> delegate;
1381 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
1382 ON_CALL(delegate, GetTaskRunners()).WillByDefault(ReturnRef(task_runners));
1385 std::unique_ptr<Rasterizer> rasterizer;
1387 rasterizer = std::make_unique<Rasterizer>(delegate);
1396 auto surface = std::make_unique<MockSurface>();
1397 ON_CALL(*
surface, AllowsDrawingWhenGpuDisabled()).WillByDefault(Return(
true));
1399 .WillByDefault([&] {
1402 return std::make_unique<SurfaceFrame>(
1403 nullptr, framebuffer_info,
1406 const std::optional<fml::TimePoint> pres_time =
1408 EXPECT_EQ(pres_time, std::nullopt);
1415 ON_CALL(*
surface, MakeRenderContextCurrent())
1417 [] {
return std::make_unique<GLContextDefaultResult>(
true); });
1420 rasterizer->Setup(std::move(
surface));
1421 auto pipeline = std::make_shared<FramePipeline>(10);
1422 auto layer_tree = std::make_unique<LayerTree>(
1424 auto layer_tree_item = std::make_unique<FrameItem>(
1429 pipeline->Produce().Complete(std::move(layer_tree_item));
1432 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
1436 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
std::shared_ptr< ContextGLES > context
std::shared_ptr< PipelineGLES > pipeline
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