diff options
author | reveman@chromium.org <reveman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-28 23:24:10 +0000 |
---|---|---|
committer | reveman@chromium.org <reveman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-28 23:24:10 +0000 |
commit | b9128259612ca9072585e5124f8341d395e33de0 (patch) | |
tree | 6ea4d71f4ec9dc74fb84717f01ec97260f2d321f /cc | |
parent | d7c8ee6ab8b0c834f8fcff9642032e6c58a68bdf (diff) | |
download | chromium_src-b9128259612ca9072585e5124f8341d395e33de0.zip chromium_src-b9128259612ca9072585e5124f8341d395e33de0.tar.gz chromium_src-b9128259612ca9072585e5124f8341d395e33de0.tar.bz2 |
cc: Make internal::RasterWorkerPoolTask an internal::Task.
Clean up RasterWorkerPool by making internal::RasterWorkerPoolTask a real
task that can be run by TaskGraphRunner. Reduces the complexity of our
RasterWorkerPool implementations significantly and improves performance
by reducing the number of heap allocations performed when scheduling tasks.
Also makes PixelBufferRasterWorkerPool only run image decode reply
callbacks when CheckForCompletedTasks() is called.
BUG=246546
Review URL: https://codereview.chromium.org/133933004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@247521 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r-- | cc/resources/image_raster_worker_pool.cc | 154 | ||||
-rw-r--r-- | cc/resources/image_raster_worker_pool.h | 23 | ||||
-rw-r--r-- | cc/resources/pixel_buffer_raster_worker_pool.cc | 407 | ||||
-rw-r--r-- | cc/resources/pixel_buffer_raster_worker_pool.h | 44 | ||||
-rw-r--r-- | cc/resources/raster_worker_pool.cc | 163 | ||||
-rw-r--r-- | cc/resources/raster_worker_pool.h | 61 | ||||
-rw-r--r-- | cc/resources/raster_worker_pool_perftest.cc | 84 | ||||
-rw-r--r-- | cc/resources/raster_worker_pool_unittest.cc | 47 | ||||
-rw-r--r-- | cc/test/fake_tile_manager.cc | 30 |
9 files changed, 485 insertions, 528 deletions
diff --git a/cc/resources/image_raster_worker_pool.cc b/cc/resources/image_raster_worker_pool.cc index 46ebbbc..de9ba9d 100644 --- a/cc/resources/image_raster_worker_pool.cc +++ b/cc/resources/image_raster_worker_pool.cc @@ -12,46 +12,6 @@ namespace cc { -namespace { - -class ImageWorkerPoolTaskImpl : public internal::WorkerPoolTask { - public: - typedef base::Callback<void(bool was_canceled)> Reply; - - ImageWorkerPoolTaskImpl(internal::RasterWorkerPoolTask* task, - uint8_t* buffer, - int stride, - const Reply& reply) - : task_(task), buffer_(buffer), stride_(stride), reply_(reply) {} - - // Overridden from internal::Task: - virtual void RunOnWorkerThread(unsigned thread_index) OVERRIDE { - TRACE_EVENT0("cc", "ImageWorkerPoolTaskImpl::RunOnWorkerThread"); - if (!buffer_) - return; - - task_->RunOnWorkerThread( - thread_index, buffer_, task_->resource()->size(), stride_); - } - - // Overridden from internal::WorkerPoolTask: - virtual void CompleteOnOriginThread() OVERRIDE { - reply_.Run(!HasFinishedRunning()); - } - - private: - virtual ~ImageWorkerPoolTaskImpl() {} - - scoped_refptr<internal::RasterWorkerPoolTask> task_; - uint8_t* buffer_; - int stride_; - const Reply reply_; - - DISALLOW_COPY_AND_ASSIGN(ImageWorkerPoolTaskImpl); -}; - -} // namespace - ImageRasterWorkerPool::ImageRasterWorkerPool( ResourceProvider* resource_provider, ContextProvider* context_provider, @@ -61,9 +21,7 @@ ImageRasterWorkerPool::ImageRasterWorkerPool( raster_tasks_pending_(false), raster_tasks_required_for_activation_pending_(false) {} -ImageRasterWorkerPool::~ImageRasterWorkerPool() { - DCHECK_EQ(0u, image_tasks_.size()); -} +ImageRasterWorkerPool::~ImageRasterWorkerPool() {} void ImageRasterWorkerPool::ScheduleTasks(RasterTask::Queue* queue) { TRACE_EVENT0("cc", "ImageRasterWorkerPool::ScheduleTasks"); @@ -101,49 +59,22 @@ void ImageRasterWorkerPool::ScheduleTasks(RasterTask::Queue* queue) { ++it) { internal::RasterWorkerPoolTask* task = it->get(); DCHECK(!task->HasCompleted()); - DCHECK(!task->WasCanceled()); if (task->use_gpu_rasterization()) { gpu_raster_tasks.push_back(task); continue; } - TaskMap::iterator image_it = image_tasks_.find(task); - if (image_it != image_tasks_.end()) { - internal::WorkerPoolTask* image_task = image_it->second.get(); - CreateGraphNodeForImageTask(image_task, - task->dependencies(), - priority++, - IsRasterTaskRequiredForActivation(task), - raster_required_for_activation_finished_node, - raster_finished_node, - &graph); - continue; - } + task->ScheduleOnOriginThread(this); - // Acquire image for resource. - resource_provider()->AcquireImage(task->resource()->id()); - - // Map image for raster. - uint8* buffer = resource_provider()->MapImage(task->resource()->id()); - int stride = resource_provider()->GetImageStride(task->resource()->id()); - - scoped_refptr<internal::WorkerPoolTask> new_image_task( - new ImageWorkerPoolTaskImpl( - task, - buffer, - stride, - base::Bind(&ImageRasterWorkerPool::OnRasterTaskCompleted, - base::Unretained(this), - make_scoped_refptr(task)))); - image_tasks_[task] = new_image_task; - CreateGraphNodeForImageTask(new_image_task.get(), - task->dependencies(), - priority++, - IsRasterTaskRequiredForActivation(task), - raster_required_for_activation_finished_node, - raster_finished_node, - &graph); + CreateGraphNodeForImageRasterTask( + task, + task->dependencies(), + priority++, + IsRasterTaskRequiredForActivation(task), + raster_required_for_activation_finished_node, + raster_finished_node, + &graph); } SetTaskGraph(&graph); @@ -171,6 +102,47 @@ ResourceFormat ImageRasterWorkerPool::GetResourceFormat() const { return resource_provider()->best_texture_format(); } +void ImageRasterWorkerPool::CheckForCompletedTasks() { + TRACE_EVENT0("cc", "ImageRasterWorkerPool::CheckForCompletedTasks"); + + internal::Task::Vector completed_tasks; + CollectCompletedWorkerPoolTasks(&completed_tasks); + + for (internal::Task::Vector::const_iterator it = completed_tasks.begin(); + it != completed_tasks.end(); + ++it) { + internal::WorkerPoolTask* task = + static_cast<internal::WorkerPoolTask*>(it->get()); + + task->WillComplete(); + task->CompleteOnOriginThread(this); + task->DidComplete(); + + task->RunReplyOnOriginThread(); + } + + CheckForCompletedGpuRasterTasks(); +} + +void* ImageRasterWorkerPool::AcquireBufferForRaster( + internal::RasterWorkerPoolTask* task, + int* stride) { + // Acquire image for resource. + resource_provider()->AcquireImage(task->resource()->id()); + + *stride = resource_provider()->GetImageStride(task->resource()->id()); + return resource_provider()->MapImage(task->resource()->id()); +} + +void ImageRasterWorkerPool::OnRasterCompleted( + internal::RasterWorkerPoolTask* task, + const PicturePileImpl::Analysis& analysis) { + resource_provider()->UnmapImage(task->resource()->id()); +} + +void ImageRasterWorkerPool::OnImageDecodeCompleted( + internal::WorkerPoolTask* task) {} + void ImageRasterWorkerPool::OnRasterTasksFinished() { DCHECK(raster_tasks_pending_); raster_tasks_pending_ = false; @@ -191,28 +163,6 @@ void ImageRasterWorkerPool::OnRasterTasksRequiredForActivationFinished() { client()->DidFinishRunningTasksRequiredForActivation(); } -void ImageRasterWorkerPool::OnRasterTaskCompleted( - scoped_refptr<internal::RasterWorkerPoolTask> task, - bool was_canceled) { - TRACE_EVENT1("cc", - "ImageRasterWorkerPool::OnRasterTaskCompleted", - "was_canceled", - was_canceled); - - DCHECK(!task->use_gpu_rasterization()); - DCHECK(image_tasks_.find(task.get()) != image_tasks_.end()); - - // Balanced with MapImage() call in ScheduleTasks(). - resource_provider()->UnmapImage(task->resource()->id()); - - task->DidRun(was_canceled); - task->WillComplete(); - task->CompleteOnOriginThread(); - task->DidComplete(); - - image_tasks_.erase(task.get()); -} - scoped_ptr<base::Value> ImageRasterWorkerPool::StateAsValue() const { scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue); @@ -223,7 +173,7 @@ scoped_ptr<base::Value> ImageRasterWorkerPool::StateAsValue() const { } // static -void ImageRasterWorkerPool::CreateGraphNodeForImageTask( +void ImageRasterWorkerPool::CreateGraphNodeForImageRasterTask( internal::WorkerPoolTask* image_task, const internal::Task::Vector& decode_tasks, unsigned priority, diff --git a/cc/resources/image_raster_worker_pool.h b/cc/resources/image_raster_worker_pool.h index d22e238..b60004c 100644 --- a/cc/resources/image_raster_worker_pool.h +++ b/cc/resources/image_raster_worker_pool.h @@ -9,7 +9,8 @@ namespace cc { -class CC_EXPORT ImageRasterWorkerPool : public RasterWorkerPool { +class CC_EXPORT ImageRasterWorkerPool : public RasterWorkerPool, + public internal::WorkerPoolTaskClient { public: virtual ~ImageRasterWorkerPool(); @@ -25,20 +26,28 @@ class CC_EXPORT ImageRasterWorkerPool : public RasterWorkerPool { virtual void ScheduleTasks(RasterTask::Queue* queue) OVERRIDE; virtual unsigned GetResourceTarget() const OVERRIDE; virtual ResourceFormat GetResourceFormat() const OVERRIDE; - virtual void OnRasterTasksFinished() OVERRIDE; - virtual void OnRasterTasksRequiredForActivationFinished() OVERRIDE; + virtual void CheckForCompletedTasks() OVERRIDE; + + // Overridden from internal::WorkerPoolTaskClient: + virtual void* AcquireBufferForRaster(internal::RasterWorkerPoolTask* task, + int* stride) OVERRIDE; + virtual void OnRasterCompleted(internal::RasterWorkerPoolTask* task, + const PicturePileImpl::Analysis& analysis) + OVERRIDE; + virtual void OnImageDecodeCompleted(internal::WorkerPoolTask* task) OVERRIDE; private: ImageRasterWorkerPool(ResourceProvider* resource_provider, ContextProvider* context_provider, unsigned texture_target); - void OnRasterTaskCompleted(scoped_refptr<internal::RasterWorkerPoolTask> task, - bool was_canceled); + // Overridden from RasterWorkerPool: + virtual void OnRasterTasksFinished() OVERRIDE; + virtual void OnRasterTasksRequiredForActivationFinished() OVERRIDE; scoped_ptr<base::Value> StateAsValue() const; - static void CreateGraphNodeForImageTask( + static void CreateGraphNodeForImageRasterTask( internal::WorkerPoolTask* image_task, const internal::Task::Vector& decode_tasks, unsigned priority, @@ -49,8 +58,6 @@ class CC_EXPORT ImageRasterWorkerPool : public RasterWorkerPool { const unsigned texture_target_; - TaskMap image_tasks_; - bool raster_tasks_pending_; bool raster_tasks_required_for_activation_pending_; diff --git a/cc/resources/pixel_buffer_raster_worker_pool.cc b/cc/resources/pixel_buffer_raster_worker_pool.cc index bbdc31e..b1972aa 100644 --- a/cc/resources/pixel_buffer_raster_worker_pool.cc +++ b/cc/resources/pixel_buffer_raster_worker_pool.cc @@ -16,49 +16,8 @@ #endif namespace cc { - namespace { -class PixelBufferWorkerPoolTaskImpl : public internal::WorkerPoolTask { - public: - typedef base::Callback<void(bool was_canceled, bool needs_upload)> Reply; - - PixelBufferWorkerPoolTaskImpl(internal::RasterWorkerPoolTask* task, - uint8_t* buffer, - const Reply& reply) - : task_(task), buffer_(buffer), reply_(reply), needs_upload_(false) {} - - // Overridden from internal::Task: - virtual void RunOnWorkerThread(unsigned thread_index) OVERRIDE { - // |buffer_| can be NULL in lost context situations. - if (!buffer_) { - // |needs_upload_| still needs to be true as task has not - // been canceled. - needs_upload_ = true; - return; - } - needs_upload_ = task_->RunOnWorkerThread( - thread_index, buffer_, task_->resource()->size(), 0); - } - - // Overridden from internal::WorkerPoolTask: - virtual void CompleteOnOriginThread() OVERRIDE { - // |needs_upload_| must be be false if task didn't run. - DCHECK(HasFinishedRunning() || !needs_upload_); - reply_.Run(!HasFinishedRunning(), needs_upload_); - } - - private: - virtual ~PixelBufferWorkerPoolTaskImpl() {} - - scoped_refptr<internal::RasterWorkerPoolTask> task_; - uint8_t* buffer_; - const Reply reply_; - bool needs_upload_; - - DISALLOW_COPY_AND_ASSIGN(PixelBufferWorkerPoolTaskImpl); -}; - const int kCheckForCompletedRasterTasksDelayMs = 6; const size_t kMaxScheduledRasterTasks = 48; @@ -80,7 +39,7 @@ void AddDependenciesToGraphNode(internal::GraphNode* node, // Only used as std::find_if predicate for DCHECKs. bool WasCanceled(const internal::RasterWorkerPoolTask* task) { - return task->WasCanceled(); + return !task->HasFinishedRunning(); } } // namespace @@ -105,9 +64,10 @@ PixelBufferRasterWorkerPool::PixelBufferRasterWorkerPool( PixelBufferRasterWorkerPool::~PixelBufferRasterWorkerPool() { DCHECK(shutdown_); DCHECK(!check_for_completed_raster_tasks_pending_); - DCHECK_EQ(0u, pixel_buffer_tasks_.size()); - DCHECK_EQ(0u, tasks_with_pending_upload_.size()); - DCHECK_EQ(0u, completed_tasks_.size()); + DCHECK_EQ(0u, raster_task_states_.size()); + DCHECK_EQ(0u, raster_tasks_with_pending_upload_.size()); + DCHECK_EQ(0u, completed_raster_tasks_.size()); + DCHECK_EQ(0u, completed_image_decode_tasks_.size()); } void PixelBufferRasterWorkerPool::Shutdown() { @@ -118,19 +78,18 @@ void PixelBufferRasterWorkerPool::Shutdown() { CheckForCompletedUploads(); check_for_completed_raster_tasks_callback_.Cancel(); check_for_completed_raster_tasks_pending_ = false; - for (TaskMap::iterator it = pixel_buffer_tasks_.begin(); - it != pixel_buffer_tasks_.end(); + for (RasterTaskStateMap::iterator it = raster_task_states_.begin(); + it != raster_task_states_.end(); ++it) { internal::RasterWorkerPoolTask* task = it->first; - internal::WorkerPoolTask* pixel_buffer_task = it->second.get(); - // All inactive tasks needs to be canceled. - if (!pixel_buffer_task && !task->HasFinishedRunning()) { - task->DidRun(true); - completed_tasks_.push_back(task); + // All unscheduled tasks need to be canceled. + if (it->second == UNSCHEDULED) { + completed_raster_tasks_.push_back(task); + it->second = COMPLETED; } } - DCHECK_EQ(completed_tasks_.size(), pixel_buffer_tasks_.size()); + DCHECK_EQ(completed_raster_tasks_.size(), raster_task_states_.size()); } void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTask::Queue* queue) { @@ -144,64 +103,65 @@ void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTask::Queue* queue) { should_notify_client_if_no_tasks_are_pending_ = true; should_notify_client_if_no_tasks_required_for_activation_are_pending_ = true; - tasks_required_for_activation_.clear(); + raster_tasks_required_for_activation_.clear(); - // Build new pixel buffer task set. - TaskMap new_pixel_buffer_tasks; + // Build new raster task state map. + RasterTaskStateMap new_raster_task_states; RasterTaskVector gpu_raster_tasks; for (RasterTaskVector::const_iterator it = raster_tasks().begin(); it != raster_tasks().end(); ++it) { internal::RasterWorkerPoolTask* task = it->get(); - DCHECK(new_pixel_buffer_tasks.find(task) == new_pixel_buffer_tasks.end()); - DCHECK(!task->HasCompleted()); - DCHECK(!task->WasCanceled()); + DCHECK(new_raster_task_states.find(task) == new_raster_task_states.end()); if (task->use_gpu_rasterization()) { gpu_raster_tasks.push_back(task); continue; } - new_pixel_buffer_tasks[task] = pixel_buffer_tasks_[task]; - pixel_buffer_tasks_.erase(task); - - if (IsRasterTaskRequiredForActivation(task)) - tasks_required_for_activation_.insert(task); + RasterTaskStateMap::iterator state_it = raster_task_states_.find(task); + if (state_it != raster_task_states_.end()) { + RasterTaskState state = state_it->second; + + new_raster_task_states[task] = state; + // |raster_tasks_required_for_activation_| contains all tasks that need to + // complete before we can send a "ready to activate" signal. Tasks that + // have already completed should not be part of this set. + if (state != COMPLETED && IsRasterTaskRequiredForActivation(task)) + raster_tasks_required_for_activation_.insert(task); + + raster_task_states_.erase(state_it); + } else { + new_raster_task_states[task] = UNSCHEDULED; + if (IsRasterTaskRequiredForActivation(task)) + raster_tasks_required_for_activation_.insert(task); + } } - // Transfer remaining pixel buffer tasks to |new_pixel_buffer_tasks| - // and cancel all remaining inactive tasks. - for (TaskMap::iterator it = pixel_buffer_tasks_.begin(); - it != pixel_buffer_tasks_.end(); + // Transfer old raster task state to |new_raster_task_states| and cancel all + // remaining unscheduled tasks. + for (RasterTaskStateMap::iterator it = raster_task_states_.begin(); + it != raster_task_states_.end(); ++it) { internal::RasterWorkerPoolTask* task = it->first; - internal::WorkerPoolTask* pixel_buffer_task = it->second.get(); - - // Move task to |new_pixel_buffer_tasks| - new_pixel_buffer_tasks[task] = pixel_buffer_task; - - // Inactive task can be canceled. - if (!pixel_buffer_task && !task->HasFinishedRunning()) { - task->DidRun(true); - DCHECK(std::find(completed_tasks_.begin(), - completed_tasks_.end(), - task) == completed_tasks_.end()); - completed_tasks_.push_back(task); - } else if (IsRasterTaskRequiredForActivation(task)) { - tasks_required_for_activation_.insert(task); + DCHECK(new_raster_task_states.find(task) == new_raster_task_states.end()); + DCHECK(!IsRasterTaskRequiredForActivation(task)); + + // Unscheduled task can be canceled. + if (it->second == UNSCHEDULED) { + DCHECK(std::find(completed_raster_tasks_.begin(), + completed_raster_tasks_.end(), + task) == completed_raster_tasks_.end()); + completed_raster_tasks_.push_back(task); + new_raster_task_states[task] = COMPLETED; + continue; } - } - // |tasks_required_for_activation_| contains all tasks that need to - // complete before we can send a "ready to activate" signal. Tasks - // that have already completed should not be part of this set. - for (RasterTaskDeque::const_iterator it = completed_tasks_.begin(); - it != completed_tasks_.end() && !tasks_required_for_activation_.empty(); - ++it) { - tasks_required_for_activation_.erase(*it); + // Move state to |new_raster_task_states|. + new_raster_task_states[task] = it->second; } - pixel_buffer_tasks_.swap(new_pixel_buffer_tasks); + raster_task_states_.swap(new_raster_task_states); // Check for completed tasks when ScheduleTasks() is called as // priorities might have changed and this maximizes the number @@ -241,25 +201,98 @@ ResourceFormat PixelBufferRasterWorkerPool::GetResourceFormat() const { void PixelBufferRasterWorkerPool::CheckForCompletedTasks() { TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::CheckForCompletedTasks"); - RasterWorkerPool::CheckForCompletedTasks(); + CheckForCompletedWorkerPoolTasks(); CheckForCompletedUploads(); FlushUploads(); - RasterTaskDeque completed_tasks; - completed_tasks_.swap(completed_tasks); + while (!completed_image_decode_tasks_.empty()) { + internal::WorkerPoolTask* task = + completed_image_decode_tasks_.front().get(); - while (!completed_tasks.empty()) { - internal::RasterWorkerPoolTask* task = completed_tasks.front().get(); - DCHECK(pixel_buffer_tasks_.find(task) != pixel_buffer_tasks_.end()); + task->RunReplyOnOriginThread(); - pixel_buffer_tasks_.erase(task); + completed_image_decode_tasks_.pop_front(); + } - task->WillComplete(); - task->CompleteOnOriginThread(); - task->DidComplete(); + while (!completed_raster_tasks_.empty()) { + internal::RasterWorkerPoolTask* task = + completed_raster_tasks_.front().get(); + DCHECK(raster_task_states_.find(task) != raster_task_states_.end()); + DCHECK_EQ(COMPLETED, raster_task_states_[task]); - completed_tasks.pop_front(); + raster_task_states_.erase(task); + + task->RunReplyOnOriginThread(); + + completed_raster_tasks_.pop_front(); } + + CheckForCompletedGpuRasterTasks(); +} + +void* PixelBufferRasterWorkerPool::AcquireBufferForRaster( + internal::RasterWorkerPoolTask* task, + int* stride) { + // Request a pixel buffer. This will reserve shared memory. + resource_provider()->AcquirePixelBuffer(task->resource()->id()); + + *stride = 0; + return resource_provider()->MapPixelBuffer(task->resource()->id()); +} + +void PixelBufferRasterWorkerPool::OnRasterCompleted( + internal::RasterWorkerPoolTask* task, + const PicturePileImpl::Analysis& analysis) { + TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("cc"), + "PixelBufferRasterWorkerPool::OnRasterCompleted", + "was_canceled", + !task->HasFinishedRunning(), + "needs_upload", + task->HasFinishedRunning() && !analysis.is_solid_color); + + DCHECK(raster_task_states_.find(task) != raster_task_states_.end()); + DCHECK_EQ(SCHEDULED, raster_task_states_[task]); + + // Balanced with MapPixelBuffer() call in AcquireBufferForRaster(). + resource_provider()->UnmapPixelBuffer(task->resource()->id()); + + if (!task->HasFinishedRunning() || analysis.is_solid_color) { + resource_provider()->ReleasePixelBuffer(task->resource()->id()); + + if (!task->HasFinishedRunning()) { + // When priorites change, a raster task can be canceled as a result of + // no longer being of high enough priority to fit in our throttled + // raster task budget. The task has not yet completed in this case. + RasterTaskVector::const_iterator it = + std::find(raster_tasks().begin(), raster_tasks().end(), task); + if (it != raster_tasks().end()) { + raster_task_states_[task] = UNSCHEDULED; + return; + } + } + + DCHECK(std::find(completed_raster_tasks_.begin(), + completed_raster_tasks_.end(), + task) == completed_raster_tasks_.end()); + completed_raster_tasks_.push_back(task); + raster_task_states_[task] = COMPLETED; + raster_tasks_required_for_activation_.erase(task); + return; + } + + DCHECK(task->HasFinishedRunning()); + + resource_provider()->BeginSetPixels(task->resource()->id()); + has_performed_uploads_since_last_flush_ = true; + + bytes_pending_upload_ += task->resource()->bytes(); + raster_tasks_with_pending_upload_.push_back(task); + raster_task_states_[task] = UPLOADING; +} + +void PixelBufferRasterWorkerPool::OnImageDecodeCompleted( + internal::WorkerPoolTask* task) { + completed_image_decode_tasks_.push_back(task); } void PixelBufferRasterWorkerPool::OnRasterTasksFinished() { @@ -302,16 +335,18 @@ void PixelBufferRasterWorkerPool::CheckForCompletedUploads() { RasterTaskDeque tasks_with_completed_uploads; // First check if any have completed. - while (!tasks_with_pending_upload_.empty()) { + while (!raster_tasks_with_pending_upload_.empty()) { internal::RasterWorkerPoolTask* task = - tasks_with_pending_upload_.front().get(); + raster_tasks_with_pending_upload_.front().get(); + DCHECK(raster_task_states_.find(task) != raster_task_states_.end()); + DCHECK_EQ(UPLOADING, raster_task_states_[task]); // Uploads complete in the order they are issued. if (!resource_provider()->DidSetPixelsComplete(task->resource()->id())) break; tasks_with_completed_uploads.push_back(task); - tasks_with_pending_upload_.pop_front(); + raster_tasks_with_pending_upload_.pop_front(); } DCHECK(client()); @@ -320,17 +355,17 @@ void PixelBufferRasterWorkerPool::CheckForCompletedUploads() { if (should_force_some_uploads_to_complete) { RasterTaskDeque tasks_with_uploads_to_force; - RasterTaskDeque::iterator it = tasks_with_pending_upload_.begin(); - while (it != tasks_with_pending_upload_.end()) { + RasterTaskDeque::iterator it = raster_tasks_with_pending_upload_.begin(); + while (it != raster_tasks_with_pending_upload_.end()) { internal::RasterWorkerPoolTask* task = it->get(); - DCHECK(pixel_buffer_tasks_.find(task) != pixel_buffer_tasks_.end()); + DCHECK(raster_task_states_.find(task) != raster_task_states_.end()); // Force all uploads required for activation to complete. // During shutdown, force all pending uploads to complete. if (shutdown_ || IsRasterTaskRequiredForActivation(task)) { tasks_with_uploads_to_force.push_back(task); tasks_with_completed_uploads.push_back(task); - it = tasks_with_pending_upload_.erase(it); + it = raster_tasks_with_pending_upload_.erase(it); continue; } @@ -349,7 +384,7 @@ void PixelBufferRasterWorkerPool::CheckForCompletedUploads() { } // Release shared memory and move tasks with completed uploads - // to |completed_tasks_|. + // to |completed_raster_tasks_|. while (!tasks_with_completed_uploads.empty()) { internal::RasterWorkerPoolTask* task = tasks_with_completed_uploads.front().get(); @@ -359,13 +394,13 @@ void PixelBufferRasterWorkerPool::CheckForCompletedUploads() { bytes_pending_upload_ -= task->resource()->bytes(); - task->DidRun(false); - - DCHECK(std::find(completed_tasks_.begin(), completed_tasks_.end(), task) == - completed_tasks_.end()); - completed_tasks_.push_back(task); + DCHECK(std::find(completed_raster_tasks_.begin(), + completed_raster_tasks_.end(), + task) == completed_raster_tasks_.end()); + completed_raster_tasks_.push_back(task); + raster_task_states_[task] = COMPLETED; - tasks_required_for_activation_.erase(task); + raster_tasks_required_for_activation_.erase(task); tasks_with_completed_uploads.pop_front(); } @@ -465,16 +500,17 @@ void PixelBufferRasterWorkerPool::ScheduleMoreTasks() { ++it) { internal::RasterWorkerPoolTask* task = it->get(); - // |pixel_buffer_tasks_| contains all tasks that have not yet completed. - TaskMap::iterator pixel_buffer_it = pixel_buffer_tasks_.find(task); - if (pixel_buffer_it == pixel_buffer_tasks_.end()) + // |raster_task_states_| contains the state of all tasks that we have not + // yet run reply callbacks for. + RasterTaskStateMap::iterator state_it = raster_task_states_.find(task); + if (state_it == raster_task_states_.end()) continue; - // HasFinishedRunning() will return true when set pixels has completed. - if (task->HasFinishedRunning()) { - DCHECK(std::find(completed_tasks_.begin(), - completed_tasks_.end(), - task) != completed_tasks_.end()); + // Skip task if completed. + if (state_it->second == COMPLETED) { + DCHECK(std::find(completed_raster_tasks_.begin(), + completed_raster_tasks_.end(), + task) != completed_raster_tasks_.end()); continue; } @@ -486,10 +522,8 @@ void PixelBufferRasterWorkerPool::ScheduleMoreTasks() { break; } - internal::WorkerPoolTask* pixel_buffer_task = pixel_buffer_it->second.get(); - // If raster has finished, just update |bytes_pending_upload|. - if (pixel_buffer_task && pixel_buffer_task->HasCompleted()) { + if (state_it->second == UPLOADING) { bytes_pending_upload = new_bytes_pending_upload; continue; } @@ -511,31 +545,12 @@ void PixelBufferRasterWorkerPool::ScheduleMoreTasks() { ? REQUIRED_FOR_ACTIVATION_TYPE : PREPAINT_TYPE; - // Use existing pixel buffer task if available. - if (pixel_buffer_task) { - tasks[type].container().push_back(CreateGraphNodeForRasterTask( - pixel_buffer_task, task->dependencies(), priority++, &graph)); - continue; - } + task->ScheduleOnOriginThread(this); + DCHECK(state_it->second == UNSCHEDULED || state_it->second == SCHEDULED); + state_it->second = SCHEDULED; - // Request a pixel buffer. This will reserve shared memory. - resource_provider()->AcquirePixelBuffer(task->resource()->id()); - - // MapPixelBuffer() returns NULL if context was lost at the time - // AcquirePixelBuffer() was called. For simplicity we still post - // a raster task that is essentially a noop in these situations. - uint8* buffer = resource_provider()->MapPixelBuffer(task->resource()->id()); - - scoped_refptr<internal::WorkerPoolTask> new_pixel_buffer_task( - new PixelBufferWorkerPoolTaskImpl( - task, - buffer, - base::Bind(&PixelBufferRasterWorkerPool::OnRasterTaskCompleted, - base::Unretained(this), - make_scoped_refptr(task)))); - pixel_buffer_tasks_[task] = new_pixel_buffer_task; tasks[type].container().push_back(CreateGraphNodeForRasterTask( - new_pixel_buffer_task.get(), task->dependencies(), priority++, &graph)); + task, task->dependencies(), priority++, &graph)); } scoped_refptr<internal::WorkerPoolTask> @@ -544,16 +559,16 @@ void PixelBufferRasterWorkerPool::ScheduleMoreTasks() { size_t scheduled_raster_task_required_for_activation_count = tasks[REQUIRED_FOR_ACTIVATION_TYPE].container().size(); DCHECK_LE(scheduled_raster_task_required_for_activation_count, - tasks_required_for_activation_.size()); + raster_tasks_required_for_activation_.size()); // Schedule OnRasterTasksRequiredForActivationFinished call only when // notification is pending and throttling is not preventing all pending // tasks required for activation from being scheduled. if (scheduled_raster_task_required_for_activation_count == - tasks_required_for_activation_.size() && + raster_tasks_required_for_activation_.size() && should_notify_client_if_no_tasks_required_for_activation_are_pending_) { new_raster_required_for_activation_finished_task = CreateRasterRequiredForActivationFinishedTask( - tasks_required_for_activation_.size()); + raster_tasks_required_for_activation_.size()); raster_required_for_activation_finished_task_pending_ = true; internal::GraphNode* raster_required_for_activation_finished_node = CreateGraphNodeForTask( @@ -594,68 +609,19 @@ void PixelBufferRasterWorkerPool::ScheduleMoreTasks() { new_raster_required_for_activation_finished_task); } -void PixelBufferRasterWorkerPool::OnRasterTaskCompleted( - scoped_refptr<internal::RasterWorkerPoolTask> task, - bool was_canceled, - bool needs_upload) { - TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("cc"), - "PixelBufferRasterWorkerPool::OnRasterTaskCompleted", - "was_canceled", - was_canceled, - "needs_upload", - needs_upload); - - DCHECK(!task->use_gpu_rasterization()); - DCHECK(pixel_buffer_tasks_.find(task.get()) != pixel_buffer_tasks_.end()); - - // Balanced with MapPixelBuffer() call in ScheduleMoreTasks(). - resource_provider()->UnmapPixelBuffer(task->resource()->id()); - - if (!needs_upload) { - resource_provider()->ReleasePixelBuffer(task->resource()->id()); - - if (was_canceled) { - // When priorites change, a raster task can be canceled as a result of - // no longer being of high enough priority to fit in our throttled - // raster task budget. The task has not yet completed in this case. - RasterTaskVector::const_iterator it = - std::find(raster_tasks().begin(), raster_tasks().end(), task); - if (it != raster_tasks().end()) { - pixel_buffer_tasks_[task.get()] = NULL; - return; - } - } - - task->DidRun(was_canceled); - DCHECK(std::find(completed_tasks_.begin(), completed_tasks_.end(), task) == - completed_tasks_.end()); - completed_tasks_.push_back(task); - tasks_required_for_activation_.erase(task); - return; - } - - DCHECK(!was_canceled); - - resource_provider()->BeginSetPixels(task->resource()->id()); - has_performed_uploads_since_last_flush_ = true; - - bytes_pending_upload_ += task->resource()->bytes(); - tasks_with_pending_upload_.push_back(task); -} - unsigned PixelBufferRasterWorkerPool::PendingRasterTaskCount() const { unsigned num_completed_raster_tasks = - tasks_with_pending_upload_.size() + completed_tasks_.size(); - DCHECK_GE(pixel_buffer_tasks_.size(), num_completed_raster_tasks); - return pixel_buffer_tasks_.size() - num_completed_raster_tasks; + raster_tasks_with_pending_upload_.size() + completed_raster_tasks_.size(); + DCHECK_GE(raster_task_states_.size(), num_completed_raster_tasks); + return raster_task_states_.size() - num_completed_raster_tasks; } bool PixelBufferRasterWorkerPool::HasPendingTasks() const { - return PendingRasterTaskCount() || !tasks_with_pending_upload_.empty(); + return PendingRasterTaskCount() || !raster_tasks_with_pending_upload_.empty(); } bool PixelBufferRasterWorkerPool::HasPendingTasksRequiredForActivation() const { - return !tasks_required_for_activation_.empty(); + return !raster_tasks_required_for_activation_.empty(); } const char* PixelBufferRasterWorkerPool::StateName() const { @@ -663,20 +629,37 @@ const char* PixelBufferRasterWorkerPool::StateName() const { return "rasterizing"; if (PendingRasterTaskCount()) return "throttled"; - if (!tasks_with_pending_upload_.empty()) + if (!raster_tasks_with_pending_upload_.empty()) return "waiting_for_uploads"; return "finishing"; } +void PixelBufferRasterWorkerPool::CheckForCompletedWorkerPoolTasks() { + internal::Task::Vector completed_tasks; + CollectCompletedWorkerPoolTasks(&completed_tasks); + + for (internal::Task::Vector::const_iterator it = completed_tasks.begin(); + it != completed_tasks.end(); + ++it) { + internal::WorkerPoolTask* task = + static_cast<internal::WorkerPoolTask*>(it->get()); + + task->WillComplete(); + task->CompleteOnOriginThread(this); + task->DidComplete(); + } +} + scoped_ptr<base::Value> PixelBufferRasterWorkerPool::StateAsValue() const { scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue); - state->SetInteger("completed_count", completed_tasks_.size()); - state->SetInteger("pending_count", pixel_buffer_tasks_.size()); - state->SetInteger("pending_upload_count", tasks_with_pending_upload_.size()); + state->SetInteger("completed_count", completed_raster_tasks_.size()); + state->SetInteger("pending_count", raster_task_states_.size()); + state->SetInteger("pending_upload_count", + raster_tasks_with_pending_upload_.size()); state->SetInteger("required_for_activation_count", - tasks_required_for_activation_.size()); + raster_tasks_required_for_activation_.size()); state->Set("scheduled_state", ScheduledStateAsValue().release()); state->Set("throttle_state", ThrottleStateAsValue().release()); return state.PassAs<base::Value>(); diff --git a/cc/resources/pixel_buffer_raster_worker_pool.h b/cc/resources/pixel_buffer_raster_worker_pool.h index d564da1..e794162 100644 --- a/cc/resources/pixel_buffer_raster_worker_pool.h +++ b/cc/resources/pixel_buffer_raster_worker_pool.h @@ -6,8 +6,6 @@ #define CC_RESOURCES_PIXEL_BUFFER_RASTER_WORKER_POOL_H_ #include <deque> -#include <set> -#include <vector> #include "base/cancelable_callback.h" #include "base/containers/hash_tables.h" @@ -15,7 +13,9 @@ namespace cc { -class CC_EXPORT PixelBufferRasterWorkerPool : public RasterWorkerPool { +class CC_EXPORT PixelBufferRasterWorkerPool + : public RasterWorkerPool, + public internal::WorkerPoolTaskClient { public: virtual ~PixelBufferRasterWorkerPool(); @@ -27,34 +27,45 @@ class CC_EXPORT PixelBufferRasterWorkerPool : public RasterWorkerPool { resource_provider, context_provider, max_transfer_buffer_usage_bytes)); } - // Overridden from WorkerPool: - virtual void Shutdown() OVERRIDE; - // Overridden from RasterWorkerPool: + virtual void Shutdown() OVERRIDE; virtual void ScheduleTasks(RasterTask::Queue* queue) OVERRIDE; virtual unsigned GetResourceTarget() const OVERRIDE; virtual ResourceFormat GetResourceFormat() const OVERRIDE; virtual void CheckForCompletedTasks() OVERRIDE; - virtual void OnRasterTasksFinished() OVERRIDE; - virtual void OnRasterTasksRequiredForActivationFinished() OVERRIDE; + + // Overridden from internal::WorkerPoolTaskClient: + virtual void* AcquireBufferForRaster(internal::RasterWorkerPoolTask* task, + int* stride) OVERRIDE; + virtual void OnRasterCompleted(internal::RasterWorkerPoolTask* task, + const PicturePileImpl::Analysis& analysis) + OVERRIDE; + virtual void OnImageDecodeCompleted(internal::WorkerPoolTask* task) OVERRIDE; private: + enum RasterTaskState { UNSCHEDULED, SCHEDULED, UPLOADING, COMPLETED }; + typedef std::deque<scoped_refptr<internal::RasterWorkerPoolTask> > + RasterTaskDeque; + typedef internal::RasterWorkerPoolTask* RasterTaskMapKey; + typedef base::hash_map<RasterTaskMapKey, RasterTaskState> RasterTaskStateMap; + PixelBufferRasterWorkerPool(ResourceProvider* resource_provider, ContextProvider* context_provider, size_t max_transfer_buffer_usage_bytes); + // Overridden from RasterWorkerPool: + virtual void OnRasterTasksFinished() OVERRIDE; + virtual void OnRasterTasksRequiredForActivationFinished() OVERRIDE; + void FlushUploads(); void CheckForCompletedUploads(); void ScheduleCheckForCompletedRasterTasks(); void CheckForCompletedRasterTasks(); void ScheduleMoreTasks(); - void OnRasterTaskCompleted(scoped_refptr<internal::RasterWorkerPoolTask> task, - bool was_canceled, - bool needs_upload); - void DidCompleteRasterTask(internal::RasterWorkerPoolTask* task); unsigned PendingRasterTaskCount() const; bool HasPendingTasks() const; bool HasPendingTasksRequiredForActivation() const; + void CheckForCompletedWorkerPoolTasks(); const char* StateName() const; scoped_ptr<base::Value> StateAsValue() const; @@ -62,10 +73,11 @@ class CC_EXPORT PixelBufferRasterWorkerPool : public RasterWorkerPool { bool shutdown_; - TaskMap pixel_buffer_tasks_; - RasterTaskDeque tasks_with_pending_upload_; - RasterTaskDeque completed_tasks_; - RasterTaskSet tasks_required_for_activation_; + RasterTaskSet raster_tasks_required_for_activation_; + RasterTaskStateMap raster_task_states_; + RasterTaskDeque raster_tasks_with_pending_upload_; + RasterTaskDeque completed_raster_tasks_; + TaskDeque completed_image_decode_tasks_; size_t scheduled_raster_task_count_; size_t bytes_pending_upload_; diff --git a/cc/resources/raster_worker_pool.cc b/cc/resources/raster_worker_pool.cc index 7403f6d..cfd2c51 100644 --- a/cc/resources/raster_worker_pool.cc +++ b/cc/resources/raster_worker_pool.cc @@ -92,7 +92,9 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { tile_id_(tile_id), source_frame_number_(source_frame_number), rendering_stats_(rendering_stats), - reply_(reply) {} + reply_(reply), + buffer_(NULL), + stride_(0) {} void RunAnalysisOnThread(unsigned thread_index) { TRACE_EVENT1("cc", @@ -119,7 +121,7 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { analysis_.is_solid_color &= kUseColorEstimator; } - bool RunRasterOnThread(unsigned thread_index, + void RunRasterOnThread(unsigned thread_index, void* buffer, gfx::Size size, int stride) { @@ -137,9 +139,6 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { DCHECK(picture_pile_.get()); DCHECK(buffer); - if (analysis_.is_solid_color) - return false; - SkBitmap bitmap; switch (resource()->format()) { case RGBA_4444: @@ -166,21 +165,35 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { SkCanvas canvas(&device); Raster(picture_pile_->GetCloneForDrawingOnThread(thread_index), &canvas); ChangeBitmapConfigIfNeeded(bitmap, buffer); - - return true; } - // Overridden from internal::RasterWorkerPoolTask: - virtual bool RunOnWorkerThread(unsigned thread_index, - void* buffer, - gfx::Size size, - int stride) OVERRIDE { + // Overridden from internal::Task: + virtual void RunOnWorkerThread(unsigned thread_index) OVERRIDE { // TODO(alokp): For now run-on-worker-thread implies software rasterization. DCHECK(!use_gpu_rasterization()); RunAnalysisOnThread(thread_index); - return RunRasterOnThread(thread_index, buffer, size, stride); + if (buffer_ && !analysis_.is_solid_color) + RunRasterOnThread(thread_index, buffer_, resource()->size(), stride_); } + // Overridden from internal::WorkerPoolTask: + virtual void ScheduleOnOriginThread(internal::WorkerPoolTaskClient* client) + OVERRIDE { + DCHECK(!use_gpu_rasterization()); + if (buffer_) + return; + buffer_ = client->AcquireBufferForRaster(this, &stride_); + } + virtual void CompleteOnOriginThread(internal::WorkerPoolTaskClient* client) + OVERRIDE { + DCHECK(!use_gpu_rasterization()); + client->OnRasterCompleted(this, analysis_); + } + virtual void RunReplyOnOriginThread() OVERRIDE { + reply_.Run(analysis_, !HasFinishedRunning()); + } + + // Overridden from internal::RasterWorkerPoolTask: virtual void RunOnOriginThread(ResourceProvider* resource_provider, ContextProvider* context_provider) OVERRIDE { // TODO(alokp): For now run-on-origin-thread implies gpu rasterization. @@ -207,10 +220,6 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { Raster(picture_pile_, canvas.get()); } - virtual void CompleteOnOriginThread() OVERRIDE { - reply_.Run(analysis_, !HasFinishedRunning() || WasCanceled()); - } - protected: virtual ~RasterWorkerPoolTaskImpl() {} @@ -303,6 +312,8 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { int source_frame_number_; RenderingStatsInstrumentation* rendering_stats_; const RasterWorkerPool::RasterTask::Reply reply_; + void* buffer_; + int stride_; DISALLOW_COPY_AND_ASSIGN(RasterWorkerPoolTaskImpl); }; @@ -329,7 +340,13 @@ class ImageDecodeWorkerPoolTaskImpl : public internal::WorkerPoolTask { } // Overridden from internal::WorkerPoolTask: - virtual void CompleteOnOriginThread() OVERRIDE { + virtual void ScheduleOnOriginThread(internal::WorkerPoolTaskClient* client) + OVERRIDE {} + virtual void CompleteOnOriginThread(internal::WorkerPoolTaskClient* client) + OVERRIDE { + client->OnImageDecodeCompleted(this); + } + virtual void RunReplyOnOriginThread() OVERRIDE { reply_.Run(!HasFinishedRunning()); } @@ -354,14 +371,20 @@ class RasterFinishedWorkerPoolTaskImpl : public internal::WorkerPoolTask { : origin_loop_(base::MessageLoopProxy::current().get()), on_raster_finished_callback_(on_raster_finished_callback) {} - // Overridden from internal::WorkerPoolTask: + // Overridden from internal::Task: virtual void RunOnWorkerThread(unsigned thread_index) OVERRIDE { TRACE_EVENT0("cc", "RasterFinishedWorkerPoolTaskImpl::RunOnWorkerThread"); origin_loop_->PostTask( FROM_HERE, base::Bind(&RasterFinishedWorkerPoolTaskImpl::RunOnOriginThread, this)); } - virtual void CompleteOnOriginThread() OVERRIDE {} + + // Overridden from internal::WorkerPoolTask: + virtual void ScheduleOnOriginThread(internal::WorkerPoolTaskClient* client) + OVERRIDE {} + virtual void CompleteOnOriginThread(internal::WorkerPoolTaskClient* client) + OVERRIDE {} + virtual void RunReplyOnOriginThread() OVERRIDE {} protected: virtual ~RasterFinishedWorkerPoolTaskImpl() {} @@ -449,35 +472,12 @@ bool WorkerPoolTask::HasCompleted() const { return did_complete_; } RasterWorkerPoolTask::RasterWorkerPoolTask(const Resource* resource, internal::Task::Vector* dependencies, bool use_gpu_rasterization) - : did_run_(false), - did_complete_(false), - was_canceled_(false), - resource_(resource), - use_gpu_rasterization_(use_gpu_rasterization) { + : resource_(resource), use_gpu_rasterization_(use_gpu_rasterization) { dependencies_.swap(*dependencies); } RasterWorkerPoolTask::~RasterWorkerPoolTask() {} -void RasterWorkerPoolTask::DidRun(bool was_canceled) { - DCHECK(!did_run_); - did_run_ = true; - was_canceled_ = was_canceled; -} - -bool RasterWorkerPoolTask::HasFinishedRunning() const { return did_run_; } - -bool RasterWorkerPoolTask::WasCanceled() const { return was_canceled_; } - -void RasterWorkerPoolTask::WillComplete() { DCHECK(!did_complete_); } - -void RasterWorkerPoolTask::DidComplete() { - DCHECK(!did_complete_); - did_complete_ = true; -} - -bool RasterWorkerPoolTask::HasCompleted() const { return did_complete_; } - } // namespace internal RasterWorkerPool::Task::Set::Set() {} @@ -580,10 +580,10 @@ RasterWorkerPool::RasterTask RasterWorkerPool::CreateRasterTask( RasterWorkerPool::Task RasterWorkerPool::CreateImageDecodeTask( SkPixelRef* pixel_ref, int layer_id, - RenderingStatsInstrumentation* stats_instrumentation, + RenderingStatsInstrumentation* rendering_stats, const Task::Reply& reply) { return Task(new ImageDecodeWorkerPoolTaskImpl( - pixel_ref, layer_id, stats_instrumentation, reply)); + pixel_ref, layer_id, rendering_stats, reply)); } void RasterWorkerPool::SetClient(RasterWorkerPoolClient* client) { @@ -600,39 +600,16 @@ void RasterWorkerPool::Shutdown() { weak_ptr_factory_.InvalidateWeakPtrs(); } -void RasterWorkerPool::CheckForCompletedTasks() { - TRACE_EVENT0("cc", "RasterWorkerPool::CheckForCompletedTasks"); - - CheckForCompletedWorkerPoolTasks(); - - // Complete gpu rasterization tasks. - while (!completed_gpu_raster_tasks_.empty()) { - internal::RasterWorkerPoolTask* task = - completed_gpu_raster_tasks_.front().get(); - - task->WillComplete(); - task->CompleteOnOriginThread(); - task->DidComplete(); - - completed_gpu_raster_tasks_.pop_front(); - } +void RasterWorkerPool::SetRasterTasks(RasterTask::Queue* queue) { + raster_tasks_.swap(queue->tasks_); + raster_tasks_required_for_activation_.swap( + queue->tasks_required_for_activation_); } -void RasterWorkerPool::CheckForCompletedWorkerPoolTasks() { - internal::Task::Vector completed_tasks; - g_task_graph_runner.Pointer()->CollectCompletedTasks(namespace_token_, - &completed_tasks); - - for (internal::Task::Vector::const_iterator it = completed_tasks.begin(); - it != completed_tasks.end(); - ++it) { - internal::WorkerPoolTask* task = - static_cast<internal::WorkerPoolTask*>(it->get()); - - task->WillComplete(); - task->CompleteOnOriginThread(); - task->DidComplete(); - } +bool RasterWorkerPool::IsRasterTaskRequiredForActivation( + internal::RasterWorkerPoolTask* task) const { + return raster_tasks_required_for_activation_.find(task) != + raster_tasks_required_for_activation_.end(); } void RasterWorkerPool::SetTaskGraph(TaskGraph* graph) { @@ -642,16 +619,10 @@ void RasterWorkerPool::SetTaskGraph(TaskGraph* graph) { g_task_graph_runner.Pointer()->SetTaskGraph(namespace_token_, graph); } -void RasterWorkerPool::SetRasterTasks(RasterTask::Queue* queue) { - raster_tasks_.swap(queue->tasks_); - raster_tasks_required_for_activation_.swap( - queue->tasks_required_for_activation_); -} - -bool RasterWorkerPool::IsRasterTaskRequiredForActivation( - internal::RasterWorkerPoolTask* task) const { - return raster_tasks_required_for_activation_.find(task) != - raster_tasks_required_for_activation_.end(); +void RasterWorkerPool::CollectCompletedWorkerPoolTasks( + internal::Task::Vector* completed_tasks) { + g_task_graph_runner.Pointer()->CollectCompletedTasks(namespace_token_, + completed_tasks); } void RasterWorkerPool::RunGpuRasterTasks(const RasterTaskVector& tasks) { @@ -668,8 +639,13 @@ void RasterWorkerPool::RunGpuRasterTasks(const RasterTaskVector& tasks) { internal::RasterWorkerPoolTask* task = it->get(); DCHECK(task->use_gpu_rasterization()); + task->DidSchedule(); + task->WillRun(); task->RunOnOriginThread(resource_provider_, context_provider_); - task->DidRun(false); + task->DidRun(); + task->WillComplete(); + task->DidComplete(); + completed_gpu_raster_tasks_.push_back(task); } @@ -678,6 +654,17 @@ void RasterWorkerPool::RunGpuRasterTasks(const RasterTaskVector& tasks) { gr_context->flush(); } +void RasterWorkerPool::CheckForCompletedGpuRasterTasks() { + // Complete gpu rasterization tasks. + while (!completed_gpu_raster_tasks_.empty()) { + internal::WorkerPoolTask* task = completed_gpu_raster_tasks_.front().get(); + + task->RunReplyOnOriginThread(); + + completed_gpu_raster_tasks_.pop_front(); + } +} + scoped_refptr<internal::WorkerPoolTask> RasterWorkerPool::CreateRasterFinishedTask() { return make_scoped_refptr(new RasterFinishedWorkerPoolTaskImpl(base::Bind( diff --git a/cc/resources/raster_worker_pool.h b/cc/resources/raster_worker_pool.h index 2490892..081dbb3 100644 --- a/cc/resources/raster_worker_pool.h +++ b/cc/resources/raster_worker_pool.h @@ -26,9 +26,26 @@ class ResourceProvider; namespace internal { +class WorkerPoolTask; +class RasterWorkerPoolTask; + +class CC_EXPORT WorkerPoolTaskClient { + public: + virtual void* AcquireBufferForRaster(RasterWorkerPoolTask* task, + int* stride) = 0; + virtual void OnRasterCompleted(RasterWorkerPoolTask* task, + const PicturePileImpl::Analysis& analysis) = 0; + virtual void OnImageDecodeCompleted(WorkerPoolTask* task) = 0; + + protected: + virtual ~WorkerPoolTaskClient() {} +}; + class CC_EXPORT WorkerPoolTask : public Task { public: - virtual void CompleteOnOriginThread() = 0; + virtual void ScheduleOnOriginThread(WorkerPoolTaskClient* client) = 0; + virtual void CompleteOnOriginThread(WorkerPoolTaskClient* client) = 0; + virtual void RunReplyOnOriginThread() = 0; void WillComplete(); void DidComplete(); @@ -42,43 +59,22 @@ class CC_EXPORT WorkerPoolTask : public Task { bool did_complete_; }; -class CC_EXPORT RasterWorkerPoolTask - : public base::RefCounted<RasterWorkerPoolTask> { +class CC_EXPORT RasterWorkerPoolTask : public WorkerPoolTask { public: - // Returns true if |buffer| was written to. False indicate that - // the content of |buffer| is undefined and the resource doesn't - // need to be initialized. - virtual bool RunOnWorkerThread(unsigned thread_index, - void* buffer, - gfx::Size size, - int stride) = 0; virtual void RunOnOriginThread(ResourceProvider* resource_provider, ContextProvider* context_provider) = 0; - virtual void CompleteOnOriginThread() = 0; - - void DidRun(bool was_canceled); - bool HasFinishedRunning() const; - bool WasCanceled() const; - void WillComplete(); - void DidComplete(); - bool HasCompleted() const; const Resource* resource() const { return resource_; } const internal::Task::Vector& dependencies() const { return dependencies_; } bool use_gpu_rasterization() const { return use_gpu_rasterization_; } protected: - friend class base::RefCounted<RasterWorkerPoolTask>; - RasterWorkerPoolTask(const Resource* resource, internal::Task::Vector* dependencies, bool use_gpu_rasterization); virtual ~RasterWorkerPoolTask(); private: - bool did_run_; - bool did_complete_; - bool was_canceled_; const Resource* resource_; Task::Vector dependencies_; bool use_gpu_rasterization_; @@ -214,7 +210,7 @@ class CC_EXPORT RasterWorkerPool { static Task CreateImageDecodeTask( SkPixelRef* pixel_ref, int layer_id, - RenderingStatsInstrumentation* stats_instrumentation, + RenderingStatsInstrumentation* rendering_stats, const Task::Reply& reply); void SetClient(RasterWorkerPoolClient* client); @@ -231,7 +227,7 @@ class CC_EXPORT RasterWorkerPool { virtual void ScheduleTasks(RasterTask::Queue* queue) = 0; // Force a check for completed tasks. - virtual void CheckForCompletedTasks(); + virtual void CheckForCompletedTasks() = 0; // Returns the target that needs to be used for raster task resources. virtual unsigned GetResourceTarget() const = 0; @@ -242,14 +238,10 @@ class CC_EXPORT RasterWorkerPool { protected: typedef internal::TaskGraphRunner::TaskGraph TaskGraph; typedef std::vector<scoped_refptr<internal::WorkerPoolTask> > TaskVector; + typedef std::deque<scoped_refptr<internal::WorkerPoolTask> > TaskDeque; typedef std::vector<scoped_refptr<internal::RasterWorkerPoolTask> > RasterTaskVector; - typedef std::deque<scoped_refptr<internal::RasterWorkerPoolTask> > - RasterTaskDeque; typedef base::hash_set<internal::RasterWorkerPoolTask*> RasterTaskSet; - typedef internal::RasterWorkerPoolTask* TaskMapKey; - typedef base::hash_map<TaskMapKey, scoped_refptr<internal::WorkerPoolTask> > - TaskMap; RasterWorkerPool(ResourceProvider* resource_provider, ContextProvider* context_provider); @@ -257,14 +249,15 @@ class CC_EXPORT RasterWorkerPool { virtual void OnRasterTasksFinished() = 0; virtual void OnRasterTasksRequiredForActivationFinished() = 0; - void CheckForCompletedWorkerPoolTasks(); - void SetTaskGraph(TaskGraph* graph); - void SetRasterTasks(RasterTask::Queue* queue); bool IsRasterTaskRequiredForActivation(internal::RasterWorkerPoolTask* task) const; + void SetTaskGraph(TaskGraph* graph); + void CollectCompletedWorkerPoolTasks(internal::Task::Vector* completed_tasks); + // Run raster tasks that use GPU on current thread. void RunGpuRasterTasks(const RasterTaskVector& tasks); + void CheckForCompletedGpuRasterTasks(); RasterWorkerPoolClient* client() const { return client_; } ResourceProvider* resource_provider() const { return resource_provider_; } @@ -312,7 +305,7 @@ class CC_EXPORT RasterWorkerPool { ContextProvider* context_provider_; RasterTask::Queue::TaskVector raster_tasks_; RasterTask::Queue::TaskSet raster_tasks_required_for_activation_; - RasterTaskDeque completed_gpu_raster_tasks_; + TaskDeque completed_gpu_raster_tasks_; scoped_refptr<internal::WorkerPoolTask> raster_finished_task_; scoped_refptr<internal::WorkerPoolTask> diff --git a/cc/resources/raster_worker_pool_perftest.cc b/cc/resources/raster_worker_pool_perftest.cc index 38a2310..e11c0ae 100644 --- a/cc/resources/raster_worker_pool_perftest.cc +++ b/cc/resources/raster_worker_pool_perftest.cc @@ -17,19 +17,8 @@ static const int kTimeLimitMillis = 2000; static const int kWarmupRuns = 5; static const int kTimeCheckInterval = 10; -class PerfWorkerPoolTaskImpl : public internal::WorkerPoolTask { - public: - // Overridden from internal::Task: - virtual void RunOnWorkerThread(unsigned thread_index) OVERRIDE {} - - // Overridden from internal::WorkerPoolTask: - virtual void CompleteOnOriginThread() OVERRIDE {} - - private: - virtual ~PerfWorkerPoolTaskImpl() {} -}; - -class PerfRasterWorkerPool : public RasterWorkerPool { +class PerfRasterWorkerPool : public RasterWorkerPool, + public internal::WorkerPoolTaskClient { public: PerfRasterWorkerPool() : RasterWorkerPool(NULL, NULL) {} virtual ~PerfRasterWorkerPool() {} @@ -50,6 +39,37 @@ class PerfRasterWorkerPool : public RasterWorkerPool { NOTREACHED(); return RGBA_8888; } + virtual void CheckForCompletedTasks() OVERRIDE { + internal::Task::Vector completed_tasks; + CollectCompletedWorkerPoolTasks(&completed_tasks); + + for (internal::Task::Vector::const_iterator it = completed_tasks.begin(); + it != completed_tasks.end(); + ++it) { + internal::WorkerPoolTask* task = + static_cast<internal::WorkerPoolTask*>(it->get()); + + task->WillComplete(); + task->CompleteOnOriginThread(this); + task->DidComplete(); + + task->RunReplyOnOriginThread(); + } + + CheckForCompletedGpuRasterTasks(); + } + + // Overridden from internal::WorkerPoolTaskClient: + virtual void* AcquireBufferForRaster(internal::RasterWorkerPoolTask* task, + int* stride) OVERRIDE { + return NULL; + } + virtual void OnRasterCompleted(internal::RasterWorkerPoolTask* task, + const PicturePileImpl::Analysis& analysis) + OVERRIDE {} + virtual void OnImageDecodeCompleted(internal::WorkerPoolTask* task) OVERRIDE { + } + virtual void OnRasterTasksFinished() OVERRIDE { NOTREACHED(); } virtual void OnRasterTasksRequiredForActivationFinished() OVERRIDE { NOTREACHED(); @@ -57,19 +77,6 @@ class PerfRasterWorkerPool : public RasterWorkerPool { void SetRasterTasks(RasterTask::Queue* queue) { RasterWorkerPool::SetRasterTasks(queue); - - TaskMap perf_tasks; - for (RasterTaskVector::const_iterator it = raster_tasks().begin(); - it != raster_tasks().end(); - ++it) { - internal::RasterWorkerPoolTask* task = it->get(); - - scoped_refptr<internal::WorkerPoolTask> new_perf_task( - new PerfWorkerPoolTaskImpl); - perf_tasks[task] = new_perf_task; - } - - perf_tasks_.swap(perf_tasks); } void BuildTaskGraph() { @@ -96,29 +103,20 @@ class PerfRasterWorkerPool : public RasterWorkerPool { ++it) { internal::RasterWorkerPoolTask* task = it->get(); - TaskMap::iterator perf_it = perf_tasks_.find(task); - DCHECK(perf_it != perf_tasks_.end()); - if (perf_it != perf_tasks_.end()) { - internal::WorkerPoolTask* perf_task = perf_it->second.get(); - - internal::GraphNode* perf_node = CreateGraphNodeForRasterTask( - perf_task, task->dependencies(), priority++, &graph); + internal::GraphNode* node = CreateGraphNodeForRasterTask( + task, task->dependencies(), priority++, &graph); - if (IsRasterTaskRequiredForActivation(task)) { - raster_required_for_activation_finished_node->add_dependency(); - perf_node->add_dependent( - raster_required_for_activation_finished_node); - } - - raster_finished_node->add_dependency(); - perf_node->add_dependent(raster_finished_node); + if (IsRasterTaskRequiredForActivation(task)) { + raster_required_for_activation_finished_node->add_dependency(); + node->add_dependent(raster_required_for_activation_finished_node); } + + raster_finished_node->add_dependency(); + node->add_dependent(raster_finished_node); } } private: - TaskMap perf_tasks_; - DISALLOW_COPY_AND_ASSIGN(PerfRasterWorkerPool); }; diff --git a/cc/resources/raster_worker_pool_unittest.cc b/cc/resources/raster_worker_pool_unittest.cc index 1f5d95c..92248f2 100644 --- a/cc/resources/raster_worker_pool_unittest.cc +++ b/cc/resources/raster_worker_pool_unittest.cc @@ -41,23 +41,31 @@ class TestRasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { reply_(reply), raster_thread_(RASTER_THREAD_NONE) {} - // Overridden from internal::RasterWorkerPoolTask: - virtual bool RunOnWorkerThread(unsigned thread_index, - void* buffer, - gfx::Size size, - int stride) OVERRIDE { + // Overridden from internal::Task: + virtual void RunOnWorkerThread(unsigned thread_index) OVERRIDE { raster_thread_ = RASTER_THREAD_WORKER; - return true; } + + // Overridden from internal::WorkerPoolTask: + virtual void ScheduleOnOriginThread(internal::WorkerPoolTaskClient* client) + OVERRIDE { + int stride; + client->AcquireBufferForRaster(this, &stride); + } + virtual void CompleteOnOriginThread(internal::WorkerPoolTaskClient* client) + OVERRIDE { + client->OnRasterCompleted(this, PicturePileImpl::Analysis()); + } + virtual void RunReplyOnOriginThread() OVERRIDE { + reply_.Run( + PicturePileImpl::Analysis(), !HasFinishedRunning(), raster_thread_); + } + + // Overridden from internal::RasterWorkerPoolTask: virtual void RunOnOriginThread(ResourceProvider* resource_provider, ContextProvider* context_provider) OVERRIDE { raster_thread_ = RASTER_THREAD_ORIGIN; } - virtual void CompleteOnOriginThread() OVERRIDE { - reply_.Run(PicturePileImpl::Analysis(), - !HasFinishedRunning() || WasCanceled(), - raster_thread_); - } protected: virtual ~TestRasterWorkerPoolTaskImpl() {} @@ -82,16 +90,14 @@ class BlockingRasterWorkerPoolTaskImpl : public TestRasterWorkerPoolTaskImpl { use_gpu_rasterization), lock_(lock) {} - // Overridden from internal::RasterWorkerPoolTask: - virtual bool RunOnWorkerThread(unsigned thread_index, - void* buffer, - gfx::Size size, - int stride) OVERRIDE { + // Overridden from internal::Task: + virtual void RunOnWorkerThread(unsigned thread_index) OVERRIDE { base::AutoLock lock(*lock_); - return TestRasterWorkerPoolTaskImpl::RunOnWorkerThread( - thread_index, buffer, size, stride); + TestRasterWorkerPoolTaskImpl::RunOnWorkerThread(thread_index); } - virtual void CompleteOnOriginThread() OVERRIDE {} + + // Overridden from internal::WorkerPoolTask: + virtual void RunReplyOnOriginThread() OVERRIDE {} protected: virtual ~BlockingRasterWorkerPoolTaskImpl() {} @@ -397,7 +403,8 @@ class RasterWorkerPoolTestFailedMapResource : public RasterWorkerPoolTest { bool was_canceled, TestRasterWorkerPoolTaskImpl::RasterThread raster_thread) OVERRIDE { EXPECT_FALSE(was_canceled); - EXPECT_EQ(TestRasterWorkerPoolTaskImpl::RASTER_THREAD_NONE, raster_thread); + EXPECT_EQ(TestRasterWorkerPoolTaskImpl::RASTER_THREAD_WORKER, + raster_thread); EndTest(); } diff --git a/cc/test/fake_tile_manager.cc b/cc/test/fake_tile_manager.cc index d5bc80b..347d14f 100644 --- a/cc/test/fake_tile_manager.cc +++ b/cc/test/fake_tile_manager.cc @@ -13,23 +13,31 @@ namespace cc { namespace { -class FakeRasterWorkerPool : public RasterWorkerPool { +class FakeRasterWorkerPool : public RasterWorkerPool, + public internal::WorkerPoolTaskClient { public: FakeRasterWorkerPool() : RasterWorkerPool(NULL, NULL) {} + // Overridden from RasterWorkerPool: virtual void ScheduleTasks(RasterTask::Queue* queue) OVERRIDE { RasterWorkerPool::SetRasterTasks(queue); for (RasterTaskVector::const_iterator it = raster_tasks().begin(); it != raster_tasks().end(); ++it) { + internal::WorkerPoolTask* task = it->get(); + + task->DidSchedule(); + completed_tasks_.push_back(it->get()); } } virtual void CheckForCompletedTasks() OVERRIDE { while (!completed_tasks_.empty()) { - internal::RasterWorkerPoolTask* task = completed_tasks_.front().get(); + internal::WorkerPoolTask* task = completed_tasks_.front().get(); + task->WillComplete(); - task->CompleteOnOriginThread(); task->DidComplete(); + task->RunReplyOnOriginThread(); + completed_tasks_.pop_front(); } } @@ -39,11 +47,23 @@ class FakeRasterWorkerPool : public RasterWorkerPool { virtual ResourceFormat GetResourceFormat() const OVERRIDE { return RGBA_8888; } + + // Overridden from internal::WorkerPoolTaskClient: + virtual void* AcquireBufferForRaster(internal::RasterWorkerPoolTask* task, + int* stride) OVERRIDE { + return NULL; + } + virtual void OnRasterCompleted(internal::RasterWorkerPoolTask* task, + const PicturePileImpl::Analysis& analysis) + OVERRIDE {} + virtual void OnImageDecodeCompleted(internal::WorkerPoolTask* task) OVERRIDE { + } + + private: + // Overridden from RasterWorkerPool: virtual void OnRasterTasksFinished() OVERRIDE {} virtual void OnRasterTasksRequiredForActivationFinished() OVERRIDE {} - private: - typedef std::deque<scoped_refptr<internal::RasterWorkerPoolTask> > TaskDeque; TaskDeque completed_tasks_; }; |