| 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 <unordered_map> | 7 #include <unordered_map> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| 11 #include "cc/surfaces/compositor_frame_sink_support.h" |
| 11 #include "cc/surfaces/surface.h" | 12 #include "cc/surfaces/surface.h" |
| 12 #include "cc/surfaces/surface_factory.h" | |
| 13 #include "cc/surfaces/surface_factory_client.h" | |
| 14 #include "cc/surfaces/surface_id.h" | 13 #include "cc/surfaces/surface_id.h" |
| 15 #include "cc/surfaces/surface_manager.h" | 14 #include "cc/surfaces/surface_manager.h" |
| 16 #include "testing/gmock/include/gmock/gmock.h" | 15 #include "testing/gmock/include/gmock/gmock.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 18 | 17 |
| 19 using testing::ElementsAre; | 18 using testing::ElementsAre; |
| 20 using testing::IsEmpty; | 19 using testing::IsEmpty; |
| 21 using testing::SizeIs; | 20 using testing::SizeIs; |
| 22 using testing::UnorderedElementsAre; | 21 using testing::UnorderedElementsAre; |
| 23 | 22 |
| 24 namespace cc { | 23 namespace cc { |
| 25 | 24 |
| 26 namespace { | 25 namespace { |
| 27 | 26 |
| 28 constexpr FrameSinkId kFrameSink1(1, 0); | 27 constexpr FrameSinkId kFrameSink1(1, 0); |
| 29 constexpr FrameSinkId kFrameSink2(2, 0); | 28 constexpr FrameSinkId kFrameSink2(2, 0); |
| 30 constexpr FrameSinkId kFrameSink3(3, 0); | 29 constexpr FrameSinkId kFrameSink3(3, 0); |
| 31 | 30 |
| 32 class StubSurfaceFactoryClient : public SurfaceFactoryClient { | |
| 33 public: | |
| 34 void ReturnResources(const ReturnedResourceArray& resources) override {} | |
| 35 void SetBeginFrameSource(BeginFrameSource* begin_frame_source) override {} | |
| 36 }; | |
| 37 | |
| 38 } // namespace | 31 } // namespace |
| 39 | 32 |
| 40 // Tests for reference tracking in SurfaceManager. | 33 // Tests for reference tracking in SurfaceManager. |
| 41 class SurfaceManagerRefTest : public testing::Test { | 34 class SurfaceManagerRefTest : public testing::Test { |
| 42 public: | 35 public: |
| 43 SurfaceManager& manager() { return *manager_; } | 36 SurfaceManager& manager() { return *manager_; } |
| 44 | 37 |
| 45 // Creates a new Surface with the provided |frame_sink_id| and |local_id|. | 38 // Creates a new Surface with the provided |frame_sink_id| and |local_id|. |
| 46 // Will first create a SurfaceFactory for |frame_sink_id| if necessary. | 39 // Will first create a Surfacesupport for |frame_sink_id| if necessary. |
| 47 SurfaceId CreateSurface(const FrameSinkId& frame_sink_id, uint32_t local_id) { | 40 SurfaceId CreateSurface(const FrameSinkId& frame_sink_id, uint32_t local_id) { |
| 48 LocalSurfaceId local_surface_id(local_id, | 41 LocalSurfaceId local_surface_id(local_id, |
| 49 base::UnguessableToken::Deserialize(0, 1u)); | 42 base::UnguessableToken::Deserialize(0, 1u)); |
| 50 GetFactory(frame_sink_id) | 43 GetCompositorFrameSinkSupport(frame_sink_id) |
| 51 .SubmitCompositorFrame(local_surface_id, CompositorFrame(), | 44 .SubmitCompositorFrame(local_surface_id, CompositorFrame()); |
| 52 SurfaceFactory::DrawCallback()); | |
| 53 return SurfaceId(frame_sink_id, local_surface_id); | 45 return SurfaceId(frame_sink_id, local_surface_id); |
| 54 } | 46 } |
| 55 | 47 |
| 56 // Destroy Surface with |surface_id|. | 48 // Destroy Surface with |surface_id|. |
| 57 void DestroySurface(const SurfaceId& surface_id) { | 49 void DestroySurface(const SurfaceId& surface_id) { |
| 58 GetFactory(surface_id.frame_sink_id()).EvictSurface(); | 50 GetCompositorFrameSinkSupport(surface_id.frame_sink_id()).EvictFrame(); |
| 59 } | 51 } |
| 60 | 52 |
| 61 SurfaceFactory& GetFactory(const FrameSinkId& frame_sink_id) { | 53 CompositorFrameSinkSupport& GetCompositorFrameSinkSupport( |
| 62 auto& factory_ptr = factories_[frame_sink_id]; | 54 const FrameSinkId& frame_sink_id) { |
| 63 if (!factory_ptr) | 55 auto& support_ptr = supports_[frame_sink_id]; |
| 64 factory_ptr = base::MakeUnique<SurfaceFactory>(frame_sink_id, | 56 if (!support_ptr) { |
| 65 manager_.get(), &client_); | 57 constexpr bool is_root = false; |
| 66 return *factory_ptr; | 58 constexpr bool handles_frame_sink_id_invalidation = true; |
| 59 constexpr bool needs_sync_points = true; |
| 60 support_ptr = CompositorFrameSinkSupport::Create( |
| 61 nullptr, manager_.get(), frame_sink_id, is_root, |
| 62 handles_frame_sink_id_invalidation, needs_sync_points); |
| 63 } |
| 64 return *support_ptr; |
| 65 } |
| 66 |
| 67 void DestroyCompositorFrameSinkSupport(const FrameSinkId& frame_sink_id) { |
| 68 auto support_ptr = supports_.find(frame_sink_id); |
| 69 ASSERT_NE(support_ptr, supports_.end()); |
| 70 supports_.erase(support_ptr); |
| 67 } | 71 } |
| 68 | 72 |
| 69 void RemoveSurfaceReference(const SurfaceId& parent_id, | 73 void RemoveSurfaceReference(const SurfaceId& parent_id, |
| 70 const SurfaceId& child_id) { | 74 const SurfaceId& child_id) { |
| 71 manager_->RemoveSurfaceReferences({SurfaceReference(parent_id, child_id)}); | 75 manager_->RemoveSurfaceReferences({SurfaceReference(parent_id, child_id)}); |
| 72 } | 76 } |
| 73 | 77 |
| 74 void AddSurfaceReference(const SurfaceId& parent_id, | 78 void AddSurfaceReference(const SurfaceId& parent_id, |
| 75 const SurfaceId& child_id) { | 79 const SurfaceId& child_id) { |
| 76 manager_->AddSurfaceReferences({SurfaceReference(parent_id, child_id)}); | 80 manager_->AddSurfaceReferences({SurfaceReference(parent_id, child_id)}); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 98 } | 102 } |
| 99 | 103 |
| 100 protected: | 104 protected: |
| 101 // testing::Test: | 105 // testing::Test: |
| 102 void SetUp() override { | 106 void SetUp() override { |
| 103 // Start each test with a fresh SurfaceManager instance. | 107 // Start each test with a fresh SurfaceManager instance. |
| 104 manager_ = base::MakeUnique<SurfaceManager>( | 108 manager_ = base::MakeUnique<SurfaceManager>( |
| 105 SurfaceManager::LifetimeType::REFERENCES); | 109 SurfaceManager::LifetimeType::REFERENCES); |
| 106 } | 110 } |
| 107 void TearDown() override { | 111 void TearDown() override { |
| 108 for (auto& factory : factories_) | 112 for (auto& support : supports_) |
| 109 factory.second->EvictSurface(); | 113 support.second->EvictFrame(); |
| 110 factories_.clear(); | 114 supports_.clear(); |
| 111 manager_.reset(); | 115 manager_.reset(); |
| 112 } | 116 } |
| 113 | 117 |
| 114 std::unordered_map<FrameSinkId, | 118 std::unordered_map<FrameSinkId, |
| 115 std::unique_ptr<SurfaceFactory>, | 119 std::unique_ptr<CompositorFrameSinkSupport>, |
| 116 FrameSinkIdHash> | 120 FrameSinkIdHash> |
| 117 factories_; | 121 supports_; |
| 118 std::unique_ptr<SurfaceManager> manager_; | 122 std::unique_ptr<SurfaceManager> manager_; |
| 119 StubSurfaceFactoryClient client_; | |
| 120 }; | 123 }; |
| 121 | 124 |
| 122 TEST_F(SurfaceManagerRefTest, AddReference) { | 125 TEST_F(SurfaceManagerRefTest, AddReference) { |
| 123 SurfaceId id1 = CreateSurface(kFrameSink1, 1); | 126 SurfaceId id1 = CreateSurface(kFrameSink1, 1); |
| 124 AddSurfaceReference(manager().GetRootSurfaceId(), id1); | 127 AddSurfaceReference(manager().GetRootSurfaceId(), id1); |
| 125 | 128 |
| 126 EXPECT_THAT(GetReferencesFor(id1), | 129 EXPECT_THAT(GetReferencesFor(id1), |
| 127 UnorderedElementsAre(manager().GetRootSurfaceId())); | 130 UnorderedElementsAre(manager().GetRootSurfaceId())); |
| 128 EXPECT_THAT(GetReferencesFrom(id1), IsEmpty()); | 131 EXPECT_THAT(GetReferencesFrom(id1), IsEmpty()); |
| 129 } | 132 } |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 457 manager().AssignTemporaryReference(id1, kFrameSink1); | 460 manager().AssignTemporaryReference(id1, kFrameSink1); |
| 458 ASSERT_THAT(GetAllTempReferences(), UnorderedElementsAre(id1)); | 461 ASSERT_THAT(GetAllTempReferences(), UnorderedElementsAre(id1)); |
| 459 | 462 |
| 460 // Adding a real surface reference will remove the temporary reference. | 463 // Adding a real surface reference will remove the temporary reference. |
| 461 AddSurfaceReference(parent_id, id1); | 464 AddSurfaceReference(parent_id, id1); |
| 462 ASSERT_THAT(GetAllTempReferences(), IsEmpty()); | 465 ASSERT_THAT(GetAllTempReferences(), IsEmpty()); |
| 463 ASSERT_THAT(GetReferencesFor(id1), UnorderedElementsAre(parent_id)); | 466 ASSERT_THAT(GetReferencesFor(id1), UnorderedElementsAre(parent_id)); |
| 464 | 467 |
| 465 // When |kFrameSink1| is invalidated it shouldn't change the surface | 468 // When |kFrameSink1| is invalidated it shouldn't change the surface |
| 466 // references. | 469 // references. |
| 467 manager().InvalidateFrameSinkId(kFrameSink1); | 470 DestroyCompositorFrameSinkSupport(kFrameSink1); |
| 468 ASSERT_THAT(GetReferencesFor(id1), UnorderedElementsAre(parent_id)); | 471 ASSERT_THAT(GetReferencesFor(id1), UnorderedElementsAre(parent_id)); |
| 469 } | 472 } |
| 470 | 473 |
| 471 TEST_F(SurfaceManagerRefTest, CheckDropTemporaryReferenceWorks) { | 474 TEST_F(SurfaceManagerRefTest, CheckDropTemporaryReferenceWorks) { |
| 472 const SurfaceId id1 = CreateSurface(kFrameSink1, 1); | 475 const SurfaceId id1 = CreateSurface(kFrameSink1, 1); |
| 473 ASSERT_THAT(GetAllTempReferences(), UnorderedElementsAre(id1)); | 476 ASSERT_THAT(GetAllTempReferences(), UnorderedElementsAre(id1)); |
| 474 | 477 |
| 475 // An example of why this could happen is the window server doesn't know the | 478 // An example of why this could happen is the window server doesn't know the |
| 476 // owner, maybe it has crashed and been cleanup already, and asks to drop the | 479 // owner, maybe it has crashed and been cleanup already, and asks to drop the |
| 477 // temporary reference. | 480 // temporary reference. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 492 ASSERT_THAT(GetAllTempReferences(), UnorderedElementsAre(id1a, id1b)); | 495 ASSERT_THAT(GetAllTempReferences(), UnorderedElementsAre(id1a, id1b)); |
| 493 | 496 |
| 494 // Assign |id1a| to |kFrameSink1|. This doesn't change the temporary | 497 // Assign |id1a| to |kFrameSink1|. This doesn't change the temporary |
| 495 // reference, it just assigns as owner to it. | 498 // reference, it just assigns as owner to it. |
| 496 manager().AssignTemporaryReference(id1a, kFrameSink1); | 499 manager().AssignTemporaryReference(id1a, kFrameSink1); |
| 497 ASSERT_THAT(GetAllTempReferences(), UnorderedElementsAre(id1a, id1b)); | 500 ASSERT_THAT(GetAllTempReferences(), UnorderedElementsAre(id1a, id1b)); |
| 498 | 501 |
| 499 // If the parent client crashes then the CompositorFrameSink connection will | 502 // If the parent client crashes then the CompositorFrameSink connection will |
| 500 // be closed and the FrameSinkId invalidated. The temporary reference | 503 // be closed and the FrameSinkId invalidated. The temporary reference |
| 501 // |kFrameSink1| owns to |id2a| will be removed. | 504 // |kFrameSink1| owns to |id2a| will be removed. |
| 502 manager().InvalidateFrameSinkId(kFrameSink1); | 505 DestroyCompositorFrameSinkSupport(kFrameSink1); |
| 503 ASSERT_THAT(GetAllTempReferences(), UnorderedElementsAre(id1b)); | 506 ASSERT_THAT(GetAllTempReferences(), UnorderedElementsAre(id1b)); |
| 504 | 507 |
| 505 // If the parent has crashed then the window server will have already removed | 508 // If the parent has crashed then the window server will have already removed |
| 506 // it from the ServerWindow hierarchy and won't have an owner for |id2b|. The | 509 // it from the ServerWindow hierarchy and won't have an owner for |id2b|. The |
| 507 // window server will ask to drop the reference instead. | 510 // window server will ask to drop the reference instead. |
| 508 manager().DropTemporaryReference(id1b); | 511 manager().DropTemporaryReference(id1b); |
| 509 ASSERT_THAT(GetAllTempReferences(), IsEmpty()); | 512 ASSERT_THAT(GetAllTempReferences(), IsEmpty()); |
| 510 } | 513 } |
| 511 | 514 |
| 512 } // namespace cc | 515 } // namespace cc |
| OLD | NEW |