Commit bffd19e7 authored by danakj@chromium.org's avatar danakj@chromium.org

cc: Find a better prioritized rect when the viewport rect is huge.

When a part of the layer is visible, then it has a visible_content_rect which
is the best place to expand the prioritized rect from.

If no part of the layer is visible, we use the viewport rect in content space.
However, when the layer clips the viewport, this rect becomes enormous.
Currently the ExpandRectEquallyToAreaBoundedBy function "expands" the viewport
to cover the target area, but if the viewport is huge, it shrinks it instead.
When it shrinks to a rect far away from the layer, the layer is considered too
far from the viewport for prioritization.

Instead, we should only grow the viewport in content space, then intersect with
the tiling's content bounds (as before) to find an appropriate starting rect.

Tests:
PictureLayerTilingIteratorTest.TilesExistGiantViewport
PictureLayerTilingIteratorTest.TilesExistOutsideViewport
PictureLayerTilingIteratorTest.TilesExistLargeViewportAndLayerWithSmallVisibleArea
PictureLayerTilingIteratorTest.TilesExistLargeViewportAndLayerWithLargeVisibleArea

BUG=231521

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@194596 0039d316-1c4b-4281-b951-d872f2087c98
parent fc3ab0c7
......@@ -288,6 +288,7 @@ void PictureLayerImpl::UpdateTilePriorities() {
tree,
layer_tree_impl()->device_viewport_size(),
viewport_in_content_space,
visible_content_rect(),
last_bounds_,
bounds(),
last_content_scale_,
......
......@@ -342,6 +342,7 @@ void PictureLayerTiling::UpdateTilePriorities(
WhichTree tree,
gfx::Size device_viewport,
const gfx::RectF& viewport_in_layer_space,
const gfx::RectF& visible_layer_rect,
gfx::Size last_layer_bounds,
gfx::Size current_layer_bounds,
float last_layer_contents_scale,
......@@ -378,14 +379,20 @@ void PictureLayerTiling::UpdateTilePriorities(
gfx::Rect viewport_in_content_space =
gfx::ToEnclosingRect(gfx::ScaleRect(viewport_in_layer_space,
contents_scale_));
gfx::Rect visible_content_rect =
gfx::ToEnclosingRect(gfx::ScaleRect(visible_layer_rect,
contents_scale_));
gfx::Size tile_size = tiling_data_.max_texture_size();
int64 prioritized_rect_area =
max_tiles_for_interest_area *
tile_size.width() * tile_size.height();
gfx::Rect starting_rect = visible_content_rect.IsEmpty()
? viewport_in_content_space
: visible_content_rect;
gfx::Rect prioritized_rect = ExpandRectEquallyToAreaBoundedBy(
viewport_in_content_space,
starting_rect,
prioritized_rect_area,
ContentRect());
DCHECK(ContentRect().Contains(prioritized_rect));
......@@ -565,23 +572,25 @@ gfx::Rect PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
DCHECK(!bounding_rect.IsEmpty());
DCHECK_GT(target_area, 0);
// Expand the starting rect to cover target_area.
// Expand the starting rect to cover target_area, if it is smaller than it.
int delta = ComputeExpansionDelta(
2, 2, starting_rect.width(), starting_rect.height(), target_area);
gfx::Rect expanded_starting_rect = starting_rect;
expanded_starting_rect.Inset(-delta, -delta);
if (delta > 0)
expanded_starting_rect.Inset(-delta, -delta);
gfx::Rect rect = IntersectRects(expanded_starting_rect, bounding_rect);
if (rect.IsEmpty()) {
// The starting_rect and bounding_rect are far away.
return rect;
}
if (rect == expanded_starting_rect) {
// The expanded starting rect already covers target_area on bounding_rect.
if (delta >= 0 && rect == expanded_starting_rect) {
// The starting rect already covers the entire bounding_rect and isn't too
// large for the target_area.
return rect;
}
// Continue to expand rect to let it cover target_area.
// Continue to expand/shrink rect to let it cover target_area.
// These values will be updated by the loop and uses as the output.
int origin_x = rect.x();
......@@ -611,13 +620,6 @@ gfx::Rect PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
for (int event_index = 0; event_index < 4; event_index++) {
const EdgeEvent& event = events[event_index];
// Early out if our distance to event is 0.
// This optimization is not required for correctness.
if (event.distance == 0) {
--*event.num_edges;
continue;
}
int delta = ComputeExpansionDelta(
num_x_edges, num_y_edges, width, height, target_area);
......
......@@ -131,6 +131,7 @@ class CC_EXPORT PictureLayerTiling {
WhichTree tree,
gfx::Size device_viewport,
const gfx::RectF& viewport_in_layer_space,
const gfx::RectF& visible_layer_rect,
gfx::Size last_layer_bounds,
gfx::Size current_layer_bounds,
float last_layer_contents_scale,
......
......@@ -279,6 +279,7 @@ void PictureLayerTilingSet::UpdateTilePriorities(
WhichTree tree,
gfx::Size device_viewport,
gfx::Rect viewport_in_content_space,
gfx::Rect visible_content_rect,
gfx::Size last_layer_bounds,
gfx::Size current_layer_bounds,
float last_layer_contents_scale,
......@@ -290,15 +291,18 @@ void PictureLayerTilingSet::UpdateTilePriorities(
bool store_screen_space_quads_on_tiles,
size_t max_tiles_for_interest_area) {
gfx::RectF viewport_in_layer_space = gfx::ScaleRect(
viewport_in_content_space,
1.f / current_layer_contents_scale,
1.f / current_layer_contents_scale);
viewport_in_content_space,
1.f / current_layer_contents_scale);
gfx::RectF visible_layer_rect = gfx::ScaleRect(
visible_content_rect,
1.f / current_layer_contents_scale);
for (size_t i = 0; i < tilings_.size(); ++i) {
tilings_[i]->UpdateTilePriorities(
tree,
device_viewport,
viewport_in_layer_space,
visible_layer_rect,
last_layer_bounds,
current_layer_bounds,
last_layer_contents_scale,
......
......@@ -55,6 +55,7 @@ class CC_EXPORT PictureLayerTilingSet {
WhichTree tree,
gfx::Size device_viewport,
gfx::Rect viewport_in_content_space,
gfx::Rect visible_content_rect,
gfx::Size last_layer_bounds,
gfx::Size current_layer_bounds,
float last_layer_contents_scale,
......
......@@ -421,6 +421,7 @@ TEST_F(PictureLayerTilingIteratorTest, TilesExist) {
ACTIVE_TREE,
layer_bounds, // device viewport
gfx::Rect(layer_bounds), // viewport in layer space
gfx::Rect(layer_bounds), // visible content rect
layer_bounds, // last layer bounds
layer_bounds, // current layer bounds
1.f, // last contents scale
......@@ -438,6 +439,7 @@ TEST_F(PictureLayerTilingIteratorTest, TilesExist) {
ACTIVE_TREE,
layer_bounds, // device viewport
gfx::Rect(), // viewport in layer space
gfx::Rect(), // visible content rect
layer_bounds, // last layer bounds
layer_bounds, // current layer bounds
1.f, // last contents scale
......@@ -451,5 +453,154 @@ TEST_F(PictureLayerTilingIteratorTest, TilesExist) {
VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
}
TEST_F(PictureLayerTilingIteratorTest, TilesExistGiantViewport) {
gfx::Size layer_bounds(1099, 801);
Initialize(gfx::Size(100, 100), 1.f, layer_bounds);
VerifyTilesExactlyCoverRect(1.f, gfx::Rect(layer_bounds));
VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
gfx::Rect giant_rect(-10000000, -10000000, 1000000000, 1000000000);
tiling_->UpdateTilePriorities(
ACTIVE_TREE,
layer_bounds, // device viewport
giant_rect, // viewport in layer space
gfx::Rect(layer_bounds), // visible content rect
layer_bounds, // last layer bounds
layer_bounds, // current layer bounds
1.f, // last contents scale
1.f, // current contents scale
gfx::Transform(), // last screen transform
gfx::Transform(), // current screen transform
1, // current frame number
1.0, // current frame time
false, // store screen space quads on tiles
10000); // max tiles in tile manager
VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true));
// If the visible content rect is empty, it should still have live tiles.
tiling_->UpdateTilePriorities(
ACTIVE_TREE,
layer_bounds, // device viewport
giant_rect, // viewport in layer space
gfx::Rect(), // visible content rect
layer_bounds, // last layer bounds
layer_bounds, // current layer bounds
1.f, // last contents scale
1.f, // current contents scale
gfx::Transform(), // last screen transform
gfx::Transform(), // current screen transform
2, // current frame number
2.0, // current frame time
false, // store screen space quads on tiles
10000); // max tiles in tile manager
VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true));
}
TEST_F(PictureLayerTilingIteratorTest, TilesExistOutsideViewport) {
gfx::Size layer_bounds(1099, 801);
Initialize(gfx::Size(100, 100), 1.f, layer_bounds);
VerifyTilesExactlyCoverRect(1.f, gfx::Rect(layer_bounds));
VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
// This rect does not intersect with the layer, as the layer is outside the
// viewport.
gfx::Rect viewport_rect(1100, 0, 1000, 1000);
EXPECT_FALSE(viewport_rect.Intersects(gfx::Rect(layer_bounds)));
tiling_->UpdateTilePriorities(
ACTIVE_TREE,
layer_bounds, // device viewport
viewport_rect, // viewport in layer space
gfx::Rect(), // visible content rect
layer_bounds, // last layer bounds
layer_bounds, // current layer bounds
1.f, // last contents scale
1.f, // current contents scale
gfx::Transform(), // last screen transform
gfx::Transform(), // current screen transform
2, // current frame number
2.0, // current frame time
false, // store screen space quads on tiles
10000); // max tiles in tile manager
VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true));
}
static void TilesIntersectingRectExist(gfx::Rect rect, Tile* tile) {
ASSERT_TRUE(tile != NULL);
bool expected_live = rect.Intersects(tile->content_rect());
EXPECT_EQ(expected_live, tile->priority(ACTIVE_TREE).is_live) <<
"Rects intersecting " << rect.ToString() << " should exist. " <<
"Current tile rect is " << tile->content_rect().ToString();
}
TEST_F(PictureLayerTilingIteratorTest,
TilesExistLargeViewportAndLayerWithSmallVisibleArea) {
gfx::Size layer_bounds(10000, 10000);
Initialize(gfx::Size(100, 100), 1.f, layer_bounds);
VerifyTilesExactlyCoverRect(1.f, gfx::Rect(layer_bounds));
VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
gfx::Rect visible_rect(8000, 8000, 50, 50);
tiling_->UpdateTilePriorities(
ACTIVE_TREE,
layer_bounds, // device viewport
gfx::Rect(layer_bounds), // viewport in layer space
visible_rect, // visible content rect
layer_bounds, // last layer bounds
layer_bounds, // current layer bounds
1.f, // last contents scale
1.f, // current contents scale
gfx::Transform(), // last screen transform
gfx::Transform(), // current screen transform
2, // current frame number
2.0, // current frame time
false, // store screen space quads on tiles
1); // max tiles in tile manager
VerifyTiles(1.f,
gfx::Rect(layer_bounds),
base::Bind(&TilesIntersectingRectExist, visible_rect));
}
static void CountExistingTiles(int *count, Tile* tile) {
ASSERT_TRUE(tile != NULL);
if (tile->priority(ACTIVE_TREE).is_live)
++(*count);
}
TEST_F(PictureLayerTilingIteratorTest,
TilesExistLargeViewportAndLayerWithLargeVisibleArea) {
gfx::Size layer_bounds(10000, 10000);
Initialize(gfx::Size(100, 100), 1.f, layer_bounds);
VerifyTilesExactlyCoverRect(1.f, gfx::Rect(layer_bounds));
VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
tiling_->UpdateTilePriorities(
ACTIVE_TREE,
layer_bounds, // device viewport
gfx::Rect(layer_bounds), // viewport in layer space
gfx::Rect(layer_bounds), // visible content rect
layer_bounds, // last layer bounds
layer_bounds, // current layer bounds
1.f, // last contents scale
1.f, // current contents scale
gfx::Transform(), // last screen transform
gfx::Transform(), // current screen transform
2, // current frame number
2.0, // current frame time
false, // store screen space quads on tiles
1); // max tiles in tile manager
int num_tiles = 0;
VerifyTiles(1.f,
gfx::Rect(layer_bounds),
base::Bind(&CountExistingTiles, &num_tiles));
// If we're making a rect the size of one tile, it can only overlap up to 4
// tiles depending on its position.
EXPECT_LE(num_tiles, 4);
}
} // namespace
} // namespace cc
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