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

Unified Diff: cc/picture_layer_tiling.cc

Issue 12287027: cc: Compute the inflated rect to cover a fixed number of tiles. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Use sqrt(double) for android 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cc/picture_layer_tiling.h ('k') | cc/picture_layer_tiling_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/picture_layer_tiling.cc
diff --git a/cc/picture_layer_tiling.cc b/cc/picture_layer_tiling.cc
index 95be306169e327fa4b7f8685d86fc3c0fc979e18..398b26e347a621e7a322c01ec2fe17169c8fe546 100644
--- a/cc/picture_layer_tiling.cc
+++ b/cc/picture_layer_tiling.cc
@@ -4,6 +4,8 @@
#include "cc/picture_layer_tiling.h"
+#include <cmath>
+
#include "base/debug/trace_event.h"
#include "cc/math_util.h"
#include "ui/gfx/point_conversions.h"
@@ -391,21 +393,24 @@ void PictureLayerTiling::UpdateTilePriorities(
gfx::Rect viewport_in_content_space =
gfx::ToEnclosingRect(gfx::ScaleRect(viewport_in_layer_space,
contents_scale_));
- gfx::Rect inflated_rect = viewport_in_content_space;
- float adjusted_inset = TilePriority::kMaxDistanceInContentSpace /
- std::max(contents_scale_, 1.f);
- inflated_rect.Inset(
- -adjusted_inset,
- -adjusted_inset,
- -adjusted_inset,
- -adjusted_inset);
- inflated_rect.Intersect(ContentRect());
+
+ static const int64 kMaxTilesForPrioritizedRect = 80;
nduca 2013/02/16 22:30:59 Should we put this by where the old constant lived
danakj 2013/02/18 19:26:20 Right, I feel like asking 3 people would get you 3
+
+ gfx::Size tile_size = tiling_data_.max_texture_size();
+ int64 prioritized_rect_area = kMaxTilesForPrioritizedRect *
+ tile_size.width() * tile_size.height();
+
+ gfx::Rect prioritized_rect = ExpandRectEquallyToAreaBoundedBy(
+ viewport_in_content_space,
+ prioritized_rect_area,
+ ContentRect());
+ DCHECK(ContentRect().Contains(prioritized_rect));
// Iterate through all of the tiles that were live last frame but will
// not be live this frame, and mark them as being dead.
for (TilingData::DifferenceIterator iter(&tiling_data_,
last_prioritized_rect_,
- inflated_rect);
+ prioritized_rect);
iter;
++iter) {
TileMap::iterator find = tiles_.find(iter.index());
@@ -417,7 +422,7 @@ void PictureLayerTiling::UpdateTilePriorities(
Tile* tile = find->second.get();
tile->set_priority(tree, priority);
}
- last_prioritized_rect_ = inflated_rect;
+ last_prioritized_rect_ = prioritized_rect;
gfx::Rect view_rect(device_viewport);
float current_scale = current_layer_contents_scale / contents_scale_;
@@ -434,7 +439,7 @@ void PictureLayerTiling::UpdateTilePriorities(
last_screen_transform.matrix().get(0, 3),
last_screen_transform.matrix().get(1, 3));
- for (TilingData::Iterator iter(&tiling_data_, inflated_rect);
+ for (TilingData::Iterator iter(&tiling_data_, prioritized_rect);
iter; ++iter) {
TileMap::iterator find = tiles_.find(iter.index());
if (find == tiles_.end())
@@ -467,7 +472,7 @@ void PictureLayerTiling::UpdateTilePriorities(
tile->set_priority(tree, priority);
}
} else {
- for (TilingData::Iterator iter(&tiling_data_, inflated_rect);
+ for (TilingData::Iterator iter(&tiling_data_, prioritized_rect);
iter; ++iter) {
TileMap::iterator find = tiles_.find(iter.index());
if (find == tiles_.end())
@@ -539,4 +544,213 @@ scoped_ptr<base::Value> PictureLayerTiling::AsValue() const {
return state.PassAs<base::Value>();
}
+namespace {
+
+int ComputeOffsetToExpand4EdgesEqually(int old_width,
+ int old_height,
+ int64 target_area) {
+ // We need to expand the rect in 4 directions, we can compute the
+ // amount to expand along each axis with a quadratic equation:
+ // (old_w + add) * (old_h + add) = target_area
+ // old_w * old_h + old_w * add + add * old_h + add * add = target_area
+ // add^2 + add * (old_w + old_h) - target_area + old_w * old_h = 0
+ // Therefore, we solve the quadratic equation with:
+ // a = 1
+ // b = old_w + old_h
+ // c = -target_area + old_w * old_h
+ int a = 1;
+ int64 b = old_width + old_height;
+ int64 c = -target_area + old_width * old_height;
+ int sqrt_part = std::sqrt(b * b - 4.0 * a * c);
+ int add_each_axis = (-b + sqrt_part) / 2 / a;
+ return add_each_axis / 2;
+}
+
+int ComputeOffsetToExpand3EdgesEqually(int old_width,
+ int old_height,
+ int64 target_area,
+ bool left_complete,
+ bool top_complete,
+ bool right_complete,
+ bool bottom_complete) {
+ // We need to expand the rect in three directions, so we will have to
+ // expand along one axis twice as much as the other. Otherwise, this
+ // is very similar to the case where we expand in all 4 directions.
+
+ if (left_complete || right_complete) {
+ // Expanding twice as much vertically as horizontally.
+ // (old_w + add) * (old_h + add*2) = target_area
+ // old_w * old_h + old_w * add*2 + add * old_h + add * add*2 = target_area
+ // (add^2)*2 + add * (old_w*2 + old_h) - target_area + old_w * old_h = 0
+ // Therefore, we solve the quadratic equation with:
+ // a = 2
+ // b = old_w*2 + old_h
+ // c = -target_area + old_w * old_h
+ int a = 2;
+ int64 b = old_width * 2 + old_height;
+ int64 c = -target_area + old_width * old_height;
+ int sqrt_part = std::sqrt(b * b - 4.0 * a * c);
+ int add_each_direction = (-b + sqrt_part) / 2 / a;
+ return add_each_direction;
+ } else {
+ // Expanding twice as much horizontally as vertically.
+ // (old_w + add*2) * (old_h + add) = target_area
+ // old_w * old_h + old_w * add + add*2 * old_h + add*2 * add = target_area
+ // (add^2)*2 + add * (old_w + old_h*2) - target_area + old_w * old_h = 0
+ // Therefore, we solve the quadratic equation with:
+ // a = 2
+ // b = old_w + old_h*2
+ // c = -target_area + old_w * old_h
+ int a = 2;
+ int64 b = old_width + old_height * 2;
+ int64 c = -target_area + old_width * old_height;
+ int sqrt_part = std::sqrt(b * b - 4.0 * a * c);
+ int add_each_direction = (-b + sqrt_part) / 2 / a;
+ return add_each_direction;
+ }
+}
+
+int ComputeOffsetToExpand2EdgesEqually(int old_width,
+ int old_height,
+ int64 target_area,
+ bool left_complete,
+ bool top_complete,
+ bool right_complete,
+ bool bottom_complete) {
+ // We need to expand the rect along two directions. If the two directions
+ // are opposite from each other then we only need to compute a distance
+ // along a single axis.
+ if (left_complete && right_complete) {
+ // Expanding along the vertical axis only:
+ // old_w * (old_h + add) = target_area
+ // old_w * old_h + old_w * add = target_area
+ // add_vertically = (target_area - old_w * old_h) / old_w
+ int add_vertically = target_area / old_width - old_height;
+ return add_vertically / 2;
+ } else if (top_complete && bottom_complete) {
+ // Expanding along the horizontal axis only:
+ // (old_w + add) * old_h = target_area
+ // old_w * old_h + add * old_h = target_area
+ // add_horizontally = (target_area - old_w * old_h) / old_h
+ int add_horizontally = target_area / old_height - old_width;
+ return add_horizontally / 2;
+ } else {
+ // If we need to expand along both horizontal and vertical axes, we can use
+ // the same result as if we were expanding all four edges. But we apply the
+ // offset computed for opposing edges to a single edge.
+ int add_each_direction = ComputeOffsetToExpand4EdgesEqually(
+ old_width, old_height, target_area);
+ return add_each_direction * 2;
+ }
+}
+
+int ComputeOffsetToExpand1Edge(int old_width,
+ int old_height,
+ int64 target_area,
+ bool left_complete,
+ bool top_complete,
+ bool right_complete,
+ bool bottom_complete) {
+ // We need to expand the rect in a single direction, so we are either
+ // moving just a verical edge, or just a horizontal edge.
+ if (!top_complete || !bottom_complete) {
+ // Moving a vertical edge:
+ // old_w * (old_h + add) = target_area
+ // old_w * old_h + old_w * add = target_area
+ // add_vertically = (target_area - old_w * old_h) / old_w
+ int add_vertically = target_area / old_width - old_height;
+ return add_vertically;
+ } else {
+ // Moving a horizontal edge:
+ // (old_w + add) * old_h = target_area
+ // old_w * old_h + add * old_h = target_area
+ // add_horizontally = (target_area - old_w * old_h) / old_h
+ int add_horizontally = target_area / old_height - old_width;
+ return add_horizontally;
+ }
+}
+
+} // namespace
+
+// static
+gfx::Rect PictureLayerTiling::ExpandRectEquallyToAreaBoundedBy(
+ gfx::Rect starting_rect,
+ int64 target_area,
+ gfx::Rect bounding_rect) {
+
+ bool left_complete = false;
+ bool top_complete = false;
+ bool right_complete = false;
+ bool bottom_complete = false;
+ int num_edges_complete = 0;
+
+ gfx::Rect working_rect = starting_rect;
+ for (int i = 0; i < 4; ++i) {
+ if (num_edges_complete != i)
+ continue;
+ int offset_for_each_edge = 0;
+ switch (num_edges_complete) {
+ case 0:
+ offset_for_each_edge = ComputeOffsetToExpand4EdgesEqually(
+ working_rect.width(),
+ working_rect.height(),
+ target_area);
+ break;
+ case 1:
+ offset_for_each_edge = ComputeOffsetToExpand3EdgesEqually(
+ working_rect.width(),
+ working_rect.height(),
+ target_area,
+ left_complete,
+ top_complete,
+ right_complete,
+ bottom_complete);
+ break;
+ case 2:
+ offset_for_each_edge = ComputeOffsetToExpand2EdgesEqually(
+ working_rect.width(),
+ working_rect.height(),
+ target_area,
+ left_complete,
+ top_complete,
+ right_complete,
+ bottom_complete);
+ break;
+ case 3:
+ offset_for_each_edge = ComputeOffsetToExpand1Edge(
+ working_rect.width(),
+ working_rect.height(),
+ target_area,
+ left_complete,
+ top_complete,
+ right_complete,
+ bottom_complete);
+ }
+
+ working_rect.Inset((left_complete ? 0 : -offset_for_each_edge),
+ (top_complete ? 0 : -offset_for_each_edge),
+ (right_complete ? 0 : -offset_for_each_edge),
+ (bottom_complete ? 0 : -offset_for_each_edge));
+
+ if (bounding_rect.Contains(working_rect))
+ return working_rect;
+ working_rect.Intersect(bounding_rect);
+
+ if (working_rect.x() == bounding_rect.x()) left_complete = true;
+ if (working_rect.y() == bounding_rect.y()) top_complete = true;
+ if (working_rect.right() == bounding_rect.right()) right_complete = true;
+ if (working_rect.bottom() == bounding_rect.bottom()) bottom_complete = true;
+
+ num_edges_complete = (left_complete ? 1 : 0) +
+ (top_complete ? 1 : 0) +
+ (right_complete ? 1 : 0) +
+ (bottom_complete ? 1 : 0);
+ if (num_edges_complete == 4)
+ return working_rect;
+ }
+
+ NOTREACHED();
+ return starting_rect;
+}
+
} // namespace cc
« no previous file with comments | « cc/picture_layer_tiling.h ('k') | cc/picture_layer_tiling_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698