summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsohan.jyoti@samsung.com <sohan.jyoti@samsung.com@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-29 11:50:03 +0000
committersohan.jyoti@samsung.com <sohan.jyoti@samsung.com@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-29 11:50:03 +0000
commitcfa7fd92d44fd9254bfbbeeb9a4940425520d887 (patch)
tree251cd9828313663048152dacd16209a7b1e0724a
parentdb4d24fdaf4a32bcc3a213eb980696956f58e22a (diff)
downloadchromium_src-cfa7fd92d44fd9254bfbbeeb9a4940425520d887.zip
chromium_src-cfa7fd92d44fd9254bfbbeeb9a4940425520d887.tar.gz
chromium_src-cfa7fd92d44fd9254bfbbeeb9a4940425520d887.tar.bz2
cc: Add support for partial swaps when using impl-side painting by only
damaging viewport area covered by newly initialized tiles. In the current implementation, during frame draw and visible tile update, LTHI was setting damage to the entire viewport area, irrespective of the initialized tiled content rect. As part of the patch we are trying to ascertain newly initialized tile rect from TileManager, notify LTHI about it, and save it as damage rect in LayerImpl. During frame draw, when the damage for surfaces and layers are tracked, we query for these damaged layer rects and unify with the DamageTracker's damage rect. BUG= Review URL: https://codereview.chromium.org/219963005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@266852 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--cc/layers/layer_impl.cc5
-rw-r--r--cc/layers/layer_impl.h7
-rw-r--r--cc/resources/tile_manager.cc2
-rw-r--r--cc/resources/tile_manager.h1
-rw-r--r--cc/resources/tile_manager_perftest.cc1
-rw-r--r--cc/resources/tile_manager_unittest.cc2
-rw-r--r--cc/test/fake_tile_manager_client.h1
-rw-r--r--cc/trees/damage_tracker.cc16
-rw-r--r--cc/trees/damage_tracker_unittest.cc94
-rw-r--r--cc/trees/layer_tree_host_impl.cc19
-rw-r--r--cc/trees/layer_tree_host_impl.h1
11 files changed, 139 insertions, 10 deletions
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc
index f4d618b..3c50683 100644
--- a/cc/layers/layer_impl.cc
+++ b/cc/layers/layer_impl.cc
@@ -707,6 +707,7 @@ void LayerImpl::ResetAllChangeTrackingForSubtree() {
layer_property_changed_ = false;
update_rect_ = gfx::RectF();
+ damage_rect_ = gfx::RectF();
if (draw_properties_.render_surface)
draw_properties_.render_surface->ResetPropertyChangedFlag();
@@ -1036,6 +1037,10 @@ void LayerImpl::SetUpdateRect(const gfx::RectF& update_rect) {
SetNeedsPushProperties();
}
+void LayerImpl::AddDamageRect(const gfx::RectF& damage_rect) {
+ damage_rect_ = gfx::UnionRects(damage_rect_, damage_rect);
+}
+
void LayerImpl::SetContentBounds(const gfx::Size& content_bounds) {
if (this->content_bounds() == content_bounds)
return;
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h
index b6f0b05..0649856 100644
--- a/cc/layers/layer_impl.h
+++ b/cc/layers/layer_impl.h
@@ -458,6 +458,10 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver,
const gfx::RectF& update_rect() const { return update_rect_; }
+ void AddDamageRect(const gfx::RectF& damage_rect);
+
+ const gfx::RectF& damage_rect() const { return damage_rect_; }
+
virtual base::DictionaryValue* LayerTreeAsJson() const;
void SetStackingOrderChanged(bool stacking_order_changed);
@@ -659,6 +663,9 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver,
// Uses layer (not content) space.
gfx::RectF update_rect_;
+ // This rect is in layer space.
+ gfx::RectF damage_rect_;
+
// Manages animations for this layer.
scoped_refptr<LayerAnimationController> layer_animation_controller_;
diff --git a/cc/resources/tile_manager.cc b/cc/resources/tile_manager.cc
index f9fafbb..38948c3 100644
--- a/cc/resources/tile_manager.cc
+++ b/cc/resources/tile_manager.cc
@@ -1199,6 +1199,8 @@ void TileManager::OnRasterTaskCompleted(
++resources_releasable_;
}
+ client_->NotifyTileInitialized(tile);
+
FreeUnusedResourcesForTile(tile);
if (tile->priority(ACTIVE_TREE).distance_to_visible == 0.f)
did_initialize_visible_tile_ = true;
diff --git a/cc/resources/tile_manager.h b/cc/resources/tile_manager.h
index e3abb19..c1534f4 100644
--- a/cc/resources/tile_manager.h
+++ b/cc/resources/tile_manager.h
@@ -32,6 +32,7 @@ class ResourceProvider;
class CC_EXPORT TileManagerClient {
public:
virtual void NotifyReadyToActivate() = 0;
+ virtual void NotifyTileInitialized(const Tile* tile) = 0;
protected:
virtual ~TileManagerClient() {}
diff --git a/cc/resources/tile_manager_perftest.cc b/cc/resources/tile_manager_perftest.cc
index bfe50e02..e81270d 100644
--- a/cc/resources/tile_manager_perftest.cc
+++ b/cc/resources/tile_manager_perftest.cc
@@ -322,6 +322,7 @@ class TileManagerTileIteratorPerfTest : public testing::Test,
// TileManagerClient implementation.
virtual void NotifyReadyToActivate() OVERRIDE { ready_to_activate_ = true; }
+ virtual void NotifyTileInitialized(const Tile* tile) OVERRIDE {}
TileManager* tile_manager() { return host_impl_.tile_manager(); }
diff --git a/cc/resources/tile_manager_unittest.cc b/cc/resources/tile_manager_unittest.cc
index 8edecd5..e45272e 100644
--- a/cc/resources/tile_manager_unittest.cc
+++ b/cc/resources/tile_manager_unittest.cc
@@ -84,6 +84,7 @@ class TileManagerTest : public testing::TestWithParam<bool>,
// TileManagerClient implementation.
virtual void NotifyReadyToActivate() OVERRIDE { ready_to_activate_ = true; }
+ virtual void NotifyTileInitialized(const Tile* tile) OVERRIDE {}
TileVector CreateTilesWithSize(int count,
TilePriority active_priority,
@@ -739,6 +740,7 @@ class TileManagerTileIteratorTest : public testing::Test,
// TileManagerClient implementation.
virtual void NotifyReadyToActivate() OVERRIDE { ready_to_activate_ = true; }
+ virtual void NotifyTileInitialized(const Tile* tile) OVERRIDE {}
TileManager* tile_manager() { return host_impl_.tile_manager(); }
diff --git a/cc/test/fake_tile_manager_client.h b/cc/test/fake_tile_manager_client.h
index 81f5ea6..dd368b9 100644
--- a/cc/test/fake_tile_manager_client.h
+++ b/cc/test/fake_tile_manager_client.h
@@ -15,6 +15,7 @@ class FakeTileManagerClient : public TileManagerClient {
// TileManagerClient implementation.
virtual void NotifyReadyToActivate() OVERRIDE {}
+ virtual void NotifyTileInitialized(const Tile* tile) OVERRIDE {}
};
} // namespace cc
diff --git a/cc/trees/damage_tracker.cc b/cc/trees/damage_tracker.cc
index 4074146..866f09d 100644
--- a/cc/trees/damage_tracker.cc
+++ b/cc/trees/damage_tracker.cc
@@ -287,6 +287,9 @@ void DamageTracker::ExtendDamageForLayer(LayerImpl* layer,
layer->draw_transform(), gfx::Rect(layer->content_bounds()));
data.Update(rect_in_target_space, mailboxId_);
+ gfx::RectF damage_rect =
+ gfx::UnionRects(layer->update_rect(), layer->damage_rect());
+
if (layer_is_new || layer->LayerPropertyChanged()) {
// If a layer is new or has changed, then its entire layer rect affects the
// target surface.
@@ -295,14 +298,13 @@ void DamageTracker::ExtendDamageForLayer(LayerImpl* layer,
// The layer's old region is now exposed on the target surface, too.
// Note old_rect_in_target_space is already in target space.
target_damage_rect->Union(old_rect_in_target_space);
- } else if (!layer->update_rect().IsEmpty()) {
+ } else if (!damage_rect.IsEmpty()) {
// If the layer properties haven't changed, then the the target surface is
- // only affected by the layer's update area, which could be empty.
- gfx::Rect update_content_rect =
- layer->LayerRectToContentRect(layer->update_rect());
- gfx::Rect update_rect_in_target_space = MathUtil::MapEnclosingClippedRect(
- layer->draw_transform(), update_content_rect);
- target_damage_rect->Union(update_rect_in_target_space);
+ // only affected by the layer's damaged area, which could be empty.
+ gfx::Rect damage_content_rect = layer->LayerRectToContentRect(damage_rect);
+ gfx::Rect damage_rect_in_target_space = MathUtil::MapEnclosingClippedRect(
+ layer->draw_transform(), damage_content_rect);
+ target_damage_rect->Union(damage_rect_in_target_space);
}
}
diff --git a/cc/trees/damage_tracker_unittest.cc b/cc/trees/damage_tracker_unittest.cc
index 9476955..51a6137 100644
--- a/cc/trees/damage_tracker_unittest.cc
+++ b/cc/trees/damage_tracker_unittest.cc
@@ -268,6 +268,100 @@ TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) {
EXPECT_EQ(gfx::Rect(120, 125, 1, 2).ToString(), root_damage_rect.ToString());
}
+TEST_F(DamageTrackerTest, VerifyDamageForLayerDamageRects) {
+ scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
+ LayerImpl* child = root->children()[0];
+
+ // CASE 1: Adding the layer damage rect should cause the corresponding damage
+ // to the surface.
+ ClearDamageForAllSurfaces(root.get());
+ child->AddDamageRect(gfx::RectF(10.f, 11.f, 12.f, 13.f));
+ EmulateDrawingOneFrame(root.get());
+
+ // Damage position on the surface should be: position of layer damage_rect
+ // (10, 11) relative to the child (100, 100).
+ gfx::Rect root_damage_rect =
+ root->render_surface()->damage_tracker()->current_damage_rect();
+ EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(110, 111, 12, 13)));
+
+ // CASE 2: The same layer damage rect twice in a row still produces the same
+ // damage.
+ ClearDamageForAllSurfaces(root.get());
+ child->AddDamageRect(gfx::RectF(10.f, 11.f, 12.f, 13.f));
+ EmulateDrawingOneFrame(root.get());
+ root_damage_rect =
+ root->render_surface()->damage_tracker()->current_damage_rect();
+ EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(110, 111, 12, 13)));
+
+ // CASE 3: Adding a different layer damage rect should cause damage on the
+ // new damaged region, but no additional exposed old region.
+ ClearDamageForAllSurfaces(root.get());
+ child->AddDamageRect(gfx::RectF(20.f, 25.f, 1.f, 2.f));
+ EmulateDrawingOneFrame(root.get());
+
+ // Damage position on the surface should be: position of layer damage_rect
+ // (20, 25) relative to the child (100, 100).
+ root_damage_rect =
+ root->render_surface()->damage_tracker()->current_damage_rect();
+ EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(120, 125, 1, 2)));
+
+ // CASE 4: Adding multiple layer damage rects should cause a unified
+ // damage on root damage rect.
+ ClearDamageForAllSurfaces(root.get());
+ child->AddDamageRect(gfx::RectF(20.f, 25.f, 1.f, 2.f));
+ child->AddDamageRect(gfx::RectF(10.f, 15.f, 3.f, 4.f));
+ EmulateDrawingOneFrame(root.get());
+
+ // Damage position on the surface should be: position of layer damage_rect
+ // (20, 25) relative to the child (100, 100).
+ root_damage_rect =
+ root->render_surface()->damage_tracker()->current_damage_rect();
+ EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(120, 125, 1, 2)));
+ EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(110, 115, 3, 4)));
+}
+
+TEST_F(DamageTrackerTest, VerifyDamageForLayerUpdateAndDamageRects) {
+ scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
+ LayerImpl* child = root->children()[0];
+
+ // CASE 1: Adding the layer damage rect and update rect should cause the
+ // corresponding damage to the surface.
+ ClearDamageForAllSurfaces(root.get());
+ child->AddDamageRect(gfx::RectF(5.f, 6.f, 12.f, 13.f));
+ child->SetUpdateRect(gfx::RectF(15.f, 16.f, 14.f, 10.f));
+ EmulateDrawingOneFrame(root.get());
+
+ // Damage position on the surface should be: position of unified layer
+ // damage_rect and update rect (5, 6)
+ // relative to the child (100, 100).
+ gfx::Rect root_damage_rect =
+ root->render_surface()->damage_tracker()->current_damage_rect();
+ EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(105, 106, 24, 20)));
+
+ // CASE 2: The same layer damage rect and update rect twice in a row still
+ // produces the same damage.
+ ClearDamageForAllSurfaces(root.get());
+ child->AddDamageRect(gfx::RectF(10.f, 11.f, 12.f, 13.f));
+ child->SetUpdateRect(gfx::RectF(10.f, 11.f, 14.f, 15.f));
+ EmulateDrawingOneFrame(root.get());
+ root_damage_rect =
+ root->render_surface()->damage_tracker()->current_damage_rect();
+ EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(110, 111, 14, 15)));
+
+ // CASE 3: Adding a different layer damage rect and update rect should cause
+ // damage on the new damaged region, but no additional exposed old region.
+ ClearDamageForAllSurfaces(root.get());
+ child->AddDamageRect(gfx::RectF(20.f, 25.f, 2.f, 3.f));
+ child->SetUpdateRect(gfx::RectF(5.f, 10.f, 7.f, 8.f));
+ EmulateDrawingOneFrame(root.get());
+
+ // Damage position on the surface should be: position of unified layer damage
+ // rect and update rect (5, 10) relative to the child (100, 100).
+ root_damage_rect =
+ root->render_surface()->damage_tracker()->current_damage_rect();
+ EXPECT_EQ(true, root_damage_rect.Contains(gfx::Rect(105, 110, 17, 18)));
+}
+
TEST_F(DamageTrackerTest, VerifyDamageForPropertyChanges) {
scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
LayerImpl* child = root->children()[0];
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index e764517..34e20d3 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -1127,6 +1127,9 @@ void LayerTreeHostImpl::BlockNotifyReadyToActivateForTesting(bool block) {
}
void LayerTreeHostImpl::DidInitializeVisibleTileForTesting() {
+ // Add arbitrary damage, to trigger prepare-to-draws.
+ // Here, setting damage as viewport size, used only for testing.
+ SetFullRootLayerDamage();
DidInitializeVisibleTile();
}
@@ -1202,9 +1205,6 @@ void LayerTreeHostImpl::DidModifyTilePriorities() {
}
void LayerTreeHostImpl::DidInitializeVisibleTile() {
- // TODO(reveman): Determine tiles that changed and only damage
- // what's necessary.
- SetFullRootLayerDamage();
if (client_ && !client_->IsInsideDraw())
client_->DidInitializeVisibleTileOnImplThread();
}
@@ -1213,6 +1213,19 @@ void LayerTreeHostImpl::NotifyReadyToActivate() {
client_->NotifyReadyToActivate();
}
+void LayerTreeHostImpl::NotifyTileInitialized(const Tile* tile) {
+ if (!active_tree_)
+ return;
+
+ LayerImpl* layer_impl =
+ active_tree_->FindActiveTreeLayerById(tile->layer_id());
+ if (layer_impl) {
+ gfx::RectF layer_damage_rect =
+ gfx::ScaleRect(tile->content_rect(), 1.f / tile->contents_scale());
+ layer_impl->AddDamageRect(layer_damage_rect);
+ }
+}
+
void LayerTreeHostImpl::SetMemoryPolicy(const ManagedMemoryPolicy& policy) {
SetManagedMemoryPolicy(policy, zero_budget_);
}
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index 8eb77fe..3598a9d 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -225,6 +225,7 @@ class CC_EXPORT LayerTreeHostImpl
// TileManagerClient implementation.
virtual void NotifyReadyToActivate() OVERRIDE;
+ virtual void NotifyTileInitialized(const Tile* tile) OVERRIDE;
// OutputSurfaceClient implementation.
virtual void DeferredInitialize() OVERRIDE;