Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / cc / resources / pixel_buffer_raster_worker_pool.cc
index bbdc31e..21ee1cc 100644 (file)
@@ -9,87 +9,39 @@
 #include "base/values.h"
 #include "cc/debug/traced_value.h"
 #include "cc/resources/resource.h"
-#include "third_party/skia/include/core/SkBitmapDevice.h"
-
-#if defined(OS_ANDROID)
-#include "base/android/sys_utils.h"
-#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;
 
-typedef base::StackVector<internal::GraphNode*, kMaxScheduledRasterTasks>
-    NodeVector;
-
-void AddDependenciesToGraphNode(internal::GraphNode* node,
-                                const NodeVector::ContainerType& dependencies) {
-  for (NodeVector::ContainerType::const_iterator it = dependencies.begin();
-       it != dependencies.end();
-       ++it) {
-    internal::GraphNode* dependency = *it;
-
-    node->add_dependency();
-    dependency->add_dependent(node);
-  }
-}
+typedef base::StackVector<internal::WorkerPoolTask*, kMaxScheduledRasterTasks>
+    WorkerPoolTaskVector;
 
 // Only used as std::find_if predicate for DCHECKs.
 bool WasCanceled(const internal::RasterWorkerPoolTask* task) {
-  return task->WasCanceled();
+  return !task->HasFinishedRunning();
 }
 
 }  // namespace
 
+// static
+scoped_ptr<RasterWorkerPool> PixelBufferRasterWorkerPool::Create(
+    ResourceProvider* resource_provider,
+    size_t max_transfer_buffer_usage_bytes) {
+  return make_scoped_ptr<RasterWorkerPool>(
+      new PixelBufferRasterWorkerPool(GetTaskGraphRunner(),
+                                      resource_provider,
+                                      max_transfer_buffer_usage_bytes));
+}
+
 PixelBufferRasterWorkerPool::PixelBufferRasterWorkerPool(
+    internal::TaskGraphRunner* task_graph_runner,
     ResourceProvider* resource_provider,
-    ContextProvider* context_provider,
     size_t max_transfer_buffer_usage_bytes)
-    : RasterWorkerPool(resource_provider, context_provider),
+    : RasterWorkerPool(task_graph_runner, resource_provider),
       shutdown_(false),
       scheduled_raster_task_count_(0),
       bytes_pending_upload_(0),
