| Index: cc/tile_manager.cc
|
| diff --git a/cc/tile_manager.cc b/cc/tile_manager.cc
|
| index 929bb678469e2741e4a2150d4d0c0548661a99c3..62f7b5f4799a837da7bbb0299ab6b30f9279e678 100644
|
| --- a/cc/tile_manager.cc
|
| +++ b/cc/tile_manager.cc
|
| @@ -5,35 +5,22 @@
|
| #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_pool.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;
|
| @@ -52,108 +39,23 @@ cc::TileManagerBin BinFromTilePriority(const cc::TilePriority& prio) {
|
| }
|
|
|
| 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),
|
| @@ -174,19 +76,10 @@ TileManager::TileManager(
|
| size_t num_raster_threads)
|
| : client_(client),
|
| resource_pool_(ResourcePool::Create(resource_provider)),
|
| + raster_worker_(RasterWorkerPool::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_.push_back(thread.Pass());
|
| - }
|
| -
|
| ResetBinCounts();
|
| }
|
|
|
| @@ -195,14 +88,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();
|
| @@ -218,7 +112,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();
|
| @@ -238,7 +132,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();
|
| @@ -382,16 +277,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;
|
| }
|
| @@ -498,32 +387,18 @@ 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
|
| // 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);
|
| + DispatchImageDecodeTasksForTile(*it);
|
| ManagedTileState& managed_state = (*it)->managed_state();
|
| if (managed_state.pending_pixel_refs.empty()) {
|
| - RasterThread* thread = GetFreeRasterThread();
|
| - if (!thread)
|
| + if (raster_worker_->IsBusy())
|
| return;
|
| - DispatchOneRasterTask(thread, *it);
|
| + DispatchOneRasterTask(*it);
|
| tiles_with_image_decoding_tasks_.erase(it++);
|
| } else {
|
| ++it;
|
| @@ -534,15 +409,14 @@ void TileManager::DispatchMoreTasks() {
|
| // 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);
|
| + DispatchImageDecodeTasksForTile(tile);
|
| ManagedTileState& managed_state = tile->managed_state();
|
| 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();
|
| }
|
| @@ -562,7 +436,7 @@ void TileManager::GatherPixelRefsForTile(Tile* tile) {
|
| }
|
| }
|
|
|
| -void TileManager::DispatchImageDecodingTasksForTile(Tile* tile) {
|
| +void TileManager::DispatchImageDecodeTasksForTile(Tile* tile) {
|
| GatherPixelRefsForTile(tile);
|
| std::list<skia::LazyPixelRef*>& pending_pixel_refs =
|
| tile->managed_state().pending_pixel_refs;
|
| @@ -578,45 +452,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);
|
| + DispatchOneImageDecodeTask(tile, *it);
|
| ++it;
|
| }
|
| }
|
| }
|
|
|
| -void TileManager::DispatchOneImageDecodingTask(RasterThread* thread,
|
| - scoped_refptr<Tile> tile,
|
| - skia::LazyPixelRef* pixel_ref) {
|
| - TRACE_EVENT0("cc", "TileManager::DispatchOneImageDecodingTask");
|
| +void TileManager::DispatchOneImageDecodeTask(
|
| + scoped_refptr<Tile> tile, skia::LazyPixelRef* pixel_ref) {
|
| + TRACE_EVENT0("cc", "TileManager::DispatchOneImageDecodeTask");
|
| 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_->PostImageDecodeTaskAndReply(
|
| + pixel_ref,
|
| + base::Bind(&TileManager::OnImageDecodeTaskCompleted,
|
| + 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::OnImageDecodeTaskCompleted(
|
| + scoped_refptr<Tile> tile, uint32_t pixel_ref_id) {
|
| + TRACE_EVENT0("cc", "TileManager::OnImageDecodeTaskCompleted");
|
| 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 =
|
| @@ -629,11 +493,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);
|
| @@ -645,37 +509,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.
|
| resource_pool_->resource_provider()->unmapPixelBuffer(resource->id());
|
| @@ -713,6 +564,7 @@ void TileManager::OnRasterTaskCompleted(
|
| resource_pool_->ReleaseResource(resource.Pass());
|
| managed_tile_state.resource_is_being_initialized = false;
|
| }
|
| +
|
| DispatchMoreTasks();
|
| }
|
|
|
| @@ -725,4 +577,4 @@ void TileManager::DidFinishTileInitialization(Tile* tile) {
|
| drawable_tiles_in_bin_count_[managed_tile_state.bin[i]][i]++;
|
| }
|
|
|
| -}
|
| +} // namespace cc
|
|
|