Chromium Code Reviews| Index: cc/tile_manager.cc |
| diff --git a/cc/tile_manager.cc b/cc/tile_manager.cc |
| index 932c2a836d4181fd8c6f099fceaf76c5e223bbf4..6d6616209fcaec8f90cb2ca760f5c6e1901ee2e7 100644 |
| --- a/cc/tile_manager.cc |
| +++ b/cc/tile_manager.cc |
| @@ -66,6 +66,16 @@ class RasterThread : public base::Thread { |
| base::Bind(&RasterThread::RunReply, base::Unretained(this), reply)); |
| } |
| + void PostImageDecodingTaskAndReply(const tracked_objects::Location& from_here, |
| + skia::LazyPixelRef* pixel_ref, |
| + const base::Closure& reply) { |
| + ++num_pending_tasks_; |
| + message_loop_proxy()->PostTaskAndReply( |
| + from_here, |
| + base::Bind(&skia::LazyPixelRef::Decode, base::Unretained(pixel_ref)), |
| + base::Bind(&RasterThread::RunReply, base::Unretained(this), reply)); |
| + } |
| + |
| private: |
| static void RunRasterTask(PicturePileImpl* picture_pile, |
| uint8_t* mapped_buffer, |
| @@ -101,7 +111,8 @@ ManagedTileState::ManagedTileState() |
| : can_use_gpu_memory(false), |
| can_be_freed(true), |
| resource_is_being_initialized(false), |
| - contents_swizzled(false) { |
| + contents_swizzled(false), |
| + need_to_gather_pixel_refs(true) { |
| } |
| ManagedTileState::~ManagedTileState() { |
| @@ -284,7 +295,7 @@ void TileManager::ManageTiles() { |
| AssignGpuMemoryToTiles(); |
| // Finally, kick the rasterizer. |
| - DispatchMoreRasterTasks(); |
| + DispatchMoreTasks(); |
| } |
| void TileManager::CheckForCompletedSetPixels() { |
| @@ -370,28 +381,123 @@ void TileManager::FreeResourcesForTile(Tile* tile) { |
| resource_pool_->ReleaseResource(managed_tile_state.resource.Pass()); |
| } |
| -void TileManager::DispatchMoreRasterTasks() { |
| - while (!tiles_that_need_to_be_rasterized_.empty()) { |
| - 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; |
| - } |
| +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; |
| +} |
| - // Stop dispatching tasks when all threads are busy. |
| - if (!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 |
| + // in the need_to_be_rasterized queue. |
| + std::list<Tile*>::iterator it = tiles_with_image_decoding_tasks_.begin(); |
| + while (it != tiles_with_image_decoding_tasks_.end()) { |
| + DispatchImageDecodingTasksForTile(*it); |
| + ManagedTileState& managed_state = (*it)->managed_state(); |
| + if (managed_state.pending_pixel_refs.empty()) { |
| + RasterThread* thread = GetFreeRasterThread(); |
| + if (!thread) |
| return; |
| + DispatchOneRasterTask(thread, *it); |
| + tiles_with_image_decoding_tasks_.erase(it++); |
| + } else { |
| + ++it; |
| + } |
| + } |
| - DispatchOneRasterTask(thread, tiles_that_need_to_be_rasterized_.back()); |
| + // 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. |
| + while (!tiles_that_need_to_be_rasterized_.empty()) { |
| + Tile* tile = tiles_that_need_to_be_rasterized_.back(); |
| + DispatchImageDecodingTasksForTile(tile); |
| + ManagedTileState& managed_state = tile->managed_state(); |
| + if (!managed_state.pending_pixel_refs.empty()) |
| + tiles_with_image_decoding_tasks_.push_back(tile); |
| + else { |
|
reveman
2012/12/11 05:07:18
nit: curly braces around both IF and ELSE required
qinmin
2012/12/11 05:36:20
Done.
|
| + RasterThread* thread = GetFreeRasterThread(); |
| + if (!thread) |
| + return; |
| + DispatchOneRasterTask(thread, tile); |
| + } |
| tiles_that_need_to_be_rasterized_.pop_back(); |
| } |
| } |
| +void TileManager::DispatchImageDecodingTasksForTile(Tile* tile) { |
| + ManagedTileState& managed_state = tile->managed_state(); |
| + if (!managed_state.need_to_gather_pixel_refs) { |
| + const_cast<PicturePileImpl *>(tile->picture_pile())->GatherPixelRefs( |
| + tile->content_rect_, managed_state.pending_pixel_refs); |
| + managed_state.need_to_gather_pixel_refs = false; |
| + } |
| + |
| + RasterThread* thread = 0; |
|
reveman
2012/12/11 05:07:18
nit: |thread| is not needed in this scope. please
qinmin
2012/12/11 05:36:20
Done.
|
| + std::list<skia::LazyPixelRef*>& pending_pixel_refs = |
| + tile->managed_state().pending_pixel_refs; |
| + std::list<skia::LazyPixelRef*>::iterator it = pending_pixel_refs.begin(); |
| + while (it != pending_pixel_refs.end()) { |
| + if (pending_decode_tasks_.end() != pending_decode_tasks_.find( |
| + (*it)->getGenerationID())) { |
| + ++it; |
| + continue; |
| + } |
| + if ((*it)->PrepareToDecode(skia::LazyPixelRef::PrepareParams())) |
| + pending_pixel_refs.erase(it++); |
| + else { |
|
reveman
2012/12/11 05:07:18
nit: curly braces around both IF and ELSE required
qinmin
2012/12/11 05:36:20
Done.
|
| + thread = GetFreeRasterThread(); |
| + if (thread) |
| + DispatchOneImageDecodingTask(thread, tile, *it); |
| + ++it; |
| + } |
| + } |
| +} |
| + |
| +void TileManager::DispatchOneImageDecodingTask(RasterThread* thread, |
| + 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; |
| + |
| + thread->PostImageDecodingTaskAndReply( |
| + FROM_HERE, |
| + 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) { |
| + TRACE_EVENT0("cc", "TileManager::OnImageDecoded"); |
| + pending_decode_tasks_.erase(pixel_ref_id); |
| + |
| + for (TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); |
| + it != tiles_with_image_decoding_tasks_.end(); ++it) { |
| + std::list<skia::LazyPixelRef*>& pixel_refs = |
| + (*it)->managed_state().pending_pixel_refs; |
| + for (std::list<skia::LazyPixelRef*>::iterator pixel_it = |
| + pixel_refs.begin(); pixel_it != pixel_refs.end(); ++pixel_it) { |
| + if (pixel_ref_id == (*pixel_it)->getGenerationID()) { |
| + pixel_refs.erase(pixel_it); |
| + break; |
| + } |
| + } |
| + } |
| + DispatchMoreTasks(); |
| +} |
| + |
| void TileManager::DispatchOneRasterTask( |
| RasterThread* thread, scoped_refptr<Tile> tile) { |
| TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask"); |
| @@ -446,7 +552,7 @@ void TileManager::OnRasterTaskCompleted( |
| // tiles. The result of this could be that this tile is no longer |
| // allowed to use gpu memory and in that case we need to abort |
| // initialization and free all associated resources before calling |
| - // DispatchMoreRasterTasks(). |
| + // DispatchMoreTasks(). |
| AssignGpuMemoryToTiles(); |
| // Finish resource initialization if |can_use_gpu_memory| is true. |
| @@ -470,8 +576,7 @@ void TileManager::OnRasterTaskCompleted( |
| resource_pool_->ReleaseResource(resource.Pass()); |
| managed_tile_state.resource_is_being_initialized = false; |
| } |
| - |
| - DispatchMoreRasterTasks(); |
| + DispatchMoreTasks(); |
| } |
| void TileManager::DidFinishTileInitialization(Tile* tile) { |