| Index: cc/surfaces/surface_unittest.cc
|
| diff --git a/cc/surfaces/surface_unittest.cc b/cc/surfaces/surface_unittest.cc
|
| index dc6dc2dee90556bd39d69f88154bc70219bf6558..f5e7624f7f85c4121e33e4d69cbafacd27393799 100644
|
| --- a/cc/surfaces/surface_unittest.cc
|
| +++ b/cc/surfaces/surface_unittest.cc
|
| @@ -3,10 +3,14 @@
|
| // found in the LICENSE file.
|
|
|
| #include "cc/surfaces/surface.h"
|
| +#include "base/memory/ptr_util.h"
|
| +#include "cc/surfaces/surface_dependency_tracker.h"
|
| #include "cc/surfaces/surface_factory.h"
|
| #include "cc/surfaces/surface_factory_client.h"
|
| #include "cc/surfaces/surface_id_allocator.h"
|
| #include "cc/surfaces/surface_manager.h"
|
| +#include "cc/test/begin_frame_args_test.h"
|
| +#include "cc/test/fake_external_begin_frame_source.h"
|
| #include "cc/test/scheduler_test_common.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| #include "ui/gfx/geometry/size.h"
|
| @@ -16,6 +20,14 @@ namespace {
|
|
|
| static constexpr FrameSinkId kArbitraryFrameSinkId(1, 1);
|
|
|
| +CompositorFrame MakeCompositorFrame(
|
| + std::vector<SurfaceId> referenced_surfaces) {
|
| + CompositorFrame compositor_frame;
|
| + compositor_frame.metadata.referenced_surfaces =
|
| + std::move(referenced_surfaces);
|
| + return compositor_frame;
|
| +}
|
| +
|
| class FakeSurfaceFactoryClient : public SurfaceFactoryClient {
|
| public:
|
| FakeSurfaceFactoryClient() : begin_frame_source_(nullptr) {}
|
| @@ -32,6 +44,309 @@ class FakeSurfaceFactoryClient : public SurfaceFactoryClient {
|
| BeginFrameSource* begin_frame_source_;
|
| };
|
|
|
| +// Surface 1 is blocked on Surface 2 and Surface 3.
|
| +TEST(SurfaceTest, DisplayCompositorLocking1) {
|
| + SurfaceManager manager;
|
| + std::unique_ptr<FakeExternalBeginFrameSource> begin_frame_source(
|
| + new FakeExternalBeginFrameSource(0.f, false));
|
| +
|
| + std::unique_ptr<SurfaceDependencyTracker> dependency_tracker(
|
| + new SurfaceDependencyTracker(&manager, begin_frame_source.get()));
|
| + manager.SetDependencyTracker(std::move(dependency_tracker));
|
| +
|
| + LocalSurfaceId local_surface_id1(6, base::UnguessableToken::Create());
|
| + SurfaceId surface_id1(FrameSinkId(1, 1), local_surface_id1);
|
| +
|
| + LocalSurfaceId local_surface_id2(7, base::UnguessableToken::Create());
|
| + SurfaceId surface_id2(FrameSinkId(2, 2), local_surface_id2);
|
| +
|
| + LocalSurfaceId local_surface_id3(8, base::UnguessableToken::Create());
|
| + SurfaceId surface_id3(FrameSinkId(3, 3), local_surface_id3);
|
| +
|
| + FakeSurfaceFactoryClient surface_factory_client1;
|
| + SurfaceFactory factory1(FrameSinkId(1, 1), &manager,
|
| + &surface_factory_client1);
|
| + factory1.SubmitCompositorFrame(
|
| + local_surface_id1, MakeCompositorFrame({surface_id2, surface_id3}),
|
| + SurfaceFactory::DrawCallback());
|
| + EXPECT_TRUE(manager.dependency_tracker()->has_deadline());
|
| +
|
| + // |factory1| is blocked on |surface_id2| and |surface_id3|.
|
| + EXPECT_FALSE(factory1.current_surface_for_testing()->HasActiveFrame());
|
| + EXPECT_TRUE(factory1.current_surface_for_testing()->HasPendingFrame());
|
| +
|
| + FakeSurfaceFactoryClient surface_factory_client2;
|
| + SurfaceFactory factory2(FrameSinkId(2, 2), &manager,
|
| + &surface_factory_client2);
|
| + factory2.SubmitCompositorFrame(local_surface_id2,
|
| + MakeCompositorFrame(std::vector<SurfaceId>()),
|
| + SurfaceFactory::DrawCallback());
|
| +
|
| + EXPECT_TRUE(manager.dependency_tracker()->has_deadline());
|
| + EXPECT_TRUE(factory2.current_surface_for_testing()->HasActiveFrame());
|
| + EXPECT_FALSE(factory2.current_surface_for_testing()->HasPendingFrame());
|
| +
|
| + // |factory1| is blocked on just |surface_id3|.
|
| + EXPECT_FALSE(factory1.current_surface_for_testing()->HasActiveFrame());
|
| + EXPECT_TRUE(factory1.current_surface_for_testing()->HasPendingFrame());
|
| +
|
| + FakeSurfaceFactoryClient surface_factory_client3;
|
| + SurfaceFactory factory3(FrameSinkId(3, 3), &manager,
|
| + &surface_factory_client3);
|
| + factory3.SubmitCompositorFrame(local_surface_id3,
|
| + MakeCompositorFrame(std::vector<SurfaceId>()),
|
| + SurfaceFactory::DrawCallback());
|
| + EXPECT_FALSE(manager.dependency_tracker()->has_deadline());
|
| +
|
| + // |factory1|'s Frame is now active.
|
| + EXPECT_TRUE(factory1.current_surface_for_testing()->HasActiveFrame());
|
| + EXPECT_FALSE(factory1.current_surface_for_testing()->HasPendingFrame());
|
| +
|
| + factory1.EvictSurface();
|
| + factory2.EvictSurface();
|
| + factory3.EvictSurface();
|
| +}
|
| +
|
| +// Surface 1 is blocked on Surface 2 which is blocked on Surface 3.
|
| +TEST(SurfaceTest, DisplayCompositorLocking2) {
|
| + SurfaceManager manager;
|
| + std::unique_ptr<FakeExternalBeginFrameSource> begin_frame_source(
|
| + new FakeExternalBeginFrameSource(0.f, false));
|
| +
|
| + std::unique_ptr<SurfaceDependencyTracker> dependency_tracker(
|
| + new SurfaceDependencyTracker(&manager, begin_frame_source.get()));
|
| + manager.SetDependencyTracker(std::move(dependency_tracker));
|
| +
|
| + LocalSurfaceId local_surface_id1(6, base::UnguessableToken::Create());
|
| + SurfaceId surface_id1(FrameSinkId(1, 1), local_surface_id1);
|
| +
|
| + LocalSurfaceId local_surface_id2(7, base::UnguessableToken::Create());
|
| + SurfaceId surface_id2(FrameSinkId(2, 2), local_surface_id2);
|
| +
|
| + LocalSurfaceId local_surface_id3(8, base::UnguessableToken::Create());
|
| + SurfaceId surface_id3(FrameSinkId(3, 3), local_surface_id3);
|
| +
|
| + FakeSurfaceFactoryClient surface_factory_client1;
|
| + SurfaceFactory factory1(FrameSinkId(1, 1), &manager,
|
| + &surface_factory_client1);
|
| + factory1.SubmitCompositorFrame(local_surface_id1,
|
| + MakeCompositorFrame({surface_id2}),
|
| + SurfaceFactory::DrawCallback());
|
| +
|
| + // |factory1| is blocked on |surface_id2|.
|
| + EXPECT_FALSE(factory1.current_surface_for_testing()->HasActiveFrame());
|
| + EXPECT_TRUE(factory1.current_surface_for_testing()->HasPendingFrame());
|
| +
|
| + FakeSurfaceFactoryClient surface_factory_client2;
|
| + SurfaceFactory factory2(FrameSinkId(2, 2), &manager,
|
| + &surface_factory_client2);
|
| + factory2.SubmitCompositorFrame(local_surface_id2,
|
| + MakeCompositorFrame({surface_id3}),
|
| + SurfaceFactory::DrawCallback());
|
| +
|
| + // |factory2| is blocked on |surface_id3|.
|
| + EXPECT_FALSE(factory2.current_surface_for_testing()->HasActiveFrame());
|
| + EXPECT_TRUE(factory2.current_surface_for_testing()->HasPendingFrame());
|
| +
|
| + // |factory1| is still blocked on just |surface_id2|.
|
| + EXPECT_FALSE(factory1.current_surface_for_testing()->HasActiveFrame());
|
| + EXPECT_TRUE(factory1.current_surface_for_testing()->HasPendingFrame());
|
| +
|
| + FakeSurfaceFactoryClient surface_factory_client3;
|
| + SurfaceFactory factory3(FrameSinkId(3, 3), &manager,
|
| + &surface_factory_client3);
|
| + CompositorFrame frame3;
|
| + factory3.SubmitCompositorFrame(local_surface_id3,
|
| + MakeCompositorFrame(std::vector<SurfaceId>()),
|
| + SurfaceFactory::DrawCallback());
|
| +
|
| + // |factory1|'s Frame is now active.
|
| + EXPECT_TRUE(factory1.current_surface_for_testing()->HasActiveFrame());
|
| + EXPECT_FALSE(factory1.current_surface_for_testing()->HasPendingFrame());
|
| +
|
| + // |factory2|'s Frame is now active.
|
| + EXPECT_TRUE(factory2.current_surface_for_testing()->HasActiveFrame());
|
| + EXPECT_FALSE(factory2.current_surface_for_testing()->HasPendingFrame());
|
| +
|
| + factory1.EvictSurface();
|
| + factory2.EvictSurface();
|
| + factory3.EvictSurface();
|
| +}
|
| +
|
| +// Surface 1 and Surface 2 are blocked on Surface 3.
|
| +TEST(SurfaceTest, DisplayCompositorLocking3) {
|
| + SurfaceManager manager;
|
| + std::unique_ptr<FakeExternalBeginFrameSource> begin_frame_source(
|
| + new FakeExternalBeginFrameSource(0.f, false));
|
| +
|
| + std::unique_ptr<SurfaceDependencyTracker> dependency_tracker(
|
| + new SurfaceDependencyTracker(&manager, begin_frame_source.get()));
|
| + manager.SetDependencyTracker(std::move(dependency_tracker));
|
| +
|
| + LocalSurfaceId local_surface_id1(6, base::UnguessableToken::Create());
|
| + SurfaceId surface_id1(FrameSinkId(1, 1), local_surface_id1);
|
| +
|
| + LocalSurfaceId local_surface_id2(7, base::UnguessableToken::Create());
|
| + SurfaceId surface_id2(FrameSinkId(2, 2), local_surface_id2);
|
| +
|
| + LocalSurfaceId local_surface_id3(8, base::UnguessableToken::Create());
|
| + SurfaceId surface_id3(FrameSinkId(3, 3), local_surface_id3);
|
| +
|
| + FakeSurfaceFactoryClient surface_factory_client1;
|
| + SurfaceFactory factory1(FrameSinkId(1, 1), &manager,
|
| + &surface_factory_client1);
|
| + factory1.SubmitCompositorFrame(local_surface_id1,
|
| + MakeCompositorFrame({surface_id3}),
|
| + SurfaceFactory::DrawCallback());
|
| +
|
| + // |factory1| is blocked on |surface_id3|.
|
| + EXPECT_FALSE(factory1.current_surface_for_testing()->HasActiveFrame());
|
| + EXPECT_TRUE(factory1.current_surface_for_testing()->HasPendingFrame());
|
| +
|
| + FakeSurfaceFactoryClient surface_factory_client2;
|
| + SurfaceFactory factory2(FrameSinkId(2, 2), &manager,
|
| + &surface_factory_client2);
|
| + factory2.SubmitCompositorFrame(local_surface_id2,
|
| + MakeCompositorFrame({surface_id3}),
|
| + SurfaceFactory::DrawCallback());
|
| +
|
| + // |factory2| is blocked on |surface_id3|.
|
| + EXPECT_FALSE(factory2.current_surface_for_testing()->HasActiveFrame());
|
| + EXPECT_TRUE(factory2.current_surface_for_testing()->HasPendingFrame());
|
| +
|
| + // |factory1| is still blocked on |surface_id3|.
|
| + EXPECT_FALSE(factory1.current_surface_for_testing()->HasActiveFrame());
|
| + EXPECT_TRUE(factory1.current_surface_for_testing()->HasPendingFrame());
|
| +
|
| + FakeSurfaceFactoryClient surface_factory_client3;
|
| + SurfaceFactory factory3(FrameSinkId(3, 3), &manager,
|
| + &surface_factory_client3);
|
| + factory3.SubmitCompositorFrame(local_surface_id3,
|
| + MakeCompositorFrame(std::vector<SurfaceId>()),
|
| + SurfaceFactory::DrawCallback());
|
| +
|
| + // |factory1|'s Frame is now active.
|
| + EXPECT_TRUE(factory1.current_surface_for_testing()->HasActiveFrame());
|
| + EXPECT_FALSE(factory1.current_surface_for_testing()->HasPendingFrame());
|
| +
|
| + // |factory2|'s Frame is now active.
|
| + EXPECT_TRUE(factory2.current_surface_for_testing()->HasActiveFrame());
|
| + EXPECT_FALSE(factory2.current_surface_for_testing()->HasPendingFrame());
|
| +
|
| + factory1.EvictSurface();
|
| + factory2.EvictSurface();
|
| + factory3.EvictSurface();
|
| +}
|
| +
|
| +// |factory1| is blocked on |surface_id2| but the deadline hits.
|
| +TEST(SurfaceTest, DisplayCompositorLocking4) {
|
| + SurfaceManager manager;
|
| + std::unique_ptr<FakeExternalBeginFrameSource> begin_frame_source(
|
| + new FakeExternalBeginFrameSource(0.f, false));
|
| +
|
| + std::unique_ptr<SurfaceDependencyTracker> dependency_tracker(
|
| + new SurfaceDependencyTracker(&manager, begin_frame_source.get()));
|
| + manager.SetDependencyTracker(std::move(dependency_tracker));
|
| +
|
| + LocalSurfaceId local_surface_id1(6, base::UnguessableToken::Create());
|
| + SurfaceId surface_id1(FrameSinkId(1, 1), local_surface_id1);
|
| +
|
| + LocalSurfaceId local_surface_id2(7, base::UnguessableToken::Create());
|
| + SurfaceId surface_id2(FrameSinkId(2, 2), local_surface_id2);
|
| +
|
| + LocalSurfaceId local_surface_id3(8, base::UnguessableToken::Create());
|
| + SurfaceId surface_id3(FrameSinkId(3, 3), local_surface_id3);
|
| +
|
| + FakeSurfaceFactoryClient surface_factory_client1;
|
| + SurfaceFactory factory1(FrameSinkId(1, 1), &manager,
|
| + &surface_factory_client1);
|
| + CompositorFrame frame;
|
| + factory1.SubmitCompositorFrame(local_surface_id1,
|
| + MakeCompositorFrame({surface_id2}),
|
| + SurfaceFactory::DrawCallback());
|
| + EXPECT_TRUE(manager.dependency_tracker()->has_deadline());
|
| +
|
| + // |factory1| is blocked on |surface_id2|.
|
| + EXPECT_FALSE(factory1.current_surface_for_testing()->HasActiveFrame());
|
| + EXPECT_TRUE(factory1.current_surface_for_testing()->HasPendingFrame());
|
| +
|
| + FakeSurfaceFactoryClient surface_factory_client2;
|
| + SurfaceFactory factory2(FrameSinkId(2, 2), &manager,
|
| + &surface_factory_client2);
|
| + factory2.SubmitCompositorFrame(local_surface_id2,
|
| + MakeCompositorFrame({surface_id3}),
|
| + SurfaceFactory::DrawCallback());
|
| + EXPECT_TRUE(manager.dependency_tracker()->has_deadline());
|
| +
|
| + // |factory2| is blocked on |surface_id3|.
|
| + EXPECT_FALSE(factory2.current_surface_for_testing()->HasActiveFrame());
|
| + EXPECT_TRUE(factory2.current_surface_for_testing()->HasPendingFrame());
|
| +
|
| + BeginFrameArgs args =
|
| + CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 1);
|
| + begin_frame_source->TestOnBeginFrame(args);
|
| +
|
| + // |factory1| is still blocked on |surface_id2|.
|
| + EXPECT_FALSE(factory1.current_surface_for_testing()->HasActiveFrame());
|
| + EXPECT_TRUE(factory1.current_surface_for_testing()->HasPendingFrame());
|
| +
|
| + // |factory2| is still blcoked on |surface_id3|.
|
| + EXPECT_FALSE(factory2.current_surface_for_testing()->HasActiveFrame());
|
| + EXPECT_TRUE(factory2.current_surface_for_testing()->HasPendingFrame());
|
| +
|
| + begin_frame_source->TestOnBeginFrame(args);
|
| + begin_frame_source->TestOnBeginFrame(args);
|
| + begin_frame_source->TestOnBeginFrame(args);
|
| +
|
| + // |factory1| and |factory2| are no longer blocked.
|
| + EXPECT_TRUE(factory1.current_surface_for_testing()->HasActiveFrame());
|
| + EXPECT_FALSE(factory1.current_surface_for_testing()->HasPendingFrame());
|
| + EXPECT_TRUE(factory2.current_surface_for_testing()->HasActiveFrame());
|
| + EXPECT_FALSE(factory2.current_surface_for_testing()->HasPendingFrame());
|
| + EXPECT_FALSE(manager.dependency_tracker()->has_deadline());
|
| +
|
| + factory1.EvictSurface();
|
| + factory2.EvictSurface();
|
| +}
|
| +
|
| +// Frame activates once a new frame is submitted.
|
| +TEST(SurfaceTest, DisplayCompositorLocking5) {
|
| + SurfaceManager manager;
|
| + std::unique_ptr<FakeExternalBeginFrameSource> begin_frame_source(
|
| + new FakeExternalBeginFrameSource(0.f, false));
|
| +
|
| + manager.SetDependencyTracker(base::MakeUnique<SurfaceDependencyTracker>(
|
| + &manager, begin_frame_source.get()));
|
| +
|
| + LocalSurfaceId local_surface_id1(6, base::UnguessableToken::Create());
|
| + SurfaceId surface_id1(FrameSinkId(1, 1), local_surface_id1);
|
| +
|
| + LocalSurfaceId local_surface_id2(7, base::UnguessableToken::Create());
|
| + SurfaceId surface_id2(FrameSinkId(2, 2), local_surface_id2);
|
| +
|
| + FakeSurfaceFactoryClient surface_factory_client1;
|
| + SurfaceFactory factory1(FrameSinkId(1, 1), &manager,
|
| + &surface_factory_client1);
|
| + factory1.SubmitCompositorFrame(local_surface_id1,
|
| + MakeCompositorFrame({surface_id2}),
|
| + SurfaceFactory::DrawCallback());
|
| +
|
| + // |factory1|'s Frame is blocked on |surface_id2|.
|
| + EXPECT_FALSE(factory1.current_surface_for_testing()->HasActiveFrame());
|
| + EXPECT_TRUE(factory1.current_surface_for_testing()->HasPendingFrame());
|
| + EXPECT_TRUE(manager.dependency_tracker()->has_deadline());
|
| +
|
| + // Another frame is submitted to |factory1| that has no dependencies.
|
| + factory1.SubmitCompositorFrame(local_surface_id1,
|
| + MakeCompositorFrame(std::vector<SurfaceId>()),
|
| + SurfaceFactory::DrawCallback());
|
| + EXPECT_TRUE(factory1.current_surface_for_testing()->HasActiveFrame());
|
| + EXPECT_FALSE(factory1.current_surface_for_testing()->HasPendingFrame());
|
| + EXPECT_FALSE(manager.dependency_tracker()->has_deadline());
|
| +
|
| + factory1.EvictSurface();
|
| +}
|
| +
|
| TEST(SurfaceTest, SurfaceLifetime) {
|
| SurfaceManager manager;
|
| FakeSurfaceFactoryClient surface_factory_client;
|
|
|