@@ -100,14 +52,16 @@ PixelBufferRasterWorkerPool::PixelBufferRasterWorkerPool(
       should_notify_client_if_no_tasks_required_for_activation_are_pending_(
           false),
       raster_finished_task_pending_(false),
-      raster_required_for_activation_finished_task_pending_(false) {}
+      raster_required_for_activation_finished_task_pending_(false),
+      weak_factory_(this) {}
 
 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() {
@@ -116,92 +70,86 @@ void PixelBufferRasterWorkerPool::Shutdown() {
 
   CheckForCompletedWorkerPoolTasks();
   CheckForCompletedUploads();
-  check_for_completed_raster_tasks_callback_.Cancel();
+
+  weak_factory_.InvalidateWeakPtrs();
   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) {
   TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleTasks");
 
-  RasterWorkerPool::SetRasterTasks(queue);
-
   if (!should_notify_client_if_no_tasks_are_pending_)
     TRACE_EVENT_ASYNC_BEGIN0("cc", "ScheduledTasks", this);
 
   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();
-
-  // Build new pixel buffer task set.
-  TaskMap new_pixel_buffer_tasks;
-  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());
-
-    if (task->use_gpu_rasterization()) {
-      gpu_raster_tasks.push_back(task);
-      continue;
+  raster_tasks_required_for_activation_.clear();
+
+  // Build new raster task state map.
+  RasterTaskStateMap new_raster_task_states;
+  for (RasterTaskQueueIterator it(queue); it; ++it) {
+    internal::RasterWorkerPoolTask* task = *it;
+    DCHECK(new_raster_task_states.find(task) == new_raster_task_states.end());
+
+    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 && it.required_for_activation())
+        raster_tasks_required_for_activation_.insert(task);
+
+      raster_task_states_.erase(state_it);
+    } else {
+      DCHECK(!task->HasBeenScheduled());
+      new_raster_task_states[task] = UNSCHEDULED;
+      if (it.required_for_activation())
+        raster_tasks_required_for_activation_.insert(task);
     }
-
-    new_pixel_buffer_tasks[task] = pixel_buffer_tasks_[task];
-    pixel_buffer_tasks_.erase(task);
-
-    if (IsRasterTaskRequiredForActivation(task))
-      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());
+
+    // Unscheduled task can be canceled.
+    if (it->second == UNSCHEDULED) {
+      DCHECK(!task->HasBeenScheduled());
+      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_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
@@ -215,12 +163,9 @@ void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTask::Queue* queue) {
 
   // Cancel any pending check for completed raster tasks and schedule
   // another check.
-  check_for_completed_raster_tasks_callback_.Cancel();
-  check_for_completed_raster_tasks_pending_ = false;
+  check_for_completed_raster_tasks_time_ = base::TimeTicks();
   ScheduleCheckForCompletedRasterTasks();
 
-  RunGpuRasterTasks(gpu_raster_tasks);
-
   TRACE_EVENT_ASYNC_STEP_INTO1(
       "cc",
       "ScheduledTasks",
@@ -241,25 +186,92 @@ 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]);
+
+    raster_task_states_.erase(task);
+
+    task->RunReplyOnOriginThread();
+
+    completed_raster_tasks_.pop_front();
+  }
+}
+
+SkCanvas* PixelBufferRasterWorkerPool::AcquireCanvasForRaster(
+    internal::RasterWorkerPoolTask* task) {
+  resource_provider()->AcquirePixelRasterBuffer(task->resource()->id());
+  return resource_provider()->MapPixelRasterBuffer(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 MapPixelRasterBuffer() call in AcquireCanvasForRaster().
+  resource_provider()->UnmapPixelRasterBuffer(task->resource()->id());
 
-    completed_tasks.pop_front();
+  if (!task->HasFinishedRunning() || analysis.is_solid_color) {
+    resource_provider()->ReleasePixelRasterBuffer(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.
+      for (RasterTaskQueueIterator it(&raster_tasks_); it; ++it) {
+        if (*it == task) {
+          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 +314,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 +334,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,50 +363,75 @@ 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();
 
     // It's now safe to release the pixel buffer and the shared memory.
-    resource_provider()->ReleasePixelBuffer(task->resource()->id());
+    resource_provider()->ReleasePixelRasterBuffer(task->resource()->id());
 
     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();
   }
 }
 
 void PixelBufferRasterWorkerPool::ScheduleCheckForCompletedRasterTasks() {
+  base::TimeDelta delay =
+      base::TimeDelta::FromMilliseconds(kCheckForCompletedRasterTasksDelayMs);
+  if (check_for_completed_raster_tasks_time_.is_null())
+    check_for_completed_raster_tasks_time_ = base::TimeTicks::Now() + delay;
+
   if (check_for_completed_raster_tasks_pending_)
     return;
 
-  check_for_completed_raster_tasks_callback_.Reset(
-      base::Bind(&PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks,
-                 base::Unretained(this)));
   base::MessageLoopProxy::current()->PostDelayedTask(
       FROM_HERE,
-      check_for_completed_raster_tasks_callback_.callback(),
-      base::TimeDelta::FromMilliseconds(kCheckForCompletedRasterTasksDelayMs));
+      base::Bind(&PixelBufferRasterWorkerPool::OnCheckForCompletedRasterTasks,
+                 weak_factory_.GetWeakPtr()),
+      delay);
   check_for_completed_raster_tasks_pending_ = true;
 }
 
+void PixelBufferRasterWorkerPool::OnCheckForCompletedRasterTasks() {
+  if (check_for_completed_raster_tasks_time_.is_null()) {
+    check_for_completed_raster_tasks_pending_ = false;
+    return;
+  }
+
+  base::TimeDelta delay =
+      check_for_completed_raster_tasks_time_ - base::TimeTicks::Now();
+
+  // Post another delayed task if it is not yet time to check for completed
+  // raster tasks.
+  if (delay > base::TimeDelta()) {
+    base::MessageLoopProxy::current()->PostDelayedTask(
+        FROM_HERE,
+        base::Bind(&PixelBufferRasterWorkerPool::OnCheckForCompletedRasterTasks,
+                   weak_factory_.GetWeakPtr()),
+        delay);
+    return;
+  }
+
+  check_for_completed_raster_tasks_pending_ = false;
+  CheckForCompletedRasterTasks();
+}
+
 void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() {
   TRACE_EVENT0("cc",
                "PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks");
 
   DCHECK(should_notify_client_if_no_tasks_are_pending_);
-
-  check_for_completed_raster_tasks_callback_.Cancel();
-  check_for_completed_raster_tasks_pending_ = false;
+  check_for_completed_raster_tasks_time_ = base::TimeTicks();
 
   CheckForCompletedWorkerPoolTasks();
   CheckForCompletedUploads();
@@ -405,6 +444,7 @@ void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() {
        !HasPendingTasksRequiredForActivation());
   bool will_notify_client_that_no_tasks_are_pending =
       (should_notify_client_if_no_tasks_are_pending_ &&
+       !raster_required_for_activation_finished_task_pending_ &&
        !raster_finished_task_pending_ && !HasPendingTasks());
 
   // Adjust the need to generate notifications before scheduling more tasks.
@@ -432,10 +472,10 @@ void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() {
 
   // Generate client notifications.
   if (will_notify_client_that_no_tasks_required_for_activation_are_pending) {
-    DCHECK(std::find_if(raster_tasks_required_for_activation().begin(),
-                        raster_tasks_required_for_activation().end(),
+    DCHECK(std::find_if(raster_tasks_required_for_activation_.begin(),
+                        raster_tasks_required_for_activation_.end(),
                         WasCanceled) ==
-           raster_tasks_required_for_activation().end());
+           raster_tasks_required_for_activation_.end());
     client()->DidFinishRunningTasksRequiredForActivation();
   }
   if (will_notify_client_that_no_tasks_are_pending) {
@@ -448,33 +488,30 @@ void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() {
 void PixelBufferRasterWorkerPool::ScheduleMoreTasks() {
   TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleMoreTasks");
 
-  enum RasterTaskType {
-    PREPAINT_TYPE = 0,
-    REQUIRED_FOR_ACTIVATION_TYPE = 1,
-    NUM_TYPES = 2
-  };
-  NodeVector tasks[NUM_TYPES];
-  unsigned priority = 2u;  // 0-1 reserved for RasterFinished tasks.
-  TaskGraph graph;
+  WorkerPoolTaskVector tasks;
+  WorkerPoolTaskVector tasks_required_for_activation;
+
+  unsigned priority = kRasterTaskPriorityBase;
+
+  graph_.Reset();
 
   size_t bytes_pending_upload = bytes_pending_upload_;
   bool did_throttle_raster_tasks = false;
 
-  for (RasterTaskVector::const_iterator it = raster_tasks().begin();
-       it != raster_tasks().end();
-       ++it) {
-    internal::RasterWorkerPoolTask* task = it->get();
+  for (RasterTaskQueueIterator it(&raster_tasks_); it; ++it) {
+    internal::RasterWorkerPoolTask* task = *it;
 
-    // |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,19 +523,15 @@ 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) {
+      DCHECK(task->HasCompleted());
       bytes_pending_upload = new_bytes_pending_upload;
       continue;
     }
 
     // Throttle raster tasks based on kMaxScheduledRasterTasks.
-    size_t scheduled_raster_task_count =
-        tasks[PREPAINT_TYPE].container().size() +
-        tasks[REQUIRED_FOR_ACTIVATION_TYPE].container().size();
-    if (scheduled_raster_task_count >= kMaxScheduledRasterTasks) {
+    if (tasks.container().size() >= kMaxScheduledRasterTasks) {
       did_throttle_raster_tasks = true;
       break;
     }
@@ -507,68 +540,49 @@ void PixelBufferRasterWorkerPool::ScheduleMoreTasks() {
     // throttling limits.
     bytes_pending_upload = new_bytes_pending_upload;
 
-    RasterTaskType type = IsRasterTaskRequiredForActivation(task)
-                              ? REQUIRED_FOR_ACTIVATION_TYPE
-                              : PREPAINT_TYPE;
+    DCHECK(state_it->second == UNSCHEDULED || state_it->second == SCHEDULED);
+    state_it->second = SCHEDULED;
 
-    // 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;
-    }
+    InsertNodeForRasterTask(&graph_, task, task->dependencies(), priority++);
 
-    // 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));
+    tasks.container().push_back(task);
+    if (it.required_for_activation())
+      tasks_required_for_activation.container().push_back(task);
   }
 
   scoped_refptr<internal::WorkerPoolTask>
       new_raster_required_for_activation_finished_task;
 
   size_t scheduled_raster_task_required_for_activation_count =
-      tasks[REQUIRED_FOR_ACTIVATION_TYPE].container().size();
+      tasks_required_for_activation.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(
-            new_raster_required_for_activation_finished_task.get(),
-            0u,  // Priority 0
-            &graph);
-    AddDependenciesToGraphNode(raster_required_for_activation_finished_node,
-                               tasks[REQUIRED_FOR_ACTIVATION_TYPE].container());
+    InsertNodeForTask(&graph_,
+                      new_raster_required_for_activation_finished_task.get(),
+                      kRasterRequiredForActivationFinishedTaskPriority,
+                      scheduled_raster_task_required_for_activation_count);
+    for (WorkerPoolTaskVector::ContainerType::const_iterator it =
+             tasks_required_for_activation.container().begin();
+         it != tasks_required_for_activation.container().end();
+         ++it) {
+      graph_.edges.push_back(internal::TaskGraph::Edge(
+          *it, new_raster_required_for_activation_finished_task.get()));
+    }
   }
 
   scoped_refptr<internal::WorkerPoolTask> new_raster_finished_task;
 
-  size_t scheduled_raster_task_count =
-      tasks[PREPAINT_TYPE].container().size() +
-      tasks[REQUIRED_FOR_ACTIVATION_TYPE].container().size();
+  size_t scheduled_raster_task_count = tasks.container().size();
   DCHECK_LE(scheduled_raster_task_count, PendingRasterTaskCount());
   // Schedule OnRasterTasksFinished call only when notification is pending
   // and throttling is not preventing all pending tasks from being scheduled.
@@ -576,16 +590,20 @@ void PixelBufferRasterWorkerPool::ScheduleMoreTasks() {
       should_notify_client_if_no_tasks_are_pending_) {
     new_raster_finished_task = CreateRasterFinishedTask();
     raster_finished_task_pending_ = true;
-    internal::GraphNode* raster_finished_node =
-        CreateGraphNodeForTask(new_raster_finished_task.get(),
-                               1u,  // Priority 1
-                               &graph);
-    for (unsigned type = 0; type < NUM_TYPES; ++type) {
-      AddDependenciesToGraphNode(raster_finished_node, tasks[type].container());
+    InsertNodeForTask(&graph_,
+                      new_raster_finished_task.get(),
+                      kRasterFinishedTaskPriority,
+                      scheduled_raster_task_count);
+    for (WorkerPoolTaskVector::ContainerType::const_iterator it =
+             tasks.container().begin();
+         it != tasks.container().end();
+         ++it) {
+      graph_.edges.push_back(
+          internal::TaskGraph::Edge(*it, new_raster_finished_task.get()));
     }
   }
 
-  SetTaskGraph(&graph);
+  SetTaskGraph(&graph_);
 
   scheduled_raster_task_count_ = scheduled_raster_task_count;
 
@@ -594,68 +612,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,21 +632,42 @@ 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() {
+  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();
+  }
+  completed_tasks_.clear();
+}
+
+bool PixelBufferRasterWorkerPool::IsRasterTaskRequiredForActivation(
+    internal::RasterWorkerPoolTask* task) const {
+  return raster_tasks_required_for_activation_.find(task) !=
+         raster_tasks_required_for_activation_.end();
+}
+
 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("required_for_activation_count",
-                    tasks_required_for_activation_.size());
-  state->Set("scheduled_state", ScheduledStateAsValue().release());
+  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("pending_required_for_activation_count",
+                    raster_tasks_required_for_activation_.size());
   state->Set("throttle_state", ThrottleStateAsValue().release());
   return state.PassAs<base::Value>();
 }