blob: 0336419a2bb9e9fa2c3cbfa2201e6df9cf5a38dd [file] [log] [blame]
// Copyright 2020 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/test/fake_content_layer_client.h"
#include "cc/test/fake_picture_layer.h"
#include "cc/test/layer_tree_test.h"
#include "cc/test/property_tree_test_utils.h"
#include "cc/trees/layer_tree_impl.h"
#include "components/viz/common/quads/compositor_frame.h"
#include "components/viz/common/surfaces/subtree_capture_id.h"
namespace cc {
namespace {
constexpr viz::SubtreeCaptureId kCaptureId{22};
// A base class for tests that verifies the bahvior of the layer tree when a
// sub layer has a valid viz::SubtreeCaptureId.
class LayerTreeHostCaptureTest : public LayerTreeTest {
public:
void SetupTree() override {
scoped_refptr<Layer> root = FakePictureLayer::Create(&client_);
root->SetBounds(gfx::Size(100, 100));
child_ = FakePictureLayer::Create(&client_);
child_->SetBounds(gfx::Size(50, 60));
child_->SetPosition(gfx::PointF(10.f, 5.5f));
root->AddChild(child_);
grand_child_ = FakePictureLayer::Create(&client_);
grand_child_->SetBounds(gfx::Size(70, 30));
grand_child_->SetPosition(gfx::PointF(50.f, 50.f));
child_->AddChild(grand_child_);
layer_tree_host()->SetRootLayer(root);
LayerTreeTest::SetupTree();
client_.set_bounds(root->bounds());
}
void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
LayerImpl* root = impl->active_tree()->root_layer();
LayerImpl* child = impl->active_tree()->LayerById(child_->id());
LayerImpl* grand_child = impl->active_tree()->LayerById(grand_child_->id());
VerifyLayerImpls(root, child, grand_child);
}
protected:
// Lets test subclasses to verify the LayerImpls of the layers in the tree.
virtual void VerifyLayerImpls(LayerImpl* root,
LayerImpl* child,
LayerImpl* grand_child) = 0;
FakeContentLayerClient client_;
scoped_refptr<Layer> child_;
scoped_refptr<Layer> grand_child_;
};
// -----------------------------------------------------------------------------
// LayerTreeHostCaptureTestNoExtraRenderPassWhenNotCapturing:
//
// Tests that a layer tree that doesn't have a viz::SubtreeCaptureId on any of
// its layers, draw in a single root render surface, and generates a single
// compositor render pass.
class LayerTreeHostCaptureTestNoExtraRenderPassWhenNotCapturing
: public LayerTreeHostCaptureTest {
public:
void BeginTest() override { PostSetNeedsCommitToMainThread(); }
void VerifyLayerImpls(LayerImpl* root,
LayerImpl* child,
LayerImpl* grand_child) override {
// All layers in the tree draw in the same root render surface.
auto* root_surface = GetRenderSurface(root);
auto* child_surface = GetRenderSurface(child);
auto* grand_child_surface = GetRenderSurface(grand_child);
EXPECT_EQ(root_surface, child_surface);
EXPECT_EQ(root_surface, grand_child_surface);
EXPECT_FALSE(root_surface->CopyOfOutputRequired());
EXPECT_FALSE(root_surface->SubtreeCaptureId().is_valid());
EndTest();
}
void DisplayReceivedCompositorFrameOnThread(
const viz::CompositorFrame& frame) override {
// There should be a single compositor render pass, which has no valid
// SubtreeCaptureId.
ASSERT_EQ(frame.render_pass_list.size(), 1u);
EXPECT_FALSE(frame.render_pass_list.back()->subtree_capture_id.is_valid());
}
};
SINGLE_AND_MULTI_THREAD_TEST_F(
LayerTreeHostCaptureTestNoExtraRenderPassWhenNotCapturing);
// -----------------------------------------------------------------------------
// LayerTreeHostCaptureTestLayerWithCaptureIdElevatesToSurface
//
// Tests that a layer sub tree whose root has a valid viz::SubtreeCaptureId will
// draw into a separate render surface and a separate render pass.
class LayerTreeHostCaptureTestLayerWithCaptureIdElevatesToSurface
: public LayerTreeHostCaptureTest {
public:
void BeginTest() override { child_->SetSubtreeCaptureId(kCaptureId); }
void VerifyLayerImpls(LayerImpl* root,
LayerImpl* child,
LayerImpl* grand_child) override {
// |child| should draw into a separate render surface from that of the root,
// and the |grand_child| should draw into the render surface of its parent
// (which is |child|'s).
// The |chils|'s surface should have the expected capture ID.
auto* root_surface = GetRenderSurface(root);
auto* child_surface = GetRenderSurface(child);
auto* grand_child_surface = GetRenderSurface(grand_child);
EXPECT_NE(root_surface, child_surface);
EXPECT_NE(root_surface, grand_child_surface);
EXPECT_EQ(child_surface, grand_child_surface);
EXPECT_EQ(kCaptureId, child_surface->SubtreeCaptureId());
EXPECT_TRUE(child_surface->CopyOfOutputRequired());
EndTest();
}
void DisplayReceivedCompositorFrameOnThread(
const viz::CompositorFrame& frame) override {
// There should be 2 render passes. The non-root render pass is associated
// with the layer subtree rooted at |child| and should have the expected
// capture ID.
ASSERT_EQ(frame.render_pass_list.size(), 2u);
EXPECT_TRUE(frame.render_pass_list.front()->subtree_capture_id.is_valid());
EXPECT_EQ(kCaptureId, frame.render_pass_list.front()->subtree_capture_id);
EXPECT_FALSE(frame.render_pass_list.back()->subtree_capture_id.is_valid());
}
};
SINGLE_AND_MULTI_THREAD_TEST_F(
LayerTreeHostCaptureTestLayerWithCaptureIdElevatesToSurface);
} // namespace
} // namespace cc