Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 <stddef.h> | 5 #include <stddef.h> |
| 6 | 6 |
| 7 #include "cc/scheduler/begin_frame_source.h" | 7 #include "cc/scheduler/begin_frame_source.h" |
| 8 #include "cc/surfaces/surface_factory_client.h" | 8 #include "cc/surfaces/compositor_frame_sink_support.h" |
| 9 #include "cc/surfaces/surface_manager.h" | 9 #include "cc/surfaces/surface_manager.h" |
| 10 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
| 11 | 11 |
| 12 namespace cc { | 12 namespace cc { |
| 13 namespace { | |
| 13 | 14 |
| 14 class FakeSurfaceFactoryClient : public SurfaceFactoryClient { | 15 constexpr bool is_root = true; |
| 15 public: | 16 constexpr bool is_root_child = false; |
| 16 explicit FakeSurfaceFactoryClient(const FrameSinkId& frame_sink_id) | 17 constexpr bool handles_frame_sink_id_invalidation = false; |
| 17 : source_(nullptr), manager_(nullptr), frame_sink_id_(frame_sink_id) {} | 18 constexpr bool needs_sync_points = true; |
| 18 | 19 |
| 19 FakeSurfaceFactoryClient(const FrameSinkId& frame_sink_id, | 20 } // namespace |
| 20 SurfaceManager* manager) | |
| 21 : source_(nullptr), manager_(nullptr), frame_sink_id_(frame_sink_id) { | |
| 22 DCHECK(manager); | |
| 23 Register(manager); | |
| 24 } | |
| 25 | |
| 26 ~FakeSurfaceFactoryClient() override { | |
| 27 if (manager_) { | |
| 28 Unregister(); | |
| 29 } | |
| 30 EXPECT_EQ(nullptr, source_); | |
| 31 } | |
| 32 | |
| 33 BeginFrameSource* source() { return source_; } | |
| 34 const FrameSinkId& frame_sink_id() { return frame_sink_id_; } | |
| 35 | |
| 36 void Register(SurfaceManager* manager) { | |
| 37 EXPECT_EQ(nullptr, manager_); | |
| 38 manager_ = manager; | |
| 39 manager_->RegisterSurfaceFactoryClient(frame_sink_id_, this); | |
| 40 } | |
| 41 | |
| 42 void Unregister() { | |
| 43 EXPECT_NE(manager_, nullptr); | |
| 44 manager_->UnregisterSurfaceFactoryClient(frame_sink_id_); | |
| 45 manager_ = nullptr; | |
| 46 } | |
| 47 | |
| 48 // SurfaceFactoryClient implementation. | |
| 49 void ReturnResources(const ReturnedResourceArray& resources) override {} | |
| 50 void SetBeginFrameSource(BeginFrameSource* begin_frame_source) override { | |
| 51 DCHECK(!source_ || !begin_frame_source); | |
| 52 source_ = begin_frame_source; | |
| 53 }; | |
| 54 | |
| 55 private: | |
| 56 BeginFrameSource* source_; | |
| 57 SurfaceManager* manager_; | |
| 58 FrameSinkId frame_sink_id_; | |
| 59 }; | |
| 60 | 21 |
| 61 class SurfaceManagerTest : public testing::Test { | 22 class SurfaceManagerTest : public testing::Test { |
| 62 public: | 23 public: |
| 63 // These tests don't care about namespace registration, so just preregister | 24 // These tests don't care about namespace registration, so just preregister |
| 64 // a set of namespaces that tests can use freely without worrying if they're | 25 // a set of namespaces that tests can use freely without worrying if they're |
| 65 // valid or not. | 26 // valid or not. |
| 66 enum { MAX_FRAME_SINK = 10 }; | 27 enum { MAX_FRAME_SINK = 10 }; |
| 67 | 28 |
| 68 SurfaceManagerTest() { | 29 SurfaceManagerTest() { |
| 69 for (size_t i = 0; i < MAX_FRAME_SINK; ++i) | 30 for (size_t i = 0; i < MAX_FRAME_SINK; ++i) |
| 70 manager_.RegisterFrameSinkId(FrameSinkId(i, i)); | 31 manager_.RegisterFrameSinkId(FrameSinkId(i, i)); |
| 71 } | 32 } |
| 72 | 33 |
| 73 ~SurfaceManagerTest() override { | 34 ~SurfaceManagerTest() override { |
| 74 for (size_t i = 0; i < MAX_FRAME_SINK; ++i) | 35 for (size_t i = 0; i < MAX_FRAME_SINK; ++i) |
| 75 manager_.InvalidateFrameSinkId(FrameSinkId(i, i)); | 36 manager_.InvalidateFrameSinkId(FrameSinkId(i, i)); |
| 76 } | 37 } |
| 77 | 38 |
| 78 protected: | 39 protected: |
| 79 SurfaceManager manager_; | 40 SurfaceManager manager_; |
| 80 }; | 41 }; |
| 81 | 42 |
| 82 TEST_F(SurfaceManagerTest, SingleClients) { | 43 TEST_F(SurfaceManagerTest, SingleClients) { |
| 83 FakeSurfaceFactoryClient client(FrameSinkId(1, 1)); | 44 CompositorFrameSinkSupport client( |
| 84 FakeSurfaceFactoryClient other_client(FrameSinkId(2, 2)); | 45 nullptr, &manager_, FrameSinkId(1, 1), is_root_child, |
| 46 handles_frame_sink_id_invalidation, needs_sync_points); | |
| 47 CompositorFrameSinkSupport other_client( | |
| 48 nullptr, &manager_, FrameSinkId(2, 2), is_root_child, | |
| 49 handles_frame_sink_id_invalidation, needs_sync_points); | |
| 85 StubBeginFrameSource source; | 50 StubBeginFrameSource source; |
| 86 | 51 |
| 87 EXPECT_EQ(nullptr, client.source()); | 52 EXPECT_EQ(nullptr, client.begin_frame_source()); |
| 88 EXPECT_EQ(nullptr, other_client.source()); | 53 EXPECT_EQ(nullptr, other_client.begin_frame_source()); |
| 89 client.Register(&manager_); | |
| 90 other_client.Register(&manager_); | |
| 91 EXPECT_EQ(nullptr, client.source()); | |
| 92 EXPECT_EQ(nullptr, other_client.source()); | |
| 93 | 54 |
| 94 // Test setting unsetting BFS | 55 // Test setting unsetting BFS |
| 95 manager_.RegisterBeginFrameSource(&source, client.frame_sink_id()); | 56 manager_.RegisterBeginFrameSource(&source, client.frame_sink_id()); |
| 96 EXPECT_EQ(&source, client.source()); | 57 EXPECT_EQ(&source, client.begin_frame_source()); |
| 97 EXPECT_EQ(nullptr, other_client.source()); | 58 EXPECT_EQ(nullptr, other_client.begin_frame_source()); |
| 98 manager_.UnregisterBeginFrameSource(&source); | 59 manager_.UnregisterBeginFrameSource(&source); |
| 99 EXPECT_EQ(nullptr, client.source()); | 60 EXPECT_EQ(nullptr, client.begin_frame_source()); |
| 100 EXPECT_EQ(nullptr, other_client.source()); | 61 EXPECT_EQ(nullptr, other_client.begin_frame_source()); |
| 101 | 62 |
| 102 // Set BFS for other namespace | 63 // Set BFS for other namespace |
| 103 manager_.RegisterBeginFrameSource(&source, other_client.frame_sink_id()); | 64 manager_.RegisterBeginFrameSource(&source, other_client.frame_sink_id()); |
| 104 EXPECT_EQ(&source, other_client.source()); | 65 EXPECT_EQ(&source, other_client.begin_frame_source()); |
| 105 EXPECT_EQ(nullptr, client.source()); | 66 EXPECT_EQ(nullptr, client.begin_frame_source()); |
| 106 manager_.UnregisterBeginFrameSource(&source); | 67 manager_.UnregisterBeginFrameSource(&source); |
| 107 EXPECT_EQ(nullptr, client.source()); | 68 EXPECT_EQ(nullptr, client.begin_frame_source()); |
| 108 EXPECT_EQ(nullptr, other_client.source()); | 69 EXPECT_EQ(nullptr, other_client.begin_frame_source()); |
| 109 | 70 |
| 110 // Re-set BFS for original | 71 // Re-set BFS for original |
| 111 manager_.RegisterBeginFrameSource(&source, client.frame_sink_id()); | 72 manager_.RegisterBeginFrameSource(&source, client.frame_sink_id()); |
| 112 EXPECT_EQ(&source, client.source()); | 73 EXPECT_EQ(&source, client.begin_frame_source()); |
| 113 manager_.UnregisterBeginFrameSource(&source); | 74 manager_.UnregisterBeginFrameSource(&source); |
| 114 EXPECT_EQ(nullptr, client.source()); | 75 EXPECT_EQ(nullptr, client.begin_frame_source()); |
| 115 } | 76 } |
| 116 | 77 |
| 117 TEST_F(SurfaceManagerTest, MultipleDisplays) { | 78 TEST_F(SurfaceManagerTest, MultipleDisplays) { |
| 118 StubBeginFrameSource root1_source; | 79 StubBeginFrameSource root1_source; |
| 119 StubBeginFrameSource root2_source; | 80 StubBeginFrameSource root2_source; |
| 120 | 81 |
| 121 // root1 -> A -> B | 82 // root1 -> A -> B |
| 122 // root2 -> C | 83 // root2 -> C |
| 123 FakeSurfaceFactoryClient root1(FrameSinkId(1, 1), &manager_); | 84 CompositorFrameSinkSupport root1(nullptr, &manager_, FrameSinkId(1, 1), |
| 124 FakeSurfaceFactoryClient root2(FrameSinkId(2, 2), &manager_); | 85 is_root, handles_frame_sink_id_invalidation, |
| 125 FakeSurfaceFactoryClient client_a(FrameSinkId(3, 3), &manager_); | 86 needs_sync_points); |
| 126 FakeSurfaceFactoryClient client_b(FrameSinkId(4, 4), &manager_); | 87 CompositorFrameSinkSupport root2(nullptr, &manager_, FrameSinkId(2, 2), |
| 127 FakeSurfaceFactoryClient client_c(FrameSinkId(5, 5), &manager_); | 88 is_root, handles_frame_sink_id_invalidation, |
| 89 needs_sync_points); | |
| 90 CompositorFrameSinkSupport client_a( | |
| 91 nullptr, &manager_, FrameSinkId(3, 3), is_root_child, | |
| 92 handles_frame_sink_id_invalidation, needs_sync_points); | |
| 93 CompositorFrameSinkSupport client_b( | |
| 94 nullptr, &manager_, FrameSinkId(4, 4), is_root_child, | |
| 95 handles_frame_sink_id_invalidation, needs_sync_points); | |
| 96 CompositorFrameSinkSupport client_c( | |
| 97 nullptr, &manager_, FrameSinkId(5, 5), is_root_child, | |
| 98 handles_frame_sink_id_invalidation, needs_sync_points); | |
| 128 | 99 |
| 129 manager_.RegisterBeginFrameSource(&root1_source, root1.frame_sink_id()); | 100 manager_.RegisterBeginFrameSource(&root1_source, root1.frame_sink_id()); |
| 130 manager_.RegisterBeginFrameSource(&root2_source, root2.frame_sink_id()); | 101 manager_.RegisterBeginFrameSource(&root2_source, root2.frame_sink_id()); |
| 131 EXPECT_EQ(root1.source(), &root1_source); | 102 EXPECT_EQ(root1.begin_frame_source(), &root1_source); |
| 132 EXPECT_EQ(root2.source(), &root2_source); | 103 EXPECT_EQ(root2.begin_frame_source(), &root2_source); |
| 133 | 104 |
| 134 // Set up initial hierarchy. | 105 // Set up initial hierarchy. |
| 135 manager_.RegisterFrameSinkHierarchy(root1.frame_sink_id(), | 106 manager_.RegisterFrameSinkHierarchy(root1.frame_sink_id(), |
| 136 client_a.frame_sink_id()); | 107 client_a.frame_sink_id()); |
| 137 EXPECT_EQ(client_a.source(), root1.source()); | 108 EXPECT_EQ(client_a.begin_frame_source(), root1.begin_frame_source()); |
| 138 manager_.RegisterFrameSinkHierarchy(client_a.frame_sink_id(), | 109 manager_.RegisterFrameSinkHierarchy(client_a.frame_sink_id(), |
| 139 client_b.frame_sink_id()); | 110 client_b.frame_sink_id()); |
| 140 EXPECT_EQ(client_b.source(), root1.source()); | 111 EXPECT_EQ(client_b.begin_frame_source(), root1.begin_frame_source()); |
| 141 manager_.RegisterFrameSinkHierarchy(root2.frame_sink_id(), | 112 manager_.RegisterFrameSinkHierarchy(root2.frame_sink_id(), |
| 142 client_c.frame_sink_id()); | 113 client_c.frame_sink_id()); |
| 143 EXPECT_EQ(client_c.source(), root2.source()); | 114 EXPECT_EQ(client_c.begin_frame_source(), root2.begin_frame_source()); |
| 144 | 115 |
| 145 // Attach A into root2's subtree, like a window moving across displays. | 116 // Attach A into root2's subtree, like a window moving across displays. |
| 146 // root1 -> A -> B | 117 // root1 -> A -> B |
| 147 // root2 -> C -> A -> B | 118 // root2 -> C -> A -> B |
| 148 manager_.RegisterFrameSinkHierarchy(client_c.frame_sink_id(), | 119 manager_.RegisterFrameSinkHierarchy(client_c.frame_sink_id(), |
| 149 client_a.frame_sink_id()); | 120 client_a.frame_sink_id()); |
| 150 // With the heuristic of just keeping existing BFS in the face of multiple, | 121 // With the heuristic of just keeping existing BFS in the face of multiple, |
| 151 // no client sources should change. | 122 // no client sources should change. |
| 152 EXPECT_EQ(client_a.source(), root1.source()); | 123 EXPECT_EQ(client_a.begin_frame_source(), root1.begin_frame_source()); |
| 153 EXPECT_EQ(client_b.source(), root1.source()); | 124 EXPECT_EQ(client_b.begin_frame_source(), root1.begin_frame_source()); |
| 154 EXPECT_EQ(client_c.source(), root2.source()); | 125 EXPECT_EQ(client_c.begin_frame_source(), root2.begin_frame_source()); |
| 155 | 126 |
| 156 // Detach A from root1. A and B should now be updated to root2. | 127 // Detach A from root1. A and B should now be updated to root2. |
| 157 manager_.UnregisterFrameSinkHierarchy(root1.frame_sink_id(), | 128 manager_.UnregisterFrameSinkHierarchy(root1.frame_sink_id(), |
| 158 client_a.frame_sink_id()); | 129 client_a.frame_sink_id()); |
| 159 EXPECT_EQ(client_a.source(), root2.source()); | 130 EXPECT_EQ(client_a.begin_frame_source(), root2.begin_frame_source()); |
| 160 EXPECT_EQ(client_b.source(), root2.source()); | 131 EXPECT_EQ(client_b.begin_frame_source(), root2.begin_frame_source()); |
| 161 EXPECT_EQ(client_c.source(), root2.source()); | 132 EXPECT_EQ(client_c.begin_frame_source(), root2.begin_frame_source()); |
| 162 | 133 |
| 163 // Detach root1 from BFS. root1 should now have no source. | 134 // Detach root1 from BFS. root1 should now have no source. |
| 164 manager_.UnregisterBeginFrameSource(&root1_source); | 135 manager_.UnregisterBeginFrameSource(&root1_source); |
| 165 EXPECT_EQ(nullptr, root1.source()); | 136 EXPECT_EQ(nullptr, root1.begin_frame_source()); |
| 166 EXPECT_NE(nullptr, root2.source()); | 137 EXPECT_NE(nullptr, root2.begin_frame_source()); |
| 167 | 138 |
| 168 // Detatch root2 from BFS. | 139 // Detatch root2 from BFS. |
| 169 manager_.UnregisterBeginFrameSource(&root2_source); | 140 manager_.UnregisterBeginFrameSource(&root2_source); |
| 170 EXPECT_EQ(nullptr, client_a.source()); | 141 EXPECT_EQ(nullptr, client_a.begin_frame_source()); |
| 171 EXPECT_EQ(nullptr, client_b.source()); | 142 EXPECT_EQ(nullptr, client_b.begin_frame_source()); |
| 172 EXPECT_EQ(nullptr, client_c.source()); | 143 EXPECT_EQ(nullptr, client_c.begin_frame_source()); |
| 173 EXPECT_EQ(nullptr, root2.source()); | 144 EXPECT_EQ(nullptr, root2.begin_frame_source()); |
| 174 | 145 |
| 175 // Cleanup hierarchy. | 146 // Cleanup hierarchy. |
| 176 manager_.UnregisterFrameSinkHierarchy(root2.frame_sink_id(), | 147 manager_.UnregisterFrameSinkHierarchy(root2.frame_sink_id(), |
| 177 client_c.frame_sink_id()); | 148 client_c.frame_sink_id()); |
| 178 manager_.UnregisterFrameSinkHierarchy(client_c.frame_sink_id(), | 149 manager_.UnregisterFrameSinkHierarchy(client_c.frame_sink_id(), |
| 179 client_a.frame_sink_id()); | 150 client_a.frame_sink_id()); |
| 180 manager_.UnregisterFrameSinkHierarchy(client_a.frame_sink_id(), | 151 manager_.UnregisterFrameSinkHierarchy(client_a.frame_sink_id(), |
| 181 client_b.frame_sink_id()); | 152 client_b.frame_sink_id()); |
| 182 } | 153 } |
| 183 | 154 |
| 184 // This test verifies that a BeginFrameSource path to the root from a | 155 // This test verifies that a BeginFrameSource path to the root from a |
| 185 // FrameSinkId is preserved even if that FrameSinkId has no children | 156 // FrameSinkId is preserved even if that FrameSinkId has no children |
| 186 // and does not have a corresponding SurfaceFactoryClient. | 157 // and does not have a corresponding SurfaceFactoryClient. |
| 187 TEST_F(SurfaceManagerTest, ParentWithoutClientRetained) { | 158 TEST_F(SurfaceManagerTest, ParentWithoutClientRetained) { |
| 188 StubBeginFrameSource root_source; | 159 StubBeginFrameSource root_source; |
| 189 | 160 |
| 190 constexpr FrameSinkId kFrameSinkIdRoot(1, 1); | 161 constexpr FrameSinkId kFrameSinkIdRoot(1, 1); |
| 191 constexpr FrameSinkId kFrameSinkIdA(2, 2); | 162 constexpr FrameSinkId kFrameSinkIdA(2, 2); |
| 192 constexpr FrameSinkId kFrameSinkIdB(3, 3); | 163 constexpr FrameSinkId kFrameSinkIdB(3, 3); |
| 193 constexpr FrameSinkId kFrameSinkIdC(4, 4); | 164 constexpr FrameSinkId kFrameSinkIdC(4, 4); |
| 194 | 165 |
| 195 FakeSurfaceFactoryClient root(kFrameSinkIdRoot, &manager_); | 166 CompositorFrameSinkSupport root(nullptr, &manager_, kFrameSinkIdRoot, is_root, |
| 196 FakeSurfaceFactoryClient client_b(kFrameSinkIdB, &manager_); | 167 handles_frame_sink_id_invalidation, |
| 197 FakeSurfaceFactoryClient client_c(kFrameSinkIdC, &manager_); | 168 needs_sync_points); |
| 169 CompositorFrameSinkSupport client_b( | |
| 170 nullptr, &manager_, kFrameSinkIdB, is_root_child, | |
| 171 handles_frame_sink_id_invalidation, needs_sync_points); | |
| 172 CompositorFrameSinkSupport client_c( | |
| 173 nullptr, &manager_, kFrameSinkIdC, is_root_child, | |
| 174 handles_frame_sink_id_invalidation, needs_sync_points); | |
| 198 | 175 |
| 199 manager_.RegisterBeginFrameSource(&root_source, root.frame_sink_id()); | 176 manager_.RegisterBeginFrameSource(&root_source, root.frame_sink_id()); |
| 200 EXPECT_EQ(&root_source, root.source()); | 177 EXPECT_EQ(&root_source, root.begin_frame_source()); |
| 201 | 178 |
| 202 // Set up initial hierarchy: root -> A -> B. | 179 // Set up initial hierarchy: root -> A -> B. |
| 203 // Note that A does not have a SurfaceFactoryClient. | 180 // Note that A does not have a SurfaceFactoryClient. |
| 204 manager_.RegisterFrameSinkHierarchy(kFrameSinkIdRoot, kFrameSinkIdA); | 181 manager_.RegisterFrameSinkHierarchy(kFrameSinkIdRoot, kFrameSinkIdA); |
| 205 manager_.RegisterFrameSinkHierarchy(kFrameSinkIdA, kFrameSinkIdB); | 182 manager_.RegisterFrameSinkHierarchy(kFrameSinkIdA, kFrameSinkIdB); |
| 206 // The root's BeginFrameSource should propagate to B. | 183 // The root's BeginFrameSource should propagate to B. |
| 207 EXPECT_EQ(root.source(), client_b.source()); | 184 EXPECT_EQ(root.begin_frame_source(), client_b.begin_frame_source()); |
| 208 | 185 |
| 209 // Unregister B, and attach C to A: root -> A -> C | 186 // Unregister B, and attach C to A: root -> A -> C |
| 210 manager_.UnregisterFrameSinkHierarchy(kFrameSinkIdA, kFrameSinkIdB); | 187 manager_.UnregisterFrameSinkHierarchy(kFrameSinkIdA, kFrameSinkIdB); |
| 211 EXPECT_EQ(nullptr, client_b.source()); | 188 EXPECT_EQ(nullptr, client_b.begin_frame_source()); |
| 212 manager_.RegisterFrameSinkHierarchy(kFrameSinkIdA, kFrameSinkIdC); | 189 manager_.RegisterFrameSinkHierarchy(kFrameSinkIdA, kFrameSinkIdC); |
| 213 // The root's BeginFrameSource should propagate to C. | 190 // The root's BeginFrameSource should propagate to C. |
| 214 EXPECT_EQ(root.source(), client_c.source()); | 191 EXPECT_EQ(root.begin_frame_source(), client_c.begin_frame_source()); |
| 215 | 192 |
| 216 manager_.UnregisterBeginFrameSource(&root_source); | 193 manager_.UnregisterBeginFrameSource(&root_source); |
| 217 EXPECT_EQ(nullptr, root.source()); | 194 EXPECT_EQ(nullptr, root.begin_frame_source()); |
| 218 EXPECT_EQ(nullptr, client_c.source()); | 195 EXPECT_EQ(nullptr, client_c.begin_frame_source()); |
| 219 } | 196 } |
| 220 | 197 |
| 221 // This test sets up the same hierarchy as ParentWithoutClientRetained. | 198 // This test sets up the same hierarchy as ParentWithoutClientRetained. |
| 222 // However, this unit test registers the BeginFrameSource AFTER C | 199 // However, this unit test registers the BeginFrameSource AFTER C |
| 223 // has been attached to A. This test verifies that the BeginFrameSource | 200 // has been attached to A. This test verifies that the BeginFrameSource |
| 224 // propagates all the way to C. | 201 // propagates all the way to C. |
| 225 TEST_F(SurfaceManagerTest, | 202 TEST_F(SurfaceManagerTest, |
| 226 ParentWithoutClientRetained_LateBeginFrameRegistration) { | 203 ParentWithoutClientRetained_LateBeginFrameRegistration) { |
| 227 StubBeginFrameSource root_source; | 204 StubBeginFrameSource root_source; |
| 228 | 205 |
| 229 constexpr FrameSinkId kFrameSinkIdRoot(1, 1); | 206 constexpr FrameSinkId kFrameSinkIdRoot(1, 1); |
| 230 constexpr FrameSinkId kFrameSinkIdA(2, 2); | 207 constexpr FrameSinkId kFrameSinkIdA(2, 2); |
| 231 constexpr FrameSinkId kFrameSinkIdB(3, 3); | 208 constexpr FrameSinkId kFrameSinkIdB(3, 3); |
| 232 constexpr FrameSinkId kFrameSinkIdC(4, 4); | 209 constexpr FrameSinkId kFrameSinkIdC(4, 4); |
| 233 | 210 |
| 234 FakeSurfaceFactoryClient root(kFrameSinkIdRoot, &manager_); | 211 CompositorFrameSinkSupport root(nullptr, &manager_, kFrameSinkIdRoot, is_root, |
| 235 FakeSurfaceFactoryClient client_b(kFrameSinkIdB, &manager_); | 212 handles_frame_sink_id_invalidation, |
| 236 FakeSurfaceFactoryClient client_c(kFrameSinkIdC, &manager_); | 213 needs_sync_points); |
| 214 CompositorFrameSinkSupport client_b( | |
| 215 nullptr, &manager_, kFrameSinkIdB, is_root_child, | |
| 216 handles_frame_sink_id_invalidation, needs_sync_points); | |
| 217 CompositorFrameSinkSupport client_c( | |
| 218 nullptr, &manager_, kFrameSinkIdC, is_root_child, | |
| 219 handles_frame_sink_id_invalidation, needs_sync_points); | |
| 237 | 220 |
| 238 // Set up initial hierarchy: root -> A -> B. | 221 // Set up initial hierarchy: root -> A -> B. |
| 239 // Note that A does not have a SurfaceFactoryClient. | 222 // Note that A does not have a SurfaceFactoryClient. |
| 240 manager_.RegisterFrameSinkHierarchy(kFrameSinkIdRoot, kFrameSinkIdA); | 223 manager_.RegisterFrameSinkHierarchy(kFrameSinkIdRoot, kFrameSinkIdA); |
| 241 manager_.RegisterFrameSinkHierarchy(kFrameSinkIdA, kFrameSinkIdB); | 224 manager_.RegisterFrameSinkHierarchy(kFrameSinkIdA, kFrameSinkIdB); |
| 242 // The root does not yet have a BeginFrameSource so client B should not have | 225 // The root does not yet have a BeginFrameSource so client B should not have |
| 243 // one either. | 226 // one either. |
| 244 EXPECT_EQ(nullptr, client_b.source()); | 227 EXPECT_EQ(nullptr, client_b.begin_frame_source()); |
| 245 | 228 |
| 246 // Unregister B, and attach C to A: root -> A -> C | 229 // Unregister B, and attach C to A: root -> A -> C |
| 247 manager_.UnregisterFrameSinkHierarchy(kFrameSinkIdA, kFrameSinkIdB); | 230 manager_.UnregisterFrameSinkHierarchy(kFrameSinkIdA, kFrameSinkIdB); |
| 248 manager_.RegisterFrameSinkHierarchy(kFrameSinkIdA, kFrameSinkIdC); | 231 manager_.RegisterFrameSinkHierarchy(kFrameSinkIdA, kFrameSinkIdC); |
| 249 | 232 |
| 250 // Registering a BeginFrameSource at the root should propagate it to C. | 233 // Registering a BeginFrameSource at the root should propagate it to C. |
| 251 manager_.RegisterBeginFrameSource(&root_source, root.frame_sink_id()); | 234 manager_.RegisterBeginFrameSource(&root_source, root.frame_sink_id()); |
| 252 // The root's BeginFrameSource should propagate to C. | 235 // The root's BeginFrameSource should propagate to C. |
| 253 EXPECT_EQ(&root_source, root.source()); | 236 EXPECT_EQ(&root_source, root.begin_frame_source()); |
| 254 EXPECT_EQ(root.source(), client_c.source()); | 237 EXPECT_EQ(root.begin_frame_source(), client_c.begin_frame_source()); |
| 255 | 238 |
| 256 manager_.UnregisterBeginFrameSource(&root_source); | 239 manager_.UnregisterBeginFrameSource(&root_source); |
| 257 EXPECT_EQ(nullptr, root.source()); | 240 EXPECT_EQ(nullptr, root.begin_frame_source()); |
| 258 EXPECT_EQ(nullptr, client_c.source()); | 241 EXPECT_EQ(nullptr, client_c.begin_frame_source()); |
| 259 } | 242 } |
| 260 | 243 |
| 261 // In practice, registering and unregistering both parent/child relationships | 244 // In practice, registering and unregistering both parent/child relationships |
| 262 // and SurfaceFactoryClients can happen in any ordering with respect to | 245 // and SurfaceFactoryClients can happen in any ordering with respect to |
| 263 // each other. These following tests verify that all the data structures | 246 // each other. These following tests verify that all the data structures |
| 264 // are properly set up and cleaned up under the four permutations of orderings | 247 // are properly set up and cleaned up under the four permutations of orderings |
| 265 // of this nesting. | 248 // of this nesting. |
| 266 | 249 |
| 267 class SurfaceManagerOrderingTest : public SurfaceManagerTest { | 250 class SurfaceManagerOrderingTest : public SurfaceManagerTest { |
| 268 public: | 251 public: |
| 269 SurfaceManagerOrderingTest() | 252 SurfaceManagerOrderingTest() |
| 270 : client_a_(FrameSinkId(1, 1)), | 253 : hierarchy_registered_(false), |
| 271 client_b_(FrameSinkId(2, 2)), | |
| 272 client_c_(FrameSinkId(3, 3)), | |
| 273 hierarchy_registered_(false), | |
| 274 clients_registered_(false), | 254 clients_registered_(false), |
| 275 bfs_registered_(false) { | 255 bfs_registered_(false) { |
| 276 AssertCorrectBFSState(); | 256 AssertCorrectBFSState(); |
| 277 } | 257 } |
| 278 | 258 |
| 279 ~SurfaceManagerOrderingTest() override { | 259 ~SurfaceManagerOrderingTest() override { |
| 280 EXPECT_FALSE(hierarchy_registered_); | 260 EXPECT_FALSE(hierarchy_registered_); |
| 281 EXPECT_FALSE(clients_registered_); | 261 EXPECT_FALSE(clients_registered_); |
| 282 EXPECT_FALSE(bfs_registered_); | 262 EXPECT_FALSE(bfs_registered_); |
| 283 AssertCorrectBFSState(); | 263 AssertCorrectBFSState(); |
| 284 } | 264 } |
| 285 | 265 |
| 286 void RegisterHierarchy() { | 266 void RegisterHierarchy() { |
| 287 DCHECK(!hierarchy_registered_); | 267 DCHECK(!hierarchy_registered_); |
| 288 hierarchy_registered_ = true; | 268 hierarchy_registered_ = true; |
| 289 manager_.RegisterFrameSinkHierarchy(client_a_.frame_sink_id(), | 269 manager_.RegisterFrameSinkHierarchy(frame_sink_id_a_, frame_sink_id_b_); |
| 290 client_b_.frame_sink_id()); | 270 manager_.RegisterFrameSinkHierarchy(frame_sink_id_b_, frame_sink_id_c_); |
| 291 manager_.RegisterFrameSinkHierarchy(client_b_.frame_sink_id(), | |
| 292 client_c_.frame_sink_id()); | |
| 293 AssertCorrectBFSState(); | 271 AssertCorrectBFSState(); |
| 294 } | 272 } |
| 295 void UnregisterHierarchy() { | 273 void UnregisterHierarchy() { |
| 296 DCHECK(hierarchy_registered_); | 274 DCHECK(hierarchy_registered_); |
| 297 hierarchy_registered_ = false; | 275 hierarchy_registered_ = false; |
| 298 manager_.UnregisterFrameSinkHierarchy(client_a_.frame_sink_id(), | 276 manager_.UnregisterFrameSinkHierarchy(frame_sink_id_a_, frame_sink_id_b_); |
| 299 client_b_.frame_sink_id()); | 277 manager_.UnregisterFrameSinkHierarchy(frame_sink_id_b_, frame_sink_id_c_); |
| 300 manager_.UnregisterFrameSinkHierarchy(client_b_.frame_sink_id(), | |
| 301 client_c_.frame_sink_id()); | |
| 302 AssertCorrectBFSState(); | 278 AssertCorrectBFSState(); |
| 303 } | 279 } |
| 304 | 280 |
| 305 void RegisterClients() { | 281 void RegisterClients() { |
| 306 DCHECK(!clients_registered_); | 282 DCHECK(!clients_registered_); |
| 307 clients_registered_ = true; | 283 clients_registered_ = true; |
| 308 client_a_.Register(&manager_); | 284 client_a_ = base::MakeUnique<CompositorFrameSinkSupport>( |
| 309 client_b_.Register(&manager_); | 285 nullptr, &manager_, frame_sink_id_a_, is_root, |
| 310 client_c_.Register(&manager_); | 286 handles_frame_sink_id_invalidation, needs_sync_points); |
| 287 client_b_ = base::MakeUnique<CompositorFrameSinkSupport>( | |
| 288 nullptr, &manager_, frame_sink_id_b_, is_root_child, | |
| 289 handles_frame_sink_id_invalidation, needs_sync_points); | |
| 290 client_c_ = base::MakeUnique<CompositorFrameSinkSupport>( | |
| 291 nullptr, &manager_, frame_sink_id_c_, is_root_child, | |
| 292 handles_frame_sink_id_invalidation, needs_sync_points); | |
| 311 AssertCorrectBFSState(); | 293 AssertCorrectBFSState(); |
| 312 } | 294 } |
| 313 | 295 |
| 314 void UnregisterClients() { | 296 void UnregisterClients() { |
| 315 DCHECK(clients_registered_); | 297 DCHECK(clients_registered_); |
| 316 clients_registered_ = false; | 298 clients_registered_ = false; |
| 317 client_a_.Unregister(); | 299 client_a_.reset(); |
| 318 client_b_.Unregister(); | 300 client_b_.reset(); |
| 319 client_c_.Unregister(); | 301 client_c_.reset(); |
| 320 AssertCorrectBFSState(); | 302 AssertCorrectBFSState(); |
| 321 } | 303 } |
| 322 | 304 |
| 323 void RegisterBFS() { | 305 void RegisterBFS() { |
| 324 DCHECK(!bfs_registered_); | 306 DCHECK(!bfs_registered_); |
| 325 bfs_registered_ = true; | 307 bfs_registered_ = true; |
| 326 manager_.RegisterBeginFrameSource(&source_, client_a_.frame_sink_id()); | 308 manager_.RegisterBeginFrameSource(&source_, frame_sink_id_a_); |
| 327 AssertCorrectBFSState(); | 309 AssertCorrectBFSState(); |
| 328 } | 310 } |
| 329 void UnregisterBFS() { | 311 void UnregisterBFS() { |
| 330 DCHECK(bfs_registered_); | 312 DCHECK(bfs_registered_); |
| 331 bfs_registered_ = false; | 313 bfs_registered_ = false; |
| 332 manager_.UnregisterBeginFrameSource(&source_); | 314 manager_.UnregisterBeginFrameSource(&source_); |
| 333 AssertCorrectBFSState(); | 315 AssertCorrectBFSState(); |
| 334 } | 316 } |
| 335 | 317 |
| 336 void AssertEmptyBFS() { | 318 void AssertEmptyBFS() { |
| 337 EXPECT_EQ(nullptr, client_a_.source()); | 319 EXPECT_TRUE(client_a_.get() == nullptr || |
| 338 EXPECT_EQ(nullptr, client_b_.source()); | 320 client_a_->begin_frame_source() == nullptr); |
| 339 EXPECT_EQ(nullptr, client_c_.source()); | 321 EXPECT_TRUE(client_b_.get() == nullptr || |
| 322 client_b_->begin_frame_source() == nullptr); | |
| 323 EXPECT_TRUE(client_c_.get() == nullptr || | |
| 324 client_c_->begin_frame_source() == nullptr); | |
| 340 } | 325 } |
| 341 | 326 |
| 342 void AssertAllValidBFS() { | 327 void AssertAllValidBFS() { |
| 343 EXPECT_EQ(&source_, client_a_.source()); | 328 EXPECT_EQ(&source_, client_a_->begin_frame_source()); |
| 344 EXPECT_EQ(&source_, client_b_.source()); | 329 EXPECT_EQ(&source_, client_b_->begin_frame_source()); |
| 345 EXPECT_EQ(&source_, client_c_.source()); | 330 EXPECT_EQ(&source_, client_c_->begin_frame_source()); |
| 346 } | 331 } |
| 347 | 332 |
| 348 protected: | 333 protected: |
| 349 void AssertCorrectBFSState() { | 334 void AssertCorrectBFSState() { |
| 350 if (!clients_registered_ || !bfs_registered_) { | 335 if (!clients_registered_ || !bfs_registered_) { |
| 351 AssertEmptyBFS(); | 336 AssertEmptyBFS(); |
| 352 return; | 337 return; |
| 353 } | 338 } |
| 354 if (!hierarchy_registered_) { | 339 if (!hierarchy_registered_) { |
| 355 // A valid but not attached to anything. | 340 // A valid but not attached to anything. |
| 356 EXPECT_EQ(&source_, client_a_.source()); | 341 EXPECT_EQ(&source_, client_a_->begin_frame_source()); |
| 357 EXPECT_EQ(nullptr, client_b_.source()); | 342 EXPECT_TRUE(client_b_.get() == nullptr || |
|
Fady Samuel
2017/04/04 22:48:16
Can this happen?
Alex Z.
2017/04/05 14:38:55
Yes. It happens in SurfaceManagerOrderingTest(),
| |
| 358 EXPECT_EQ(nullptr, client_c_.source()); | 343 client_b_->begin_frame_source() == nullptr); |
| 344 EXPECT_TRUE(client_c_.get() == nullptr || | |
|
Fady Samuel
2017/04/04 22:48:17
Can this happen?
Alex Z.
2017/04/05 14:38:55
Yes. It happens in SurfaceManagerOrderingTest(),
| |
| 345 client_c_->begin_frame_source() == nullptr); | |
| 359 return; | 346 return; |
| 360 } | 347 } |
| 361 | 348 |
| 362 AssertAllValidBFS(); | 349 AssertAllValidBFS(); |
| 363 } | 350 } |
| 364 | 351 |
| 365 StubBeginFrameSource source_; | 352 StubBeginFrameSource source_; |
| 366 // A -> B -> C hierarchy, with A always having the BFS. | 353 // A -> B -> C hierarchy, with A always having the BFS. |
| 367 FakeSurfaceFactoryClient client_a_; | 354 std::unique_ptr<CompositorFrameSinkSupport> client_a_; |
| 368 FakeSurfaceFactoryClient client_b_; | 355 std::unique_ptr<CompositorFrameSinkSupport> client_b_; |
| 369 FakeSurfaceFactoryClient client_c_; | 356 std::unique_ptr<CompositorFrameSinkSupport> client_c_; |
| 357 | |
| 358 const FrameSinkId frame_sink_id_a_ = FrameSinkId(1, 1); | |
| 359 const FrameSinkId frame_sink_id_b_ = FrameSinkId(2, 2); | |
| 360 const FrameSinkId frame_sink_id_c_ = FrameSinkId(3, 3); | |
|
Fady Samuel
2017/04/04 22:48:17
Move these to the anonymous namespace.
Alex Z.
2017/04/05 14:38:55
Done.
| |
| 370 | 361 |
| 371 bool hierarchy_registered_; | 362 bool hierarchy_registered_; |
| 372 bool clients_registered_; | 363 bool clients_registered_; |
| 373 bool bfs_registered_; | 364 bool bfs_registered_; |
| 374 }; | 365 }; |
| 375 | 366 |
| 376 enum RegisterOrder { REGISTER_HIERARCHY_FIRST, REGISTER_CLIENTS_FIRST }; | 367 enum RegisterOrder { REGISTER_HIERARCHY_FIRST, REGISTER_CLIENTS_FIRST }; |
| 377 enum UnregisterOrder { UNREGISTER_HIERARCHY_FIRST, UNREGISTER_CLIENTS_FIRST }; | 368 enum UnregisterOrder { UNREGISTER_HIERARCHY_FIRST, UNREGISTER_CLIENTS_FIRST }; |
| 378 enum BFSOrder { BFS_FIRST, BFS_SECOND, BFS_THIRD }; | 369 enum BFSOrder { BFS_FIRST, BFS_SECOND, BFS_THIRD }; |
| 379 | 370 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 443 } | 434 } |
| 444 | 435 |
| 445 INSTANTIATE_TEST_CASE_P( | 436 INSTANTIATE_TEST_CASE_P( |
| 446 SurfaceManagerOrderingParamTestInstantiation, | 437 SurfaceManagerOrderingParamTestInstantiation, |
| 447 SurfaceManagerOrderingParamTest, | 438 SurfaceManagerOrderingParamTest, |
| 448 ::testing::Combine(::testing::ValuesIn(kRegisterOrderList), | 439 ::testing::Combine(::testing::ValuesIn(kRegisterOrderList), |
| 449 ::testing::ValuesIn(kUnregisterOrderList), | 440 ::testing::ValuesIn(kUnregisterOrderList), |
| 450 ::testing::ValuesIn(kBFSOrderList))); | 441 ::testing::ValuesIn(kBFSOrderList))); |
| 451 | 442 |
| 452 } // namespace cc | 443 } // namespace cc |
| OLD | NEW |