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/image_raster_worker_pool.h"
6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/debug/trace_event.h"
8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "cc/debug/traced_value.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "cc/resources/resource.h"
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace cc {
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static
14a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochscoped_ptr<RasterWorkerPool> ImageRasterWorkerPool::Create(
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::SequencedTaskRunner* task_runner,
16a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    TaskGraphRunner* task_graph_runner,
17a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    ResourceProvider* resource_provider) {
18a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  return make_scoped_ptr<RasterWorkerPool>(new ImageRasterWorkerPool(
19a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      task_runner, task_graph_runner, resource_provider));
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ImageRasterWorkerPool::ImageRasterWorkerPool(
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::SequencedTaskRunner* task_runner,
24a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    TaskGraphRunner* task_graph_runner,
25a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    ResourceProvider* resource_provider)
26c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    : task_runner_(task_runner),
27c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      task_graph_runner_(task_graph_runner),
28c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      namespace_token_(task_graph_runner->GetNamespaceToken()),
29c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      resource_provider_(resource_provider),
30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      raster_tasks_pending_(false),
31c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      raster_tasks_required_for_activation_pending_(false),
32c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      raster_finished_weak_ptr_factory_(this) {}
33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ImageRasterWorkerPool::~ImageRasterWorkerPool() {}
35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
36a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochRasterizer* ImageRasterWorkerPool::AsRasterizer() { return this; }
37a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
38a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid ImageRasterWorkerPool::SetClient(RasterizerClient* client) {
39c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  client_ = client;
40c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
41c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
42c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid ImageRasterWorkerPool::Shutdown() {
43c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  TRACE_EVENT0("cc", "ImageRasterWorkerPool::Shutdown");
44c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
45a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  TaskGraph empty;
46c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  task_graph_runner_->ScheduleTasks(namespace_token_, &empty);
47c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_);
48c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
49c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ImageRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) {
51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  TRACE_EVENT0("cc", "ImageRasterWorkerPool::ScheduleTasks");
52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK_EQ(queue->required_for_activation_count,
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            static_cast<size_t>(
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                std::count_if(queue->items.begin(),
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              queue->items.end(),
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              RasterTaskQueue::Item::IsRequiredForActivation)));
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!raster_tasks_pending_)
60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    TRACE_EVENT_ASYNC_BEGIN0("cc", "ScheduledTasks", this);
61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  raster_tasks_pending_ = true;
63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  raster_tasks_required_for_activation_pending_ = true;
64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  unsigned priority = kRasterTaskPriorityBase;
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  graph_.Reset();
68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
69c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Cancel existing OnRasterFinished callbacks.
70c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  raster_finished_weak_ptr_factory_.InvalidateWeakPtrs();
71c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
72a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  scoped_refptr<RasterizerTask>
73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new_raster_required_for_activation_finished_task(
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          CreateRasterRequiredForActivationFinishedTask(
75c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch              queue->required_for_activation_count,
76c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch              task_runner_.get(),
77c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch              base::Bind(
78c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                  &ImageRasterWorkerPool::OnRasterRequiredForActivationFinished,
79c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                  raster_finished_weak_ptr_factory_.GetWeakPtr())));
80a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  scoped_refptr<RasterizerTask> new_raster_finished_task(
81c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      CreateRasterFinishedTask(
82c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          task_runner_.get(),
83c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          base::Bind(&ImageRasterWorkerPool::OnRasterFinished,
84c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                     raster_finished_weak_ptr_factory_.GetWeakPtr())));
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (RasterTaskQueue::Item::Vector::const_iterator it = queue->items.begin();
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       it != queue->items.end();
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       ++it) {
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const RasterTaskQueue::Item& item = *it;
90a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    RasterTask* task = item.task;
91d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    DCHECK(!task->HasCompleted());
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (item.required_for_activation) {
94a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      graph_.edges.push_back(TaskGraph::Edge(
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          task, new_raster_required_for_activation_finished_task.get()));
96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
98c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++);
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    graph_.edges.push_back(
101a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        TaskGraph::Edge(task, new_raster_finished_task.get()));
102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  InsertNodeForTask(&graph_,
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    new_raster_required_for_activation_finished_task.get(),
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    kRasterRequiredForActivationFinishedTaskPriority,
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    queue->required_for_activation_count);
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  InsertNodeForTask(&graph_,
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    new_raster_finished_task.get(),
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    kRasterFinishedTaskPriority,
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    queue->items.size());
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
113c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ScheduleTasksOnOriginThread(this, &graph_);
114c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  task_graph_runner_->ScheduleTasks(namespace_token_, &graph_);
115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
116c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  raster_finished_task_ = new_raster_finished_task;
117c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  raster_required_for_activation_finished_task_ =
118c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      new_raster_required_for_activation_finished_task;
119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  TRACE_EVENT_ASYNC_STEP_INTO1(
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "cc",
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "ScheduledTasks",
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      this,
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "rasterizing",
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "state",
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      TracedValue::FromValue(StateAsValue().release()));
127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ImageRasterWorkerPool::CheckForCompletedTasks() {
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TRACE_EVENT0("cc", "ImageRasterWorkerPool::CheckForCompletedTasks");
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
132c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  task_graph_runner_->CollectCompletedTasks(namespace_token_,
133c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                            &completed_tasks_);
134a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  for (Task::Vector::const_iterator it = completed_tasks_.begin();
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       it != completed_tasks_.end();
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       ++it) {
137a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    RasterizerTask* task = static_cast<RasterizerTask*>(it->get());
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    task->WillComplete();
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    task->CompleteOnOriginThread(this);
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    task->DidComplete();
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    task->RunReplyOnOriginThread();
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  completed_tasks_.clear();
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
148a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochSkCanvas* ImageRasterWorkerPool::AcquireCanvasForRaster(RasterTask* task) {
149a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  return resource_provider_->MapImageRasterBuffer(task->resource()->id());
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
152a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid ImageRasterWorkerPool::ReleaseCanvasForRaster(RasterTask* task) {
153a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  resource_provider_->UnmapImageRasterBuffer(task->resource()->id());
154a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
155a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // Map/UnmapImageRasterBuffer provides direct access to the memory used by the
156a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // GPU. Read lock fences are required to ensure that we're not trying to map a
157a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // resource that is currently in-use by the GPU.
158a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  resource_provider_->EnableReadLockFences(task->resource()->id(), true);
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
161c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid ImageRasterWorkerPool::OnRasterFinished() {
162c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  TRACE_EVENT0("cc", "ImageRasterWorkerPool::OnRasterFinished");
163c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(raster_tasks_pending_);
165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  raster_tasks_pending_ = false;
166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this);
167c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  client_->DidFinishRunningTasks();
168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
170c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid ImageRasterWorkerPool::OnRasterRequiredForActivationFinished() {
171c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  TRACE_EVENT0("cc",
172c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch               "ImageRasterWorkerPool::OnRasterRequiredForActivationFinished");
173c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(raster_tasks_required_for_activation_pending_);
175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  raster_tasks_required_for_activation_pending_ = false;
1761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  TRACE_EVENT_ASYNC_STEP_INTO1(
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "cc",
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "ScheduledTasks",
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      this,
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "rasterizing",
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "state",
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      TracedValue::FromValue(StateAsValue().release()));
183c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  client_->DidFinishRunningTasksRequiredForActivation();
184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochscoped_ptr<base::Value> ImageRasterWorkerPool::StateAsValue() const {
187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue);
188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  state->SetBoolean("tasks_required_for_activation_pending",
190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                    raster_tasks_required_for_activation_pending_);
191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return state.PassAs<base::Value>();
192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace cc
195