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

Side by Side Diff: cc/tile_priority.cc

Issue 12084031: A host of micro-optimizations and a refactor of TimeForBoundsToIntersect (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebasing to tip of tree Created 7 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « cc/tile_priority.h ('k') | cc/tile_priority_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/tile_priority.h" 5 #include "cc/tile_priority.h"
6 6
7 #include "base/values.h" 7 #include "base/values.h"
8 8
9 namespace { 9 namespace {
10 10
11 // TODO(qinmin): modify ui/range/Range.h to support template so that we 11 // TODO(qinmin): modify ui/range/Range.h to support template so that we
12 // don't need to define this. 12 // don't need to define this.
13 struct Range { 13 struct Range {
14 Range(double start, double end) : start_(start), end_(end) {} 14 Range(float start, float end) : start_(start), end_(end) {}
15 Range Intersects(const Range& other);
16 bool IsEmpty(); 15 bool IsEmpty();
17 double start_; 16 float start_;
18 double end_; 17 float end_;
19 }; 18 };
20 19
21 Range Range::Intersects(const Range& other) { 20 inline bool Intersects(const Range& a, const Range& b) {
22 start_ = std::max(start_, other.start_); 21 return a.start_ < b.end_ && b.start_ < a.end_;
23 end_ = std::min(end_, other.end_); 22 }
24 return Range(start_, end_); 23
24 inline Range Intersect(const Range& a, const Range& b) {
25 return Range(std::max(a.start_, b.start_), std::min(a.end_, b.end_));
25 } 26 }
26 27
27 bool Range::IsEmpty() { 28 bool Range::IsEmpty() {
28 return start_ >= end_; 29 return start_ >= end_;
29 } 30 }
30 31
31 // Calculate a time range that |value| will be larger than |threshold| 32 inline void IntersectNegativeHalfplane(Range& out, float previous,
32 // given the velocity of its change. 33 float current, float target, float time_delta) {
33 Range TimeRangeValueLargerThanThreshold( 34 float time_per_dist = time_delta / (current - previous);
34 int value, int threshold, double velocity) { 35 float t = (target - current) * time_per_dist;
35 double minimum_time = 0; 36 if (time_per_dist > 0.0f)
36 double maximum_time = cc::TilePriority::kMaxTimeToVisibleInSeconds; 37 out.start_ = std::max(out.start_, t);
38 else
39 out.end_ = std::min(out.end_, t);
40 }
37 41
38 if (velocity > 0) { 42 inline void IntersectPositiveHalfplane(Range& out, float previous,
39 if (value < threshold) 43 float current, float target, float time_delta) {
40 minimum_time = std::min(cc::TilePriority::kMaxTimeToVisibleInSeconds, 44 float time_per_dist = time_delta / (current - previous);
41 (threshold - value) / velocity); 45 float t = (target - current) * time_per_dist;
42 } else if (velocity <= 0) { 46 if (time_per_dist < 0.0f)
43 if (value < threshold) 47 out.start_ = std::max(out.start_, t);
44 minimum_time = cc::TilePriority::kMaxTimeToVisibleInSeconds; 48 else
45 else if (velocity != 0) 49 out.end_ = std::min(out.end_, t);
46 maximum_time = std::min(maximum_time, (threshold - value) / velocity);
47 }
48
49 return Range(minimum_time, maximum_time);
50 } 50 }
51 51
52 } // namespace 52 } // namespace
53 53
54 namespace cc { 54 namespace cc {
55 55
56 const double TilePriority::kMaxTimeToVisibleInSeconds = 1000.0; 56 const float TilePriority::kMaxDistanceInContentSpace = 4096.0f;
57 const double TilePriority::kMaxDistanceInContentSpace = 4096.0;
58 57
59 scoped_ptr<base::Value> WhichTreeAsValue(WhichTree tree) { 58 scoped_ptr<base::Value> WhichTreeAsValue(WhichTree tree) {
60 switch (tree) { 59 switch (tree) {
61 case ACTIVE_TREE: 60 case ACTIVE_TREE:
62 return scoped_ptr<base::Value>(base::Value::CreateStringValue( 61 return scoped_ptr<base::Value>(base::Value::CreateStringValue(
63 "ACTIVE_TREE")); 62 "ACTIVE_TREE"));
64 case PENDING_TREE: 63 case PENDING_TREE:
65 return scoped_ptr<base::Value>(base::Value::CreateStringValue( 64 return scoped_ptr<base::Value>(base::Value::CreateStringValue(
66 "PENDING_TREE")); 65 "PENDING_TREE"));
67 default: 66 default:
68 DCHECK(false) << "Unrecognized WhichTree value"; 67 DCHECK(false) << "Unrecognized WhichTree value";
69 return scoped_ptr<base::Value>(base::Value::CreateStringValue( 68 return scoped_ptr<base::Value>(base::Value::CreateStringValue(
70 "<unknown WhichTree value>")); 69 "<unknown WhichTree value>"));
71 } 70 }
72 } 71 }
73 72
74 int TilePriority::manhattanDistance(const gfx::RectF& a, const gfx::RectF& b) {
75 gfx::RectF c = gfx::UnionRects(a, b);
76 // Rects touching the edge of the screen should not be considered visible.
77 // So we add 1 pixel here to avoid that situation.
78 int x = static_cast<int>(
79 std::max(0.0f, c.width() - a.width() - b.width() + 1));
80 int y = static_cast<int>(
81 std::max(0.0f, c.height() - a.height() - b.height() + 1));
82 return (x + y);
83 }
84 73
85 double TilePriority::TimeForBoundsToIntersect(gfx::RectF previous_bounds, 74 float TilePriority::TimeForBoundsToIntersect(const gfx::RectF& previous_bounds,
86 gfx::RectF current_bounds, 75 const gfx::RectF& current_bounds,
87 double time_delta, 76 float time_delta,
88 gfx::RectF target_bounds) { 77 const gfx::RectF& target_bounds) {
89 if (current_bounds.Intersects(target_bounds)) 78 // Perform an intersection test explicitly between current and target.
90 return 0; 79 if (current_bounds.x() < target_bounds.right() &&
80 current_bounds.y() < target_bounds.bottom() &&
81 target_bounds.x() < current_bounds.right() &&
82 target_bounds.y() < current_bounds.bottom())
83 return 0.0f;
91 84
92 if (previous_bounds.Intersects(target_bounds) || time_delta == 0) 85 const float kMaxTimeToVisibleInSeconds =
86 std::numeric_limits<float>::infinity();
87
88 if (time_delta == 0.0f)
93 return kMaxTimeToVisibleInSeconds; 89 return kMaxTimeToVisibleInSeconds;
94 90
95 // As we are trying to solve the case of both scaling and scrolling, using 91 // As we are trying to solve the case of both scaling and scrolling, using
96 // a single coordinate with velocity is not enough. The logic here is to 92 // a single coordinate with velocity is not enough. The logic here is to
97 // calculate the velocity for each edge. Then we calculate the time range that 93 // calculate the velocity for each edge. Then we calculate the time range that
98 // each edge will stay on the same side of the target bounds. If there is an 94 // each edge will stay on the same side of the target bounds. If there is an
99 // overlap between these time ranges, the bounds must have intersect with 95 // overlap between these time ranges, the bounds must have intersect with
100 // each other during that period of time. 96 // each other during that period of time.
101 double velocity = 97 Range range(0.0f, kMaxTimeToVisibleInSeconds);
102 (current_bounds.right() - previous_bounds.right()) / time_delta; 98 IntersectPositiveHalfplane(
103 Range range = TimeRangeValueLargerThanThreshold( 99 range, previous_bounds.x(), current_bounds.x(),
104 current_bounds.right(), target_bounds.x(), velocity); 100 target_bounds.right(), time_delta);
105 101 IntersectNegativeHalfplane(
106 velocity = (current_bounds.x() - previous_bounds.x()) / time_delta; 102 range, previous_bounds.right(), current_bounds.right(),
107 range = range.Intersects(TimeRangeValueLargerThanThreshold( 103 target_bounds.x(), time_delta);
108 -current_bounds.x(), -target_bounds.right(), -velocity)); 104 IntersectPositiveHalfplane(
109 105 range, previous_bounds.y(), current_bounds.y(),
110 106 target_bounds.bottom(), time_delta);
111 velocity = (current_bounds.y() - previous_bounds.y()) / time_delta; 107 IntersectNegativeHalfplane(
112 range = range.Intersects(TimeRangeValueLargerThanThreshold( 108 range, previous_bounds.bottom(), current_bounds.bottom(),
113 -current_bounds.y(), -target_bounds.bottom(), -velocity)); 109 target_bounds.y(), time_delta);
114
115 velocity = (current_bounds.bottom() - previous_bounds.bottom()) / time_delta;
116 range = range.Intersects(TimeRangeValueLargerThanThreshold(
117 current_bounds.bottom(), target_bounds.y(), velocity));
118
119 return range.IsEmpty() ? kMaxTimeToVisibleInSeconds : range.start_; 110 return range.IsEmpty() ? kMaxTimeToVisibleInSeconds : range.start_;
120 } 111 }
121 112
122 scoped_ptr<base::Value> TileMemoryLimitPolicyAsValue( 113 scoped_ptr<base::Value> TileMemoryLimitPolicyAsValue(
123 TileMemoryLimitPolicy policy) { 114 TileMemoryLimitPolicy policy) {
124 switch (policy) { 115 switch (policy) {
125 case ALLOW_NOTHING: 116 case ALLOW_NOTHING:
126 return scoped_ptr<base::Value>(base::Value::CreateStringValue( 117 return scoped_ptr<base::Value>(base::Value::CreateStringValue(
127 "ALLOW_NOTHING")); 118 "ALLOW_NOTHING"));
128 case ALLOW_ABSOLUTE_MINIMUM: 119 case ALLOW_ABSOLUTE_MINIMUM:
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 scoped_ptr<base::Value> GlobalStateThatImpactsTilePriority::AsValue() const { 153 scoped_ptr<base::Value> GlobalStateThatImpactsTilePriority::AsValue() const {
163 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); 154 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
164 state->Set("memory_limit_policy", TileMemoryLimitPolicyAsValue(memory_limit_po licy).release()); 155 state->Set("memory_limit_policy", TileMemoryLimitPolicyAsValue(memory_limit_po licy).release());
165 state->SetInteger("memory_limit_in_bytes", memory_limit_in_bytes); 156 state->SetInteger("memory_limit_in_bytes", memory_limit_in_bytes);
166 state->Set("tree_priority", TreePriorityAsValue(tree_priority).release()); 157 state->Set("tree_priority", TreePriorityAsValue(tree_priority).release());
167 return state.PassAs<base::Value>(); 158 return state.PassAs<base::Value>();
168 } 159 }
169 160
170 161
171 } // namespace cc 162 } // namespace cc
OLDNEW
« no previous file with comments | « cc/tile_priority.h ('k') | cc/tile_priority_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698