OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "base/message_loop/message_loop_proxy.h" |
| 6 #include "cc/layers/solid_color_layer.h" |
| 7 #include "cc/layers/surface_layer.h" |
| 8 #include "cc/test/fake_impl_proxy.h" |
| 9 #include "cc/test/fake_layer_tree_host.h" |
| 10 #include "cc/test/fake_layer_tree_host_client.h" |
| 11 #include "cc/test/fake_layer_tree_host_impl.h" |
| 12 #include "cc/test/fake_output_surface.h" |
| 13 #include "cc/test/layer_tree_test.h" |
| 14 #include "cc/test/test_shared_bitmap_manager.h" |
| 15 #include "cc/trees/layer_tree_host.h" |
| 16 #include "testing/gmock/include/gmock/gmock.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" |
| 18 |
| 19 namespace cc { |
| 20 namespace { |
| 21 |
| 22 class SurfaceLayerTest : public testing::Test { |
| 23 public: |
| 24 SurfaceLayerTest() |
| 25 : fake_client_( |
| 26 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)) {} |
| 27 |
| 28 protected: |
| 29 virtual void SetUp() { |
| 30 layer_tree_host_ = FakeLayerTreeHost::Create(&fake_client_); |
| 31 layer_tree_host_->SetViewportSize(gfx::Size(10, 10)); |
| 32 } |
| 33 |
| 34 virtual void TearDown() { |
| 35 if (layer_tree_host_) { |
| 36 layer_tree_host_->SetRootLayer(nullptr); |
| 37 layer_tree_host_ = nullptr; |
| 38 } |
| 39 } |
| 40 |
| 41 scoped_ptr<FakeLayerTreeHost> layer_tree_host_; |
| 42 FakeLayerTreeHostClient fake_client_; |
| 43 TestSharedBitmapManager shared_bitmap_manager_; |
| 44 }; |
| 45 |
| 46 void SatisfyCallback(SurfaceSequence* out, SurfaceSequence in) { |
| 47 *out = in; |
| 48 } |
| 49 |
| 50 void RequireCallback(SurfaceId* out_id, |
| 51 std::set<SurfaceSequence>* out, |
| 52 SurfaceId in_id, |
| 53 SurfaceSequence in) { |
| 54 *out_id = in_id; |
| 55 out->insert(in); |
| 56 } |
| 57 |
| 58 // Check that one surface can be referenced by multiple LayerTreeHosts, and |
| 59 // each will create its own SurfaceSequence that's satisfied on destruction. |
| 60 TEST_F(SurfaceLayerTest, MultipleFramesOneSurface) { |
| 61 SurfaceSequence blank_change; // Receives sequence if commit doesn't happen. |
| 62 |
| 63 SurfaceId required_id; |
| 64 std::set<SurfaceSequence> required_seq; |
| 65 scoped_refptr<SurfaceLayer> layer(SurfaceLayer::Create( |
| 66 base::Bind(&SatisfyCallback, &blank_change), |
| 67 base::Bind(&RequireCallback, &required_id, &required_seq))); |
| 68 layer->SetSurfaceId(SurfaceId(1)); |
| 69 layer_tree_host_->set_surface_id_namespace(1); |
| 70 layer_tree_host_->SetRootLayer(layer); |
| 71 |
| 72 scoped_ptr<FakeLayerTreeHost> layer_tree_host2 = |
| 73 FakeLayerTreeHost::Create(&fake_client_); |
| 74 scoped_refptr<SurfaceLayer> layer2(SurfaceLayer::Create( |
| 75 base::Bind(&SatisfyCallback, &blank_change), |
| 76 base::Bind(&RequireCallback, &required_id, &required_seq))); |
| 77 layer2->SetSurfaceId(SurfaceId(1)); |
| 78 layer_tree_host2->set_surface_id_namespace(2); |
| 79 layer_tree_host2->SetRootLayer(layer2); |
| 80 |
| 81 // Layers haven't been removed, so no sequence should be satisfied. |
| 82 EXPECT_TRUE(blank_change.is_null()); |
| 83 |
| 84 SurfaceSequence expected1(1u, 1u); |
| 85 SurfaceSequence expected2(2u, 1u); |
| 86 |
| 87 layer_tree_host2->SetRootLayer(nullptr); |
| 88 layer_tree_host2.reset(); |
| 89 |
| 90 // Layer was removed so sequence from second LayerTreeHost should be |
| 91 // satisfied. |
| 92 EXPECT_TRUE(blank_change == expected2); |
| 93 |
| 94 // Set of sequences that need to be satisfied should include sequences from |
| 95 // both trees. |
| 96 EXPECT_TRUE(required_id == SurfaceId(1)); |
| 97 EXPECT_EQ(2u, required_seq.size()); |
| 98 EXPECT_TRUE(required_seq.count(expected1)); |
| 99 EXPECT_TRUE(required_seq.count(expected2)); |
| 100 |
| 101 layer_tree_host_->SetRootLayer(nullptr); |
| 102 layer_tree_host_.reset(); |
| 103 |
| 104 // Layer was removed so sequence from first LayerTreeHost should be |
| 105 // satisfied. |
| 106 EXPECT_TRUE(blank_change == expected1); |
| 107 |
| 108 // No more SurfaceSequences should have been generated that need to have be |
| 109 // satisfied. |
| 110 EXPECT_EQ(2u, required_seq.size()); |
| 111 } |
| 112 |
| 113 // Check that SurfaceSequence is sent through swap promise. |
| 114 class SurfaceLayerSwapPromise : public LayerTreeTest { |
| 115 public: |
| 116 SurfaceLayerSwapPromise() |
| 117 : commit_count_(0), sequence_was_satisfied_(false) {} |
| 118 |
| 119 void BeginTest() override { |
| 120 layer_tree_host()->set_surface_id_namespace(1); |
| 121 layer_ = SurfaceLayer::Create( |
| 122 base::Bind(&SatisfyCallback, &satisfied_sequence_), |
| 123 base::Bind(&RequireCallback, &required_id_, &required_set_)); |
| 124 layer_->SetSurfaceId(SurfaceId(1)); |
| 125 |
| 126 // Layer hasn't been added to tree so no SurfaceSequence generated yet. |
| 127 EXPECT_EQ(0u, required_set_.size()); |
| 128 |
| 129 layer_tree_host()->SetRootLayer(layer_); |
| 130 |
| 131 // Should have SurfaceSequence from first tree. |
| 132 SurfaceSequence expected(1u, 1u); |
| 133 EXPECT_TRUE(required_id_ == SurfaceId(1)); |
| 134 EXPECT_EQ(1u, required_set_.size()); |
| 135 EXPECT_TRUE(required_set_.count(expected)); |
| 136 |
| 137 gfx::Size bounds(100, 100); |
| 138 layer_tree_host()->SetViewportSize(bounds); |
| 139 PostSetNeedsCommitToMainThread(); |
| 140 } |
| 141 |
| 142 void DidCommit() override { |
| 143 base::MessageLoopProxy::current()->PostTask( |
| 144 FROM_HERE, base::Bind(&SurfaceLayerSwapPromise::ChangeTree, |
| 145 base::Unretained(this))); |
| 146 } |
| 147 |
| 148 void ChangeTree() { |
| 149 ++commit_count_; |
| 150 switch (commit_count_) { |
| 151 case 1: |
| 152 // Remove SurfaceLayer from tree to cause SwapPromise to be created. |
| 153 blank_layer_ = SolidColorLayer::Create(); |
| 154 blank_layer_->SetIsDrawable(true); |
| 155 blank_layer_->SetBounds(gfx::Size(10, 10)); |
| 156 layer_tree_host()->SetRootLayer(blank_layer_); |
| 157 break; |
| 158 case 2: |
| 159 break; |
| 160 default: |
| 161 NOTREACHED(); |
| 162 break; |
| 163 } |
| 164 } |
| 165 |
| 166 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { |
| 167 EXPECT_TRUE(result); |
| 168 std::vector<uint32_t>& satisfied = |
| 169 output_surface()->last_sent_frame().metadata.satisfies_sequences; |
| 170 EXPECT_LE(satisfied.size(), 1u); |
| 171 if (satisfied.size() == 1) { |
| 172 // Eventually the one SurfaceSequence should be satisfied, but only |
| 173 // after the layer was removed from the tree, and only once. |
| 174 EXPECT_EQ(1u, satisfied[0]); |
| 175 EXPECT_LE(1, commit_count_); |
| 176 EXPECT_FALSE(sequence_was_satisfied_); |
| 177 sequence_was_satisfied_ = true; |
| 178 EndTest(); |
| 179 } |
| 180 } |
| 181 |
| 182 void AfterTest() override { |
| 183 EXPECT_TRUE(required_id_ == SurfaceId(1)); |
| 184 EXPECT_EQ(1u, required_set_.size()); |
| 185 // Sequence should have been satisfied through Swap, not with the |
| 186 // callback. |
| 187 EXPECT_TRUE(satisfied_sequence_.is_null()); |
| 188 } |
| 189 |
| 190 private: |
| 191 int commit_count_; |
| 192 bool sequence_was_satisfied_; |
| 193 scoped_refptr<SurfaceLayer> layer_; |
| 194 scoped_refptr<Layer> blank_layer_; |
| 195 SurfaceSequence satisfied_sequence_; |
| 196 |
| 197 SurfaceId required_id_; |
| 198 std::set<SurfaceSequence> required_set_; |
| 199 }; |
| 200 |
| 201 // TODO(jbauman): Reenable on single thread once http://crbug.com/421923 is |
| 202 // fixed. |
| 203 MULTI_THREAD_TEST_F(SurfaceLayerSwapPromise); |
| 204 |
| 205 } // namespace |
| 206 } // namespace cc |
OLD | NEW |