Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / cc / resources / pixel_buffer_raster_worker_pool.cc
index 67ae593..b1011fc 100644 (file)
@@ -9,13 +9,59 @@
 #include "base/containers/stack_container.h"
 #include "base/debug/trace_event.h"
 #include "base/debug/trace_event_argument.h"
+#include "base/strings/stringprintf.h"
 #include "cc/debug/traced_value.h"
+#include "cc/resources/raster_buffer.h"
 #include "cc/resources/resource.h"
 #include "gpu/command_buffer/client/gles2_interface.h"
+#include "third_party/skia/include/utils/SkNullCanvas.h"
 
 namespace cc {
 namespace {
 
+class RasterBufferImpl : public RasterBuffer {
+ public:
+  RasterBufferImpl(ResourceProvider* resource_provider,
+                   const Resource* resource)
+      : resource_provider_(resource_provider),
+        resource_(resource),
+        buffer_(NULL),
+        stride_(0) {
+    resource_provider_->AcquirePixelBuffer(resource_->id());
+    buffer_ = resource_provider_->MapPixelBuffer(resource_->id(), &stride_);
+  }
+
+  virtual ~RasterBufferImpl() {
+    resource_provider_->ReleasePixelBuffer(resource_->id());
+  }
+
+  // Overridden from RasterBuffer:
+  virtual skia::RefPtr<SkCanvas> AcquireSkCanvas() OVERRIDE {
+    if (!buffer_)
+      return skia::AdoptRef(SkCreateNullCanvas());
+
+    RasterWorkerPool::AcquireBitmapForBuffer(
+        &bitmap_, buffer_, resource_->format(), resource_->size(), stride_);
+    return skia::AdoptRef(new SkCanvas(bitmap_));
+  }
+  virtual void ReleaseSkCanvas(const skia::RefPtr<SkCanvas>& canvas) OVERRIDE {
+    if (!buffer_)
+      return;
+
+    RasterWorkerPool::ReleaseBitmapForBuffer(
+        &bitmap_, buffer_, resource_->format());
+  }
+
+ private:
+  ResourceProvider* resource_provider_;
+  const Resource* resource_;
+  uint8_t* buffer_;
+  int stride_;
+  SkBitmap bitmap_;
+
+  DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl);
+};
+
 const int kCheckForCompletedRasterTasksDelayMs = 6;
 
 const size_t kMaxScheduledRasterTasks = 48;
@@ -23,8 +69,39 @@ const size_t kMaxScheduledRasterTasks = 48;
 typedef base::StackVector<RasterTask*, kMaxScheduledRasterTasks>
     RasterTaskVector;
 
+TaskSetCollection NonEmptyTaskSetsFromTaskCounts(const size_t* task_counts) {
+  TaskSetCollection task_sets;
+  for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) {
+    if (task_counts[task_set])
+      task_sets[task_set] = true;
+  }
+  return task_sets;
+}
+
+void AddTaskSetsToTaskCounts(size_t* task_counts,
+                             const TaskSetCollection& task_sets) {
+  for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) {
+    if (task_sets[task_set])
+      task_counts[task_set]++;
+  }
+}
+
+void RemoveTaskSetsFromTaskCounts(size_t* task_counts,
+                                  const TaskSetCollection& task_sets) {
+  for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) {
+    if (task_sets[task_set])
+      task_counts[task_set]--;
+  }
+}
+
 }  // namespace
 
