summaryrefslogtreecommitdiffstats
path: root/cc/tile_priority.cc
diff options
context:
space:
mode:
authorjochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-31 09:29:27 +0000
committerjochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-31 09:29:27 +0000
commit7fbc3818fb03439153c32f20e024db9b3103c3bb (patch)
treec9d06e199e69bd1e887300bbb5a64406d738a1b4 /cc/tile_priority.cc
parentfe2da44a03faf54f1f26e6a67182d7945a876c1a (diff)
downloadchromium_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.cc116
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_;
}