| 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..939e0b163d4a459aa50d0437a9aec5b94c2f8230 100644
|
| --- a/cc/resources/picture_layer_tiling.cc
|
| +++ b/cc/resources/picture_layer_tiling.cc
|
| @@ -339,223 +339,154 @@ 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_x = last_visible_rect_in_content_space_.x();
|
| + int old_y = last_visible_rect_in_content_space_.y();
|
| + int old_right = last_visible_rect_in_content_space_.right();
|
| + int old_bottom = last_visible_rect_in_content_space_.bottom();
|
| +
|
| + int new_x = visible_rect_in_content_space.x();
|
| + int new_y = visible_rect_in_content_space.y();
|
| + int new_right = visible_rect_in_content_space.right();
|
| + int new_bottom = visible_rect_in_content_space.bottom();
|
| +
|
| + int skewport_limit = client_->GetSkewportExtrapolationLimitInContentPixels();
|
| +
|
| + // Compute the maximum skewport based on |skewport_limit|.
|
| + gfx::Rect max_skewport = skewport;
|
| + max_skewport.Inset(
|
| + -skewport_limit, -skewport_limit, -skewport_limit, -skewport_limit);
|
| +
|
| + // Inset the skewport by the needed adjustment.
|
| + skewport.Inset(extrapolation_multiplier * (new_x - old_x),
|
| + extrapolation_multiplier * (new_y - old_y),
|
| + extrapolation_multiplier * (old_right - new_right),
|
| + extrapolation_multiplier * (old_bottom - new_bottom));
|
| +
|
| + // Clip the skewport to |max_skewport|.
|
| + skewport.Intersect(max_skewport);
|
| +
|
| + // Finally, ensure that visible rect is contained in the skewport.
|
| + 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(
|
|
|