+PixelBufferRasterWorkerPool::RasterTaskState::RasterTaskState(
+    RasterTask* task,
+    const TaskSetCollection& task_sets)
+    : type(UNSCHEDULED), task(task), task_sets(task_sets) {
+}
+
 // static
 scoped_ptr<RasterWorkerPool> PixelBufferRasterWorkerPool::Create(
     base::SequencedTaskRunner* task_runner,
@@ -53,15 +130,9 @@ PixelBufferRasterWorkerPool::PixelBufferRasterWorkerPool(
       resource_provider_(resource_provider),
       shutdown_(false),
       scheduled_raster_task_count_(0u),
-      raster_tasks_required_for_activation_count_(0u),
       bytes_pending_upload_(0u),
       max_bytes_pending_upload_(max_transfer_buffer_usage_bytes),
       has_performed_uploads_since_last_flush_(false),
-      should_notify_client_if_no_tasks_are_pending_(false),
-      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),
       check_for_completed_raster_task_notifier_(
           task_runner,
           base::Bind(&PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks,
@@ -70,6 +141,7 @@ PixelBufferRasterWorkerPool::PixelBufferRasterWorkerPool(
               kCheckForCompletedRasterTasksDelayMs)),
       raster_finished_weak_ptr_factory_(this) {
   DCHECK(context_provider_);
+  std::fill(task_counts_, task_counts_ + kNumberOfTaskSets, 0);
 }
 
 PixelBufferRasterWorkerPool::~PixelBufferRasterWorkerPool() {
@@ -77,7 +149,7 @@ PixelBufferRasterWorkerPool::~PixelBufferRasterWorkerPool() {
   DCHECK_EQ(0u, raster_tasks_with_pending_upload_.size());
   DCHECK_EQ(0u, completed_raster_tasks_.size());
   DCHECK_EQ(0u, completed_image_decode_tasks_.size());
-  DCHECK_EQ(0u, raster_tasks_required_for_activation_count_);
+  DCHECK(NonEmptyTaskSetsFromTaskCounts(task_counts_).none());
 }
 
 Rasterizer* PixelBufferRasterWorkerPool::AsRasterizer() { return this; }
@@ -117,19 +189,11 @@ void PixelBufferRasterWorkerPool::Shutdown() {
 void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) {
   TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleTasks");
 
-  DCHECK_EQ(queue->required_for_activation_count,
-            static_cast<size_t>(
-                std::count_if(queue->items.begin(),
-                              queue->items.end(),
-                              RasterTaskQueue::Item::IsRequiredForActivation)));
-
-  if (!should_notify_client_if_no_tasks_are_pending_)
+  if (should_notify_client_if_no_tasks_are_pending_.none())
     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;
-
-  raster_tasks_required_for_activation_count_ = 0u;
+  should_notify_client_if_no_tasks_are_pending_.set();
+  std::fill(task_counts_, task_counts_ + kNumberOfTaskSets, 0);
 
   // Update raster task state and remove items from old queue.
   for (RasterTaskQueue::Item::Vector::const_iterator it = queue->items.begin();
@@ -157,21 +221,19 @@ void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) {
     if (state_it != raster_task_states_.end()) {
       RasterTaskState& state = *state_it;
 
-      state.required_for_activation = item.required_for_activation;
+      state.task_sets = item.task_sets;
       // |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.
-      if (state.type != RasterTaskState::COMPLETED) {
-        raster_tasks_required_for_activation_count_ +=
-            item.required_for_activation;
-      }
+      if (state.type != RasterTaskState::COMPLETED)
+        AddTaskSetsToTaskCounts(task_counts_, item.task_sets);
+
       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;
+    raster_task_states_.push_back(RasterTaskState(task, item.task_sets));
+    AddTaskSetsToTaskCounts(task_counts_, item.task_sets);
   }
 
   // Determine what tasks in old queue need to be canceled.
@@ -203,8 +265,8 @@ void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) {
       state.type = RasterTaskState::COMPLETED;
     }
 
-    // No longer required for activation.
-    state.required_for_activation = false;
+    // No longer in any task set.
+    state.task_sets.reset();
   }
 
   raster_tasks_.Swap(queue);
@@ -261,51 +323,30 @@ void PixelBufferRasterWorkerPool::CheckForCompletedTasks() {
   completed_raster_tasks_.clear();
 }
 
-SkCanvas* PixelBufferRasterWorkerPool::AcquireCanvasForRaster(
-    RasterTask* task) {
-  DCHECK(std::find_if(raster_task_states_.begin(),
-                      raster_task_states_.end(),
-                      RasterTaskState::TaskComparator(task)) !=
-         raster_task_states_.end());
-  resource_provider_->AcquirePixelRasterBuffer(task->resource()->id());
-  return resource_provider_->MapPixelRasterBuffer(task->resource()->id());
-}
-
-void PixelBufferRasterWorkerPool::ReleaseCanvasForRaster(RasterTask* task) {
-  DCHECK(std::find_if(raster_task_states_.begin(),
-                      raster_task_states_.end(),
-                      RasterTaskState::TaskComparator(task)) !=
-         raster_task_states_.end());
-  resource_provider_->ReleasePixelRasterBuffer(task->resource()->id());
+scoped_ptr<RasterBuffer> PixelBufferRasterWorkerPool::AcquireBufferForRaster(
+    const Resource* resource) {
+  return make_scoped_ptr<RasterBuffer>(
+      new RasterBufferImpl(resource_provider_, resource));
 }
 
-void PixelBufferRasterWorkerPool::OnRasterFinished() {
-  TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::OnRasterFinished");
-
-  // |should_notify_client_if_no_tasks_are_pending_| can be set to false as
-  // a result of a scheduled CheckForCompletedRasterTasks() call. No need to
-  // perform another check in that case as we've already notified the client.
-  if (!should_notify_client_if_no_tasks_are_pending_)
-    return;
-  raster_finished_task_pending_ = false;
-
-  // Call CheckForCompletedRasterTasks() when we've finished running all
-  // raster tasks needed since last time ScheduleTasks() was called.
-  // This reduces latency between the time when all tasks have finished
-  // running and the time when the client is notified.
-  CheckForCompletedRasterTasks();
+void PixelBufferRasterWorkerPool::ReleaseBufferForRaster(
+    scoped_ptr<RasterBuffer> buffer) {
+  // Nothing to do here. RasterBufferImpl destructor cleans up after itself.
 }
 
-void PixelBufferRasterWorkerPool::OnRasterRequiredForActivationFinished() {
-  TRACE_EVENT0(
-      "cc",
-      "PixelBufferRasterWorkerPool::OnRasterRequiredForActivationFinished");
-
-  // Analogous to OnRasterTasksFinished(), there's no need to call
-  // CheckForCompletedRasterTasks() if the client has already been notified.
-  if (!should_notify_client_if_no_tasks_required_for_activation_are_pending_)
+void PixelBufferRasterWorkerPool::OnRasterFinished(TaskSet task_set) {
+  TRACE_EVENT2("cc",
+               "PixelBufferRasterWorkerPool::OnRasterFinished",
+               "task_set",
+               task_set,
+               "should_notify_client_if_no_tasks_are_pending",
+               should_notify_client_if_no_tasks_are_pending_[task_set]);
+
+  // There's no need to call CheckForCompletedRasterTasks() if the client has
+  // already been notified.
+  if (!should_notify_client_if_no_tasks_are_pending_[task_set])
     return;
-  raster_required_for_activation_finished_task_pending_ = false;
+  raster_finished_tasks_pending_[task_set] = false;
 
   // This reduces latency between the time when all tasks required for
   // activation have finished running and the time when the client is
@@ -345,8 +386,10 @@ void PixelBufferRasterWorkerPool::CheckForCompletedUploads() {
   }
 
   DCHECK(client_);
+  TaskSetCollection tasks_that_should_be_forced_to_complete =
+      client_->TasksThatShouldBeForcedToComplete();
   bool should_force_some_uploads_to_complete =
-      shutdown_ || client_->ShouldForceTasksRequiredForActivationToComplete();
+      shutdown_ || tasks_that_should_be_forced_to_complete.any();
 
   if (should_force_some_uploads_to_complete) {
     RasterTask::Vector tasks_with_uploads_to_force;
@@ -360,9 +403,10 @@ void PixelBufferRasterWorkerPool::CheckForCompletedUploads() {
       DCHECK(state_it != raster_task_states_.end());
       const RasterTaskState& state = *state_it;
 
-      // Force all uploads required for activation to complete.
+      // Force all uploads to complete for which the client requests to do so.
       // During shutdown, force all pending uploads to complete.
-      if (shutdown_ || state.required_for_activation) {
+      if (shutdown_ ||
+          (state.task_sets & tasks_that_should_be_forced_to_complete).any()) {
         tasks_with_uploads_to_force.push_back(task);
         tasks_with_completed_uploads.push_back(task);
         it = raster_tasks_with_pending_upload_.erase(it);
@@ -415,10 +459,10 @@ void PixelBufferRasterWorkerPool::CheckForCompletedUploads() {
                      task) == completed_raster_tasks_.end());
     completed_raster_tasks_.push_back(task);
     state.type = RasterTaskState::COMPLETED;
-    DCHECK_LE(static_cast<size_t>(state.required_for_activation),
-              raster_tasks_required_for_activation_count_);
-    raster_tasks_required_for_activation_count_ -=
-        state.required_for_activation;
+    // Triggers if the current task belongs to a set that should be empty.
+    DCHECK((state.task_sets & ~NonEmptyTaskSetsFromTaskCounts(task_counts_))
+               .none());
+    RemoveTaskSetsFromTaskCounts(task_counts_, state.task_sets);
   }
 }
 
@@ -429,27 +473,20 @@ void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() {
   // Since this function can be called directly, cancel any pending checks.
   check_for_completed_raster_task_notifier_.Cancel();
 
-  DCHECK(should_notify_client_if_no_tasks_are_pending_);
+  DCHECK(should_notify_client_if_no_tasks_are_pending_.any());
 
   CheckForCompletedRasterizerTasks();
   CheckForCompletedUploads();
   FlushUploads();
 
   // Determine what client notifications to generate.
-  bool will_notify_client_that_no_tasks_required_for_activation_are_pending =
-      (should_notify_client_if_no_tasks_required_for_activation_are_pending_ &&
-       !raster_required_for_activation_finished_task_pending_ &&
-       !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());
+  TaskSetCollection will_notify_client_that_no_tasks_are_pending =
+      should_notify_client_if_no_tasks_are_pending_ &
+      ~raster_finished_tasks_pending_ & ~PendingTasks();
 
   // Adjust the need to generate notifications before scheduling more tasks.
-  should_notify_client_if_no_tasks_required_for_activation_are_pending_ &=
-      !will_notify_client_that_no_tasks_required_for_activation_are_pending;
   should_notify_client_if_no_tasks_are_pending_ &=
-      !will_notify_client_that_no_tasks_are_pending;
+      ~will_notify_client_that_no_tasks_are_pending;
 
   scheduled_raster_task_count_ = 0;
   if (PendingRasterTaskCount())
@@ -460,34 +497,33 @@ void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() {
 
   // Schedule another check for completed raster tasks while there are
   // pending raster tasks or pending uploads.
-  if (HasPendingTasks())
+  if (PendingTasks().any())
     check_for_completed_raster_task_notifier_.Schedule();
 
-  // Generate client notifications.
-  if (will_notify_client_that_no_tasks_required_for_activation_are_pending) {
-    DCHECK(!HasPendingTasksRequiredForActivation());
-    client_->DidFinishRunningTasksRequiredForActivation();
-  }
-  if (will_notify_client_that_no_tasks_are_pending) {
+  if (should_notify_client_if_no_tasks_are_pending_.none())
     TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this);
-    DCHECK(!HasPendingTasksRequiredForActivation());
-    client_->DidFinishRunningTasks();
+
+  // Generate client notifications.
+  for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) {
+    if (will_notify_client_that_no_tasks_are_pending[task_set]) {
+      DCHECK(!PendingTasks()[task_set]);
+      client_->DidFinishRunningTasks(task_set);
+    }
   }
 }
 
 void PixelBufferRasterWorkerPool::ScheduleMoreTasks() {
   TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleMoreTasks");
 
-  RasterTaskVector tasks;
-  RasterTaskVector tasks_required_for_activation;
+  RasterTaskVector tasks[kNumberOfTaskSets];
 
   unsigned priority = kRasterTaskPriorityBase;
 
   graph_.Reset();
 
   size_t bytes_pending_upload = bytes_pending_upload_;
-  bool did_throttle_raster_tasks = false;
-  bool did_throttle_raster_tasks_required_for_activation = false;
+  TaskSetCollection did_throttle_raster_tasks;
+  size_t scheduled_raster_task_count = 0;
 
   for (RasterTaskQueue::Item::Vector::const_iterator it =
            raster_tasks_.items.begin();
@@ -495,6 +531,7 @@ void PixelBufferRasterWorkerPool::ScheduleMoreTasks() {
        ++it) {
     const RasterTaskQueue::Item& item = *it;
     RasterTask* task = item.task;
+    DCHECK(item.task_sets.any());
 
     // |raster_task_states_| contains the state of all tasks that we have not
     // yet run reply callbacks for.
@@ -522,9 +559,7 @@ void PixelBufferRasterWorkerPool::ScheduleMoreTasks() {
     new_bytes_pending_upload += task->resource()->bytes();
     if (new_bytes_pending_upload > max_bytes_pending_upload_ &&
         bytes_pending_upload) {
-      did_throttle_raster_tasks = true;
-      if (item.required_for_activation)
-        did_throttle_raster_tasks_required_for_activation = true;
+      did_throttle_raster_tasks |= item.task_sets;
       continue;
     }
 
@@ -536,10 +571,8 @@ void PixelBufferRasterWorkerPool::ScheduleMoreTasks() {
     }
 
     // Throttle raster tasks based on kMaxScheduledRasterTasks.
-    if (tasks.container().size() >= kMaxScheduledRasterTasks) {
-      did_throttle_raster_tasks = true;
-      if (item.required_for_activation)
-        did_throttle_raster_tasks_required_for_activation = true;
+    if (scheduled_raster_task_count >= kMaxScheduledRasterTasks) {
+      did_throttle_raster_tasks |= item.task_sets;
       continue;
     }
 
@@ -553,81 +586,57 @@ void PixelBufferRasterWorkerPool::ScheduleMoreTasks() {
 
     InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++);
 
-    tasks.container().push_back(task);
-    if (item.required_for_activation)
-      tasks_required_for_activation.container().push_back(task);
+    ++scheduled_raster_task_count;
+    for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) {
+      if (item.task_sets[task_set])
+        tasks[task_set].container().push_back(task);
+    }
   }
 
   // Cancel existing OnRasterFinished callbacks.
   raster_finished_weak_ptr_factory_.InvalidateWeakPtrs();
 
-  scoped_refptr<RasterizerTask>
-      new_raster_required_for_activation_finished_task;
-
-  size_t scheduled_raster_task_required_for_activation_count =
-      tasks_required_for_activation.container().size();
-  DCHECK_LE(scheduled_raster_task_required_for_activation_count,
-            raster_tasks_required_for_activation_count_);
-  // Schedule OnRasterTasksRequiredForActivationFinished call only when
-  // notification is pending and throttling is not preventing all pending
-  // tasks required for activation from being scheduled.
-  if (!did_throttle_raster_tasks_required_for_activation &&
-      should_notify_client_if_no_tasks_required_for_activation_are_pending_) {
-    new_raster_required_for_activation_finished_task =
-        CreateRasterRequiredForActivationFinishedTask(
-            raster_tasks_.required_for_activation_count,
-            task_runner_.get(),
-            base::Bind(&PixelBufferRasterWorkerPool::
-                           OnRasterRequiredForActivationFinished,
-                       raster_finished_weak_ptr_factory_.GetWeakPtr()));
-    raster_required_for_activation_finished_task_pending_ = true;
-    InsertNodeForTask(&graph_,
-                      new_raster_required_for_activation_finished_task.get(),
-                      kRasterRequiredForActivationFinishedTaskPriority,
-                      scheduled_raster_task_required_for_activation_count);
-    for (RasterTaskVector::ContainerType::const_iterator it =
-             tasks_required_for_activation.container().begin();
-         it != tasks_required_for_activation.container().end();
-         ++it) {
-      graph_.edges.push_back(TaskGraph::Edge(
-          *it, new_raster_required_for_activation_finished_task.get()));
+  scoped_refptr<RasterizerTask> new_raster_finished_tasks[kNumberOfTaskSets];
+  size_t scheduled_task_counts[kNumberOfTaskSets] = {0};
+
+  for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) {
+    scheduled_task_counts[task_set] = tasks[task_set].container().size();
+    DCHECK_LE(scheduled_task_counts[task_set], task_counts_[task_set]);
+    // Schedule OnRasterFinished call for task set only when notification is
+    // pending and throttling is not preventing all pending tasks in the set
+    // from being scheduled.
+    if (!did_throttle_raster_tasks[task_set] &&
+        should_notify_client_if_no_tasks_are_pending_[task_set]) {
+      new_raster_finished_tasks[task_set] = CreateRasterFinishedTask(
+          task_runner_.get(),
+          base::Bind(&PixelBufferRasterWorkerPool::OnRasterFinished,
+                     raster_finished_weak_ptr_factory_.GetWeakPtr(),
+                     task_set));
+      raster_finished_tasks_pending_[task_set] = true;
+      InsertNodeForTask(&graph_,
+                        new_raster_finished_tasks[task_set].get(),
+                        kRasterFinishedTaskPriority,
+                        scheduled_task_counts[task_set]);
+      for (RasterTaskVector::ContainerType::const_iterator it =
+               tasks[task_set].container().begin();
+           it != tasks[task_set].container().end();
+           ++it) {
+        graph_.edges.push_back(
+            TaskGraph::Edge(*it, new_raster_finished_tasks[task_set].get()));
+      }
     }
   }
 
-  scoped_refptr<RasterizerTask> new_raster_finished_task;
-
-  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.
-  if (!did_throttle_raster_tasks &&
-      should_notify_client_if_no_tasks_are_pending_) {
-    new_raster_finished_task = CreateRasterFinishedTask(
-        task_runner_.get(),
-        base::Bind(&PixelBufferRasterWorkerPool::OnRasterFinished,
-                   raster_finished_weak_ptr_factory_.GetWeakPtr()));
-    raster_finished_task_pending_ = true;
-    InsertNodeForTask(&graph_,
-                      new_raster_finished_task.get(),
-                      kRasterFinishedTaskPriority,
-                      scheduled_raster_task_count);
-    for (RasterTaskVector::ContainerType::const_iterator it =
-             tasks.container().begin();
-         it != tasks.container().end();
-         ++it) {
-      graph_.edges.push_back(
-          TaskGraph::Edge(*it, new_raster_finished_task.get()));
-    }
-  }
 
   ScheduleTasksOnOriginThread(this, &graph_);
   task_graph_runner_->ScheduleTasks(namespace_token_, &graph_);
 
   scheduled_raster_task_count_ = scheduled_raster_task_count;
 
-  raster_finished_task_ = new_raster_finished_task;
-  raster_required_for_activation_finished_task_ =
-      new_raster_required_for_activation_finished_task;
+  std::copy(new_raster_finished_tasks,
+            new_raster_finished_tasks + kNumberOfTaskSets,
+            raster_finished_tasks_);
 }
 
 unsigned PixelBufferRasterWorkerPool::PendingRasterTaskCount() const {
@@ -637,12 +646,8 @@ unsigned PixelBufferRasterWorkerPool::PendingRasterTaskCount() const {
   return raster_task_states_.size() - num_completed_raster_tasks;
 }
 
-bool PixelBufferRasterWorkerPool::HasPendingTasks() const {
-  return PendingRasterTaskCount() || !raster_tasks_with_pending_upload_.empty();
-}
-
-bool PixelBufferRasterWorkerPool::HasPendingTasksRequiredForActivation() const {
-  return !!raster_tasks_required_for_activation_count_;
+TaskSetCollection PixelBufferRasterWorkerPool::PendingTasks() const {
+  return NonEmptyTaskSetsFromTaskCounts(task_counts_);
 }
 
 const char* PixelBufferRasterWorkerPool::StateName() const {
@@ -686,30 +691,23 @@ void PixelBufferRasterWorkerPool::CheckForCompletedRasterizerTasks() {
     RasterTaskState& state = *state_it;
     DCHECK_EQ(RasterTaskState::SCHEDULED, state.type);
 
-    // Balanced with MapPixelRasterBuffer() call in AcquireCanvasForRaster().
-    bool content_has_changed = resource_provider_->UnmapPixelRasterBuffer(
-        raster_task->resource()->id());
+    resource_provider_->UnmapPixelBuffer(raster_task->resource()->id());
 
-    // |content_has_changed| can be false as result of task being canceled or
-    // task implementation deciding not to modify bitmap (ie. analysis of raster
-    // commands detected content as a solid color).
-    if (!content_has_changed) {
+    if (!raster_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.
       raster_task->WillComplete();
       raster_task->CompleteOnOriginThread(this);
       raster_task->DidComplete();
 
-      if (!raster_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.
-        RasterTaskQueue::Item::Vector::const_iterator item_it =
-            std::find_if(raster_tasks_.items.begin(),
-                         raster_tasks_.items.end(),
-                         RasterTaskQueue::Item::TaskComparator(raster_task));
-        if (item_it != raster_tasks_.items.end()) {
-          state.type = RasterTaskState::UNSCHEDULED;
-          continue;
-        }
+      RasterTaskQueue::Item::Vector::const_iterator item_it =
+          std::find_if(raster_tasks_.items.begin(),
+                       raster_tasks_.items.end(),
+                       RasterTaskQueue::Item::TaskComparator(raster_task));
+      if (item_it != raster_tasks_.items.end()) {
+        state.type = RasterTaskState::UNSCHEDULED;
+        continue;
       }
 
       DCHECK(std::find(completed_raster_tasks_.begin(),
@@ -717,15 +715,13 @@ void PixelBufferRasterWorkerPool::CheckForCompletedRasterizerTasks() {
                        raster_task) == completed_raster_tasks_.end());
       completed_raster_tasks_.push_back(raster_task);
       state.type = RasterTaskState::COMPLETED;
-      DCHECK_LE(static_cast<size_t>(state.required_for_activation),
-                raster_tasks_required_for_activation_count_);
-      raster_tasks_required_for_activation_count_ -=
-          state.required_for_activation;
+      // Triggers if the current task belongs to a set that should be empty.
+      DCHECK((state.task_sets & ~NonEmptyTaskSetsFromTaskCounts(task_counts_))
+                 .none());
+      RemoveTaskSetsFromTaskCounts(task_counts_, state.task_sets);
       continue;
     }
 
-    DCHECK(raster_task->HasFinishedRunning());
-
     resource_provider_->BeginSetPixels(raster_task->resource()->id());
     has_performed_uploads_since_last_flush_ = true;
 
@@ -741,11 +737,12 @@ PixelBufferRasterWorkerPool::StateAsValue() const {
   scoped_refptr<base::debug::TracedValue> state =
       new base::debug::TracedValue();
   state->SetInteger("completed_count", completed_raster_tasks_.size());
-  state->SetInteger("pending_count", raster_task_states_.size());
+  state->BeginArray("pending_count");
+  for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set)
+    state->AppendInteger(task_counts_[task_set]);
+  state->EndArray();
   state->SetInteger("pending_upload_count",
                     raster_tasks_with_pending_upload_.size());
-  state->SetInteger("pending_required_for_activation_count",
-                    raster_tasks_required_for_activation_count_);
   state->BeginDictionary("throttle_state");
   ThrottleStateAsValueInto(state.get());
   state->EndDictionary();