Commit 0a779dde authored by vmpstr@chromium.org's avatar vmpstr@chromium.org

cc: Start using raster/eviction iterators in tile manager

This patch is a part of the series that enables raster
and eviction iterators in cc. In particular, this patch
actually starts using the iterators that have landed
previously. There should be a perf improvement for the
manage tiles case. Other than that, there should be no perf
impact.

This patch's main contribution is that it opens the door for
more optimizations to be done in the future. As well, it
simplifies the logic we have in tile manager.

BUG=329686
R=enne, reveman

Review URL: https://codereview.chromium.org/246673005

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@278654 0039d316-1c4b-4281-b951-d872f2087c98
parent 9d95f04c
......@@ -344,8 +344,6 @@ component("cc") {
"resources/prioritized_resource.h",
"resources/prioritized_resource_manager.cc",
"resources/prioritized_resource_manager.h",
"resources/prioritized_tile_set.cc",
"resources/prioritized_tile_set.h",
"resources/priority_calculator.cc",
"resources/priority_calculator.h",
"resources/raster_mode.cc",
......@@ -712,7 +710,6 @@ test("cc_unittests") {
"resources/picture_pile_unittest.cc",
"resources/picture_unittest.cc",
"resources/prioritized_resource_unittest.cc",
"resources/prioritized_tile_set_unittest.cc",
"resources/raster_worker_pool_unittest.cc",
"resources/resource_provider_unittest.cc",
"resources/resource_update_controller_unittest.cc",
......
......@@ -371,8 +371,6 @@
'resources/prioritized_resource.h',
'resources/prioritized_resource_manager.cc',
'resources/prioritized_resource_manager.h',
'resources/prioritized_tile_set.cc',
'resources/prioritized_tile_set.h',
'resources/priority_calculator.cc',
'resources/priority_calculator.h',
'resources/raster_mode.cc',
......
......@@ -75,7 +75,6 @@
'resources/picture_pile_unittest.cc',
'resources/picture_unittest.cc',
'resources/prioritized_resource_unittest.cc',
'resources/prioritized_tile_set_unittest.cc',
'resources/raster_worker_pool_unittest.cc',
'resources/resource_provider_unittest.cc',
'resources/resource_update_controller_unittest.cc',
......
......@@ -456,7 +456,7 @@ SkRect HeadsUpDisplayLayerImpl::DrawMemoryDisplay(SkCanvas* canvas,
int right,
int top,
int width) const {
if (!memory_entry_.bytes_total())
if (!memory_entry_.total_bytes_used)
return SkRect::MakeEmpty();
const int kPadding = 4;
......@@ -466,7 +466,7 @@ SkRect HeadsUpDisplayLayerImpl::DrawMemoryDisplay(SkCanvas* canvas,
const int left = bounds().width() - width - right;
const SkRect area = SkRect::MakeXYWH(left, top, width, height);
const double megabyte = 1024.0 * 1024.0;
const double kMegabyte = 1024.0 * 1024.0;
SkPaint paint = CreatePaint();
DrawGraphBackground(canvas, &paint, area);
......@@ -485,20 +485,14 @@ SkRect HeadsUpDisplayLayerImpl::DrawMemoryDisplay(SkCanvas* canvas,
kFontHeight,
title_pos);
std::string text =
base::StringPrintf("%6.1f MB used",
(memory_entry_.bytes_unreleasable +
memory_entry_.bytes_allocated) / megabyte);
std::string text = base::StringPrintf(
"%6.1f MB used", memory_entry_.total_bytes_used / kMegabyte);
DrawText(canvas, &paint, text, SkPaint::kRight_Align, kFontHeight, stat1_pos);
if (memory_entry_.bytes_over) {
if (!memory_entry_.had_enough_memory)
paint.setColor(SK_ColorRED);
text = base::StringPrintf("%6.1f MB over",
memory_entry_.bytes_over / megabyte);
} else {
text = base::StringPrintf("%6.1f MB max ",
memory_entry_.total_budget_in_bytes / megabyte);
}
text = base::StringPrintf("%6.1f MB max ",
memory_entry_.total_budget_in_bytes / kMegabyte);
DrawText(canvas, &paint, text, SkPaint::kRight_Align, kFontHeight, stat2_pos);
return area;
......
......@@ -24,7 +24,7 @@ void MemoryHistory::GetMinAndMax(size_t* min, size_t* max) const {
*max = 0;
for (RingBufferType::Iterator it = ring_buffer_.Begin(); it; ++it) {
size_t bytes_total = it->bytes_total();
size_t bytes_total = it->total_bytes_used;
if (bytes_total < *min)
*min = bytes_total;
......
......@@ -22,17 +22,12 @@ class MemoryHistory {
struct Entry {
Entry()
: total_budget_in_bytes(0),
bytes_allocated(0),
bytes_unreleasable(0),
bytes_over(0) {}
total_bytes_used(0),
had_enough_memory(false) {}
size_t total_budget_in_bytes;
size_t bytes_allocated;
size_t bytes_unreleasable;
size_t bytes_over;
size_t bytes_total() const {
return bytes_allocated + bytes_unreleasable + bytes_over;
}
size_t total_bytes_used;
bool had_enough_memory;
};
void SaveEntry(const Entry& entry);
......
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "cc/resources/prioritized_tile_set.h"
#include <algorithm>
#include "cc/resources/managed_tile_state.h"
#include "cc/resources/tile.h"
namespace cc {
class BinComparator {
public:
bool operator()(const Tile* a,
const Tile* b) const {
const ManagedTileState& ams = a->managed_state();
const ManagedTileState& bms = b->managed_state();
if (ams.priority_bin != bms.priority_bin)
return ams.priority_bin < bms.priority_bin;
if (ams.required_for_activation != bms.required_for_activation)
return ams.required_for_activation;
if (ams.resolution != bms.resolution)
return ams.resolution < bms.resolution;
if (ams.distance_to_visible != bms.distance_to_visible)
return ams.distance_to_visible < bms.distance_to_visible;
gfx::Rect a_rect = a->content_rect();
gfx::Rect b_rect = b->content_rect();
if (a_rect.y() != b_rect.y())
return a_rect.y() < b_rect.y();
return a_rect.x() < b_rect.x();
}
};
namespace {
typedef std::vector<Tile*> TileVector;
void SortBinTiles(ManagedTileBin bin, TileVector* tiles) {
switch (bin) {
case NOW_AND_READY_TO_DRAW_BIN:
case NEVER_BIN:
break;
case NOW_BIN:
case SOON_BIN:
case EVENTUALLY_AND_ACTIVE_BIN:
case EVENTUALLY_BIN:
case AT_LAST_AND_ACTIVE_BIN:
case AT_LAST_BIN:
std::sort(tiles->begin(), tiles->end(), BinComparator());
break;
default:
NOTREACHED();
}
}
} // namespace
PrioritizedTileSet::PrioritizedTileSet() {
for (int bin = 0; bin < NUM_BINS; ++bin)
bin_sorted_[bin] = true;
}
PrioritizedTileSet::~PrioritizedTileSet() {}
void PrioritizedTileSet::InsertTile(Tile* tile, ManagedTileBin bin) {
tiles_[bin].push_back(tile);
bin_sorted_[bin] = false;
}
void PrioritizedTileSet::Clear() {
for (int bin = 0; bin < NUM_BINS; ++bin) {
tiles_[bin].clear();
bin_sorted_[bin] = true;
}
}
void PrioritizedTileSet::SortBinIfNeeded(ManagedTileBin bin) {
if (!bin_sorted_[bin]) {
SortBinTiles(bin, &tiles_[bin]);
bin_sorted_[bin] = true;
}
}
PrioritizedTileSet::Iterator::Iterator(
PrioritizedTileSet* tile_set, bool use_priority_ordering)
: tile_set_(tile_set),
current_bin_(NOW_AND_READY_TO_DRAW_BIN),
use_priority_ordering_(use_priority_ordering) {
if (use_priority_ordering_)
tile_set_->SortBinIfNeeded(current_bin_);
iterator_ = tile_set->tiles_[current_bin_].begin();
if (iterator_ == tile_set_->tiles_[current_bin_].end())
AdvanceList();
}
PrioritizedTileSet::Iterator::~Iterator() {}
void PrioritizedTileSet::Iterator::DisablePriorityOrdering() {
use_priority_ordering_ = false;
}
PrioritizedTileSet::Iterator&
PrioritizedTileSet::Iterator::operator++() {
// We can't increment past the end of the tiles.
DCHECK(iterator_ != tile_set_->tiles_[current_bin_].end());
++iterator_;
if (iterator_ == tile_set_->tiles_[current_bin_].end())
AdvanceList();
return *this;
}
Tile* PrioritizedTileSet::Iterator::operator*() {
DCHECK(iterator_ != tile_set_->tiles_[current_bin_].end());
return *iterator_;
}
void PrioritizedTileSet::Iterator::AdvanceList() {
DCHECK(iterator_ == tile_set_->tiles_[current_bin_].end());
while (current_bin_ != NEVER_BIN) {
current_bin_ = static_cast<ManagedTileBin>(current_bin_ + 1);
if (use_priority_ordering_)
tile_set_->SortBinIfNeeded(current_bin_);
iterator_ = tile_set_->tiles_[current_bin_].begin();
if (iterator_ != tile_set_->tiles_[current_bin_].end())
break;
}
}
} // namespace cc
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CC_RESOURCES_PRIORITIZED_TILE_SET_H_
#define CC_RESOURCES_PRIORITIZED_TILE_SET_H_
#include <vector>
#include "cc/base/cc_export.h"
#include "cc/resources/managed_tile_state.h"
namespace cc {
class Tile;
class CC_EXPORT PrioritizedTileSet {
public:
PrioritizedTileSet();
~PrioritizedTileSet();
void InsertTile(Tile* tile, ManagedTileBin bin);
void Clear();
class CC_EXPORT Iterator {
public:
Iterator(PrioritizedTileSet* set, bool use_priority_ordering);
~Iterator();
void DisablePriorityOrdering();
Iterator& operator++();
Tile* operator->() { return *(*this); }
Tile* operator*();
operator bool() const {
return iterator_ != tile_set_->tiles_[current_bin_].end();
}
private:
void AdvanceList();
PrioritizedTileSet* tile_set_;
ManagedTileBin current_bin_;
std::vector<Tile*>::iterator iterator_;
bool use_priority_ordering_;
};
private:
friend class Iterator;
void SortBinIfNeeded(ManagedTileBin bin);
std::vector<Tile*> tiles_[NUM_BINS];
bool bin_sorted_[NUM_BINS];
};
} // namespace cc
#endif // CC_RESOURCES_PRIORITIZED_TILE_SET_H_
This diff is collapsed.
......@@ -25,7 +25,6 @@ Tile::Tile(TileManager* tile_manager,
int source_frame_number,
int flags)
: RefCountedManaged<Tile>(tile_manager),
tile_manager_(tile_manager),
tile_size_(tile_size),
content_rect_(content_rect),
contents_scale_(contents_scale),
......@@ -44,19 +43,11 @@ Tile::~Tile() {
}
void Tile::SetPriority(WhichTree tree, const TilePriority& priority) {
if (priority == priority_[tree])
return;
priority_[tree] = priority;
tile_manager_->DidChangeTilePriority(this);
}
void Tile::MarkRequiredForActivation() {
if (priority_[PENDING_TREE].required_for_activation)
return;
priority_[PENDING_TREE].required_for_activation = true;
tile_manager_->DidChangeTilePriority(this);
}
scoped_ptr<base::Value> Tile::AsValue() const {
......
......@@ -151,7 +151,6 @@ class CC_EXPORT Tile : public RefCountedManaged<Tile> {
const ManagedTileState& managed_state() const { return managed_state_; }
RasterMode DetermineRasterModeForResolution(TileResolution resolution) const;
TileManager* tile_manager_;
scoped_refptr<PicturePileImpl> picture_pile_;
gfx::Rect tile_size_;
gfx::Rect content_rect_;
......
This diff is collapsed.
......@@ -21,7 +21,6 @@
#include "cc/resources/managed_tile_state.h"
#include "cc/resources/memory_history.h"
#include "cc/resources/picture_pile_impl.h"
#include "cc/resources/prioritized_tile_set.h"
#include "cc/resources/rasterizer.h"
#include "cc/resources/resource_pool.h"
#include "cc/resources/tile.h"
......@@ -199,10 +198,8 @@ class CC_EXPORT TileManager : public RasterizerClient,
ManagedTileState::TileVersion& tile_version =
mts.tile_versions[HIGH_QUALITY_RASTER_MODE];
tile_version.resource_ = resource_pool_->AcquireResource(gfx::Size(1, 1));
bytes_releasable_ += BytesConsumedIfAllocated(tiles[i]);
++resources_releasable_;
tile_version.resource_ =
resource_pool_->AcquireResource(tiles[i]->size());
}
}
......@@ -217,12 +214,7 @@ class CC_EXPORT TileManager : public RasterizerClient,
void SetGlobalStateForTesting(
const GlobalStateThatImpactsTilePriority& state) {
// Soft limit is used for resource pool such that
// memory returns to soft limit after going over.
if (state != global_state_) {
global_state_ = state;
prioritized_tiles_dirty_ = true;
}
global_state_ = state;
}
void SetRasterizerForTesting(Rasterizer* rasterizer);
......@@ -236,13 +228,10 @@ class CC_EXPORT TileManager : public RasterizerClient,
Rasterizer* rasterizer,
RenderingStatsInstrumentation* rendering_stats_instrumentation);
// Methods called by Tile
friend class Tile;
void DidChangeTilePriority(Tile* tile);
void CleanUpReleasedTiles();
// Overriden from RefCountedManager<Tile>:
friend class Tile;
virtual void Release(Tile* tile) OVERRIDE;
// Overriden from RasterizerClient:
......@@ -257,11 +246,30 @@ class CC_EXPORT TileManager : public RasterizerClient,
virtual void ScheduleTasks(
const TileVector& tiles_that_need_to_be_rasterized);
void AssignGpuMemoryToTiles(PrioritizedTileSet* tiles,
TileVector* tiles_that_need_to_be_rasterized);
void GetTilesWithAssignedBins(PrioritizedTileSet* tiles);
void AssignGpuMemoryToTiles(TileVector* tiles_that_need_to_be_rasterized);
private:
class MemoryUsage {
public:
MemoryUsage();
MemoryUsage(int64 memory_bytes, int resource_count);
static MemoryUsage FromConfig(const gfx::Size& size, ResourceFormat format);
static MemoryUsage FromTile(const Tile* tile);
MemoryUsage& operator+=(const MemoryUsage& other);
MemoryUsage& operator-=(const MemoryUsage& other);
MemoryUsage operator-(const MemoryUsage& other);
bool Exceeds(const MemoryUsage& limit) const;
int64 memory_bytes() const { return memory_bytes_; }
private:
int64 memory_bytes_;
int resource_count_;
};
void OnImageDecodeTaskCompleted(int layer_id,
SkPixelRef* pixel_ref,
bool was_canceled);
......@@ -271,11 +279,6 @@ class CC_EXPORT TileManager : public RasterizerClient,
const PicturePileImpl::Analysis& analysis,
bool was_canceled);
inline size_t BytesConsumedIfAllocated(const Tile* tile) const {
return Resource::MemorySizeBytes(tile->size(),
resource_pool_->resource_format());
}
void FreeResourceForTile(Tile* tile, RasterMode mode);
void FreeResourcesForTile(Tile* tile);
void FreeUnusedResourcesForTile(Tile* tile);
......@@ -283,8 +286,16 @@ class CC_EXPORT TileManager : public RasterizerClient,
scoped_refptr<ImageDecodeTask> CreateImageDecodeTask(Tile* tile,
SkPixelRef* pixel_ref);
scoped_refptr<RasterTask> CreateRasterTask(Tile* tile);
void UpdatePrioritizedTileSetIfNeeded();
bool FreeTileResourcesUntilUsageIsWithinLimit(EvictionTileIterator* iterator,
const MemoryUsage& limit,
MemoryUsage* usage);
bool FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit(
EvictionTileIterator* iterator,
const MemoryUsage& limit,
const TilePriority& other_priority,
MemoryUsage* usage);
bool TilePriorityViolatesMemoryPolicy(const TilePriority& priority);
bool IsReadyToActivate() const;
void CheckIfReadyToActivate();
......@@ -297,16 +308,8 @@ class CC_EXPORT TileManager : public RasterizerClient,
typedef base::hash_map<Tile::Id, Tile*> TileMap;
TileMap tiles_;
PrioritizedTileSet prioritized_tiles_;
bool prioritized_tiles_dirty_;
bool all_tiles_that_need_to_be_rasterized_have_memory_;
bool all_tiles_required_for_activation_have_memory_;
size_t bytes_releasable_;
size_t resources_releasable_;
bool all_tiles_that_need_to_be_rasterized_are_scheduled_;
bool ever_exceeded_memory_budget_;
MemoryHistory::Entry memory_stats_from_last_assign_;
RenderingStatsInstrumentation* rendering_stats_instrumentation_;
......
This diff is collapsed.
......@@ -122,11 +122,6 @@ enum TileMemoryLimitPolicy {
// You're the only thing in town. Go crazy.
ALLOW_ANYTHING = 3, // Venti.
NUM_TILE_MEMORY_LIMIT_POLICIES = 4,
// NOTE: Be sure to update TreePriorityAsValue and kBinPolicyMap when adding
// or reordering fields.
};
scoped_ptr<base::Value> TileMemoryLimitPolicyAsValue(
TileMemoryLimitPolicy policy);
......@@ -135,8 +130,6 @@ enum TreePriority {
SAME_PRIORITY_FOR_BOTH_TREES,
SMOOTHNESS_TAKES_PRIORITY,
NEW_CONTENT_TAKES_PRIORITY
// Be sure to update TreePriorityAsValue when adding new fields.
};
scoped_ptr<base::Value> TreePriorityAsValue(TreePriority prio);
......@@ -157,17 +150,6 @@ class GlobalStateThatImpactsTilePriority {
TreePriority tree_priority;
bool operator==(const GlobalStateThatImpactsTilePriority& other) const {
return memory_limit_policy == other.memory_limit_policy &&
soft_memory_limit_in_bytes == other.soft_memory_limit_in_bytes &&
hard_memory_limit_in_bytes == other.hard_memory_limit_in_bytes &&
num_resources_limit == other.num_resources_limit &&
tree_priority == other.tree_priority;
}
bool operator!=(const GlobalStateThatImpactsTilePriority& other) const {
return !(*this == other);
}
scoped_ptr<base::Value> AsValue() const;
};
......
......@@ -81,11 +81,9 @@ FakeTileManager::~FakeTileManager() {}
void FakeTileManager::AssignMemoryToTiles(
const GlobalStateThatImpactsTilePriority& state) {
tiles_for_raster.clear();
all_tiles.Clear();
SetGlobalStateForTesting(state);
GetTilesWithAssignedBins(&all_tiles);
AssignGpuMemoryToTiles(&all_tiles, &tiles_for_raster);
AssignGpuMemoryToTiles(&tiles_for_raster);
}
bool FakeTileManager::HasBeenAssignedMemory(Tile* tile) {
......
......@@ -27,7 +27,6 @@ class FakeTileManager : public TileManager {
virtual void Release(Tile* tile) OVERRIDE;
std::vector<Tile*> tiles_for_raster;
PrioritizedTileSet all_tiles;
};
} // namespace cc
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment