Commit 2eb7fbb5 authored by jbauman's avatar jbauman Committed by Commit bot

Aggregate damage rects in surface aggregator

The surface aggregator should keep track of the last frame from each surface that was aggregated, and use that to determine what the appropriate damage rect is for the next aggregation.

BUG=
TEST=chrome --use-surfaces --disable-gpu

Review URL: https://codereview.chromium.org/506273002

Cr-Commit-Position: refs/heads/master@{#292227}
parent 86693c47
...@@ -89,10 +89,8 @@ bool Display::Draw() { ...@@ -89,10 +89,8 @@ bool Display::Draw() {
if (!output_surface_) if (!output_surface_)
return false; return false;
contained_surfaces_.clear();
scoped_ptr<CompositorFrame> frame = scoped_ptr<CompositorFrame> frame =
aggregator_->Aggregate(current_surface_id_, &contained_surfaces_); aggregator_->Aggregate(current_surface_id_);
if (!frame) if (!frame)
return false; return false;
...@@ -116,10 +114,11 @@ bool Display::Draw() { ...@@ -116,10 +114,11 @@ bool Display::Draw() {
disable_picture_quad_image_filtering); disable_picture_quad_image_filtering);
CompositorFrameMetadata metadata; CompositorFrameMetadata metadata;
renderer_->SwapBuffers(metadata); renderer_->SwapBuffers(metadata);
for (std::set<SurfaceId>::iterator it = contained_surfaces_.begin(); for (SurfaceAggregator::SurfaceIndexMap::iterator it =
it != contained_surfaces_.end(); aggregator_->previous_contained_surfaces().begin();
it != aggregator_->previous_contained_surfaces().end();
++it) { ++it) {
Surface* surface = manager_->GetSurfaceForId(*it); Surface* surface = manager_->GetSurfaceForId(it->first);
if (surface) if (surface)
surface->RunDrawCallbacks(); surface->RunDrawCallbacks();
} }
...@@ -127,7 +126,7 @@ bool Display::Draw() { ...@@ -127,7 +126,7 @@ bool Display::Draw() {
} }
void Display::OnSurfaceDamaged(SurfaceId surface) { void Display::OnSurfaceDamaged(SurfaceId surface) {
if (contained_surfaces_.find(surface) != contained_surfaces_.end()) if (aggregator_ && aggregator_->previous_contained_surfaces().count(surface))
client_->DisplayDamaged(); client_->DisplayDamaged();
} }
......
...@@ -89,8 +89,6 @@ class CC_SURFACES_EXPORT Display : public OutputSurfaceClient, ...@@ -89,8 +89,6 @@ class CC_SURFACES_EXPORT Display : public OutputSurfaceClient,
scoped_ptr<SurfaceAggregator> aggregator_; scoped_ptr<SurfaceAggregator> aggregator_;
scoped_ptr<DirectRenderer> renderer_; scoped_ptr<DirectRenderer> renderer_;
std::set<SurfaceId> contained_surfaces_;
DISALLOW_COPY_AND_ASSIGN(Display); DISALLOW_COPY_AND_ASSIGN(Display);
}; };
......
...@@ -9,8 +9,15 @@ ...@@ -9,8 +9,15 @@
namespace cc { 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::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() { Surface::~Surface() {
...@@ -29,6 +36,7 @@ void Surface::QueueFrame(scoped_ptr<CompositorFrame> frame, ...@@ -29,6 +36,7 @@ void Surface::QueueFrame(scoped_ptr<CompositorFrame> frame,
current_frame_ = frame.Pass(); current_frame_ = frame.Pass();
factory_->ReceiveFromChild( factory_->ReceiveFromChild(
current_frame_->delegated_frame_data->resource_list); current_frame_->delegated_frame_data->resource_list);
++frame_index_;
if (previous_frame) { if (previous_frame) {
ReturnedResourceArray previous_resources; ReturnedResourceArray previous_resources;
......
...@@ -32,6 +32,9 @@ class CC_SURFACES_EXPORT Surface { ...@@ -32,6 +32,9 @@ class CC_SURFACES_EXPORT Surface {
// Returns the most recent frame that is eligible to be rendered. // Returns the most recent frame that is eligible to be rendered.
const CompositorFrame* GetEligibleFrame(); 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(); void RunDrawCallbacks();
SurfaceFactory* factory() { return factory_; } SurfaceFactory* factory() { return factory_; }
...@@ -42,6 +45,7 @@ class CC_SURFACES_EXPORT Surface { ...@@ -42,6 +45,7 @@ class CC_SURFACES_EXPORT Surface {
SurfaceFactory* factory_; SurfaceFactory* factory_;
// TODO(jamesr): Support multiple frames in flight. // TODO(jamesr): Support multiple frames in flight.
scoped_ptr<CompositorFrame> current_frame_; scoped_ptr<CompositorFrame> current_frame_;
int frame_index_;
base::Closure draw_callback_; base::Closure draw_callback_;
......
...@@ -132,17 +132,29 @@ bool SurfaceAggregator::TakeResources(Surface* surface, ...@@ -132,17 +132,29 @@ bool SurfaceAggregator::TakeResources(Surface* surface,
return invalid_frame; 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, void SurfaceAggregator::HandleSurfaceQuad(const SurfaceDrawQuad* surface_quad,
RenderPass* dest_pass) { RenderPass* dest_pass) {
SurfaceId surface_id = surface_quad->surface_id; 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 // If this surface's id is already in our referenced set then it creates
// a cycle in the graph and should be dropped. // a cycle in the graph and should be dropped.
if (referenced_surfaces_.count(surface_id)) if (referenced_surfaces_.count(surface_id))
return; return;
Surface* surface = manager_->GetSurfaceForId(surface_id); Surface* surface = manager_->GetSurfaceForId(surface_id);
if (!surface) if (!surface) {
contained_surfaces_[surface_id] = 0;
return; return;
}
contained_surfaces_[surface_id] = surface->frame_index();
const CompositorFrame* frame = surface->GetEligibleFrame(); const CompositorFrame* frame = surface->GetEligibleFrame();
if (!frame) if (!frame)
return; return;
...@@ -198,6 +210,11 @@ void SurfaceAggregator::HandleSurfaceQuad(const SurfaceDrawQuad* surface_quad, ...@@ -198,6 +210,11 @@ void SurfaceAggregator::HandleSurfaceQuad(const SurfaceDrawQuad* surface_quad,
surface_quad->quadTransform(), surface_quad->quadTransform(),
dest_pass, dest_pass,
surface_id); 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); referenced_surfaces_.erase(it);
} }
...@@ -268,17 +285,18 @@ void SurfaceAggregator::CopyQuadsToPass( ...@@ -268,17 +285,18 @@ void SurfaceAggregator::CopyQuadsToPass(
} }
void SurfaceAggregator::CopyPasses(const RenderPassList& source_pass_list, 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) { for (size_t i = 0; i < source_pass_list.size(); ++i) {
const RenderPass& source = *source_pass_list[i]; const RenderPass& source = *source_pass_list[i];
scoped_ptr<RenderPass> copy_pass(RenderPass::Create()); 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, copy_pass->SetAll(remapped_pass_id,
source.output_rect, source.output_rect,
source.damage_rect, DamageRectForSurface(surface, source),
source.transform_to_root_target, source.transform_to_root_target,
source.has_transparent_background); source.has_transparent_background);
...@@ -286,19 +304,16 @@ void SurfaceAggregator::CopyPasses(const RenderPassList& source_pass_list, ...@@ -286,19 +304,16 @@ void SurfaceAggregator::CopyPasses(const RenderPassList& source_pass_list,
source.shared_quad_state_list, source.shared_quad_state_list,
gfx::Transform(), gfx::Transform(),
copy_pass.get(), copy_pass.get(),
surface_id); surface->surface_id());
dest_pass_list_->push_back(copy_pass.Pass()); dest_pass_list_->push_back(copy_pass.Pass());
} }
} }
scoped_ptr<CompositorFrame> SurfaceAggregator::Aggregate( scoped_ptr<CompositorFrame> SurfaceAggregator::Aggregate(SurfaceId surface_id) {
SurfaceId surface_id,
std::set<SurfaceId>* contained_surfaces) {
contained_surfaces_ = contained_surfaces;
contained_surfaces_->insert(surface_id);
Surface* surface = manager_->GetSurfaceForId(surface_id); Surface* surface = manager_->GetSurfaceForId(surface_id);
DCHECK(surface); DCHECK(surface);
contained_surfaces_[surface_id] = surface->frame_index();
const CompositorFrame* root_surface_frame = surface->GetEligibleFrame(); const CompositorFrame* root_surface_frame = surface->GetEligibleFrame();
if (!root_surface_frame) if (!root_surface_frame)
return scoped_ptr<CompositorFrame>(); return scoped_ptr<CompositorFrame>();
...@@ -322,12 +337,14 @@ scoped_ptr<CompositorFrame> SurfaceAggregator::Aggregate( ...@@ -322,12 +337,14 @@ scoped_ptr<CompositorFrame> SurfaceAggregator::Aggregate(
&source_pass_list); &source_pass_list);
DCHECK(!invalid_frame); DCHECK(!invalid_frame);
CopyPasses(source_pass_list, surface_id); CopyPasses(source_pass_list, surface);
referenced_surfaces_.erase(it); referenced_surfaces_.erase(it);
DCHECK(referenced_surfaces_.empty()); DCHECK(referenced_surfaces_.empty());
dest_pass_list_ = NULL; dest_pass_list_ = NULL;
contained_surfaces_.swap(previous_contained_surfaces_);
contained_surfaces_.clear();
// TODO(jamesr): Aggregate all resource references into the returned frame's // TODO(jamesr): Aggregate all resource references into the returned frame's
// resource list. // resource list.
......
...@@ -26,12 +26,15 @@ class SurfaceManager; ...@@ -26,12 +26,15 @@ class SurfaceManager;
class CC_SURFACES_EXPORT SurfaceAggregator { class CC_SURFACES_EXPORT SurfaceAggregator {
public: public:
typedef base::hash_map<SurfaceId, int> SurfaceIndexMap;
SurfaceAggregator(SurfaceManager* manager, ResourceProvider* provider); SurfaceAggregator(SurfaceManager* manager, ResourceProvider* provider);
~SurfaceAggregator(); ~SurfaceAggregator();
scoped_ptr<CompositorFrame> Aggregate( scoped_ptr<CompositorFrame> Aggregate(SurfaceId surface_id);
SurfaceId surface_id, SurfaceIndexMap& previous_contained_surfaces() {
std::set<SurfaceId>* contained_surfaces); return previous_contained_surfaces_;
}
private: private:
RenderPassId RemapPassId(RenderPassId surface_local_pass_id, RenderPassId RemapPassId(RenderPassId surface_local_pass_id,
...@@ -47,12 +50,15 @@ class CC_SURFACES_EXPORT SurfaceAggregator { ...@@ -47,12 +50,15 @@ class CC_SURFACES_EXPORT SurfaceAggregator {
const gfx::Transform& content_to_target_transform, const gfx::Transform& content_to_target_transform,
RenderPass* dest_pass, RenderPass* dest_pass,
SurfaceId surface_id); 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, bool TakeResources(Surface* surface,
const DelegatedFrameData* frame_data, const DelegatedFrameData* frame_data,
RenderPassList* render_pass_list); RenderPassList* render_pass_list);
int ChildIdForSurface(Surface* surface); int ChildIdForSurface(Surface* surface);
gfx::Rect DamageRectForSurface(const Surface* surface,
const RenderPass& source);
SurfaceManager* manager_; SurfaceManager* manager_;
ResourceProvider* provider_; ResourceProvider* provider_;
...@@ -74,8 +80,10 @@ class CC_SURFACES_EXPORT SurfaceAggregator { ...@@ -74,8 +80,10 @@ class CC_SURFACES_EXPORT SurfaceAggregator {
typedef std::set<SurfaceId> SurfaceSet; typedef std::set<SurfaceId> SurfaceSet;
SurfaceSet referenced_surfaces_; SurfaceSet referenced_surfaces_;
// This is the set of surfaces that were used in the last draw. // For each Surface used in the last aggregation, gives the frame_index at
SurfaceSet* contained_surfaces_; // that time.
SurfaceIndexMap previous_contained_surfaces_;
SurfaceIndexMap contained_surfaces_;
// This is the pass list for the aggregated frame. // This is the pass list for the aggregated frame.
RenderPassList* dest_pass_list_; RenderPassList* dest_pass_list_;
......
This diff is collapsed.
...@@ -90,9 +90,8 @@ TEST_F(SurfacesPixelTest, DrawSimpleFrame) { ...@@ -90,9 +90,8 @@ TEST_F(SurfacesPixelTest, DrawSimpleFrame) {
factory_.SubmitFrame(root_surface_id, root_frame.Pass(), base::Closure()); factory_.SubmitFrame(root_surface_id, root_frame.Pass(), base::Closure());
SurfaceAggregator aggregator(&manager_, resource_provider_.get()); SurfaceAggregator aggregator(&manager_, resource_provider_.get());
std::set<SurfaceId> surface_set;
scoped_ptr<CompositorFrame> aggregated_frame = scoped_ptr<CompositorFrame> aggregated_frame =
aggregator.Aggregate(root_surface_id, &surface_set); aggregator.Aggregate(root_surface_id);
factory_.Destroy(root_surface_id); factory_.Destroy(root_surface_id);
bool discard_alpha = false; bool discard_alpha = false;
...@@ -173,9 +172,8 @@ TEST_F(SurfacesPixelTest, DrawSimpleAggregatedFrame) { ...@@ -173,9 +172,8 @@ TEST_F(SurfacesPixelTest, DrawSimpleAggregatedFrame) {
} }
SurfaceAggregator aggregator(&manager_, resource_provider_.get()); SurfaceAggregator aggregator(&manager_, resource_provider_.get());
std::set<SurfaceId> surface_set;
scoped_ptr<CompositorFrame> aggregated_frame = scoped_ptr<CompositorFrame> aggregated_frame =
aggregator.Aggregate(root_surface_id, &surface_set); aggregator.Aggregate(root_surface_id);
bool discard_alpha = false; bool discard_alpha = false;
ExactPixelComparator pixel_comparator(discard_alpha); ExactPixelComparator pixel_comparator(discard_alpha);
...@@ -314,9 +312,8 @@ TEST_F(SurfacesPixelTest, DrawAggregatedFrameWithSurfaceTransforms) { ...@@ -314,9 +312,8 @@ TEST_F(SurfacesPixelTest, DrawAggregatedFrameWithSurfaceTransforms) {
} }
SurfaceAggregator aggregator(&manager_, resource_provider_.get()); SurfaceAggregator aggregator(&manager_, resource_provider_.get());
std::set<SurfaceId> surface_set;
scoped_ptr<CompositorFrame> aggregated_frame = scoped_ptr<CompositorFrame> aggregated_frame =
aggregator.Aggregate(root_surface_id, &surface_set); aggregator.Aggregate(root_surface_id);
bool discard_alpha = false; bool discard_alpha = false;
ExactPixelComparator pixel_comparator(discard_alpha); ExactPixelComparator pixel_comparator(discard_alpha);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment