summaryrefslogtreecommitdiffstats
path: root/cc/surfaces
diff options
context:
space:
mode:
authorbrianderson <brianderson@chromium.org>2015-10-20 13:35:31 -0700
committerCommit bot <commit-bot@chromium.org>2015-10-20 20:36:33 +0000
commit877996b0753f32b67fac2835756d23f476e72f10 (patch)
treee33de9848de316fb45daa59de60eecf7b47d0d62 /cc/surfaces
parente020927c5d71942748f67c25c347d1355dd11135 (diff)
downloadchromium_src-877996b0753f32b67fac2835756d23f476e72f10.zip
chromium_src-877996b0753f32b67fac2835756d23f476e72f10.tar.gz
chromium_src-877996b0753f32b67fac2835756d23f476e72f10.tar.bz2
cc: Plumbing for BeginFrameSource based on Surfaces
This patch makes a stable decision about which Display a Surface belongs to and notifies the corresponding SurfaceFactoryClient of the BeginFrameSource belonging to that Display. The stable decision is based on the sorted order of Display pointers that the Surface currently belongs to. This is only plumbing - the actual endpoints (BeginFrameSource to use and what to do with that BeginFrameSource) still need to be hooked up. R=jbauman,mithro BUG=401331, 471411 CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel Review URL: https://codereview.chromium.org/1304063014 Cr-Commit-Position: refs/heads/master@{#355140}
Diffstat (limited to 'cc/surfaces')
-rw-r--r--cc/surfaces/display.cc29
-rw-r--r--cc/surfaces/display.h7
-rw-r--r--cc/surfaces/display_scheduler.cc4
-rw-r--r--cc/surfaces/display_scheduler.h7
-rw-r--r--cc/surfaces/display_unittest.cc45
-rw-r--r--cc/surfaces/onscreen_display_client.cc5
-rw-r--r--cc/surfaces/onscreen_display_client.h7
-rw-r--r--cc/surfaces/surface.cc31
-rw-r--r--cc/surfaces/surface.h9
-rw-r--r--cc/surfaces/surface_aggregator.cc46
-rw-r--r--cc/surfaces/surface_aggregator.h18
-rw-r--r--cc/surfaces/surface_aggregator_perftest.cc12
-rw-r--r--cc/surfaces/surface_aggregator_unittest.cc290
-rw-r--r--cc/surfaces/surface_display_output_surface.cc7
-rw-r--r--cc/surfaces/surface_display_output_surface.h2
-rw-r--r--cc/surfaces/surface_factory.cc6
-rw-r--r--cc/surfaces/surface_factory.h5
-rw-r--r--cc/surfaces/surface_factory_client.h12
-rw-r--r--cc/surfaces/surface_factory_unittest.cc115
-rw-r--r--cc/surfaces/surface_hittest_unittest.cc2
-rw-r--r--cc/surfaces/surface_unittest.cc128
-rw-r--r--cc/surfaces/surfaces_pixeltest.cc20
22 files changed, 723 insertions, 84 deletions
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);