Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2606)

Unified Diff: cc/surfaces/surface_unittest.cc

Issue 2676373004: Implement service-side surface synchronization (Closed)
Patch Set: Use base::flat_set Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: cc/surfaces/surface_unittest.cc
diff --git a/cc/surfaces/surface_unittest.cc b/cc/surfaces/surface_unittest.cc
index dc6dc2dee90556bd39d69f88154bc70219bf6558..9a9f508659c63e9edb38322a0c096dbd0f49dd99 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,329 @@ 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();
+
+ // Destroy the SurfaceDependencyTracker before we destroy the
+ // BeginFrameSource.
+ manager.SetDependencyTracker(nullptr);
+}
+
+// Surface 1 is blocked on Surface 2 which is blocked on Surface 3.
+TEST(SurfaceTest, DisplayCompositorLocking2) {
vmpstr 2017/02/08 19:25:40 Can you name the tests something more descriptive?
Fady Samuel 2017/02/08 23:39:58 Done.
+ 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();
+
+ // Destroy the SurfaceDependencyTracker before we destroy the
+ // BeginFrameSource.
+ manager.SetDependencyTracker(nullptr);
+}
+
+// Surface 1 and Surface 2 are blocked on Surface 3.
+TEST(SurfaceTest, DisplayCompositorLocking3) {
vmpstr 2017/02/08 19:25:40 DisplayCompositorLockingTwoBlockedOnOne
Fady Samuel 2017/02/08 23:39:58 Done.
+ 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();
+
+ // Destroy the SurfaceDependencyTracker before we destroy the
+ // BeginFrameSource.
+ manager.SetDependencyTracker(nullptr);
+}
+
+// |factory1| is blocked on |surface_id2| but the deadline hits.
+TEST(SurfaceTest, DisplayCompositorLocking4) {
vmpstr 2017/02/08 19:25:40 DisplayCompositorLockingDeadlineHits
Fady Samuel 2017/02/08 23:39:58 Done.
+ 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);
vmpstr 2017/02/08 19:25:40 Can you make this into a for loop that checks the
Fady Samuel 2017/02/08 23:39:58 Done.
+ 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();
+
+ // Destroy the SurfaceDependencyTracker before we destroy the
+ // BeginFrameSource.
+ manager.SetDependencyTracker(nullptr);
+}
+
+// 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();
+
+ // Destroy the SurfaceDependencyTracker before we destroy the
+ // BeginFrameSource.
+ manager.SetDependencyTracker(nullptr);
+}
+
TEST(SurfaceTest, SurfaceLifetime) {
SurfaceManager manager;
FakeSurfaceFactoryClient surface_factory_client;

Powered by Google App Engine
This is Rietveld 408576698