| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/containers/flat_set.h" | 5 #include "base/containers/flat_set.h" |
| 6 #include "cc/surfaces/compositor_frame_sink_support.h" | 6 #include "cc/surfaces/compositor_frame_sink_support.h" |
| 7 #include "cc/surfaces/surface_id.h" | 7 #include "cc/surfaces/surface_id.h" |
| 8 #include "cc/surfaces/surface_manager.h" | 8 #include "cc/surfaces/surface_manager.h" |
| 9 #include "cc/surfaces/surface_observer.h" | |
| 10 #include "cc/test/begin_frame_args_test.h" | 9 #include "cc/test/begin_frame_args_test.h" |
| 11 #include "cc/test/compositor_frame_helpers.h" | 10 #include "cc/test/compositor_frame_helpers.h" |
| 12 #include "cc/test/fake_external_begin_frame_source.h" | 11 #include "cc/test/fake_external_begin_frame_source.h" |
| 12 #include "cc/test/fake_surface_observer.h" |
| 13 #include "cc/test/mock_compositor_frame_sink_support_client.h" | 13 #include "cc/test/mock_compositor_frame_sink_support_client.h" |
| 14 #include "testing/gmock/include/gmock/gmock.h" | 14 #include "testing/gmock/include/gmock/gmock.h" |
| 15 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
| 16 | 16 |
| 17 using testing::_; | 17 using testing::_; |
| 18 using testing::Eq; | 18 using testing::Eq; |
| 19 using testing::IsEmpty; | 19 using testing::IsEmpty; |
| 20 using testing::UnorderedElementsAre; | 20 using testing::UnorderedElementsAre; |
| 21 | 21 |
| 22 namespace cc { | 22 namespace cc { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 38 } | 38 } |
| 39 | 39 |
| 40 SurfaceId MakeSurfaceId(const FrameSinkId& frame_sink_id, uint32_t local_id) { | 40 SurfaceId MakeSurfaceId(const FrameSinkId& frame_sink_id, uint32_t local_id) { |
| 41 return SurfaceId( | 41 return SurfaceId( |
| 42 frame_sink_id, | 42 frame_sink_id, |
| 43 LocalSurfaceId(local_id, base::UnguessableToken::Deserialize(0, 1u))); | 43 LocalSurfaceId(local_id, base::UnguessableToken::Deserialize(0, 1u))); |
| 44 } | 44 } |
| 45 | 45 |
| 46 } // namespace | 46 } // namespace |
| 47 | 47 |
| 48 class SurfaceSynchronizationTest : public testing::Test, | 48 class SurfaceSynchronizationTest : public testing::Test { |
| 49 public SurfaceObserver { | |
| 50 public: | 49 public: |
| 51 SurfaceSynchronizationTest() | 50 SurfaceSynchronizationTest() |
| 52 : surface_manager_(SurfaceManager::LifetimeType::REFERENCES) {} | 51 : surface_manager_(SurfaceManager::LifetimeType::REFERENCES), |
| 52 surface_observer_(false) {} |
| 53 ~SurfaceSynchronizationTest() override {} | 53 ~SurfaceSynchronizationTest() override {} |
| 54 | 54 |
| 55 CompositorFrameSinkSupport& display_support() { return *supports_[0]; } | 55 CompositorFrameSinkSupport& display_support() { return *supports_[0]; } |
| 56 Surface* display_surface() { | 56 Surface* display_surface() { |
| 57 return display_support().current_surface_for_testing(); | 57 return display_support().current_surface_for_testing(); |
| 58 } | 58 } |
| 59 | 59 |
| 60 CompositorFrameSinkSupport& parent_support() { return *supports_[1]; } | 60 CompositorFrameSinkSupport& parent_support() { return *supports_[1]; } |
| 61 Surface* parent_surface() { | 61 Surface* parent_surface() { |
| 62 return parent_support().current_surface_for_testing(); | 62 return parent_support().current_surface_for_testing(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 } | 94 } |
| 95 | 95 |
| 96 SurfaceDependencyTracker& dependency_tracker() { | 96 SurfaceDependencyTracker& dependency_tracker() { |
| 97 return *surface_manager_.dependency_tracker(); | 97 return *surface_manager_.dependency_tracker(); |
| 98 } | 98 } |
| 99 | 99 |
| 100 FakeExternalBeginFrameSource* begin_frame_source() { | 100 FakeExternalBeginFrameSource* begin_frame_source() { |
| 101 return begin_frame_source_.get(); | 101 return begin_frame_source_.get(); |
| 102 } | 102 } |
| 103 | 103 |
| 104 FakeSurfaceObserver& surface_observer() { return surface_observer_; } |
| 105 |
| 104 // testing::Test: | 106 // testing::Test: |
| 105 void SetUp() override { | 107 void SetUp() override { |
| 106 testing::Test::SetUp(); | 108 testing::Test::SetUp(); |
| 107 | 109 |
| 108 begin_frame_source_ = | 110 begin_frame_source_ = |
| 109 base::MakeUnique<FakeExternalBeginFrameSource>(0.f, false); | 111 base::MakeUnique<FakeExternalBeginFrameSource>(0.f, false); |
| 110 dependency_tracker_ = base::MakeUnique<SurfaceDependencyTracker>( | 112 dependency_tracker_ = base::MakeUnique<SurfaceDependencyTracker>( |
| 111 &surface_manager_, begin_frame_source_.get()); | 113 &surface_manager_, begin_frame_source_.get()); |
| 112 surface_manager_.SetDependencyTracker(dependency_tracker_.get()); | 114 surface_manager_.SetDependencyTracker(dependency_tracker_.get()); |
| 113 surface_manager_.AddObserver(this); | 115 surface_manager_.AddObserver(&surface_observer_); |
| 114 supports_.push_back(CompositorFrameSinkSupport::Create( | 116 supports_.push_back(CompositorFrameSinkSupport::Create( |
| 115 &support_client_, &surface_manager_, kDisplayFrameSink, kIsRoot, | 117 &support_client_, &surface_manager_, kDisplayFrameSink, kIsRoot, |
| 116 kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints)); | 118 kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints)); |
| 117 supports_.push_back(CompositorFrameSinkSupport::Create( | 119 supports_.push_back(CompositorFrameSinkSupport::Create( |
| 118 &support_client_, &surface_manager_, kParentFrameSink, kIsChildRoot, | 120 &support_client_, &surface_manager_, kParentFrameSink, kIsChildRoot, |
| 119 kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints)); | 121 kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints)); |
| 120 supports_.push_back(CompositorFrameSinkSupport::Create( | 122 supports_.push_back(CompositorFrameSinkSupport::Create( |
| 121 &support_client_, &surface_manager_, kChildFrameSink1, kIsChildRoot, | 123 &support_client_, &surface_manager_, kChildFrameSink1, kIsChildRoot, |
| 122 kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints)); | 124 kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints)); |
| 123 supports_.push_back(CompositorFrameSinkSupport::Create( | 125 supports_.push_back(CompositorFrameSinkSupport::Create( |
| 124 &support_client_, &surface_manager_, kChildFrameSink2, kIsChildRoot, | 126 &support_client_, &surface_manager_, kChildFrameSink2, kIsChildRoot, |
| 125 kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints)); | 127 kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints)); |
| 126 | 128 |
| 127 // Normally, the BeginFrameSource would be registered by the Display. We | 129 // Normally, the BeginFrameSource would be registered by the Display. We |
| 128 // register it here so that BeginFrames are received by the display support, | 130 // register it here so that BeginFrames are received by the display support, |
| 129 // for use in the PassesOnBeginFrameAcks test. Other supports do not receive | 131 // for use in the PassesOnBeginFrameAcks test. Other supports do not receive |
| 130 // BeginFrames, since the frame sink hierarchy is not set up in this test. | 132 // BeginFrames, since the frame sink hierarchy is not set up in this test. |
| 131 surface_manager_.RegisterBeginFrameSource(begin_frame_source_.get(), | 133 surface_manager_.RegisterBeginFrameSource(begin_frame_source_.get(), |
| 132 kDisplayFrameSink); | 134 kDisplayFrameSink); |
| 133 } | 135 } |
| 134 | 136 |
| 135 void TearDown() override { | 137 void TearDown() override { |
| 136 surface_manager_.RemoveObserver(this); | 138 surface_manager_.RemoveObserver(&surface_observer_); |
| 137 surface_manager_.SetDependencyTracker(nullptr); | 139 surface_manager_.SetDependencyTracker(nullptr); |
| 138 surface_manager_.UnregisterBeginFrameSource(begin_frame_source_.get()); | 140 surface_manager_.UnregisterBeginFrameSource(begin_frame_source_.get()); |
| 139 | 141 |
| 140 dependency_tracker_.reset(); | 142 dependency_tracker_.reset(); |
| 141 | 143 |
| 142 // SurfaceDependencyTracker depends on this BeginFrameSource and so it must | 144 // SurfaceDependencyTracker depends on this BeginFrameSource and so it must |
| 143 // be destroyed AFTER the dependency tracker is destroyed. | 145 // be destroyed AFTER the dependency tracker is destroyed. |
| 144 begin_frame_source_.reset(); | 146 begin_frame_source_.reset(); |
| 145 | 147 |
| 146 supports_.clear(); | 148 supports_.clear(); |
| 147 | 149 |
| 148 damaged_surfaces_.clear(); | 150 surface_observer_.Reset(); |
| 149 } | 151 } |
| 150 | 152 |
| 151 bool IsSurfaceDamaged(const SurfaceId& surface_id) const { | |
| 152 return damaged_surfaces_.count(surface_id) > 0; | |
| 153 } | |
| 154 | |
| 155 // SurfaceObserver implementation: | |
| 156 void OnSurfaceCreated(const SurfaceInfo& surface_info) override {} | |
| 157 void OnSurfaceDamaged(const SurfaceId& surface_id, bool* changed) override { | |
| 158 damaged_surfaces_.insert(surface_id); | |
| 159 } | |
| 160 void OnSurfaceDiscarded(const SurfaceId& surface_id) override {} | |
| 161 | |
| 162 protected: | 153 protected: |
| 163 testing::NiceMock<MockCompositorFrameSinkSupportClient> support_client_; | 154 testing::NiceMock<MockCompositorFrameSinkSupportClient> support_client_; |
| 164 | 155 |
| 165 private: | 156 private: |
| 166 base::flat_set<SurfaceId> damaged_surfaces_; | |
| 167 SurfaceManager surface_manager_; | 157 SurfaceManager surface_manager_; |
| 158 FakeSurfaceObserver surface_observer_; |
| 168 std::unique_ptr<FakeExternalBeginFrameSource> begin_frame_source_; | 159 std::unique_ptr<FakeExternalBeginFrameSource> begin_frame_source_; |
| 169 std::unique_ptr<SurfaceDependencyTracker> dependency_tracker_; | 160 std::unique_ptr<SurfaceDependencyTracker> dependency_tracker_; |
| 170 std::vector<std::unique_ptr<CompositorFrameSinkSupport>> supports_; | 161 std::vector<std::unique_ptr<CompositorFrameSinkSupport>> supports_; |
| 171 | 162 |
| 172 DISALLOW_COPY_AND_ASSIGN(SurfaceSynchronizationTest); | 163 DISALLOW_COPY_AND_ASSIGN(SurfaceSynchronizationTest); |
| 173 }; | 164 }; |
| 174 | 165 |
| 175 // The display root surface should have a surface reference from the top-level | 166 // The display root surface should have a surface reference from the top-level |
| 176 // root added/removed when a CompositorFrame is submitted with a new SurfaceId. | 167 // root added/removed when a CompositorFrame is submitted with a new SurfaceId. |
| 177 TEST_F(SurfaceSynchronizationTest, RootSurfaceReceivesReferences) { | 168 TEST_F(SurfaceSynchronizationTest, RootSurfaceReceivesReferences) { |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 MakeCompositorFrame({child_id1}, empty_surface_ids(), | 244 MakeCompositorFrame({child_id1}, empty_surface_ids(), |
| 254 TransferableResourceArray())); | 245 TransferableResourceArray())); |
| 255 | 246 |
| 256 // parent_support is blocked on |child_id1|. | 247 // parent_support is blocked on |child_id1|. |
| 257 EXPECT_TRUE(dependency_tracker().has_deadline()); | 248 EXPECT_TRUE(dependency_tracker().has_deadline()); |
| 258 EXPECT_FALSE(parent_surface()->HasActiveFrame()); | 249 EXPECT_FALSE(parent_surface()->HasActiveFrame()); |
| 259 EXPECT_TRUE(parent_surface()->HasPendingFrame()); | 250 EXPECT_TRUE(parent_surface()->HasPendingFrame()); |
| 260 EXPECT_THAT(parent_surface()->blocking_surfaces(), | 251 EXPECT_THAT(parent_surface()->blocking_surfaces(), |
| 261 UnorderedElementsAre(child_id1)); | 252 UnorderedElementsAre(child_id1)); |
| 262 // The parent should not report damage until it activates. | 253 // The parent should not report damage until it activates. |
| 263 EXPECT_FALSE(IsSurfaceDamaged(parent_id)); | 254 EXPECT_FALSE(surface_observer().IsSurfaceDamaged(parent_id)); |
| 264 | 255 |
| 265 child_support1().SubmitCompositorFrame( | 256 child_support1().SubmitCompositorFrame( |
| 266 child_id1.local_surface_id(), | 257 child_id1.local_surface_id(), |
| 267 MakeCompositorFrame({child_id2}, empty_surface_ids(), | 258 MakeCompositorFrame({child_id2}, empty_surface_ids(), |
| 268 TransferableResourceArray())); | 259 TransferableResourceArray())); |
| 269 | 260 |
| 270 // child_support1 should now be blocked on |child_id2|. | 261 // child_support1 should now be blocked on |child_id2|. |
| 271 EXPECT_TRUE(dependency_tracker().has_deadline()); | 262 EXPECT_TRUE(dependency_tracker().has_deadline()); |
| 272 EXPECT_FALSE(child_surface1()->HasActiveFrame()); | 263 EXPECT_FALSE(child_surface1()->HasActiveFrame()); |
| 273 EXPECT_TRUE(child_surface1()->HasPendingFrame()); | 264 EXPECT_TRUE(child_surface1()->HasPendingFrame()); |
| 274 EXPECT_THAT(child_surface1()->blocking_surfaces(), | 265 EXPECT_THAT(child_surface1()->blocking_surfaces(), |
| 275 UnorderedElementsAre(child_id2)); | 266 UnorderedElementsAre(child_id2)); |
| 276 // The parent and child should not report damage until they activate. | 267 // The parent and child should not report damage until they activate. |
| 277 EXPECT_FALSE(IsSurfaceDamaged(parent_id)); | 268 EXPECT_FALSE(surface_observer().IsSurfaceDamaged(parent_id)); |
| 278 EXPECT_FALSE(IsSurfaceDamaged(child_id1)); | 269 EXPECT_FALSE(surface_observer().IsSurfaceDamaged(child_id1)); |
| 279 | 270 |
| 280 // The parent should still be blocked on |child_id1| because it's pending. | 271 // The parent should still be blocked on |child_id1| because it's pending. |
| 281 EXPECT_THAT(parent_surface()->blocking_surfaces(), | 272 EXPECT_THAT(parent_surface()->blocking_surfaces(), |
| 282 UnorderedElementsAre(child_id1)); | 273 UnorderedElementsAre(child_id1)); |
| 283 | 274 |
| 284 // Submit a CompositorFrame without any dependencies to |child_id2|. | 275 // Submit a CompositorFrame without any dependencies to |child_id2|. |
| 285 // parent_support should be activated. | 276 // parent_support should be activated. |
| 286 child_support2().SubmitCompositorFrame( | 277 child_support2().SubmitCompositorFrame( |
| 287 child_id2.local_surface_id(), | 278 child_id2.local_surface_id(), |
| 288 MakeCompositorFrame(empty_surface_ids(), empty_surface_ids(), | 279 MakeCompositorFrame(empty_surface_ids(), empty_surface_ids(), |
| 289 TransferableResourceArray())); | 280 TransferableResourceArray())); |
| 290 | 281 |
| 291 EXPECT_FALSE(dependency_tracker().has_deadline()); | 282 EXPECT_FALSE(dependency_tracker().has_deadline()); |
| 292 | 283 |
| 293 // child_surface1 should now be active. | 284 // child_surface1 should now be active. |
| 294 EXPECT_TRUE(child_surface1()->HasActiveFrame()); | 285 EXPECT_TRUE(child_surface1()->HasActiveFrame()); |
| 295 EXPECT_FALSE(child_surface1()->HasPendingFrame()); | 286 EXPECT_FALSE(child_surface1()->HasPendingFrame()); |
| 296 EXPECT_THAT(child_surface1()->blocking_surfaces(), IsEmpty()); | 287 EXPECT_THAT(child_surface1()->blocking_surfaces(), IsEmpty()); |
| 297 | 288 |
| 298 // parent_surface should now be active. | 289 // parent_surface should now be active. |
| 299 EXPECT_TRUE(parent_surface()->HasActiveFrame()); | 290 EXPECT_TRUE(parent_surface()->HasActiveFrame()); |
| 300 EXPECT_FALSE(parent_surface()->HasPendingFrame()); | 291 EXPECT_FALSE(parent_surface()->HasPendingFrame()); |
| 301 EXPECT_THAT(parent_surface()->blocking_surfaces(), IsEmpty()); | 292 EXPECT_THAT(parent_surface()->blocking_surfaces(), IsEmpty()); |
| 302 | 293 |
| 303 // All three surfaces |parent_id|, |child_id1|, and |child_id2| should | 294 // All three surfaces |parent_id|, |child_id1|, and |child_id2| should |
| 304 // now report damage. This would trigger a new display frame. | 295 // now report damage. This would trigger a new display frame. |
| 305 EXPECT_TRUE(IsSurfaceDamaged(parent_id)); | 296 EXPECT_TRUE(surface_observer().IsSurfaceDamaged(parent_id)); |
| 306 EXPECT_TRUE(IsSurfaceDamaged(child_id1)); | 297 EXPECT_TRUE(surface_observer().IsSurfaceDamaged(child_id1)); |
| 307 EXPECT_TRUE(IsSurfaceDamaged(child_id2)); | 298 EXPECT_TRUE(surface_observer().IsSurfaceDamaged(child_id2)); |
| 308 } | 299 } |
| 309 | 300 |
| 310 // parent_surface and child_surface1 are blocked on |child_id2|. | 301 // parent_surface and child_surface1 are blocked on |child_id2|. |
| 311 TEST_F(SurfaceSynchronizationTest, TwoBlockedOnOne) { | 302 TEST_F(SurfaceSynchronizationTest, TwoBlockedOnOne) { |
| 312 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1); | 303 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1); |
| 313 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1); | 304 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1); |
| 314 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink2, 1); | 305 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink2, 1); |
| 315 | 306 |
| 316 parent_support().SubmitCompositorFrame( | 307 parent_support().SubmitCompositorFrame( |
| 317 parent_id.local_surface_id(), | 308 parent_id.local_surface_id(), |
| (...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 972 ui::LatencyInfo::LatencyComponent comp1; | 963 ui::LatencyInfo::LatencyComponent comp1; |
| 973 EXPECT_TRUE( | 964 EXPECT_TRUE( |
| 974 aggregated_latency_info.FindLatency(latency_type1, latency_id1, &comp1)); | 965 aggregated_latency_info.FindLatency(latency_type1, latency_id1, &comp1)); |
| 975 EXPECT_EQ(latency_sequence_number1, comp1.sequence_number); | 966 EXPECT_EQ(latency_sequence_number1, comp1.sequence_number); |
| 976 EXPECT_TRUE( | 967 EXPECT_TRUE( |
| 977 aggregated_latency_info.FindLatency(latency_type2, latency_id2, nullptr)); | 968 aggregated_latency_info.FindLatency(latency_type2, latency_id2, nullptr)); |
| 978 EXPECT_TRUE(aggregated_latency_info.FindLatency( | 969 EXPECT_TRUE(aggregated_latency_info.FindLatency( |
| 979 ui::DISPLAY_COMPOSITOR_RECEIVED_FRAME_COMPONENT, nullptr)); | 970 ui::DISPLAY_COMPOSITOR_RECEIVED_FRAME_COMPONENT, nullptr)); |
| 980 } | 971 } |
| 981 | 972 |
| 982 // TODO(eseckler): Add back tests for BeginFrameAck forwarding through | |
| 983 // CompositorFrameSinkSupport when we add plumbing of BeginFrameAcks through | |
| 984 // SurfaceObservers. | |
| 985 | |
| 986 // Checks that resources and ack are sent together if possible. | 973 // Checks that resources and ack are sent together if possible. |
| 987 TEST_F(SurfaceSynchronizationTest, ReturnResourcesWithAck) { | 974 TEST_F(SurfaceSynchronizationTest, ReturnResourcesWithAck) { |
| 988 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1); | 975 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1); |
| 989 TransferableResource resource; | 976 TransferableResource resource; |
| 990 resource.id = 1234; | 977 resource.id = 1234; |
| 991 parent_support().SubmitCompositorFrame( | 978 parent_support().SubmitCompositorFrame( |
| 992 parent_id.local_surface_id(), | 979 parent_id.local_surface_id(), |
| 993 MakeCompositorFrame(empty_surface_ids(), empty_surface_ids(), | 980 MakeCompositorFrame(empty_surface_ids(), empty_surface_ids(), |
| 994 {resource})); | 981 {resource})); |
| 995 ReturnedResourceArray returned_resources; | 982 ReturnedResourceArray returned_resources; |
| (...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1358 DidReceiveCompositorFrameAck(Eq(returned_resources2))); | 1345 DidReceiveCompositorFrameAck(Eq(returned_resources2))); |
| 1359 child_support1().SubmitCompositorFrame( | 1346 child_support1().SubmitCompositorFrame( |
| 1360 child_id1.local_surface_id(), | 1347 child_id1.local_surface_id(), |
| 1361 MakeCompositorFrame(empty_surface_ids(), empty_surface_ids(), | 1348 MakeCompositorFrame(empty_surface_ids(), empty_surface_ids(), |
| 1362 {resource2})); | 1349 {resource2})); |
| 1363 testing::Mock::VerifyAndClearExpectations(&support_client_); | 1350 testing::Mock::VerifyAndClearExpectations(&support_client_); |
| 1364 } | 1351 } |
| 1365 | 1352 |
| 1366 } // namespace test | 1353 } // namespace test |
| 1367 } // namespace cc | 1354 } // namespace cc |
| OLD | NEW |