Commit 367b93da authored by Carlos Caballero's avatar Carlos Caballero Committed by Commit Bot

Freeze compositor queue when all pages are frozen.

Bug: 1111720
Change-Id: I6325fbfef9bc9f18495dbd3c4842571e56a356a5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2332656
Commit-Queue: Carlos Caballero <carlscab@google.com>
Reviewed-by: default avatarAlexander Timin <altimin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#794967}
parent 1b75d718
......@@ -1534,6 +1534,8 @@ void MainThreadSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) {
new_policy.find_in_page_priority() =
find_in_page_budget_pool_controller_->CurrentTaskPriority();
new_policy.should_freeze_compositor_task_queue() = AllPagesFrozen();
// Tracing is done before the early out check, because it's quite possible we
// will otherwise miss this information in traces.
CreateTraceEventObjectSnapshotLocked();
......@@ -1565,8 +1567,6 @@ void MainThreadSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) {
}
}
DCHECK(compositor_task_queue_->IsQueueEnabled());
Policy old_policy = main_thread_only().current_policy;
main_thread_only().current_policy = new_policy;
......@@ -1596,6 +1596,8 @@ void MainThreadSchedulerImpl::UpdateStateForAllTaskQueues(
current_policy.GetQueuePolicy(queue_class),
should_update_priorities);
}
compositor_task_queue_enabled_voter_->SetVoteToEnable(
!current_policy.should_freeze_compositor_task_queue());
}
void MainThreadSchedulerImpl::UpdateTaskQueueState(
......@@ -2412,11 +2414,13 @@ void MainThreadSchedulerImpl::AddPageScheduler(
memory_purge_manager_.OnPageCreated(
page_scheduler->GetPageLifecycleState());
}
base::AutoLock lock(any_thread_lock_);
any_thread().waiting_for_any_main_frame_contentful_paint =
IsAnyMainFrameWaitingForFirstContentfulPaint();
any_thread().waiting_for_any_main_frame_meaningful_paint =
IsAnyMainFrameWaitingForFirstMeaningfulPaint();
UpdatePolicyLocked(UpdateType::kMayEarlyOutIfPolicyUnchanged);
}
void MainThreadSchedulerImpl::RemovePageScheduler(
......@@ -2428,11 +2432,13 @@ void MainThreadSchedulerImpl::RemovePageScheduler(
memory_purge_manager_.OnPageDestroyed(
page_scheduler->GetPageLifecycleState());
}
base::AutoLock lock(any_thread_lock_);
any_thread().waiting_for_any_main_frame_contentful_paint =
IsAnyMainFrameWaitingForFirstContentfulPaint();
any_thread().waiting_for_any_main_frame_meaningful_paint =
IsAnyMainFrameWaitingForFirstMeaningfulPaint();
UpdatePolicyLocked(UpdateType::kMayEarlyOutIfPolicyUnchanged);
}
void MainThreadSchedulerImpl::OnFrameAdded(
......@@ -2453,10 +2459,12 @@ void MainThreadSchedulerImpl::OnFrameRemoved(
void MainThreadSchedulerImpl::OnPageFrozen() {
memory_purge_manager_.OnPageFrozen();
UpdatePolicy();
}
void MainThreadSchedulerImpl::OnPageResumed() {
memory_purge_manager_.OnPageResumed();
UpdatePolicy();
}
void MainThreadSchedulerImpl::BroadcastIntervention(const String& message) {
......@@ -2802,6 +2810,16 @@ void MainThreadSchedulerImpl::DispatchOnTaskCompletionCallbacks() {
main_thread_only().on_task_completion_callbacks.clear();
}
bool MainThreadSchedulerImpl::AllPagesFrozen() const {
if (main_thread_only().page_schedulers.IsEmpty())
return false;
for (const auto* scheduler : main_thread_only().page_schedulers) {
if (!scheduler->IsFrozen())
return false;
}
return true;
}
// static
const char* MainThreadSchedulerImpl::UseCaseToString(UseCase use_case) {
switch (use_case) {
......
......@@ -566,6 +566,13 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
return should_prioritize_loading_with_compositing_;
}
bool& should_freeze_compositor_task_queue() {
return should_freeze_compositor_task_queue_;
}
bool should_freeze_compositor_task_queue() const {
return should_freeze_compositor_task_queue_;
}
base::sequence_manager::TaskQueue::QueuePriority& compositor_priority() {
return compositor_priority_;
}
......@@ -591,6 +598,8 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
frozen_when_backgrounded_ == other.frozen_when_backgrounded_ &&
should_prioritize_loading_with_compositing_ ==
other.should_prioritize_loading_with_compositing_ &&
should_freeze_compositor_task_queue_ ==
other.should_freeze_compositor_task_queue_ &&
compositor_priority_ == other.compositor_priority_ &&
find_in_page_priority_ == other.find_in_page_priority_ &&
use_case_ == other.use_case_;
......@@ -603,6 +612,7 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
bool should_disable_throttling_;
bool frozen_when_backgrounded_;
bool should_prioritize_loading_with_compositing_;
bool should_freeze_compositor_task_queue_{false};
// Priority of task queues belonging to the compositor class (Check
// MainThread::QueueClass).
......@@ -797,6 +807,8 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
void AsValueIntoLocked(base::trace_event::TracedValue*,
base::TimeTicks optional_now) const;
bool AllPagesFrozen() const;
// Indicates that scheduler has been shutdown.
// It should be accessed only on the main thread, but couldn't be a member
// of MainThreadOnly struct because last might be destructed before we
......
......@@ -40,6 +40,7 @@
#include "third_party/blink/renderer/platform/scheduler/main_thread/find_in_page_budget_pool_controller.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/test/recording_task_time_observer.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
#include "v8/include/v8.h"
......@@ -3386,6 +3387,51 @@ TEST_F(MainThreadSchedulerImplTest, PauseTimersForAndroidWebView) {
}
#endif // defined(OS_ANDROID)
TEST_F(MainThreadSchedulerImplTest, FreezesCompositorQueueWhenAllPagesFrozen) {
main_frame_scheduler_.reset();
page_scheduler_.reset();
std::unique_ptr<PageScheduler> sched_1 =
scheduler_->CreatePageScheduler(nullptr);
sched_1->SetPageVisible(false);
std::unique_ptr<PageScheduler> sched_2 =
scheduler_->CreatePageScheduler(nullptr);
sched_2->SetPageVisible(false);
Vector<String> run_order;
sched_1->SetPageVisible(false);
sched_1->SetPageFrozen(true);
PostTestTasks(&run_order, "D1 C1");
base::RunLoop().RunUntilIdle();
EXPECT_THAT(run_order, testing::ElementsAre("D1", "C1"));
run_order.clear();
sched_2->SetPageFrozen(true);
PostTestTasks(&run_order, "D2 C2");
base::RunLoop().RunUntilIdle();
EXPECT_THAT(run_order, testing::ElementsAre("D2"));
run_order.clear();
std::unique_ptr<PageScheduler> sched_3 =
scheduler_->CreatePageScheduler(nullptr);
sched_3->SetPageVisible(false);
base::RunLoop().RunUntilIdle();
EXPECT_THAT(run_order, testing::ElementsAre("C2"));
run_order.clear();
PostTestTasks(&run_order, "D3 C3");
sched_3.reset();
base::RunLoop().RunUntilIdle();
EXPECT_THAT(run_order, testing::ElementsAre("D3"));
run_order.clear();
sched_1.reset();
sched_2.reset();
base::RunLoop().RunUntilIdle();
EXPECT_THAT(run_order, testing::ElementsAre("C3"));
}
class MainThreadSchedulerImplWithInitalVirtualTimeTest
: public MainThreadSchedulerImplTest {
public:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment