diff options
author | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-31 09:29:27 +0000 |
---|---|---|
committer | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-31 09:29:27 +0000 |
commit | 7fbc3818fb03439153c32f20e024db9b3103c3bb (patch) | |
tree | c9d06e199e69bd1e887300bbb5a64406d738a1b4 /cc/tile_priority.cc | |
parent | fe2da44a03faf54f1f26e6a67182d7945a876c1a (diff) | |
download | chromium_src-7fbc3818fb03439153c32f20e024db9b3103c3bb.zip chromium_src-7fbc3818fb03439153c32f20e024db9b3103c3bb.tar.gz chromium_src-7fbc3818fb03439153c32f20e024db9b3103c3bb.tar.bz2 |
Revert 179770
Introduces a new static initializer
> A host of micro-optimizations and a refactor of TimeForBoundsToIntersect
>
> I used perf to profile the compositor thread and addressed performance problems
> with the top fuctions. The result is about a 2.5x performance boost.
> (~1.3ms -> ~.5ms) on List of Pokemon for UpdateTilePriorities.
>
> Most of the optimizations are inlining small functions. The refactor of
> TimeForBoundsToIntersect also eliminates many unnecessary float-double
> conversions.
>
>
> BUG=172406
>
>
> Review URL: https://chromiumcodereview.appspot.com/12084031
TBR=whunt@chromium.org
Review URL: https://codereview.chromium.org/12082092
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@179834 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc/tile_priority.cc')
-rw-r--r-- | cc/tile_priority.cc | 116 |
1 files changed, 63 insertions, 53 deletions
diff --git a/cc/tile_priority.cc b/cc/tile_priority.cc index f0c0c53..ec77029 100644 --- a/cc/tile_priority.cc +++ b/cc/tile_priority.cc @@ -11,51 +11,50 @@ namespace { // TODO(qinmin): modify ui/range/Range.h to support template so that we // don't need to define this. struct Range { - Range(float start, float end) : start_(start), end_(end) {} + Range(double start, double end) : start_(start), end_(end) {} + Range Intersects(const Range& other); bool IsEmpty(); - float start_; - float end_; + double start_; + double end_; }; -inline bool Intersects(const Range& a, const Range& b) { - return a.start_ < b.end_ && b.start_ < a.end_; -} - -inline Range Intersect(const Range& a, const Range& b) { - return Range(std::max(a.start_, b.start_), std::min(a.end_, b.end_)); +Range Range::Intersects(const Range& other) { + start_ = std::max(start_, other.start_); + end_ = std::min(end_, other.end_); + return Range(start_, end_); } bool Range::IsEmpty() { return start_ >= end_; } -inline void IntersectNegativeHalfplane(Range& out, float previous, - float current, float target, float time_delta) { - float time_per_dist = time_delta / (current - previous); - float t = (target - current) * time_per_dist; - if (time_per_dist > 0.0f) - out.start_ = std::max(out.start_, t); - else - out.end_ = std::min(out.end_, t); -} +// Calculate a time range that |value| will be larger than |threshold| +// given the velocity of its change. +Range TimeRangeValueLargerThanThreshold( + int value, int threshold, double velocity) { + double minimum_time = 0; + double maximum_time = cc::TilePriority::kMaxTimeToVisibleInSeconds; + + if (velocity > 0) { + if (value < threshold) + minimum_time = std::min(cc::TilePriority::kMaxTimeToVisibleInSeconds, + (threshold - value) / velocity); + } else if (velocity <= 0) { + if (value < threshold) + minimum_time = cc::TilePriority::kMaxTimeToVisibleInSeconds; + else if (velocity != 0) + maximum_time = std::min(maximum_time, (threshold - value) / velocity); + } -inline void IntersectPositiveHalfplane(Range& out, float previous, - float current, float target, float time_delta) { - float time_per_dist = time_delta / (current - previous); - float t = (target - current) * time_per_dist; - if (time_per_dist < 0.0f) - out.start_ = std::max(out.start_, t); - else - out.end_ = std::min(out.end_, t); + return Range(minimum_time, maximum_time); } } // namespace namespace cc { -const float TilePriority::kMaxDistanceInContentSpace = 4096.0f; -const float TilePriority::kMaxTimeToVisibleInSeconds = - std::numeric_limits<float>::infinity(); +const double TilePriority::kMaxTimeToVisibleInSeconds = 1000.0; +const double TilePriority::kMaxDistanceInContentSpace = 4096.0; scoped_ptr<base::Value> WhichTreeAsValue(WhichTree tree) { switch (tree) { @@ -72,19 +71,25 @@ scoped_ptr<base::Value> WhichTreeAsValue(WhichTree tree) { } } +int TilePriority::manhattanDistance(const gfx::RectF& a, const gfx::RectF& b) { + gfx::RectF c = gfx::UnionRects(a, b); + // Rects touching the edge of the screen should not be considered visible. + // So we add 1 pixel here to avoid that situation. + int x = static_cast<int>( + std::max(0.0f, c.width() - a.width() - b.width() + 1)); + int y = static_cast<int>( + std::max(0.0f, c.height() - a.height() - b.height() + 1)); + return (x + y); +} -float TilePriority::TimeForBoundsToIntersect(const gfx::RectF& previous_bounds, - const gfx::RectF& current_bounds, - float time_delta, - const gfx::RectF& target_bounds) { - // Perform an intersection test explicitly between current and target. - if (current_bounds.x() < target_bounds.right() && - current_bounds.y() < target_bounds.bottom() && - target_bounds.x() < current_bounds.right() && - target_bounds.y() < current_bounds.bottom()) - return 0.0f; +double TilePriority::TimeForBoundsToIntersect(gfx::RectF previous_bounds, + gfx::RectF current_bounds, + double time_delta, + gfx::RectF target_bounds) { + if (current_bounds.Intersects(target_bounds)) + return 0; - if (time_delta == 0.0f) + if (previous_bounds.Intersects(target_bounds) || time_delta == 0) return kMaxTimeToVisibleInSeconds; // As we are trying to solve the case of both scaling and scrolling, using @@ -93,19 +98,24 @@ float TilePriority::TimeForBoundsToIntersect(const gfx::RectF& previous_bounds, // each edge will stay on the same side of the target bounds. If there is an // overlap between these time ranges, the bounds must have intersect with // each other during that period of time. - Range range(0.0f, kMaxTimeToVisibleInSeconds); - IntersectPositiveHalfplane( - range, previous_bounds.x(), current_bounds.x(), - target_bounds.right(), time_delta); - IntersectNegativeHalfplane( - range, previous_bounds.right(), current_bounds.right(), - target_bounds.x(), time_delta); - IntersectPositiveHalfplane( - range, previous_bounds.y(), current_bounds.y(), - target_bounds.bottom(), time_delta); - IntersectNegativeHalfplane( - range, previous_bounds.bottom(), current_bounds.bottom(), - target_bounds.y(), time_delta); + double velocity = + (current_bounds.right() - previous_bounds.right()) / time_delta; + Range range = TimeRangeValueLargerThanThreshold( + current_bounds.right(), target_bounds.x(), velocity); + + velocity = (current_bounds.x() - previous_bounds.x()) / time_delta; + range = range.Intersects(TimeRangeValueLargerThanThreshold( + -current_bounds.x(), -target_bounds.right(), -velocity)); + + + velocity = (current_bounds.y() - previous_bounds.y()) / time_delta; + range = range.Intersects(TimeRangeValueLargerThanThreshold( + -current_bounds.y(), -target_bounds.bottom(), -velocity)); + + velocity = (current_bounds.bottom() - previous_bounds.bottom()) / time_delta; + range = range.Intersects(TimeRangeValueLargerThanThreshold( + current_bounds.bottom(), target_bounds.y(), velocity)); + return range.IsEmpty() ? kMaxTimeToVisibleInSeconds : range.start_; } |