Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(84)

Unified Diff: cc/resources/picture_layer_tiling.cc

Issue 140513006: cc: Simplify picture layer tiling update tile priorities. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: format + clip inverse projected rect Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: cc/resources/picture_layer_tiling.cc
diff --git a/cc/resources/picture_layer_tiling.cc b/cc/resources/picture_layer_tiling.cc
index cfab6f25c852b97040c36488cceffa89abc790c1..5faf7e534b302389336d9a5acb27909f61ef116d 100644
--- a/cc/resources/picture_layer_tiling.cc
+++ b/cc/resources/picture_layer_tiling.cc
@@ -17,6 +17,10 @@
namespace cc {
+namespace {
+int kSkewportExtrapolatedLimitInContentPixels = 2000;
enne (OOO) 2014/02/11 00:43:56 Should this be a LayerTreeSetting?
vmpstr 2014/02/11 23:45:25 Done.
+}
+
scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create(
float contents_scale,
const gfx::Size& layer_bounds,
@@ -339,223 +343,152 @@ void PictureLayerTiling::Reset() {
tiles_.clear();
}
+gfx::Rect PictureLayerTiling::ComputeSkewport(
+ double current_frame_time_in_seconds,
+ const gfx::Rect& visible_rect_in_content_space) const {
+ gfx::Rect skewport = visible_rect_in_content_space;
+ if (last_impl_frame_time_in_seconds_ == 0.0)
+ return skewport;
+
+ double time_delta =
+ current_frame_time_in_seconds - last_impl_frame_time_in_seconds_;
+ if (time_delta == 0.0)
+ return skewport;
+
+ float skewport_target_time_in_seconds =
+ client_->GetSkewportTargetTimeInSeconds();
+ double extrapolation_multiplier =
+ skewport_target_time_in_seconds / time_delta;
+
+ int old_width = last_visible_rect_in_content_space_.width();
+ int old_height = last_visible_rect_in_content_space_.height();
+ int old_x = last_visible_rect_in_content_space_.x();
+ int old_y = last_visible_rect_in_content_space_.y();
+
+ int new_width = visible_rect_in_content_space.width();
+ int new_height = visible_rect_in_content_space.height();
+ int new_x = visible_rect_in_content_space.x();
+ int new_y = visible_rect_in_content_space.y();
+
+ int x_adjustment = std::min<int>(extrapolation_multiplier * (new_x - old_x),
+ kSkewportExtrapolatedLimitInContentPixels);
+ int y_adjustment = std::min<int>(extrapolation_multiplier * (new_y - old_y),
+ kSkewportExtrapolatedLimitInContentPixels);
+ int width_adjustment =
+ std::min<int>(extrapolation_multiplier * (new_width - old_width),
+ kSkewportExtrapolatedLimitInContentPixels);
+ int height_adjustment =
+ std::min<int>(extrapolation_multiplier * (new_height - old_height),
+ kSkewportExtrapolatedLimitInContentPixels);
+
+ skewport.set_width(skewport.width() + width_adjustment);
+ skewport.set_height(skewport.height() + height_adjustment);
+ skewport.set_x(skewport.x() + x_adjustment);
+ skewport.set_y(skewport.y() + y_adjustment);
+
+ skewport.Union(visible_rect_in_content_space);
+ return skewport;
+}
+
void PictureLayerTiling::UpdateTilePriorities(
WhichTree tree,
- const gfx::Size& device_viewport,
- const gfx::Rect& viewport_in_layer_space,
const gfx::Rect& visible_layer_rect,
- const gfx::Size& last_layer_bounds,
- const gfx::Size& current_layer_bounds,
- float last_layer_contents_scale,
- float current_layer_contents_scale,
- const gfx::Transform& last_screen_transform,
- const gfx::Transform& current_screen_transform,
- double current_frame_time_in_seconds,
- size_t max_tiles_for_interest_area) {
+ float layer_contents_scale,
+ double current_frame_time_in_seconds) {
if (!NeedsUpdateForFrameAtTime(current_frame_time_in_seconds)) {
// This should never be zero for the purposes of has_ever_been_updated().
DCHECK_NE(current_frame_time_in_seconds, 0.0);
return;
}
+
+ gfx::Rect visible_rect_in_content_space =
+ gfx::ScaleToEnclosingRect(visible_layer_rect, contents_scale_);
+
if (ContentRect().IsEmpty()) {
last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds;
+ last_visible_rect_in_content_space_ = visible_rect_in_content_space;
return;
}
- gfx::Rect viewport_in_content_space =
- gfx::ScaleToEnclosingRect(viewport_in_layer_space, contents_scale_);
- gfx::Rect visible_content_rect =
- gfx::ScaleToEnclosingRect(visible_layer_rect, contents_scale_);
+ size_t max_tiles_for_interest_area = client_->GetMaxTilesForInterestArea();
gfx::Size tile_size = tiling_data_.max_texture_size();
- int64 interest_rect_area =
+ int64 eventually_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 interest_rect = ExpandRectEquallyToAreaBoundedBy(
- starting_rect,
- interest_rect_area,
- ContentRect(),
- &expansion_cache_);
- DCHECK(interest_rect.IsEmpty() ||
- ContentRect().Contains(interest_rect));
-
- SetLiveTilesRect(interest_rect);
-
- double time_delta = 0;
- if (last_impl_frame_time_in_seconds_ != 0.0 &&
- last_layer_bounds == current_layer_bounds) {
- time_delta =
- current_frame_time_in_seconds - last_impl_frame_time_in_seconds_;
+ gfx::Rect skewport = ComputeSkewport(current_frame_time_in_seconds,
+ visible_rect_in_content_space);
+ DCHECK(skewport.Contains(visible_rect_in_content_space));
+
+ gfx::Rect eventually_rect =
+ ExpandRectEquallyToAreaBoundedBy(visible_rect_in_content_space,
+ eventually_rect_area,
+ ContentRect(),
+ &expansion_cache_);
+ DCHECK(eventually_rect.IsEmpty() || ContentRect().Contains(eventually_rect));
+
+ SetLiveTilesRect(eventually_rect);
+
+ last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds;
+ last_visible_rect_in_content_space_ = visible_rect_in_content_space;
+
+ // Assign now priority to all visible tiles.
+ TilePriority now_priority(resolution_, TilePriority::NOW, 0);
+ for (TilingData::Iterator iter(&tiling_data_, visible_rect_in_content_space);
+ iter;
+ ++iter) {
+ TileMap::iterator find = tiles_.find(iter.index());
+ if (find == tiles_.end())
+ continue;
+ Tile* tile = find->second.get();
+
+ tile->SetPriority(tree, now_priority);
}
- gfx::RectF view_rect(device_viewport);
- float current_scale = current_layer_contents_scale / contents_scale_;
- float last_scale = last_layer_contents_scale / contents_scale_;
-
- // Fast path tile priority calculation when both transforms are translations.
- if (last_screen_transform.IsApproximatelyIdentityOrTranslation(
- std::numeric_limits<float>::epsilon()) &&
- current_screen_transform.IsApproximatelyIdentityOrTranslation(
- std::numeric_limits<float>::epsilon())) {
- gfx::Vector2dF current_offset(
- current_screen_transform.matrix().get(0, 3),
- current_screen_transform.matrix().get(1, 3));
- gfx::Vector2dF last_offset(
- last_screen_transform.matrix().get(0, 3),
- last_screen_transform.matrix().get(1, 3));
-
- for (TilingData::Iterator iter(&tiling_data_, interest_rect);
- iter; ++iter) {
- TileMap::iterator find = tiles_.find(iter.index());
- if (find == tiles_.end())
- continue;
- Tile* tile = find->second.get();
-
- gfx::Rect tile_bounds =
- tiling_data_.TileBounds(iter.index_x(), iter.index_y());
- gfx::RectF current_screen_rect = gfx::ScaleRect(
- tile_bounds,
- current_scale,
- current_scale) + current_offset;
- gfx::RectF last_screen_rect = gfx::ScaleRect(
- tile_bounds,
- last_scale,
- last_scale) + last_offset;
-
- float distance_to_visible_in_pixels =
- current_screen_rect.ManhattanInternalDistance(view_rect);
-
- float time_to_visible_in_seconds =
- TilePriority::TimeForBoundsToIntersect(
- last_screen_rect, current_screen_rect, time_delta, view_rect);
- TilePriority priority(
- resolution_,
- time_to_visible_in_seconds,
- distance_to_visible_in_pixels);
- tile->SetPriority(tree, priority);
- }
- } else if (!last_screen_transform.HasPerspective() &&
- !current_screen_transform.HasPerspective()) {
- // Secondary fast path that can be applied for any affine transforms.
-
- // Initialize the necessary geometry in screen space, so that we can
- // iterate over tiles in screen space without needing a costly transform
- // mapping for each tile.
-
- // Apply screen space transform to the local origin point (0, 0); only the
- // translation component is needed and can be initialized directly.
- gfx::Point current_screen_space_origin(
- current_screen_transform.matrix().get(0, 3),
- current_screen_transform.matrix().get(1, 3));
-
- gfx::Point last_screen_space_origin(
- last_screen_transform.matrix().get(0, 3),
- last_screen_transform.matrix().get(1, 3));
-
- float current_tile_width = tiling_data_.TileSizeX(0) * current_scale;
- float last_tile_width = tiling_data_.TileSizeX(0) * last_scale;
- float current_tile_height = tiling_data_.TileSizeY(0) * current_scale;
- float last_tile_height = tiling_data_.TileSizeY(0) * last_scale;
-
- // Apply screen space transform to local basis vectors (tile_width, 0) and
- // (0, tile_height); the math simplifies and can be initialized directly.
- gfx::Vector2dF current_horizontal(
- current_screen_transform.matrix().get(0, 0) * current_tile_width,
- current_screen_transform.matrix().get(1, 0) * current_tile_width);
- gfx::Vector2dF current_vertical(
- current_screen_transform.matrix().get(0, 1) * current_tile_height,
- current_screen_transform.matrix().get(1, 1) * current_tile_height);
-
- gfx::Vector2dF last_horizontal(
- last_screen_transform.matrix().get(0, 0) * last_tile_width,
- last_screen_transform.matrix().get(1, 0) * last_tile_width);
- gfx::Vector2dF last_vertical(
- last_screen_transform.matrix().get(0, 1) * last_tile_height,
- last_screen_transform.matrix().get(1, 1) * last_tile_height);
-
- for (TilingData::Iterator iter(&tiling_data_, interest_rect);
- iter; ++iter) {
- TileMap::iterator find = tiles_.find(iter.index());
- if (find == tiles_.end())
- continue;
+ // Assign soon priority to all tiles in the skewport that are not visible.
+ float content_to_screen_scale =
+ 1.0f / (contents_scale_ * layer_contents_scale);
+ for (TilingData::DifferenceIterator iter(
+ &tiling_data_, skewport, visible_rect_in_content_space);
+ iter;
+ ++iter) {
+ TileMap::iterator find = tiles_.find(iter.index());
+ if (find == tiles_.end())
+ continue;
+ Tile* tile = find->second.get();
- Tile* tile = find->second.get();
-
- int i = iter.index_x();
- int j = iter.index_y();
- gfx::PointF current_tile_origin = current_screen_space_origin +
- ScaleVector2d(current_horizontal, i) +
- ScaleVector2d(current_vertical, j);
- gfx::PointF last_tile_origin = last_screen_space_origin +
- ScaleVector2d(last_horizontal, i) +
- ScaleVector2d(last_vertical, j);
-
- gfx::RectF current_screen_rect = gfx::QuadF(
- current_tile_origin,
- current_tile_origin + current_horizontal,
- current_tile_origin + current_horizontal + current_vertical,
- current_tile_origin + current_vertical).BoundingBox();
-
- gfx::RectF last_screen_rect = gfx::QuadF(
- last_tile_origin,
- last_tile_origin + last_horizontal,
- last_tile_origin + last_horizontal + last_vertical,
- last_tile_origin + last_vertical).BoundingBox();
-
- float distance_to_visible_in_pixels =
- current_screen_rect.ManhattanInternalDistance(view_rect);
-
- float time_to_visible_in_seconds =
- TilePriority::TimeForBoundsToIntersect(
- last_screen_rect, current_screen_rect, time_delta, view_rect);
- TilePriority priority(
- resolution_,
- time_to_visible_in_seconds,
- distance_to_visible_in_pixels);
- tile->SetPriority(tree, priority);
- }
- } else {
- for (TilingData::Iterator iter(&tiling_data_, interest_rect);
- iter; ++iter) {
- TileMap::iterator find = tiles_.find(iter.index());
- if (find == tiles_.end())
- continue;
- Tile* tile = find->second.get();
-
- gfx::Rect tile_bounds =
- tiling_data_.TileBounds(iter.index_x(), iter.index_y());
- gfx::RectF current_layer_content_rect = gfx::ScaleRect(
- tile_bounds,
- current_scale,
- current_scale);
- gfx::RectF current_screen_rect = MathUtil::MapClippedRect(
- current_screen_transform, current_layer_content_rect);
- gfx::RectF last_layer_content_rect = gfx::ScaleRect(
- tile_bounds,
- last_scale,
- last_scale);
- gfx::RectF last_screen_rect = MathUtil::MapClippedRect(
- last_screen_transform, last_layer_content_rect);
-
- float distance_to_visible_in_pixels =
- current_screen_rect.ManhattanInternalDistance(view_rect);
-
- float time_to_visible_in_seconds =
- TilePriority::TimeForBoundsToIntersect(
- last_screen_rect, current_screen_rect, time_delta, view_rect);
-
- TilePriority priority(
- resolution_,
- time_to_visible_in_seconds,
- distance_to_visible_in_pixels);
- tile->SetPriority(tree, priority);
- }
+ gfx::Rect tile_bounds =
+ tiling_data_.TileBounds(iter.index_x(), iter.index_y());
+
+ float distance_to_visible =
+ visible_rect_in_content_space.ManhattanInternalDistance(tile_bounds) *
+ content_to_screen_scale;
+
+ TilePriority priority(resolution_, TilePriority::SOON, distance_to_visible);
+ tile->SetPriority(tree, priority);
}
- last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds;
+ // Assign eventually priority to all tiles in the eventually rect that are not
+ // in the skewport.
+ for (TilingData::DifferenceIterator iter(
+ &tiling_data_, eventually_rect, skewport);
+ iter;
+ ++iter) {
+ TileMap::iterator find = tiles_.find(iter.index());
+ if (find == tiles_.end())
+ continue;
+ Tile* tile = find->second.get();
+
+ gfx::Rect tile_bounds =
+ tiling_data_.TileBounds(iter.index_x(), iter.index_y());
+
+ float distance_to_visible =
+ visible_rect_in_content_space.ManhattanInternalDistance(tile_bounds) *
+ content_to_screen_scale;
+ TilePriority priority(
+ resolution_, TilePriority::EVENTUALLY, distance_to_visible);
+ tile->SetPriority(tree, priority);
+ }
}
void PictureLayerTiling::SetLiveTilesRect(

Powered by Google App Engine
This is Rietveld 408576698