5#define FML_USED_ON_EMBEDDER
7#include "flutter/shell/common/rasterizer.h"
12#include "flutter/flow/frame_timings.h"
13#include "flutter/fml/synchronization/count_down_latch.h"
14#include "flutter/fml/time/time_point.h"
15#include "flutter/shell/common/thread_host.h"
16#include "flutter/testing/testing.h"
23#include "gmock/gmock.h"
27using testing::NiceMock;
29using testing::ReturnRef;
34constexpr float kDevicePixelRatio = 2.0f;
37std::vector<std::unique_ptr<LayerTreeTask>> SingleLayerTreeList(
39 std::unique_ptr<LayerTree> layer_tree,
41 std::vector<std::unique_ptr<LayerTreeTask>> tasks;
42 tasks.push_back(std::make_unique<LayerTreeTask>(
43 view_id, std::move(layer_tree), pixel_ratio));
47class MockDelegate :
public Rasterizer::Delegate {
51 (
const FrameTiming& frame_timing),
54 MOCK_METHOD(
fml::TimePoint, GetLatestFrameTargetTime, (), (
const,
override));
55 MOCK_METHOD(
const TaskRunners&, GetTaskRunners, (), (
const,
override));
57 GetParentRasterThreadMerger,
60 MOCK_METHOD(std::shared_ptr<const fml::SyncSwitch>,
61 GetIsGpuDisabledSyncSwitch,
64 MOCK_METHOD(
const Settings&, GetSettings, (), (
const,
override));
66 ShouldDiscardLayerTree,
73 MOCK_METHOD(
bool, IsValid, (), (
override));
74 MOCK_METHOD(std::unique_ptr<SurfaceFrame>,
78 MOCK_METHOD(
SkMatrix, GetRootTransformation, (), (
const,
override));
80 MOCK_METHOD(std::unique_ptr<GLContextResult>,
81 MakeRenderContextCurrent,
84 MOCK_METHOD(
bool, ClearRenderContext, (), (
override));
85 MOCK_METHOD(
bool, AllowsDrawingWhenGpuDisabled, (), (
const,
override));
88class MockExternalViewEmbedder :
public ExternalViewEmbedder {
90 MOCK_METHOD(DlCanvas*, GetRootCanvas, (), (
override));
91 MOCK_METHOD(
void, CancelFrame, (), (
override));
100 (
SkISize frame_size,
double device_pixel_ratio),
103 PrerollCompositeEmbeddedView,
104 (int64_t view_id, std::unique_ptr<EmbeddedViewParams>
params),
111 MOCK_METHOD(DlCanvas*, CompositeEmbeddedView, (int64_t view_id), (
override));
114 (int64_t flutter_view_id,
116 const std::shared_ptr<impeller::AiksContext>& aiks_context,
117 std::unique_ptr<SurfaceFrame>
frame),
122 (
bool should_resubmit_frame,
125 MOCK_METHOD(
bool, SupportsDynamicThreadMerging, (), (
override));
130 NiceMock<MockDelegate> delegate;
132 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
133 auto rasterizer = std::make_unique<Rasterizer>(delegate);
139 std::unique_ptr<FrameTimingsRecorder> recorder =
140 std::make_unique<FrameTimingsRecorder>();
141 recorder->RecordVsync(timestamp, timestamp);
142 recorder->RecordBuildStart(timestamp);
143 recorder->RecordBuildEnd(timestamp);
151TEST(RasterizerTest, drawEmptyPipeline) {
152 std::string test_name =
153 ::testing::UnitTest::GetInstance()->current_test_info()->name();
154 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
162 NiceMock<MockDelegate> delegate;
164 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
165 ON_CALL(delegate, GetTaskRunners()).WillByDefault(ReturnRef(task_runners));
166 auto rasterizer = std::make_unique<Rasterizer>(delegate);
167 auto surface = std::make_unique<NiceMock<MockSurface>>();
168 EXPECT_CALL(*
surface, MakeRenderContextCurrent())
169 .WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(
true))));
170 rasterizer->Setup(std::move(
surface));
173 auto pipeline = std::make_shared<FramePipeline>(10);
174 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
175 rasterizer->Draw(pipeline);
182 drawWithExternalViewEmbedderExternalViewEmbedderSubmitFrameCalled) {
183 std::string test_name =
184 ::testing::UnitTest::GetInstance()->current_test_info()->name();
185 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
193 NiceMock<MockDelegate> delegate;
195 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
196 EXPECT_CALL(delegate, GetTaskRunners())
197 .WillRepeatedly(ReturnRef(task_runners));
198 EXPECT_CALL(delegate, OnFrameRasterized(_));
199 auto rasterizer = std::make_unique<Rasterizer>(delegate);
200 auto surface = std::make_unique<NiceMock<MockSurface>>();
202 std::shared_ptr<NiceMock<MockExternalViewEmbedder>> external_view_embedder =
203 std::make_shared<NiceMock<MockExternalViewEmbedder>>();
204 rasterizer->SetExternalViewEmbedder(external_view_embedder);
209 auto surface_frame = std::make_unique<SurfaceFrame>(
211 nullptr, framebuffer_info,
214 EXPECT_CALL(*
surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(
true));
216 .WillOnce(Return(ByMove(std::move(surface_frame))));
217 EXPECT_CALL(*
surface, MakeRenderContextCurrent())
218 .WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(
true))));
220 EXPECT_CALL(*external_view_embedder,
225 EXPECT_CALL(*external_view_embedder, PrepareFlutterView(
229 EXPECT_CALL(*external_view_embedder,
233 *external_view_embedder,
239 rasterizer->Setup(std::move(
surface));
242 auto pipeline = std::make_shared<FramePipeline>(10);
246 auto layer_tree_item = std::make_unique<FrameItem>(
251 pipeline->Produce().Complete(std::move(layer_tree_item));
253 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
254 rasterizer->Draw(pipeline);
262 drawWithExternalViewEmbedderAndThreadMergerNotMergedExternalViewEmbedderSubmitFrameNotCalled) {
263 std::string test_name =
264 ::testing::UnitTest::GetInstance()->current_test_info()->name();
265 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
273 NiceMock<MockDelegate> delegate;
275 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
276 EXPECT_CALL(delegate, GetTaskRunners())
277 .WillRepeatedly(ReturnRef(task_runners));
278 EXPECT_CALL(delegate, OnFrameRasterized(_));
279 auto rasterizer = std::make_unique<Rasterizer>(delegate);
280 auto surface = std::make_unique<NiceMock<MockSurface>>();
281 std::shared_ptr<NiceMock<MockExternalViewEmbedder>> external_view_embedder =
282 std::make_shared<NiceMock<MockExternalViewEmbedder>>();
283 rasterizer->SetExternalViewEmbedder(external_view_embedder);
284 EXPECT_CALL(*external_view_embedder, SupportsDynamicThreadMerging)
285 .WillRepeatedly(Return(
true));
288 auto surface_frame = std::make_unique<SurfaceFrame>(
290 nullptr, framebuffer_info,
293 EXPECT_CALL(*
surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(
true));
295 .WillOnce(Return(ByMove(std::move(surface_frame))));
296 EXPECT_CALL(*
surface, MakeRenderContextCurrent())
297 .WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(
true))));
299 EXPECT_CALL(*external_view_embedder, BeginFrame(
nullptr,
302 EXPECT_CALL(*external_view_embedder, PrepareFlutterView(
306 EXPECT_CALL(*external_view_embedder,
309 EXPECT_CALL(*external_view_embedder, EndFrame(
false,
313 rasterizer->Setup(std::move(
surface));
316 auto pipeline = std::make_shared<FramePipeline>(10);
317 auto layer_tree = std::make_unique<LayerTree>(
319 auto layer_tree_item = std::make_unique<FrameItem>(
324 pipeline->Produce().Complete(std::move(layer_tree_item));
326 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
327 rasterizer->Draw(pipeline);
335 drawWithExternalViewEmbedderAndThreadsMergedExternalViewEmbedderSubmitFrameCalled) {
336 std::string test_name =
337 ::testing::UnitTest::GetInstance()->current_test_info()->name();
338 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
349 NiceMock<MockDelegate> delegate;
351 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
352 EXPECT_CALL(delegate, GetTaskRunners())
353 .WillRepeatedly(ReturnRef(task_runners));
354 EXPECT_CALL(delegate, OnFrameRasterized(_));
356 auto rasterizer = std::make_unique<Rasterizer>(delegate);
357 auto surface = std::make_unique<NiceMock<MockSurface>>();
359 std::shared_ptr<NiceMock<MockExternalViewEmbedder>> external_view_embedder =
360 std::make_shared<NiceMock<MockExternalViewEmbedder>>();
361 rasterizer->SetExternalViewEmbedder(external_view_embedder);
366 auto surface_frame = std::make_unique<SurfaceFrame>(
368 nullptr, framebuffer_info,
371 EXPECT_CALL(*
surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(
true));
373 .WillOnce(Return(ByMove(std::move(surface_frame))));
374 EXPECT_CALL(*
surface, MakeRenderContextCurrent())
375 .WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(
true))));
376 EXPECT_CALL(*external_view_embedder, SupportsDynamicThreadMerging)
377 .WillRepeatedly(Return(
true));
379 EXPECT_CALL(*external_view_embedder, BeginFrame(
nullptr,
382 EXPECT_CALL(*external_view_embedder, PrepareFlutterView(
386 EXPECT_CALL(*external_view_embedder,
389 EXPECT_CALL(*external_view_embedder, EndFrame(
false,
393 rasterizer->Setup(std::move(
surface));
395 auto pipeline = std::make_shared<FramePipeline>(10);
398 auto layer_tree_item = std::make_unique<FrameItem>(
403 pipeline->Produce().Complete(std::move(layer_tree_item));
405 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
406 rasterizer->Draw(pipeline);
410 drawLastLayerTreeWithThreadsMergedExternalViewEmbedderAndEndFrameCalled) {
411 std::string test_name =
412 ::testing::UnitTest::GetInstance()->current_test_info()->name();
413 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
424 NiceMock<MockDelegate> delegate;
426 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
427 EXPECT_CALL(delegate, GetTaskRunners())
428 .WillRepeatedly(ReturnRef(task_runners));
429 EXPECT_CALL(delegate, OnFrameRasterized(_));
431 auto rasterizer = std::make_unique<Rasterizer>(delegate);
432 auto surface = std::make_unique<NiceMock<MockSurface>>();
434 std::shared_ptr<NiceMock<MockExternalViewEmbedder>> external_view_embedder =
435 std::make_shared<NiceMock<MockExternalViewEmbedder>>();
436 rasterizer->SetExternalViewEmbedder(external_view_embedder);
441 auto surface_frame1 = std::make_unique<SurfaceFrame>(
443 nullptr, framebuffer_info,
446 auto surface_frame2 = std::make_unique<SurfaceFrame>(
448 nullptr, framebuffer_info,
451 EXPECT_CALL(*
surface, AllowsDrawingWhenGpuDisabled())
452 .WillRepeatedly(Return(
true));
455 .WillOnce(Return(ByMove(std::move(surface_frame1))))
456 .WillOnce(Return(ByMove(std::move(surface_frame2))));
457 EXPECT_CALL(*
surface, MakeRenderContextCurrent())
458 .WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(
true))));
459 EXPECT_CALL(*external_view_embedder, SupportsDynamicThreadMerging)
460 .WillRepeatedly(Return(
true));
462 EXPECT_CALL(*external_view_embedder, BeginFrame(
nullptr,
465 EXPECT_CALL(*external_view_embedder, PrepareFlutterView(
469 EXPECT_CALL(*external_view_embedder,
472 EXPECT_CALL(*external_view_embedder, EndFrame(
false,
476 rasterizer->Setup(std::move(
surface));
478 auto pipeline = std::make_shared<FramePipeline>(10);
481 auto layer_tree_item = std::make_unique<FrameItem>(
486 pipeline->Produce().Complete(std::move(layer_tree_item));
491 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
492 rasterizer->Draw(pipeline);
499TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNoSurfaceIsSet) {
500 std::string test_name =
501 ::testing::UnitTest::GetInstance()->current_test_info()->name();
502 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
510 NiceMock<MockDelegate> delegate;
512 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
513 EXPECT_CALL(delegate, GetTaskRunners())
514 .WillRepeatedly(ReturnRef(task_runners));
515 auto rasterizer = std::make_unique<Rasterizer>(delegate);
517 std::shared_ptr<NiceMock<MockExternalViewEmbedder>> external_view_embedder =
518 std::make_shared<NiceMock<MockExternalViewEmbedder>>();
519 rasterizer->SetExternalViewEmbedder(external_view_embedder);
522 *external_view_embedder,
530 auto pipeline = std::make_shared<FramePipeline>(10);
531 auto layer_tree = std::make_unique<LayerTree>(
533 auto layer_tree_item = std::make_unique<FrameItem>(
538 pipeline->Produce().Complete(std::move(layer_tree_item));
540 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
541 rasterizer->Draw(pipeline);
547TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNotUsedThisFrame) {
548 std::string test_name =
549 ::testing::UnitTest::GetInstance()->current_test_info()->name();
550 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
558 NiceMock<MockDelegate> delegate;
560 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
561 EXPECT_CALL(delegate, GetTaskRunners())
562 .WillRepeatedly(ReturnRef(task_runners));
563 auto is_gpu_disabled_sync_switch =
564 std::make_shared<const fml::SyncSwitch>(
false);
565 ON_CALL(delegate, GetIsGpuDisabledSyncSwitch())
566 .WillByDefault(Return(is_gpu_disabled_sync_switch));
568 auto rasterizer = std::make_unique<Rasterizer>(delegate);
569 auto surface = std::make_unique<NiceMock<MockSurface>>();
570 EXPECT_CALL(*
surface, MakeRenderContextCurrent())
571 .WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(
true))));
573 std::shared_ptr<NiceMock<MockExternalViewEmbedder>> external_view_embedder =
574 std::make_shared<NiceMock<MockExternalViewEmbedder>>();
575 rasterizer->SetExternalViewEmbedder(external_view_embedder);
576 rasterizer->Setup(std::move(
surface));
578 EXPECT_CALL(*external_view_embedder, BeginFrame(
nullptr,
581 EXPECT_CALL(*external_view_embedder, PrepareFlutterView(
586 *external_view_embedder,
594 auto pipeline = std::make_shared<FramePipeline>(10);
595 auto layer_tree = std::make_unique<LayerTree>(
597 auto layer_tree_item = std::make_unique<FrameItem>(
602 pipeline->Produce().Complete(std::move(layer_tree_item));
605 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
true));
606 DrawStatus status = rasterizer->Draw(pipeline);
615TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenPipelineIsEmpty) {
616 std::string test_name =
617 ::testing::UnitTest::GetInstance()->current_test_info()->name();
618 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
626 NiceMock<MockDelegate> delegate;
628 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
629 EXPECT_CALL(delegate, GetTaskRunners())
630 .WillRepeatedly(ReturnRef(task_runners));
632 auto rasterizer = std::make_unique<Rasterizer>(delegate);
633 auto surface = std::make_unique<NiceMock<MockSurface>>();
634 EXPECT_CALL(*
surface, MakeRenderContextCurrent())
635 .WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(
true))));
637 std::shared_ptr<NiceMock<MockExternalViewEmbedder>> external_view_embedder =
638 std::make_shared<NiceMock<MockExternalViewEmbedder>>();
639 rasterizer->SetExternalViewEmbedder(external_view_embedder);
640 rasterizer->Setup(std::move(
surface));
643 *external_view_embedder,
651 auto pipeline = std::make_shared<FramePipeline>(10);
652 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
653 DrawStatus status = rasterizer->Draw(pipeline);
660TEST(RasterizerTest, drawMultipleViewsWithExternalViewEmbedder) {
661 std::string test_name =
662 ::testing::UnitTest::GetInstance()->current_test_info()->name();
663 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
671 NiceMock<MockDelegate> delegate;
673 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
674 EXPECT_CALL(delegate, GetTaskRunners())
675 .WillRepeatedly(ReturnRef(task_runners));
676 EXPECT_CALL(delegate, OnFrameRasterized(_));
677 auto rasterizer = std::make_unique<Rasterizer>(delegate);
678 auto surface = std::make_unique<NiceMock<MockSurface>>();
679 std::shared_ptr<NiceMock<MockExternalViewEmbedder>> external_view_embedder =
680 std::make_shared<NiceMock<MockExternalViewEmbedder>>();
681 rasterizer->SetExternalViewEmbedder(external_view_embedder);
682 EXPECT_CALL(*external_view_embedder, SupportsDynamicThreadMerging)
683 .WillRepeatedly(Return(
false));
684 EXPECT_CALL(*
surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(
true));
689 return std::make_unique<SurfaceFrame>(
691 nullptr, framebuffer_info,
695 EXPECT_CALL(*
surface, MakeRenderContextCurrent())
696 .WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(
true))));
698 EXPECT_CALL(*external_view_embedder, BeginFrame(
nullptr,
701 EXPECT_CALL(*external_view_embedder,
705 EXPECT_CALL(*external_view_embedder,
706 SubmitFlutterView(0, _, _, _))
708 EXPECT_CALL(*external_view_embedder,
712 EXPECT_CALL(*external_view_embedder,
713 SubmitFlutterView(1, _, _, _))
715 EXPECT_CALL(*external_view_embedder, EndFrame(
false,
719 rasterizer->Setup(std::move(
surface));
722 auto pipeline = std::make_shared<FramePipeline>(10);
723 std::vector<std::unique_ptr<LayerTreeTask>> tasks;
724 tasks.push_back(std::make_unique<LayerTreeTask>(
726 tasks.push_back(std::make_unique<LayerTreeTask>(
728 auto layer_tree_item = std::make_unique<FrameItem>(
731 pipeline->Produce().Complete(std::move(layer_tree_item));
733 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
734 rasterizer->Draw(pipeline);
741 drawWithGpuEnabledAndSurfaceAllowsDrawingWhenGpuDisabledDoesAcquireFrame) {
742 std::string test_name =
743 ::testing::UnitTest::GetInstance()->current_test_info()->name();
744 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
752 NiceMock<MockDelegate> delegate;
754 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
755 EXPECT_CALL(delegate, GetTaskRunners())
756 .WillRepeatedly(ReturnRef(task_runners));
757 EXPECT_CALL(delegate, OnFrameRasterized(_));
759 auto rasterizer = std::make_unique<Rasterizer>(delegate);
760 auto surface = std::make_unique<NiceMock<MockSurface>>();
761 auto is_gpu_disabled_sync_switch =
762 std::make_shared<const fml::SyncSwitch>(
false);
766 auto surface_frame = std::make_unique<SurfaceFrame>(
768 nullptr, framebuffer_info,
771 EXPECT_CALL(*
surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(
true));
772 ON_CALL(delegate, GetIsGpuDisabledSyncSwitch())
773 .WillByDefault(Return(is_gpu_disabled_sync_switch));
774 EXPECT_CALL(delegate, GetIsGpuDisabledSyncSwitch()).Times(0);
776 .WillOnce(Return(ByMove(std::move(surface_frame))));
777 EXPECT_CALL(*
surface, MakeRenderContextCurrent())
778 .WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(
true))));
780 rasterizer->Setup(std::move(
surface));
783 auto pipeline = std::make_shared<FramePipeline>(10);
784 auto layer_tree = std::make_unique<LayerTree>(
786 auto layer_tree_item = std::make_unique<FrameItem>(
791 pipeline->Produce().Complete(std::move(layer_tree_item));
793 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
794 rasterizer->Draw(pipeline);
802 drawWithGpuDisabledAndSurfaceAllowsDrawingWhenGpuDisabledDoesAcquireFrame) {
803 std::string test_name =
804 ::testing::UnitTest::GetInstance()->current_test_info()->name();
805 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
813 NiceMock<MockDelegate> delegate;
815 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
816 EXPECT_CALL(delegate, GetTaskRunners())
817 .WillRepeatedly(ReturnRef(task_runners));
818 EXPECT_CALL(delegate, OnFrameRasterized(_));
819 auto rasterizer = std::make_unique<Rasterizer>(delegate);
820 auto surface = std::make_unique<NiceMock<MockSurface>>();
821 auto is_gpu_disabled_sync_switch =
822 std::make_shared<const fml::SyncSwitch>(
true);
827 auto surface_frame = std::make_unique<SurfaceFrame>(
829 nullptr, framebuffer_info,
832 EXPECT_CALL(*
surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(
true));
833 ON_CALL(delegate, GetIsGpuDisabledSyncSwitch())
834 .WillByDefault(Return(is_gpu_disabled_sync_switch));
835 EXPECT_CALL(delegate, GetIsGpuDisabledSyncSwitch()).Times(0);
837 .WillOnce(Return(ByMove(std::move(surface_frame))));
838 EXPECT_CALL(*
surface, MakeRenderContextCurrent())
839 .WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(
true))));
841 rasterizer->Setup(std::move(
surface));
844 auto pipeline = std::make_shared<FramePipeline>(10);
845 auto layer_tree = std::make_unique<LayerTree>(
847 auto layer_tree_item = std::make_unique<FrameItem>(
852 pipeline->Produce().Complete(std::move(layer_tree_item));
854 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
855 DrawStatus status = rasterizer->Draw(pipeline);
864 drawWithGpuEnabledAndSurfaceDisallowsDrawingWhenGpuDisabledDoesAcquireFrame) {
865 std::string test_name =
866 ::testing::UnitTest::GetInstance()->current_test_info()->name();
867 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
875 NiceMock<MockDelegate> delegate;
877 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
878 EXPECT_CALL(delegate, GetTaskRunners())
879 .WillRepeatedly(ReturnRef(task_runners));
880 EXPECT_CALL(delegate, OnFrameRasterized(_));
881 auto rasterizer = std::make_unique<Rasterizer>(delegate);
882 auto surface = std::make_unique<NiceMock<MockSurface>>();
883 auto is_gpu_disabled_sync_switch =
884 std::make_shared<const fml::SyncSwitch>(
false);
889 auto surface_frame = std::make_unique<SurfaceFrame>(
891 nullptr, framebuffer_info,
894 EXPECT_CALL(*
surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(
false));
895 EXPECT_CALL(delegate, GetIsGpuDisabledSyncSwitch())
896 .WillOnce(Return(is_gpu_disabled_sync_switch));
898 .WillOnce(Return(ByMove(std::move(surface_frame))));
899 EXPECT_CALL(*
surface, MakeRenderContextCurrent())
900 .WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(
true))));
902 rasterizer->Setup(std::move(
surface));
905 auto pipeline = std::make_shared<FramePipeline>(10);
906 auto layer_tree = std::make_unique<LayerTree>(
908 auto layer_tree_item = std::make_unique<FrameItem>(
913 pipeline->Produce().Complete(std::move(layer_tree_item));
915 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
916 DrawStatus status = rasterizer->Draw(pipeline);
925 drawWithGpuDisabledAndSurfaceDisallowsDrawingWhenGpuDisabledDoesntAcquireFrame) {
926 std::string test_name =
927 ::testing::UnitTest::GetInstance()->current_test_info()->name();
928 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
936 NiceMock<MockDelegate> delegate;
938 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
939 EXPECT_CALL(delegate, GetTaskRunners())
940 .WillRepeatedly(ReturnRef(task_runners));
941 EXPECT_CALL(delegate, OnFrameRasterized(_)).Times(0);
942 auto rasterizer = std::make_unique<Rasterizer>(delegate);
943 auto surface = std::make_unique<NiceMock<MockSurface>>();
944 auto is_gpu_disabled_sync_switch =
945 std::make_shared<const fml::SyncSwitch>(
true);
950 auto surface_frame = std::make_unique<SurfaceFrame>(
952 nullptr, framebuffer_info,
955 EXPECT_CALL(*
surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(
false));
956 EXPECT_CALL(delegate, GetIsGpuDisabledSyncSwitch())
957 .WillOnce(Return(is_gpu_disabled_sync_switch));
959 EXPECT_CALL(*
surface, MakeRenderContextCurrent())
960 .WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(
true))));
962 rasterizer->Setup(std::move(
surface));
965 auto pipeline = std::make_shared<FramePipeline>(10);
966 auto layer_tree = std::make_unique<LayerTree>(
968 auto layer_tree_item = std::make_unique<FrameItem>(
973 pipeline->Produce().Complete(std::move(layer_tree_item));
975 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
976 DrawStatus status = rasterizer->Draw(pipeline);
985 FrameTimingRecorderShouldStartRecordingRasterTimeBeforeSurfaceAcquireFrame) {
986 std::string test_name =
987 ::testing::UnitTest::GetInstance()->current_test_info()->name();
988 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
996 NiceMock<MockDelegate> delegate;
998 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
999 EXPECT_CALL(delegate, GetTaskRunners())
1000 .WillRepeatedly(ReturnRef(task_runners));
1001 EXPECT_CALL(delegate, OnFrameRasterized(_))
1009 auto rasterizer = std::make_unique<Rasterizer>(delegate);
1010 auto surface = std::make_unique<NiceMock<MockSurface>>();
1011 auto is_gpu_disabled_sync_switch =
1012 std::make_shared<const fml::SyncSwitch>(
false);
1013 ON_CALL(delegate, GetIsGpuDisabledSyncSwitch())
1014 .WillByDefault(Return(is_gpu_disabled_sync_switch));
1016 .WillByDefault(::testing::Invoke([] {
return nullptr; }));
1018 EXPECT_CALL(*
surface, MakeRenderContextCurrent())
1019 .WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(
true))));
1020 rasterizer->Setup(std::move(
surface));
1023 auto pipeline = std::make_shared<FramePipeline>(10);
1024 auto layer_tree = std::make_unique<LayerTree>(
1026 auto layer_tree_item = std::make_unique<FrameItem>(
1031 pipeline->Produce().Complete(std::move(layer_tree_item));
1033 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
1034 DrawStatus status = rasterizer->Draw(pipeline);
1044 drawLayerTreeWithCorrectFrameTimingWhenPipelineIsMoreAvailable) {
1045 std::string test_name =
1046 ::testing::UnitTest::GetInstance()->current_test_info()->name();
1047 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
1054 thread_host.
io_thread->GetTaskRunner());
1055 NiceMock<MockDelegate> delegate;
1057 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
1058 ON_CALL(delegate, GetTaskRunners()).WillByDefault(ReturnRef(task_runners));
1061 std::unique_ptr<Rasterizer> rasterizer;
1063 rasterizer = std::make_unique<Rasterizer>(delegate);
1068 auto surface = std::make_unique<NiceMock<MockSurface>>();
1069 EXPECT_CALL(*
surface, AllowsDrawingWhenGpuDisabled())
1070 .WillRepeatedly(Return(
true));
1072 .WillByDefault(::testing::Invoke([] {
1075 return std::make_unique<SurfaceFrame>(
1077 nullptr, framebuffer_info,
1082 ON_CALL(*
surface, MakeRenderContextCurrent())
1083 .WillByDefault(::testing::Invoke(
1084 [] {
return std::make_unique<GLContextDefaultResult>(
true); }));
1089 std::vector<fml::TimePoint> timestamps = {first_timestamp, second_timestamp};
1090 int frame_rasterized_count = 0;
1091 EXPECT_CALL(delegate, OnFrameRasterized(_))
1093 .WillRepeatedly([&](
const FrameTiming& frame_timing) {
1094 EXPECT_EQ(timestamps[frame_rasterized_count],
1096 EXPECT_EQ(timestamps[frame_rasterized_count],
1098 EXPECT_EQ(timestamps[frame_rasterized_count],
1100 frame_rasterized_count++;
1105 rasterizer->Setup(std::move(
surface));
1106 auto pipeline = std::make_shared<FramePipeline>(10);
1107 for (
int i = 0; i < 2; i++) {
1108 auto layer_tree = std::make_unique<LayerTree>(
1110 auto layer_tree_item = std::make_unique<FrameItem>(
1115 pipeline->Produce().Complete(std::move(layer_tree_item));
1117 EXPECT_EQ(
result.is_first_item, i == 0);
1121 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
1122 rasterizer->Draw(pipeline);
1124 count_down_latch.
Wait();
1132TEST(RasterizerTest, TeardownFreesResourceCache) {
1133 std::string test_name =
1134 ::testing::UnitTest::GetInstance()->current_test_info()->name();
1135 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
1142 thread_host.
io_thread->GetTaskRunner());
1144 NiceMock<MockDelegate> delegate;
1146 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
1147 EXPECT_CALL(delegate, GetTaskRunners())
1148 .WillRepeatedly(ReturnRef(task_runners));
1150 auto rasterizer = std::make_unique<Rasterizer>(delegate);
1151 auto surface = std::make_unique<NiceMock<MockSurface>>();
1153 context->setResourceCacheLimit(0);
1155 EXPECT_CALL(*
surface, MakeRenderContextCurrent())
1156 .WillRepeatedly([]() -> std::unique_ptr<GLContextResult> {
1157 return std::make_unique<GLContextDefaultResult>(
true);
1159 EXPECT_CALL(*
surface, GetContext()).WillRepeatedly(Return(context.get()));
1161 rasterizer->Setup(std::move(
surface));
1162 EXPECT_EQ(context->getResourceCacheLimit(), 0ul);
1164 rasterizer->SetResourceCacheMaxBytes(10000000,
false);
1165 EXPECT_EQ(context->getResourceCacheLimit(), 10000000ul);
1166 EXPECT_EQ(context->getResourceCachePurgeableBytes(), 0ul);
1170 context->getResourceCacheUsage(&
count, &bytes);
1171 EXPECT_EQ(bytes, 0ul);
1180 sk_surface->getCanvas()->drawPaint(
paint);
1183 EXPECT_EQ(context->getResourceCachePurgeableBytes(), 0ul);
1187 context->getResourceCacheUsage(&
count, &bytes);
1188 EXPECT_GT(bytes, 0ul);
1189 EXPECT_GT(context->getResourceCachePurgeableBytes(), 0ul);
1191 rasterizer->Teardown();
1192 EXPECT_EQ(context->getResourceCachePurgeableBytes(), 0ul);
1195TEST(RasterizerTest, TeardownNoSurface) {
1196 std::string test_name =
1197 ::testing::UnitTest::GetInstance()->current_test_info()->name();
1198 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
1205 thread_host.
io_thread->GetTaskRunner());
1207 NiceMock<MockDelegate> delegate;
1209 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
1210 EXPECT_CALL(delegate, GetTaskRunners())
1211 .WillRepeatedly(ReturnRef(task_runners));
1213 auto rasterizer = std::make_unique<Rasterizer>(delegate);
1216 rasterizer->Teardown();
1219TEST(RasterizerTest, presentationTimeSetWhenVsyncTargetInFuture) {
1220 GTEST_SKIP() <<
"eglPresentationTime is disabled due to "
1221 "https://github.com/flutter/flutter/issues/112503";
1223 std::string test_name =
1224 ::testing::UnitTest::GetInstance()->current_test_info()->name();
1225 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
1231 thread_host.
io_thread->GetTaskRunner());
1233 NiceMock<MockDelegate> delegate;
1235 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
1236 ON_CALL(delegate, GetTaskRunners()).WillByDefault(ReturnRef(task_runners));
1239 std::unique_ptr<Rasterizer> rasterizer;
1241 rasterizer = std::make_unique<Rasterizer>(delegate);
1248 auto second_timestamp = first_timestamp + millis_16;
1249 std::vector<fml::TimePoint> timestamps = {first_timestamp, second_timestamp};
1251 int frames_submitted = 0;
1253 auto surface = std::make_unique<MockSurface>();
1254 ON_CALL(*
surface, AllowsDrawingWhenGpuDisabled()).WillByDefault(Return(
true));
1256 .WillByDefault(::testing::Invoke([&] {
1259 return std::make_unique<SurfaceFrame>(
1260 nullptr, framebuffer_info,
1263 const auto pres_time = *
frame.submit_info().presentation_time;
1264 const auto diff = pres_time - first_timestamp;
1265 int num_frames_submitted = frames_submitted++;
1266 EXPECT_EQ(diff.ToMilliseconds(),
1267 num_frames_submitted * millis_16.ToMilliseconds());
1274 ON_CALL(*
surface, MakeRenderContextCurrent())
1275 .WillByDefault(::testing::Invoke(
1276 [] {
return std::make_unique<GLContextDefaultResult>(
true); }));
1279 rasterizer->Setup(std::move(
surface));
1280 auto pipeline = std::make_shared<FramePipeline>(10);
1281 for (
int i = 0; i < 2; i++) {
1282 auto layer_tree = std::make_unique<LayerTree>(
1284 auto layer_tree_item = std::make_unique<FrameItem>(
1289 pipeline->Produce().Complete(std::move(layer_tree_item));
1291 EXPECT_EQ(
result.is_first_item, i == 0);
1295 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
1296 rasterizer->Draw(pipeline);
1299 submit_latch.
Wait();
1308TEST(RasterizerTest, presentationTimeNotSetWhenVsyncTargetInPast) {
1309 GTEST_SKIP() <<
"eglPresentationTime is disabled due to "
1310 "https://github.com/flutter/flutter/issues/112503";
1312 std::string test_name =
1313 ::testing::UnitTest::GetInstance()->current_test_info()->name();
1314 ThreadHost thread_host(
"io.flutter.test." + test_name +
".",
1320 thread_host.
io_thread->GetTaskRunner());
1322 NiceMock<MockDelegate> delegate;
1324 ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings));
1325 ON_CALL(delegate, GetTaskRunners()).WillByDefault(ReturnRef(task_runners));
1328 std::unique_ptr<Rasterizer> rasterizer;
1330 rasterizer = std::make_unique<Rasterizer>(delegate);
1339 auto surface = std::make_unique<MockSurface>();
1340 ON_CALL(*
surface, AllowsDrawingWhenGpuDisabled()).WillByDefault(Return(
true));
1342 .WillByDefault(::testing::Invoke([&] {
1345 return std::make_unique<SurfaceFrame>(
1346 nullptr, framebuffer_info,
1349 const std::optional<fml::TimePoint> pres_time =
1350 frame.submit_info().presentation_time;
1351 EXPECT_EQ(pres_time, std::nullopt);
1358 ON_CALL(*
surface, MakeRenderContextCurrent())
1359 .WillByDefault(::testing::Invoke(
1360 [] {
return std::make_unique<GLContextDefaultResult>(
true); }));
1363 rasterizer->Setup(std::move(
surface));
1364 auto pipeline = std::make_shared<FramePipeline>(10);
1365 auto layer_tree = std::make_unique<LayerTree>(
1367 auto layer_tree_item = std::make_unique<FrameItem>(
1372 pipeline->Produce().Complete(std::move(layer_tree_item));
1374 EXPECT_EQ(
result.is_first_item,
true);
1375 ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(
false));
1376 rasterizer->Draw(pipeline);
1379 submit_latch.
Wait();
#define TEST(S, s, D, expected)
static sk_sp< GrDirectContext > MakeMock(const GrMockOptions *, const GrContextOptions &)
static sk_sp< SkColorSpace > MakeSRGB()
Developer-facing API for rendering anything within the engine.
fml::TimePoint Get(Phase phase) 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
SK_API sk_sp< SkSurface > RenderTarget(GrRecordingContext *context, skgpu::Budgeted budgeted, const SkImageInfo &imageInfo, int sampleCount, GrSurfaceOrigin surfaceOrigin, const SkSurfaceProps *surfaceProps, bool shouldCreateWithMips=false, bool isProtected=false)
static std::unique_ptr< FrameTimingsRecorder > CreateFinishedBuildRecorder()
constexpr FlutterViewId kImplicitViewId
it will be possible to load the file into Perfetto s trace viewer 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
std::chrono::duration< double, std::milli > Milliseconds
static constexpr SkISize Make(int32_t w, int32_t h)
static SkImageInfo MakeN32Premul(int width, int height)
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
#define EXPECT_TRUE(handle)