Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions shell/common/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,11 @@ if (enable_unittests) {
"//third_party/googletest:gmock",
]

# Swiftshader only supports x86/64.
if (shell_enable_vulkan && (target_cpu == "x86" || target_cpu == "x64")) {
deps += [ "//third_party/swiftshader_flutter:swiftshader_vulkan" ]
}

if (is_fuchsia) {
sources += [ "shell_fuchsia_unittests.cc" ]

Expand Down
12 changes: 8 additions & 4 deletions shell/common/rasterizer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,14 @@ void Rasterizer::TeardownExternalViewEmbedder() {
}

void Rasterizer::Teardown() {
auto context_switch =
surface_ ? surface_->MakeRenderContextCurrent() : nullptr;
if (context_switch && context_switch->GetResult()) {
compositor_context_->OnGrContextDestroyed();
if (surface_) {
auto context_switch = surface_->MakeRenderContextCurrent();
if (context_switch->GetResult()) {
compositor_context_->OnGrContextDestroyed();
if (auto* context = surface_->GetContext()) {
context->purgeUnlockedResources(/*scratchResourcesOnly=*/false);
}
}
}

surface_.reset();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can move the surface_.reset() into the if (surface_) block

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Expand Down
169 changes: 127 additions & 42 deletions shell/common/rasterizer_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

using testing::_;
using testing::ByMove;
using testing::NiceMock;
using testing::Return;
using testing::ReturnRef;

Expand Down Expand Up @@ -77,7 +78,7 @@ class MockExternalViewEmbedder : public ExternalViewEmbedder {
} // namespace

TEST(RasterizerTest, create) {
MockDelegate delegate;
NiceMock<MockDelegate> delegate;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes are not essential to this patch, but eliminate a lot of noise when running these test targets related to unexpected mock function calls.

auto rasterizer = std::make_unique<Rasterizer>(delegate);
EXPECT_TRUE(rasterizer != nullptr);
}
Expand Down Expand Up @@ -106,10 +107,10 @@ TEST(RasterizerTest, drawEmptyPipeline) {
thread_host.raster_thread->GetTaskRunner(),
thread_host.ui_thread->GetTaskRunner(),
thread_host.io_thread->GetTaskRunner());
MockDelegate delegate;
NiceMock<MockDelegate> delegate;
ON_CALL(delegate, GetTaskRunners()).WillByDefault(ReturnRef(task_runners));
auto rasterizer = std::make_unique<Rasterizer>(delegate);
auto surface = std::make_unique<MockSurface>();
auto surface = std::make_unique<NiceMock<MockSurface>>();
EXPECT_CALL(*surface, MakeRenderContextCurrent())
.WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(true))));
rasterizer->Setup(std::move(surface));
Expand All @@ -133,15 +134,15 @@ TEST(RasterizerTest,
thread_host.raster_thread->GetTaskRunner(),
thread_host.ui_thread->GetTaskRunner(),
thread_host.io_thread->GetTaskRunner());
MockDelegate delegate;
NiceMock<MockDelegate> delegate;
EXPECT_CALL(delegate, GetTaskRunners())
.WillRepeatedly(ReturnRef(task_runners));
EXPECT_CALL(delegate, OnFrameRasterized(_));
auto rasterizer = std::make_unique<Rasterizer>(delegate);
auto surface = std::make_unique<MockSurface>();
auto surface = std::make_unique<NiceMock<MockSurface>>();

std::shared_ptr<MockExternalViewEmbedder> external_view_embedder =
std::make_shared<MockExternalViewEmbedder>();
std::shared_ptr<NiceMock<MockExternalViewEmbedder>> external_view_embedder =
std::make_shared<NiceMock<MockExternalViewEmbedder>>();
rasterizer->SetExternalViewEmbedder(external_view_embedder);

SurfaceFrame::FramebufferInfo framebuffer_info;
Expand Down Expand Up @@ -200,14 +201,14 @@ TEST(
thread_host.raster_thread->GetTaskRunner(),
thread_host.ui_thread->GetTaskRunner(),
thread_host.io_thread->GetTaskRunner());
MockDelegate delegate;
NiceMock<MockDelegate> delegate;
EXPECT_CALL(delegate, GetTaskRunners())
.WillRepeatedly(ReturnRef(task_runners));
EXPECT_CALL(delegate, OnFrameRasterized(_));
auto rasterizer = std::make_unique<Rasterizer>(delegate);
auto surface = std::make_unique<MockSurface>();
std::shared_ptr<MockExternalViewEmbedder> external_view_embedder =
std::make_shared<MockExternalViewEmbedder>();
auto surface = std::make_unique<NiceMock<MockSurface>>();
std::shared_ptr<NiceMock<MockExternalViewEmbedder>> external_view_embedder =
std::make_shared<NiceMock<MockExternalViewEmbedder>>();
rasterizer->SetExternalViewEmbedder(external_view_embedder);
EXPECT_CALL(*external_view_embedder, SupportsDynamicThreadMerging)
.WillRepeatedly(Return(true));
Expand Down Expand Up @@ -265,16 +266,16 @@ TEST(
thread_host.ui_thread->GetTaskRunner(),
thread_host.io_thread->GetTaskRunner());

