diff options
Diffstat (limited to 'cc')
-rw-r--r-- | cc/surfaces/display.cc | 13 | ||||
-rw-r--r-- | cc/surfaces/display.h | 2 | ||||
-rw-r--r-- | cc/surfaces/surface.cc | 10 | ||||
-rw-r--r-- | cc/surfaces/surface.h | 4 | ||||
-rw-r--r-- | cc/surfaces/surface_aggregator.cc | 41 | ||||
-rw-r--r-- | cc/surfaces/surface_aggregator.h | 20 | ||||
-rw-r--r-- | cc/surfaces/surface_aggregator_unittest.cc | 201 | ||||
-rw-r--r-- | cc/surfaces/surfaces_pixeltest.cc | 9 |
8 files changed, 246 insertions, 54 deletions
diff --git a/cc/surfaces/display.cc b/cc/surfaces/display.cc index 4e01b70..70367e4 100644 --- a/cc/surfaces/display.cc +++ b/cc/surfaces/display.cc @@ -89,10 +89,8 @@ bool Display::Draw() { if (!output_surface_) return false; - contained_surfaces_.clear(); - scoped_ptr<CompositorFrame> frame = - aggregator_->Aggregate(current_surface_id_, &contained_surfaces_); + aggregator_->Aggregate(current_surface_id_); if (!frame) return false; @@ -116,10 +114,11 @@ bool Display::Draw() { disable_picture_quad_image_filtering); CompositorFrameMetadata metadata; renderer_->SwapBuffers(metadata); - for (std::set<SurfaceId>::iterator it = contained_surfaces_.begin(); - it != contained_surfaces_.end(); + for (SurfaceAggregator::SurfaceIndexMap::iterator it = + aggregator_->previous_contained_surfaces().begin(); + it != aggregator_->previous_contained_surfaces().end(); ++it) { - Surface* surface = manager_->GetSurfaceForId(*it); + Surface* surface = manager_->GetSurfaceForId(it->first); if (surface) surface->RunDrawCallbacks(); } @@ -127,7 +126,7 @@ bool Display::Draw() { } void Display::OnSurfaceDamaged(SurfaceId surface) { - if (contained_surfaces_.find(surface) != contained_surfaces_.end()) + if (aggregator_ && aggregator_->previous_contained_surfaces().count(surface)) client_->DisplayDamaged(); } diff --git a/cc/surfaces/display.h b/cc/surfaces/display.h index a5501cb..57d6af4 100644 --- a/cc/surfaces/display.h +++ b/cc/surfaces/display.h @@ -89,8 +89,6 @@ class CC_SURFACES_EXPORT Display : public OutputSurfaceClient, scoped_ptr<SurfaceAggregator> aggregator_; scoped_ptr<DirectRenderer> renderer_; - std::set<SurfaceId> contained_surfaces_; - DISALLOW_COPY_AND_ASSIGN(Display); }; diff --git a/cc/surfaces/surface.cc b/cc/surfaces/surface.cc index 32d6395..b3565a5 100644 --- a/cc/surfaces/surface.cc +++ b/cc/surfaces/surface.cc @@ -9,8 +9,15 @@ namespace cc { +// The frame index starts at 2 so that empty frames will be treated as +// completely damaged the first time they're drawn from. +static const int kFrameIndexStart = 2; + Surface::Surface(SurfaceId id, const gfx::Size& size, SurfaceFactory* factory) - : surface_id_(id), size_(size), factory_(factory) { + : surface_id_(id), + size_(size), + factory_(factory), + frame_index_(kFrameIndexStart) { } Surface::~Surface() { @@ -29,6 +36,7 @@ void Surface::QueueFrame(scoped_ptr<CompositorFrame> frame, current_frame_ = frame.Pass(); factory_->ReceiveFromChild( current_frame_->delegated_frame_data->resource_list); + ++frame_index_; if (previous_frame) { ReturnedResourceArray previous_resources; diff --git a/cc/surfaces/surface.h b/cc/surfaces/surface.h index c76530b..b12c34f 100644 --- a/cc/surfaces/surface.h +++ b/cc/surfaces/surface.h @@ -32,6 +32,9 @@ class CC_SURFACES_EXPORT Surface { // Returns the most recent frame that is eligible to be rendered. const CompositorFrame* GetEligibleFrame(); + // Returns a number that increments by 1 every time a new frame is enqueued. + int frame_index() const { return frame_index_; } + void RunDrawCallbacks(); SurfaceFactory* factory() { return factory_; } @@ -42,6 +45,7 @@ class CC_SURFACES_EXPORT Surface { SurfaceFactory* factory_; // TODO(jamesr): Support multiple frames in flight. scoped_ptr<CompositorFrame> current_frame_; + int frame_index_; base::Closure draw_callback_; diff --git a/cc/surfaces/surface_aggregator.cc b/cc/surfaces/surface_aggregator.cc index f9ef036..5ddd832 100644 --- a/cc/surfaces/surface_aggregator.cc +++ b/cc/surfaces/surface_aggregator.cc @@ -132,17 +132,29 @@ bool SurfaceAggregator::TakeResources(Surface* surface, return invalid_frame; } +gfx::Rect SurfaceAggregator::DamageRectForSurface(const Surface* surface, + const RenderPass& source) { + int previous_index = previous_contained_surfaces_[surface->surface_id()]; + if (previous_index == surface->frame_index()) + return gfx::Rect(); + else if (previous_index == surface->frame_index() - 1) + return source.damage_rect; + return gfx::Rect(surface->size()); +} + void SurfaceAggregator::HandleSurfaceQuad(const SurfaceDrawQuad* surface_quad, RenderPass* dest_pass) { SurfaceId surface_id = surface_quad->surface_id; - contained_surfaces_->insert(surface_id); // If this surface's id is already in our referenced set then it creates // a cycle in the graph and should be dropped. if (referenced_surfaces_.count(surface_id)) return; Surface* surface = manager_->GetSurfaceForId(surface_id); - if (!surface) + if (!surface) { + contained_surfaces_[surface_id] = 0; return; + } + contained_surfaces_[surface_id] = surface->frame_index(); const CompositorFrame* frame = surface->GetEligibleFrame(); if (!frame) return; @@ -198,6 +210,11 @@ void SurfaceAggregator::HandleSurfaceQuad(const SurfaceDrawQuad* surface_quad, surface_quad->quadTransform(), dest_pass, surface_id); + dest_pass->damage_rect = + gfx::UnionRects(dest_pass->damage_rect, + MathUtil::MapEnclosingClippedRect( + surface_quad->quadTransform(), + DamageRectForSurface(surface, last_pass))); referenced_surfaces_.erase(it); } @@ -268,17 +285,18 @@ void SurfaceAggregator::CopyQuadsToPass( } void SurfaceAggregator::CopyPasses(const RenderPassList& source_pass_list, - SurfaceId surface_id) { + const Surface* surface) { for (size_t i = 0; i < source_pass_list.size(); ++i) { const RenderPass& source = *source_pass_list[i]; scoped_ptr<RenderPass> copy_pass(RenderPass::Create()); - RenderPassId remapped_pass_id = RemapPassId(source.id, surface_id); + RenderPassId remapped_pass_id = + RemapPassId(source.id, surface->surface_id()); copy_pass->SetAll(remapped_pass_id, source.output_rect, - source.damage_rect, + DamageRectForSurface(surface, source), source.transform_to_root_target, source.has_transparent_background); @@ -286,19 +304,16 @@ void SurfaceAggregator::CopyPasses(const RenderPassList& source_pass_list, source.shared_quad_state_list, gfx::Transform(), copy_pass.get(), - surface_id); + surface->surface_id()); dest_pass_list_->push_back(copy_pass.Pass()); } } -scoped_ptr<CompositorFrame> SurfaceAggregator::Aggregate( - SurfaceId surface_id, - std::set<SurfaceId>* contained_surfaces) { - contained_surfaces_ = contained_surfaces; - contained_surfaces_->insert(surface_id); +scoped_ptr<CompositorFrame> SurfaceAggregator::Aggregate(SurfaceId surface_id) { Surface* surface = manager_->GetSurfaceForId(surface_id); DCHECK(surface); + contained_surfaces_[surface_id] = surface->frame_index(); const CompositorFrame* root_surface_frame = surface->GetEligibleFrame(); if (!root_surface_frame) return scoped_ptr<CompositorFrame>(); @@ -322,12 +337,14 @@ scoped_ptr<CompositorFrame> SurfaceAggregator::Aggregate( &source_pass_list); DCHECK(!invalid_frame); - CopyPasses(source_pass_list, surface_id); + CopyPasses(source_pass_list, surface); referenced_surfaces_.erase(it); DCHECK(referenced_surfaces_.empty()); dest_pass_list_ = NULL; + contained_surfaces_.swap(previous_contained_surfaces_); + contained_surfaces_.clear(); // TODO(jamesr): Aggregate all resource references into the returned frame's // resource list. diff --git a/cc/surfaces/surface_aggregator.h b/cc/surfaces/surface_aggregator.h index 65174b5..5e91c87 100644 --- a/cc/surfaces/surface_aggregator.h +++ b/cc/surfaces/surface_aggregator.h @@ -26,12 +26,15 @@ class SurfaceManager; class CC_SURFACES_EXPORT SurfaceAggregator { public: + typedef base::hash_map<SurfaceId, int> SurfaceIndexMap; + SurfaceAggregator(SurfaceManager* manager, ResourceProvider* provider); ~SurfaceAggregator(); - scoped_ptr<CompositorFrame> Aggregate( - SurfaceId surface_id, - std::set<SurfaceId>* contained_surfaces); + scoped_ptr<CompositorFrame> Aggregate(SurfaceId surface_id); + SurfaceIndexMap& previous_contained_surfaces() { + return previous_contained_surfaces_; + } private: RenderPassId RemapPassId(RenderPassId surface_local_pass_id, @@ -47,12 +50,15 @@ class CC_SURFACES_EXPORT SurfaceAggregator { const gfx::Transform& content_to_target_transform, RenderPass* dest_pass, SurfaceId surface_id); - void CopyPasses(const RenderPassList& source_pass_list, SurfaceId surface_id); + void CopyPasses(const RenderPassList& source_pass_list, + const Surface* surface); bool TakeResources(Surface* surface, const DelegatedFrameData* frame_data, RenderPassList* render_pass_list); int ChildIdForSurface(Surface* surface); + gfx::Rect DamageRectForSurface(const Surface* surface, + const RenderPass& source); SurfaceManager* manager_; ResourceProvider* provider_; @@ -74,8 +80,10 @@ class CC_SURFACES_EXPORT SurfaceAggregator { typedef std::set<SurfaceId> SurfaceSet; SurfaceSet referenced_surfaces_; - // This is the set of surfaces that were used in the last draw. - SurfaceSet* contained_surfaces_; + // For each Surface used in the last aggregation, gives the frame_index at + // that time. + SurfaceIndexMap previous_contained_surfaces_; + SurfaceIndexMap contained_surfaces_; // This is the pass list for the aggregated frame. RenderPassList* dest_pass_list_; diff --git a/cc/surfaces/surface_aggregator_unittest.cc b/cc/surfaces/surface_aggregator_unittest.cc index cd857ba..50b21db 100644 --- a/cc/surfaces/surface_aggregator_unittest.cc +++ b/cc/surfaces/surface_aggregator_unittest.cc @@ -61,9 +61,7 @@ class SurfaceAggregatorTest : public testing::Test { TEST_F(SurfaceAggregatorTest, ValidSurfaceNoFrame) { SurfaceId one_id(7); factory_.Create(one_id, SurfaceSize()); - std::set<SurfaceId> surface_set; - scoped_ptr<CompositorFrame> frame = - aggregator_.Aggregate(one_id, &surface_set); + scoped_ptr<CompositorFrame> frame = aggregator_.Aggregate(one_id); EXPECT_FALSE(frame); factory_.Destroy(one_id); } @@ -87,9 +85,8 @@ class SurfaceAggregatorValidSurfaceTest : public SurfaceAggregatorTest { size_t expected_pass_count, SurfaceId* surface_ids, size_t expected_surface_count) { - std::set<SurfaceId> surface_set; scoped_ptr<CompositorFrame> aggregated_frame = - aggregator_.Aggregate(root_surface_id_, &surface_set); + aggregator_.Aggregate(root_surface_id_); ASSERT_TRUE(aggregated_frame); ASSERT_TRUE(aggregated_frame->delegated_frame_data); @@ -100,9 +97,12 @@ class SurfaceAggregatorValidSurfaceTest : public SurfaceAggregatorTest { TestPassesMatchExpectations( expected_passes, expected_pass_count, &frame_data->render_pass_list); - EXPECT_EQ(expected_surface_count, surface_set.size()); + EXPECT_EQ(expected_surface_count, + aggregator_.previous_contained_surfaces().size()); for (size_t i = 0; i < expected_surface_count; i++) { - EXPECT_TRUE(surface_set.find(surface_ids[i]) != surface_set.end()); + EXPECT_TRUE( + aggregator_.previous_contained_surfaces().find(surface_ids[i]) != + aggregator_.previous_contained_surfaces().end()); } } @@ -227,9 +227,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassSurfaceReference) { SubmitFrame(root_passes, arraysize(root_passes), root_surface_id_); - std::set<SurfaceId> surface_set; scoped_ptr<CompositorFrame> aggregated_frame = - aggregator_.Aggregate(root_surface_id_, &surface_set); + aggregator_.Aggregate(root_surface_id_); ASSERT_TRUE(aggregated_frame); ASSERT_TRUE(aggregated_frame->delegated_frame_data); @@ -451,9 +450,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, RenderPassIdMapping) { test::Pass(parent_quad[1], arraysize(parent_quad[1]), parent_pass_id[1])}; SubmitFrame(parent_passes, arraysize(parent_passes), root_surface_id_); - std::set<SurfaceId> surface_set; scoped_ptr<CompositorFrame> aggregated_frame = - aggregator_.Aggregate(root_surface_id_, &surface_set); + aggregator_.Aggregate(root_surface_id_); ASSERT_TRUE(aggregated_frame); ASSERT_TRUE(aggregated_frame->delegated_frame_data); @@ -623,9 +621,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateSharedQuadStateProperties) { QueuePassAsFrame(root_pass.Pass(), root_surface_id_); - std::set<SurfaceId> surface_set; scoped_ptr<CompositorFrame> aggregated_frame = - aggregator_.Aggregate(root_surface_id_, &surface_set); + aggregator_.Aggregate(root_surface_id_); ASSERT_TRUE(aggregated_frame); ASSERT_TRUE(aggregated_frame->delegated_frame_data); @@ -727,9 +724,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateMultiplePassWithTransform) { factory_.SubmitFrame(root_surface_id_, root_frame.Pass(), base::Closure()); - std::set<SurfaceId> surface_set; scoped_ptr<CompositorFrame> aggregated_frame = - aggregator_.Aggregate(root_surface_id_, &surface_set); + aggregator_.Aggregate(root_surface_id_); ASSERT_TRUE(aggregated_frame); ASSERT_TRUE(aggregated_frame->delegated_frame_data); @@ -797,6 +793,174 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateMultiplePassWithTransform) { factory_.Destroy(child_surface_id); } +// Tests that damage rects are aggregated correctly when surfaces change. +TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) { + SurfaceId child_surface_id = allocator_.GenerateId(); + factory_.Create(child_surface_id, SurfaceSize()); + RenderPassId child_pass_id = RenderPassId(1, 1); + test::Quad child_quads[] = {test::Quad::RenderPassQuad(child_pass_id)}; + test::Pass child_passes[] = { + test::Pass(child_quads, arraysize(child_quads), child_pass_id)}; + + RenderPassList child_pass_list; + AddPasses(&child_pass_list, + gfx::Rect(SurfaceSize()), + child_passes, + arraysize(child_passes)); + + RenderPass* child_root_pass = child_pass_list.at(0u); + SharedQuadState* child_root_pass_sqs = + child_root_pass->shared_quad_state_list[0]; + child_root_pass_sqs->content_to_target_transform.Translate(8, 0); + + scoped_ptr<DelegatedFrameData> child_frame_data(new DelegatedFrameData); + child_pass_list.swap(child_frame_data->render_pass_list); + + scoped_ptr<CompositorFrame> child_frame(new CompositorFrame); + child_frame->delegated_frame_data = child_frame_data.Pass(); + + factory_.SubmitFrame(child_surface_id, child_frame.Pass(), base::Closure()); + + test::Quad root_quads[] = {test::Quad::SurfaceQuad(child_surface_id)}; + test::Pass root_passes[] = {test::Pass(root_quads, arraysize(root_quads))}; + + RenderPassList root_pass_list; + AddPasses(&root_pass_list, + gfx::Rect(SurfaceSize()), + root_passes, + arraysize(root_passes)); + + root_pass_list.at(0) + ->shared_quad_state_list[0] + ->content_to_target_transform.Translate(0, 10); + root_pass_list.at(0)->damage_rect = gfx::Rect(5, 5, 10, 10); + + scoped_ptr<DelegatedFrameData> root_frame_data(new DelegatedFrameData); + root_pass_list.swap(root_frame_data->render_pass_list); + + scoped_ptr<CompositorFrame> root_frame(new CompositorFrame); + root_frame->delegated_frame_data = root_frame_data.Pass(); + + factory_.SubmitFrame(root_surface_id_, root_frame.Pass(), base::Closure()); + + scoped_ptr<CompositorFrame> aggregated_frame = + aggregator_.Aggregate(root_surface_id_); + + ASSERT_TRUE(aggregated_frame); + ASSERT_TRUE(aggregated_frame->delegated_frame_data); + + DelegatedFrameData* frame_data = aggregated_frame->delegated_frame_data.get(); + + const RenderPassList& aggregated_pass_list = frame_data->render_pass_list; + + ASSERT_EQ(1u, aggregated_pass_list.size()); + + // Damage rect for first aggregation should contain entire root surface. + EXPECT_TRUE( + aggregated_pass_list[0]->damage_rect.Contains(gfx::Rect(SurfaceSize()))); + + { + AddPasses(&child_pass_list, + gfx::Rect(SurfaceSize()), + child_passes, + arraysize(child_passes)); + + RenderPass* child_root_pass = child_pass_list.at(0u); + SharedQuadState* child_root_pass_sqs = + child_root_pass->shared_quad_state_list[0]; + child_root_pass_sqs->content_to_target_transform.Translate(8, 0); + child_root_pass->damage_rect = gfx::Rect(10, 10, 10, 10); + + scoped_ptr<DelegatedFrameData> child_frame_data(new DelegatedFrameData); + child_pass_list.swap(child_frame_data->render_pass_list); + + scoped_ptr<CompositorFrame> child_frame(new CompositorFrame); + child_frame->delegated_frame_data = child_frame_data.Pass(); + + factory_.SubmitFrame(child_surface_id, child_frame.Pass(), base::Closure()); + + scoped_ptr<CompositorFrame> aggregated_frame = + aggregator_.Aggregate(root_surface_id_); + + ASSERT_TRUE(aggregated_frame); + ASSERT_TRUE(aggregated_frame->delegated_frame_data); + + DelegatedFrameData* frame_data = + aggregated_frame->delegated_frame_data.get(); + + const RenderPassList& aggregated_pass_list = frame_data->render_pass_list; + + ASSERT_EQ(1u, aggregated_pass_list.size()); + + // Outer surface didn't change, so transformed inner damage rect should be + // used. + EXPECT_EQ(gfx::Rect(10, 20, 10, 10).ToString(), + aggregated_pass_list[0]->damage_rect.ToString()); + } + + { + RenderPassList root_pass_list; + AddPasses(&root_pass_list, + gfx::Rect(SurfaceSize()), + root_passes, + arraysize(root_passes)); + + root_pass_list.at(0) + ->shared_quad_state_list[0] + ->content_to_target_transform.Translate(0, 10); + root_pass_list.at(0)->damage_rect = gfx::Rect(0, 0, 1, 1); + + scoped_ptr<DelegatedFrameData> root_frame_data(new DelegatedFrameData); + root_pass_list.swap(root_frame_data->render_pass_list); + + scoped_ptr<CompositorFrame> root_frame(new CompositorFrame); + root_frame->delegated_frame_data = root_frame_data.Pass(); + + factory_.SubmitFrame(root_surface_id_, root_frame.Pass(), base::Closure()); + } + + { + RenderPassList root_pass_list; + AddPasses(&root_pass_list, + gfx::Rect(SurfaceSize()), + root_passes, + arraysize(root_passes)); + + root_pass_list.at(0) + ->shared_quad_state_list[0] + ->content_to_target_transform.Translate(0, 10); + root_pass_list.at(0)->damage_rect = gfx::Rect(1, 1, 1, 1); + + scoped_ptr<DelegatedFrameData> root_frame_data(new DelegatedFrameData); + root_pass_list.swap(root_frame_data->render_pass_list); + + scoped_ptr<CompositorFrame> root_frame(new CompositorFrame); + root_frame->delegated_frame_data = root_frame_data.Pass(); + + factory_.SubmitFrame(root_surface_id_, root_frame.Pass(), base::Closure()); + + scoped_ptr<CompositorFrame> aggregated_frame = + aggregator_.Aggregate(root_surface_id_); + + ASSERT_TRUE(aggregated_frame); + ASSERT_TRUE(aggregated_frame->delegated_frame_data); + + DelegatedFrameData* frame_data = + aggregated_frame->delegated_frame_data.get(); + + const RenderPassList& aggregated_pass_list = frame_data->render_pass_list; + + ASSERT_EQ(1u, aggregated_pass_list.size()); + + // The root surface was enqueued without being aggregated once, so it should + // be treated as completely damaged. + EXPECT_TRUE(aggregated_pass_list[0]->damage_rect.Contains( + gfx::Rect(SurfaceSize()))); + } + + factory_.Destroy(child_surface_id); +} + class SurfaceAggregatorWithResourcesTest : public testing::Test { public: virtual void SetUp() { @@ -899,17 +1063,14 @@ TEST_F(SurfaceAggregatorWithResourcesTest, TakeResourcesOneSurface) { ResourceProvider::ResourceId ids[] = {11, 12, 13}; SubmitFrameWithResources(ids, arraysize(ids), &factory, surface_id); - std::set<SurfaceId> surface_set; - scoped_ptr<CompositorFrame> frame = - aggregator_->Aggregate(surface_id, &surface_set); + scoped_ptr<CompositorFrame> frame = aggregator_->Aggregate(surface_id); // Nothing should be available to be returned yet. EXPECT_TRUE(client.returned_resources().empty()); SubmitFrameWithResources(NULL, 0u, &factory, surface_id); - surface_set.clear(); - frame = aggregator_->Aggregate(surface_id, &surface_set); + frame = aggregator_->Aggregate(surface_id); ASSERT_EQ(3u, client.returned_resources().size()); ResourceProvider::ResourceId returned_ids[3]; diff --git a/cc/surfaces/surfaces_pixeltest.cc b/cc/surfaces/surfaces_pixeltest.cc index bdc7c40..1e8166f 100644 --- a/cc/surfaces/surfaces_pixeltest.cc +++ b/cc/surfaces/surfaces_pixeltest.cc @@ -90,9 +90,8 @@ TEST_F(SurfacesPixelTest, DrawSimpleFrame) { factory_.SubmitFrame(root_surface_id, root_frame.Pass(), base::Closure()); SurfaceAggregator aggregator(&manager_, resource_provider_.get()); - std::set<SurfaceId> surface_set; scoped_ptr<CompositorFrame> aggregated_frame = - aggregator.Aggregate(root_surface_id, &surface_set); + aggregator.Aggregate(root_surface_id); factory_.Destroy(root_surface_id); bool discard_alpha = false; @@ -173,9 +172,8 @@ TEST_F(SurfacesPixelTest, DrawSimpleAggregatedFrame) { } SurfaceAggregator aggregator(&manager_, resource_provider_.get()); - std::set<SurfaceId> surface_set; scoped_ptr<CompositorFrame> aggregated_frame = - aggregator.Aggregate(root_surface_id, &surface_set); + aggregator.Aggregate(root_surface_id); bool discard_alpha = false; ExactPixelComparator pixel_comparator(discard_alpha); @@ -314,9 +312,8 @@ TEST_F(SurfacesPixelTest, DrawAggregatedFrameWithSurfaceTransforms) { } SurfaceAggregator aggregator(&manager_, resource_provider_.get()); - std::set<SurfaceId> surface_set; scoped_ptr<CompositorFrame> aggregated_frame = - aggregator.Aggregate(root_surface_id, &surface_set); + aggregator.Aggregate(root_surface_id); bool discard_alpha = false; ExactPixelComparator pixel_comparator(discard_alpha); |