summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cc/picture_layer_tiling.cc13
-rw-r--r--cc/tile.cc19
-rw-r--r--cc/tile.h21
-rw-r--r--cc/tile_manager.cc16
-rw-r--r--cc/tile_manager.h13
-rw-r--r--cc/tile_priority.cc117
-rw-r--r--cc/tile_priority.h28
-rw-r--r--cc/tile_priority_unittest.cc8
-rw-r--r--ui/gfx/rect_f.cc18
-rw-r--r--ui/gfx/rect_f.h17
10 files changed, 131 insertions, 139 deletions
diff --git a/cc/picture_layer_tiling.cc b/cc/picture_layer_tiling.cc
index d90eb42..cfa9b60 100644
--- a/cc/picture_layer_tiling.cc
+++ b/cc/picture_layer_tiling.cc
@@ -4,6 +4,7 @@
#include "cc/picture_layer_tiling.h"
+#include "base/debug/trace_event.h"
#include "cc/math_util.h"
#include "ui/gfx/point_conversions.h"
#include "ui/gfx/rect_conversions.h"
@@ -335,6 +336,7 @@ void PictureLayerTiling::UpdateTilePriorities(
const gfx::Transform& current_screen_transform,
int current_source_frame_number,
double current_frame_time) {
+ TRACE_EVENT0("cc", "PictureLayerTiling::UpdateTilePriorities");
gfx::Rect content_rect = ContentRect();
if (content_rect.IsEmpty())
return;
@@ -425,12 +427,12 @@ void PictureLayerTiling::UpdateTilePriorities(
last_scale,
last_scale) + last_offset;
- float time_to_visible_in_seconds =
- TilePriority::TimeForBoundsToIntersect(
- last_screen_rect, current_screen_rect, time_delta, view_rect);
float distance_to_visible_in_pixels =
TilePriority::manhattanDistance(current_screen_rect, view_rect);
+ float time_to_visible_in_seconds =
+ TilePriority::TimeForBoundsToIntersect(
+ last_screen_rect, current_screen_rect, time_delta, view_rect);
TilePriority priority(
resolution_,
time_to_visible_in_seconds,
@@ -462,11 +464,12 @@ void PictureLayerTiling::UpdateTilePriorities(
gfx::RectF last_screen_rect = MathUtil::mapClippedRect(
last_screen_transform, last_layer_content_rect);
+ float distance_to_visible_in_pixels =
+ TilePriority::manhattanDistance(current_screen_rect, view_rect);
+
float time_to_visible_in_seconds =
TilePriority::TimeForBoundsToIntersect(
last_screen_rect, current_screen_rect, time_delta, view_rect);
- float distance_to_visible_in_pixels =
- TilePriority::manhattanDistance(current_screen_rect, view_rect);
TilePriority priority(
resolution_,
diff --git a/cc/tile.cc b/cc/tile.cc
index 7cb4bec..bc07dcc 100644
--- a/cc/tile.cc
+++ b/cc/tile.cc
@@ -28,23 +28,4 @@ Tile::~Tile() {
tile_manager_->UnregisterTile(this);
}
-void Tile::set_priority(WhichTree tree, const TilePriority& priority) {
- tile_manager_->WillModifyTilePriority(this, tree, priority);
- priority_[tree] = priority;
-}
-
-ResourceProvider::ResourceId Tile::GetResourceId() const {
- if (!managed_state_.resource)
- return 0;
- if (managed_state_.resource_is_being_initialized)
- return 0;
-
- return managed_state_.resource->id();
-}
-
-size_t Tile::bytes_consumed_if_allocated() const {
- DCHECK(format_ == GL_RGBA);
- return 4 * tile_size_.width() * tile_size_.height();
-}
-
} // namespace cc
diff --git a/cc/tile.h b/cc/tile.h
index fb0c3f3..d438d8e 100644
--- a/cc/tile.h
+++ b/cc/tile.h
@@ -42,10 +42,20 @@ class CC_EXPORT Tile : public base::RefCounted<Tile> {
priority_[PENDING_TREE]);
}
- void set_priority(WhichTree tree, const TilePriority& priority);
+ void set_priority(WhichTree tree, const TilePriority& priority) {
+ tile_manager_->WillModifyTilePriority(this, tree, priority);
+ priority_[tree] = priority;
+ }
// Returns 0 if not drawable.
- ResourceProvider::ResourceId GetResourceId() const;
+ ResourceProvider::ResourceId GetResourceId() const {
+ if (!managed_state_.resource)
+ return 0;
+ if (managed_state_.resource_is_being_initialized)
+ return 0;
+
+ return managed_state_.resource->id();
+ }
const gfx::Rect& opaque_rect() const { return opaque_rect_; }
@@ -66,7 +76,12 @@ class CC_EXPORT Tile : public base::RefCounted<Tile> {
friend class BinComparator;
ManagedTileState& managed_state() { return managed_state_; }
const ManagedTileState& managed_state() const { return managed_state_; }
- size_t bytes_consumed_if_allocated() const;
+
+ inline size_t bytes_consumed_if_allocated() const {
+ DCHECK(format_ == GL_RGBA);
+ return 4 * tile_size_.width() * tile_size_.height();
+ }
+
// Normal private methods.
friend class base::RefCounted<Tile>;
diff --git a/cc/tile_manager.cc b/cc/tile_manager.cc
index 6c60aec..d2da74c 100644
--- a/cc/tile_manager.cc
+++ b/cc/tile_manager.cc
@@ -35,7 +35,7 @@ const int kMaxPendingUploadBytes = 100 * 1024 * 1024;
// Determine bin based on three categories of tiles: things we need now,
// things we need soon, and eventually.
-TileManagerBin BinFromTilePriority(const TilePriority& prio) {
+inline TileManagerBin BinFromTilePriority(const TilePriority& prio) {
if (!prio.is_live)
return NEVER_BIN;
@@ -190,20 +190,6 @@ void TileManager::UnregisterTile(Tile* tile) {
DCHECK(false) << "Could not find tile version.";
}
-void TileManager::WillModifyTilePriority(
- Tile* tile, WhichTree tree, const TilePriority& new_priority) {
- // TODO(nduca): Do something smarter if reprioritization turns out to be
- // costly.
- ScheduleManageTiles();
-}
-
-void TileManager::ScheduleManageTiles() {
- if (manage_tiles_pending_)
- return;
- client_->ScheduleManageTiles();
- manage_tiles_pending_ = true;
-}
-
class BinComparator {
public:
bool operator() (const Tile* a, const Tile* b) const {
diff --git a/cc/tile_manager.h b/cc/tile_manager.h
index 46d374e..d537079 100644
--- a/cc/tile_manager.h
+++ b/cc/tile_manager.h
@@ -118,13 +118,22 @@ class CC_EXPORT TileManager {
void RegisterTile(Tile* tile);
void UnregisterTile(Tile* tile);
void WillModifyTilePriority(
- Tile* tile, WhichTree tree, const TilePriority& new_priority);
+ Tile* tile, WhichTree tree, const TilePriority& new_priority) {
+ // TODO(nduca): Do something smarter if reprioritization turns out to be
+ // costly.
+ ScheduleManageTiles();
+ }
private:
void SortTiles();
void AssignGpuMemoryToTiles();
void FreeResourcesForTile(Tile* tile);
- void ScheduleManageTiles();
+ void ScheduleManageTiles() {
+ if (manage_tiles_pending_)
+ return;
+ client_->ScheduleManageTiles();
+ manage_tiles_pending_ = true;
+ }
void DispatchMoreTasks();
void GatherPixelRefsForTile(Tile* tile);
void DispatchImageDecodeTasksForTile(Tile* tile);
diff --git a/cc/tile_priority.cc b/cc/tile_priority.cc
index ec77029..cb5e956 100644
--- a/cc/tile_priority.cc
+++ b/cc/tile_priority.cc
@@ -11,50 +11,49 @@ namespace {
// TODO(qinmin): modify ui/range/Range.h to support template so that we
// don't need to define this.
struct Range {
- Range(double start, double end) : start_(start), end_(end) {}
- Range Intersects(const Range& other);
+ Range(float start, float end) : start_(start), end_(end) {}
bool IsEmpty();
- double start_;
- double end_;
+ float start_;
+ float end_;
};
-Range Range::Intersects(const Range& other) {
- start_ = std::max(start_, other.start_);
- end_ = std::min(end_, other.end_);
- return Range(start_, 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_));
}
bool Range::IsEmpty() {
return start_ >= end_;
}
-// 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 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);
+}
- return Range(minimum_time, maximum_time);
+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);
}
} // namespace
namespace cc {
-const double TilePriority::kMaxTimeToVisibleInSeconds = 1000.0;
-const double TilePriority::kMaxDistanceInContentSpace = 4096.0;
+const float TilePriority::kMaxDistanceInContentSpace = 4096.0f;
scoped_ptr<base::Value> WhichTreeAsValue(WhichTree tree) {
switch (tree) {
@@ -71,25 +70,22 @@ 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);
-}
-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;
+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;
+
+ const float kMaxTimeToVisibleInSeconds =
+ std::numeric_limits<float>::infinity();
- if (previous_bounds.Intersects(target_bounds) || time_delta == 0)
+ if (time_delta == 0.0f)
return kMaxTimeToVisibleInSeconds;
// As we are trying to solve the case of both scaling and scrolling, using
@@ -98,24 +94,19 @@ double TilePriority::TimeForBoundsToIntersect(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.
- 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));
-
+ 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);
return range.IsEmpty() ? kMaxTimeToVisibleInSeconds : range.start_;
}
diff --git a/cc/tile_priority.h b/cc/tile_priority.h
index 7672a38..ae07d5a 100644
--- a/cc/tile_priority.h
+++ b/cc/tile_priority.h
@@ -89,18 +89,30 @@ struct CC_EXPORT TilePriority {
pending.distance_to_visible_in_pixels);
}
- static const double kMaxTimeToVisibleInSeconds;
- static const double kMaxDistanceInContentSpace;
-
- static int manhattanDistance(const gfx::RectF& a, const gfx::RectF& b);
+ static const float kMaxDistanceInContentSpace;
+
+ static inline float manhattanDistance(const gfx::RectF& a, const gfx::RectF& b) {
+ // Compute the union explicitly.
+ gfx::RectF c = gfx::RectF(
+ std::min(a.x(), b.x()),
+ std::min(a.y(), b.y()),
+ std::max(a.right(), b.right()) - std::min(a.x(), b.x()),
+ std::max(a.bottom(), b.bottom()) - std::min(a.y(), b.y()));
+
+ // Rects touching the edge of the screen should not be considered visible.
+ // So we add 1 pixel here to avoid that situation.
+ float x = std::max(0.0f, c.width() - a.width() - b.width() + 1.0f);
+ float y = std::max(0.0f, c.height() - a.height() - b.height() + 1.0f);
+ return (x + y);
+ }
// Calculate the time for the |current_bounds| to intersect with the
// |target_bounds| given its previous location and time delta.
// This function should work for both scaling and scrolling case.
- static double TimeForBoundsToIntersect(gfx::RectF previous_bounds,
- gfx::RectF current_bounds,
- double time_delta,
- gfx::RectF target_bounds);
+ static float TimeForBoundsToIntersect(const gfx::RectF& previous_bounds,
+ const gfx::RectF& current_bounds,
+ float time_delta,
+ const gfx::RectF& target_bounds);
// If a tile is not live, then all other fields are invalid.
bool is_live;
diff --git a/cc/tile_priority_unittest.cc b/cc/tile_priority_unittest.cc
index bcca044..5eea2b4 100644
--- a/cc/tile_priority_unittest.cc
+++ b/cc/tile_priority_unittest.cc
@@ -10,6 +10,7 @@ namespace cc {
namespace {
TEST(TilePriorityTest, TimeForBoundsToIntersectWithScroll) {
+ const float inf = std::numeric_limits<float>::infinity();
gfx::Rect target(0, 0, 800, 600);
gfx::Rect current(100, 100, 100, 100);
EXPECT_EQ(0, TilePriority::TimeForBoundsToIntersect(
@@ -20,15 +21,16 @@ TEST(TilePriorityTest, TimeForBoundsToIntersectWithScroll) {
gfx::Rect(400, 400, 100, 100), current, 1, target));
current = gfx::Rect(-300, -300, 100, 100);
- EXPECT_EQ(1000, TilePriority::TimeForBoundsToIntersect(
+ EXPECT_EQ(inf, TilePriority::TimeForBoundsToIntersect(
gfx::Rect(0, 0, 100, 100), current, 1, target));
- EXPECT_EQ(1000, TilePriority::TimeForBoundsToIntersect(
+ EXPECT_EQ(inf, TilePriority::TimeForBoundsToIntersect(
gfx::Rect(-200, -200, 100, 100), current, 1, target));
EXPECT_EQ(2, TilePriority::TimeForBoundsToIntersect(
gfx::Rect(-400, -400, 100, 100), current, 1, target));
}
TEST(TilePriorityTest, TimeForBoundsToIntersectWithScale) {
+ const float inf = std::numeric_limits<float>::infinity();
gfx::Rect target(0, 0, 800, 600);
gfx::Rect current(100, 100, 100, 100);
EXPECT_EQ(0, TilePriority::TimeForBoundsToIntersect(
@@ -39,7 +41,7 @@ TEST(TilePriorityTest, TimeForBoundsToIntersectWithScale) {
gfx::Rect(400, 400, 400, 400), current, 1, target));
current = gfx::Rect(-300, -300, 100, 100);
- EXPECT_EQ(1000, TilePriority::TimeForBoundsToIntersect(
+ EXPECT_EQ(inf, TilePriority::TimeForBoundsToIntersect(
gfx::Rect(-400, -400, 300, 300), current, 1, target));
EXPECT_EQ(8, TilePriority::TimeForBoundsToIntersect(
gfx::Rect(-275, -275, 50, 50), current, 1, target));
diff --git a/ui/gfx/rect_f.cc b/ui/gfx/rect_f.cc
index d7b1089..0f055e1 100644
--- a/ui/gfx/rect_f.cc
+++ b/ui/gfx/rect_f.cc
@@ -31,18 +31,6 @@ std::string RectF::ToString() const {
size().ToString().c_str());
}
-RectF operator+(const RectF& lhs, const Vector2dF& rhs) {
- RectF result(lhs);
- result += rhs;
- return result;
-}
-
-RectF operator-(const RectF& lhs, const Vector2dF& rhs) {
- RectF result(lhs);
- result -= rhs;
- return result;
-}
-
RectF IntersectRects(const RectF& a, const RectF& b) {
RectF result = a;
result.Intersect(b);
@@ -61,12 +49,6 @@ RectF SubtractRects(const RectF& a, const RectF& b) {
return result;
}
-RectF ScaleRect(const RectF& r, float x_scale, float y_scale) {
- RectF result = r;
- result.Scale(x_scale, y_scale);
- return result;
-}
-
RectF BoundingRect(const PointF& p1, const PointF& p2) {
float rx = std::min(p1.x(), p2.x());
float ry = std::min(p1.y(), p2.y());
diff --git a/ui/gfx/rect_f.h b/ui/gfx/rect_f.h
index 78524a0..62bedf2 100644
--- a/ui/gfx/rect_f.h
+++ b/ui/gfx/rect_f.h
@@ -69,8 +69,15 @@ inline bool operator!=(const RectF& lhs, const RectF& rhs) {
return !(lhs == rhs);
}
-UI_EXPORT RectF operator+(const RectF& lhs, const Vector2dF& rhs);
-UI_EXPORT RectF operator-(const RectF& lhs, const Vector2dF& rhs);
+inline RectF operator+(const RectF& lhs, const Vector2dF& rhs) {
+ return RectF(lhs.x() + rhs.x(), lhs.y() + rhs.y(),
+ lhs.width(), lhs.height());
+}
+
+inline RectF operator-(const RectF& lhs, const Vector2dF& rhs) {
+ return RectF(lhs.x() - rhs.x(), lhs.y() - rhs.y(),
+ lhs.width(), lhs.height());
+}
inline RectF operator+(const Vector2dF& lhs, const RectF& rhs) {
return rhs + lhs;
@@ -79,7 +86,11 @@ inline RectF operator+(const Vector2dF& lhs, const RectF& rhs) {
UI_EXPORT RectF IntersectRects(const RectF& a, const RectF& b);
UI_EXPORT RectF UnionRects(const RectF& a, const RectF& b);
UI_EXPORT RectF SubtractRects(const RectF& a, const RectF& b);
-UI_EXPORT RectF ScaleRect(const RectF& r, float x_scale, float y_scale);
+
+inline RectF ScaleRect(const RectF& r, float x_scale, float y_scale) {
+ return RectF(r.x() * x_scale, r.y() * y_scale,
+ r.width() * x_scale, r.height() * y_scale);
+}
inline RectF ScaleRect(const RectF& r, float scale) {
return ScaleRect(r, scale, scale);