MockDelegate delegate;
NiceMock<MockDelegate> delegate;
EXPECT_CALL(delegate, GetTaskRunners())
.WillRepeatedly(ReturnRef(task_runners));
EXPECT_CALL(delegate, OnFrameRasterized(_));

auto rasterizer = std::make_unique<Rasterizer>(delegate);
auto surface = std::make_unique<MockSurface>();
auto surface = std::make_unique<NiceMock<MockSurface>>();

std::shared_ptr<MockExternalViewEmbedder> external_view_embedder =
std::make_shared<MockExternalViewEmbedder>();
std::shared_ptr<NiceMock<MockExternalViewEmbedder>> external_view_embedder =
std::make_shared<NiceMock<MockExternalViewEmbedder>>();
rasterizer->SetExternalViewEmbedder(external_view_embedder);

SurfaceFrame::FramebufferInfo framebuffer_info;
Expand Down Expand Up @@ -329,16 +330,16 @@ TEST(RasterizerTest,
thread_host.ui_thread->GetTaskRunner(),
thread_host.io_thread->GetTaskRunner());

MockDelegate delegate;
NiceMock<MockDelegate> delegate;
EXPECT_CALL(delegate, GetTaskRunners())
.WillRepeatedly(ReturnRef(task_runners));
EXPECT_CALL(delegate, OnFrameRasterized(_));

auto rasterizer = std::make_unique<Rasterizer>(delegate);
auto surface = std::make_unique<MockSurface>();
auto surface = std::make_unique<NiceMock<MockSurface>>();

std::shared_ptr<MockExternalViewEmbedder> external_view_embedder =
std::make_shared<MockExternalViewEmbedder>();
std::shared_ptr<NiceMock<MockExternalViewEmbedder>> external_view_embedder =
std::make_shared<NiceMock<MockExternalViewEmbedder>>();
rasterizer->SetExternalViewEmbedder(external_view_embedder);

SurfaceFrame::FramebufferInfo framebuffer_info;
Expand Down Expand Up @@ -402,13 +403,13 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNoSurfaceIsSet) {
thread_host.raster_thread->GetTaskRunner(),
thread_host.ui_thread->GetTaskRunner(),
thread_host.io_thread->GetTaskRunner());
MockDelegate delegate;
NiceMock<MockDelegate> delegate;
EXPECT_CALL(delegate, GetTaskRunners())
.WillRepeatedly(ReturnRef(task_runners));
auto rasterizer = std::make_unique<Rasterizer>(delegate);

std::shared_ptr<MockExternalViewEmbedder> external_view_embedder =
std::make_shared<MockExternalViewEmbedder>();
std::shared_ptr<NiceMock<MockExternalViewEmbedder>> external_view_embedder =
std::make_shared<NiceMock<MockExternalViewEmbedder>>();
rasterizer->SetExternalViewEmbedder(external_view_embedder);

EXPECT_CALL(
Expand Down Expand Up @@ -445,17 +446,17 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNotUsedThisFrame) {
thread_host.raster_thread->GetTaskRunner(),
thread_host.ui_thread->GetTaskRunner(),
thread_host.io_thread->GetTaskRunner());
MockDelegate delegate;
NiceMock<MockDelegate> delegate;
EXPECT_CALL(delegate, GetTaskRunners())
.WillRepeatedly(ReturnRef(task_runners));

auto rasterizer = std::make_unique<Rasterizer>(delegate);
auto surface = std::make_unique<MockSurface>();
auto surface = std::make_unique<NiceMock<MockSurface>>();
EXPECT_CALL(*surface, MakeRenderContextCurrent())
.WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(true))));

std::shared_ptr<MockExternalViewEmbedder> external_view_embedder =
std::make_shared<MockExternalViewEmbedder>();
std::shared_ptr<NiceMock<MockExternalViewEmbedder>> external_view_embedder =
std::make_shared<NiceMock<MockExternalViewEmbedder>>();
rasterizer->SetExternalViewEmbedder(external_view_embedder);
rasterizer->Setup(std::move(surface));

Expand Down Expand Up @@ -500,17 +501,17 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenPipelineIsEmpty) {
thread_host.raster_thread->GetTaskRunner(),
thread_host.ui_thread->GetTaskRunner(),
thread_host.io_thread->GetTaskRunner());
MockDelegate delegate;
NiceMock<MockDelegate> delegate;
EXPECT_CALL(delegate, GetTaskRunners())
.WillRepeatedly(ReturnRef(task_runners));

