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

Unified Diff: cc/tiles/picture_layer_tiling_set.cc

Issue 1939963002: cc: Move prepaint region calculations to the tiling set. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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/tiles/picture_layer_tiling_set.cc
diff --git a/cc/tiles/picture_layer_tiling_set.cc b/cc/tiles/picture_layer_tiling_set.cc
index 865ff0976d459f21a5bf049531f430829eb064e9..f4c26a0668c524ad906ac92378a3d4a7bf2b8e15 100644
--- a/cc/tiles/picture_layer_tiling_set.cc
+++ b/cc/tiles/picture_layer_tiling_set.cc
@@ -12,6 +12,7 @@
#include "base/memory/ptr_util.h"
#include "cc/playback/raster_source.h"
+#include "ui/gfx/geometry/rect_conversions.h"
namespace cc {
@@ -31,31 +32,34 @@ inline float LargerRatio(float float1, float float2) {
return float1 > float2 ? float1 / float2 : float2 / float1;
}
+const float kSoonBorderDistanceViewportPercentage = 0.15f;
+const float kMaxSoonBorderDistanceInScreenPixels = 312.f;
+
} // namespace
// static
std::unique_ptr<PictureLayerTilingSet> PictureLayerTilingSet::Create(
WhichTree tree,
PictureLayerTilingClient* client,
- size_t tiling_interest_area_padding,
+ int tiling_interest_area_padding,
float skewport_target_time_in_seconds,
- int skewport_extrapolation_limit_in_content_pixels) {
- return base::WrapUnique(new PictureLayerTilingSet(
- tree, client, tiling_interest_area_padding,
- skewport_target_time_in_seconds,
- skewport_extrapolation_limit_in_content_pixels));
+ int skewport_extrapolation_limit_in_screen_pixels) {
+ return base::WrapUnique(
+ new PictureLayerTilingSet(tree, client, tiling_interest_area_padding,
+ skewport_target_time_in_seconds,
+ skewport_extrapolation_limit_in_screen_pixels));
}
PictureLayerTilingSet::PictureLayerTilingSet(
WhichTree tree,
PictureLayerTilingClient* client,
- size_t tiling_interest_area_padding,
+ int tiling_interest_area_padding,
float skewport_target_time_in_seconds,
- int skewport_extrapolation_limit_in_content_pixels)
+ int skewport_extrapolation_limit_in_screen_pixels)
: tiling_interest_area_padding_(tiling_interest_area_padding),
skewport_target_time_in_seconds_(skewport_target_time_in_seconds),
- skewport_extrapolation_limit_in_content_pixels_(
- skewport_extrapolation_limit_in_content_pixels),
+ skewport_extrapolation_limit_in_screen_pixels_(
+ skewport_extrapolation_limit_in_screen_pixels),
tree_(tree),
client_(client) {}
@@ -79,14 +83,12 @@ void PictureLayerTilingSet::CopyTilingsAndPropertiesFromPendingTwin(
float contents_scale = pending_twin_tiling->contents_scale();
PictureLayerTiling* this_tiling = FindTilingWithScale(contents_scale);
if (!this_tiling) {
- std::unique_ptr<PictureLayerTiling> new_tiling =
- PictureLayerTiling::Create(
- tree_, contents_scale, raster_source, client_,
- tiling_interest_area_padding_, skewport_target_time_in_seconds_,
- skewport_extrapolation_limit_in_content_pixels_);
+ std::unique_ptr<PictureLayerTiling> new_tiling(new PictureLayerTiling(
+ tree_, contents_scale, raster_source_, client_));
tilings_.push_back(std::move(new_tiling));
this_tiling = tilings_.back().get();
tiling_sort_required = true;
+ state_since_last_tile_priority_update_.added_tilings = true;
}
this_tiling->TakeTilesAndPropertiesFrom(pending_twin_tiling.get(),
layer_invalidation);
@@ -107,6 +109,8 @@ void PictureLayerTilingSet::UpdateTilingsToCurrentRasterSourceForActivation(
RemoveTilingsBelowScale(minimum_contents_scale);
RemoveTilingsAboveScale(maximum_contents_scale);
+ raster_source_ = raster_source;
+
// Copy over tilings that are shared with the |pending_twin_set| tiling set.
// Also, copy all of the properties from twin tilings.
CopyTilingsAndPropertiesFromPendingTwin(pending_twin_set, raster_source,
@@ -120,6 +124,7 @@ void PictureLayerTilingSet::UpdateTilingsToCurrentRasterSourceForActivation(
tiling->SetRasterSourceAndResize(raster_source);
tiling->Invalidate(layer_invalidation);
+ state_since_last_tile_priority_update_.invalidated = true;
// This is needed for cases where the live tiles rect didn't change but
// recordings exist in the raster source that did not exist on the last
// raster source.
@@ -145,6 +150,8 @@ void PictureLayerTilingSet::UpdateTilingsToCurrentRasterSourceForCommit(
RemoveTilingsBelowScale(minimum_contents_scale);
RemoveTilingsAboveScale(maximum_contents_scale);
+ raster_source_ = raster_source;
+
// Invalidate tiles and update them to the new raster source.
for (const std::unique_ptr<PictureLayerTiling>& tiling : tilings_) {
DCHECK(tree_ != PENDING_TREE || !tiling->has_tiles());
@@ -152,8 +159,10 @@ void PictureLayerTilingSet::UpdateTilingsToCurrentRasterSourceForCommit(
// We can commit on either active or pending trees, but only active one can
// have tiles at this point.
- if (tree_ == ACTIVE_TREE)
+ if (tree_ == ACTIVE_TREE) {
tiling->Invalidate(layer_invalidation);
+ state_since_last_tile_priority_update_.invalidated = true;
+ }
// This is needed for cases where the live tiles rect didn't change but
// recordings exist in the raster source that did not exist on the last
@@ -166,9 +175,11 @@ void PictureLayerTilingSet::UpdateTilingsToCurrentRasterSourceForCommit(
void PictureLayerTilingSet::UpdateRasterSourceDueToLCDChange(
scoped_refptr<RasterSource> raster_source,
const Region& layer_invalidation) {
+ raster_source_ = raster_source;
for (const auto& tiling : tilings_) {
tiling->SetRasterSourceAndResize(raster_source);
tiling->Invalidate(layer_invalidation);
+ state_since_last_tile_priority_update_.invalidated = true;
// Since the invalidation changed, we need to create any missing tiles in
// the live tiles rect again.
tiling->CreateMissingTilesInLiveTilesRect();
@@ -252,16 +263,18 @@ void PictureLayerTilingSet::MarkAllTilingsNonIdeal() {
PictureLayerTiling* PictureLayerTilingSet::AddTiling(
float contents_scale,
scoped_refptr<RasterSource> raster_source) {
+ if (!raster_source_)
+ raster_source_ = raster_source;
+
for (size_t i = 0; i < tilings_.size(); ++i) {
DCHECK_NE(tilings_[i]->contents_scale(), contents_scale);
DCHECK_EQ(tilings_[i]->raster_source(), raster_source.get());
}
- tilings_.push_back(PictureLayerTiling::Create(
- tree_, contents_scale, raster_source, client_,
- tiling_interest_area_padding_, skewport_target_time_in_seconds_,
- skewport_extrapolation_limit_in_content_pixels_));
+ tilings_.push_back(base::WrapUnique(
+ new PictureLayerTiling(tree_, contents_scale, raster_source, client_)));
PictureLayerTiling* appended = tilings_.back().get();
+ state_since_last_tile_priority_update_.added_tilings = true;
std::sort(tilings_.begin(), tilings_.end(), LargestToSmallestScaleFunctor());
return appended;
@@ -357,21 +370,165 @@ float PictureLayerTilingSet::GetMaximumContentsScale() const {
return tilings_[0]->contents_scale();
}
+bool PictureLayerTilingSet::TilingsNeedUpdate(
+ const gfx::Rect& visible_rect_in_layer_space,
+ double current_frame_time_in_seconds) {
+ // If we don't have any tilings, we don't need an update.
+ if (num_tilings() == 0)
+ return false;
+
+ // If we never updated the tiling set, then our history is empty. We should
+ // update tilings.
+ if (visible_rect_history_.empty())
+ return true;
+
+ // If we've added new tilings since the last update, then we have to update at
+ // least that one tiling.
+ if (state_since_last_tile_priority_update_.added_tilings)
+ return true;
+
+ // Finally, if some state changed (either frame time or visible rect), then we
+ // need to inform the tilings of the change.
+ const auto& last_frame = visible_rect_history_.front();
+ if (current_frame_time_in_seconds != last_frame.frame_time_in_seconds)
+ return true;
+
+ if (visible_rect_in_layer_space != last_frame.visible_rect_in_layer_space)
+ return true;
+ return false;
+}
+
+gfx::Rect PictureLayerTilingSet::ComputeSkewport(
+ const gfx::Rect& visible_rect_in_layer_space,
+ double current_frame_time_in_seconds,
+ float ideal_contents_scale) {
+ gfx::Rect skewport = visible_rect_in_layer_space;
+ if (skewport.IsEmpty() || visible_rect_history_.empty())
+ return skewport;
+
+ // Use the oldest recorded history to get a stable skewport.
+ const auto& historical_frame = visible_rect_history_.back();
+ double time_delta =
+ current_frame_time_in_seconds - historical_frame.frame_time_in_seconds;
+ if (time_delta == 0.)
+ return skewport;
+
+ double extrapolation_multiplier =
+ skewport_target_time_in_seconds_ / time_delta;
+ int old_x = historical_frame.visible_rect_in_layer_space.x();
+ int old_y = historical_frame.visible_rect_in_layer_space.y();
+ int old_right = historical_frame.visible_rect_in_layer_space.right();
+ int old_bottom = historical_frame.visible_rect_in_layer_space.bottom();
+
+ int new_x = visible_rect_in_layer_space.x();
+ int new_y = visible_rect_in_layer_space.y();
+ int new_right = visible_rect_in_layer_space.right();
+ int new_bottom = visible_rect_in_layer_space.bottom();
+
+ int inset_x = (new_x - old_x) * extrapolation_multiplier;
+ int inset_y = (new_y - old_y) * extrapolation_multiplier;
+ int inset_right = (old_right - new_right) * extrapolation_multiplier;
+ int inset_bottom = (old_bottom - new_bottom) * extrapolation_multiplier;
+
+ int skewport_extrapolation_limit_in_layer_pixels =
+ skewport_extrapolation_limit_in_screen_pixels_ / ideal_contents_scale;
+ gfx::Rect max_skewport = skewport;
+ max_skewport.Inset(-skewport_extrapolation_limit_in_layer_pixels,
+ -skewport_extrapolation_limit_in_layer_pixels);
+
+ skewport.Inset(inset_x, inset_y, inset_right, inset_bottom);
+ skewport.Union(visible_rect_in_layer_space);
+ skewport.Intersect(max_skewport);
+
+ // Due to limits in int's representation, it is possible that the two
+ // operations above (union and intersect) result in an empty skewport. To
+ // avoid any unpleasant situations like that, union the visible rect again to
+ // ensure that skewport.Contains(visible_rect_in_layer_space) is always
+ // true.
+ skewport.Union(visible_rect_in_layer_space);
+ return skewport;
+}
+
+gfx::Rect PictureLayerTilingSet::ComputeSoonBorderRect(
+ const gfx::Rect& visible_rect,
+ float ideal_contents_scale) {
+ int max_dimension = std::max(visible_rect.width(), visible_rect.height());
+ int distance =
+ std::min<int>(kMaxSoonBorderDistanceInScreenPixels * ideal_contents_scale,
+ max_dimension * kSoonBorderDistanceViewportPercentage);
+
+ gfx::Rect soon_border_rect = visible_rect;
+ soon_border_rect.Inset(-distance, -distance);
+ return soon_border_rect;
+}
+
+void PictureLayerTilingSet::UpdatePriorityRects(
+ const gfx::Rect& visible_rect_in_layer_space,
+ double current_frame_time_in_seconds,
+ float ideal_contents_scale) {
+ visible_rect_in_layer_space_ = gfx::Rect();
+ eventually_rect_in_layer_space_ = gfx::Rect();
+
+ // We keep things as floats in here.
+ if (!visible_rect_in_layer_space.IsEmpty()) {
+ gfx::RectF eventually_rectf(visible_rect_in_layer_space);
+ eventually_rectf.Inset(-tiling_interest_area_padding_,
+ -tiling_interest_area_padding_);
+ if (eventually_rectf.Intersects(
+ gfx::RectF(gfx::SizeF(raster_source_->GetSize())))) {
+ visible_rect_in_layer_space_ = visible_rect_in_layer_space;
+ eventually_rect_in_layer_space_ = gfx::ToEnclosingRect(eventually_rectf);
+ }
+ }
+
+ skewport_in_layer_space_ =
+ ComputeSkewport(visible_rect_in_layer_space_,
+ current_frame_time_in_seconds, ideal_contents_scale);
+ DCHECK(skewport_in_layer_space_.Contains(visible_rect_in_layer_space_));
+ DCHECK(eventually_rect_in_layer_space_.Contains(skewport_in_layer_space_));
+
+ soon_border_rect_in_layer_space_ =
+ ComputeSoonBorderRect(visible_rect_in_layer_space_, ideal_contents_scale);
+ DCHECK(
+ soon_border_rect_in_layer_space_.Contains(visible_rect_in_layer_space_));
+ DCHECK(eventually_rect_in_layer_space_.Contains(
+ soon_border_rect_in_layer_space_));
+
+ // Finally, update our visible rect history. Note that we use the original
+ // visible rect here, since we want as accurate of a history as possible for
+ // stable skewports.
+ visible_rect_history_.push_front(FrameVisibleRect(
+ visible_rect_in_layer_space_, current_frame_time_in_seconds));
+ if (visible_rect_history_.size() > 2)
+ visible_rect_history_.pop_back();
+}
+
bool PictureLayerTilingSet::UpdateTilePriorities(
- const gfx::Rect& required_rect_in_layer_space,
+ const gfx::Rect& visible_rect_in_layer_space,
float ideal_contents_scale,
double current_frame_time_in_seconds,
const Occlusion& occlusion_in_layer_space,
bool can_require_tiles_for_activation) {
- bool updated = false;
+ StateSinceLastTilePriorityUpdate::AutoClear auto_clear_state(
+ &state_since_last_tile_priority_update_);
+
+ if (!TilingsNeedUpdate(visible_rect_in_layer_space,
+ current_frame_time_in_seconds)) {
+ return state_since_last_tile_priority_update_.invalidated;
+ }
+
+ UpdatePriorityRects(visible_rect_in_layer_space,
+ current_frame_time_in_seconds, ideal_contents_scale);
+
for (const auto& tiling : tilings_) {
tiling->set_can_require_tiles_for_activation(
can_require_tiles_for_activation);
- updated |= tiling->ComputeTilePriorityRects(
- required_rect_in_layer_space, ideal_contents_scale,
- current_frame_time_in_seconds, occlusion_in_layer_space);
+ tiling->ComputeTilePriorityRects(
+ visible_rect_in_layer_space_, skewport_in_layer_space_,
+ soon_border_rect_in_layer_space_, eventually_rect_in_layer_space_,
+ ideal_contents_scale, occlusion_in_layer_space);
}
- return updated;
+ return true;
}
void PictureLayerTilingSet::GetAllPrioritizedTilesForTracing(

Powered by Google App Engine
This is Rietveld 408576698