Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / cc / resources / tile_priority.cc
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
3 // found in the LICENSE file.
4
5 #include "cc/resources/tile_priority.h"
6
7 #include "base/values.h"
8 #include "cc/base/math_util.h"
9
10 namespace {
11
12 // TODO(qinmin): modify ui/gfx/range/range.h to support template so that we
13 // don't need to define this.
14 struct Range {
15   Range(float start, float end) : start_(start), end_(end) {}
16   bool IsEmpty();
17   float start_;
18   float end_;
19 };
20
21 bool Range::IsEmpty() {
22   return start_ >= end_;
23 }
24
25 inline void IntersectNegativeHalfplane(Range* out,
26                                        float previous,
27                                        float current,
28                                        float target,
29                                        float time_delta) {
30   float time_per_dist = time_delta / (current - previous);
31   float t = (target - current) * time_per_dist;
32   if (time_per_dist > 0.0f)
33     out->start_ = std::max(out->start_, t);
34   else
35     out->end_ = std::min(out->end_, t);
36 }
37
38 inline void IntersectPositiveHalfplane(Range* out,
39                                        float previous,
40                                        float current,
41                                        float target,
42                                        float time_delta) {
43   float time_per_dist = time_delta / (current - previous);
44   float t = (target - current) * time_per_dist;
45   if (time_per_dist < 0.0f)
46     out->start_ = std::max(out->start_, t);
47   else
48     out->end_ = std::min(out->end_, t);
49 }
50
51 }  // namespace
52
53 namespace cc {
54
55 scoped_ptr<base::Value> WhichTreeAsValue(WhichTree tree) {
56   switch (tree) {
57   case ACTIVE_TREE:
58       return scoped_ptr<base::Value>(base::Value::CreateStringValue(
59           "ACTIVE_TREE"));
60   case PENDING_TREE:
61       return scoped_ptr<base::Value>(base::Value::CreateStringValue(
62           "PENDING_TREE"));
63   default:
64       DCHECK(false) << "Unrecognized WhichTree value " << tree;
65       return scoped_ptr<base::Value>(base::Value::CreateStringValue(
66           "<unknown WhichTree value>"));
67   }
68 }
69
70 scoped_ptr<base::Value> TileResolutionAsValue(
71     TileResolution resolution) {
72   switch (resolution) {
73   case LOW_RESOLUTION:
74     return scoped_ptr<base::Value>(base::Value::CreateStringValue(
75         "LOW_RESOLUTION"));
76   case HIGH_RESOLUTION:
77     return scoped_ptr<base::Value>(base::Value::CreateStringValue(
78         "HIGH_RESOLUTION"));
79   case NON_IDEAL_RESOLUTION:
80       return scoped_ptr<base::Value>(base::Value::CreateStringValue(
81         "NON_IDEAL_RESOLUTION"));
82   }
83   DCHECK(false) << "Unrecognized TileResolution value " << resolution;
84   return scoped_ptr<base::Value>(base::Value::CreateStringValue(
85       "<unknown TileResolution value>"));
86 }
87
88 scoped_ptr<base::Value> TilePriority::AsValue() const {
89   scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
90   state->Set("resolution", TileResolutionAsValue(resolution).release());
91   state->Set("time_to_visible_in_seconds",
92              MathUtil::AsValueSafely(time_to_visible_in_seconds).release());
93   state->Set("distance_to_visible_in_pixels",
94              MathUtil::AsValueSafely(distance_to_visible_in_pixels).release());
95   return state.PassAs<base::Value>();
96 }
97
98 float TilePriority::TimeForBoundsToIntersect(const gfx::RectF& previous_bounds,
99                                              const gfx::RectF& current_bounds,
100                                              float time_delta,
101                                              const gfx::RectF& target_bounds) {
102   // Perform an intersection test explicitly between current and target.
103   if (current_bounds.x() < target_bounds.right() &&
104       current_bounds.y() < target_bounds.bottom() &&
105       target_bounds.x() < current_bounds.right() &&
106       target_bounds.y() < current_bounds.bottom())
107     return 0.0f;
108
109   const float kMaxTimeToVisibleInSeconds =
110       std::numeric_limits<float>::infinity();
111
112   if (time_delta == 0.0f)
113     return kMaxTimeToVisibleInSeconds;
114
115   // As we are trying to solve the case of both scaling and scrolling, using
116   // a single coordinate with velocity is not enough. The logic here is to
117   // calculate the velocity for each edge. Then we calculate the time range that
118   // each edge will stay on the same side of the target bounds. If there is an
119   // overlap between these time ranges, the bounds must have intersect with
120   // each other during that period of time.
121   Range range(0.0f, kMaxTimeToVisibleInSeconds);
122   IntersectPositiveHalfplane(
123       &range, previous_bounds.x(), current_bounds.x(),
124       target_bounds.right(), time_delta);
125   IntersectNegativeHalfplane(
126       &range, previous_bounds.right(), current_bounds.right(),
127       target_bounds.x(), time_delta);
128   IntersectPositiveHalfplane(
129       &range, previous_bounds.y(), current_bounds.y(),
130       target_bounds.bottom(), time_delta);
131   IntersectNegativeHalfplane(
132       &range, previous_bounds.bottom(), current_bounds.bottom(),
133       target_bounds.y(), time_delta);
134   return range.IsEmpty() ? kMaxTimeToVisibleInSeconds : range.start_;
135 }
136
137 scoped_ptr<base::Value> TileMemoryLimitPolicyAsValue(
138     TileMemoryLimitPolicy policy) {
139   switch (policy) {
140   case ALLOW_NOTHING:
141       return scoped_ptr<base::Value>(base::Value::CreateStringValue(
142           "ALLOW_NOTHING"));
143   case ALLOW_ABSOLUTE_MINIMUM:
144       return scoped_ptr<base::Value>(base::Value::CreateStringValue(
145           "ALLOW_ABSOLUTE_MINIMUM"));
146   case ALLOW_PREPAINT_ONLY:
147       return scoped_ptr<base::Value>(base::Value::CreateStringValue(
148           "ALLOW_PREPAINT_ONLY"));
149   case ALLOW_ANYTHING:
150       return scoped_ptr<base::Value>(base::Value::CreateStringValue(
151           "ALLOW_ANYTHING"));
152   default:
153       DCHECK(false) << "Unrecognized policy value";
154       return scoped_ptr<base::Value>(base::Value::CreateStringValue(
155           "<unknown>"));
156   }
157 }
158
159 scoped_ptr<base::Value> TreePriorityAsValue(TreePriority prio) {
160   switch (prio) {
161   case SAME_PRIORITY_FOR_BOTH_TREES:
162       return scoped_ptr<base::Value>(base::Value::CreateStringValue(
163           "SAME_PRIORITY_FOR_BOTH_TREES"));
164   case SMOOTHNESS_TAKES_PRIORITY:
165       return scoped_ptr<base::Value>(base::Value::CreateStringValue(
166           "SMOOTHNESS_TAKES_PRIORITY"));
167   case NEW_CONTENT_TAKES_PRIORITY:
168       return scoped_ptr<base::Value>(base::Value::CreateStringValue(
169           "NEW_CONTENT_TAKES_PRIORITY"));
170   }
171   DCHECK(false) << "Unrecognized priority value " << prio;
172   return scoped_ptr<base::Value>(base::Value::CreateStringValue(
173       "<unknown>"));
174 }
175
176 scoped_ptr<base::Value> GlobalStateThatImpactsTilePriority::AsValue() const {
177   scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
178   state->Set("memory_limit_policy",
179              TileMemoryLimitPolicyAsValue(memory_limit_policy).release());
180   state->SetInteger("memory_limit_in_bytes", memory_limit_in_bytes);
181   state->SetInteger("unused_memory_limit_in_bytes",
182                     unused_memory_limit_in_bytes);
183   state->SetInteger("num_resources_limit", num_resources_limit);
184   state->Set("tree_priority", TreePriorityAsValue(tree_priority).release());
185   return state.PassAs<base::Value>();
186 }
187
188 }  // namespace cc