1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
cc / trees / layer_tree_host_unittest_capture.cc [blame]
// Copyright 2020 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/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(base::Token(0u, 22u));
// 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