Chromium Code Reviews| 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 "cc/surfaces/compositor_frame_sink_support.h" | 5 #include "cc/surfaces/compositor_frame_sink_support.h" |
| 6 | 6 |
| 7 #include "base/debug/stack_trace.h" | |
| 7 #include "base/macros.h" | 8 #include "base/macros.h" |
| 8 #include "cc/output/compositor_frame.h" | 9 #include "cc/output/compositor_frame.h" |
| 9 #include "cc/surfaces/compositor_frame_sink_support_client.h" | 10 #include "cc/surfaces/compositor_frame_sink_support_client.h" |
| 10 #include "cc/surfaces/frame_sink_id.h" | 11 #include "cc/surfaces/frame_sink_id.h" |
| 11 #include "cc/surfaces/surface_id.h" | 12 #include "cc/surfaces/surface_id.h" |
| 12 #include "cc/surfaces/surface_manager.h" | 13 #include "cc/surfaces/surface_manager.h" |
| 13 #include "cc/test/begin_frame_args_test.h" | 14 #include "cc/test/begin_frame_args_test.h" |
| 14 #include "cc/test/fake_external_begin_frame_source.h" | 15 #include "cc/test/fake_external_begin_frame_source.h" |
| 15 #include "testing/gmock/include/gmock/gmock.h" | 16 #include "testing/gmock/include/gmock/gmock.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
| 17 | 18 |
| 18 using testing::UnorderedElementsAre; | 19 using testing::UnorderedElementsAre; |
| 19 using testing::IsEmpty; | 20 using testing::IsEmpty; |
| 20 using testing::SizeIs; | 21 using testing::SizeIs; |
| 22 using testing::Invoke; | |
| 23 using testing::_; | |
| 24 using testing::InSequence; | |
| 21 | 25 |
| 22 namespace cc { | 26 namespace cc { |
| 23 namespace test { | 27 namespace test { |
| 24 namespace { | 28 namespace { |
| 25 | 29 |
| 26 constexpr FrameSinkId kDisplayFrameSink(2, 0); | 30 constexpr FrameSinkId kDisplayFrameSink(2, 0); |
| 27 constexpr FrameSinkId kParentFrameSink(3, 0); | 31 constexpr FrameSinkId kParentFrameSink(3, 0); |
| 28 constexpr FrameSinkId kChildFrameSink1(65563, 0); | 32 constexpr FrameSinkId kChildFrameSink1(65563, 0); |
| 29 constexpr FrameSinkId kChildFrameSink2(65564, 0); | 33 constexpr FrameSinkId kChildFrameSink2(65564, 0); |
| 30 constexpr FrameSinkId kArbitraryFrameSink(1337, 7331); | 34 constexpr FrameSinkId kArbitraryFrameSink(1337, 7331); |
| 31 | 35 |
| 36 class MockCompositorFrameSinkSupportClient | |
| 37 : public CompositorFrameSinkSupportClient { | |
| 38 public: | |
| 39 MockCompositorFrameSinkSupportClient() { | |
| 40 ON_CALL(*this, ReclaimResources(_)) | |
| 41 .WillByDefault(Invoke( | |
| 42 this, | |
| 43 &MockCompositorFrameSinkSupportClient::ReclaimResourcesInternal)); | |
| 44 } | |
| 45 | |
| 46 ReturnedResourceArray& last_returned_resources() { | |
| 47 return last_returned_resources_; | |
| 48 } | |
| 49 | |
| 50 // CompositorFrameSinkSupportClient implementation. | |
| 51 MOCK_METHOD0(DidReceiveCompositorFrameAck, void()); | |
| 52 MOCK_METHOD1(OnBeginFrame, void(const BeginFrameArgs&)); | |
| 53 MOCK_METHOD1(ReclaimResources, void(const ReturnedResourceArray&)); | |
| 54 MOCK_METHOD2(WillDrawSurface, void(const LocalSurfaceId&, const gfx::Rect&)); | |
| 55 | |
| 56 private: | |
| 57 void ReclaimResourcesInternal(const ReturnedResourceArray& resources) { | |
| 58 last_returned_resources_ = resources; | |
| 59 } | |
| 60 | |
| 61 ReturnedResourceArray last_returned_resources_; | |
| 62 }; | |
| 63 | |
| 32 std::vector<SurfaceId> empty_surface_ids() { | 64 std::vector<SurfaceId> empty_surface_ids() { |
| 33 return std::vector<SurfaceId>(); | 65 return std::vector<SurfaceId>(); |
| 34 } | 66 } |
| 35 | 67 |
| 36 SurfaceId MakeSurfaceId(const FrameSinkId& frame_sink_id, uint32_t local_id) { | 68 SurfaceId MakeSurfaceId(const FrameSinkId& frame_sink_id, uint32_t local_id) { |
| 37 return SurfaceId( | 69 return SurfaceId( |
| 38 frame_sink_id, | 70 frame_sink_id, |
| 39 LocalSurfaceId(local_id, base::UnguessableToken::Deserialize(0, 1u))); | 71 LocalSurfaceId(local_id, base::UnguessableToken::Deserialize(0, 1u))); |
| 40 } | 72 } |
| 41 | 73 |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 64 TransferableResource resource; | 96 TransferableResource resource; |
| 65 resource.id = id; | 97 resource.id = id; |
| 66 resource.format = format; | 98 resource.format = format; |
| 67 resource.filter = filter; | 99 resource.filter = filter; |
| 68 resource.size = size; | 100 resource.size = size; |
| 69 return resource; | 101 return resource; |
| 70 } | 102 } |
| 71 | 103 |
| 72 } // namespace | 104 } // namespace |
| 73 | 105 |
| 74 class CompositorFrameSinkSupportTest : public testing::Test, | 106 class CompositorFrameSinkSupportTest : public testing::Test { |
| 75 public CompositorFrameSinkSupportClient { | |
| 76 public: | 107 public: |
| 77 CompositorFrameSinkSupportTest() | 108 CompositorFrameSinkSupportTest() |
| 78 : surface_manager_(SurfaceManager::LifetimeType::REFERENCES) {} | 109 : surface_manager_(SurfaceManager::LifetimeType::REFERENCES) {} |
| 79 ~CompositorFrameSinkSupportTest() override {} | 110 ~CompositorFrameSinkSupportTest() override {} |
| 80 | 111 |
| 81 CompositorFrameSinkSupport& display_support() { return *supports_[0]; } | 112 CompositorFrameSinkSupport& display_support() { return *supports_[0]; } |
| 82 | 113 |
| 83 CompositorFrameSinkSupport& parent_support() { return *supports_[1]; } | 114 CompositorFrameSinkSupport& parent_support() { return *supports_[1]; } |
| 84 Surface* parent_surface() { | 115 Surface* parent_surface() { |
| 85 return parent_support().current_surface_for_testing(); | 116 return parent_support().current_surface_for_testing(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 117 } | 148 } |
| 118 | 149 |
| 119 SurfaceDependencyTracker& dependency_tracker() { | 150 SurfaceDependencyTracker& dependency_tracker() { |
| 120 return *surface_manager_.dependency_tracker(); | 151 return *surface_manager_.dependency_tracker(); |
| 121 } | 152 } |
| 122 | 153 |
| 123 FakeExternalBeginFrameSource* begin_frame_source() { | 154 FakeExternalBeginFrameSource* begin_frame_source() { |
| 124 return begin_frame_source_.get(); | 155 return begin_frame_source_.get(); |
| 125 } | 156 } |
| 126 | 157 |
| 127 ReturnedResourceArray& last_returned_resources() { | |
| 128 return last_returned_resources_; | |
| 129 } | |
| 130 | |
| 131 // testing::Test: | 158 // testing::Test: |
| 132 void SetUp() override { | 159 void SetUp() override { |
| 133 testing::Test::SetUp(); | 160 testing::Test::SetUp(); |
| 134 begin_frame_source_ = | 161 begin_frame_source_ = |
| 135 base::MakeUnique<FakeExternalBeginFrameSource>(0.f, false); | 162 base::MakeUnique<FakeExternalBeginFrameSource>(0.f, false); |
| 136 std::unique_ptr<SurfaceDependencyTracker> dependency_tracker( | 163 std::unique_ptr<SurfaceDependencyTracker> dependency_tracker( |
| 137 new SurfaceDependencyTracker(&surface_manager_, | 164 new SurfaceDependencyTracker(&surface_manager_, |
| 138 begin_frame_source_.get())); | 165 begin_frame_source_.get())); |
| 139 surface_manager_.SetDependencyTracker(std::move(dependency_tracker)); | 166 surface_manager_.SetDependencyTracker(std::move(dependency_tracker)); |
| 140 supports_.push_back(base::MakeUnique<CompositorFrameSinkSupport>( | 167 supports_.push_back(base::MakeUnique<CompositorFrameSinkSupport>( |
| 141 this, &surface_manager_, kDisplayFrameSink, true /* is_root */, | 168 &support_client_, &surface_manager_, kDisplayFrameSink, |
| 142 true /* handles_frame_sink_id_invalidation */, | 169 true /* is_root */, true /* handles_frame_sink_id_invalidation */, |
| 143 true /* needs_sync_points */)); | 170 true /* needs_sync_points */)); |
| 144 supports_.push_back(base::MakeUnique<CompositorFrameSinkSupport>( | 171 supports_.push_back(base::MakeUnique<CompositorFrameSinkSupport>( |
| 145 this, &surface_manager_, kParentFrameSink, false /* is_root */, | 172 &support_client_, &surface_manager_, kParentFrameSink, |
| 146 true /* handles_frame_sink_id_invalidation */, | 173 false /* is_root */, true /* handles_frame_sink_id_invalidation */, |
| 147 true /* needs_sync_points */)); | 174 true /* needs_sync_points */)); |
| 148 supports_.push_back(base::MakeUnique<CompositorFrameSinkSupport>( | 175 supports_.push_back(base::MakeUnique<CompositorFrameSinkSupport>( |
| 149 this, &surface_manager_, kChildFrameSink1, false /* is_root */, | 176 &support_client_, &surface_manager_, kChildFrameSink1, |
| 150 true /* handles_frame_sink_id_invalidation */, | 177 false /* is_root */, true /* handles_frame_sink_id_invalidation */, |
| 151 true /* needs_sync_points */)); | 178 true /* needs_sync_points */)); |
| 152 supports_.push_back(base::MakeUnique<CompositorFrameSinkSupport>( | 179 supports_.push_back(base::MakeUnique<CompositorFrameSinkSupport>( |
| 153 this, &surface_manager_, kChildFrameSink2, false /* is_root */, | 180 &support_client_, &surface_manager_, kChildFrameSink2, |
| 154 true /* handles_frame_sink_id_invalidation */, | 181 false /* is_root */, true /* handles_frame_sink_id_invalidation */, |
| 155 true /* needs_sync_points */)); | 182 true /* needs_sync_points */)); |
| 156 | 183 |
| 157 // Normally, the BeginFrameSource would be registered by the Display. We | 184 // Normally, the BeginFrameSource would be registered by the Display. We |
| 158 // register it here so that BeginFrames are received by the display support, | 185 // register it here so that BeginFrames are received by the display support, |
| 159 // for use in the PassesOnBeginFrameAcks test. Other supports do not receive | 186 // for use in the PassesOnBeginFrameAcks test. Other supports do not receive |
| 160 // BeginFrames, since the frame sink hierarchy is not set up in this test. | 187 // BeginFrames, since the frame sink hierarchy is not set up in this test. |
| 161 surface_manager_.RegisterBeginFrameSource(begin_frame_source_.get(), | 188 surface_manager_.RegisterBeginFrameSource(begin_frame_source_.get(), |
| 162 kDisplayFrameSink); | 189 kDisplayFrameSink); |
| 163 } | 190 } |
| 164 | 191 |
| 165 void TearDown() override { | 192 void TearDown() override { |
| 166 surface_manager_.SetDependencyTracker(nullptr); | 193 surface_manager_.SetDependencyTracker(nullptr); |
| 167 surface_manager_.UnregisterBeginFrameSource(begin_frame_source_.get()); | 194 surface_manager_.UnregisterBeginFrameSource(begin_frame_source_.get()); |
| 168 | 195 |
| 169 // SurfaceDependencyTracker depends on this BeginFrameSource and so it must | 196 // SurfaceDependencyTracker depends on this BeginFrameSource and so it must |
| 170 // be destroyed AFTER the dependency tracker is destroyed. | 197 // be destroyed AFTER the dependency tracker is destroyed. |
| 171 begin_frame_source_.reset(); | 198 begin_frame_source_.reset(); |
| 172 | 199 |
| 173 supports_.clear(); | 200 supports_.clear(); |
| 174 } | 201 } |
| 175 | 202 |
| 176 // CompositorFrameSinkSupportClient implementation. | 203 protected: |
| 177 void DidReceiveCompositorFrameAck() override {} | 204 testing::NiceMock<MockCompositorFrameSinkSupportClient> support_client_; |
| 178 void OnBeginFrame(const BeginFrameArgs& args) override {} | |
| 179 void ReclaimResources(const ReturnedResourceArray& resources) override { | |
| 180 last_returned_resources_ = resources; | |
| 181 } | |
| 182 void WillDrawSurface(const LocalSurfaceId& local_surface_id, | |
| 183 const gfx::Rect& damage_rect) override {} | |
| 184 | 205 |
| 185 private: | 206 private: |
| 186 SurfaceManager surface_manager_; | 207 SurfaceManager surface_manager_; |
| 187 std::unique_ptr<FakeExternalBeginFrameSource> begin_frame_source_; | 208 std::unique_ptr<FakeExternalBeginFrameSource> begin_frame_source_; |
| 188 std::vector<std::unique_ptr<CompositorFrameSinkSupport>> supports_; | 209 std::vector<std::unique_ptr<CompositorFrameSinkSupport>> supports_; |
| 189 ReturnedResourceArray last_returned_resources_; | |
| 190 | 210 |
| 191 DISALLOW_COPY_AND_ASSIGN(CompositorFrameSinkSupportTest); | 211 DISALLOW_COPY_AND_ASSIGN(CompositorFrameSinkSupportTest); |
| 192 }; | 212 }; |
| 193 | 213 |
| 194 // The display root surface should have a surface reference from the top-level | 214 // The display root surface should have a surface reference from the top-level |
| 195 // root added/removed when a CompositorFrame is submitted with a new SurfaceId. | 215 // root added/removed when a CompositorFrame is submitted with a new SurfaceId. |
| 196 TEST_F(CompositorFrameSinkSupportTest, RootSurfaceReceivesReferences) { | 216 TEST_F(CompositorFrameSinkSupportTest, RootSurfaceReceivesReferences) { |
| 197 const SurfaceId display_id_first = MakeSurfaceId(kDisplayFrameSink, 1); | 217 const SurfaceId display_id_first = MakeSurfaceId(kDisplayFrameSink, 1); |
| 198 const SurfaceId display_id_second = MakeSurfaceId(kDisplayFrameSink, 2); | 218 const SurfaceId display_id_second = MakeSurfaceId(kDisplayFrameSink, 2); |
| 199 | 219 |
| (...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 575 | 595 |
| 576 // The parent submits a CompositorFrame without any dependencies. That frame | 596 // The parent submits a CompositorFrame without any dependencies. That frame |
| 577 // should activate immediately, replacing the earlier frame. The resource from | 597 // should activate immediately, replacing the earlier frame. The resource from |
| 578 // the earlier frame should be returned to the client. | 598 // the earlier frame should be returned to the client. |
| 579 parent_support().SubmitCompositorFrame( | 599 parent_support().SubmitCompositorFrame( |
| 580 parent_id.local_surface_id(), MakeCompositorFrame({empty_surface_ids()})); | 600 parent_id.local_surface_id(), MakeCompositorFrame({empty_surface_ids()})); |
| 581 EXPECT_TRUE(parent_surface()->HasActiveFrame()); | 601 EXPECT_TRUE(parent_surface()->HasActiveFrame()); |
| 582 EXPECT_FALSE(parent_surface()->HasPendingFrame()); | 602 EXPECT_FALSE(parent_surface()->HasPendingFrame()); |
| 583 EXPECT_THAT(parent_surface()->blocking_surfaces_for_testing(), IsEmpty()); | 603 EXPECT_THAT(parent_surface()->blocking_surfaces_for_testing(), IsEmpty()); |
| 584 ReturnedResource returned_resource = resource.ToReturnedResource(); | 604 ReturnedResource returned_resource = resource.ToReturnedResource(); |
| 585 EXPECT_THAT(last_returned_resources(), | 605 EXPECT_THAT(support_client_.last_returned_resources(), |
| 586 UnorderedElementsAre(returned_resource)); | 606 UnorderedElementsAre(returned_resource)); |
| 587 } | 607 } |
| 588 | 608 |
| 589 // This test verifies that a SurfaceReference from parent to child can be added | 609 // This test verifies that a SurfaceReference from parent to child can be added |
| 590 // prior to the child submitting a CompositorFrame. This test also verifies that | 610 // prior to the child submitting a CompositorFrame. This test also verifies that |
| 591 // when the child later submits a CompositorFrame, | 611 // when the child later submits a CompositorFrame, |
| 592 TEST_F(CompositorFrameSinkSupportTest, | 612 TEST_F(CompositorFrameSinkSupportTest, |
| 593 DisplayCompositorLockingReferenceAddedBeforeChildExists) { | 613 DisplayCompositorLockingReferenceAddedBeforeChildExists) { |
| 594 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1); | 614 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1); |
| 595 const SurfaceId child_id = MakeSurfaceId(kChildFrameSink1, 1); | 615 const SurfaceId child_id = MakeSurfaceId(kChildFrameSink1, 1); |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 940 BeginFrameArgs args = | 960 BeginFrameArgs args = |
| 941 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 1); | 961 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 1); |
| 942 begin_frame_source()->TestOnBeginFrame(args); | 962 begin_frame_source()->TestOnBeginFrame(args); |
| 943 | 963 |
| 944 // Check that the support forwards our ack to the BeginFrameSource. | 964 // Check that the support forwards our ack to the BeginFrameSource. |
| 945 BeginFrameAck ack(0, 1, 1, 0, false); | 965 BeginFrameAck ack(0, 1, 1, 0, false); |
| 946 display_support().DidFinishFrame(ack); | 966 display_support().DidFinishFrame(ack); |
| 947 EXPECT_EQ(ack, begin_frame_source()->LastAckForObserver(&display_support())); | 967 EXPECT_EQ(ack, begin_frame_source()->LastAckForObserver(&display_support())); |
| 948 } | 968 } |
| 949 | 969 |
| 970 // Checks whether the resources are returned before we send an ack. | |
| 971 TEST_F(CompositorFrameSinkSupportTest, ReturnResourcesBeforeAck) { | |
| 972 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1); | |
| 973 CompositorFrame frame; | |
| 974 TransferableResource resource; | |
| 975 resource.id = 1234; | |
| 976 frame.resource_list.push_back(resource); | |
|
Fady Samuel
2017/03/08 23:20:21
You could use MakeCompositorFrameWithResources?
| |
| 977 parent_support().SubmitCompositorFrame(parent_id.local_surface_id(), | |
| 978 std::move(frame)); | |
| 979 { | |
| 980 InSequence x; | |
| 981 EXPECT_CALL(support_client_, ReclaimResources(_)); | |
| 982 EXPECT_CALL(support_client_, DidReceiveCompositorFrameAck()); | |
| 983 } | |
| 984 parent_support().SubmitCompositorFrame(parent_id.local_surface_id(), | |
| 985 CompositorFrame()); | |
| 986 } | |
| 987 | |
| 950 } // namespace test | 988 } // namespace test |
| 951 } // namespace cc | 989 } // namespace cc |
| OLD | NEW |