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"
115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/debug/trace_event_argument.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/strings/stringprintf.h"
13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "cc/debug/traced_value.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "cc/resources/raster_buffer.h"
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "cc/resources/resource.h"
16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "gpu/command_buffer/client/gles2_interface.h"
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "third_party/skia/include/utils/SkNullCanvas.h"
183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace cc {
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace {
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass RasterBufferImpl : public RasterBuffer {
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public:
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RasterBufferImpl(ResourceProvider* resource_provider,
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   const Resource* resource)
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      : resource_provider_(resource_provider),
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        resource_(resource),
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        buffer_(NULL),
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        stride_(0) {
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    resource_provider_->AcquirePixelBuffer(resource_->id());
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    buffer_ = resource_provider_->MapPixelBuffer(resource_->id(), &stride_);
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual ~RasterBufferImpl() {
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    resource_provider_->ReleasePixelBuffer(resource_->id());
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Overridden from RasterBuffer:
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual skia::RefPtr<SkCanvas> AcquireSkCanvas() OVERRIDE {
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!buffer_)
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return skia::AdoptRef(SkCreateNullCanvas());
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    RasterWorkerPool::AcquireBitmapForBuffer(
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        &bitmap_, buffer_, resource_->format(), resource_->size(), stride_);
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return skia::AdoptRef(new SkCanvas(bitmap_));
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void ReleaseSkCanvas(const skia::RefPtr<SkCanvas>& canvas) OVERRIDE {
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!buffer_)
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return;
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    RasterWorkerPool::ReleaseBitmapForBuffer(
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        &bitmap_, buffer_, resource_->format());
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private:
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ResourceProvider* resource_provider_;
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const Resource* resource_;
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  uint8_t* buffer_;
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int stride_;
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SkBitmap bitmap_;
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl);
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const int kCheckForCompletedRasterTasksDelayMs = 6;
66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst size_t kMaxScheduledRasterTasks = 48;
68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
69a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochtypedef base::StackVector<RasterTask*, kMaxScheduledRasterTasks>
70a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    RasterTaskVector;
717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTaskSetCollection NonEmptyTaskSetsFromTaskCounts(const size_t* task_counts) {
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TaskSetCollection task_sets;
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) {
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (task_counts[task_set])
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      task_sets[task_set] = true;
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return task_sets;
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AddTaskSetsToTaskCounts(size_t* task_counts,
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             const TaskSetCollection& task_sets) {
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) {
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (task_sets[task_set])
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      task_counts[task_set]++;
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid RemoveTaskSetsFromTaskCounts(size_t* task_counts,
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                  const TaskSetCollection& task_sets) {
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) {
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (task_sets[task_set])
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      task_counts[task_set]--;
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace
98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciPixelBufferRasterWorkerPool::RasterTaskState::RasterTaskState(
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    RasterTask* task,
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const TaskSetCollection& task_sets)
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : type(UNSCHEDULED), task(task), task_sets(task_sets) {
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static
106a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochscoped_ptr<RasterWorkerPool> PixelBufferRasterWorkerPool::Create(
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::SequencedTaskRunner* task_runner,
108a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    TaskGraphRunner* task_graph_runner,
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ContextProvider* context_provider,
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ResourceProvider* resource_provider,
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    size_t max_transfer_buffer_usage_bytes) {
112a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  return make_scoped_ptr<RasterWorkerPool>(
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new PixelBufferRasterWorkerPool(task_runner,
114a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                      task_graph_runner,
115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                      context_provider,
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      resource_provider,
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      max_transfer_buffer_usage_bytes));
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)PixelBufferRasterWorkerPool::PixelBufferRasterWorkerPool(
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::SequencedTaskRunner* task_runner,
122a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    TaskGraphRunner* task_graph_runner,
123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ContextProvider* context_provider,
124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ResourceProvider* resource_provider,
12558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    size_t max_transfer_buffer_usage_bytes)
126c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    : task_runner_(task_runner),
127c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      task_graph_runner_(task_graph_runner),
128c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      namespace_token_(task_graph_runner->GetNamespaceToken()),
129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      context_provider_(context_provider),
130c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      resource_provider_(resource_provider),
131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      shutdown_(false),
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      scheduled_raster_task_count_(0u),
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      bytes_pending_upload_(0u),
13458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      max_bytes_pending_upload_(max_transfer_buffer_usage_bytes),
135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      has_performed_uploads_since_last_flush_(false),
136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      check_for_completed_raster_task_notifier_(
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          task_runner,
138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          base::Bind(&PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks,
139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     base::Unretained(this)),
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          base::TimeDelta::FromMilliseconds(
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)              kCheckForCompletedRasterTasksDelayMs)),
142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      raster_finished_weak_ptr_factory_(this) {
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(context_provider_);
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::fill(task_counts_, task_counts_ + kNumberOfTaskSets, 0);
145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)PixelBufferRasterWorkerPool::~PixelBufferRasterWorkerPool() {
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_EQ(0u, raster_task_states_.size());
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_EQ(0u, raster_tasks_with_pending_upload_.size());
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_EQ(0u, completed_raster_tasks_.size());
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_EQ(0u, completed_image_decode_tasks_.size());
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(NonEmptyTaskSetsFromTaskCounts(task_counts_).none());
153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
155a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochRasterizer* PixelBufferRasterWorkerPool::AsRasterizer() { return this; }
156a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
157a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid PixelBufferRasterWorkerPool::SetClient(RasterizerClient* client) {
158c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  client_ = client;
159c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
160c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void PixelBufferRasterWorkerPool::Shutdown() {
162c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::Shutdown");
163c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  shutdown_ = true;
165c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
166a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  TaskGraph empty;
167c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  task_graph_runner_->ScheduleTasks(namespace_token_, &empty);
168c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_);
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
170a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  CheckForCompletedRasterizerTasks();
171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  CheckForCompletedUploads();
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  check_for_completed_raster_task_notifier_.Cancel();
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (RasterTaskState::Vector::iterator it = raster_task_states_.begin();
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       it != raster_task_states_.end();
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       ++it) {
178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RasterTaskState& state = *it;
179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // All unscheduled tasks need to be canceled.
181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (state.type == RasterTaskState::UNSCHEDULED) {
182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      completed_raster_tasks_.push_back(state.task);
183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      state.type = RasterTaskState::COMPLETED;
1847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_EQ(completed_raster_tasks_.size(), raster_task_states_.size());
187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) {
190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleTasks");
191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (should_notify_client_if_no_tasks_are_pending_.none())
193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    TRACE_EVENT_ASYNC_BEGIN0("cc", "ScheduledTasks", this);
194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  should_notify_client_if_no_tasks_are_pending_.set();
1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::fill(task_counts_, task_counts_ + kNumberOfTaskSets, 0);
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Update raster task state and remove items from old queue.
199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (RasterTaskQueue::Item::Vector::const_iterator it = queue->items.begin();
200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       it != queue->items.end();
201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       ++it) {
202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const RasterTaskQueue::Item& item = *it;
203a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    RasterTask* task = item.task;
204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Remove any old items that are associated with this task. The result is
206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // that the old queue is left with all items not present in this queue,
207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // which we use below to determine what tasks need to be canceled.
208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RasterTaskQueue::Item::Vector::iterator old_it =
209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        std::find_if(raster_tasks_.items.begin(),
210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     raster_tasks_.items.end(),
211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     RasterTaskQueue::Item::TaskComparator(task));
212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (old_it != raster_tasks_.items.end()) {
213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      std::swap(*old_it, raster_tasks_.items.back());
214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      raster_tasks_.items.pop_back();
215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RasterTaskState::Vector::iterator state_it =
218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        std::find_if(raster_task_states_.begin(),
219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     raster_task_states_.end(),
220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     RasterTaskState::TaskComparator(task));
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (state_it != raster_task_states_.end()) {
222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      RasterTaskState& state = *state_it;
223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      state.task_sets = item.task_sets;
225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // |raster_tasks_required_for_activation_count| accounts for all tasks
226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // that need to complete before we can send a "ready to activate" signal.
227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // Tasks that have already completed should not be part of this count.
2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (state.type != RasterTaskState::COMPLETED)
2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        AddTaskSetsToTaskCounts(task_counts_, item.task_sets);
2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      continue;
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK(!task->HasBeenScheduled());
2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    raster_task_states_.push_back(RasterTaskState(task, item.task_sets));
2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    AddTaskSetsToTaskCounts(task_counts_, item.task_sets);
237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Determine what tasks in old queue need to be canceled.
240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (RasterTaskQueue::Item::Vector::const_iterator it =
241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           raster_tasks_.items.begin();
242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       it != raster_tasks_.items.end();
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       ++it) {
244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const RasterTaskQueue::Item& item = *it;
245a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    RasterTask* task = item.task;
246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RasterTaskState::Vector::iterator state_it =
248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        std::find_if(raster_task_states_.begin(),
249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     raster_task_states_.end(),
250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     RasterTaskState::TaskComparator(task));
251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // We've already processed completion if we can't find a RasterTaskState for
252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // this task.
253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (state_it == raster_task_states_.end())
254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      continue;
255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RasterTaskState& state = *state_it;
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Unscheduled task can be canceled.
259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (state.type == RasterTaskState::UNSCHEDULED) {
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DCHECK(!task->HasBeenScheduled());
2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DCHECK(std::find(completed_raster_tasks_.begin(),
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       completed_raster_tasks_.end(),
2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       task) == completed_raster_tasks_.end());
2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      completed_raster_tasks_.push_back(task);
265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      state.type = RasterTaskState::COMPLETED;
266d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
267eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // No longer in any task set.
2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    state.task_sets.reset();
2707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  raster_tasks_.Swap(queue);
273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Check for completed tasks when ScheduleTasks() is called as
275eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // priorities might have changed and this maximizes the number
276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // of top priority tasks that are scheduled.
277a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  CheckForCompletedRasterizerTasks();
278eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  CheckForCompletedUploads();
279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  FlushUploads();
280eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
281eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Schedule new tasks.
282eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ScheduleMoreTasks();
283eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Reschedule check for completed raster tasks.
285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  check_for_completed_raster_task_notifier_.Schedule();
286eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  TRACE_EVENT_ASYNC_STEP_INTO1(
2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      "cc", "ScheduledTasks", this, StateName(), "state", StateAsValue());
289868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
291868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void PixelBufferRasterWorkerPool::CheckForCompletedTasks() {
292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::CheckForCompletedTasks");
293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
294a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  CheckForCompletedRasterizerTasks();
2957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  CheckForCompletedUploads();
2967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  FlushUploads();
297868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
298a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  for (RasterizerTask::Vector::const_iterator it =
299c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch           completed_image_decode_tasks_.begin();
300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       it != completed_image_decode_tasks_.end();
301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       ++it) {
302a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    RasterizerTask* task = it->get();
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    task->RunReplyOnOriginThread();
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  completed_image_decode_tasks_.clear();
306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
307a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  for (RasterTask::Vector::const_iterator it = completed_raster_tasks_.begin();
308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       it != completed_raster_tasks_.end();
309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       ++it) {
310a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    RasterTask* task = it->get();
311a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RasterTaskState::Vector::iterator state_it =
312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        std::find_if(raster_task_states_.begin(),
313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     raster_task_states_.end(),
314a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     RasterTaskState::TaskComparator(task));
315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK(state_it != raster_task_states_.end());
316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK_EQ(RasterTaskState::COMPLETED, state_it->type);
317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
318a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    std::swap(*state_it, raster_task_states_.back());
319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    raster_task_states_.pop_back();
320868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    task->RunReplyOnOriginThread();
322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  completed_raster_tasks_.clear();
324868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
325868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciscoped_ptr<RasterBuffer> PixelBufferRasterWorkerPool::AcquireBufferForRaster(
3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const Resource* resource) {
3281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return make_scoped_ptr<RasterBuffer>(
3291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new RasterBufferImpl(resource_provider_, resource));
3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid PixelBufferRasterWorkerPool::ReleaseBufferForRaster(
3331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<RasterBuffer> buffer) {
3341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Nothing to do here. RasterBufferImpl destructor cleans up after itself.
335eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
336eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid PixelBufferRasterWorkerPool::OnRasterFinished(TaskSet task_set) {
3381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT2("cc",
3391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "PixelBufferRasterWorkerPool::OnRasterFinished",
3401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "task_set",
3411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               task_set,
3421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "should_notify_client_if_no_tasks_are_pending",
3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               should_notify_client_if_no_tasks_are_pending_[task_set]);
3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // There's no need to call CheckForCompletedRasterTasks() if the client has
3461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // already been notified.
3471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!should_notify_client_if_no_tasks_are_pending_[task_set])
348eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
3491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  raster_finished_tasks_pending_[task_set] = false;
350eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
351eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // This reduces latency between the time when all tasks required for
352eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // activation have finished running and the time when the client is
353eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // notified.
354eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  CheckForCompletedRasterTasks();
355eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
356eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void PixelBufferRasterWorkerPool::FlushUploads() {
3587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!has_performed_uploads_since_last_flush_)
3597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
3607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  context_provider_->ContextGL()->ShallowFlushCHROMIUM();
3627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  has_performed_uploads_since_last_flush_ = false;
3637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
3647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void PixelBufferRasterWorkerPool::CheckForCompletedUploads() {
366a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  RasterTask::Vector tasks_with_completed_uploads;
3677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // First check if any have completed.
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  while (!raster_tasks_with_pending_upload_.empty()) {
370a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    RasterTask* task = raster_tasks_with_pending_upload_.front().get();
371a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    DCHECK(std::find_if(raster_task_states_.begin(),
372a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                        raster_task_states_.end(),
373a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                        RasterTaskState::TaskComparator(task)) !=
374a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch           raster_task_states_.end());
375a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    DCHECK_EQ(RasterTaskState::UPLOADING,
376a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch              std::find_if(raster_task_states_.begin(),
377a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                           raster_task_states_.end(),
378a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                           RasterTaskState::TaskComparator(task))->type);
3797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // Uploads complete in the order they are issued.
381a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    if (!resource_provider_->DidSetPixelsComplete(task->resource()->id()))
3827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      break;
3837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    tasks_with_completed_uploads.push_back(task);
3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    raster_tasks_with_pending_upload_.pop_front();
3867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
3877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
388c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(client_);
3891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TaskSetCollection tasks_that_should_be_forced_to_complete =
3901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      client_->TasksThatShouldBeForcedToComplete();
3917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool should_force_some_uploads_to_complete =
3921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      shutdown_ || tasks_that_should_be_forced_to_complete.any();
3937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (should_force_some_uploads_to_complete) {
395a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    RasterTask::Vector tasks_with_uploads_to_force;
396a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    RasterTaskDeque::iterator it = raster_tasks_with_pending_upload_.begin();
3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    while (it != raster_tasks_with_pending_upload_.end()) {
398a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      RasterTask* task = it->get();
399a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      RasterTaskState::Vector::const_iterator state_it =
400a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          std::find_if(raster_task_states_.begin(),
401a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       raster_task_states_.end(),
402a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       RasterTaskState::TaskComparator(task));
403a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DCHECK(state_it != raster_task_states_.end());
404a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      const RasterTaskState& state = *state_it;
4057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // Force all uploads to complete for which the client requests to do so.
4077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // During shutdown, force all pending uploads to complete.
4081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (shutdown_ ||
4091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          (state.task_sets & tasks_that_should_be_forced_to_complete).any()) {
410eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        tasks_with_uploads_to_force.push_back(task);
4117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        tasks_with_completed_uploads.push_back(task);
4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        it = raster_tasks_with_pending_upload_.erase(it);
4137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        continue;
4147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      }
4157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      ++it;
417868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
418eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
419eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Force uploads in reverse order. Since forcing can cause a wait on
420eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // all previous uploads, we would rather wait only once downstream.
421a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    for (RasterTask::Vector::reverse_iterator it =
422c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch             tasks_with_uploads_to_force.rbegin();
423eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch         it != tasks_with_uploads_to_force.rend();
424eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch         ++it) {
425a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      RasterTask* task = it->get();
426a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
427a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      resource_provider_->ForceSetPixelsToComplete(task->resource()->id());
428eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      has_performed_uploads_since_last_flush_ = true;
429eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
430868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
431868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Release shared memory and move tasks with completed uploads
4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // to |completed_raster_tasks_|.
434a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  for (RasterTask::Vector::const_iterator it =
435c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch           tasks_with_completed_uploads.begin();
436a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       it != tasks_with_completed_uploads.end();
437a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       ++it) {
438a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    RasterTask* task = it->get();
439a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RasterTaskState::Vector::iterator state_it =
440a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        std::find_if(raster_task_states_.begin(),
441a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     raster_task_states_.end(),
442a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     RasterTaskState::TaskComparator(task));
443a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK(state_it != raster_task_states_.end());
444a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RasterTaskState& state = *state_it;
4457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
446a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    bytes_pending_upload_ -= task->resource()->bytes();
4477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
448a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    task->WillComplete();
449a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    task->CompleteOnOriginThread(this);
450a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    task->DidComplete();
4517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
452a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // Async set pixels commands are not necessarily processed in-sequence with
453a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // drawing commands. Read lock fences are required to ensure that async
454a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // commands don't access the resource while used for drawing.
4555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    resource_provider_->EnableReadLockFences(task->resource()->id());
456a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
4575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(std::find(completed_raster_tasks_.begin(),
4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     completed_raster_tasks_.end(),
4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     task) == completed_raster_tasks_.end());
4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    completed_raster_tasks_.push_back(task);
461a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    state.type = RasterTaskState::COMPLETED;
4621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Triggers if the current task belongs to a set that should be empty.
4631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DCHECK((state.task_sets & ~NonEmptyTaskSetsFromTaskCounts(task_counts_))
4641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               .none());
4651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    RemoveTaskSetsFromTaskCounts(task_counts_, state.task_sets);
4667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
467868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
468868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() {
4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TRACE_EVENT0("cc",
4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)               "PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks");
4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
473cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Since this function can be called directly, cancel any pending checks.
474cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  check_for_completed_raster_task_notifier_.Cancel();
475cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
4761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(should_notify_client_if_no_tasks_are_pending_.any());
477868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
478a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  CheckForCompletedRasterizerTasks();
4797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  CheckForCompletedUploads();
4807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  FlushUploads();
481868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
482eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Determine what client notifications to generate.
4831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TaskSetCollection will_notify_client_that_no_tasks_are_pending =
4841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      should_notify_client_if_no_tasks_are_pending_ &
4851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ~raster_finished_tasks_pending_ & ~PendingTasks();
486eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
487eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Adjust the need to generate notifications before scheduling more tasks.
488eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  should_notify_client_if_no_tasks_are_pending_ &=
4891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ~will_notify_client_that_no_tasks_are_pending;
490eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
4917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scheduled_raster_task_count_ = 0;
492eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (PendingRasterTaskCount())
493eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ScheduleMoreTasks();
494eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
4951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  TRACE_EVENT_ASYNC_STEP_INTO1(
4965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      "cc", "ScheduledTasks", this, StateName(), "state", StateAsValue());
497eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
498eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Schedule another check for completed raster tasks while there are
499eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // pending raster tasks or pending uploads.
5001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (PendingTasks().any())
501cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    check_for_completed_raster_task_notifier_.Schedule();
502eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
5031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (should_notify_client_if_no_tasks_are_pending_.none())
504eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this);
5051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Generate client notifications.
5071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) {
5081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (will_notify_client_that_no_tasks_are_pending[task_set]) {
5091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      DCHECK(!PendingTasks()[task_set]);
5101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      client_->DidFinishRunningTasks(task_set);
5111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
512eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
513868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
514868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
515868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void PixelBufferRasterWorkerPool::ScheduleMoreTasks() {
516868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleMoreTasks");
517868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RasterTaskVector tasks[kNumberOfTaskSets];
5195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  unsigned priority = kRasterTaskPriorityBase;
5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  graph_.Reset();
523868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
524eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  size_t bytes_pending_upload = bytes_pending_upload_;
5251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TaskSetCollection did_throttle_raster_tasks;
5261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  size_t scheduled_raster_task_count = 0;
527868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
528a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (RasterTaskQueue::Item::Vector::const_iterator it =
529a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           raster_tasks_.items.begin();
530a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       it != raster_tasks_.items.end();
531a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       ++it) {
532a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const RasterTaskQueue::Item& item = *it;
533a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    RasterTask* task = item.task;
5341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DCHECK(item.task_sets.any());
535868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // |raster_task_states_| contains the state of all tasks that we have not
5375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // yet run reply callbacks for.
538a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RasterTaskState::Vector::iterator state_it =
539a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        std::find_if(raster_task_states_.begin(),
540a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     raster_task_states_.end(),
541a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     RasterTaskState::TaskComparator(task));
5425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (state_it == raster_task_states_.end())
543868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      continue;
544868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
545a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RasterTaskState& state = *state_it;
546a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
5475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Skip task if completed.
548a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (state.type == RasterTaskState::COMPLETED) {
5495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DCHECK(std::find(completed_raster_tasks_.begin(),
5505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       completed_raster_tasks_.end(),
5515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       task) != completed_raster_tasks_.end());
552868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      continue;
553868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
554868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
55503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // All raster tasks need to be throttled by bytes of pending uploads,
55603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // but if it's the only task allow it to complete no matter what its size,
55703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // to prevent starvation of the task queue.
558868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    size_t new_bytes_pending_upload = bytes_pending_upload;
559868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    new_bytes_pending_upload += task->resource()->bytes();
56003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (new_bytes_pending_upload > max_bytes_pending_upload_ &&
56103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        bytes_pending_upload) {
5621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      did_throttle_raster_tasks |= item.task_sets;
563a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      continue;
5645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
5657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // If raster has finished, just update |bytes_pending_upload|.
567a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (state.type == RasterTaskState::UPLOADING) {
568a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DCHECK(!task->HasCompleted());
5697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      bytes_pending_upload = new_bytes_pending_upload;
5707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      continue;
5717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
5727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
573eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Throttle raster tasks based on kMaxScheduledRasterTasks.
5741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (scheduled_raster_task_count >= kMaxScheduledRasterTasks) {
5751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      did_throttle_raster_tasks |= item.task_sets;
576a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      continue;
5775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
5787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
579eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Update |bytes_pending_upload| now that task has cleared all
580eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // throttling limits.
581868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bytes_pending_upload = new_bytes_pending_upload;
582868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
583a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK(state.type == RasterTaskState::UNSCHEDULED ||
584a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           state.type == RasterTaskState::SCHEDULED);
585a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    state.type = RasterTaskState::SCHEDULED;
5867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
587c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++);
5885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ++scheduled_raster_task_count;
5901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) {
5911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (item.task_sets[task_set])
5921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        tasks[task_set].container().push_back(task);
5931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
594868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
595868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
596c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Cancel existing OnRasterFinished callbacks.
597c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  raster_finished_weak_ptr_factory_.InvalidateWeakPtrs();
598c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
5991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<RasterizerTask> new_raster_finished_tasks[kNumberOfTaskSets];
6001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  size_t scheduled_task_counts[kNumberOfTaskSets] = {0};
6011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) {
6031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scheduled_task_counts[task_set] = tasks[task_set].container().size();
6041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DCHECK_LE(scheduled_task_counts[task_set], task_counts_[task_set]);
6051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Schedule OnRasterFinished call for task set only when notification is
6061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // pending and throttling is not preventing all pending tasks in the set
6071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // from being scheduled.
6081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!did_throttle_raster_tasks[task_set] &&
6091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        should_notify_client_if_no_tasks_are_pending_[task_set]) {
6101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new_raster_finished_tasks[task_set] = CreateRasterFinishedTask(
6111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          task_runner_.get(),
6121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          base::Bind(&PixelBufferRasterWorkerPool::OnRasterFinished,
6131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     raster_finished_weak_ptr_factory_.GetWeakPtr(),
6141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     task_set));
6151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      raster_finished_tasks_pending_[task_set] = true;
6161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      InsertNodeForTask(&graph_,
6171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        new_raster_finished_tasks[task_set].get(),
6181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        kRasterFinishedTaskPriority,
6191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        scheduled_task_counts[task_set]);
6201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      for (RasterTaskVector::ContainerType::const_iterator it =
6211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               tasks[task_set].container().begin();
6221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci           it != tasks[task_set].container().end();
6231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci           ++it) {
6241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        graph_.edges.push_back(
6251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            TaskGraph::Edge(*it, new_raster_finished_tasks[task_set].get()));
6261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
6275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
628eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
629868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
630eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK_LE(scheduled_raster_task_count, PendingRasterTaskCount());
631868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
632c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ScheduleTasksOnOriginThread(this, &graph_);
633c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  task_graph_runner_->ScheduleTasks(namespace_token_, &graph_);
634eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
635eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scheduled_raster_task_count_ = scheduled_raster_task_count;
636eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
6371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::copy(new_raster_finished_tasks,
6381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            new_raster_finished_tasks + kNumberOfTaskSets,
6391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            raster_finished_tasks_);
640868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
641868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
642eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochunsigned PixelBufferRasterWorkerPool::PendingRasterTaskCount() const {
643eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  unsigned num_completed_raster_tasks =
6445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      raster_tasks_with_pending_upload_.size() + completed_raster_tasks_.size();
6455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_GE(raster_task_states_.size(), num_completed_raster_tasks);
6465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return raster_task_states_.size() - num_completed_raster_tasks;
647eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
648eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
6491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTaskSetCollection PixelBufferRasterWorkerPool::PendingTasks() const {
6501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return NonEmptyTaskSetsFromTaskCounts(task_counts_);
651eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
652eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
653eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst char* PixelBufferRasterWorkerPool::StateName() const {
654eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (scheduled_raster_task_count_)
655eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return "rasterizing";
656eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (PendingRasterTaskCount())
657eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return "throttled";
6585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!raster_tasks_with_pending_upload_.empty())
659eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return "waiting_for_uploads";
660eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
661eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return "finishing";
662eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
663eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
664a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid PixelBufferRasterWorkerPool::CheckForCompletedRasterizerTasks() {
665c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  TRACE_EVENT0("cc",
666a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch               "PixelBufferRasterWorkerPool::CheckForCompletedRasterizerTasks");
667c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
668c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  task_graph_runner_->CollectCompletedTasks(namespace_token_,
669c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                            &completed_tasks_);
670a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  for (Task::Vector::const_iterator it = completed_tasks_.begin();
6715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       it != completed_tasks_.end();
6725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       ++it) {
673a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    RasterizerTask* task = static_cast<RasterizerTask*>(it->get());
6745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
675a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    RasterTask* raster_task = task->AsRasterTask();
676a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    if (!raster_task) {
677a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      task->WillComplete();
678a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      task->CompleteOnOriginThread(this);
679a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      task->DidComplete();
680a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
681a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      completed_image_decode_tasks_.push_back(task);
682a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      continue;
683a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
684a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
685a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    RasterTaskState::Vector::iterator state_it =
686a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        std::find_if(raster_task_states_.begin(),
687a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                     raster_task_states_.end(),
688a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                     RasterTaskState::TaskComparator(raster_task));
689a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    DCHECK(state_it != raster_task_states_.end());
690a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
691a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RasterTaskState& state = *state_it;
692a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK_EQ(RasterTaskState::SCHEDULED, state.type);
693a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
6941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    resource_provider_->UnmapPixelBuffer(raster_task->resource()->id());
695a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
6961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!raster_task->HasFinishedRunning()) {
6971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // When priorites change, a raster task can be canceled as a result of
6981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // no longer being of high enough priority to fit in our throttled
6991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // raster task budget. The task has not yet completed in this case.
700a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      raster_task->WillComplete();
701a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      raster_task->CompleteOnOriginThread(this);
702a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      raster_task->DidComplete();
703a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
7041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      RasterTaskQueue::Item::Vector::const_iterator item_it =
7051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          std::find_if(raster_tasks_.items.begin(),
7061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                       raster_tasks_.items.end(),
7071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                       RasterTaskQueue::Item::TaskComparator(raster_task));
7081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (item_it != raster_tasks_.items.end()) {
7091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        state.type = RasterTaskState::UNSCHEDULED;
7101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        continue;
711a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      }
712a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
713a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DCHECK(std::find(completed_raster_tasks_.begin(),
714a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       completed_raster_tasks_.end(),
715a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                       raster_task) == completed_raster_tasks_.end());
716a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      completed_raster_tasks_.push_back(raster_task);
717a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      state.type = RasterTaskState::COMPLETED;
7181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // Triggers if the current task belongs to a set that should be empty.
7191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      DCHECK((state.task_sets & ~NonEmptyTaskSetsFromTaskCounts(task_counts_))
7201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 .none());
7211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      RemoveTaskSetsFromTaskCounts(task_counts_, state.task_sets);
722a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      continue;
723a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
724a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
725a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    resource_provider_->BeginSetPixels(raster_task->resource()->id());
726a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    has_performed_uploads_since_last_flush_ = true;
727a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
728a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    bytes_pending_upload_ += raster_task->resource()->bytes();
729a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    raster_tasks_with_pending_upload_.push_back(raster_task);
730a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    state.type = RasterTaskState::UPLOADING;
7315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
7325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  completed_tasks_.clear();
7335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
7345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)scoped_refptr<base::debug::ConvertableToTraceFormat>
7365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)PixelBufferRasterWorkerPool::StateAsValue() const {
7375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_refptr<base::debug::TracedValue> state =
7385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new base::debug::TracedValue();
7395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  state->SetInteger("completed_count", completed_raster_tasks_.size());
7401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  state->BeginArray("pending_count");
7411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set)
7421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    state->AppendInteger(task_counts_[task_set]);
7431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  state->EndArray();
7445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  state->SetInteger("pending_upload_count",
7455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    raster_tasks_with_pending_upload_.size());
7465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  state->BeginDictionary("throttle_state");
7475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ThrottleStateAsValueInto(state.get());
7485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  state->EndDictionary();
7495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return state;
750eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
751eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
7525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void PixelBufferRasterWorkerPool::ThrottleStateAsValueInto(
7535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::debug::TracedValue* throttle_state) const {
754eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  throttle_state->SetInteger("bytes_available_for_upload",
7553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             max_bytes_pending_upload_ - bytes_pending_upload_);
756eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  throttle_state->SetInteger("bytes_pending_upload", bytes_pending_upload_);
757eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  throttle_state->SetInteger("scheduled_raster_task_count",
758eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                             scheduled_raster_task_count_);
759868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
760868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
761868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace cc
762