OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "services/ui/ws/embedded_surface_tracker.h" |
| 6 |
| 7 #include <memory> |
| 8 |
| 9 #include "base/logging.h" |
| 10 #include "base/macros.h" |
| 11 #include "cc/ipc/mojo_compositor_frame_sink.mojom.h" |
| 12 #include "cc/surfaces/frame_sink_id.h" |
| 13 #include "cc/surfaces/surface_id.h" |
| 14 #include "cc/surfaces/surface_reference.h" |
| 15 #include "mojo/public/cpp/bindings/binding.h" |
| 16 #include "mojo/public/cpp/bindings/interface_request.h" |
| 17 #include "testing/gmock/include/gmock/gmock.h" |
| 18 #include "testing/gtest/include/gtest/gtest.h" |
| 19 |
| 20 using testing::ElementsAre; |
| 21 using testing::IsEmpty; |
| 22 |
| 23 namespace ui { |
| 24 namespace test { |
| 25 namespace { |
| 26 |
| 27 constexpr cc::FrameSinkId kParentFrameSink(2, 1); |
| 28 constexpr cc::FrameSinkId kEmbeddedFrameSink(65563, 1); |
| 29 |
| 30 cc::SurfaceId MakeSurfaceId(const cc::FrameSinkId& frame_sink_id, |
| 31 uint32_t local_id) { |
| 32 return cc::SurfaceId( |
| 33 frame_sink_id, |
| 34 cc::LocalFrameId(local_id, base::UnguessableToken::Deserialize(0, 1u))); |
| 35 } |
| 36 |
| 37 class TestMojoCompositorFrameSink : public cc::mojom::MojoCompositorFrameSink { |
| 38 public: |
| 39 TestMojoCompositorFrameSink() {} |
| 40 ~TestMojoCompositorFrameSink() override {} |
| 41 |
| 42 const std::vector<cc::SurfaceReference>& added() const { return added_; } |
| 43 const std::vector<cc::SurfaceReference>& removed() const { return removed_; } |
| 44 |
| 45 // Reset |added_| and |removed_|. |
| 46 void Reset() { |
| 47 added_.clear(); |
| 48 removed_.clear(); |
| 49 } |
| 50 |
| 51 // cc::mojom::MojoCompositorFrameSink: |
| 52 void SetNeedsBeginFrame(bool needs_begin_frame) override {} |
| 53 void SubmitCompositorFrame(const cc::LocalFrameId& local_frame_id, |
| 54 cc::CompositorFrame frame) override {} |
| 55 void AddSurfaceReferences( |
| 56 const std::vector<cc::SurfaceReference>& references) override { |
| 57 added_ = references; |
| 58 } |
| 59 void RemoveSurfaceReferences( |
| 60 const std::vector<cc::SurfaceReference>& references) override { |
| 61 removed_ = references; |
| 62 } |
| 63 void EvictFrame() override {} |
| 64 void Require(const cc::LocalFrameId& local_frame_id, |
| 65 const cc::SurfaceSequence& sequence) override {} |
| 66 void Satisfy(const cc::SurfaceSequence& sequence) override {} |
| 67 |
| 68 private: |
| 69 std::vector<cc::SurfaceReference> added_; |
| 70 std::vector<cc::SurfaceReference> removed_; |
| 71 |
| 72 DISALLOW_COPY_AND_ASSIGN(TestMojoCompositorFrameSink); |
| 73 }; |
| 74 |
| 75 } // namespace |
| 76 |
| 77 class EmbeddedSurfaceTrackerTest : public testing::Test { |
| 78 public: |
| 79 EmbeddedSurfaceTrackerTest() {} |
| 80 ~EmbeddedSurfaceTrackerTest() override {} |
| 81 |
| 82 EmbeddedSurfaceTracker& tracker() { return *tracker_; } |
| 83 TestMojoCompositorFrameSink& frame_sink() { return frame_sink_; } |
| 84 |
| 85 const std::vector<cc::SurfaceReference>& references_to_add() { |
| 86 return tracker_->references_to_add_; |
| 87 } |
| 88 |
| 89 const std::vector<cc::SurfaceReference>& references_to_remove() { |
| 90 return tracker_->references_to_remove_; |
| 91 } |
| 92 |
| 93 // testing::Test: |
| 94 void SetUp() override { |
| 95 testing::Test::SetUp(); |
| 96 tracker_ = base::MakeUnique<EmbeddedSurfaceTracker>(); |
| 97 } |
| 98 |
| 99 void TearDown() override { |
| 100 frame_sink_.Reset(); |
| 101 tracker_.reset(); |
| 102 } |
| 103 |
| 104 private: |
| 105 std::unique_ptr<EmbeddedSurfaceTracker> tracker_; |
| 106 TestMojoCompositorFrameSink frame_sink_; |
| 107 |
| 108 DISALLOW_COPY_AND_ASSIGN(EmbeddedSurfaceTrackerTest); |
| 109 }; |
| 110 |
| 111 TEST_F(EmbeddedSurfaceTrackerTest, SetCurrentSurfaceId) { |
| 112 const cc::SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1); |
| 113 |
| 114 // Initially HasValidSurfaceId() should be false. |
| 115 EXPECT_FALSE(tracker().HasValidSurfaceId()); |
| 116 |
| 117 // After setting current SurfaceId then HasValidSurfaceId() should be true. |
| 118 tracker().SetCurrentSurfaceId(parent_id); |
| 119 EXPECT_TRUE(tracker().HasValidSurfaceId()); |
| 120 EXPECT_EQ(parent_id, tracker().current_surface_id()); |
| 121 } |
| 122 |
| 123 TEST_F(EmbeddedSurfaceTrackerTest, EmbedSurface) { |
| 124 const cc::SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1); |
| 125 const cc::SurfaceId embedded_id = MakeSurfaceId(kEmbeddedFrameSink, 1); |
| 126 const cc::SurfaceReference reference(parent_id, embedded_id); |
| 127 |
| 128 // Set parent surface id then embed another surface. The tracker should have a |
| 129 // reference to add from parent surface to embedded surface. |
| 130 tracker().SetCurrentSurfaceId(parent_id); |
| 131 tracker().EmbedSurface(embedded_id); |
| 132 EXPECT_THAT(references_to_add(), ElementsAre(reference)); |
| 133 |
| 134 // After adding references the tracker should no longer have any references to |
| 135 // add and MojoCompositorFrameSink should have been called with surfaces to |
| 136 // add. |
| 137 tracker().SendAddSurfaceReferences(&frame_sink()); |
| 138 EXPECT_THAT(frame_sink().added(), ElementsAre(reference)); |
| 139 EXPECT_THAT(references_to_add(), IsEmpty()); |
| 140 } |
| 141 |
| 142 TEST_F(EmbeddedSurfaceTrackerTest, EmbedNewSurface) { |
| 143 const cc::SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1); |
| 144 const cc::SurfaceId embedded_id_first = MakeSurfaceId(kEmbeddedFrameSink, 1); |
| 145 const cc::SurfaceId embedded_id_second = MakeSurfaceId(kEmbeddedFrameSink, 2); |
| 146 const cc::SurfaceReference reference_first(parent_id, embedded_id_first); |
| 147 const cc::SurfaceReference reference_second(parent_id, embedded_id_second); |
| 148 |
| 149 // Embed a surface and add references. |
| 150 tracker().SetCurrentSurfaceId(parent_id); |
| 151 tracker().EmbedSurface(embedded_id_first); |
| 152 tracker().SendAddSurfaceReferences(&frame_sink()); |
| 153 EXPECT_THAT(frame_sink().added(), ElementsAre(reference_first)); |
| 154 |
| 155 // Embed a newer surface with the same FrameSinkId as the first embedded |
| 156 // surface. The first reference should be in the list to remove and the new |
| 157 // reference in the last to add. |
| 158 tracker().EmbedSurface(embedded_id_second); |
| 159 EXPECT_THAT(references_to_remove(), ElementsAre(reference_first)); |
| 160 EXPECT_THAT(references_to_add(), ElementsAre(reference_second)); |
| 161 } |
| 162 |
| 163 TEST_F(EmbeddedSurfaceTrackerTest, UnembedSurface) { |
| 164 const cc::SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1); |
| 165 const cc::SurfaceId embedded_id = MakeSurfaceId(kEmbeddedFrameSink, 1); |
| 166 const cc::SurfaceReference reference(parent_id, embedded_id); |
| 167 |
| 168 tracker().SetCurrentSurfaceId(parent_id); |
| 169 tracker().EmbedSurface(embedded_id); |
| 170 tracker().SendAddSurfaceReferences(&frame_sink()); |
| 171 EXPECT_THAT(frame_sink().added(), ElementsAre(reference)); |
| 172 EXPECT_THAT(references_to_remove(), IsEmpty()); |
| 173 |
| 174 // Unembed the surface. The reference should be in the list to remove. |
| 175 tracker().UnembedSurface(embedded_id.frame_sink_id()); |
| 176 EXPECT_THAT(references_to_remove(), ElementsAre(reference)); |
| 177 |
| 178 // Perform remove, the list to remove should be empty and |
| 179 // MojoCompositorFrameSink should have been called with surfaces to remove. |
| 180 tracker().SendRemoveSurfaceReferences(&frame_sink()); |
| 181 EXPECT_THAT(references_to_remove(), IsEmpty()); |
| 182 EXPECT_THAT(frame_sink().removed(), ElementsAre(reference)); |
| 183 } |
| 184 |
| 185 TEST_F(EmbeddedSurfaceTrackerTest, EmbedSurfaceBeforeSetClientSurfaceId) { |
| 186 const cc::SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1); |
| 187 const cc::SurfaceId embedded_id = MakeSurfaceId(kEmbeddedFrameSink, 1); |
| 188 const cc::SurfaceReference reference(parent_id, embedded_id); |
| 189 |
| 190 // Embed a surface before the parent id is set. There should be no references |
| 191 // to add because we don't know the parent id yet. |
| 192 tracker().EmbedSurface(embedded_id); |
| 193 EXPECT_THAT(references_to_add(), IsEmpty()); |
| 194 |
| 195 // Set the parent id, this should add a reference to add to the embedded |
| 196 // surface. |
| 197 tracker().SetCurrentSurfaceId(parent_id); |
| 198 EXPECT_THAT(references_to_add(), ElementsAre(reference)); |
| 199 } |
| 200 |
| 201 TEST_F(EmbeddedSurfaceTrackerTest, UpdateCurrentSurfaceId) { |
| 202 const cc::SurfaceId parent_id_first = MakeSurfaceId(kParentFrameSink, 1); |
| 203 const cc::SurfaceId parent_id_second = MakeSurfaceId(kParentFrameSink, 1); |
| 204 const cc::SurfaceId embedded_id = MakeSurfaceId(kEmbeddedFrameSink, 1); |
| 205 const cc::SurfaceReference reference(parent_id_second, embedded_id); |
| 206 |
| 207 // Set parent id and embed a surface. |
| 208 tracker().SetCurrentSurfaceId(parent_id_first); |
| 209 tracker().EmbedSurface(embedded_id); |
| 210 tracker().SendAddSurfaceReferences(&frame_sink()); |
| 211 |
| 212 // Update the current parent id. There should be a reference to add from the |
| 213 // new parent id to the embedded surface. |
| 214 tracker().SetCurrentSurfaceId(parent_id_second); |
| 215 EXPECT_THAT(references_to_add(), ElementsAre(reference)); |
| 216 } |
| 217 |
| 218 TEST_F(EmbeddedSurfaceTrackerTest, UpdateCurrentSurfaceIdBeforeAdding) { |
| 219 const cc::SurfaceId parent_id_first = MakeSurfaceId(kParentFrameSink, 1); |
| 220 const cc::SurfaceId parent_id_second = MakeSurfaceId(kParentFrameSink, 1); |
| 221 const cc::SurfaceId embedded_id = MakeSurfaceId(kEmbeddedFrameSink, 1); |
| 222 const cc::SurfaceReference reference_first(parent_id_first, embedded_id); |
| 223 const cc::SurfaceReference reference_second(parent_id_second, embedded_id); |
| 224 |
| 225 // Set parent id and embed a surface. There should be a reference to add from |
| 226 // the parent to embedded surface. |
| 227 tracker().SetCurrentSurfaceId(parent_id_first); |
| 228 tracker().EmbedSurface(embedded_id); |
| 229 EXPECT_THAT(references_to_add(), ElementsAre(reference_first)); |
| 230 |
| 231 // Update the parent id before sending IPC to add references. There should be |
| 232 // a reference to add from the new parent id to the embedded surface and the |
| 233 // previous reference to add was deleted. |
| 234 tracker().SetCurrentSurfaceId(parent_id_second); |
| 235 EXPECT_THAT(references_to_add(), ElementsAre(reference_second)); |
| 236 } |
| 237 |
| 238 } // namespace test |
| 239 } // namespace ui |
OLD | NEW |