From 122f242588e832b067ebd9c6cb73968075e4de08 Mon Sep 17 00:00:00 2001 From: gaaclarke <30870216+gaaclarke@users.noreply.github.com> Date: Wed, 4 Nov 2020 13:56:29 -0800 Subject: [PATCH] added unit tests to the rasterizer (#22282) --- ci/licenses_golden/licenses_flutter | 1 + shell/common/BUILD.gn | 1 + shell/common/rasterizer_unittests.cc | 135 +++++++++++++++++++++++++++ 3 files changed, 137 insertions(+) create mode 100644 shell/common/rasterizer_unittests.cc diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 890afa28c66a6..14a1326db114f 100755 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -631,6 +631,7 @@ FILE: ../../../flutter/shell/common/pointer_data_dispatcher.cc FILE: ../../../flutter/shell/common/pointer_data_dispatcher.h FILE: ../../../flutter/shell/common/rasterizer.cc FILE: ../../../flutter/shell/common/rasterizer.h +FILE: ../../../flutter/shell/common/rasterizer_unittests.cc FILE: ../../../flutter/shell/common/run_configuration.cc FILE: ../../../flutter/shell/common/run_configuration.h FILE: ../../../flutter/shell/common/serialization_callbacks.cc diff --git a/shell/common/BUILD.gn b/shell/common/BUILD.gn index 2cc266712c2a7..13fc319f9f27e 100644 --- a/shell/common/BUILD.gn +++ b/shell/common/BUILD.gn @@ -244,6 +244,7 @@ if (enable_unittests) { "input_events_unittests.cc", "persistent_cache_unittests.cc", "pipeline_unittests.cc", + "rasterizer_unittests.cc", "shell_unittests.cc", "skp_shader_warmup_unittests.cc", ] diff --git a/shell/common/rasterizer_unittests.cc b/shell/common/rasterizer_unittests.cc new file mode 100644 index 0000000000000..47a1f700fc843 --- /dev/null +++ b/shell/common/rasterizer_unittests.cc @@ -0,0 +1,135 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/common/rasterizer.h" + +#include "flutter/shell/common/thread_host.h" +#include "flutter/testing/testing.h" +#include "gmock/gmock.h" + +using testing::_; +using testing::Return; +using testing::ReturnRef; + +namespace flutter { +namespace { +class MockDelegate : public Rasterizer::Delegate { + public: + MOCK_METHOD1(OnFrameRasterized, void(const FrameTiming& frame_timing)); + MOCK_METHOD0(GetFrameBudget, fml::Milliseconds()); + MOCK_CONST_METHOD0(GetLatestFrameTargetTime, fml::TimePoint()); + MOCK_CONST_METHOD0(GetTaskRunners, const TaskRunners&()); + MOCK_CONST_METHOD0(GetIsGpuDisabledSyncSwitch, + std::shared_ptr()); +}; + +class MockSurface : public Surface { + public: + MOCK_METHOD0(IsValid, bool()); + MOCK_METHOD1(AcquireFrame, + std::unique_ptr(const SkISize& size)); + MOCK_CONST_METHOD0(GetRootTransformation, SkMatrix()); + MOCK_METHOD0(GetContext, GrDirectContext*()); + MOCK_METHOD0(GetExternalViewEmbedder, ExternalViewEmbedder*()); + MOCK_METHOD0(MakeRenderContextCurrent, std::unique_ptr()); + MOCK_METHOD0(ClearRenderContext, bool()); +}; + +class MockExternalViewEmbedder : public ExternalViewEmbedder { + public: + MOCK_METHOD0(GetRootCanvas, SkCanvas*()); + MOCK_METHOD0(CancelFrame, void()); + MOCK_METHOD4(BeginFrame, + void(SkISize frame_size, + GrDirectContext* context, + double device_pixel_ratio, + fml::RefPtr raster_thread_merger)); + MOCK_METHOD2(PrerollCompositeEmbeddedView, + void(int view_id, std::unique_ptr params)); + MOCK_METHOD1(PostPrerollAction, + PostPrerollResult( + fml::RefPtr raster_thread_merger)); + MOCK_METHOD0(GetCurrentCanvases, std::vector()); + MOCK_METHOD1(CompositeEmbeddedView, SkCanvas*(int view_id)); + MOCK_METHOD2(SubmitFrame, + void(GrDirectContext* context, + std::unique_ptr frame)); + MOCK_METHOD2(EndFrame, + void(bool should_resubmit_frame, + fml::RefPtr raster_thread_merger)); + MOCK_METHOD0(SupportsDynamicThreadMerging, bool()); +}; +} // namespace + +TEST(RasterizerTest, create) { + MockDelegate delegate; + auto rasterizer = std::make_unique(delegate); + EXPECT_TRUE(rasterizer != nullptr); +} + +TEST(RasterizerTest, drawEmptyPipeline) { + std::string test_name = + ::testing::UnitTest::GetInstance()->current_test_info()->name(); + ThreadHost thread_host("io.flutter.test." + test_name + ".", + ThreadHost::Type::Platform | ThreadHost::Type::GPU | + ThreadHost::Type::IO | ThreadHost::Type::UI); + TaskRunners task_runners("test", thread_host.platform_thread->GetTaskRunner(), + thread_host.raster_thread->GetTaskRunner(), + thread_host.ui_thread->GetTaskRunner(), + thread_host.io_thread->GetTaskRunner()); + MockDelegate delegate; + ON_CALL(delegate, GetTaskRunners()).WillByDefault(ReturnRef(task_runners)); + auto rasterizer = std::make_unique(delegate); + auto surface = std::make_unique(); + rasterizer->Setup(std::move(surface)); + fml::AutoResetWaitableEvent latch; + thread_host.raster_thread->GetTaskRunner()->PostTask([&] { + auto pipeline = fml::AdoptRef(new Pipeline(/*depth=*/10)); + rasterizer->Draw(pipeline, nullptr); + latch.Signal(); + }); + latch.Wait(); +} + +TEST(RasterizerTest, drawWithExternalViewEmbedder) { + std::string test_name = + ::testing::UnitTest::GetInstance()->current_test_info()->name(); + ThreadHost thread_host("io.flutter.test." + test_name + ".", + ThreadHost::Type::Platform | ThreadHost::Type::GPU | + ThreadHost::Type::IO | ThreadHost::Type::UI); + TaskRunners task_runners("test", thread_host.platform_thread->GetTaskRunner(), + thread_host.raster_thread->GetTaskRunner(), + thread_host.ui_thread->GetTaskRunner(), + thread_host.io_thread->GetTaskRunner()); + MockDelegate delegate; + EXPECT_CALL(delegate, GetTaskRunners()) + .WillRepeatedly(ReturnRef(task_runners)); + EXPECT_CALL(delegate, OnFrameRasterized(_)); + auto rasterizer = std::make_unique(delegate); + auto surface = std::make_unique(); + MockExternalViewEmbedder external_view_embedder; + EXPECT_CALL(*surface, GetExternalViewEmbedder()) + .WillRepeatedly(Return(&external_view_embedder)); + EXPECT_CALL(external_view_embedder, + BeginFrame(SkISize(), nullptr, 2.0, + fml::RefPtr(nullptr))); + EXPECT_CALL(external_view_embedder, + EndFrame(false, fml::RefPtr(nullptr))); + rasterizer->Setup(std::move(surface)); + fml::AutoResetWaitableEvent latch; + thread_host.raster_thread->GetTaskRunner()->PostTask([&] { + auto pipeline = fml::AdoptRef(new Pipeline(/*depth=*/10)); + auto layer_tree = std::make_unique(/*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0f); + bool result = pipeline->Produce().Complete(std::move(layer_tree)); + EXPECT_TRUE(result); + std::function no_discard = [](LayerTree&) { + return false; + }; + rasterizer->Draw(pipeline, no_discard); + latch.Signal(); + }); + latch.Wait(); +} +} // namespace flutter