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 |