diff options
34 files changed, 777 insertions, 84 deletions
diff --git a/android_webview/browser/hardware_renderer.cc b/android_webview/browser/hardware_renderer.cc index b13f0ef..4c4d9bb 100644 --- a/android_webview/browser/hardware_renderer.cc +++ b/android_webview/browser/hardware_renderer.cc @@ -203,6 +203,13 @@ void HardwareRenderer::ReturnResources( shared_renderer_state_->InsertReturnedResourcesOnRT(resources); } +void HardwareRenderer::SetBeginFrameSource( + cc::SurfaceId surface_id, + cc::BeginFrameSource* begin_frame_source) { + // TODO(tansell): Hook this up. + NOTIMPLEMENTED(); +} + void HardwareRenderer::SetBackingFrameBufferObject( int framebuffer_binding_ext) { gl_surface_->SetBackingFrameBufferObject(framebuffer_binding_ext); diff --git a/android_webview/browser/hardware_renderer.h b/android_webview/browser/hardware_renderer.h index 49a51ba..2772ac1 100644 --- a/android_webview/browser/hardware_renderer.h +++ b/android_webview/browser/hardware_renderer.h @@ -47,6 +47,8 @@ class HardwareRenderer : public cc::DisplayClient, // cc::SurfaceFactoryClient implementation. void ReturnResources(const cc::ReturnedResourceArray& resources) override; + void SetBeginFrameSource(cc::SurfaceId surface_id, + cc::BeginFrameSource* begin_frame_source) override; void ReturnResourcesInChildFrame(); diff --git a/cc/surfaces/display.cc b/cc/surfaces/display.cc index dd776fb..7cd9d6d 100644 --- a/cc/surfaces/display.cc +++ b/cc/surfaces/display.cc @@ -131,8 +131,8 @@ void Display::InitializeRenderer() { // overlays. bool output_partial_list = renderer_->Capabilities().using_partial_swap && !output_surface_->GetOverlayCandidateValidator(); - aggregator_.reset(new SurfaceAggregator(manager_, resource_provider_.get(), - output_partial_list)); + aggregator_.reset(new SurfaceAggregator( + this, manager_, resource_provider_.get(), output_partial_list)); } void Display::DidLoseOutputSurface() { @@ -150,6 +150,31 @@ void Display::UpdateRootSurfaceResourcesLocked() { scheduler_->SetRootSurfaceResourcesLocked(root_surface_resources_locked); } +void Display::AddSurface(Surface* surface) { + // Checking for the output_surface ensures Display::Initialize has been + // called and that scheduler_ won't change its value. + DCHECK(output_surface_); + + // WebView's HardwareRenderer will never have a scheduler. + if (!scheduler_) + return; + + surface->AddBeginFrameSource(scheduler_->begin_frame_source_for_children()); +} + +void Display::RemoveSurface(Surface* surface) { + // Checking for the output_surface ensures Display::Initialize has been + // called and that scheduler_ won't change its value. + DCHECK(output_surface_); + + // WebView's HardwareRenderer will never have a scheduler. + if (!scheduler_) + return; + + surface->RemoveBeginFrameSource( + scheduler_->begin_frame_source_for_children()); +} + bool Display::DrawAndSwap() { TRACE_EVENT0("cc", "Display::DrawAndSwap"); diff --git a/cc/surfaces/display.h b/cc/surfaces/display.h index b849b46..3873d13 100644 --- a/cc/surfaces/display.h +++ b/cc/surfaces/display.h @@ -11,6 +11,7 @@ #include "cc/output/output_surface_client.h" #include "cc/output/renderer.h" #include "cc/resources/returned_resource.h" +#include "cc/scheduler/begin_frame_source.h" #include "cc/surfaces/display_scheduler.h" #include "cc/surfaces/surface_aggregator.h" #include "cc/surfaces/surface_id.h" @@ -28,6 +29,7 @@ class Size; namespace cc { +class BeginFrameSource; class DirectRenderer; class DisplayClient; class OutputSurface; @@ -46,6 +48,7 @@ class TextureMailboxDeleter; class CC_SURFACES_EXPORT Display : public DisplaySchedulerClient, public OutputSurfaceClient, public RendererClient, + public SurfaceAggregatorClient, public SurfaceDamageObserver { public: Display(DisplayClient* client, @@ -66,6 +69,10 @@ class CC_SURFACES_EXPORT Display : public DisplaySchedulerClient, SurfaceId CurrentSurfaceId(); + // SurfaceAggregatorClient implementation + void AddSurface(Surface* surface) override; + void RemoveSurface(Surface* surface) override; + // DisplaySchedulerClient implementation. bool DrawAndSwap() override; diff --git a/cc/surfaces/display_scheduler.cc b/cc/surfaces/display_scheduler.cc index 033632e..feb84ea 100644 --- a/cc/surfaces/display_scheduler.cc +++ b/cc/surfaces/display_scheduler.cc @@ -33,6 +33,10 @@ DisplayScheduler::DisplayScheduler(DisplaySchedulerClient* client, begin_frame_source_->AddObserver(this); begin_frame_deadline_closure_ = base::Bind( &DisplayScheduler::OnBeginFrameDeadline, weak_ptr_factory_.GetWeakPtr()); + + // TODO(tansell): Set this to something useful. + begin_frame_source_for_children_ = SyntheticBeginFrameSource::Create( + task_runner, BeginFrameArgs::DefaultInterval()); } DisplayScheduler::~DisplayScheduler() { diff --git a/cc/surfaces/display_scheduler.h b/cc/surfaces/display_scheduler.h index 4ffc6ea..7b043c0 100644 --- a/cc/surfaces/display_scheduler.h +++ b/cc/surfaces/display_scheduler.h @@ -48,6 +48,10 @@ class CC_SURFACES_EXPORT DisplayScheduler : public BeginFrameObserverBase { // BeginFrameObserverBase implementation bool OnBeginFrameDerivedImpl(const BeginFrameArgs& args) override; + BeginFrameSource* begin_frame_source_for_children() { + return begin_frame_source_for_children_.get(); + } + protected: base::TimeTicks DesiredBeginFrameDeadlineTime(); virtual void ScheduleBeginFrameDeadline(); @@ -64,6 +68,9 @@ class CC_SURFACES_EXPORT DisplayScheduler : public BeginFrameObserverBase { base::CancelableClosure begin_frame_deadline_task_; base::TimeTicks begin_frame_deadline_task_time_; + // TODO(tansell): Set this to something useful. + scoped_ptr<BeginFrameSource> begin_frame_source_for_children_; + bool output_surface_lost_; bool root_surface_resources_locked_; diff --git a/cc/surfaces/display_unittest.cc b/cc/surfaces/display_unittest.cc index 6058f15..7b82d96 100644 --- a/cc/surfaces/display_unittest.cc +++ b/cc/surfaces/display_unittest.cc @@ -26,9 +26,21 @@ using testing::AnyNumber; namespace cc { namespace { -class EmptySurfaceFactoryClient : public SurfaceFactoryClient { +class FakeSurfaceFactoryClient : public SurfaceFactoryClient { public: + FakeSurfaceFactoryClient() : begin_frame_source_(nullptr) {} + void ReturnResources(const ReturnedResourceArray& resources) override {} + + void SetBeginFrameSource(SurfaceId surface_id, + BeginFrameSource* begin_frame_source) override { + begin_frame_source_ = begin_frame_source; + } + + BeginFrameSource* begin_frame_source() { return begin_frame_source_; } + + private: + BeginFrameSource* begin_frame_source_; }; class TestSoftwareOutputDevice : public SoftwareOutputDevice { @@ -42,7 +54,7 @@ class TestSoftwareOutputDevice : public SoftwareOutputDevice { class DisplayTest : public testing::Test { public: DisplayTest() - : factory_(&manager_, &empty_client_), + : factory_(&manager_, &surface_factory_client_), software_output_device_(nullptr), task_runner_(new base::NullTaskRunner) {} @@ -73,7 +85,7 @@ class DisplayTest : public testing::Test { } SurfaceManager manager_; - EmptySurfaceFactoryClient empty_client_; + FakeSurfaceFactoryClient surface_factory_client_; SurfaceFactory factory_; TestSoftwareOutputDevice* software_output_device_; scoped_ptr<FakeOutputSurface> output_surface_; @@ -103,7 +115,9 @@ class TestDisplayScheduler : public DisplayScheduler { damaged(false), display_resized_(false), has_new_root_surface(false), - swapped(false) {} + swapped(false) { + begin_frame_source_for_children_.reset(new FakeBeginFrameSource); + } ~TestDisplayScheduler() override {} @@ -136,6 +150,29 @@ void CopyCallback(bool* called, scoped_ptr<CopyOutputResult> result) { *called = true; } +// Verify Display responds to SurfaceAggregatorClient methods properly. +TEST_F(DisplayTest, DisplayAsSurfaceAggregatorClient) { + SetUpContext(nullptr); + TestDisplayClient client; + RendererSettings settings; + Display display(&client, &manager_, shared_bitmap_manager_.get(), nullptr, + settings); + + TestDisplayScheduler scheduler(&display, &fake_begin_frame_source_, + task_runner_.get()); + display.Initialize(output_surface_.Pass(), &scheduler); + + SurfaceId surface_id(6); + factory_.Create(surface_id); + Surface* surface = manager_.GetSurfaceForId(surface_id); + + EXPECT_EQ(nullptr, surface_factory_client_.begin_frame_source()); + display.AddSurface(surface); + EXPECT_NE(nullptr, surface_factory_client_.begin_frame_source()); + display.RemoveSurface(surface); + EXPECT_EQ(nullptr, surface_factory_client_.begin_frame_source()); +} + // Check that frame is damaged and swapped only under correct conditions. TEST_F(DisplayTest, DisplayDamaged) { SetUpContext(nullptr); diff --git a/cc/surfaces/onscreen_display_client.cc b/cc/surfaces/onscreen_display_client.cc index 29a2a7a..067f443 100644 --- a/cc/surfaces/onscreen_display_client.cc +++ b/cc/surfaces/onscreen_display_client.cc @@ -22,15 +22,14 @@ OnscreenDisplayClient::OnscreenDisplayClient( const RendererSettings& settings, scoped_refptr<base::SingleThreadTaskRunner> task_runner) : output_surface_(output_surface.Pass()), + task_runner_(task_runner), display_(new Display(this, manager, bitmap_manager, gpu_memory_buffer_manager, settings)), - task_runner_(task_runner), output_surface_lost_(false), - disable_display_vsync_(settings.disable_display_vsync) { -} + disable_display_vsync_(settings.disable_display_vsync) {} OnscreenDisplayClient::~OnscreenDisplayClient() { } diff --git a/cc/surfaces/onscreen_display_client.h b/cc/surfaces/onscreen_display_client.h index 4c4245d..3094306 100644 --- a/cc/surfaces/onscreen_display_client.h +++ b/cc/surfaces/onscreen_display_client.h @@ -53,11 +53,14 @@ class CC_SURFACES_EXPORT OnscreenDisplayClient protected: scoped_ptr<OutputSurface> output_surface_; - scoped_ptr<Display> display_; + // Be careful of destruction order: + // Display depends on DisplayScheduler depends on *BeginFrameSource + // depends on TaskRunner. + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; scoped_ptr<SyntheticBeginFrameSource> synthetic_frame_source_; scoped_ptr<BackToBackBeginFrameSource> unthrottled_frame_source_; scoped_ptr<DisplayScheduler> scheduler_; - scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + scoped_ptr<Display> display_; SurfaceDisplayOutputSurface* surface_display_output_surface_; bool output_surface_lost_; bool disable_display_vsync_; diff --git a/cc/surfaces/surface.cc b/cc/surfaces/surface.cc index e3b0f5e..0ffd522 100644 --- a/cc/surfaces/surface.cc +++ b/cc/surfaces/surface.cc @@ -35,6 +35,9 @@ Surface::~Surface() { } if (!draw_callback_.is_null()) draw_callback_.Run(SurfaceDrawStatus::DRAW_SKIPPED); + + if (factory_) + factory_->SetBeginFrameSource(surface_id_, NULL); } void Surface::QueueFrame(scoped_ptr<CompositorFrame> frame, @@ -175,6 +178,34 @@ void Surface::SatisfyDestructionDependencies( destruction_dependencies_.end()); } +void Surface::AddBeginFrameSource(BeginFrameSource* begin_frame_source) { + DCHECK(base::STLIsSorted(begin_frame_sources_)); + DCHECK(!ContainsValue(begin_frame_sources_, begin_frame_source)) + << begin_frame_source; + begin_frame_sources_.insert(begin_frame_source); + UpdatePrimaryBeginFrameSource(); +} + +void Surface::RemoveBeginFrameSource(BeginFrameSource* begin_frame_source) { + size_t erase_count = begin_frame_sources_.erase(begin_frame_source); + DCHECK_EQ(1u, erase_count); + UpdatePrimaryBeginFrameSource(); +} + +void Surface::UpdatePrimaryBeginFrameSource() { + // Ensure the BeginFrameSources are sorted so our we make a stable decision + // regarding which source is primary. + // TODO(brianderson): Do something smarter based on coverage instead. + DCHECK(base::STLIsSorted(begin_frame_sources_)); + + BeginFrameSource* primary_source = nullptr; + if (!begin_frame_sources_.empty()) + primary_source = *begin_frame_sources_.begin(); + + if (factory_) + factory_->SetBeginFrameSource(surface_id_, primary_source); +} + void Surface::ClearCopyRequests() { if (current_frame_) { for (const auto& render_pass : diff --git a/cc/surfaces/surface.h b/cc/surfaces/surface.h index 8ef332e..18ca744 100644 --- a/cc/surfaces/surface.h +++ b/cc/surfaces/surface.h @@ -6,6 +6,7 @@ #define CC_SURFACES_SURFACE_H_ #include <map> +#include <set> #include <vector> #include "base/callback.h" @@ -80,8 +81,12 @@ class CC_SURFACES_EXPORT Surface { bool destroyed() const { return destroyed_; } void set_destroyed(bool destroyed) { destroyed_ = destroyed; } + void AddBeginFrameSource(BeginFrameSource* begin_frame_source); + void RemoveBeginFrameSource(BeginFrameSource* begin_frame_source); + private: void ClearCopyRequests(); + void UpdatePrimaryBeginFrameSource(); SurfaceId surface_id_; base::WeakPtr<SurfaceFactory> factory_; @@ -91,6 +96,10 @@ class CC_SURFACES_EXPORT Surface { bool destroyed_; std::vector<SurfaceSequence> destruction_dependencies_; + // This surface may have multiple BeginFrameSources if it is + // on multiple Displays. + std::set<BeginFrameSource*> begin_frame_sources_; + std::vector<SurfaceId> referenced_surfaces_; DrawCallback draw_callback_; diff --git a/cc/surfaces/surface_aggregator.cc b/cc/surfaces/surface_aggregator.cc index 902f836..967f496 100644 --- a/cc/surfaces/surface_aggregator.cc +++ b/cc/surfaces/surface_aggregator.cc @@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/containers/hash_tables.h" #include "base/logging.h" +#include "base/stl_util.h" #include "base/trace_event/trace_event.h" #include "cc/base/math_util.h" #include "cc/output/compositor_frame.h" @@ -40,17 +41,23 @@ void MoveMatchingRequests( } // namespace -SurfaceAggregator::SurfaceAggregator(SurfaceManager* manager, +SurfaceAggregator::SurfaceAggregator(SurfaceAggregatorClient* client, + SurfaceManager* manager, ResourceProvider* provider, bool aggregate_only_damaged) - : manager_(manager), + : client_(client), + manager_(manager), provider_(provider), next_render_pass_id_(1), aggregate_only_damaged_(aggregate_only_damaged) { DCHECK(manager_); } -SurfaceAggregator::~SurfaceAggregator() {} +SurfaceAggregator::~SurfaceAggregator() { + // Notify client of all surfaces being removed. + contained_surfaces_.clear(); + ProcessAddedAndRemovedSurfaces(); +} // Create a clip rect for an aggregated quad from the original clip rect and // the clip rect from the surface it's on. @@ -135,14 +142,18 @@ int SurfaceAggregator::ChildIdForSurface(Surface* surface) { } } +gfx::Rect SurfaceAggregator::DamageRectForSurface( + const Surface* surface, + const RenderPass& source, + const gfx::Rect& full_rect) const { + auto it = previous_contained_surfaces_.find(surface->surface_id()); + if (it == previous_contained_surfaces_.end()) + return full_rect; -gfx::Rect SurfaceAggregator::DamageRectForSurface(const Surface* surface, - const RenderPass& source, - const gfx::Rect& full_rect) { - int previous_index = previous_contained_surfaces_[surface->surface_id()]; + int previous_index = it->second; if (previous_index == surface->frame_index()) return gfx::Rect(); - else if (previous_index == surface->frame_index() - 1) + if (previous_index == surface->frame_index() - 1) return source.damage_rect; return full_rect; } @@ -450,9 +461,10 @@ void SurfaceAggregator::CopyPasses(const DelegatedFrameData* frame_data, } } -void SurfaceAggregator::RemoveUnreferencedChildren() { +void SurfaceAggregator::ProcessAddedAndRemovedSurfaces() { for (const auto& surface : previous_contained_surfaces_) { if (!contained_surfaces_.count(surface.first)) { + // Release resources of removed surface. SurfaceToResourceChildIdMap::iterator it = surface_id_to_resource_child_id_.find(surface.first); if (it != surface_id_to_resource_child_id_.end()) { @@ -460,9 +472,21 @@ void SurfaceAggregator::RemoveUnreferencedChildren() { surface_id_to_resource_child_id_.erase(it); } + // Notify client of removed surface. Surface* surface_ptr = manager_->GetSurfaceForId(surface.first); - if (surface_ptr) + if (surface_ptr) { surface_ptr->RunDrawCallbacks(SurfaceDrawStatus::DRAW_SKIPPED); + client_->RemoveSurface(surface_ptr); + } + } + } + + for (const auto& surface : contained_surfaces_) { + if (!previous_contained_surfaces_.count(surface.first)) { + // Notify client of added surface. + Surface* surface_ptr = manager_->GetSurfaceForId(surface.first); + if (surface_ptr) + client_->AddSurface(surface_ptr); } } } @@ -606,7 +630,7 @@ scoped_ptr<CompositorFrame> SurfaceAggregator::Aggregate(SurfaceId surface_id) { dest_pass_list_->back()->damage_rect = root_damage_rect_; dest_pass_list_ = NULL; - RemoveUnreferencedChildren(); + ProcessAddedAndRemovedSurfaces(); contained_surfaces_.swap(previous_contained_surfaces_); contained_surfaces_.clear(); diff --git a/cc/surfaces/surface_aggregator.h b/cc/surfaces/surface_aggregator.h index 1ff4a45..738aeec 100644 --- a/cc/surfaces/surface_aggregator.h +++ b/cc/surfaces/surface_aggregator.h @@ -25,11 +25,20 @@ class Surface; class SurfaceDrawQuad; class SurfaceManager; +class CC_SURFACES_EXPORT SurfaceAggregatorClient { + public: + virtual ~SurfaceAggregatorClient() {} + + virtual void AddSurface(Surface* surface) = 0; + virtual void RemoveSurface(Surface* surface) = 0; +}; + class CC_SURFACES_EXPORT SurfaceAggregator { public: typedef base::hash_map<SurfaceId, int> SurfaceIndexMap; - SurfaceAggregator(SurfaceManager* manager, + SurfaceAggregator(SurfaceAggregatorClient* client, + SurfaceManager* manager, ResourceProvider* provider, bool aggregate_only_damaged); ~SurfaceAggregator(); @@ -79,13 +88,16 @@ class CC_SURFACES_EXPORT SurfaceAggregator { // Remove Surfaces that were referenced before but aren't currently // referenced from the ResourceProvider. - void RemoveUnreferencedChildren(); + // Also notifies SurfaceAggregatorClient of newly added and removed + // child surfaces. + void ProcessAddedAndRemovedSurfaces(); int ChildIdForSurface(Surface* surface); gfx::Rect DamageRectForSurface(const Surface* surface, const RenderPass& source, - const gfx::Rect& full_rect); + const gfx::Rect& full_rect) const; + SurfaceAggregatorClient* client_; // Outlives this class. SurfaceManager* manager_; ResourceProvider* provider_; diff --git a/cc/surfaces/surface_aggregator_perftest.cc b/cc/surfaces/surface_aggregator_perftest.cc index 2960c44..95085c3 100644 --- a/cc/surfaces/surface_aggregator_perftest.cc +++ b/cc/surfaces/surface_aggregator_perftest.cc @@ -24,6 +24,14 @@ namespace { class EmptySurfaceFactoryClient : public SurfaceFactoryClient { public: void ReturnResources(const ReturnedResourceArray& resources) override {} + void SetBeginFrameSource(SurfaceId surface_id, + BeginFrameSource* begin_frame_source) override {} +}; + +class EmptySurfaceAggregatorClient : public SurfaceAggregatorClient { + public: + void AddSurface(Surface* surface) override {} + void RemoveSurface(Surface* surface) override {} }; class SurfaceAggregatorPerfTest : public testing::Test { @@ -44,7 +52,8 @@ class SurfaceAggregatorPerfTest : public testing::Test { bool optimize_damage, bool full_damage, const std::string& name) { - aggregator_.reset(new SurfaceAggregator(&manager_, resource_provider_.get(), + aggregator_.reset(new SurfaceAggregator(&surface_aggregator_client_, + &manager_, resource_provider_.get(), optimize_damage)); for (int i = 1; i <= num_surfaces; i++) { factory_.Create(SurfaceId(i)); @@ -139,6 +148,7 @@ class SurfaceAggregatorPerfTest : public testing::Test { scoped_ptr<SharedBitmapManager> shared_bitmap_manager_; scoped_ptr<ResourceProvider> resource_provider_; scoped_ptr<SurfaceAggregator> aggregator_; + EmptySurfaceAggregatorClient surface_aggregator_client_; LapTimer timer_; }; diff --git a/cc/surfaces/surface_aggregator_unittest.cc b/cc/surfaces/surface_aggregator_unittest.cc index bee479c..63aba46 100644 --- a/cc/surfaces/surface_aggregator_unittest.cc +++ b/cc/surfaces/surface_aggregator_unittest.cc @@ -43,20 +43,47 @@ gfx::Size SurfaceSize() { class EmptySurfaceFactoryClient : public SurfaceFactoryClient { public: void ReturnResources(const ReturnedResourceArray& resources) override {} + void WillDrawSurface(SurfaceId id, const gfx::Rect& damage_rect) override { last_surface_id_ = id; last_damage_rect_ = damage_rect; } + void SetBeginFrameSource(SurfaceId surface_id, + BeginFrameSource* begin_frame_source) override {} + gfx::Rect last_damage_rect_; SurfaceId last_surface_id_; }; +class FakeSurfaceAggregatorClient : public SurfaceAggregatorClient { + public: + void AddSurface(Surface* surface) override { + EXPECT_FALSE(HasSurface(surface)); + surfaces_.insert(surface); + } + + void RemoveSurface(Surface* surface) override { + EXPECT_TRUE(HasSurface(surface)); + surfaces_.erase(surface); + } + + bool HasSurface(Surface* surface) const { + return surfaces_.count(surface) != 0; + } + + private: + std::set<Surface*> surfaces_; +}; + class SurfaceAggregatorTest : public testing::Test { public: explicit SurfaceAggregatorTest(bool use_damage_rect) : factory_(&manager_, &empty_client_), - aggregator_(&manager_, NULL, use_damage_rect) {} + aggregator_(&surface_aggregator_client_, + &manager_, + NULL, + use_damage_rect) {} SurfaceAggregatorTest() : SurfaceAggregatorTest(false) {} @@ -64,14 +91,20 @@ class SurfaceAggregatorTest : public testing::Test { SurfaceManager manager_; EmptySurfaceFactoryClient empty_client_; SurfaceFactory factory_; + FakeSurfaceAggregatorClient surface_aggregator_client_; SurfaceAggregator aggregator_; }; TEST_F(SurfaceAggregatorTest, ValidSurfaceNoFrame) { SurfaceId one_id(7); factory_.Create(one_id); + Surface* surface = manager_.GetSurfaceForId(one_id); + + EXPECT_FALSE(surface_aggregator_client_.HasSurface(surface)); scoped_ptr<CompositorFrame> frame = aggregator_.Aggregate(one_id); EXPECT_FALSE(frame); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(surface)); + factory_.Destroy(one_id); } @@ -88,6 +121,7 @@ class SurfaceAggregatorValidSurfaceTest : public SurfaceAggregatorTest { SurfaceAggregatorTest::SetUp(); root_surface_id_ = allocator_.GenerateId(); factory_.Create(root_surface_id_); + root_surface_ = manager_.GetSurfaceForId(root_surface_id_); } void TearDown() override { @@ -158,6 +192,7 @@ class SurfaceAggregatorValidSurfaceTest : public SurfaceAggregatorTest { protected: SurfaceId root_surface_id_; + Surface* root_surface_; SurfaceIdAllocator allocator_; SurfaceIdAllocator child_allocator_; }; @@ -172,7 +207,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleFrame) { SubmitCompositorFrame(passes, arraysize(passes), root_surface_id_); SurfaceId ids[] = {root_surface_id_}; + + EXPECT_FALSE(surface_aggregator_client_.HasSurface(root_surface_)); AggregateAndVerify(passes, arraysize(passes), ids, arraysize(ids)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface_)); // Check that WillDrawSurface was called. EXPECT_EQ(gfx::Rect(SurfaceSize()), empty_client_.last_damage_rect_); @@ -182,6 +220,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleFrame) { TEST_F(SurfaceAggregatorValidSurfaceTest, OpacityCopied) { SurfaceId embedded_surface_id = allocator_.GenerateId(); factory_.Create(embedded_surface_id); + Surface* embedded_surface = manager_.GetSurfaceForId(embedded_surface_id); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(embedded_surface)); test::Quad embedded_quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN), test::Quad::SolidColorQuad(SK_ColorBLUE)}; @@ -196,9 +236,15 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, OpacityCopied) { SubmitCompositorFrame(passes, arraysize(passes), root_surface_id_); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(embedded_surface)); + scoped_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(embedded_surface)); + ASSERT_TRUE(aggregated_frame); ASSERT_TRUE(aggregated_frame->delegated_frame_data); @@ -232,7 +278,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassSimpleFrame) { SubmitCompositorFrame(passes, arraysize(passes), root_surface_id_); SurfaceId ids[] = {root_surface_id_}; + + EXPECT_FALSE(surface_aggregator_client_.HasSurface(root_surface_)); AggregateAndVerify(passes, arraysize(passes), ids, arraysize(ids)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface_)); } // This tests very simple embedding. root_surface has a frame containing a few @@ -242,6 +291,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassSimpleFrame) { TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleSurfaceReference) { SurfaceId embedded_surface_id = allocator_.GenerateId(); factory_.Create(embedded_surface_id); + Surface* embedded_surface = manager_.GetSurfaceForId(embedded_surface_id); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(embedded_surface)); test::Quad embedded_quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN)}; test::Pass embedded_passes[] = { @@ -257,6 +308,9 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleSurfaceReference) { SubmitCompositorFrame(root_passes, arraysize(root_passes), root_surface_id_); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(embedded_surface)); + test::Quad expected_quads[] = {test::Quad::SolidColorQuad(SK_ColorWHITE), test::Quad::SolidColorQuad(SK_ColorGREEN), test::Quad::SolidColorQuad(SK_ColorBLACK)}; @@ -266,12 +320,17 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleSurfaceReference) { AggregateAndVerify( expected_passes, arraysize(expected_passes), ids, arraysize(ids)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(embedded_surface)); + factory_.Destroy(embedded_surface_id); } TEST_F(SurfaceAggregatorValidSurfaceTest, CopyRequest) { SurfaceId embedded_surface_id = allocator_.GenerateId(); factory_.Create(embedded_surface_id); + Surface* embedded_surface = manager_.GetSurfaceForId(embedded_surface_id); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(embedded_surface)); test::Quad embedded_quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN)}; test::Pass embedded_passes[] = { @@ -291,9 +350,15 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, CopyRequest) { SubmitCompositorFrame(root_passes, arraysize(root_passes), root_surface_id_); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(embedded_surface)); + scoped_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(embedded_surface)); + ASSERT_TRUE(aggregated_frame); ASSERT_TRUE(aggregated_frame->delegated_frame_data); @@ -330,6 +395,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, CopyRequest) { TEST_F(SurfaceAggregatorValidSurfaceTest, RootCopyRequest) { SurfaceId embedded_surface_id = allocator_.GenerateId(); factory_.Create(embedded_surface_id); + Surface* embedded_surface = manager_.GetSurfaceForId(embedded_surface_id); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(embedded_surface)); test::Quad embedded_quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN)}; test::Pass embedded_passes[] = { @@ -370,9 +437,15 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, RootCopyRequest) { SurfaceFactory::DrawCallback()); } + EXPECT_FALSE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(embedded_surface)); + scoped_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(embedded_surface)); + ASSERT_TRUE(aggregated_frame); ASSERT_TRUE(aggregated_frame->delegated_frame_data); @@ -420,6 +493,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, RootCopyRequest) { TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassSurfaceReference) { SurfaceId embedded_surface_id = child_allocator_.GenerateId(); factory_.Create(embedded_surface_id); + Surface* embedded_surface = manager_.GetSurfaceForId(embedded_surface_id); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(embedded_surface)); RenderPassId pass_ids[] = {RenderPassId(1, 1), RenderPassId(1, 2), RenderPassId(1, 3)}; @@ -448,9 +523,15 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassSurfaceReference) { SubmitCompositorFrame(root_passes, arraysize(root_passes), root_surface_id_); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(embedded_surface)); + scoped_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(embedded_surface)); + ASSERT_TRUE(aggregated_frame); ASSERT_TRUE(aggregated_frame->delegated_frame_data); @@ -570,8 +651,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, InvalidSurfaceReference) { test::Pass expected_passes[] = { test::Pass(expected_quads, arraysize(expected_quads))}; SurfaceId ids[] = {root_surface_id_, InvalidSurfaceId()}; + + EXPECT_FALSE(surface_aggregator_client_.HasSurface(root_surface_)); AggregateAndVerify( expected_passes, arraysize(expected_passes), ids, arraysize(ids)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface_)); } // Tests a reference to a valid surface with no submitted frame. This quad @@ -579,6 +663,9 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, InvalidSurfaceReference) { TEST_F(SurfaceAggregatorValidSurfaceTest, ValidSurfaceReferenceWithNoFrame) { SurfaceId surface_with_no_frame_id = allocator_.GenerateId(); factory_.Create(surface_with_no_frame_id); + Surface* surface_with_no_frame = + manager_.GetSurfaceForId(surface_with_no_frame_id); + test::Quad quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN), test::Quad::SurfaceQuad(surface_with_no_frame_id, 1.f), test::Quad::SolidColorQuad(SK_ColorBLUE)}; @@ -591,8 +678,12 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, ValidSurfaceReferenceWithNoFrame) { test::Pass expected_passes[] = { test::Pass(expected_quads, arraysize(expected_quads))}; SurfaceId ids[] = {root_surface_id_, surface_with_no_frame_id}; + EXPECT_FALSE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(surface_with_no_frame)); AggregateAndVerify( expected_passes, arraysize(expected_passes), ids, arraysize(ids)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(surface_with_no_frame)); factory_.Destroy(surface_with_no_frame_id); } @@ -609,14 +700,18 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleCyclicalReference) { test::Pass expected_passes[] = { test::Pass(expected_quads, arraysize(expected_quads))}; SurfaceId ids[] = {root_surface_id_}; + EXPECT_FALSE(surface_aggregator_client_.HasSurface(root_surface_)); AggregateAndVerify( expected_passes, arraysize(expected_passes), ids, arraysize(ids)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface_)); } // Tests a more complex cycle with one intermediate surface. TEST_F(SurfaceAggregatorValidSurfaceTest, TwoSurfaceCyclicalReference) { SurfaceId child_surface_id = allocator_.GenerateId(); factory_.Create(child_surface_id); + Surface* child_surface = manager_.GetSurfaceForId(child_surface_id); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(child_surface)); test::Quad parent_quads[] = {test::Quad::SolidColorQuad(SK_ColorBLUE), test::Quad::SurfaceQuad(child_surface_id, 1.f), @@ -648,8 +743,12 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, TwoSurfaceCyclicalReference) { test::Pass expected_passes[] = { test::Pass(expected_quads, arraysize(expected_quads))}; SurfaceId ids[] = {root_surface_id_, child_surface_id}; + EXPECT_FALSE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(child_surface)); AggregateAndVerify( expected_passes, arraysize(expected_passes), ids, arraysize(ids)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(child_surface)); factory_.Destroy(child_surface_id); } @@ -658,6 +757,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, TwoSurfaceCyclicalReference) { TEST_F(SurfaceAggregatorValidSurfaceTest, RenderPassIdMapping) { SurfaceId child_surface_id = allocator_.GenerateId(); factory_.Create(child_surface_id); + Surface* child_surface = manager_.GetSurfaceForId(child_surface_id); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(child_surface)); RenderPassId child_pass_id[] = {RenderPassId(1, 1), RenderPassId(1, 2)}; test::Quad child_quad[][1] = {{test::Quad::SolidColorQuad(SK_ColorGREEN)}, @@ -680,9 +781,16 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, RenderPassIdMapping) { SubmitCompositorFrame(parent_passes, arraysize(parent_passes), root_surface_id_); + + EXPECT_FALSE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(child_surface)); + scoped_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(child_surface)); + ASSERT_TRUE(aggregated_frame); ASSERT_TRUE(aggregated_frame->delegated_frame_data); @@ -780,6 +888,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateSharedQuadStateProperties) { RenderPassId pass_id(1, 1); SurfaceId grandchild_surface_id = allocator_.GenerateId(); factory_.Create(grandchild_surface_id); + Surface* grandchild_surface = manager_.GetSurfaceForId(grandchild_surface_id); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(grandchild_surface)); scoped_ptr<RenderPass> grandchild_pass = RenderPass::Create(); gfx::Rect output_rect(SurfaceSize()); gfx::Rect damage_rect(SurfaceSize()); @@ -792,6 +902,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateSharedQuadStateProperties) { SurfaceId child_one_surface_id = allocator_.GenerateId(); factory_.Create(child_one_surface_id); + Surface* child_one_surface = manager_.GetSurfaceForId(child_one_surface_id); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(child_one_surface)); scoped_ptr<RenderPass> child_one_pass = RenderPass::Create(); child_one_pass->SetNew( @@ -810,6 +922,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateSharedQuadStateProperties) { SurfaceId child_two_surface_id = allocator_.GenerateId(); factory_.Create(child_two_surface_id); + Surface* child_two_surface = manager_.GetSurfaceForId(child_two_surface_id); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(child_two_surface)); scoped_ptr<RenderPass> child_two_pass = RenderPass::Create(); child_two_pass->SetNew( @@ -843,9 +957,19 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateSharedQuadStateProperties) { QueuePassAsFrame(root_pass.Pass(), root_surface_id_); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(grandchild_surface)); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(child_one_surface)); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(child_two_surface)); + scoped_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(grandchild_surface)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(child_one_surface)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(child_two_surface)); + ASSERT_TRUE(aggregated_frame); ASSERT_TRUE(aggregated_frame->delegated_frame_data); @@ -891,8 +1015,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateSharedQuadStateProperties) { TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateMultiplePassWithTransform) { // Innermost child surface. SurfaceId child_surface_id = allocator_.GenerateId(); + factory_.Create(child_surface_id); + Surface* child_surface = manager_.GetSurfaceForId(child_surface_id); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(child_surface)); { - factory_.Create(child_surface_id); RenderPassId child_pass_id[] = {RenderPassId(1, 1), RenderPassId(1, 2)}; test::Quad child_quads[][1] = { {test::Quad::SolidColorQuad(SK_ColorGREEN)}, @@ -932,8 +1058,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateMultiplePassWithTransform) { // Middle child surface. SurfaceId middle_surface_id = allocator_.GenerateId(); + factory_.Create(middle_surface_id); + Surface* middle_surface = manager_.GetSurfaceForId(middle_surface_id); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(middle_surface)); { - factory_.Create(middle_surface_id); test::Quad middle_quads[] = { test::Quad::SurfaceQuad(child_surface_id, 1.f)}; test::Pass middle_passes[] = { @@ -996,9 +1124,17 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateMultiplePassWithTransform) { factory_.SubmitCompositorFrame(root_surface_id_, root_frame.Pass(), SurfaceFactory::DrawCallback()); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(child_surface)); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(middle_surface)); + scoped_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(child_surface)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(middle_surface)); + ASSERT_TRUE(aggregated_frame); ASSERT_TRUE(aggregated_frame->delegated_frame_data); @@ -1102,6 +1238,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) { SurfaceId child_surface_id = allocator_.GenerateId(); factory_.Create(child_surface_id); + Surface* child_surface = manager_.GetSurfaceForId(child_surface_id); factory_.SubmitCompositorFrame(child_surface_id, child_frame.Pass(), SurfaceFactory::DrawCallback()); @@ -1128,6 +1265,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) { SurfaceId parent_surface_id = allocator_.GenerateId(); factory_.Create(parent_surface_id); + Surface* parent_surface = manager_.GetSurfaceForId(parent_surface_id); factory_.SubmitCompositorFrame(parent_surface_id, parent_surface_frame.Pass(), SurfaceFactory::DrawCallback()); @@ -1163,9 +1301,17 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) { factory_.SubmitCompositorFrame(root_surface_id_, root_frame.Pass(), SurfaceFactory::DrawCallback()); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(child_surface)); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(parent_surface)); + scoped_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(child_surface)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(parent_surface)); + ASSERT_TRUE(aggregated_frame); ASSERT_TRUE(aggregated_frame->delegated_frame_data); @@ -1200,9 +1346,17 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) { factory_.SubmitCompositorFrame(child_surface_id, child_frame.Pass(), SurfaceFactory::DrawCallback()); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(child_surface)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(parent_surface)); + scoped_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(child_surface)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(parent_surface)); + ASSERT_TRUE(aggregated_frame); ASSERT_TRUE(aggregated_frame->delegated_frame_data); @@ -1262,9 +1416,17 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) { factory_.SubmitCompositorFrame(root_surface_id_, root_frame.Pass(), SurfaceFactory::DrawCallback()); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(child_surface)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(parent_surface)); + scoped_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(child_surface)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(parent_surface)); + ASSERT_TRUE(aggregated_frame); ASSERT_TRUE(aggregated_frame->delegated_frame_data); @@ -1283,9 +1445,17 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) { // No Surface changed, so no damage should be given. { + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(child_surface)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(parent_surface)); + scoped_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(child_surface)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(parent_surface)); + ASSERT_TRUE(aggregated_frame); ASSERT_TRUE(aggregated_frame->delegated_frame_data); @@ -1302,10 +1472,18 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) { // SetFullDamageRectForSurface should cause the entire output to be // marked as damaged. { + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(child_surface)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(parent_surface)); + aggregator_.SetFullDamageForSurface(root_surface_id_); scoped_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(child_surface)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(parent_surface)); + ASSERT_TRUE(aggregated_frame); ASSERT_TRUE(aggregated_frame->delegated_frame_data); @@ -1334,6 +1512,7 @@ class SurfaceAggregatorPartialSwapTest TEST_F(SurfaceAggregatorPartialSwapTest, IgnoreOutside) { SurfaceId child_surface_id = allocator_.GenerateId(); factory_.Create(child_surface_id); + Surface* child_surface = manager_.GetSurfaceForId(child_surface_id); // The child surface has two quads, one with a visible rect of 13,13 4x4 and // the other other with a visible rect of 10,10 2x2 (relative to root target // space). @@ -1379,9 +1558,15 @@ TEST_F(SurfaceAggregatorPartialSwapTest, IgnoreOutside) { SubmitPassListAsFrame(root_surface_id_, &root_pass_list); } + EXPECT_FALSE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(child_surface)); + scoped_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(child_surface)); + ASSERT_TRUE(aggregated_frame); ASSERT_TRUE(aggregated_frame->delegated_frame_data); @@ -1414,9 +1599,15 @@ TEST_F(SurfaceAggregatorPartialSwapTest, IgnoreOutside) { } { + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(child_surface)); + scoped_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(child_surface)); + ASSERT_TRUE(aggregated_frame); ASSERT_TRUE(aggregated_frame->delegated_frame_data); @@ -1469,9 +1660,15 @@ TEST_F(SurfaceAggregatorPartialSwapTest, IgnoreOutside) { } { + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(child_surface)); + scoped_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(child_surface)); + ASSERT_TRUE(aggregated_frame); ASSERT_TRUE(aggregated_frame->delegated_frame_data); @@ -1493,9 +1690,15 @@ TEST_F(SurfaceAggregatorPartialSwapTest, IgnoreOutside) { } { + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(child_surface)); + scoped_ptr<CompositorFrame> aggregated_frame = aggregator_.Aggregate(root_surface_id_); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface_)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(child_surface)); + ASSERT_TRUE(aggregated_frame); ASSERT_TRUE(aggregated_frame->delegated_frame_data); @@ -1524,8 +1727,9 @@ class SurfaceAggregatorWithResourcesTest : public testing::Test { resource_provider_ = FakeResourceProvider::Create( output_surface_.get(), shared_bitmap_manager_.get()); - aggregator_.reset( - new SurfaceAggregator(&manager_, resource_provider_.get(), false)); + aggregator_.reset(new SurfaceAggregator(&surface_aggregator_client_, + &manager_, resource_provider_.get(), + false)); } protected: @@ -1535,6 +1739,7 @@ class SurfaceAggregatorWithResourcesTest : public testing::Test { scoped_ptr<SharedBitmapManager> shared_bitmap_manager_; scoped_ptr<ResourceProvider> resource_provider_; scoped_ptr<SurfaceAggregator> aggregator_; + FakeSurfaceAggregatorClient surface_aggregator_client_; }; class ResourceTrackingSurfaceFactoryClient : public SurfaceFactoryClient { @@ -1550,6 +1755,9 @@ class ResourceTrackingSurfaceFactoryClient : public SurfaceFactoryClient { return returned_resources_; } + void SetBeginFrameSource(SurfaceId surface_id, + BeginFrameSource* begin_frame_source) override {} + private: ReturnedResourceArray returned_resources_; @@ -1609,21 +1817,30 @@ TEST_F(SurfaceAggregatorWithResourcesTest, TakeResourcesOneSurface) { SurfaceFactory factory(&manager_, &client); SurfaceId surface_id(7u); factory.Create(surface_id); + Surface* surface = manager_.GetSurfaceForId(surface_id); ResourceId ids[] = {11, 12, 13}; SubmitCompositorFrameWithResources(ids, arraysize(ids), true, SurfaceId(), &factory, surface_id); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(surface)); + scoped_ptr<CompositorFrame> frame = aggregator_->Aggregate(surface_id); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(surface)); + // Nothing should be available to be returned yet. EXPECT_TRUE(client.returned_resources().empty()); SubmitCompositorFrameWithResources(NULL, 0u, true, SurfaceId(), &factory, surface_id); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(surface)); + frame = aggregator_->Aggregate(surface_id); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(surface)); + ASSERT_EQ(3u, client.returned_resources().size()); ResourceId returned_ids[3]; for (size_t i = 0; i < 3; ++i) { @@ -1639,6 +1856,7 @@ TEST_F(SurfaceAggregatorWithResourcesTest, TakeInvalidResources) { SurfaceFactory factory(&manager_, &client); SurfaceId surface_id(7u); factory.Create(surface_id); + Surface* surface = manager_.GetSurfaceForId(surface_id); scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); scoped_ptr<RenderPass> pass = RenderPass::Create(); @@ -1655,9 +1873,13 @@ TEST_F(SurfaceAggregatorWithResourcesTest, TakeInvalidResources) { factory.SubmitCompositorFrame(surface_id, frame.Pass(), SurfaceFactory::DrawCallback()); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(surface)); + scoped_ptr<CompositorFrame> returned_frame = aggregator_->Aggregate(surface_id); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(surface)); + // Nothing should be available to be returned yet. EXPECT_TRUE(client.returned_resources().empty()); @@ -1672,29 +1894,44 @@ TEST_F(SurfaceAggregatorWithResourcesTest, TakeInvalidResources) { TEST_F(SurfaceAggregatorWithResourcesTest, TwoSurfaces) { ResourceTrackingSurfaceFactoryClient client; SurfaceFactory factory(&manager_, &client); - SurfaceId surface_id(7u); - factory.Create(surface_id); - SurfaceId surface_id2(8u); - factory.Create(surface_id2); + SurfaceId surface1_id(7u); + factory.Create(surface1_id); + Surface* surface1 = manager_.GetSurfaceForId(surface1_id); + + SurfaceId surface2_id(8u); + factory.Create(surface2_id); + Surface* surface2 = manager_.GetSurfaceForId(surface2_id); ResourceId ids[] = {11, 12, 13}; SubmitCompositorFrameWithResources(ids, arraysize(ids), true, SurfaceId(), - &factory, surface_id); + &factory, surface1_id); ResourceId ids2[] = {14, 15, 16}; SubmitCompositorFrameWithResources(ids2, arraysize(ids2), true, SurfaceId(), - &factory, surface_id2); + &factory, surface2_id); - scoped_ptr<CompositorFrame> frame = aggregator_->Aggregate(surface_id); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(surface1)); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(surface2)); + + scoped_ptr<CompositorFrame> frame = aggregator_->Aggregate(surface1_id); + + EXPECT_TRUE(surface_aggregator_client_.HasSurface(surface1)); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(surface2)); SubmitCompositorFrameWithResources(NULL, 0, true, SurfaceId(), &factory, - surface_id); + surface1_id); // Nothing should be available to be returned yet. EXPECT_TRUE(client.returned_resources().empty()); - frame = aggregator_->Aggregate(surface_id2); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(surface1)); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(surface2)); + + frame = aggregator_->Aggregate(surface2_id); - // surface_id wasn't referenced, so its resources should be returned. + EXPECT_FALSE(surface_aggregator_client_.HasSurface(surface1)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(surface2)); + + // surface1_id wasn't referenced, so its resources should be returned. ASSERT_EQ(3u, client.returned_resources().size()); ResourceId returned_ids[3]; for (size_t i = 0; i < 3; ++i) { @@ -1703,8 +1940,8 @@ TEST_F(SurfaceAggregatorWithResourcesTest, TwoSurfaces) { EXPECT_THAT(returned_ids, testing::WhenSorted(testing::ElementsAreArray(ids))); EXPECT_EQ(3u, resource_provider_->num_resources()); - factory.Destroy(surface_id); - factory.Destroy(surface_id2); + factory.Destroy(surface1_id); + factory.Destroy(surface2_id); } // Ensure that aggregator completely ignores Surfaces that reference invalid @@ -1714,10 +1951,13 @@ TEST_F(SurfaceAggregatorWithResourcesTest, InvalidChildSurface) { SurfaceFactory factory(&manager_, &client); SurfaceId root_surface_id(7u); factory.Create(root_surface_id); + Surface* root_surface = manager_.GetSurfaceForId(root_surface_id); SurfaceId middle_surface_id(8u); factory.Create(middle_surface_id); + Surface* middle_surface = manager_.GetSurfaceForId(middle_surface_id); SurfaceId child_surface_id(9u); factory.Create(child_surface_id); + Surface* child_surface = manager_.GetSurfaceForId(child_surface_id); ResourceId ids[] = {14, 15, 16}; SubmitCompositorFrameWithResources(ids, arraysize(ids), true, SurfaceId(), @@ -1733,9 +1973,17 @@ TEST_F(SurfaceAggregatorWithResourcesTest, InvalidChildSurface) { middle_surface_id, &factory, root_surface_id); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(root_surface)); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(middle_surface)); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(child_surface)); + scoped_ptr<CompositorFrame> frame; frame = aggregator_->Aggregate(root_surface_id); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(middle_surface)); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(child_surface)); + RenderPassList* pass_list = &frame->delegated_frame_data->render_pass_list; ASSERT_EQ(1u, pass_list->size()); EXPECT_EQ(1u, pass_list->back()->shared_quad_state_list.size()); @@ -1745,8 +1993,16 @@ TEST_F(SurfaceAggregatorWithResourcesTest, InvalidChildSurface) { child_surface_id, &factory, middle_surface_id); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(middle_surface)); + EXPECT_FALSE(surface_aggregator_client_.HasSurface(child_surface)); + frame = aggregator_->Aggregate(root_surface_id); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(root_surface)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(middle_surface)); + EXPECT_TRUE(surface_aggregator_client_.HasSurface(child_surface)); + pass_list = &frame->delegated_frame_data->render_pass_list; ASSERT_EQ(1u, pass_list->size()); EXPECT_EQ(3u, pass_list->back()->shared_quad_state_list.size()); diff --git a/cc/surfaces/surface_display_output_surface.cc b/cc/surfaces/surface_display_output_surface.cc index ed26b49..9e9ade7 100644 --- a/cc/surfaces/surface_display_output_surface.cc +++ b/cc/surfaces/surface_display_output_surface.cc @@ -93,6 +93,13 @@ void SurfaceDisplayOutputSurface::ReturnResources( client_->ReclaimResources(&ack); } +void SurfaceDisplayOutputSurface::SetBeginFrameSource( + SurfaceId surface_id, + BeginFrameSource* begin_frame_source) { + // TODO(tansell): Hook this up. + NOTIMPLEMENTED(); +} + void SurfaceDisplayOutputSurface::SwapBuffersComplete(SurfaceDrawStatus drawn) { if (client_ && !display_client_->output_surface_lost()) client_->DidSwapBuffersComplete(); diff --git a/cc/surfaces/surface_display_output_surface.h b/cc/surfaces/surface_display_output_surface.h index 2cdaadc..5dbbbe0 100644 --- a/cc/surfaces/surface_display_output_surface.h +++ b/cc/surfaces/surface_display_output_surface.h @@ -45,6 +45,8 @@ class CC_SURFACES_EXPORT SurfaceDisplayOutputSurface // SurfaceFactoryClient implementation. void ReturnResources(const ReturnedResourceArray& resources) override; + void SetBeginFrameSource(SurfaceId surface_id, + BeginFrameSource* begin_frame_source) override; private: void SwapBuffersComplete(SurfaceDrawStatus drawn); diff --git a/cc/surfaces/surface_factory.cc b/cc/surfaces/surface_factory.cc index 72ebdc4..b71994e 100644 --- a/cc/surfaces/surface_factory.cc +++ b/cc/surfaces/surface_factory.cc @@ -27,6 +27,7 @@ SurfaceFactory::~SurfaceFactory() { << " entries in map on destruction."; } DestroyAll(); + client_->SetBeginFrameSource(SurfaceId(), nullptr); } void SurfaceFactory::DestroyAll() { @@ -49,6 +50,11 @@ void SurfaceFactory::Destroy(SurfaceId surface_id) { manager_->Destroy(surface_map_.take_and_erase(it)); } +void SurfaceFactory::SetBeginFrameSource(SurfaceId surface_id, + BeginFrameSource* begin_frame_source) { + client_->SetBeginFrameSource(surface_id, begin_frame_source); +} + void SurfaceFactory::SubmitCompositorFrame(SurfaceId surface_id, scoped_ptr<CompositorFrame> frame, const DrawCallback& callback) { diff --git a/cc/surfaces/surface_factory.h b/cc/surfaces/surface_factory.h index 762d5a2..1347728 100644 --- a/cc/surfaces/surface_factory.h +++ b/cc/surfaces/surface_factory.h @@ -23,6 +23,7 @@ class Size; } namespace cc { +class BeginFrameSource; class CopyOutputRequest; class Surface; class SurfaceFactoryClient; @@ -46,6 +47,10 @@ class CC_SURFACES_EXPORT SurfaceFactory void Create(SurfaceId surface_id); void Destroy(SurfaceId surface_id); void DestroyAll(); + + void SetBeginFrameSource(SurfaceId surface_id, + BeginFrameSource* begin_frame_source); + // A frame can only be submitted to a surface created by this factory, // although the frame may reference surfaces created by other factories. // The callback is called the first time this frame is used to draw, or if diff --git a/cc/surfaces/surface_factory_client.h b/cc/surfaces/surface_factory_client.h index c2a04af..e79b185 100644 --- a/cc/surfaces/surface_factory_client.h +++ b/cc/surfaces/surface_factory_client.h @@ -12,6 +12,9 @@ namespace cc { +class BeginFrameSource; +struct SurfaceId; + class CC_SURFACES_EXPORT SurfaceFactoryClient { public: virtual ~SurfaceFactoryClient() {} @@ -20,6 +23,15 @@ class CC_SURFACES_EXPORT SurfaceFactoryClient { virtual void WillDrawSurface(SurfaceId surface_id, const gfx::Rect& damage_rect) {} + + // This allows the SurfaceFactory to tell it's client what BeginFrameSource + // to use for a given surface_id. + // If there are multiple active surface_ids, it is the client's + // responsibility to pick or distribute the correct BeginFrameSource. + // If surface_id is null, then all BeginFrameSources previously + // set by this function should be invalidated. + virtual void SetBeginFrameSource(SurfaceId surface_id, + BeginFrameSource* begin_frame_source) = 0; }; } // namespace cc diff --git a/cc/surfaces/surface_factory_unittest.cc b/cc/surfaces/surface_factory_unittest.cc index 9629a4e..d516aa3 100644 --- a/cc/surfaces/surface_factory_unittest.cc +++ b/cc/surfaces/surface_factory_unittest.cc @@ -12,6 +12,7 @@ #include "cc/surfaces/surface_factory.h" #include "cc/surfaces/surface_factory_client.h" #include "cc/surfaces/surface_manager.h" +#include "cc/test/scheduler_test_common.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/geometry/size.h" @@ -20,7 +21,7 @@ namespace { class TestSurfaceFactoryClient : public SurfaceFactoryClient { public: - TestSurfaceFactoryClient() {} + TestSurfaceFactoryClient() : begin_frame_source_(nullptr) {} ~TestSurfaceFactoryClient() override {} void ReturnResources(const ReturnedResourceArray& resources) override { @@ -28,27 +29,36 @@ class TestSurfaceFactoryClient : public SurfaceFactoryClient { returned_resources_.end(), resources.begin(), resources.end()); } + void SetBeginFrameSource(SurfaceId surface_id, + BeginFrameSource* begin_frame_source) override { + begin_frame_source_ = begin_frame_source; + } + const ReturnedResourceArray& returned_resources() const { return returned_resources_; } void clear_returned_resources() { returned_resources_.clear(); } + BeginFrameSource* begin_frame_source() const { return begin_frame_source_; } + private: ReturnedResourceArray returned_resources_; + BeginFrameSource* begin_frame_source_; DISALLOW_COPY_AND_ASSIGN(TestSurfaceFactoryClient); }; class SurfaceFactoryTest : public testing::Test { public: - SurfaceFactoryTest() : factory_(&manager_, &client_), surface_id_(3) { - factory_.Create(surface_id_); + SurfaceFactoryTest() + : factory_(new SurfaceFactory(&manager_, &client_)), surface_id_(3) { + factory_->Create(surface_id_); } ~SurfaceFactoryTest() override { if (!surface_id_.is_null()) - factory_.Destroy(surface_id_); + factory_->Destroy(surface_id_); } void SubmitCompositorFrameWithResources(ResourceId* resource_ids, @@ -62,8 +72,8 @@ class SurfaceFactoryTest : public testing::Test { } scoped_ptr<CompositorFrame> frame(new CompositorFrame); frame->delegated_frame_data = frame_data.Pass(); - factory_.SubmitCompositorFrame(surface_id_, frame.Pass(), - SurfaceFactory::DrawCallback()); + factory_->SubmitCompositorFrame(surface_id_, frame.Pass(), + SurfaceFactory::DrawCallback()); } void UnrefResources(ResourceId* ids_to_unref, @@ -76,7 +86,7 @@ class SurfaceFactoryTest : public testing::Test { resource.count = counts_to_unref[i]; unref_array.push_back(resource); } - factory_.UnrefResources(unref_array); + factory_->UnrefResources(unref_array); } void CheckReturnedResourcesMatchExpected(ResourceId* expected_returned_ids, @@ -95,14 +105,14 @@ class SurfaceFactoryTest : public testing::Test { void RefCurrentFrameResources() { Surface* surface = manager_.GetSurfaceForId(surface_id_); - factory_.RefResources( + factory_->RefResources( surface->GetEligibleFrame()->delegated_frame_data->resource_list); } protected: SurfaceManager manager_; TestSurfaceFactoryClient client_; - SurfaceFactory factory_; + scoped_ptr<SurfaceFactory> factory_; SurfaceId surface_id_; }; @@ -374,17 +384,17 @@ TEST_F(SurfaceFactoryTest, ResourceLifetime) { TEST_F(SurfaceFactoryTest, BlankNoIndexIncrement) { SurfaceId surface_id(6); - factory_.Create(surface_id); + factory_->Create(surface_id); Surface* surface = manager_.GetSurfaceForId(surface_id); ASSERT_NE(nullptr, surface); EXPECT_EQ(2, surface->frame_index()); scoped_ptr<CompositorFrame> frame(new CompositorFrame); frame->delegated_frame_data.reset(new DelegatedFrameData); - factory_.SubmitCompositorFrame(surface_id, frame.Pass(), - SurfaceFactory::DrawCallback()); + factory_->SubmitCompositorFrame(surface_id, frame.Pass(), + SurfaceFactory::DrawCallback()); EXPECT_EQ(2, surface->frame_index()); - factory_.Destroy(surface_id); + factory_->Destroy(surface_id); } void DrawCallback(uint32* execute_count, @@ -397,7 +407,7 @@ void DrawCallback(uint32* execute_count, // Tests doing a DestroyAll before shutting down the factory; TEST_F(SurfaceFactoryTest, DestroyAll) { SurfaceId id(7); - factory_.Create(id); + factory_->Create(id); scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); TransferableResource resource; @@ -409,25 +419,25 @@ TEST_F(SurfaceFactoryTest, DestroyAll) { uint32 execute_count = 0; SurfaceDrawStatus drawn = SurfaceDrawStatus::DRAW_SKIPPED; - factory_.SubmitCompositorFrame( + factory_->SubmitCompositorFrame( id, frame.Pass(), base::Bind(&DrawCallback, &execute_count, &drawn)); surface_id_ = SurfaceId(); - factory_.DestroyAll(); + factory_->DestroyAll(); EXPECT_EQ(1u, execute_count); EXPECT_EQ(SurfaceDrawStatus::DRAW_SKIPPED, drawn); } TEST_F(SurfaceFactoryTest, DestroySequence) { SurfaceId id2(5); - factory_.Create(id2); + factory_->Create(id2); manager_.RegisterSurfaceIdNamespace(0); // Check that waiting before the sequence is satisfied works. manager_.GetSurfaceForId(id2) ->AddDestructionDependency(SurfaceSequence(0, 4)); - factory_.Destroy(id2); + factory_->Destroy(id2); scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); scoped_ptr<CompositorFrame> frame(new CompositorFrame); @@ -435,16 +445,16 @@ TEST_F(SurfaceFactoryTest, DestroySequence) { frame->metadata.satisfies_sequences.push_back(4); frame->delegated_frame_data = frame_data.Pass(); DCHECK(manager_.GetSurfaceForId(id2)); - factory_.SubmitCompositorFrame(surface_id_, frame.Pass(), - SurfaceFactory::DrawCallback()); + factory_->SubmitCompositorFrame(surface_id_, frame.Pass(), + SurfaceFactory::DrawCallback()); DCHECK(!manager_.GetSurfaceForId(id2)); // Check that waiting after the sequence is satisfied works. - factory_.Create(id2); + factory_->Create(id2); DCHECK(manager_.GetSurfaceForId(id2)); manager_.GetSurfaceForId(id2) ->AddDestructionDependency(SurfaceSequence(0, 6)); - factory_.Destroy(id2); + factory_->Destroy(id2); DCHECK(!manager_.GetSurfaceForId(id2)); } @@ -453,12 +463,12 @@ TEST_F(SurfaceFactoryTest, DestroySequence) { TEST_F(SurfaceFactoryTest, InvalidIdNamespace) { uint32_t id_namespace = 9u; SurfaceId id(5); - factory_.Create(id); + factory_->Create(id); manager_.RegisterSurfaceIdNamespace(id_namespace); manager_.GetSurfaceForId(id) ->AddDestructionDependency(SurfaceSequence(id_namespace, 4)); - factory_.Destroy(id); + factory_->Destroy(id); // Verify the dependency has prevented the surface from getting destroyed. EXPECT_TRUE(manager_.GetSurfaceForId(id)); @@ -472,7 +482,7 @@ TEST_F(SurfaceFactoryTest, InvalidIdNamespace) { TEST_F(SurfaceFactoryTest, DestroyCycle) { SurfaceId id2(5); - factory_.Create(id2); + factory_->Create(id2); manager_.RegisterSurfaceIdNamespace(0); @@ -487,10 +497,10 @@ TEST_F(SurfaceFactoryTest, DestroyCycle) { frame_data->render_pass_list.push_back(render_pass.Pass()); scoped_ptr<CompositorFrame> frame(new CompositorFrame); frame->delegated_frame_data = frame_data.Pass(); - factory_.SubmitCompositorFrame(id2, frame.Pass(), - SurfaceFactory::DrawCallback()); + factory_->SubmitCompositorFrame(id2, frame.Pass(), + SurfaceFactory::DrawCallback()); } - factory_.Destroy(id2); + factory_->Destroy(id2); // Give surface_id_ a frame that references id2. { @@ -500,10 +510,10 @@ TEST_F(SurfaceFactoryTest, DestroyCycle) { frame_data->render_pass_list.push_back(render_pass.Pass()); scoped_ptr<CompositorFrame> frame(new CompositorFrame); frame->delegated_frame_data = frame_data.Pass(); - factory_.SubmitCompositorFrame(surface_id_, frame.Pass(), - SurfaceFactory::DrawCallback()); + factory_->SubmitCompositorFrame(surface_id_, frame.Pass(), + SurfaceFactory::DrawCallback()); } - factory_.Destroy(surface_id_); + factory_->Destroy(surface_id_); EXPECT_TRUE(manager_.GetSurfaceForId(id2)); // surface_id_ should be retained by reference from id2. EXPECT_TRUE(manager_.GetSurfaceForId(surface_id_)); @@ -534,8 +544,8 @@ TEST_F(SurfaceFactoryTest, DuplicateCopyRequest) { frame_data->render_pass_list.push_back(render_pass.Pass()); scoped_ptr<CompositorFrame> frame(new CompositorFrame); frame->delegated_frame_data = frame_data.Pass(); - factory_.SubmitCompositorFrame(surface_id_, frame.Pass(), - SurfaceFactory::DrawCallback()); + factory_->SubmitCompositorFrame(surface_id_, frame.Pass(), + SurfaceFactory::DrawCallback()); } void* source1 = &source1; void* source2 = &source2; @@ -546,7 +556,7 @@ TEST_F(SurfaceFactoryTest, DuplicateCopyRequest) { base::Bind(&CopyRequestTestCallback, &called1)); request->set_source(source1); - factory_.RequestCopyOfSurface(surface_id_, request.Pass()); + factory_->RequestCopyOfSurface(surface_id_, request.Pass()); EXPECT_FALSE(called1); bool called2 = false; @@ -554,7 +564,7 @@ TEST_F(SurfaceFactoryTest, DuplicateCopyRequest) { base::Bind(&CopyRequestTestCallback, &called2)); request->set_source(source2); - factory_.RequestCopyOfSurface(surface_id_, request.Pass()); + factory_->RequestCopyOfSurface(surface_id_, request.Pass()); // Callbacks have different sources so neither should be called. EXPECT_FALSE(called1); EXPECT_FALSE(called2); @@ -564,18 +574,49 @@ TEST_F(SurfaceFactoryTest, DuplicateCopyRequest) { base::Bind(&CopyRequestTestCallback, &called3)); request->set_source(source1); - factory_.RequestCopyOfSurface(surface_id_, request.Pass()); + factory_->RequestCopyOfSurface(surface_id_, request.Pass()); // Two callbacks are from source1, so the first should be called. EXPECT_TRUE(called1); EXPECT_FALSE(called2); EXPECT_FALSE(called3); - factory_.Destroy(surface_id_); + factory_->Destroy(surface_id_); surface_id_ = SurfaceId(); EXPECT_TRUE(called1); EXPECT_TRUE(called2); EXPECT_TRUE(called3); } +// Verifies BFS is forwarded to the client. +TEST_F(SurfaceFactoryTest, SetBeginFrameSource) { + FakeBeginFrameSource bfs1; + FakeBeginFrameSource bfs2; + EXPECT_EQ(nullptr, client_.begin_frame_source()); + factory_->SetBeginFrameSource(surface_id_, &bfs1); + EXPECT_EQ(&bfs1, client_.begin_frame_source()); + factory_->SetBeginFrameSource(surface_id_, &bfs2); + EXPECT_EQ(&bfs2, client_.begin_frame_source()); + factory_->SetBeginFrameSource(surface_id_, nullptr); + EXPECT_EQ(nullptr, client_.begin_frame_source()); +} + +TEST_F(SurfaceFactoryTest, BeginFrameSourceRemovedOnFactoryDestruction) { + FakeBeginFrameSource bfs; + factory_->SetBeginFrameSource(surface_id_, &bfs); + EXPECT_EQ(&bfs, client_.begin_frame_source()); + + // Prevent the Surface from being destroyed when we destroy the factory. + manager_.RegisterSurfaceIdNamespace(0); + manager_.GetSurfaceForId(surface_id_) + ->AddDestructionDependency(SurfaceSequence(0, 4)); + + surface_id_ = SurfaceId(); + factory_->DestroyAll(); + + EXPECT_EQ(&bfs, client_.begin_frame_source()); + factory_.reset(); + EXPECT_EQ(nullptr, client_.begin_frame_source()); +} + } // namespace } // namespace cc diff --git a/cc/surfaces/surface_hittest_unittest.cc b/cc/surfaces/surface_hittest_unittest.cc index ac9e3bc..92c61b8 100644 --- a/cc/surfaces/surface_hittest_unittest.cc +++ b/cc/surfaces/surface_hittest_unittest.cc @@ -55,6 +55,8 @@ void RunTests(SurfaceManager* manager, TestCase* tests, size_t test_count) { class EmptySurfaceFactoryClient : public SurfaceFactoryClient { public: void ReturnResources(const ReturnedResourceArray& resources) override {} + void SetBeginFrameSource(SurfaceId surface_id, + BeginFrameSource* begin_frame_source) override {} }; void CreateSharedQuadState(RenderPass* pass, diff --git a/cc/surfaces/surface_unittest.cc b/cc/surfaces/surface_unittest.cc index 42fd55f..5a9b744 100644 --- a/cc/surfaces/surface_unittest.cc +++ b/cc/surfaces/surface_unittest.cc @@ -4,16 +4,36 @@ #include "cc/surfaces/surface.h" #include "cc/surfaces/surface_factory.h" +#include "cc/surfaces/surface_factory_client.h" #include "cc/surfaces/surface_manager.h" +#include "cc/test/scheduler_test_common.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/geometry/size.h" namespace cc { namespace { +class FakeSurfaceFactoryClient : public SurfaceFactoryClient { + public: + FakeSurfaceFactoryClient() : begin_frame_source_(nullptr) {} + + void ReturnResources(const ReturnedResourceArray& resources) override {} + + void SetBeginFrameSource(SurfaceId surface_id, + BeginFrameSource* begin_frame_source) override { + begin_frame_source_ = begin_frame_source; + } + + BeginFrameSource* begin_frame_source() { return begin_frame_source_; } + + private: + BeginFrameSource* begin_frame_source_; +}; + TEST(SurfaceTest, SurfaceLifetime) { SurfaceManager manager; - SurfaceFactory factory(&manager, NULL); + FakeSurfaceFactoryClient surface_factory_client; + SurfaceFactory factory(&manager, &surface_factory_client); SurfaceId surface_id(6); { @@ -25,5 +45,111 @@ TEST(SurfaceTest, SurfaceLifetime) { EXPECT_EQ(NULL, manager.GetSurfaceForId(surface_id)); } +TEST(SurfaceTest, StableBeginFrameSourceIndependentOfOrderAdded) { + SurfaceManager manager; + FakeSurfaceFactoryClient surface_factory_client; + SurfaceFactory factory(&manager, &surface_factory_client); + + SurfaceId surface_id(6); + factory.Create(surface_id); + Surface* surface = manager.GetSurfaceForId(surface_id); + + FakeBeginFrameSource bfs1; + FakeBeginFrameSource bfs2; + FakeBeginFrameSource bfs3; + + // Order 1. + surface->AddBeginFrameSource(&bfs1); + surface->AddBeginFrameSource(&bfs2); + surface->AddBeginFrameSource(&bfs3); + BeginFrameSource* bfs_order1 = surface_factory_client.begin_frame_source(); + // Make sure one of the provided sources was chosen. + EXPECT_TRUE(&bfs1 == bfs_order1 || &bfs2 == bfs_order1 || + &bfs3 == bfs_order1); + surface->RemoveBeginFrameSource(&bfs1); + surface->RemoveBeginFrameSource(&bfs2); + surface->RemoveBeginFrameSource(&bfs3); + EXPECT_EQ(nullptr, surface_factory_client.begin_frame_source()); + + // Order 2. + surface->AddBeginFrameSource(&bfs1); + surface->AddBeginFrameSource(&bfs3); + surface->AddBeginFrameSource(&bfs2); + BeginFrameSource* bfs_order2 = surface_factory_client.begin_frame_source(); + // Verify choice is same as before. + EXPECT_EQ(bfs_order1, bfs_order2); + surface->RemoveBeginFrameSource(&bfs1); + surface->RemoveBeginFrameSource(&bfs2); + surface->RemoveBeginFrameSource(&bfs3); + EXPECT_EQ(nullptr, surface_factory_client.begin_frame_source()); + + // Order 3. + surface->AddBeginFrameSource(&bfs2); + surface->AddBeginFrameSource(&bfs1); + surface->AddBeginFrameSource(&bfs3); + BeginFrameSource* bfs_order3 = surface_factory_client.begin_frame_source(); + // Verify choice is same as before. + EXPECT_EQ(bfs_order2, bfs_order3); + surface->RemoveBeginFrameSource(&bfs1); + surface->RemoveBeginFrameSource(&bfs2); + surface->RemoveBeginFrameSource(&bfs3); + EXPECT_EQ(nullptr, surface_factory_client.begin_frame_source()); + + // Order 4. + surface->AddBeginFrameSource(&bfs2); + surface->AddBeginFrameSource(&bfs3); + surface->AddBeginFrameSource(&bfs1); + BeginFrameSource* bfs_order4 = surface_factory_client.begin_frame_source(); + // Verify choice is same as before. + EXPECT_EQ(bfs_order3, bfs_order4); + surface->RemoveBeginFrameSource(&bfs1); + surface->RemoveBeginFrameSource(&bfs2); + surface->RemoveBeginFrameSource(&bfs3); + EXPECT_EQ(nullptr, surface_factory_client.begin_frame_source()); + + // Order 5. + surface->AddBeginFrameSource(&bfs3); + surface->AddBeginFrameSource(&bfs1); + surface->AddBeginFrameSource(&bfs2); + BeginFrameSource* bfs_order5 = surface_factory_client.begin_frame_source(); + // Verify choice is same as before. + EXPECT_EQ(bfs_order4, bfs_order5); + surface->RemoveBeginFrameSource(&bfs1); + surface->RemoveBeginFrameSource(&bfs2); + surface->RemoveBeginFrameSource(&bfs3); + EXPECT_EQ(nullptr, surface_factory_client.begin_frame_source()); + + // Order 6. + surface->AddBeginFrameSource(&bfs3); + surface->AddBeginFrameSource(&bfs2); + surface->AddBeginFrameSource(&bfs1); + BeginFrameSource* bfs_order6 = surface_factory_client.begin_frame_source(); + // Verify choice is same as before. + EXPECT_EQ(bfs_order5, bfs_order6); + surface->RemoveBeginFrameSource(&bfs1); + surface->RemoveBeginFrameSource(&bfs2); + surface->RemoveBeginFrameSource(&bfs3); + EXPECT_EQ(nullptr, surface_factory_client.begin_frame_source()); +} + +TEST(SurfaceTest, BeginFrameSourceRemovedOnSurfaceDestruction) { + SurfaceManager manager; + FakeSurfaceFactoryClient surface_factory_client; + SurfaceFactory factory(&manager, &surface_factory_client); + FakeBeginFrameSource bfs; + + SurfaceId surface_id(6); + factory.Create(surface_id); + Surface* surface = manager.GetSurfaceForId(surface_id); + surface->AddBeginFrameSource(&bfs); + + BeginFrameSource* bfs_before = surface_factory_client.begin_frame_source(); + factory.Destroy(surface_id); + BeginFrameSource* bfs_after = surface_factory_client.begin_frame_source(); + + EXPECT_EQ(&bfs, bfs_before); + EXPECT_EQ(nullptr, bfs_after); +} + } // namespace } // namespace cc diff --git a/cc/surfaces/surfaces_pixeltest.cc b/cc/surfaces/surfaces_pixeltest.cc index a584f7c..f0903f2 100644 --- a/cc/surfaces/surfaces_pixeltest.cc +++ b/cc/surfaces/surfaces_pixeltest.cc @@ -24,6 +24,14 @@ namespace { class EmptySurfaceFactoryClient : public SurfaceFactoryClient { public: void ReturnResources(const ReturnedResourceArray& resources) override {} + void SetBeginFrameSource(SurfaceId surface_id, + BeginFrameSource* begin_frame_source) override {} +}; + +class EmptySurfaceAggregatorClient : public SurfaceAggregatorClient { + public: + void AddSurface(Surface* surface) override {} + void RemoveSurface(Surface* surface) override {} }; class SurfacesPixelTest : public RendererPixelTest<GLRenderer> { @@ -83,7 +91,9 @@ TEST_F(SurfacesPixelTest, DrawSimpleFrame) { factory_.SubmitCompositorFrame(root_surface_id, root_frame.Pass(), SurfaceFactory::DrawCallback()); - SurfaceAggregator aggregator(&manager_, resource_provider_.get(), true); + EmptySurfaceAggregatorClient surface_aggregator_client; + SurfaceAggregator aggregator(&surface_aggregator_client, &manager_, + resource_provider_.get(), true); scoped_ptr<CompositorFrame> aggregated_frame = aggregator.Aggregate(root_surface_id); factory_.Destroy(root_surface_id); @@ -167,7 +177,9 @@ TEST_F(SurfacesPixelTest, DrawSimpleAggregatedFrame) { SurfaceFactory::DrawCallback()); } - SurfaceAggregator aggregator(&manager_, resource_provider_.get(), true); + EmptySurfaceAggregatorClient surface_aggregator_client; + SurfaceAggregator aggregator(&surface_aggregator_client, &manager_, + resource_provider_.get(), true); scoped_ptr<CompositorFrame> aggregated_frame = aggregator.Aggregate(root_surface_id); @@ -310,7 +322,9 @@ TEST_F(SurfacesPixelTest, DrawAggregatedFrameWithSurfaceTransforms) { SurfaceFactory::DrawCallback()); } - SurfaceAggregator aggregator(&manager_, resource_provider_.get(), true); + EmptySurfaceAggregatorClient surface_aggregator_client; + SurfaceAggregator aggregator(&surface_aggregator_client, &manager_, + resource_provider_.get(), true); scoped_ptr<CompositorFrame> aggregated_frame = aggregator.Aggregate(root_surface_id); diff --git a/components/mus/surfaces/top_level_display_client.cc b/components/mus/surfaces/top_level_display_client.cc index aba70d0..e84cf74 100644 --- a/components/mus/surfaces/top_level_display_client.cc +++ b/components/mus/surfaces/top_level_display_client.cc @@ -100,4 +100,11 @@ void TopLevelDisplayClient::ReturnResources( // TODO(fsamuel): Implement this. } +void TopLevelDisplayClient::SetBeginFrameSource( + cc::SurfaceId surface_id, + cc::BeginFrameSource* begin_frame_source) { + // TODO(tansell): Implement this. + NOTIMPLEMENTED(); +} + } // namespace mus diff --git a/components/mus/surfaces/top_level_display_client.h b/components/mus/surfaces/top_level_display_client.h index 0b58da1..f66999c 100644 --- a/components/mus/surfaces/top_level_display_client.h +++ b/components/mus/surfaces/top_level_display_client.h @@ -56,6 +56,8 @@ class TopLevelDisplayClient : public cc::DisplayClient, // SurfaceFactoryClient implementation. void ReturnResources(const cc::ReturnedResourceArray& resources) override; + void SetBeginFrameSource(cc::SurfaceId surface_id, + cc::BeginFrameSource* begin_frame_source) override; scoped_refptr<SurfacesState> surfaces_state_; cc::SurfaceFactory factory_; diff --git a/components/mus/ws/server_window_surface.cc b/components/mus/ws/server_window_surface.cc index 9e1a472..ef42bd095 100644 --- a/components/mus/ws/server_window_surface.cc +++ b/components/mus/ws/server_window_surface.cc @@ -111,6 +111,13 @@ void ServerWindowSurface::ReturnResources( mojo::Array<mojom::ReturnedResourcePtr>::From(resources)); } +void ServerWindowSurface::SetBeginFrameSource( + cc::SurfaceId surface_id, + cc::BeginFrameSource* begin_frame_source) { + // TODO(tansell): Implement this. + NOTIMPLEMENTED(); +} + } // namespace ws } // namespace mus diff --git a/components/mus/ws/server_window_surface.h b/components/mus/ws/server_window_surface.h index fb70263..bdf24a1 100644 --- a/components/mus/ws/server_window_surface.h +++ b/components/mus/ws/server_window_surface.h @@ -65,6 +65,8 @@ class ServerWindowSurface : public mojom::Surface, // SurfaceFactoryClient implementation. void ReturnResources(const cc::ReturnedResourceArray& resources) override; + void SetBeginFrameSource(cc::SurfaceId surface_id, + cc::BeginFrameSource* begin_frame_source) override; // |window_| owns |this|. ServerWindow* const window_; diff --git a/content/browser/compositor/delegated_frame_host.cc b/content/browser/compositor/delegated_frame_host.cc index ca8a0d87..8824726 100644 --- a/content/browser/compositor/delegated_frame_host.cc +++ b/content/browser/compositor/delegated_frame_host.cc @@ -557,6 +557,13 @@ void DelegatedFrameHost::WillDrawSurface(cc::SurfaceId id, AttemptFrameSubscriberCapture(damage_rect); } +void DelegatedFrameHost::SetBeginFrameSource( + cc::SurfaceId surface_id, + cc::BeginFrameSource* begin_frame_source) { + // TODO(tansell): Hook this up. + NOTIMPLEMENTED(); +} + void DelegatedFrameHost::EvictDelegatedFrame() { client_->DelegatedFrameHostGetLayer()->SetShowSolidColorContent(); frame_provider_ = NULL; diff --git a/content/browser/compositor/delegated_frame_host.h b/content/browser/compositor/delegated_frame_host.h index c9662cb..64bd04f1 100644 --- a/content/browser/compositor/delegated_frame_host.h +++ b/content/browser/compositor/delegated_frame_host.h @@ -117,6 +117,8 @@ class CONTENT_EXPORT DelegatedFrameHost // cc::SurfaceFactoryClient implementation. void ReturnResources(const cc::ReturnedResourceArray& resources) override; void WillDrawSurface(cc::SurfaceId id, const gfx::Rect& damage_rect) override; + void SetBeginFrameSource(cc::SurfaceId surface_id, + cc::BeginFrameSource* begin_frame_source) override; bool CanCopyToBitmap() const; diff --git a/content/browser/frame_host/render_widget_host_view_child_frame.cc b/content/browser/frame_host/render_widget_host_view_child_frame.cc index 88bf587..8cf5a96 100644 --- a/content/browser/frame_host/render_widget_host_view_child_frame.cc +++ b/content/browser/frame_host/render_widget_host_view_child_frame.cc @@ -461,6 +461,13 @@ void RenderWidgetHostViewChildFrame::ReturnResources( std::back_inserter(surface_returned_resources_)); } +void RenderWidgetHostViewChildFrame::SetBeginFrameSource( + cc::SurfaceId surface_id, + cc::BeginFrameSource* begin_frame_source) { + // TODO(tansell): Hook this up. + NOTIMPLEMENTED(); +} + BrowserAccessibilityManager* RenderWidgetHostViewChildFrame::CreateBrowserAccessibilityManager( BrowserAccessibilityDelegate* delegate) { diff --git a/content/browser/frame_host/render_widget_host_view_child_frame.h b/content/browser/frame_host/render_widget_host_view_child_frame.h index 68fed30..b9a0e78 100644 --- a/content/browser/frame_host/render_widget_host_view_child_frame.h +++ b/content/browser/frame_host/render_widget_host_view_child_frame.h @@ -154,6 +154,8 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame // cc::SurfaceFactoryClient implementation. void ReturnResources(const cc::ReturnedResourceArray& resources) override; + void SetBeginFrameSource(cc::SurfaceId surface_id, + cc::BeginFrameSource* begin_frame_source) override; // Declared 'public' instead of 'protected' here to allow derived classes // to Bind() to it. diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc index 97809f0..b096806 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/content/browser/renderer_host/render_widget_host_view_android.cc @@ -984,6 +984,13 @@ void RenderWidgetHostViewAndroid::ReturnResources( SendReturnedDelegatedResources(last_output_surface_id_); } +void RenderWidgetHostViewAndroid::SetBeginFrameSource( + cc::SurfaceId surface_id, + cc::BeginFrameSource* begin_frame_source) { + // TODO(tansell): Hook this up. + NOTIMPLEMENTED(); +} + void RenderWidgetHostViewAndroid::DestroyDelegatedContent() { RemoveLayers(); frame_provider_ = NULL; diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h index 541a356..8db9451 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.h +++ b/content/browser/renderer_host/render_widget_host_view_android.h @@ -169,6 +169,8 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid // cc::SurfaceFactoryClient implementation. void ReturnResources(const cc::ReturnedResourceArray& resources) override; + void SetBeginFrameSource(cc::SurfaceId surface_id, + cc::BeginFrameSource* begin_frame_source) override; // ui::GestureProviderClient implementation. void OnGestureEvent(const ui::GestureEventData& gesture) override; |