| Index: cc/surfaces/surface_manager_unittest.cc
|
| diff --git a/cc/surfaces/surface_manager_unittest.cc b/cc/surfaces/surface_manager_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..03686a841a60be5bc33a38a668ca00afc1167b0c
|
| --- /dev/null
|
| +++ b/cc/surfaces/surface_manager_unittest.cc
|
| @@ -0,0 +1,172 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include <stddef.h>
|
| +
|
| +#include "cc/scheduler/begin_frame_source.h"
|
| +#include "cc/surfaces/surface_factory_client.h"
|
| +#include "cc/surfaces/surface_manager.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace cc {
|
| +
|
| +class FakeSurfaceFactoryClient : public SurfaceFactoryClient {
|
| + public:
|
| + explicit FakeSurfaceFactoryClient(int id_namespace)
|
| + : source_(nullptr), manager_(nullptr), id_namespace_(id_namespace) {}
|
| + FakeSurfaceFactoryClient(int id_namespace, SurfaceManager* manager)
|
| + : source_(nullptr), manager_(nullptr), id_namespace_(id_namespace) {
|
| + DCHECK(manager);
|
| + Register(manager);
|
| + }
|
| +
|
| + ~FakeSurfaceFactoryClient() override {
|
| + if (manager_) {
|
| + Unregister();
|
| + }
|
| + EXPECT_EQ(source_, nullptr);
|
| + }
|
| +
|
| + BeginFrameSource* source() { return source_; }
|
| + uint32_t id_namespace() { return id_namespace_; }
|
| +
|
| + void Register(SurfaceManager* manager) {
|
| + EXPECT_EQ(manager_, nullptr);
|
| + manager_ = manager;
|
| + manager_->RegisterSurfaceFactoryClient(id_namespace_, this);
|
| + }
|
| +
|
| + void Unregister() {
|
| + EXPECT_NE(manager_, nullptr);
|
| + manager_->RegisterSurfaceFactoryClient(id_namespace_, nullptr);
|
| + manager_ = nullptr;
|
| + }
|
| +
|
| + // SurfaceFactoryClient implementation.
|
| + void ReturnResources(const ReturnedResourceArray& resources) override{};
|
| + void SetBeginFrameSource(BeginFrameSource* begin_frame_source) override {
|
| + DCHECK(!source_ || !begin_frame_source);
|
| + source_ = begin_frame_source;
|
| + };
|
| +
|
| + private:
|
| + BeginFrameSource* source_;
|
| + SurfaceManager* manager_;
|
| + uint32_t id_namespace_;
|
| +};
|
| +
|
| +class EmptyBeginFrameSource : public BeginFrameSource {
|
| + public:
|
| + void DidFinishFrame(size_t remaining_frames) override{};
|
| + void AddObserver(BeginFrameObserver* obs) override{};
|
| + void RemoveObserver(BeginFrameObserver* obs) override{};
|
| + void SetClientReady() override {}
|
| + void AsValueInto(base::trace_event::TracedValue* dict) const override{};
|
| +};
|
| +
|
| +TEST(SurfaceManagerTest, SingleClients) {
|
| + SurfaceManager manager;
|
| + FakeSurfaceFactoryClient client(1);
|
| + FakeSurfaceFactoryClient other_client(2);
|
| + EmptyBeginFrameSource source;
|
| +
|
| + EXPECT_EQ(client.source(), nullptr);
|
| + EXPECT_EQ(other_client.source(), nullptr);
|
| + client.Register(&manager);
|
| + other_client.Register(&manager);
|
| + EXPECT_EQ(client.source(), nullptr);
|
| + EXPECT_EQ(other_client.source(), nullptr);
|
| +
|
| + // Test setting unsetting BFS
|
| + manager.RegisterBeginFrameSource(&source, client.id_namespace());
|
| + EXPECT_EQ(client.source(), &source);
|
| + EXPECT_EQ(other_client.source(), nullptr);
|
| + manager.UnregisterBeginFrameSource(&source);
|
| + EXPECT_EQ(client.source(), nullptr);
|
| + EXPECT_EQ(other_client.source(), nullptr);
|
| +
|
| + // Set BFS for other namespace
|
| + manager.RegisterBeginFrameSource(&source, other_client.id_namespace());
|
| + EXPECT_EQ(other_client.source(), &source);
|
| + EXPECT_EQ(client.source(), nullptr);
|
| + manager.UnregisterBeginFrameSource(&source);
|
| + EXPECT_EQ(client.source(), nullptr);
|
| + EXPECT_EQ(other_client.source(), nullptr);
|
| +
|
| + // Re-set BFS for original
|
| + manager.RegisterBeginFrameSource(&source, client.id_namespace());
|
| + EXPECT_EQ(client.source(), &source);
|
| + manager.UnregisterBeginFrameSource(&source);
|
| + EXPECT_EQ(client.source(), nullptr);
|
| +}
|
| +
|
| +TEST(SurfaceManagerTest, MultipleDisplays) {
|
| + SurfaceManager manager;
|
| + EmptyBeginFrameSource root1_source;
|
| + EmptyBeginFrameSource root2_source;
|
| +
|
| + // root1 -> A -> B
|
| + // root2 -> C
|
| + FakeSurfaceFactoryClient root1(1, &manager);
|
| + FakeSurfaceFactoryClient root2(2, &manager);
|
| + FakeSurfaceFactoryClient client_a(3, &manager);
|
| + FakeSurfaceFactoryClient client_b(4, &manager);
|
| + FakeSurfaceFactoryClient client_c(5, &manager);
|
| +
|
| + manager.RegisterBeginFrameSource(&root1_source, root1.id_namespace());
|
| + manager.RegisterBeginFrameSource(&root2_source, root2.id_namespace());
|
| + EXPECT_EQ(root1.source(), &root1_source);
|
| + EXPECT_EQ(root2.source(), &root2_source);
|
| +
|
| + // Set up initial hierarchy.
|
| + manager.RegisterSurfaceNamespaceHierarchy(root1.id_namespace(),
|
| + client_a.id_namespace());
|
| + EXPECT_EQ(client_a.source(), root1.source());
|
| + manager.RegisterSurfaceNamespaceHierarchy(client_a.id_namespace(),
|
| + client_b.id_namespace());
|
| + EXPECT_EQ(client_b.source(), root1.source());
|
| + manager.RegisterSurfaceNamespaceHierarchy(root2.id_namespace(),
|
| + client_c.id_namespace());
|
| + EXPECT_EQ(client_c.source(), root2.source());
|
| +
|
| + // Attach A into root2's subtree, like a window moving across displays.
|
| + // root1 -> A -> B
|
| + // root2 -> C -> A -> B
|
| + manager.RegisterSurfaceNamespaceHierarchy(client_c.id_namespace(),
|
| + client_a.id_namespace());
|
| + // With the heuristic of just keeping existing BFS in the face of multiple,
|
| + // no client sources should change.
|
| + EXPECT_EQ(client_a.source(), root1.source());
|
| + EXPECT_EQ(client_b.source(), root1.source());
|
| + EXPECT_EQ(client_c.source(), root2.source());
|
| +
|
| + // Detach A from root1. A and B should now be updated to root2.
|
| + manager.UnregisterSurfaceNamespaceHierarchy(root1.id_namespace(),
|
| + client_a.id_namespace());
|
| + EXPECT_EQ(client_a.source(), root2.source());
|
| + EXPECT_EQ(client_b.source(), root2.source());
|
| + EXPECT_EQ(client_c.source(), root2.source());
|
| +
|
| + // Detach root1 from BFS. root1 should now have no source.
|
| + manager.UnregisterBeginFrameSource(&root1_source);
|
| + EXPECT_EQ(root1.source(), nullptr);
|
| + EXPECT_NE(root2.source(), nullptr);
|
| +
|
| + // Detatch root2 from BFS.
|
| + manager.UnregisterBeginFrameSource(&root2_source);
|
| + EXPECT_EQ(client_a.source(), nullptr);
|
| + EXPECT_EQ(client_b.source(), nullptr);
|
| + EXPECT_EQ(client_c.source(), nullptr);
|
| + EXPECT_EQ(root2.source(), nullptr);
|
| +
|
| + // Cleanup hierarchy.
|
| + manager.UnregisterSurfaceNamespaceHierarchy(root2.id_namespace(),
|
| + client_c.id_namespace());
|
| + manager.UnregisterSurfaceNamespaceHierarchy(client_c.id_namespace(),
|
| + client_a.id_namespace());
|
| + manager.UnregisterSurfaceNamespaceHierarchy(client_a.id_namespace(),
|
| + client_b.id_namespace());
|
| +}
|
| +
|
| +} // namespace cc
|
|
|