Index: cc/resources/pixel_buffer_raster_worker_pool.cc |
diff --git a/cc/resources/pixel_buffer_raster_worker_pool.cc b/cc/resources/pixel_buffer_raster_worker_pool.cc |
index af3a0869fe7727520aff77481a7584f11c8b7481..3e84dbc8e2afc75fe2536385c14b0235a6fd486e 100644 |
--- a/cc/resources/pixel_buffer_raster_worker_pool.cc |
+++ b/cc/resources/pixel_buffer_raster_worker_pool.cc |
@@ -4,6 +4,8 @@ |
#include "cc/resources/pixel_buffer_raster_worker_pool.h" |
+#include <algorithm> |
+ |
#include "base/containers/stack_container.h" |
#include "base/debug/trace_event.h" |
#include "base/values.h" |
@@ -74,15 +76,14 @@ void PixelBufferRasterWorkerPool::Shutdown() { |
weak_factory_.InvalidateWeakPtrs(); |
check_for_completed_raster_tasks_pending_ = false; |
- for (RasterTaskStateMap::iterator it = raster_task_states_.begin(); |
+ for (RasterTaskState::Vector::iterator it = raster_task_states_.begin(); |
it != raster_task_states_.end(); |
++it) { |
- internal::WorkerPoolTask* task = it->first; |
- RasterTaskState& state = it->second; |
+ RasterTaskState& state = *it; |
// All unscheduled tasks need to be canceled. |
if (state.type == RasterTaskState::UNSCHEDULED) { |
- completed_raster_tasks_.push_back(task); |
+ completed_raster_tasks_.push_back(state.task); |
state.type = RasterTaskState::COMPLETED; |
} |
} |
@@ -106,22 +107,33 @@ void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) { |
raster_tasks_required_for_activation_count_ = 0u; |
- // Build new raster task state map. |
- RasterTaskStateMap new_raster_task_states; |
+ // Update raster task state and remove items from old queue. |
for (RasterTaskQueue::Item::Vector::const_iterator it = queue->items.begin(); |
it != queue->items.end(); |
++it) { |
const RasterTaskQueue::Item& item = *it; |
internal::WorkerPoolTask* task = item.task; |
- DCHECK(new_raster_task_states.find(task) == new_raster_task_states.end()); |
- RasterTaskStateMap::iterator state_it = raster_task_states_.find(task); |
+ // Remove any old items that are associated with this task. The result is |
+ // that the old queue is left with all items not present in this queue, |
+ // which we use below to determine what tasks need to be canceled. |
+ RasterTaskQueue::Item::Vector::iterator old_it = |
+ std::find_if(raster_tasks_.items.begin(), |
+ raster_tasks_.items.end(), |
+ RasterTaskQueue::Item::TaskComparator(task)); |
+ if (old_it != raster_tasks_.items.end()) { |
+ std::swap(*old_it, raster_tasks_.items.back()); |
+ raster_tasks_.items.pop_back(); |
+ } |
+ |
+ RasterTaskState::Vector::iterator state_it = |
+ std::find_if(raster_task_states_.begin(), |
+ raster_task_states_.end(), |
+ RasterTaskState::TaskComparator(task)); |
if (state_it != raster_task_states_.end()) { |
- const RasterTaskState& state = state_it->second; |
+ RasterTaskState& state = *state_it; |
- new_raster_task_states[task] = |
- RasterTaskState(state) |
- .set_required_for_activation(item.required_for_activation); |
+ state.required_for_activation = item.required_for_activation; |
// |raster_tasks_required_for_activation_count| accounts for 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 count. |
@@ -129,26 +141,33 @@ void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) { |
raster_tasks_required_for_activation_count_ += |
item.required_for_activation; |
} |
- |
- raster_task_states_.erase(state_it); |
- } else { |
- DCHECK(!task->HasBeenScheduled()); |
- new_raster_task_states[task] = |
- RasterTaskState().set_required_for_activation( |
- item.required_for_activation); |
- raster_tasks_required_for_activation_count_ += |
- item.required_for_activation; |
+ continue; |
} |
+ |
+ DCHECK(!task->HasBeenScheduled()); |
+ raster_task_states_.push_back( |
+ RasterTaskState(task, item.required_for_activation)); |
+ raster_tasks_required_for_activation_count_ += item.required_for_activation; |
} |
- // Transfer old raster task state to |new_raster_task_states| and cancel all |
- // remaining unscheduled tasks. |
- for (RasterTaskStateMap::const_iterator it = raster_task_states_.begin(); |
- it != raster_task_states_.end(); |
+ // Determine what tasks in old queue need to be canceled. |
+ for (RasterTaskQueue::Item::Vector::const_iterator it = |
+ raster_tasks_.items.begin(); |
+ it != raster_tasks_.items.end(); |
++it) { |
- internal::WorkerPoolTask* task = it->first; |
- const RasterTaskState& state = it->second; |
- DCHECK(new_raster_task_states.find(task) == new_raster_task_states.end()); |
+ const RasterTaskQueue::Item& item = *it; |
+ internal::WorkerPoolTask* task = item.task; |
+ |
+ RasterTaskState::Vector::iterator state_it = |
+ std::find_if(raster_task_states_.begin(), |
+ raster_task_states_.end(), |
+ RasterTaskState::TaskComparator(task)); |
+ // We've already processed completion if we can't find a RasterTaskState for |
+ // this task. |
+ if (state_it == raster_task_states_.end()) |
+ continue; |
+ |
+ RasterTaskState& state = *state_it; |
// Unscheduled task can be canceled. |
if (state.type == RasterTaskState::UNSCHEDULED) { |
@@ -157,17 +176,14 @@ void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) { |
completed_raster_tasks_.end(), |
task) == completed_raster_tasks_.end()); |
completed_raster_tasks_.push_back(task); |
- new_raster_task_states[task] = RasterTaskState(state).set_completed(); |
- continue; |
+ state.type = RasterTaskState::COMPLETED; |
} |
- // Move state to |new_raster_task_states|. |
- new_raster_task_states[task] = |
- RasterTaskState(state).set_required_for_activation(false); |
+ // No longer required for activation. |
+ state.required_for_activation = false; |
} |
raster_tasks_.Swap(queue); |
- 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 |
@@ -208,34 +224,43 @@ void PixelBufferRasterWorkerPool::CheckForCompletedTasks() { |
CheckForCompletedUploads(); |
FlushUploads(); |
- while (!completed_image_decode_tasks_.empty()) { |
- internal::WorkerPoolTask* task = |
- completed_image_decode_tasks_.front().get(); |
- |
+ for (TaskVector::const_iterator it = completed_image_decode_tasks_.begin(); |
+ it != completed_image_decode_tasks_.end(); |
+ ++it) { |
+ internal::WorkerPoolTask* task = it->get(); |
task->RunReplyOnOriginThread(); |
- |
- completed_image_decode_tasks_.pop_front(); |
} |
+ completed_image_decode_tasks_.clear(); |
- while (!completed_raster_tasks_.empty()) { |
- internal::WorkerPoolTask* task = completed_raster_tasks_.front().get(); |
- DCHECK(raster_task_states_.find(task) != raster_task_states_.end()); |
- DCHECK_EQ(RasterTaskState::COMPLETED, raster_task_states_[task].type); |
+ for (TaskVector::const_iterator it = completed_raster_tasks_.begin(); |
+ it != completed_raster_tasks_.end(); |
+ ++it) { |
+ internal::WorkerPoolTask* task = it->get(); |
+ RasterTaskState::Vector::iterator state_it = |
+ std::find_if(raster_task_states_.begin(), |
+ raster_task_states_.end(), |
+ RasterTaskState::TaskComparator(task)); |
+ DCHECK(state_it != raster_task_states_.end()); |
+ DCHECK_EQ(RasterTaskState::COMPLETED, state_it->type); |
- raster_task_states_.erase(task); |
+ std::swap(*state_it, raster_task_states_.back()); |
+ raster_task_states_.pop_back(); |
task->RunReplyOnOriginThread(); |
- |
- completed_raster_tasks_.pop_front(); |
} |
+ completed_raster_tasks_.clear(); |
} |
SkCanvas* PixelBufferRasterWorkerPool::AcquireCanvasForRaster( |
internal::WorkerPoolTask* task, |
const Resource* resource) { |
- DCHECK(raster_task_states_.find(task) != raster_task_states_.end()); |
- DCHECK(!raster_task_states_[task].resource); |
- raster_task_states_[task].resource = resource; |
+ RasterTaskState::Vector::iterator it = |
+ std::find_if(raster_task_states_.begin(), |
+ raster_task_states_.end(), |
+ RasterTaskState::TaskComparator(task)); |
+ DCHECK(it != raster_task_states_.end()); |
+ DCHECK(!it->resource); |
+ it->resource = resource; |
resource_provider()->AcquirePixelRasterBuffer(resource->id()); |
return resource_provider()->MapPixelRasterBuffer(resource->id()); |
} |
@@ -243,8 +268,12 @@ SkCanvas* PixelBufferRasterWorkerPool::AcquireCanvasForRaster( |
void PixelBufferRasterWorkerPool::ReleaseCanvasForRaster( |
internal::WorkerPoolTask* task, |
const Resource* resource) { |
- DCHECK(raster_task_states_.find(task) != raster_task_states_.end()); |
- DCHECK(raster_task_states_[task].resource == resource); |
+ RasterTaskState::Vector::iterator it = |
+ std::find_if(raster_task_states_.begin(), |
+ raster_task_states_.end(), |
+ RasterTaskState::TaskComparator(task)); |
+ DCHECK(it != raster_task_states_.end()); |
+ DCHECK(it->resource == resource); |
resource_provider()->ReleasePixelRasterBuffer(resource->id()); |
} |
@@ -285,18 +314,21 @@ void PixelBufferRasterWorkerPool::FlushUploads() { |
} |
void PixelBufferRasterWorkerPool::CheckForCompletedUploads() { |
- TaskDeque tasks_with_completed_uploads; |
+ TaskVector tasks_with_completed_uploads; |
// First check if any have completed. |
while (!raster_tasks_with_pending_upload_.empty()) { |
internal::WorkerPoolTask* task = |
raster_tasks_with_pending_upload_.front().get(); |
- DCHECK(raster_task_states_.find(task) != raster_task_states_.end()); |
- const RasterTaskState& state = raster_task_states_[task]; |
- DCHECK_EQ(RasterTaskState::UPLOADING, state.type); |
+ RasterTaskState::Vector::const_iterator it = |
+ std::find_if(raster_task_states_.begin(), |
+ raster_task_states_.end(), |
+ RasterTaskState::TaskComparator(task)); |
+ DCHECK(it != raster_task_states_.end()); |
+ DCHECK_EQ(RasterTaskState::UPLOADING, it->type); |
// Uploads complete in the order they are issued. |
- if (!resource_provider()->DidSetPixelsComplete(state.resource->id())) |
+ if (!resource_provider()->DidSetPixelsComplete(it->resource->id())) |
break; |
tasks_with_completed_uploads.push_back(task); |
@@ -308,16 +340,19 @@ void PixelBufferRasterWorkerPool::CheckForCompletedUploads() { |
shutdown_ || client()->ShouldForceTasksRequiredForActivationToComplete(); |
if (should_force_some_uploads_to_complete) { |
- TaskDeque tasks_with_uploads_to_force; |
+ TaskVector tasks_with_uploads_to_force; |
TaskDeque::iterator it = raster_tasks_with_pending_upload_.begin(); |
while (it != raster_tasks_with_pending_upload_.end()) { |
internal::WorkerPoolTask* task = it->get(); |
- DCHECK(raster_task_states_.find(task) != raster_task_states_.end()); |
- const RasterTaskState& state = raster_task_states_[task]; |
+ RasterTaskState::Vector::const_iterator state_it = |
+ std::find_if(raster_task_states_.begin(), |
+ raster_task_states_.end(), |
+ RasterTaskState::TaskComparator(task)); |
+ DCHECK(state_it != raster_task_states_.end()); |
// Force all uploads required for activation to complete. |
// During shutdown, force all pending uploads to complete. |
- if (shutdown_ || state.required_for_activation) { |
+ if (shutdown_ || state_it->required_for_activation) { |
tasks_with_uploads_to_force.push_back(task); |
tasks_with_completed_uploads.push_back(task); |
it = raster_tasks_with_pending_upload_.erase(it); |
@@ -329,23 +364,34 @@ void PixelBufferRasterWorkerPool::CheckForCompletedUploads() { |
// Force uploads in reverse order. Since forcing can cause a wait on |
// all previous uploads, we would rather wait only once downstream. |
- for (TaskDeque::reverse_iterator it = tasks_with_uploads_to_force.rbegin(); |
+ for (TaskVector::reverse_iterator it = tasks_with_uploads_to_force.rbegin(); |
it != tasks_with_uploads_to_force.rend(); |
++it) { |
internal::WorkerPoolTask* task = it->get(); |
- const RasterTaskState& state = raster_task_states_[task]; |
- DCHECK(state.resource); |
- |
- resource_provider()->ForceSetPixelsToComplete(state.resource->id()); |
+ RasterTaskState::Vector::const_iterator state_it = |
+ std::find_if(raster_task_states_.begin(), |
+ raster_task_states_.end(), |
+ RasterTaskState::TaskComparator(task)); |
+ DCHECK(state_it != raster_task_states_.end()); |
+ DCHECK(state_it->resource); |
+ |
+ resource_provider()->ForceSetPixelsToComplete(state_it->resource->id()); |
has_performed_uploads_since_last_flush_ = true; |
} |
} |
// Release shared memory and move tasks with completed uploads |
// to |completed_raster_tasks_|. |
- while (!tasks_with_completed_uploads.empty()) { |
- internal::WorkerPoolTask* task = tasks_with_completed_uploads.front().get(); |
- RasterTaskState& state = raster_task_states_[task]; |
+ for (TaskVector::const_iterator it = tasks_with_completed_uploads.begin(); |
+ it != tasks_with_completed_uploads.end(); |
+ ++it) { |
+ internal::WorkerPoolTask* task = it->get(); |
+ RasterTaskState::Vector::iterator state_it = |
+ std::find_if(raster_task_states_.begin(), |
+ raster_task_states_.end(), |
+ RasterTaskState::TaskComparator(task)); |
+ DCHECK(state_it != raster_task_states_.end()); |
+ RasterTaskState& state = *state_it; |
bytes_pending_upload_ -= state.resource->bytes(); |
@@ -362,8 +408,6 @@ void PixelBufferRasterWorkerPool::CheckForCompletedUploads() { |
raster_tasks_required_for_activation_count_); |
raster_tasks_required_for_activation_count_ -= |
state.required_for_activation; |
- |
- tasks_with_completed_uploads.pop_front(); |
} |
} |
@@ -487,11 +531,14 @@ void PixelBufferRasterWorkerPool::ScheduleMoreTasks() { |
// |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); |
+ RasterTaskState::Vector::iterator state_it = |
+ std::find_if(raster_task_states_.begin(), |
+ raster_task_states_.end(), |
+ RasterTaskState::TaskComparator(task)); |
if (state_it == raster_task_states_.end()) |
continue; |
- RasterTaskState& state = state_it->second; |
+ RasterTaskState& state = *state_it; |
// Skip task if completed. |
if (state.type == RasterTaskState::COMPLETED) { |
@@ -636,7 +683,10 @@ void PixelBufferRasterWorkerPool::CheckForCompletedWorkerPoolTasks() { |
internal::WorkerPoolTask* task = |
static_cast<internal::WorkerPoolTask*>(it->get()); |
- RasterTaskStateMap::iterator state_it = raster_task_states_.find(task); |
+ RasterTaskState::Vector::iterator state_it = |
+ std::find_if(raster_task_states_.begin(), |
+ raster_task_states_.end(), |
+ RasterTaskState::TaskComparator(task)); |
if (state_it == raster_task_states_.end()) { |
task->WillComplete(); |
task->CompleteOnOriginThread(this); |
@@ -646,7 +696,7 @@ void PixelBufferRasterWorkerPool::CheckForCompletedWorkerPoolTasks() { |
continue; |
} |
- RasterTaskState& state = state_it->second; |
+ RasterTaskState& state = *state_it; |
DCHECK_EQ(RasterTaskState::SCHEDULED, state.type); |
DCHECK(state.resource); |