auto rasterizer = std::make_unique<Rasterizer>(delegate);
auto surface = std::make_unique<MockSurface>();
auto surface = std::make_unique<NiceMock<MockSurface>>();
EXPECT_CALL(*surface, MakeRenderContextCurrent())
.WillOnce(Return(ByMove(std::make_unique<GLContextDefaultResult>(true))));

std::shared_ptr<MockExternalViewEmbedder> external_view_embedder =
std::make_shared<MockExternalViewEmbedder>();
std::shared_ptr<NiceMock<MockExternalViewEmbedder>> external_view_embedder =
std::make_shared<NiceMock<MockExternalViewEmbedder>>();
rasterizer->SetExternalViewEmbedder(external_view_embedder);
rasterizer->Setup(std::move(surface));

Expand Down Expand Up @@ -543,13 +544,13 @@ TEST(RasterizerTest,
thread_host.raster_thread->GetTaskRunner(),
thread_host.ui_thread->GetTaskRunner(),
thread_host.io_thread->GetTaskRunner());
MockDelegate delegate;
NiceMock<MockDelegate> delegate;
EXPECT_CALL(delegate, GetTaskRunners())
.WillRepeatedly(ReturnRef(task_runners));
EXPECT_CALL(delegate, OnFrameRasterized(_));

auto rasterizer = std::make_unique<Rasterizer>(delegate);
auto surface = std::make_unique<MockSurface>();
auto surface = std::make_unique<NiceMock<MockSurface>>();
auto is_gpu_disabled_sync_switch =
std::make_shared<const fml::SyncSwitch>(false);

Expand Down Expand Up @@ -597,12 +598,12 @@ TEST(
thread_host.raster_thread->GetTaskRunner(),
thread_host.ui_thread->GetTaskRunner(),
thread_host.io_thread->GetTaskRunner());
MockDelegate delegate;
NiceMock<MockDelegate> delegate;
EXPECT_CALL(delegate, GetTaskRunners())
.WillRepeatedly(ReturnRef(task_runners));
EXPECT_CALL(delegate, OnFrameRasterized(_));
auto rasterizer = std::make_unique<Rasterizer>(delegate);
auto surface = std::make_unique<MockSurface>();
auto surface = std::make_unique<NiceMock<MockSurface>>();
auto is_gpu_disabled_sync_switch =
std::make_shared<const fml::SyncSwitch>(true);

Expand Down Expand Up @@ -652,12 +653,12 @@ TEST(
thread_host.raster_thread->GetTaskRunner(),
thread_host.ui_thread->GetTaskRunner(),
thread_host.io_thread->GetTaskRunner());
MockDelegate delegate;
NiceMock<MockDelegate> delegate;
EXPECT_CALL(delegate, GetTaskRunners())
.WillRepeatedly(ReturnRef(task_runners));
EXPECT_CALL(delegate, OnFrameRasterized(_));
auto rasterizer = std::make_unique<Rasterizer>(delegate);
auto surface = std::make_unique<MockSurface>();
auto surface = std::make_unique<NiceMock<MockSurface>>();
auto is_gpu_disabled_sync_switch =
std::make_shared<const fml::SyncSwitch>(false);

Expand Down Expand Up @@ -706,12 +707,12 @@ TEST(
thread_host.raster_thread->GetTaskRunner(),
thread_host.ui_thread->GetTaskRunner(),
thread_host.io_thread->GetTaskRunner());
MockDelegate delegate;
NiceMock<MockDelegate> delegate;
EXPECT_CALL(delegate, GetTaskRunners())
.WillRepeatedly(ReturnRef(task_runners));
EXPECT_CALL(delegate, OnFrameRasterized(_)).Times(0);
auto rasterizer = std::make_unique<Rasterizer>(delegate);
auto surface = std::make_unique<MockSurface>();
auto surface = std::make_unique<NiceMock<MockSurface>>();
auto is_gpu_disabled_sync_switch =
std::make_shared<const fml::SyncSwitch>(true);

Expand Down Expand Up @@ -758,7 +759,7 @@ TEST(RasterizerTest,
thread_host.raster_thread->GetTaskRunner(),
thread_host.ui_thread->GetTaskRunner(),
thread_host.io_thread->GetTaskRunner());
MockDelegate delegate;
NiceMock<MockDelegate> delegate;
ON_CALL(delegate, GetTaskRunners()).WillByDefault(ReturnRef(task_runners));

fml::AutoResetWaitableEvent latch;
Expand All @@ -769,7 +770,7 @@ TEST(RasterizerTest,
});
latch.Wait();

