diff options
-rw-r--r-- | cc/picture_layer_tiling.cc | 13 | ||||
-rw-r--r-- | cc/tile.cc | 19 | ||||
-rw-r--r-- | cc/tile.h | 21 | ||||
-rw-r--r-- | cc/tile_manager.cc | 16 | ||||
-rw-r--r-- | cc/tile_manager.h | 13 | ||||
-rw-r--r-- | cc/tile_priority.cc | 117 | ||||
-rw-r--r-- | cc/tile_priority.h | 28 | ||||
-rw-r--r-- | cc/tile_priority_unittest.cc | 8 | ||||
-rw-r--r-- | ui/gfx/rect_f.cc | 18 | ||||
-rw-r--r-- | ui/gfx/rect_f.h | 17 |
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_, @@ -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 @@ -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); |