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

Unified Diff: cc/tile_manager.cc

Issue 12316084: cc: Consolidate the analysis_canvas operations (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: added constant instead of -1 Created 7 years, 9 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
Index: cc/tile_manager.cc
diff --git a/cc/tile_manager.cc b/cc/tile_manager.cc
index 054b5e55fbd19b16633e9ccac9cdc3a5fae16ea4..1780849f93196a18e28a01f278f7fabe1152b2b6 100644
--- a/cc/tile_manager.cc
+++ b/cc/tile_manager.cc
@@ -145,7 +145,8 @@ ManagedTileState::ManagedTileState()
raster_state(IDLE_STATE),
resolution(NON_IDEAL_RESOLUTION),
time_to_needed_in_seconds(std::numeric_limits<float>::infinity()),
- distance_to_visible_in_pixels(std::numeric_limits<float>::infinity()) {
+ distance_to_visible_in_pixels(std::numeric_limits<float>::infinity()),
+ picture_pile_analyzed(false) {
for (int i = 0; i < NUM_TREES; ++i) {
tree_bin[i] = NEVER_BIN;
bin[i] = NEVER_BIN;
@@ -170,6 +171,10 @@ scoped_ptr<base::Value> ManagedTileState::AsValue() const {
state->Set("resolution", TileResolutionAsValue(resolution).release());
state->Set("time_to_needed_in_seconds", MathUtil::asValueSafely(time_to_needed_in_seconds).release());
state->Set("distance_to_visible_in_pixels", MathUtil::asValueSafely(distance_to_visible_in_pixels).release());
+ state->SetBoolean("is_picture_pile_analyzed", picture_pile_analyzed);
+ state->SetBoolean("is_cheap_to_raster", picture_pile_analysis.is_cheap_to_raster);
+ state->SetBoolean("is_transparent", picture_pile_analysis.is_transparent);
+ state->SetBoolean("is_solid_color", picture_pile_analysis.is_solid_color);
return state.PassAs<base::Value>();
}
@@ -177,7 +182,9 @@ TileManager::TileManager(
TileManagerClient* client,
ResourceProvider* resource_provider,
size_t num_raster_threads,
- bool use_cheapness_estimator)
+ bool use_cheapness_estimator,
+ bool use_color_estimator,
+ bool prediction_benchmarking)
: client_(client),
resource_pool_(ResourcePool::Create(resource_provider)),
raster_worker_pool_(RasterWorkerPool::Create(this, num_raster_threads)),
@@ -188,8 +195,10 @@ TileManager::TileManager(
ever_exceeded_memory_budget_(false),
record_rendering_stats_(false),
use_cheapness_estimator_(use_cheapness_estimator),
+ use_color_estimator_(use_color_estimator),
allow_cheap_tasks_(true),
- did_schedule_cheap_tasks_(false) {
+ did_schedule_cheap_tasks_(false),
+ prediction_benchmarking_(prediction_benchmarking) {
for (int i = 0; i < NUM_STATES; ++i) {
for (int j = 0; j < NUM_TREES; ++j) {
for (int k = 0; k < NUM_BINS; ++k)
@@ -371,12 +380,13 @@ void TileManager::ManageTiles() {
for (int i = 0; i < NUM_BIN_PRIORITIES; ++i)
mts.bin[i] = bin_map[mts.bin[i]];
- if (tile->priority(ACTIVE_TREE).is_live ||
- tile->priority(PENDING_TREE).is_live ||
- tile->managed_state().resource ||
- tile->managed_state().resource_is_being_initialized) {
- live_or_allocated_tiles_.push_back(tile);
- }
+ if (!tile->managed_state().resource &&
+ !tile->managed_state().resource_is_being_initialized &&
+ !tile->priority(ACTIVE_TREE).is_live &&
+ !tile->priority(PENDING_TREE).is_live)
+ continue;
+
+ live_or_allocated_tiles_.push_back(tile);
}
TRACE_COUNTER_ID1("cc", "LiveOrAllocatedTileCount", this,
live_or_allocated_tiles_.size());
@@ -459,6 +469,9 @@ void TileManager::GetMemoryStats(
for (size_t i = 0; i < live_or_allocated_tiles_.size(); i++) {
const Tile* tile = live_or_allocated_tiles_[i];
const ManagedTileState& mts = tile->managed_state();
+ if (tile->is_transparent() || tile->is_solid_color())
+ continue;
+
size_t tile_bytes = tile->bytes_consumed_if_allocated();
if (mts.gpu_memmgr_stats_bin == NOW_BIN)
*memoryRequiredBytes += tile_bytes;
@@ -579,9 +592,13 @@ void TileManager::AssignGpuMemoryToTiles() {
for (TileVector::iterator it = live_or_allocated_tiles_.begin();
it != live_or_allocated_tiles_.end(); ++it) {
Tile* tile = *it;
- if (!tile->managed_state().can_be_freed)
+ if (tile->is_solid_color() || tile->is_transparent())
+ continue;
+
+ ManagedTileState& managed_tile_state = tile->managed_state();
+ if (!managed_tile_state.can_be_freed)
unreleasable_bytes += tile->bytes_consumed_if_allocated();
- if (tile->managed_state().raster_state == WAITING_FOR_RASTER_STATE)
+ if (managed_tile_state.raster_state == WAITING_FOR_RASTER_STATE)
DidTileRasterStateChange(tile, IDLE_STATE);
}
@@ -590,8 +607,11 @@ void TileManager::AssignGpuMemoryToTiles() {
size_t bytes_left = bytes_allocatable;
for (TileVector::iterator it = live_or_allocated_tiles_.begin(); it != live_or_allocated_tiles_.end(); ++it) {
Tile* tile = *it;
- size_t tile_bytes = tile->bytes_consumed_if_allocated();
+ if (tile->is_solid_color() || tile->is_transparent())
+ continue;
+
ManagedTileState& managed_tile_state = tile->managed_state();
+ size_t tile_bytes = tile->bytes_consumed_if_allocated();
if (!managed_tile_state.can_be_freed)
continue;
if (managed_tile_state.bin[HIGH_PRIORITY_BIN] == NEVER_BIN &&
@@ -661,12 +681,13 @@ void TileManager::DispatchMoreTasks() {
// Because tiles in the image decoding list have higher priorities, we
// need to process those tiles first before we start to handle the tiles
- // in the need_to_be_rasterized queue.
+ // in the need_to_be_rasterized queue. Note that solid/transparent tiles
+ // will not be put into the decoding list.
for(TileList::iterator it = tiles_with_image_decoding_tasks_.begin();
it != tiles_with_image_decoding_tasks_.end(); ) {
+ ManagedTileState& managed_tile_state = (*it)->managed_state();
DispatchImageDecodeTasksForTile(*it);
- ManagedTileState& managed_state = (*it)->managed_state();
- if (managed_state.pending_pixel_refs.empty()) {
+ if (managed_tile_state.pending_pixel_refs.empty()) {
if (!CanDispatchRasterTask(*it))
return;
DispatchOneRasterTask(*it);
@@ -676,13 +697,23 @@ void TileManager::DispatchMoreTasks() {
}
}
- // Process all tiles in the need_to_be_rasterized queue. If a tile has
- // image decoding tasks, put it to the back of the image decoding list.
+ // Process all tiles in the need_to_be_rasterized queue. If a tile is
+ // solid/transparent, then we are done (we don't need to rasterize
+ // the tile). If a tile has image decoding tasks, put it to the back
+ // of the image decoding list.
while (!tiles_that_need_to_be_rasterized_.empty()) {
Tile* tile = tiles_that_need_to_be_rasterized_.back();
+ ManagedTileState& managed_tile_state = tile->managed_state();
+
+ AnalyzeTile(tile);
+ if (tile->is_solid_color() || tile->is_transparent()) {
+ DidTileRasterStateChange(tile, IDLE_STATE);
+ tiles_that_need_to_be_rasterized_.pop_back();
+ continue;
+ }
+
DispatchImageDecodeTasksForTile(tile);
- ManagedTileState& managed_state = tile->managed_state();
- if (!managed_state.pending_pixel_refs.empty()) {
+ if (!managed_tile_state.pending_pixel_refs.empty()) {
tiles_with_image_decoding_tasks_.push_back(tile);
} else {
if (!CanDispatchRasterTask(tile))
@@ -693,18 +724,36 @@ void TileManager::DispatchMoreTasks() {
}
}
+void TileManager::AnalyzeTile(Tile* tile) {
+ ManagedTileState& managed_tile_state = tile->managed_state();
+ if ((use_cheapness_estimator_ || use_color_estimator_) &&
+ !managed_tile_state.picture_pile_analyzed) {
+ tile->picture_pile()->AnalyzeInRect(
+ tile->content_rect(),
+ tile->contents_scale(),
+ &managed_tile_state.picture_pile_analysis);
+ managed_tile_state.picture_pile_analysis.is_cheap_to_raster &=
+ use_cheapness_estimator_;
+ managed_tile_state.picture_pile_analysis.is_solid_color &=
+ use_color_estimator_;
+ managed_tile_state.picture_pile_analysis.is_transparent &=
+ use_color_estimator_;
+ managed_tile_state.picture_pile_analyzed = true;
+ }
+}
+
void TileManager::GatherPixelRefsForTile(Tile* tile) {
TRACE_EVENT0("cc", "TileManager::GatherPixelRefsForTile");
- ManagedTileState& managed_state = tile->managed_state();
- if (managed_state.need_to_gather_pixel_refs) {
+ ManagedTileState& managed_tile_state = tile->managed_state();
+ if (managed_tile_state.need_to_gather_pixel_refs) {
base::TimeTicks gather_begin_time;
if (record_rendering_stats_)
gather_begin_time = base::TimeTicks::HighResNow();
tile->picture_pile()->GatherPixelRefs(
tile->content_rect_,
tile->contents_scale_,
- managed_state.pending_pixel_refs);
- managed_state.need_to_gather_pixel_refs = false;
+ managed_tile_state.pending_pixel_refs);
+ managed_tile_state.need_to_gather_pixel_refs = false;
if (record_rendering_stats_) {
rendering_stats_.totalImageGatheringCount++;
rendering_stats_.totalImageGatheringTime +=
@@ -794,12 +843,12 @@ void TileManager::DispatchOneRasterTask(scoped_refptr<Tile> tile) {
uint8* buffer =
resource_pool_->resource_provider()->mapPixelBuffer(resource_id);
- bool is_cheap = use_cheapness_estimator_ && allow_cheap_tasks_ &&
- tile->picture_pile()->IsCheapInRect(tile->content_rect_,
- tile->contents_scale());
+ ManagedTileState& managed_tile_state = tile->managed_state();
+ bool is_cheap_to_raster =
+ managed_tile_state.picture_pile_analysis.is_cheap_to_raster;
raster_worker_pool_->PostRasterTaskAndReply(
tile->picture_pile(),
- is_cheap,
+ allow_cheap_tasks_ && is_cheap_to_raster,
base::Bind(&TileManager::RunRasterTask,
buffer,
tile->content_rect(),
@@ -810,14 +859,14 @@ void TileManager::DispatchOneRasterTask(scoped_refptr<Tile> tile) {
tile,
base::Passed(&resource),
manage_tiles_call_count_));
- did_schedule_cheap_tasks_ |= is_cheap;
+ did_schedule_cheap_tasks_ |= (allow_cheap_tasks_ && is_cheap_to_raster);
}
TileManager::RasterTaskMetadata TileManager::GetRasterTaskMetadata(
const Tile& tile) const {
RasterTaskMetadata metadata;
const ManagedTileState& mts = tile.managed_state();
- metadata.use_cheapness_estimator = use_cheapness_estimator_;
+ metadata.prediction_benchmarking = prediction_benchmarking_;
metadata.is_tile_in_pending_tree_now_bin =
mts.tree_bin[PENDING_TREE] == NOW_BIN;
metadata.tile_resolution = mts.resolution;
@@ -958,11 +1007,19 @@ void TileManager::RunRasterTask(uint8* buffer,
10,
10);
- if (metadata.use_cheapness_estimator) {
- bool is_predicted_cheap =
- picture_pile->IsCheapInRect(rect, contents_scale);
+ if (metadata.prediction_benchmarking) {
+ PicturePileImpl::Analysis analysis;
+ picture_pile->AnalyzeInRect(rect, contents_scale, &analysis);
+ bool is_predicted_cheap = analysis.is_cheap_to_raster;
bool is_actually_cheap = duration.InMillisecondsF() <= 1.0f;
RecordCheapnessPredictorResults(is_predicted_cheap, is_actually_cheap);
+
+ RecordSolidColorPredictorResults(
+ reinterpret_cast<SkColor*>(bitmap.getPixels()),
reveman 2013/03/07 00:11:28 I assume this is always safe with SkBitmap::kARGB_
+ bitmap.getSize() / bitmap.bytesPerPixel(),
+ analysis.is_solid_color,
+ analysis.solid_color,
+ analysis.is_transparent);
}
}
}
@@ -980,6 +1037,58 @@ void TileManager::RecordCheapnessPredictorResults(bool is_predicted_cheap,
}
// static
+void TileManager::RecordSolidColorPredictorResults(
+ const SkColor* actual_colors,
+ size_t color_count,
+ bool is_predicted_solid,
+ SkColor predicted_color,
+ bool is_predicted_transparent) {
+ DCHECK_GT(color_count, 0);
+
+ bool is_actually_solid = true;
+ bool is_transparent = true;
+
+ SkColor actual_color = *actual_colors;
+ for (int i = 0; i < color_count; ++i) {
+ SkColor current_color = actual_colors[i];
+ if (current_color != actual_color ||
+ SkColorGetA(current_color) != 255)
+ is_actually_solid = false;
+
+ if (SkColorGetA(current_color) != 0)
+ is_transparent = false;
+
+ if(!is_actually_solid && !is_transparent)
+ break;
+ }
+
+ if (is_predicted_solid && !is_actually_solid)
+ UMA_HISTOGRAM_BOOLEAN("Renderer4.ColorPredictor.WrongActualNotSolid", true);
+ else if (is_predicted_solid &&
+ is_actually_solid &&
+ predicted_color != actual_color)
+ UMA_HISTOGRAM_BOOLEAN("Renderer4.ColorPredictor.WrongColor", true);
+ else if (!is_predicted_solid && is_actually_solid)
+ UMA_HISTOGRAM_BOOLEAN("Renderer4.ColorPredictor.WrongActualSolid", true);
+
+ bool correct_guess = (is_predicted_solid && is_actually_solid &&
+ predicted_color == actual_color) ||
+ (!is_predicted_solid && !is_actually_solid);
+ UMA_HISTOGRAM_BOOLEAN("Renderer4.ColorPredictor.Accuracy", correct_guess);
+
+ if (correct_guess)
+ UMA_HISTOGRAM_BOOLEAN("Renderer4.ColorPredictor.IsCorrectSolid",
+ is_predicted_solid);
+
+ if (is_predicted_transparent)
+ UMA_HISTOGRAM_BOOLEAN(
+ "Renderer4.ColorPredictor.PredictedTransparentIsActually",
+ is_transparent);
+ UMA_HISTOGRAM_BOOLEAN("Renderer4.ColorPredictor.IsActuallyTransparent",
+ is_transparent);
+}
+
+// static
void TileManager::RunImageDecodeTask(skia::LazyPixelRef* pixel_ref,
RenderingStats* stats) {
TRACE_EVENT0("cc", "TileManager::RunImageDecodeTask");
« cc/picture.h ('K') | « cc/tile_manager.h ('k') | chrome/chrome_tests_unit.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698