auto surface = std::make_unique<MockSurface>();
auto surface = std::make_unique<NiceMock<MockSurface>>();
EXPECT_CALL(*surface, AllowsDrawingWhenGpuDisabled())
.WillRepeatedly(Return(true));
ON_CALL(*surface, AcquireFrame(SkISize()))
Expand Down Expand Up @@ -831,6 +832,88 @@ TEST(RasterizerTest,
latch.Wait();
}

TEST(RasterizerTest, TeardownFreesResourceCache) {
std::string test_name =
::testing::UnitTest::GetInstance()->current_test_info()->name();
ThreadHost thread_host("io.flutter.test." + test_name + ".",
ThreadHost::Type::Platform | ThreadHost::Type::RASTER |
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());

NiceMock<MockDelegate> delegate;
EXPECT_CALL(delegate, GetTaskRunners())
.WillRepeatedly(ReturnRef(task_runners));

auto rasterizer = std::make_unique<Rasterizer>(delegate);
auto surface = std::make_unique<NiceMock<MockSurface>>();
auto context = GrDirectContext::MakeMock(nullptr);
context->setResourceCacheLimit(0);

EXPECT_CALL(*surface, MakeRenderContextCurrent())
.WillRepeatedly([]() -> std::unique_ptr<GLContextResult> {
return std::make_unique<GLContextDefaultResult>(true);
});
EXPECT_CALL(*surface, GetContext()).WillRepeatedly(Return(context.get()));

rasterizer->Setup(std::move(surface));
EXPECT_EQ(context->getResourceCacheLimit(), 0ul);

rasterizer->SetResourceCacheMaxBytes(10000000, false);
EXPECT_EQ(context->getResourceCacheLimit(), 10000000ul);
EXPECT_EQ(context->getResourceCachePurgeableBytes(), 0ul);

int count = 0;
size_t bytes = 0;
context->getResourceCacheUsage(&count, &bytes);
EXPECT_EQ(bytes, 0ul);

auto image_info =
SkImageInfo::MakeN32Premul(500, 500, SkColorSpace::MakeSRGB());
auto sk_surface =
SkSurface::MakeRenderTarget(context.get(), SkBudgeted::kYes, image_info);
EXPECT_TRUE(sk_surface);

SkPaint paint;
sk_surface->getCanvas()->drawPaint(paint);
sk_surface->getCanvas()->flush();
context->flushAndSubmit(true);

EXPECT_EQ(context->getResourceCachePurgeableBytes(), 0ul);

sk_surface.reset();

context->getResourceCacheUsage(&count, &bytes);
EXPECT_GT(bytes, 0ul);
EXPECT_GT(context->getResourceCachePurgeableBytes(), 0ul);

rasterizer->Teardown();
EXPECT_EQ(context->getResourceCachePurgeableBytes(), 0ul);
}

TEST(RasterizerTest, TeardownNoSurface) {
std::string test_name =
::testing::UnitTest::GetInstance()->current_test_info()->name();
ThreadHost thread_host("io.flutter.test." + test_name + ".",
ThreadHost::Type::Platform | ThreadHost::Type::RASTER |
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());

NiceMock<MockDelegate> delegate;
EXPECT_CALL(delegate, GetTaskRunners())
.WillRepeatedly(ReturnRef(task_runners));

auto rasterizer = std::make_unique<Rasterizer>(delegate);

EXPECT_TRUE(rasterizer);
rasterizer->Teardown();
}

TEST(RasterizerTest, presentationTimeSetWhenVsyncTargetInFuture) {
std::string test_name =
::testing::UnitTest::GetInstance()->current_test_info()->name();
Expand All @@ -841,7 +924,8 @@ TEST(RasterizerTest, presentationTimeSetWhenVsyncTargetInFuture) {
thread_host.raster_thread->GetTaskRunner(),
thread_host.ui_thread->GetTaskRunner(),
thread_host.io_thread->GetTaskRunner());
MockDelegate delegate;

NiceMock<MockDelegate> delegate;
ON_CALL(delegate, GetTaskRunners()).WillByDefault(ReturnRef(task_runners));

fml::AutoResetWaitableEvent latch;
Expand Down Expand Up @@ -920,7 +1004,8 @@ TEST(RasterizerTest, presentationTimeNotSetWhenVsyncTargetInPast) {
thread_host.raster_thread->GetTaskRunner(),
thread_host.ui_thread->GetTaskRunner(),
thread_host.io_thread->GetTaskRunner());
MockDelegate delegate;

NiceMock<MockDelegate> delegate;
ON_CALL(delegate, GetTaskRunners()).WillByDefault(ReturnRef(task_runners));

fml::AutoResetWaitableEvent latch;
Expand Down
Loading