diff --git a/shell/common/animator.cc b/shell/common/animator.cc index 2fbd6fa772f1e..8ba822fb938b8 100644 --- a/shell/common/animator.cc +++ b/shell/common/animator.cc @@ -49,7 +49,10 @@ Animator::Animator(Delegate& delegate, weak_factory_(this) { } -Animator::~Animator() = default; +Animator::~Animator() { + // Remove all queued layer trees to ensure that Skia objects are unreffed. + layer_tree_pipeline_->Clear(); +} void Animator::Stop() { paused_ = true; diff --git a/shell/common/pipeline.h b/shell/common/pipeline.h index d05e0f50612c0..310ebb1d0c50c 100644 --- a/shell/common/pipeline.h +++ b/shell/common/pipeline.h @@ -151,6 +151,12 @@ class Pipeline : public fml::RefCountedThreadSafe> { { std::scoped_lock lock(queue_mutex_); + + if (queue_.empty()) { + // Items were removed from queue in Clear after available_ was + // signalled. + return PipelineConsumeResult::NoneAvailable; + } std::tie(resource, trace_id) = std::move(queue_.front()); queue_.pop_front(); items_count = queue_.size(); @@ -171,6 +177,12 @@ class Pipeline : public fml::RefCountedThreadSafe> { : PipelineConsumeResult::Done; } + /// Remove all items from the queue. + void Clear() { + std::scoped_lock lock(queue_mutex_); + queue_.clear(); + } + private: const uint32_t depth_; fml::Semaphore empty_; diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc index 4c5090f34d8f0..18cd9f2a83367 100644 --- a/shell/common/shell_unittests.cc +++ b/shell/common/shell_unittests.cc @@ -701,9 +701,12 @@ TEST_F(ShellTest, auto end_frame_callback = [&](bool should_resubmit_frame, fml::RefPtr raster_thread_merger) { - ASSERT_TRUE(raster_thread_merger.get() != nullptr); - ASSERT_TRUE(should_resubmit_frame); - end_frame_called = true; + // The asserts below are only valid until DestroyShell is called + if (!end_frame_called) { + ASSERT_TRUE(raster_thread_merger.get() != nullptr); + ASSERT_TRUE(should_resubmit_frame); + end_frame_called = true; + } end_frame_latch.Signal(); }; auto external_view_embedder = std::make_shared(