chromium/cc/scheduler/scheduler_unittest.cc

// Copyright 2011 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cc/scheduler/scheduler.h"

#include <stddef.h>

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/auto_reset.h"
#include "base/check_op.h"
#include "base/functional/bind.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/notreached.h"
#include "base/numerics/safe_conversions.h"
#include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_mock_time_task_runner.h"
#include "base/time/time.h"
#include "base/time/time_override.h"
#include "base/trace_event/trace_event.h"
#include "cc/base/features.h"
#include "cc/metrics/begin_main_frame_metrics.h"
#include "cc/metrics/event_metrics.h"
#include "cc/test/fake_compositor_frame_reporting_controller.h"
#include "cc/test/scheduler_test_common.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "components/viz/test/begin_frame_args_test.h"
#include "components/viz/test/fake_delay_based_time_source.h"
#include "components/viz/test/fake_external_begin_frame_source.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

#define EXPECT_ACTIONS(...)

#define EXPECT_NO_ACTION()

#define EXPECT_SCOPED(statements)

namespace cc {
namespace {

base::TimeDelta kSlowDuration =;
base::TimeDelta kFastDuration =;

class FakeSchedulerClient : public SchedulerClient,
                            public viz::FakeExternalBeginFrameSource::Client {};

enum BeginFrameSourceType {};

class SchedulerTestTaskRunner : public base::TestMockTimeTaskRunner {};

class SchedulerTest : public testing::Test {};

TEST_F(SchedulerTest, InitializeLayerTreeFrameSinkDoesNotBeginImplFrame) {}

TEST_F(SchedulerTest, Stop) {}

TEST_F(SchedulerTest, VideoNeedsBeginFrames) {}

TEST_F(SchedulerTest, RequestCommit) {}

TEST_F(SchedulerTest, RequestCommitAfterSetDeferBeginMainFrame) {}

TEST_F(SchedulerTest, DeferBeginMainFrameWithRedraw) {}

TEST_F(SchedulerTest, RequestCommitAfterBeginMainFrameSent) {}

class SchedulerClientThatsetNeedsDrawInsideDraw : public FakeSchedulerClient {};

// Tests for two different situations:
// 1. the scheduler dropping SetNeedsRedraw requests that happen inside
//    a ScheduledActionDraw
// 2. the scheduler drawing twice inside a single tick
TEST_F(SchedulerTest, RequestRedrawInsideDraw) {}

// Test that requesting redraw inside a failed draw doesn't lose the request.
TEST_F(SchedulerTest, RequestRedrawInsideFailedDraw) {}

class SchedulerClientThatSetNeedsBeginMainFrameInsideDraw
    : public FakeSchedulerClient {};

// Tests for the scheduler infinite-looping on SetNeedsBeginMainFrame requests
// that happen inside a ScheduledActionDraw
TEST_F(SchedulerTest, RequestCommitInsideDraw) {}

// Tests that when a draw fails then the pending commit should not be dropped.
TEST_F(SchedulerTest, RequestCommitInsideFailedDraw) {}

TEST_F(SchedulerTest, NoSwapWhenDrawFails) {}

class SchedulerClientNeedsPrepareTilesInDraw : public FakeSchedulerClient {};

// Test prepare tiles is independant of draws.
TEST_F(SchedulerTest, PrepareTiles) {}

// Test that PrepareTiles only happens once per frame.  If an external caller
// initiates it, then the state machine should not PrepareTiles on that frame.
TEST_F(SchedulerTest, PrepareTilesOncePerFrame) {}

TEST_F(SchedulerTest, DidPrepareTilesPreventsPrepareTilesForOneFrame) {}

TEST_F(SchedulerTest, TriggerBeginFrameDeadlineEarly) {}

TEST_F(SchedulerTest, WaitForReadyToDrawDoNotPostDeadline) {}

TEST_F(SchedulerTest, WaitForReadyToDrawCancelledWhenLostLayerTreeFrameSink) {}

void SchedulerTest::AdvanceAndMissOneFrame() {}

void SchedulerTest::CheckMainFrameNotSkippedAfterLateCommit() {}

TEST_F(SchedulerTest, MainFrameNotSkippedAfterLateBeginFrame) {}

TEST_F(SchedulerTest, FrameIntervalUpdated) {}

TEST_F(SchedulerTest, MainFrameNotSkippedAfterLateCommit) {}

// Response times of BeginMainFrame's without the critical path flag set
// should not affect whether we recover latency or not.
TEST_F(
    SchedulerTest,
    MainFrameNotSkippedAfterLateCommit_LongMainFrameQueueDurationNotCritical) {}

// Response times of BeginMainFrame's with the critical path flag set
// should affect whether we recover latency or not.
TEST_F(SchedulerTest,
       MainFrameNotSkippedAfterLateCommit_LongMainFrameQueueDurationCritical) {}

TEST_F(SchedulerTest,
       MainFrameNotSkippedAfterLateCommitInPreferImplLatencyMode) {}

TEST_F(SchedulerTest,
       MainFrameNotSkippedAfterLateCommit_CommitEstimateTooLong) {}

TEST_F(SchedulerTest,
       MainFrameNotSkippedAfterLateCommit_ReadyToActivateEstimateTooLong) {}

TEST_F(SchedulerTest,
       MainFrameNotSkippedAfterLateCommit_ActivateEstimateTooLong) {}

TEST_F(SchedulerTest, MainFrameNotSkippedAfterLateCommit_DrawEstimateTooLong) {}

// If the BeginMainFrame aborts, it doesn't actually insert a frame into the
// queue, which means there is no latency to recover.
TEST_F(SchedulerTest, MainFrameNotSkippedAfterLateBeginMainFrameAbort) {}

// If the BeginMainFrame aborts, it doesn't actually insert a frame into the
// queue, which means there is no latency to recover.
TEST_F(SchedulerTest, MainFrameNotSkippedAfterCanDrawChanges) {}

TEST_F(SchedulerTest, MainFrameNotSkippedWhenNoTimingHistory) {}

void SchedulerTest::ImplFrameNotSkippedAfterLateAck() {}

TEST_F(SchedulerTest,
       ImplFrameNotSkippedAfterLateAck_MainFrameQueueDurationCriticalTooLong) {}

TEST_F(SchedulerTest, ImplFrameNotSkippedAfterLateAck_CommitEstimateTooLong) {}

TEST_F(SchedulerTest,
       ImplFrameNotSkippedAfterLateAck_ReadyToActivateEstimateTooLong) {}

TEST_F(SchedulerTest, ImplFrameNotSkippedAfterLateAck_ActivateEstimateTooLong) {}

TEST_F(SchedulerTest, ImplFrameNotSkippedAfterLateAck_DrawEstimateTooLong) {}

void SchedulerTest::BeginFramesNotFromClient(BeginFrameSourceType bfs_type) {}

TEST_F(SchedulerTest, SyntheticBeginFrames) {}

TEST_F(SchedulerTest, UnthrottledBeginFrames) {}

void SchedulerTest::BeginFramesNotFromClient_IsDrawThrottled(
    BeginFrameSourceType bfs_type) {}

TEST_F(SchedulerTest, SyntheticBeginFrames_IsDrawThrottled) {}

TEST_F(SchedulerTest, UnthrottledBeginFrames_IsDrawThrottled) {}

TEST_F(SchedulerTest,
       DidLoseLayerTreeFrameSinkAfterLayerTreeFrameSinkIsInitialized) {}

TEST_F(SchedulerTest, DidLoseLayerTreeFrameSinkAfterBeginFrameStarted) {}

TEST_F(SchedulerTest,
       DidLoseLayerTreeFrameSinkAfterBeginFrameStartedWithHighLatency) {}

TEST_F(SchedulerTest, DidLoseLayerTreeFrameSinkAfterReadyToCommit) {}

TEST_F(SchedulerTest, DidLoseLayerTreeFrameSinkAfterSetNeedsPrepareTiles) {}

TEST_F(SchedulerTest, DidLoseLayerTreeFrameSinkWithDelayBasedBeginFrameSource) {}

TEST_F(SchedulerTest, DidLoseLayerTreeFrameSinkWhenIdle) {}

TEST_F(SchedulerTest, ScheduledActionActivateAfterBecomingInvisible) {}

TEST_F(SchedulerTest, ScheduledActionActivateAfterBeginFrameSourcePaused) {}

// Tests to ensure frame sources can be successfully changed while drawing.
TEST_F(SchedulerTest, SwitchFrameSourceToUnthrottled) {}

// Tests to ensure frame sources can be successfully changed while a frame
// deadline is pending.
TEST_F(SchedulerTest, SwitchFrameSourceToUnthrottledBeforeDeadline) {}

// Tests to ensure that the active frame source can successfully be changed from
// unthrottled to throttled.
TEST_F(SchedulerTest, SwitchFrameSourceToThrottled) {}

TEST_F(SchedulerTest, SwitchFrameSourceToNullInsideDeadline) {}

// This test maskes sure that switching a frame source when not observing
// such as when not visible also works.
TEST_F(SchedulerTest, SwitchFrameSourceWhenNotObserving) {}

// Tests to ensure that we send a ScheduledActionBeginMainFrameNotExpectedUntil
// when expected.
TEST_F(SchedulerTest, ScheduledActionBeginMainFrameNotExpectedUntil) {}

// Tests to ensure that BeginMainFrameNotExpectedUntil is only sent once within
// the same frame.
TEST_F(SchedulerTest,
       ScheduledActionBeginMainFrameNotExpectedUntilSentOnlyOncePerFrame) {}

// Tests to ensure that we send a BeginMainFrameNotExpectedSoon when expected.
TEST_F(SchedulerTest, SendBeginMainFrameNotExpectedSoon_Requested) {}

// Tests to ensure that we dont't send a BeginMainFrameNotExpectedSoon when
// possible but not requested.
TEST_F(SchedulerTest, SendBeginMainFrameNotExpectedSoon_Unrequested) {}

// Tests to ensure that we send a BeginMainFrameNotExpectedSoon only once per
// frame.
TEST_F(SchedulerTest, SendBeginMainFrameNotExpectedSoonOnlyOncePerFrame) {}

// Tests to ensure that we send a BeginMainFrameNotExpectedSoon in situations
// where the client doesn't want messages when we first stopped observing
// BeginFrames but later does.
TEST_F(SchedulerTest, SendBeginMainFrameNotExpectedSoon_AlreadyIdle) {}

// This tests to ensure BeginMainFrameNotExpectedSoon is sent during idle
// periods if (1) it initially wasn't sent because the message wasn't needed at
// the time, and (2) the BeginMainFrameNotExpectedUntil was already sent in the
// frame (crbug.com/893653).
TEST_F(SchedulerTest, SendBeginMainFrameNotExpectedSoonDuringIdleIfNeeded) {}

// This tests to ensure BeginMainFrameNotExpectedSoon is sent during idle
// periods if (1) it initially wasn't sent because the message wasn't needed at
// the time, and (2) |scheduler_|.visible() is false.
TEST_F(SchedulerTest,
       ScheduledActionBeginMainFrameNotSoonSentDuringIdleIfNeededNotVisible) {}

TEST_F(SchedulerTest, SynchronousCompositorAnimation) {}

TEST_F(SchedulerTest, SynchronousCompositorOnDrawDuringIdle) {}

TEST_F(SchedulerTest, InvalidateLayerTreeFrameSinkWhenCannotDraw) {}

TEST_F(SchedulerTest, NeedsPrepareTilesInvalidates) {}

TEST_F(SchedulerTest, SetNeedsOneBeginImplFrame) {}

TEST_F(SchedulerTest, AbortEarlyIfNoDamage) {}

TEST_F(SchedulerTest, SkipDraw) {}

TEST_F(SchedulerTest, SynchronousCompositorCommitAndVerifyBeginFrameAcks) {}

class SchedulerClientSetNeedsPrepareTilesOnDraw : public FakeSchedulerClient {};

TEST_F(SchedulerTest, SynchronousCompositorPrepareTilesOnDraw) {}

// Synchronous compositor does not require the active tree to be drawn at least
// once before the next activation. This test verifies two commit-activate
// cycles without draw work correctly.
TEST_F(SchedulerTest, SynchronousCompositorAllowsActivateBeforeDraw) {}

TEST_F(SchedulerTest, SetNeedsRedrawFromWillBeginImplFrame) {}

TEST_F(SchedulerTest, SynchronousCompositorSendBeginMainFrameWhileIdle) {}

TEST_F(SchedulerTest, SynchronousCompositorResourcelessOnDrawWhenInvisible) {}

TEST_F(SchedulerTest, AuthoritativeVSyncInterval) {}

TEST_F(SchedulerTest, ImplLatencyTakesPriority) {}

TEST_F(SchedulerTest, NoLayerTreeFrameSinkCreationWhileCommitPending) {}

TEST_F(SchedulerTest, ImplSideInvalidationInsideImplFrame) {}

TEST_F(SchedulerTest, ImplSideInvalidationsMergedWithCommit) {}

TEST_F(SchedulerTest, AbortedCommitsTriggerImplSideInvalidations) {}

TEST_F(SchedulerTest, InvalidationNotBlockedOnMainFrame) {}

// The three letters appeneded to each version of this test mean the following:s
// tree_priority: B = both trees same priority; A = active tree priority;
// scroll_handler_state: H = affects scroll handler; N = does not affect scroll
// handler;
// durations: F = fast durations; S = slow durations
bool SchedulerTest::BeginMainFrameOnCriticalPath(
    TreePriority tree_priority,
    ScrollHandlerState scroll_handler_state,
    base::TimeDelta durations) {}

TEST_F(SchedulerTest, BeginMainFrameOnCriticalPath_BNF) {}

TEST_F(SchedulerTest, BeginMainFrameOnCriticalPath_BNS) {}

TEST_F(SchedulerTest, BeginMainFrameOnCriticalPath_BHF) {}

TEST_F(SchedulerTest, BeginMainFrameOnCriticalPath_BHS) {}

TEST_F(SchedulerTest, BeginMainFrameOnCriticalPath_ANF) {}

TEST_F(SchedulerTest, BeginMainFrameOnCriticalPath_ANS) {}

TEST_F(SchedulerTest, BeginMainFrameOnCriticalPath_AHF) {}

TEST_F(SchedulerTest, BeginMainFrameOnCriticalPath_AHS) {}

TEST_F(SchedulerTest, BeginFrameAckForFinishedImplFrame) {}

TEST_F(SchedulerTest, BeginFrameAckForBeginFrameBeforeLastDeadline) {}

TEST_F(SchedulerTest, BeginFrameAckForDroppedBeginFrame) {}

TEST_F(SchedulerTest, BeginFrameAckForLateMissedBeginFrame) {}

TEST_F(SchedulerTest, CriticalBeginMainFrameToActivateIsFast) {}

TEST_F(SchedulerTest, WaitForAllPipelineStagesUsesMissedBeginFrames) {}

TEST_F(SchedulerTest, WaitForAllPipelineStagesAlwaysObservesBeginFrames) {}

TEST_F(SchedulerTest, CriticalBeginMainFrameIsFast_CommitEstimateSlow) {}

TEST_F(SchedulerTest, CriticalBeginMainFrameIsFast_CommitEstimateFast) {}

TEST_F(SchedulerTest, ShouldDeferInvalidation_AllEstimatesFast) {}

TEST_F(SchedulerTest, ShouldDeferInvalidation_BMFStartToReadyToCommitSlow) {}

TEST_F(SchedulerTest, ShouldDeferInvalidation_BMFQueueDurationCriticalSlow) {}

TEST_F(SchedulerTest, ShouldDeferInvalidation_BMFQueueDurationNotCriticalSlow) {}

TEST_F(SchedulerTest, SlowMainThreadButEstimatedFastTriggersInvalidations) {}

TEST_F(SchedulerTest,
       SlowMainThreadRasterButEstimatedFastDoesNotTriggersInvalidations) {}

TEST_F(SchedulerTest, SynchronousCompositorImplSideInvalidation) {}

TEST_F(SchedulerTest, NoInvalidationForAnimateOnlyFrames) {}

TEST_F(SchedulerTest, SendEarlyDidNotProduceFrameIfIdle) {}

TEST_F(SchedulerTest,
       HighImplLatencyModePrioritizesMainFramesOverImplInvalidation) {}

class WarmUpCompositorSchedulerTest : public SchedulerTest {};

// Tests that `SetShouldWarmUp()` will start initial `LayerTreeFrameSink`
// creation even if invisible.
TEST_F(WarmUpCompositorSchedulerTest,
       SetShouldWarmUpWillStartLayerTreeFrameSinkCreation) {}

}  // namespace
}  // namespace cc