blob: 94f6ffdfa666473da68b77a2da4bfe2bcd1c7990 [file] [log] [blame]
// Copyright 2015 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/scheduler/compositor_frame_reporting_controller.h"
#include "base/macros.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace cc {
namespace {
class CompositorFrameReportingControllerTest;
class TestCompositorFrameReportingController
: public CompositorFrameReportingController {
public:
TestCompositorFrameReportingController(
CompositorFrameReportingControllerTest* test)
: CompositorFrameReportingController(), test_(test) {}
TestCompositorFrameReportingController(
const TestCompositorFrameReportingController& controller) = delete;
TestCompositorFrameReportingController& operator=(
const TestCompositorFrameReportingController& controller) = delete;
std::unique_ptr<CompositorFrameReporter>* reporters() { return reporters_; }
int ActiveReporters() {
int count = 0;
for (int i = 0; i < PipelineStage::kNumPipelineStages; ++i) {
if (reporters_[i])
++count;
}
return count;
}
protected:
CompositorFrameReportingControllerTest* test_;
};
class CompositorFrameReportingControllerTest : public testing::Test {
public:
CompositorFrameReportingControllerTest() : reporting_controller_(this) {}
// The following functions simulate the actions that would
// occur for each phase of the reporting controller.
void SimulateBeginImplFrame() { reporting_controller_.WillBeginImplFrame(); }
void SimulateBeginMainFrame() {
if (!reporting_controller_.reporters()[CompositorFrameReportingController::
PipelineStage::kBeginImplFrame])
SimulateBeginImplFrame();
CHECK(
reporting_controller_.reporters()[CompositorFrameReportingController::
PipelineStage::kBeginImplFrame]);
reporting_controller_.WillBeginMainFrame();
}
void SimulateCommit() {
if (!reporting_controller_.reporters()[CompositorFrameReportingController::
PipelineStage::kBeginMainFrame])
SimulateBeginMainFrame();
CHECK(
reporting_controller_.reporters()[CompositorFrameReportingController::
PipelineStage::kBeginMainFrame]);
reporting_controller_.WillCommit();
reporting_controller_.DidCommit();
}
void SimulateActivate() {
if (!reporting_controller_.reporters()
[CompositorFrameReportingController::PipelineStage::kCommit])
SimulateCommit();
CHECK(reporting_controller_.reporters()
[CompositorFrameReportingController::PipelineStage::kCommit]);
reporting_controller_.WillActivate();
reporting_controller_.DidActivate();
}
void SimulateSubmitCompositorFrame() {
if (!reporting_controller_.reporters()
[CompositorFrameReportingController::PipelineStage::kActivate])
SimulateActivate();
CHECK(reporting_controller_.reporters()
[CompositorFrameReportingController::PipelineStage::kActivate]);
reporting_controller_.DidSubmitCompositorFrame();
}
protected:
TestCompositorFrameReportingController reporting_controller_;
};
TEST_F(CompositorFrameReportingControllerTest, ActiveReporterCounts) {
// Check that there are no leaks with the CompositorFrameReporter
// objects no matter what the sequence of scheduled actions is
// Note that due to DCHECKs in WillCommit(), WillActivate(), etc., it
// is impossible to have 2 reporters both in BMF or Commit
// Tests Cases:
// - 2 Reporters at Activate phase
// - 2 back-to-back BeginImplFrames
// - 4 Simultaneous Reporters
// BF
reporting_controller_.WillBeginImplFrame();
EXPECT_EQ(1, reporting_controller_.ActiveReporters());
// BF -> BF
// Should replace previous reporter
reporting_controller_.WillBeginImplFrame();
EXPECT_EQ(1, reporting_controller_.ActiveReporters());
// BF -> BMF -> BF
// Should add new reporter
reporting_controller_.WillBeginMainFrame();
reporting_controller_.WillBeginImplFrame();
EXPECT_EQ(2, reporting_controller_.ActiveReporters());
// BF -> BMF -> BF -> Commit
// Should stay same
reporting_controller_.WillCommit();
reporting_controller_.DidCommit();
EXPECT_EQ(2, reporting_controller_.ActiveReporters());
// BF -> BMF -> BF -> Commit -> BMF -> Activate -> Commit -> Activation
// Having two reporters at Activate phase should delete the older one
reporting_controller_.WillBeginMainFrame();
reporting_controller_.WillActivate();
reporting_controller_.DidActivate();
reporting_controller_.WillCommit();
reporting_controller_.DidCommit();
reporting_controller_.WillActivate();
reporting_controller_.DidActivate();
EXPECT_EQ(1, reporting_controller_.ActiveReporters());
reporting_controller_.DidSubmitCompositorFrame();
EXPECT_EQ(0, reporting_controller_.ActiveReporters());
// 4 simultaneous reporters
SimulateActivate();
SimulateCommit();
SimulateBeginMainFrame();
SimulateBeginImplFrame();
EXPECT_EQ(4, reporting_controller_.ActiveReporters());
// Any additional BeginImplFrame's would be ignored
SimulateBeginImplFrame();
EXPECT_EQ(4, reporting_controller_.ActiveReporters());
}
} // namespace
} // namespace cc