summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cc/layer_tree_host_impl.h2
-rw-r--r--cc/layer_tree_impl.cc4
-rw-r--r--cc/layer_tree_impl.h1
-rw-r--r--cc/layer_tree_settings.cc1
-rw-r--r--cc/layer_tree_settings.h1
-rw-r--r--cc/picture_layer_impl.cc168
-rw-r--r--cc/picture_layer_impl.h7
-rw-r--r--cc/picture_layer_tiling.cc39
-rw-r--r--cc/picture_layer_tiling.h8
-rw-r--r--cc/picture_layer_tiling_set.cc86
-rw-r--r--cc/picture_layer_tiling_set.h20
-rw-r--r--cc/picture_layer_tiling_set_unittest.cc6
-rw-r--r--cc/scoped_ptr_vector.h5
-rw-r--r--cc/tile.h4
14 files changed, 287 insertions, 65 deletions
diff --git a/cc/layer_tree_host_impl.h b/cc/layer_tree_host_impl.h
index 4091d48..d6ba579 100644
--- a/cc/layer_tree_host_impl.h
+++ b/cc/layer_tree_host_impl.h
@@ -304,6 +304,8 @@ public:
skia::RefPtr<SkPicture> capturePicture();
+ bool pinchGestureActive() const { return m_pinchGestureActive; }
+
protected:
LayerTreeHostImpl(const LayerTreeSettings&, LayerTreeHostImplClient*, Proxy*);
void activatePendingTree();
diff --git a/cc/layer_tree_impl.cc b/cc/layer_tree_impl.cc
index 7c2cc4c..805db07 100644
--- a/cc/layer_tree_impl.cc
+++ b/cc/layer_tree_impl.cc
@@ -229,6 +229,10 @@ int LayerTreeImpl::MaxTextureSize() const {
return layer_tree_host_impl_->rendererCapabilities().maxTextureSize;
}
+bool LayerTreeImpl::PinchGestureActive() const {
+ return layer_tree_host_impl_->pinchGestureActive();
+}
+
void LayerTreeImpl::SetNeedsRedraw() {
layer_tree_host_impl_->setNeedsRedraw();
}
diff --git a/cc/layer_tree_impl.h b/cc/layer_tree_impl.h
index 801dde6b..308448b 100644
--- a/cc/layer_tree_impl.h
+++ b/cc/layer_tree_impl.h
@@ -55,6 +55,7 @@ class CC_EXPORT LayerTreeImpl {
LayerImpl* FindActiveTreeLayerById(int id);
LayerImpl* FindPendingTreeLayerById(int id);
int MaxTextureSize() const;
+ bool PinchGestureActive() const;
// Tree specific methods exposed to layer-impl tree.
// ---------------------------------------------------------------------------
diff --git a/cc/layer_tree_settings.cc b/cc/layer_tree_settings.cc
index ece7991..0891f93 100644
--- a/cc/layer_tree_settings.cc
+++ b/cc/layer_tree_settings.cc
@@ -28,6 +28,7 @@ LayerTreeSettings::LayerTreeSettings()
, shouldClearRootRenderPass(true)
, useLinearFadeScrollbarAnimator(false)
, minimumContentsScale(0.0625f)
+ , lowResContentsScaleFactor(0.125f)
, refreshRate(0)
, maxPartialTextureUpdates(std::numeric_limits<size_t>::max())
, numRasterThreads(1)
diff --git a/cc/layer_tree_settings.h b/cc/layer_tree_settings.h
index 84810f7..375cbf6 100644
--- a/cc/layer_tree_settings.h
+++ b/cc/layer_tree_settings.h
@@ -31,6 +31,7 @@ class CC_EXPORT LayerTreeSettings {
bool shouldClearRootRenderPass;
bool useLinearFadeScrollbarAnimator;
float minimumContentsScale;
+ float lowResContentsScaleFactor;
double refreshRate;
size_t maxPartialTextureUpdates;
size_t numRasterThreads;
diff --git a/cc/picture_layer_impl.cc b/cc/picture_layer_impl.cc
index 5a6f111..de06993 100644
--- a/cc/picture_layer_impl.cc
+++ b/cc/picture_layer_impl.cc
@@ -17,6 +17,10 @@
#include "ui/gfx/quad_f.h"
#include "ui/gfx/size_conversions.h"
+namespace {
+const float kMaxScaleRatioDuringPinch = 2.0f;
+}
+
namespace cc {
PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* treeImpl, int id)
@@ -24,6 +28,8 @@ PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* treeImpl, int id)
tilings_(this),
pile_(PicturePileImpl::Create()),
last_update_time_(0),
+ last_content_scale_(0),
+ ideal_contents_scale_(0),
is_mask_(false) {
}
@@ -53,7 +59,8 @@ void PictureLayerImpl::appendQuads(QuadSink& quadSink,
if (showDebugBorders()) {
for (PictureLayerTilingSet::Iterator iter(&tilings_,
contentsScaleX(),
- rect);
+ rect,
+ ideal_contents_scale_);
iter;
++iter) {
SkColor color;
@@ -74,7 +81,14 @@ void PictureLayerImpl::appendQuads(QuadSink& quadSink,
}
}
- for (PictureLayerTilingSet::Iterator iter(&tilings_, contentsScaleX(), rect);
+ // Keep track of the tilings that were used so that tilings that are
+ // unused can be considered for removal.
+ std::vector<PictureLayerTiling*> seen_tilings;
+
+ for (PictureLayerTilingSet::Iterator iter(&tilings_,
+ contentsScaleX(),
+ rect,
+ ideal_contents_scale_);
iter;
++iter) {
ResourceProvider::ResourceId resource = 0;
@@ -122,7 +136,15 @@ void PictureLayerImpl::appendQuads(QuadSink& quadSink,
outside_right_edge && useAA,
outside_bottom_edge && useAA);
quadSink.append(quad.PassAs<DrawQuad>(), appendQuadsData);
+
+ if (!seen_tilings.size() || seen_tilings.back() != iter.CurrentTiling())
+ seen_tilings.push_back(iter.CurrentTiling());
}
+
+ // During a pinch, a user could zoom in and out, so throwing away a tiling may
+ // be premature.
+ if (!layerTreeImpl()->PinchGestureActive())
+ CleanUpUnusedTilings(seen_tilings);
}
void PictureLayerImpl::dumpLayerProperties(std::string*, int indent) const {
@@ -137,16 +159,15 @@ void PictureLayerImpl::didUpdateTransforms() {
double time_delta = 0;
if (last_update_time_ != 0 && last_bounds_ == bounds() &&
last_content_bounds_ == contentBounds() &&
- last_content_scale_x_ == contentsScaleX() &&
- last_content_scale_y_ == contentsScaleY()) {
+ last_content_scale_ == contentsScaleX()) {
time_delta = current_time - last_update_time_;
}
WhichTree tree = layerTreeImpl()->IsActiveTree() ? ACTIVE_TREE : PENDING_TREE;
tilings_.UpdateTilePriorities(
tree,
layerTreeImpl()->device_viewport_size(),
+ last_content_scale_,
contentsScaleX(),
- contentsScaleY(),
last_screen_space_transform_,
current_screen_space_transform,
time_delta);
@@ -155,8 +176,7 @@ void PictureLayerImpl::didUpdateTransforms() {
last_update_time_ = current_time;
last_bounds_ = bounds();
last_content_bounds_ = contentBounds();
- last_content_scale_x_ = contentsScaleX();
- last_content_scale_y_ = contentsScaleY();
+ last_content_scale_ = contentsScaleX();
}
void PictureLayerImpl::calculateContentsScale(
@@ -170,9 +190,9 @@ void PictureLayerImpl::calculateContentsScale(
}
float min_contents_scale = layerTreeImpl()->settings().minimumContentsScale;
- ideal_contents_scale = std::max(ideal_contents_scale, min_contents_scale);
+ ideal_contents_scale_ = std::max(ideal_contents_scale, min_contents_scale);
- ManageTilings(ideal_contents_scale);
+ ManageTilings(ideal_contents_scale_);
// The content scale and bounds for a PictureLayerImpl is somewhat fictitious.
// There are (usually) several tilings at different scales. However, the
@@ -237,13 +257,16 @@ void PictureLayerImpl::SetIsMask(bool is_mask) {
if (is_mask_ == is_mask)
return;
is_mask_ = is_mask;
- tilings_.Reset();
+ tilings_.RemoveAllTiles();
}
ResourceProvider::ResourceId PictureLayerImpl::contentsResourceId() const {
gfx::Rect content_rect(gfx::Point(), contentBounds());
float scale = contentsScaleX();
- for (PictureLayerTilingSet::Iterator iter(&tilings_, scale, content_rect);
+ for (PictureLayerTilingSet::Iterator iter(&tilings_,
+ scale,
+ content_rect,
+ ideal_contents_scale_);
iter;
++iter) {
// Mask resource not ready yet.
@@ -257,25 +280,26 @@ ResourceProvider::ResourceId PictureLayerImpl::contentsResourceId() const {
return 0;
}
-void PictureLayerImpl::AddTiling(float contents_scale, gfx::Size tile_size) {
+PictureLayerTiling* PictureLayerImpl::AddTiling(float contents_scale) {
if (contents_scale < layerTreeImpl()->settings().minimumContentsScale)
- return;
+ return NULL;
- const PictureLayerTiling* tiling = tilings_.AddTiling(
+ PictureLayerTiling* tiling = tilings_.AddTiling(
contents_scale,
- tile_size);
+ TileSize());
// If a new tiling is created on the active tree, sync it to the pending tree
// so that it can share the same tiles.
if (layerTreeImpl()->IsPendingTree())
- return;
+ return tiling;
PictureLayerImpl* pending_twin = static_cast<PictureLayerImpl*>(
layerTreeImpl()->FindPendingTreeLayerById(id()));
if (!pending_twin)
- return;
+ return tiling;
DCHECK_EQ(id(), pending_twin->id());
pending_twin->SyncTiling(tiling);
+ return tiling;
}
gfx::Size PictureLayerImpl::TileSize() const {
@@ -289,18 +313,110 @@ gfx::Size PictureLayerImpl::TileSize() const {
return layerTreeImpl()->settings().defaultTileSize;
}
+namespace {
+
+inline float PositiveRatio(float float1, float float2) {
+ DCHECK(float1 > 0);
+ DCHECK(float2 > 0);
+ return float1 > float2 ? float1 / float2 : float2 / float1;
+}
+
+inline bool IsCloserToThan(
+ PictureLayerTiling* layer1,
+ PictureLayerTiling* layer2,
+ float contents_scale) {
+ // Absolute value for ratios.
+ float ratio1 = PositiveRatio(layer1->contents_scale(), contents_scale);
+ float ratio2 = PositiveRatio(layer2->contents_scale(), contents_scale);
+ return ratio1 < ratio2;
+}
+
+} // namespace
+
void PictureLayerImpl::ManageTilings(float ideal_contents_scale) {
- if (drawsContent()) {
- // TODO(enne): Add tilings during pinch zoom
- // TODO(enne): Consider culling old tilings after pinch finishes.
- if (!tilings_.num_tilings()) {
- AddTiling(ideal_contents_scale, TileSize());
- // TODO(enne): Add a low-res tiling as well.
+ DCHECK(ideal_contents_scale);
+ float low_res_factor = layerTreeImpl()->settings().lowResContentsScaleFactor;
+ float low_res_contents_scale = ideal_contents_scale * low_res_factor;
+
+ // Remove any tilings from the pending tree that don't exactly match the
+ // contents scale. The pending tree should always come in crisp. However,
+ // don't do this during a pinch, to avoid throwing away a tiling that should
+ // have been kept.
+ if (layerTreeImpl()->IsPendingTree() &&
+ !layerTreeImpl()->PinchGestureActive()) {
+ std::vector<PictureLayerTiling*> remove_list;
+ for (size_t i = 0; i < tilings_.num_tilings(); ++i) {
+ PictureLayerTiling* tiling = tilings_.tiling_at(i);
+ if (tiling->contents_scale() == ideal_contents_scale)
+ continue;
+ if (tiling->contents_scale() == low_res_contents_scale)
+ continue;
+ remove_list.push_back(tiling);
}
- } else {
- // TODO(enne): This should be unnecessary once there are two trees.
- tilings_.Reset();
+
+ for (size_t i = 0; i < remove_list.size(); ++i)
+ tilings_.Remove(remove_list[i]);
}
+
+ // Find existing tilings closest to ideal high / low res.
+ PictureLayerTiling* high_res = NULL;
+ PictureLayerTiling* low_res = NULL;
+ for (size_t i = 0; i < tilings_.num_tilings(); ++i) {
+ PictureLayerTiling* tiling = tilings_.tiling_at(i);
+ if (!high_res || IsCloserToThan(tiling, high_res, ideal_contents_scale))
+ high_res = tiling;
+ if (!low_res || IsCloserToThan(tiling, low_res, low_res_contents_scale))
+ low_res = tiling;
+
+ // Reset all tilings to non-ideal until the end of this function.
+ tiling->set_resolution(NON_IDEAL_RESOLUTION);
+ }
+
+ // The active tree always has calcDrawProperties called on it first, and
+ // any tilings added to the active tree will be synced to the pending tree.
+ // Therefore, only add tilings to the active tree.
+ if (layerTreeImpl()->IsActiveTree()) {
+ if (layerTreeImpl()->PinchGestureActive() && high_res) {
+ // If zooming out, if only available high-res tiling is very high
+ // resolution, create additional tilings closer to the ideal.
+ // When zooming in, add some additional tilings so that content
+ // "crisps up" prior to releasing pinch.
+ float ratio = PositiveRatio(
+ high_res->contents_scale(),
+ ideal_contents_scale);
+ if (ratio >= kMaxScaleRatioDuringPinch)
+ high_res = AddTiling(ideal_contents_scale);
+ } else {
+ // When not pinching or if no tilings, add exact contents scales.
+ if (!high_res || high_res->contents_scale() != ideal_contents_scale)
+ high_res = AddTiling(ideal_contents_scale);
+ if (!low_res || low_res->contents_scale() != low_res_contents_scale)
+ low_res = AddTiling(low_res_contents_scale);
+ }
+ }
+
+ if (high_res)
+ high_res->set_resolution(HIGH_RESOLUTION);
+ if (low_res && low_res != high_res)
+ low_res->set_resolution(LOW_RESOLUTION);
+}
+
+void PictureLayerImpl::CleanUpUnusedTilings(
+ std::vector<PictureLayerTiling*> used_tilings) {
+ std::vector<PictureLayerTiling*> to_remove;
+
+ for (size_t i = 0; i < tilings_.num_tilings(); ++i) {
+ PictureLayerTiling* tiling = tilings_.tiling_at(i);
+ // Don't remove the current high or low res tilinig.
+ if (tiling->resolution() != NON_IDEAL_RESOLUTION)
+ continue;
+ if (std::find(used_tilings.begin(), used_tilings.end(), tiling) ==
+ used_tilings.end())
+ to_remove.push_back(tiling);
+ }
+
+ for (size_t i = 0; i < to_remove.size(); ++i)
+ tilings_.Remove(to_remove[i]);
}
} // namespace cc
diff --git a/cc/picture_layer_impl.h b/cc/picture_layer_impl.h
index 94c1ac3..1712b44 100644
--- a/cc/picture_layer_impl.h
+++ b/cc/picture_layer_impl.h
@@ -53,10 +53,11 @@ public:
protected:
PictureLayerImpl(LayerTreeImpl* treeImpl, int id);
- void AddTiling(float contents_scale, gfx::Size tile_size);
+ PictureLayerTiling* AddTiling(float contents_scale);
void SyncFromActiveLayer(const PictureLayerImpl* other);
gfx::Size TileSize() const;
void ManageTilings(float ideal_contents_scale);
+ void CleanUpUnusedTilings(std::vector<PictureLayerTiling*> used_tilings);
PictureLayerTilingSet tilings_;
scoped_refptr<PicturePileImpl> pile_;
@@ -66,8 +67,8 @@ protected:
double last_update_time_;
gfx::Size last_bounds_;
gfx::Size last_content_bounds_;
- float last_content_scale_x_;
- float last_content_scale_y_;
+ float last_content_scale_;
+ float ideal_contents_scale_;
bool is_mask_;
friend class PictureLayer;
diff --git a/cc/picture_layer_tiling.cc b/cc/picture_layer_tiling.cc
index 7ea16fd..43d52c7 100644
--- a/cc/picture_layer_tiling.cc
+++ b/cc/picture_layer_tiling.cc
@@ -24,7 +24,8 @@ PictureLayerTiling::PictureLayerTiling(float contents_scale,
gfx::Size tile_size)
: client_(NULL),
contents_scale_(contents_scale),
- tiling_data_(tile_size, gfx::Size(), true) {
+ tiling_data_(tile_size, gfx::Size(), true),
+ resolution_(NON_IDEAL_RESOLUTION) {
}
PictureLayerTiling::~PictureLayerTiling() {
@@ -60,12 +61,6 @@ void PictureLayerTiling::CreateTile(int i, int j) {
TileMapKey key(i, j);
DCHECK(!tiles_[key]);
tiles_[key] = client_->CreateTile(this, tile_rect);
-
- // TODO(enne): Remove this when we start setting priorities correctly.
- TilePriority priority;
- priority.resolution = HIGH_RESOLUTION;
- priority.time_to_visible_in_seconds = 1000;
- tiles_[key]->set_priority(ACTIVE_TREE, priority);
}
Region PictureLayerTiling::OpaqueRegionInContentRect(
@@ -271,8 +266,8 @@ gfx::Size PictureLayerTiling::Iterator::texture_size() const {
void PictureLayerTiling::UpdateTilePriorities(
WhichTree tree,
const gfx::Size& device_viewport,
- float layer_content_scale_x,
- float layer_content_scale_y,
+ float last_layer_contents_scale,
+ float current_layer_contents_scale,
const gfx::Transform& last_screen_transform,
const gfx::Transform& current_screen_transform,
double time_delta) {
@@ -287,6 +282,7 @@ void PictureLayerTiling::UpdateTilePriorities(
for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
TileMapKey key = it->first;
TilePriority priority;
+ priority.resolution = resolution_;
if (key.first > right || key.second > bottom) {
priority.distance_to_visible_in_pixels = std::numeric_limits<int>::max();
priority.time_to_visible_in_seconds =
@@ -296,22 +292,25 @@ void PictureLayerTiling::UpdateTilePriorities(
}
gfx::Rect tile_bound = tiling_data_.TileBounds(key.first, key.second);
- gfx::RectF layer_content_rect = gfx::ScaleRect(
+ gfx::RectF current_layer_content_rect = gfx::ScaleRect(
+ tile_bound,
+ current_layer_contents_scale / contents_scale_,
+ current_layer_contents_scale / contents_scale_);
+ gfx::RectF current_screen_rect = MathUtil::mapClippedRect(
+ current_screen_transform, current_layer_content_rect);
+ gfx::RectF last_layer_content_rect = gfx::ScaleRect(
tile_bound,
- layer_content_scale_x / contents_scale_,
- layer_content_scale_y / contents_scale_);
- gfx::RectF screen_rect = MathUtil::mapClippedRect(
- current_screen_transform, layer_content_rect);
- gfx::RectF previous_rect = MathUtil::mapClippedRect(
- last_screen_transform, layer_content_rect);
-
- priority.resolution = HIGH_RESOLUTION;
+ last_layer_contents_scale / contents_scale_,
+ last_layer_contents_scale / contents_scale_);
+ gfx::RectF last_screen_rect = MathUtil::mapClippedRect(
+ last_screen_transform, last_layer_content_rect);
+
priority.time_to_visible_in_seconds =
TilePriority::TimeForBoundsToIntersect(
- previous_rect, screen_rect, time_delta, view_rect);
+ last_screen_rect, current_screen_rect, time_delta, view_rect);
priority.distance_to_visible_in_pixels =
- TilePriority::manhattanDistance(screen_rect, view_rect);
+ TilePriority::manhattanDistance(current_screen_rect, view_rect);
it->second->set_priority(tree, priority);
}
}
diff --git a/cc/picture_layer_tiling.h b/cc/picture_layer_tiling.h
index b6c7b7d..38ef4c6 100644
--- a/cc/picture_layer_tiling.h
+++ b/cc/picture_layer_tiling.h
@@ -12,6 +12,7 @@
#include "cc/hash_pair.h"
#include "cc/region.h"
#include "cc/tile.h"
+#include "cc/tile_priority.h"
#include "cc/tiling_data.h"
#include "ui/gfx/rect.h"
@@ -38,6 +39,8 @@ class CC_EXPORT PictureLayerTiling {
void Invalidate(const Region& layer_invalidation);
void SetClient(PictureLayerTilingClient* client);
+ void set_resolution(TileResolution resolution) { resolution_ = resolution; }
+ TileResolution resolution() const { return resolution_; }
gfx::Rect ContentRect() const;
float contents_scale() const { return contents_scale_; }
@@ -89,8 +92,8 @@ class CC_EXPORT PictureLayerTiling {
void UpdateTilePriorities(
WhichTree tree,
const gfx::Size& device_viewport,
- float layer_content_scale_x,
- float layer_content_scale_y,
+ float last_contents_scale,
+ float current_contents_scale,
const gfx::Transform& last_screen_transform,
const gfx::Transform& current_screen_transform,
double time_delta);
@@ -108,6 +111,7 @@ class CC_EXPORT PictureLayerTiling {
gfx::Size layer_bounds_;
TileMap tiles_;
TilingData tiling_data_;
+ TileResolution resolution_;
friend class Iterator;
};
diff --git a/cc/picture_layer_tiling_set.cc b/cc/picture_layer_tiling_set.cc
index e4bbd57..3ee9107 100644
--- a/cc/picture_layer_tiling_set.cc
+++ b/cc/picture_layer_tiling_set.cc
@@ -6,6 +6,18 @@
namespace cc {
+namespace {
+
+class LargestToSmallestScaleFunctor {
+ public:
+ bool operator() (PictureLayerTiling* left, PictureLayerTiling* right) {
+ return left->contents_scale() > right->contents_scale();
+ }
+};
+
+} // namespace
+
+
PictureLayerTilingSet::PictureLayerTilingSet(
PictureLayerTilingClient * client)
: client_(client) {
@@ -37,6 +49,8 @@ void PictureLayerTilingSet::Clone(
tilings_.push_back(tiling->Clone());
tilings_.back()->SetClient(client_);
tilings_.back()->Invalidate(invalidation);
+
+ tilings_.sort(LargestToSmallestScaleFunctor());
}
void PictureLayerTilingSet::SetLayerBounds(gfx::Size layer_bounds) {
@@ -51,27 +65,57 @@ gfx::Size PictureLayerTilingSet::LayerBounds() const {
return layer_bounds_;
}
-const PictureLayerTiling* PictureLayerTilingSet::AddTiling(
+PictureLayerTiling* PictureLayerTilingSet::AddTiling(
float contents_scale,
gfx::Size tile_size) {
tilings_.push_back(PictureLayerTiling::Create(contents_scale, tile_size));
- tilings_.back()->SetClient(client_);
- tilings_.back()->SetLayerBounds(layer_bounds_);
- return tilings_.back();
+ PictureLayerTiling* appended = tilings_.back();
+ appended->SetClient(client_);
+ appended->SetLayerBounds(layer_bounds_);
+
+ tilings_.sort(LargestToSmallestScaleFunctor());
+ return appended;
+}
+
+void PictureLayerTilingSet::RemoveAllTilings() {
+ tilings_.clear();
}
-void PictureLayerTilingSet::Reset() {
+void PictureLayerTilingSet::Remove(PictureLayerTiling* tiling) {
+ ScopedPtrVector<PictureLayerTiling>::iterator iter =
+ std::find(tilings_.begin(), tilings_.end(), tiling);
+ if (iter == tilings_.end())
+ return;
+ tilings_.erase(iter);
+}
+
+void PictureLayerTilingSet::RemoveAllTiles() {
for (size_t i = 0; i < tilings_.size(); ++i)
tilings_[i]->Reset();
}
-PictureLayerTilingSet::Iterator::Iterator(const PictureLayerTilingSet* set,
- float contents_scale,
- gfx::Rect content_rect)
+PictureLayerTilingSet::Iterator::Iterator(
+ const PictureLayerTilingSet* set,
+ float contents_scale,
+ gfx::Rect content_rect,
+ float ideal_contents_scale)
: set_(set),
contents_scale_(contents_scale),
+ ideal_contents_scale_(ideal_contents_scale),
current_tiling_(-1) {
missing_region_.Union(content_rect);
+
+ for (ideal_tiling_ = 0;
+ static_cast<size_t>(ideal_tiling_) < set_->tilings_.size();
+ ++ideal_tiling_) {
+ PictureLayerTiling* tiling = set_->tilings_[ideal_tiling_];
+ if (tiling->contents_scale() < ideal_contents_scale_) {
+ if (ideal_tiling_ > 0)
+ ideal_tiling_--;
+ break;
+ }
+ }
+
++(*this);
}
@@ -111,6 +155,30 @@ Tile* PictureLayerTilingSet::Iterator::operator*() const {
return *tiling_iter_;
}
+PictureLayerTiling* PictureLayerTilingSet::Iterator::CurrentTiling() {
+ if (current_tiling_ < 0)
+ return NULL;
+ if (static_cast<size_t>(current_tiling_) >= set_->tilings_.size())
+ return NULL;
+ return set_->tilings_[current_tiling_];
+}
+
+int PictureLayerTilingSet::Iterator::NextTiling() const {
+ // Order returned by this method is:
+ // 1. Ideal tiling index
+ // 2. Tiling index < Ideal in decreasing order (higher res than ideal)
+ // 3. Tiling index > Ideal in increasing order (lower res than ideal)
+ // 4. Tiling index > tilings.size() (invalid index)
+ if (current_tiling_ < 0)
+ return ideal_tiling_;
+ else if (current_tiling_ > ideal_tiling_)
+ return current_tiling_ + 1;
+ else if (current_tiling_)
+ return current_tiling_ - 1;
+ else
+ return ideal_tiling_ + 1;
+}
+
PictureLayerTilingSet::Iterator& PictureLayerTilingSet::Iterator::operator++() {
bool first_time = current_tiling_ < 0;
@@ -133,7 +201,7 @@ PictureLayerTilingSet::Iterator& PictureLayerTilingSet::Iterator::operator++() {
// tiling and set up to iterate through all of the remaining holes.
// This will also happen the first time through the loop.
if (!region_iter_.has_rect()) {
- current_tiling_++;
+ current_tiling_ = NextTiling();
current_region_.Swap(missing_region_);
missing_region_.Clear();
region_iter_ = Region::Iterator(current_region_);
diff --git a/cc/picture_layer_tiling_set.h b/cc/picture_layer_tiling_set.h
index 383884e..72b583e 100644
--- a/cc/picture_layer_tiling_set.h
+++ b/cc/picture_layer_tiling_set.h
@@ -26,13 +26,20 @@ class CC_EXPORT PictureLayerTilingSet {
void SetLayerBounds(gfx::Size layer_bounds);
gfx::Size LayerBounds() const;
- const PictureLayerTiling* AddTiling(
+ PictureLayerTiling* AddTiling(
float contents_scale,
gfx::Size tile_size);
size_t num_tilings() const { return tilings_.size(); }
PictureLayerTiling* tiling_at(size_t idx) { return tilings_[idx]; }
- void Reset();
+ // Remove all tilings.
+ void RemoveAllTilings();
+
+ // Remove one tiling.
+ void Remove(PictureLayerTiling* tiling);
+
+ // Remove all tiles; keep all tilings.
+ void RemoveAllTiles();
void UpdateTilePriorities(
WhichTree tree,
@@ -53,7 +60,8 @@ class CC_EXPORT PictureLayerTilingSet {
Iterator(
const PictureLayerTilingSet* set,
float contents_scale,
- gfx::Rect rect);
+ gfx::Rect content_rect,
+ float ideal_contents_scale);
~Iterator();
// Visible rect (no borders), always in the space of rect,
@@ -70,11 +78,17 @@ class CC_EXPORT PictureLayerTilingSet {
Iterator& operator++();
operator bool() const;
+ PictureLayerTiling* CurrentTiling();
+
private:
+ int NextTiling() const;
+
const PictureLayerTilingSet* set_;
float contents_scale_;
+ float ideal_contents_scale_;
PictureLayerTiling::Iterator tiling_iter_;
int current_tiling_;
+ int ideal_tiling_;
Region current_region_;
Region missing_region_;
diff --git a/cc/picture_layer_tiling_set_unittest.cc b/cc/picture_layer_tiling_set_unittest.cc
index 33a2f11..cbc9449 100644
--- a/cc/picture_layer_tiling_set_unittest.cc
+++ b/cc/picture_layer_tiling_set_unittest.cc
@@ -29,7 +29,11 @@ TEST(PictureLayerTilingSetTest, NoResources) {
gfx::Rect content_rect(gfx::Point(), content_bounds);
Region remaining(content_rect);
- PictureLayerTilingSet::Iterator iter(&set, contents_scale, content_rect);
+ PictureLayerTilingSet::Iterator iter(
+ &set,
+ contents_scale,
+ content_rect,
+ contents_scale);
for (; iter; ++iter) {
gfx::Rect geometry_rect = iter.geometry_rect();
EXPECT_TRUE(content_rect.Contains(geometry_rect));
diff --git a/cc/scoped_ptr_vector.h b/cc/scoped_ptr_vector.h
index 2923f46..71e3eb6 100644
--- a/cc/scoped_ptr_vector.h
+++ b/cc/scoped_ptr_vector.h
@@ -140,6 +140,11 @@ class ScopedPtrVector {
std::swap(*writable_a, *writable_b);
}
+ template<class Compare>
+ inline void sort(Compare comp) {
+ std::sort(data_.begin(), data_.end(), comp);
+ }
+
iterator begin() { return static_cast<iterator>(data_.begin()); }
const_iterator begin() const { return data_.begin(); }
iterator end() { return static_cast<iterator>(data_.end()); }
diff --git a/cc/tile.h b/cc/tile.h
index 51c61b7b..7d41e6a 100644
--- a/cc/tile.h
+++ b/cc/tile.h
@@ -51,6 +51,9 @@ class CC_EXPORT Tile : public base::RefCounted<Tile> {
bool contents_swizzled() const { return managed_state_.contents_swizzled; }
+ float contents_scale() const { return contents_scale_; }
+ gfx::Rect content_rect() const { return content_rect_; }
+
private:
// Methods called by by tile manager.
friend class TileManager;
@@ -58,7 +61,6 @@ class CC_EXPORT Tile : public base::RefCounted<Tile> {
ManagedTileState& managed_state() { return managed_state_; }
const ManagedTileState& managed_state() const { return managed_state_; }
size_t bytes_consumed_if_allocated() const;
- float contents_scale() const { return contents_scale_; }
// Normal private methods.
friend class base::RefCounted<Tile>;