pixel_buffer_raster_worker_pool.cc revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// found in the LICENSE file.
4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "cc/resources/pixel_buffer_raster_worker_pool.h"
6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <algorithm>
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/containers/stack_container.h"
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/debug/trace_event.h"
11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "cc/debug/traced_value.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "cc/resources/resource.h"
133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace cc {
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace {
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const int kCheckForCompletedRasterTasksDelayMs = 6;
18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst size_t kMaxScheduledRasterTasks = 48;
20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)typedef base::StackVector<internal::WorkerPoolTask*, kMaxScheduledRasterTasks>
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    WorkerPoolTaskVector;
237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace
25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static
27c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochscoped_ptr<PixelBufferRasterWorkerPool> PixelBufferRasterWorkerPool::Create(
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::SequencedTaskRunner* task_runner,
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ResourceProvider* resource_provider,
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    size_t max_transfer_buffer_usage_bytes) {
31c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return make_scoped_ptr(
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new PixelBufferRasterWorkerPool(task_runner,
33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                      GetTaskGraphRunner(),
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      resource_provider,
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      max_transfer_buffer_usage_bytes));
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)PixelBufferRasterWorkerPool::PixelBufferRasterWorkerPool(
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::SequencedTaskRunner* task_runner,
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    internal::TaskGraphRunner* task_graph_runner,
41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ResourceProvider* resource_provider,
4258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    size_t max_transfer_buffer_usage_bytes)
43c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    : task_runner_(task_runner),
44c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      task_graph_runner_(task_graph_runner),
45c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      namespace_token_(task_graph_runner->GetNamespaceToken()),
46c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      resource_provider_(resource_provider),
47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      shutdown_(false),
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      scheduled_raster_task_count_(0u),
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      raster_tasks_required_for_activation_count_(0u),
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      bytes_pending_upload_(0u),
5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      max_bytes_pending_upload_(max_transfer_buffer_usage_bytes),
52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      has_performed_uploads_since_last_flush_(false),
53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      check_for_completed_raster_tasks_pending_(false),
54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      should_notify_client_if_no_tasks_are_pending_(false),
55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      should_notify_client_if_no_tasks_required_for_activation_are_pending_(
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          false),
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      raster_finished_task_pending_(false),
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      raster_required_for_activation_finished_task_pending_(false),
59c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      raster_finished_weak_ptr_factory_(this),
60c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      weak_ptr_factory_(this) {}
61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)PixelBufferRasterWorkerPool::~PixelBufferRasterWorkerPool() {
63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(!check_for_completed_raster_tasks_pending_);
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_EQ(0u, raster_task_states_.size());
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_EQ(0u, raster_tasks_with_pending_upload_.size());
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_EQ(0u, completed_raster_tasks_.size());
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_EQ(0u, completed_image_decode_tasks_.size());
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK_EQ(0u, raster_tasks_required_for_activation_count_);
69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
71c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid PixelBufferRasterWorkerPool::SetClient(RasterWorkerPoolClient* client) {
72c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  client_ = client;
73c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
74c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void PixelBufferRasterWorkerPool::Shutdown() {
76c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::Shutdown");
77c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  shutdown_ = true;
79c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
80c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  internal::TaskGraph empty;
81c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  task_graph_runner_->ScheduleTasks(namespace_token_, &empty);
82c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_);
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckForCompletedWorkerPoolTasks();
85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  CheckForCompletedUploads();
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  check_for_completed_raster_tasks_pending_ = false;
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (RasterTaskState::Vector::iterator it = raster_task_states_.begin();
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       it != raster_task_states_.end();
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       ++it) {
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RasterTaskState& state = *it;
93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // All unscheduled tasks need to be canceled.
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (state.type == RasterTaskState::UNSCHEDULED) {
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      completed_raster_tasks_.push_back(state.task);
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      state.type = RasterTaskState::COMPLETED;
987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_EQ(completed_raster_tasks_.size(), raster_task_states_.size());
101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) {
104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleTasks");
105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK_EQ(queue->required_for_activation_count,
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            static_cast<size_t>(
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                std::count_if(queue->items.begin(),
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              queue->items.end(),
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              RasterTaskQueue::Item::IsRequiredForActivation)));
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!should_notify_client_if_no_tasks_are_pending_)
113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    TRACE_EVENT_ASYNC_BEGIN0("cc", "ScheduledTasks", this);
114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  should_notify_client_if_no_tasks_are_pending_ = true;
116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  should_notify_client_if_no_tasks_required_for_activation_are_pending_ = true;
117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  raster_tasks_required_for_activation_count_ = 0u;
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Update raster task state and remove items from old queue.
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (RasterTaskQueue::Item::Vector::const_iterator it = queue->items.begin();
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       it != queue->items.end();
123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       ++it) {
124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const RasterTaskQueue::Item& item = *it;
125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    internal::WorkerPoolTask* task = item.task;
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Remove any old items that are associated with this task. The result is
128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // that the old queue is left with all items not present in this queue,
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // which we use below to determine what tasks need to be canceled.
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RasterTaskQueue::Item::Vector::iterator old_it =
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        std::find_if(raster_tasks_.items.begin(),
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     raster_tasks_.items.end(),
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     RasterTaskQueue::Item::TaskComparator(task));
134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (old_it != raster_tasks_.items.end()) {
135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      std::swap(*old_it, raster_tasks_.items.back());
136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      raster_tasks_.items.pop_back();
137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RasterTaskState::Vector::iterator state_it =
140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        std::find_if(raster_task_states_.begin(),
141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     raster_task_states_.end(),
142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     RasterTaskState::TaskComparator(task));
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (state_it != raster_task_states_.end()) {
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      RasterTaskState& state = *state_it;
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      state.required_for_activation = item.required_for_activation;
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // |raster_tasks_required_for_activation_count| accounts for all tasks
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // that need to complete before we can send a "ready to activate" signal.
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // Tasks that have already completed should not be part of this count.
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if (state.type != RasterTaskState::COMPLETED) {
151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        raster_tasks_required_for_activation_count_ +=
152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            item.required_for_activation;
153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      }
154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      continue;
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK(!task->HasBeenScheduled());
158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    raster_task_states_.push_back(
159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        RasterTaskState(task, item.required_for_activation));
160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    raster_tasks_required_for_activation_count_ += item.required_for_activation;
161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Determine what tasks in old queue need to be canceled.
164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (RasterTaskQueue::Item::Vector::const_iterator it =
165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           raster_tasks_.items.begin();
166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       it != raster_tasks_.items.end();
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       ++it) {
168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const RasterTaskQueue::Item& item = *it;
169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    internal::WorkerPoolTask* task = item.task;
170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RasterTaskState::Vector::iterator state_it =
172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        std::find_if(raster_task_states_.begin(),
173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     raster_task_states_.end(),
174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     RasterTaskState::TaskComparator(task));
175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // We've already processed completion if we can't find a RasterTaskState for
176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // this task.
177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (state_it == raster_task_states_.end())
178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      continue;
179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RasterTaskState& state = *state_it;
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Unscheduled task can be canceled.
183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (state.type == RasterTaskState::UNSCHEDULED) {
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DCHECK(!task->HasBeenScheduled());
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DCHECK(std::find(completed_raster_tasks_.begin(),
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       completed_raster_tasks_.end(),
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       task) == completed_raster_tasks_.end());
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      completed_raster_tasks_.push_back(task);
189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      state.type = RasterTaskState::COMPLETED;
190d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // No longer required for activation.
193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    state.required_for_activation = false;
1947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
1957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  raster_tasks_.Swap(queue);
197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Check for completed tasks when ScheduleTasks() is called as
199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // priorities might have changed and this maximizes the number
200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // of top priority tasks that are scheduled.
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckForCompletedWorkerPoolTasks();
202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  CheckForCompletedUploads();
203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  FlushUploads();
204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Schedule new tasks.
206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ScheduleMoreTasks();
207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Cancel any pending check for completed raster tasks and schedule
209eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // another check.
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  check_for_completed_raster_tasks_time_ = base::TimeTicks();
211eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ScheduleCheckForCompletedRasterTasks();
212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  TRACE_EVENT_ASYNC_STEP_INTO1(
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "cc",
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "ScheduledTasks",
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      this,
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      StateName(),
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "state",
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      TracedValue::FromValue(StateAsValue().release()));
220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)unsigned PixelBufferRasterWorkerPool::GetResourceTarget() const {
223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return GL_TEXTURE_2D;
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
226d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)ResourceFormat PixelBufferRasterWorkerPool::GetResourceFormat() const {
227c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return resource_provider_->memory_efficient_texture_format();
2283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void PixelBufferRasterWorkerPool::CheckForCompletedTasks() {
231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::CheckForCompletedTasks");
232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckForCompletedWorkerPoolTasks();
2347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  CheckForCompletedUploads();
2357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  FlushUploads();
236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
237c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  for (internal::WorkerPoolTask::Vector::const_iterator it =
238c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch           completed_image_decode_tasks_.begin();
239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       it != completed_image_decode_tasks_.end();
240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       ++it) {
241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    internal::WorkerPoolTask* task = it->get();
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    task->RunReplyOnOriginThread();
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  completed_image_decode_tasks_.clear();
245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
246c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  for (internal::WorkerPoolTask::Vector::const_iterator it =
247c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch           completed_raster_tasks_.begin();
248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       it != completed_raster_tasks_.end();
249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       ++it) {
250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    internal::WorkerPoolTask* task = it->get();
251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RasterTaskState::Vector::iterator state_it =
252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        std::find_if(raster_task_states_.begin(),
253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     raster_task_states_.end(),
254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     RasterTaskState::TaskComparator(task));
255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK(state_it != raster_task_states_.end());
256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK_EQ(RasterTaskState::COMPLETED, state_it->type);
257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    std::swap(*state_it, raster_task_states_.back());
259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    raster_task_states_.pop_back();
260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    task->RunReplyOnOriginThread();
262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  completed_raster_tasks_.clear();
264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SkCanvas* PixelBufferRasterWorkerPool::AcquireCanvasForRaster(
267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    internal::WorkerPoolTask* task,
268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const Resource* resource) {
269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RasterTaskState::Vector::iterator it =
270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      std::find_if(raster_task_states_.begin(),
271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   raster_task_states_.end(),
272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   RasterTaskState::TaskComparator(task));
273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(it != raster_task_states_.end());
274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(!it->resource);
275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  it->resource = resource;
276c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  resource_provider_->AcquirePixelRasterBuffer(resource->id());
277c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return resource_provider_->MapPixelRasterBuffer(resource->id());
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void PixelBufferRasterWorkerPool::ReleaseCanvasForRaster(
281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    internal::WorkerPoolTask* task,
282a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const Resource* resource) {
283a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RasterTaskState::Vector::iterator it =
284a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      std::find_if(raster_task_states_.begin(),
285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   raster_task_states_.end(),
286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   RasterTaskState::TaskComparator(task));
287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(it != raster_task_states_.end());
288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(it->resource == resource);
289c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  resource_provider_->ReleasePixelRasterBuffer(resource->id());
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
292c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid PixelBufferRasterWorkerPool::OnRasterFinished() {
293c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::OnRasterFinished");
294c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
295eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // |should_notify_client_if_no_tasks_are_pending_| can be set to false as
296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // a result of a scheduled CheckForCompletedRasterTasks() call. No need to
297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // perform another check in that case as we've already notified the client.
298eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!should_notify_client_if_no_tasks_are_pending_)
299eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  raster_finished_task_pending_ = false;
301eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Call CheckForCompletedRasterTasks() when we've finished running all
303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // raster tasks needed since last time ScheduleTasks() was called.
304eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // This reduces latency between the time when all tasks have finished
305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // running and the time when the client is notified.
306eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  CheckForCompletedRasterTasks();
307eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
308eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
309c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid PixelBufferRasterWorkerPool::OnRasterRequiredForActivationFinished() {
310c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  TRACE_EVENT0(
311c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      "cc",
312c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      "PixelBufferRasterWorkerPool::OnRasterRequiredForActivationFinished");
313c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
314eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Analogous to OnRasterTasksFinished(), there's no need to call
315eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // CheckForCompletedRasterTasks() if the client has already been notified.
316eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!should_notify_client_if_no_tasks_required_for_activation_are_pending_)
317eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  raster_required_for_activation_finished_task_pending_ = false;
319eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
320eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // This reduces latency between the time when all tasks required for
321eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // activation have finished running and the time when the client is
322eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // notified.
323eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  CheckForCompletedRasterTasks();
324eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
325eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void PixelBufferRasterWorkerPool::FlushUploads() {
3277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!has_performed_uploads_since_last_flush_)
3287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
3297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
330c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  resource_provider_->ShallowFlushIfSupported();
3317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  has_performed_uploads_since_last_flush_ = false;
3327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
3337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void PixelBufferRasterWorkerPool::CheckForCompletedUploads() {
335c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  internal::WorkerPoolTask::Vector tasks_with_completed_uploads;
3367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // First check if any have completed.
3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  while (!raster_tasks_with_pending_upload_.empty()) {
339a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    internal::WorkerPoolTask* task =
3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        raster_tasks_with_pending_upload_.front().get();
341a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RasterTaskState::Vector::const_iterator it =
342a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        std::find_if(raster_task_states_.begin(),
343a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     raster_task_states_.end(),
344a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     RasterTaskState::TaskComparator(task));
345a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK(it != raster_task_states_.end());
346a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK_EQ(RasterTaskState::UPLOADING, it->type);
3477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // Uploads complete in the order they are issued.
349c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    if (!resource_provider_->DidSetPixelsComplete(it->resource->id()))
3507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      break;
3517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    tasks_with_completed_uploads.push_back(task);
3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    raster_tasks_with_pending_upload_.pop_front();
3547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
3557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
356c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(client_);
3577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool should_force_some_uploads_to_complete =
358c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      shutdown_ || client_->ShouldForceTasksRequiredForActivationToComplete();
3597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (should_force_some_uploads_to_complete) {
361c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    internal::WorkerPoolTask::Vector tasks_with_uploads_to_force;
362a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    TaskDeque::iterator it = raster_tasks_with_pending_upload_.begin();
3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    while (it != raster_tasks_with_pending_upload_.end()) {
364a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      internal::WorkerPoolTask* task = it->get();
365a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      RasterTaskState::Vector::const_iterator state_it =
366a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          std::find_if(raster_task_states_.begin(),
367a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       raster_task_states_.end(),
368a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       RasterTaskState::TaskComparator(task));
369a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DCHECK(state_it != raster_task_states_.end());
3707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // Force all uploads required for activation to complete.
3727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // During shutdown, force all pending uploads to complete.
373a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if (shutdown_ || state_it->required_for_activation) {
374eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        tasks_with_uploads_to_force.push_back(task);
3757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        tasks_with_completed_uploads.push_back(task);
3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        it = raster_tasks_with_pending_upload_.erase(it);
3777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        continue;
3787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      }
3797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      ++it;
381868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
382eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
383eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Force uploads in reverse order. Since forcing can cause a wait on
384eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // all previous uploads, we would rather wait only once downstream.
385c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    for (internal::WorkerPoolTask::Vector::reverse_iterator it =
386c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch             tasks_with_uploads_to_force.rbegin();
387eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch         it != tasks_with_uploads_to_force.rend();
388eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch         ++it) {
389a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      internal::WorkerPoolTask* task = it->get();
390a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      RasterTaskState::Vector::const_iterator state_it =
391a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          std::find_if(raster_task_states_.begin(),
392a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       raster_task_states_.end(),
393a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       RasterTaskState::TaskComparator(task));
394a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DCHECK(state_it != raster_task_states_.end());
395a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DCHECK(state_it->resource);
396a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
397c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      resource_provider_->ForceSetPixelsToComplete(state_it->resource->id());
398eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      has_performed_uploads_since_last_flush_ = true;
399eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
400868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
401868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Release shared memory and move tasks with completed uploads
4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // to |completed_raster_tasks_|.
404c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  for (internal::WorkerPoolTask::Vector::const_iterator it =
405c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch           tasks_with_completed_uploads.begin();
406a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       it != tasks_with_completed_uploads.end();
407a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       ++it) {
408a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    internal::WorkerPoolTask* task = it->get();
409a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RasterTaskState::Vector::iterator state_it =
410a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        std::find_if(raster_task_states_.begin(),
411a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     raster_task_states_.end(),
412a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     RasterTaskState::TaskComparator(task));
413a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK(state_it != raster_task_states_.end());
414a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RasterTaskState& state = *state_it;
4157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
416a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    bytes_pending_upload_ -= state.resource->bytes();
4177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
418a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    task->WillComplete();
419a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    task->CompleteOnOriginThread(this);
420a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    task->DidComplete();
4217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(std::find(completed_raster_tasks_.begin(),
4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     completed_raster_tasks_.end(),
4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     task) == completed_raster_tasks_.end());
4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    completed_raster_tasks_.push_back(task);
426a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    state.type = RasterTaskState::COMPLETED;
427a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK_LE(static_cast<size_t>(state.required_for_activation),
428a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)              raster_tasks_required_for_activation_count_);
429a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    raster_tasks_required_for_activation_count_ -=
430a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        state.required_for_activation;
4317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
433868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
434868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void PixelBufferRasterWorkerPool::ScheduleCheckForCompletedRasterTasks() {
4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::TimeDelta delay =
4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(kCheckForCompletedRasterTasksDelayMs);
4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (check_for_completed_raster_tasks_time_.is_null())
4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    check_for_completed_raster_tasks_time_ = base::TimeTicks::Now() + delay;
4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
440868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (check_for_completed_raster_tasks_pending_)
441868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
442868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
443c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  task_runner_->PostDelayedTask(
444868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      FROM_HERE,
4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&PixelBufferRasterWorkerPool::OnCheckForCompletedRasterTasks,
446c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                 weak_ptr_factory_.GetWeakPtr()),
4475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      delay);
448868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  check_for_completed_raster_tasks_pending_ = true;
449868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
450868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PixelBufferRasterWorkerPool::OnCheckForCompletedRasterTasks() {
4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (check_for_completed_raster_tasks_time_.is_null()) {
4535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    check_for_completed_raster_tasks_pending_ = false;
4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
456868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::TimeDelta delay =
4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      check_for_completed_raster_tasks_time_ - base::TimeTicks::Now();
4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Post another delayed task if it is not yet time to check for completed
4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // raster tasks.
4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (delay > base::TimeDelta()) {
463c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    task_runner_->PostDelayedTask(
4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        FROM_HERE,
4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::Bind(&PixelBufferRasterWorkerPool::OnCheckForCompletedRasterTasks,
466c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                   weak_ptr_factory_.GetWeakPtr()),
4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        delay);
4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
470eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
471868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  check_for_completed_raster_tasks_pending_ = false;
4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckForCompletedRasterTasks();
4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() {
4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TRACE_EVENT0("cc",
4775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)               "PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks");
4785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(should_notify_client_if_no_tasks_are_pending_);
4805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  check_for_completed_raster_tasks_time_ = base::TimeTicks();
481868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckForCompletedWorkerPoolTasks();
4837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  CheckForCompletedUploads();
4847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  FlushUploads();
485868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
486eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Determine what client notifications to generate.
487eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  bool will_notify_client_that_no_tasks_required_for_activation_are_pending =
488eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      (should_notify_client_if_no_tasks_required_for_activation_are_pending_ &&
4895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       !raster_required_for_activation_finished_task_pending_ &&
490eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch       !HasPendingTasksRequiredForActivation());
491eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  bool will_notify_client_that_no_tasks_are_pending =
492eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      (should_notify_client_if_no_tasks_are_pending_ &&
4935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       !raster_required_for_activation_finished_task_pending_ &&
4945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       !raster_finished_task_pending_ && !HasPendingTasks());
495eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
496eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Adjust the need to generate notifications before scheduling more tasks.
497eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  should_notify_client_if_no_tasks_required_for_activation_are_pending_ &=
498eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      !will_notify_client_that_no_tasks_required_for_activation_are_pending;
499eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  should_notify_client_if_no_tasks_are_pending_ &=
500eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      !will_notify_client_that_no_tasks_are_pending;
501eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
5027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scheduled_raster_task_count_ = 0;
503eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (PendingRasterTaskCount())
504eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ScheduleMoreTasks();
505eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
5061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  TRACE_EVENT_ASYNC_STEP_INTO1(
5075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "cc",
5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "ScheduledTasks",
5095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      this,
5105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      StateName(),
5115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "state",
5125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      TracedValue::FromValue(StateAsValue().release()));
513eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
514eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Schedule another check for completed raster tasks while there are
515eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // pending raster tasks or pending uploads.
516eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (HasPendingTasks())
517eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ScheduleCheckForCompletedRasterTasks();
518eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
519eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Generate client notifications.
5207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (will_notify_client_that_no_tasks_required_for_activation_are_pending) {
521a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK(!HasPendingTasksRequiredForActivation());
522c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    client_->DidFinishRunningTasksRequiredForActivation();
5237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
524eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (will_notify_client_that_no_tasks_are_pending) {
525eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this);
5267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    DCHECK(!HasPendingTasksRequiredForActivation());
527c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    client_->DidFinishRunningTasks();
528eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
529868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
530868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
531868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void PixelBufferRasterWorkerPool::ScheduleMoreTasks() {
532868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleMoreTasks");
533868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WorkerPoolTaskVector tasks;
5355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WorkerPoolTaskVector tasks_required_for_activation;
5365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  unsigned priority = kRasterTaskPriorityBase;
5385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  graph_.Reset();
540868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
541eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  size_t bytes_pending_upload = bytes_pending_upload_;
5425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool did_throttle_raster_tasks = false;
543a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool did_throttle_raster_tasks_required_for_activation = false;
544868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
545a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (RasterTaskQueue::Item::Vector::const_iterator it =
546a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           raster_tasks_.items.begin();
547a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       it != raster_tasks_.items.end();
548a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       ++it) {
549a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const RasterTaskQueue::Item& item = *it;
550a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    internal::RasterWorkerPoolTask* task = item.task;
551868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // |raster_task_states_| contains the state of all tasks that we have not
5535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // yet run reply callbacks for.
554a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RasterTaskState::Vector::iterator state_it =
555a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        std::find_if(raster_task_states_.begin(),
556a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     raster_task_states_.end(),
557a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     RasterTaskState::TaskComparator(task));
5585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (state_it == raster_task_states_.end())
559868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      continue;
560868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
561a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RasterTaskState& state = *state_it;
562a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
5635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Skip task if completed.
564a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (state.type == RasterTaskState::COMPLETED) {
5655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DCHECK(std::find(completed_raster_tasks_.begin(),
5665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       completed_raster_tasks_.end(),
5675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       task) != completed_raster_tasks_.end());
568868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      continue;
569868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
570868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // All raster tasks need to be throttled by bytes of pending uploads.
572868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    size_t new_bytes_pending_upload = bytes_pending_upload;
573868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    new_bytes_pending_upload += task->resource()->bytes();
5745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (new_bytes_pending_upload > max_bytes_pending_upload_) {
5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      did_throttle_raster_tasks = true;
576a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if (item.required_for_activation)
577a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        did_throttle_raster_tasks_required_for_activation = true;
578a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      continue;
5795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
5807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // If raster has finished, just update |bytes_pending_upload|.
582a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (state.type == RasterTaskState::UPLOADING) {
583a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DCHECK(!task->HasCompleted());
5847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      bytes_pending_upload = new_bytes_pending_upload;
5857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      continue;
5867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
5877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
588eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Throttle raster tasks based on kMaxScheduledRasterTasks.
5895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (tasks.container().size() >= kMaxScheduledRasterTasks) {
5905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      did_throttle_raster_tasks = true;
591a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if (item.required_for_activation)
592a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        did_throttle_raster_tasks_required_for_activation = true;
593a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      continue;
5945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
5957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
596eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Update |bytes_pending_upload| now that task has cleared all
597eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // throttling limits.
598868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bytes_pending_upload = new_bytes_pending_upload;
599868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
600a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK(state.type == RasterTaskState::UNSCHEDULED ||
601a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           state.type == RasterTaskState::SCHEDULED);
602a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    state.type = RasterTaskState::SCHEDULED;
6037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
604c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++);
6055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    tasks.container().push_back(task);
607a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (item.required_for_activation)
6085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      tasks_required_for_activation.container().push_back(task);
609868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
610868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
611c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Cancel existing OnRasterFinished callbacks.
612c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  raster_finished_weak_ptr_factory_.InvalidateWeakPtrs();
613c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
614eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_refptr<internal::WorkerPoolTask>
615eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new_raster_required_for_activation_finished_task;
616eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
617eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  size_t scheduled_raster_task_required_for_activation_count =
6185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      tasks_required_for_activation.container().size();
619eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK_LE(scheduled_raster_task_required_for_activation_count,
620a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            raster_tasks_required_for_activation_count_);
621eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Schedule OnRasterTasksRequiredForActivationFinished call only when
622eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // notification is pending and throttling is not preventing all pending
623eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // tasks required for activation from being scheduled.
624a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!did_throttle_raster_tasks_required_for_activation &&
625eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      should_notify_client_if_no_tasks_required_for_activation_are_pending_) {
626eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    new_raster_required_for_activation_finished_task =
6275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        CreateRasterRequiredForActivationFinishedTask(
628c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch            raster_tasks_.required_for_activation_count,
629c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch            task_runner_.get(),
630c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch            base::Bind(&PixelBufferRasterWorkerPool::
631c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                           OnRasterRequiredForActivationFinished,
632c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                       raster_finished_weak_ptr_factory_.GetWeakPtr()));
6335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    raster_required_for_activation_finished_task_pending_ = true;
6345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    InsertNodeForTask(&graph_,
6355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      new_raster_required_for_activation_finished_task.get(),
6365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      kRasterRequiredForActivationFinishedTaskPriority,
6375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      scheduled_raster_task_required_for_activation_count);
6385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for (WorkerPoolTaskVector::ContainerType::const_iterator it =
6395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)             tasks_required_for_activation.container().begin();
6405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         it != tasks_required_for_activation.container().end();
6415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         ++it) {
6425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      graph_.edges.push_back(internal::TaskGraph::Edge(
6435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          *it, new_raster_required_for_activation_finished_task.get()));
6445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
645eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
646868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
647eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_refptr<internal::WorkerPoolTask> new_raster_finished_task;
648eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
6495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  size_t scheduled_raster_task_count = tasks.container().size();
650eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK_LE(scheduled_raster_task_count, PendingRasterTaskCount());
651eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Schedule OnRasterTasksFinished call only when notification is pending
652eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // and throttling is not preventing all pending tasks from being scheduled.
6535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!did_throttle_raster_tasks &&
654eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      should_notify_client_if_no_tasks_are_pending_) {
655c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    new_raster_finished_task = CreateRasterFinishedTask(
656c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        task_runner_.get(),
657c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        base::Bind(&PixelBufferRasterWorkerPool::OnRasterFinished,
658c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                   raster_finished_weak_ptr_factory_.GetWeakPtr()));
6595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    raster_finished_task_pending_ = true;
6605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    InsertNodeForTask(&graph_,
6615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      new_raster_finished_task.get(),
6625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      kRasterFinishedTaskPriority,
6635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      scheduled_raster_task_count);
6645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for (WorkerPoolTaskVector::ContainerType::const_iterator it =
6655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)             tasks.container().begin();
6665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         it != tasks.container().end();
6675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         ++it) {
6685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      graph_.edges.push_back(
6695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          internal::TaskGraph::Edge(*it, new_raster_finished_task.get()));
670eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
671868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
672868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
673c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ScheduleTasksOnOriginThread(this, &graph_);
674c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  task_graph_runner_->ScheduleTasks(namespace_token_, &graph_);
675eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
676eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scheduled_raster_task_count_ = scheduled_raster_task_count;
677eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
678c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  raster_finished_task_ = new_raster_finished_task;
679c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  raster_required_for_activation_finished_task_ =
680c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      new_raster_required_for_activation_finished_task;
681868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
682868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
683eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochunsigned PixelBufferRasterWorkerPool::PendingRasterTaskCount() const {
684eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  unsigned num_completed_raster_tasks =
6855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      raster_tasks_with_pending_upload_.size() + completed_raster_tasks_.size();
6865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_GE(raster_task_states_.size(), num_completed_raster_tasks);
6875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return raster_task_states_.size() - num_completed_raster_tasks;
688eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
689eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
690eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool PixelBufferRasterWorkerPool::HasPendingTasks() const {
6915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return PendingRasterTaskCount() || !raster_tasks_with_pending_upload_.empty();
692868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
693868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
694eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool PixelBufferRasterWorkerPool::HasPendingTasksRequiredForActivation() const {
695a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return !!raster_tasks_required_for_activation_count_;
696eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
697eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
698eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst char* PixelBufferRasterWorkerPool::StateName() const {
699eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (scheduled_raster_task_count_)
700eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return "rasterizing";
701eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (PendingRasterTaskCount())
702eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return "throttled";
7035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!raster_tasks_with_pending_upload_.empty())
704eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return "waiting_for_uploads";
705eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
706eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return "finishing";
707eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
708eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
7095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PixelBufferRasterWorkerPool::CheckForCompletedWorkerPoolTasks() {
710c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  TRACE_EVENT0("cc",
711c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch               "PixelBufferRasterWorkerPool::CheckForCompletedWorkerPoolTasks");
712c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
713c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  task_graph_runner_->CollectCompletedTasks(namespace_token_,
714c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                            &completed_tasks_);
7155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (internal::Task::Vector::const_iterator it = completed_tasks_.begin();
7165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       it != completed_tasks_.end();
7175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       ++it) {
7185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    internal::WorkerPoolTask* task =
7195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        static_cast<internal::WorkerPoolTask*>(it->get());
7205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
721a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RasterTaskState::Vector::iterator state_it =
722a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        std::find_if(raster_task_states_.begin(),
723a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     raster_task_states_.end(),
724a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     RasterTaskState::TaskComparator(task));
725a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (state_it == raster_task_states_.end()) {
726a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      task->WillComplete();
727a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      task->CompleteOnOriginThread(this);
728a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      task->DidComplete();
729a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
730a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      completed_image_decode_tasks_.push_back(task);
731a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      continue;
732a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
733a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
734a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RasterTaskState& state = *state_it;
735a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK_EQ(RasterTaskState::SCHEDULED, state.type);
736a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK(state.resource);
737a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
738a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Balanced with MapPixelRasterBuffer() call in AcquireCanvasForRaster().
739a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    bool content_has_changed =
740c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        resource_provider_->UnmapPixelRasterBuffer(state.resource->id());
741a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
742a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // |content_has_changed| can be false as result of task being canceled or
743a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // task implementation deciding not to modify bitmap (ie. analysis of raster
744a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // commands detected content as a solid color).
745a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!content_has_changed) {
746a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      task->WillComplete();
747a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      task->CompleteOnOriginThread(this);
748a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      task->DidComplete();
749a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
750a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if (!task->HasFinishedRunning()) {
751a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        // When priorites change, a raster task can be canceled as a result of
752a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        // no longer being of high enough priority to fit in our throttled
753a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        // raster task budget. The task has not yet completed in this case.
754a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        RasterTaskQueue::Item::Vector::const_iterator item_it =
755a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            std::find_if(raster_tasks_.items.begin(),
756a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                         raster_tasks_.items.end(),
757a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                         RasterTaskQueue::Item::TaskComparator(task));
758a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        if (item_it != raster_tasks_.items.end()) {
759a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          state.type = RasterTaskState::UNSCHEDULED;
760a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          state.resource = NULL;
761a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          continue;
762a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        }
763a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      }
764a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
765a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DCHECK(std::find(completed_raster_tasks_.begin(),
766a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       completed_raster_tasks_.end(),
767a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       task) == completed_raster_tasks_.end());
768a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      completed_raster_tasks_.push_back(task);
769a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      state.type = RasterTaskState::COMPLETED;
770a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DCHECK_LE(static_cast<size_t>(state.required_for_activation),
771a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                raster_tasks_required_for_activation_count_);
772a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      raster_tasks_required_for_activation_count_ -=
773a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          state.required_for_activation;
774a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      continue;
775a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
776a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
777a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK(task->HasFinishedRunning());
778a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
779c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    resource_provider_->BeginSetPixels(state.resource->id());
780a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    has_performed_uploads_since_last_flush_ = true;
781a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
782a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    bytes_pending_upload_ += state.resource->bytes();
783a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    raster_tasks_with_pending_upload_.push_back(task);
784a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    state.type = RasterTaskState::UPLOADING;
7855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
7865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  completed_tasks_.clear();
7875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
7885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
789eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochscoped_ptr<base::Value> PixelBufferRasterWorkerPool::StateAsValue() const {
790eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue);
791eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
7925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  state->SetInteger("completed_count", completed_raster_tasks_.size());
7935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  state->SetInteger("pending_count", raster_task_states_.size());
7945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  state->SetInteger("pending_upload_count",
7955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    raster_tasks_with_pending_upload_.size());
7965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  state->SetInteger("pending_required_for_activation_count",
797a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    raster_tasks_required_for_activation_count_);
798eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  state->Set("throttle_state", ThrottleStateAsValue().release());
799eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return state.PassAs<base::Value>();
800eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
801eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
802eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochscoped_ptr<base::Value> PixelBufferRasterWorkerPool::ThrottleStateAsValue()
803eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const {
804eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<base::DictionaryValue> throttle_state(new base::DictionaryValue);
805eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
806eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  throttle_state->SetInteger("bytes_available_for_upload",
8073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             max_bytes_pending_upload_ - bytes_pending_upload_);
808eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  throttle_state->SetInteger("bytes_pending_upload", bytes_pending_upload_);
809eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  throttle_state->SetInteger("scheduled_raster_task_count",
810eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                             scheduled_raster_task_count_);
811eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return throttle_state.PassAs<base::Value>();
812868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
813868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
814868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace cc
815