Chromium Code Reviews| Index: cc/tile_manager.cc |
| diff --git a/cc/tile_manager.cc b/cc/tile_manager.cc |
| index 054b5e55fbd19b16633e9ccac9cdc3a5fae16ea4..e604ed17c2529b47d9aca0daa19cd0b45bf79981 100644 |
| --- a/cc/tile_manager.cc |
| +++ b/cc/tile_manager.cc |
| @@ -177,7 +177,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 +190,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,11 +375,16 @@ 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 || |
| + if (tile->managed_state().resource || |
| tile->managed_state().resource_is_being_initialized) { |
| live_or_allocated_tiles_.push_back(tile); |
| + } else if (tile->priority(ACTIVE_TREE).is_live || |
| + tile->priority(PENDING_TREE).is_live) { |
| + if (use_cheapness_estimator_ || use_color_estimator_) |
| + tile->picture_pile()->AnalyzeInRect(tile->content_rect(), |
|
reveman
2013/02/28 21:23:10
I'm worried that this is too expensive to do for e
reveman
2013/02/28 21:54:28
I changed my mind after talking about this. If it'
|
| + tile->contents_scale(), |
| + &mts.picture_pile_analysis); |
| + live_or_allocated_tiles_.push_back(tile); |
| } |
| } |
| TRACE_COUNTER_ID1("cc", "LiveOrAllocatedTileCount", this, |
| @@ -579,9 +588,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_state = tile->managed_state(); |
| + if (!managed_state.can_be_freed) |
| unreleasable_bytes += tile->bytes_consumed_if_allocated(); |
| - if (tile->managed_state().raster_state == WAITING_FOR_RASTER_STATE) |
| + if (managed_state.raster_state == WAITING_FOR_RASTER_STATE) |
| DidTileRasterStateChange(tile, IDLE_STATE); |
| } |
| @@ -590,28 +603,31 @@ 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; |
| + if (tile->is_solid_color() || tile->is_transparent()) |
| + continue; |
| + |
| + ManagedTileState& managed_state = tile->managed_state(); |
| size_t tile_bytes = tile->bytes_consumed_if_allocated(); |
| - ManagedTileState& managed_tile_state = tile->managed_state(); |
| - if (!managed_tile_state.can_be_freed) |
| + if (!managed_state.can_be_freed) |
| continue; |
| - if (managed_tile_state.bin[HIGH_PRIORITY_BIN] == NEVER_BIN && |
| - managed_tile_state.bin[LOW_PRIORITY_BIN] == NEVER_BIN) { |
| - managed_tile_state.can_use_gpu_memory = false; |
| + if (managed_state.bin[HIGH_PRIORITY_BIN] == NEVER_BIN && |
| + managed_state.bin[LOW_PRIORITY_BIN] == NEVER_BIN) { |
| + managed_state.can_use_gpu_memory = false; |
| FreeResourcesForTile(tile); |
| continue; |
| } |
| if (tile_bytes > bytes_left) { |
| - managed_tile_state.can_use_gpu_memory = false; |
| - if (managed_tile_state.bin[HIGH_PRIORITY_BIN] == NOW_BIN || |
| - managed_tile_state.bin[LOW_PRIORITY_BIN] == NOW_BIN) |
| + managed_state.can_use_gpu_memory = false; |
| + if (managed_state.bin[HIGH_PRIORITY_BIN] == NOW_BIN || |
| + managed_state.bin[LOW_PRIORITY_BIN] == NOW_BIN) |
| bytes_that_exceeded_memory_budget_in_now_bin += tile_bytes; |
| FreeResourcesForTile(tile); |
| continue; |
| } |
| bytes_left -= tile_bytes; |
| - managed_tile_state.can_use_gpu_memory = true; |
| - if (!managed_tile_state.resource && |
| - !managed_tile_state.resource_is_being_initialized) { |
| + managed_state.can_use_gpu_memory = true; |
| + if (!managed_state.resource && |
| + !managed_state.resource_is_being_initialized) { |
| tiles_that_need_to_be_rasterized_.push_back(tile); |
| DidTileRasterStateChange(tile, WAITING_FOR_RASTER_STATE); |
| } |
| @@ -794,12 +810,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_state = tile->managed_state(); |
| + bool is_cheap_to_raster = |
| + managed_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 +826,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; |
| @@ -942,7 +958,6 @@ void TileManager::RunRasterTask(uint8* buffer, |
| int64 total_pixels_rasterized = 0; |
| picture_pile->Raster(&canvas, rect, contents_scale, |
| &total_pixels_rasterized); |
| - |
| if (stats) { |
| stats->totalPixelsRasterized += total_pixels_rasterized; |
| @@ -958,11 +973,25 @@ 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); |
| + |
| + SkColor solid_color; |
| + bool is_predicted_solid = analysis.is_solid_color(); |
| + if (is_predicted_solid) |
| + solid_color = analysis.get_solid_color(); |
| + bool is_predicted_transparent = analysis.is_transparent(); |
| + |
| + RecordSolidColorPredictorResults( |
| + reinterpret_cast<SkColor*>(bitmap.getPixels()), |
| + bitmap.getSize() / bitmap.bytesPerPixel(), |
| + is_predicted_solid, |
| + solid_color, |
| + is_predicted_transparent); |
| } |
| } |
| } |
| @@ -980,6 +1009,55 @@ 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_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"); |