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() {
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();
}
......
......@@ -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);
};
......
......@@ -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;
......
......@@ -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_;
......
......@@ -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.
......
......@@ -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_;
......
This diff is collapsed.
......@@ -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);
......
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