blob: 09d40510211f2dc6801a4ebaec8238ab3b1b3c38 [file] [log] [blame]
// Copyright 2019 The Chromium 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 "cc/metrics/frame_sequence_tracker.h"
#include "base/macros.h"
#include "cc/metrics/compositor_frame_reporting_controller.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace cc {
namespace {
class FrameSequenceTrackerTest;
class FrameSequenceTrackerTest : public testing::Test {
public:
const uint32_t kImplDamage = 0x1;
const uint32_t kMainDamage = 0x2;
FrameSequenceTrackerTest()
: compositor_frame_reporting_controller_(
std::make_unique<CompositorFrameReportingController>()),
collection_(compositor_frame_reporting_controller_.get()),
tracker_(
collection_.CreateTracker(FrameSequenceTrackerType::kTouchScroll)) {
}
~FrameSequenceTrackerTest() override = default;
std::unique_ptr<FrameSequenceTracker> CreateNewTracker() {
return collection_.CreateTracker(FrameSequenceTrackerType::kTouchScroll);
}
viz::BeginFrameArgs CreateBeginFrameArgs(uint64_t source_id,
uint64_t sequence_number) {
auto now = base::TimeTicks::Now();
auto interval = base::TimeDelta::FromMilliseconds(16);
auto deadline = now + interval;
return viz::BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, source_id,
sequence_number, now, deadline, interval,
viz::BeginFrameArgs::NORMAL);
}
void StartImplAndMainFrames(const viz::BeginFrameArgs& args) {
collection_.NotifyBeginImplFrame(args);
collection_.NotifyBeginMainFrame(args);
}
uint32_t DispatchCompleteFrame(const viz::BeginFrameArgs& args,
uint32_t damage_type) {
StartImplAndMainFrames(args);
if (damage_type & kImplDamage) {
if (!(damage_type & kMainDamage)) {
collection_.NotifyMainFrameCausedNoDamage(args);
}
uint32_t frame_token = NextFrameToken();
collection_.NotifySubmitFrame(frame_token, viz::BeginFrameAck(args, true),
args);
return frame_token;
} else {
collection_.NotifyImplFrameCausedNoDamage(
viz::BeginFrameAck(args, false));
collection_.NotifyMainFrameCausedNoDamage(args);
}
return 0;
}
uint32_t NextFrameToken() {
static uint32_t frame_token = 0;
return ++frame_token;
}
protected:
std::unique_ptr<CompositorFrameReportingController>
compositor_frame_reporting_controller_;
FrameSequenceTrackerCollection collection_;
std::unique_ptr<FrameSequenceTracker> tracker_;
};
// Tests that the tracker works correctly when the source-id for the
// begin-frames change.
TEST_F(FrameSequenceTrackerTest, SourceIdChangeDuringSequence) {
const uint64_t source_1 = 1;
uint64_t sequence_1 = 0;
// Dispatch some frames, both causing damage to impl/main, and both impl and
// main providing damage to the frame.
auto args_1 = CreateBeginFrameArgs(source_1, ++sequence_1);
DispatchCompleteFrame(args_1, kImplDamage | kMainDamage);
args_1 = CreateBeginFrameArgs(source_1, ++sequence_1);
DispatchCompleteFrame(args_1, kImplDamage | kMainDamage);
// Start a new tracker.
auto tracker = CreateNewTracker();
// Change the source-id, and start an impl frame. This time, the main-frame
// does not provide any damage.
const uint64_t source_2 = 2;
uint64_t sequence_2 = 0;
auto args_2 = CreateBeginFrameArgs(source_2, ++sequence_2);
collection_.NotifyBeginImplFrame(args_2);
collection_.NotifyBeginMainFrame(args_2);
collection_.NotifyMainFrameCausedNoDamage(args_2);
// Since the main-frame did not have any new damage from the latest
// BeginFrameArgs, the submit-frame will carry the previous BeginFrameArgs
// (from source_1);
collection_.NotifySubmitFrame(NextFrameToken(),
viz::BeginFrameAck(args_2, true), args_1);
}
} // namespace
} // namespace cc