Chromium Code Reviews| Index: cc/tile_manager.cc |
| diff --git a/cc/tile_manager.cc b/cc/tile_manager.cc |
| index 42b7ea331dd724eccc5b267888f4c93df9a66bcd..369b38249d92ad8694728f7d93bc4c7a38d1b24a 100644 |
| --- a/cc/tile_manager.cc |
| +++ b/cc/tile_manager.cc |
| @@ -5,143 +5,45 @@ |
| #include "cc/tile_manager.h" |
| #include <algorithm> |
| -#include <set> |
| #include "base/bind.h" |
| -#include "base/command_line.h" |
| #include "base/debug/trace_event.h" |
| #include "base/logging.h" |
| -#include "base/stringprintf.h" |
| -#include "base/threading/thread.h" |
| #include "cc/platform_color.h" |
| -#include "cc/rendering_stats.h" |
| +#include "cc/raster_worker.h" |
| #include "cc/resource_pool.h" |
| -#include "cc/switches.h" |
| #include "cc/tile.h" |
| -#include "third_party/skia/include/core/SkDevice.h" |
| -namespace { |
| - |
| -const char* kRasterThreadNamePrefix = "CompositorRaster"; |
| - |
| -const int kMaxRasterThreads = 64; |
| -const int kDefaultNumberOfRasterThreads = 1; |
| +namespace cc { |
| -// Allow two pending raster tasks per thread. This keeps resource usage |
| -// low while making sure raster threads aren't unnecessarily idle. |
| -const int kNumPendingRasterTasksPerThread = 2; |
| +namespace { |
| // Determine bin based on three categories of tiles: things we need now, |
| // things we need soon, and eventually. |
| -cc::TileManagerBin BinFromTilePriority(const cc::TilePriority& prio) { |
| +TileManagerBin BinFromTilePriority(const TilePriority& prio) { |
| // The amount of time for which we want to have prepainting coverage. |
| const double prepainting_window_time_seconds = 1.0; |
| const double backfling_guard_distance_pixels = 314.0; |
| if (prio.time_to_needed_in_seconds() == std::numeric_limits<float>::max()) |
| - return cc::NEVER_BIN; |
| + return NEVER_BIN; |
| - if (prio.resolution == cc::NON_IDEAL_RESOLUTION) |
| - return cc::EVENTUALLY_BIN; |
| + if (prio.resolution == NON_IDEAL_RESOLUTION) |
| + return EVENTUALLY_BIN; |
| if (prio.time_to_needed_in_seconds() == 0 || |
| prio.distance_to_visible_in_pixels < backfling_guard_distance_pixels) |
| - return cc::NOW_BIN; |
| + return NOW_BIN; |
| if (prio.time_to_needed_in_seconds() < prepainting_window_time_seconds) |
| - return cc::SOON_BIN; |
| + return SOON_BIN; |
| - return cc::EVENTUALLY_BIN; |
| + return EVENTUALLY_BIN; |
| } |
| } // namespace |
| -namespace cc { |
| - |
| -class RasterThread : public base::Thread { |
| - public: |
| - RasterThread(const std::string name) |
| - : base::Thread(name.c_str()), |
| - num_pending_tasks_(0) { |
| - Start(); |
| - } |
| - virtual ~RasterThread() { |
| - Stop(); |
| - } |
| - |
| - int num_pending_tasks() { return num_pending_tasks_; } |
| - |
| - void PostRasterTaskAndReply(const tracked_objects::Location& from_here, |
| - PicturePileImpl* picture_pile, |
| - uint8_t* mapped_buffer, |
| - const gfx::Rect& rect, |
| - float contents_scale, |
| - RenderingStats* stats, |
| - const base::Closure& reply) { |
| - ++num_pending_tasks_; |
| - message_loop_proxy()->PostTaskAndReply( |
| - from_here, |
| - base::Bind(&RunRasterTask, |
| - base::Unretained(picture_pile), |
| - mapped_buffer, |
| - rect, |
| - contents_scale, |
| - stats), |
| - base::Bind(&RasterThread::RunReply, base::Unretained(this), reply)); |
| - } |
| - |
| - void PostImageDecodingTaskAndReply(const tracked_objects::Location& from_here, |
| - skia::LazyPixelRef* pixel_ref, |
| - RenderingStats* stats, |
| - const base::Closure& reply) { |
| - ++num_pending_tasks_; |
| - message_loop_proxy()->PostTaskAndReply( |
| - from_here, |
| - base::Bind(&RunImageDecodeTask, pixel_ref, stats), |
| - base::Bind(&RasterThread::RunReply, base::Unretained(this), reply)); |
| - } |
| - |
| - private: |
| - static void RunRasterTask(PicturePileImpl* picture_pile, |
| - uint8_t* mapped_buffer, |
| - const gfx::Rect& rect, |
| - float contents_scale, |
| - RenderingStats* stats) { |
| - TRACE_EVENT0("cc", "RasterThread::RunRasterTask"); |
| - DCHECK(picture_pile); |
| - DCHECK(mapped_buffer); |
| - SkBitmap bitmap; |
| - bitmap.setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height()); |
| - bitmap.setPixels(mapped_buffer); |
| - SkDevice device(bitmap); |
| - SkCanvas canvas(&device); |
| - picture_pile->Raster( |
| - &canvas, |
| - rect, |
| - contents_scale, |
| - stats); |
| - } |
| - |
| - static void RunImageDecodeTask(skia::LazyPixelRef* pixel_ref, |
| - RenderingStats* stats) { |
| - TRACE_EVENT0("cc", "RasterThread::RunImageDecodeTask"); |
| - base::TimeTicks decodeBeginTime = base::TimeTicks::Now(); |
| - pixel_ref->Decode(); |
| - stats->totalDeferredImageDecodeTimeInSeconds += |
| - (base::TimeTicks::Now() - decodeBeginTime).InSecondsF(); |
| - } |
| - |
| - void RunReply(const base::Closure& reply) { |
| - --num_pending_tasks_; |
| - reply.Run(); |
| - } |
| - |
| - int num_pending_tasks_; |
| - |
| - DISALLOW_COPY_AND_ASSIGN(RasterThread); |
| -}; |
| - |
| ManagedTileState::ManagedTileState() |
| : can_use_gpu_memory(false), |
| can_be_freed(true), |
| @@ -161,19 +63,10 @@ TileManager::TileManager( |
| size_t num_raster_threads) |
| : client_(client), |
| resource_pool_(ResourcePool::Create(resource_provider)), |
| + raster_worker_(RasterWorker::Create(num_raster_threads)), |
| manage_tiles_pending_(false), |
| manage_tiles_call_count_(0), |
| check_for_completed_set_pixels_pending_(false) { |
| - // Initialize all threads. |
| - const std::string thread_name_prefix = kRasterThreadNamePrefix; |
| - while (raster_threads_.size() < num_raster_threads) { |
| - int thread_number = raster_threads_.size() + 1; |
| - scoped_ptr<RasterThread> thread = make_scoped_ptr( |
| - new RasterThread(thread_name_prefix + |
| - StringPrintf("Worker%d", thread_number).c_str())); |
| - raster_threads_.append(thread.Pass()); |
| - } |
| - |
| ResetBinCounts(); |
| } |
| @@ -182,14 +75,15 @@ TileManager::~TileManager() { |
| // our memory usage to drop to zero. |
| global_state_ = GlobalStateThatImpactsTilePriority(); |
| AssignGpuMemoryToTiles(); |
| - // This should finish all pending raster tasks and release any |
| - // uninitialized resources. |
| - raster_threads_.clear(); |
| + // This should finish all pending tasks and release any uninitialized |
| + // resources. |
| + raster_worker_.reset(); |
| ManageTiles(); |
| DCHECK(tiles_.size() == 0); |
| } |
| -void TileManager::SetGlobalState(const GlobalStateThatImpactsTilePriority& global_state) { |
| +void TileManager::SetGlobalState( |
| + const GlobalStateThatImpactsTilePriority& global_state) { |
| global_state_ = global_state; |
| resource_pool_->SetMaxMemoryUsageBytes(global_state_.memory_limit_in_bytes); |
| ScheduleManageTiles(); |
| @@ -205,7 +99,7 @@ void TileManager::UnregisterTile(Tile* tile) { |
| it != tiles_with_image_decoding_tasks_.end(); it++) { |
| if (*it == tile) { |
| tiles_with_image_decoding_tasks_.erase(it); |
| - break;; |
| + break; |
| } |
| } |
| for (TileVector::iterator it = tiles_that_need_to_be_rasterized_.begin(); |
| @@ -225,7 +119,8 @@ void TileManager::UnregisterTile(Tile* tile) { |
| DCHECK(false) << "Could not find tile version."; |
| } |
| -void TileManager::WillModifyTilePriority(Tile*, WhichTree tree, const TilePriority& new_priority) { |
| +void TileManager::WillModifyTilePriority( |
| + Tile* tile, WhichTree tree, const TilePriority& new_priority) { |
| // TODO(nduca): Do something smarter if reprioritization turns out to be |
| // costly. |
| ScheduleManageTiles(); |
| @@ -368,16 +263,10 @@ void TileManager::CheckForCompletedSetPixels() { |
| } |
| void TileManager::GetRenderingStats(RenderingStats* stats) { |
| - stats->totalRasterizeTimeInSeconds = |
| - rendering_stats_.totalRasterizeTimeInSeconds; |
| - stats->totalPixelsRasterized = rendering_stats_.totalPixelsRasterized; |
| - stats->totalDeferredImageDecodeCount = |
| - rendering_stats_.totalDeferredImageDecodeCount; |
| + raster_worker_->GetRenderingStats(stats); |
| stats->totalDeferredImageCacheHitCount = |
| rendering_stats_.totalDeferredImageCacheHitCount; |
| stats->totalImageGatheringCount = rendering_stats_.totalImageGatheringCount; |
| - stats->totalDeferredImageDecodeTimeInSeconds = |
| - rendering_stats_.totalDeferredImageDecodeTimeInSeconds; |
| stats->totalImageGatheringTimeInSeconds = |
| rendering_stats_.totalImageGatheringTimeInSeconds; |
| } |
| @@ -464,19 +353,6 @@ void TileManager::FreeResourcesForTile(Tile* tile) { |
| resource_pool_->ReleaseResource(managed_tile_state.resource.Pass()); |
| } |
| -RasterThread* TileManager::GetFreeRasterThread() { |
| - RasterThread* thread = 0; |
| - for (RasterThreadVector::iterator it = raster_threads_.begin(); |
| - it != raster_threads_.end(); ++it) { |
| - if ((*it)->num_pending_tasks() == kNumPendingRasterTasksPerThread) |
| - continue; |
| - // Check if this is the best thread we've found so far. |
| - if (!thread || (*it)->num_pending_tasks() < thread->num_pending_tasks()) |
| - thread = *it; |
| - } |
| - return thread; |
| -} |
| - |
| 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 |
| @@ -486,10 +362,9 @@ void TileManager::DispatchMoreTasks() { |
| DispatchImageDecodingTasksForTile(*it); |
| ManagedTileState& managed_state = (*it)->managed_state(); |
| if (managed_state.pending_pixel_refs.empty()) { |
| - RasterThread* thread = GetFreeRasterThread(); |
| - if (!thread) |
| + if (raster_worker_->IsBusy()) |
|
nduca
2012/12/19 04:46:50
how about making it bool DispatchOneBlahBlah? In t
reveman
2012/12/27 15:26:58
Makes sense. It will be easy to do this once resou
|
| return; |
| - DispatchOneRasterTask(thread, *it); |
| + DispatchOneRasterTask(*it); |
| tiles_with_image_decoding_tasks_.erase(it++); |
| } else { |
| ++it; |
| @@ -505,10 +380,9 @@ void TileManager::DispatchMoreTasks() { |
| if (!managed_state.pending_pixel_refs.empty()) { |
| tiles_with_image_decoding_tasks_.push_back(tile); |
| } else { |
| - RasterThread* thread = GetFreeRasterThread(); |
| - if (!thread) |
| + if (raster_worker_->IsBusy()) |
| return; |
| - DispatchOneRasterTask(thread, tile); |
| + DispatchOneRasterTask(tile); |
| } |
| tiles_that_need_to_be_rasterized_.pop_back(); |
| } |
| @@ -544,45 +418,35 @@ void TileManager::DispatchImageDecodingTasksForTile(Tile* tile) { |
| rendering_stats_.totalDeferredImageCacheHitCount++; |
| pending_pixel_refs.erase(it++); |
| } else { |
| - RasterThread* thread = GetFreeRasterThread(); |
| - if (!thread) |
| + if (raster_worker_->IsBusy()) |
| return; |
| - DispatchOneImageDecodingTask(thread, tile, *it); |
| + DispatchOneImageDecodingTask(tile, *it); |
| ++it; |
| } |
| } |
| } |
| -void TileManager::DispatchOneImageDecodingTask(RasterThread* thread, |
| - scoped_refptr<Tile> tile, |
| - skia::LazyPixelRef* pixel_ref) { |
| +void TileManager::DispatchOneImageDecodingTask( |
| + scoped_refptr<Tile> tile, skia::LazyPixelRef* pixel_ref) { |
| TRACE_EVENT0("cc", "TileManager::DispatchOneImageDecodingTask"); |
| uint32_t pixel_ref_id = pixel_ref->getGenerationID(); |
| DCHECK(pending_decode_tasks_.end() == |
| pending_decode_tasks_.find(pixel_ref_id)); |
| pending_decode_tasks_[pixel_ref_id] = pixel_ref; |
| - RenderingStats* stats = new RenderingStats(); |
| - |
| - thread->PostImageDecodingTaskAndReply( |
| - FROM_HERE, |
| - pixel_ref, |
| - stats, |
| - base::Bind(&TileManager::OnImageDecodingTaskCompleted, |
| - base::Unretained(this), |
| - tile, |
| - pixel_ref_id, |
| - stats)); |
| + |
| + raster_worker_->PostImageDecodingTaskAndReply( |
| + pixel_ref, |
| + base::Bind(&TileManager::OnImageDecodingTaskCompleted, |
| + base::Unretained(this), |
| + tile, |
| + pixel_ref_id)); |
| } |
| -void TileManager::OnImageDecodingTaskCompleted(scoped_refptr<Tile> tile, |
| - uint32_t pixel_ref_id, |
| - RenderingStats* stats) { |
| - TRACE_EVENT0("cc", "TileManager::OnImageDecoded"); |
| +void TileManager::OnImageDecodingTaskCompleted( |
| + scoped_refptr<Tile> tile, uint32_t pixel_ref_id) { |
| + TRACE_EVENT0("cc", "TileManager::OnImageDecodingTaskCompleted"); |
| pending_decode_tasks_.erase(pixel_ref_id); |
| - rendering_stats_.totalDeferredImageDecodeTimeInSeconds += |
| - stats->totalDeferredImageDecodeTimeInSeconds; |
| - rendering_stats_.totalDeferredImageDecodeCount++; |
| - delete stats; |
| + |
| for (TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); |
| it != tiles_with_image_decoding_tasks_.end(); ++it) { |
| std::list<skia::LazyPixelRef*>& pixel_refs = |
| @@ -595,11 +459,11 @@ void TileManager::OnImageDecodingTaskCompleted(scoped_refptr<Tile> tile, |
| } |
| } |
| } |
| + |
| DispatchMoreTasks(); |
| } |
| -void TileManager::DispatchOneRasterTask( |
| - RasterThread* thread, scoped_refptr<Tile> tile) { |
| +void TileManager::DispatchOneRasterTask(scoped_refptr<Tile> tile) { |
| TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask"); |
| ManagedTileState& managed_tile_state = tile->managed_state(); |
| DCHECK(managed_tile_state.can_use_gpu_memory); |
| @@ -611,37 +475,24 @@ void TileManager::DispatchOneRasterTask( |
| managed_tile_state.can_be_freed = false; |
| ResourceProvider::ResourceId resource_id = resource->id(); |
| - scoped_refptr<PicturePileImpl> picture_pile_clone = |
| - tile->picture_pile()->GetCloneForDrawingOnThread(thread); |
| - RenderingStats* stats = new RenderingStats(); |
| - thread->PostRasterTaskAndReply( |
| - FROM_HERE, |
| - picture_pile_clone.get(), |
| + raster_worker_->PostRasterTaskAndReply( |
| + tile->picture_pile(), |
| resource_pool_->resource_provider()->mapPixelBuffer(resource_id), |
| tile->content_rect_, |
| tile->contents_scale(), |
| - stats, |
| base::Bind(&TileManager::OnRasterTaskCompleted, |
| base::Unretained(this), |
| tile, |
| base::Passed(&resource), |
| - picture_pile_clone, |
| - manage_tiles_call_count_, |
| - stats)); |
| + manage_tiles_call_count_)); |
| } |
| void TileManager::OnRasterTaskCompleted( |
| scoped_refptr<Tile> tile, |
| scoped_ptr<ResourcePool::Resource> resource, |
| - scoped_refptr<PicturePileImpl> picture_pile_clone, |
| - int manage_tiles_call_count_when_dispatched, |
| - RenderingStats* stats) { |
| + int manage_tiles_call_count_when_dispatched) { |
| TRACE_EVENT0("cc", "TileManager::OnRasterTaskCompleted"); |
| - rendering_stats_.totalRasterizeTimeInSeconds += |
| - stats->totalRasterizeTimeInSeconds; |
| - rendering_stats_.totalPixelsRasterized += stats->totalPixelsRasterized; |
| - delete stats; |
| // Release raster resources. |
|
nduca
2012/12/19 04:46:50
I guess I'm a bit confused about why this is stuff
reveman
2012/12/27 15:26:58
I was planning to do some of that in a second patc
|
| resource_pool_->resource_provider()->unmapPixelBuffer(resource->id()); |
| @@ -679,6 +530,7 @@ void TileManager::OnRasterTaskCompleted( |
| resource_pool_->ReleaseResource(resource.Pass()); |
| managed_tile_state.resource_is_being_initialized = false; |
| } |
| + |
| DispatchMoreTasks(); |
| } |
| @@ -691,4 +543,4 @@ void TileManager::DidFinishTileInitialization(Tile* tile) { |
| drawable_tiles_in_bin_count_[managed_tile_state.bin[i]][i]++; |
| } |
| -} |
| +} // namespace cc |