1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/resources/image_raster_worker_pool.h"
7 #include "base/debug/trace_event.h"
8 #include "cc/debug/traced_value.h"
9 #include "cc/resources/resource.h"
14 scoped_ptr
<RasterWorkerPool
> ImageRasterWorkerPool::Create(
15 base::SequencedTaskRunner
* task_runner
,
16 TaskGraphRunner
* task_graph_runner
,
17 ResourceProvider
* resource_provider
) {
18 return make_scoped_ptr
<RasterWorkerPool
>(new ImageRasterWorkerPool(
19 task_runner
, task_graph_runner
, resource_provider
));
22 ImageRasterWorkerPool::ImageRasterWorkerPool(
23 base::SequencedTaskRunner
* task_runner
,
24 TaskGraphRunner
* task_graph_runner
,
25 ResourceProvider
* resource_provider
)
26 : task_runner_(task_runner
),
27 task_graph_runner_(task_graph_runner
),
28 namespace_token_(task_graph_runner
->GetNamespaceToken()),
29 resource_provider_(resource_provider
),
30 raster_tasks_pending_(false),
31 raster_tasks_required_for_activation_pending_(false),
32 raster_finished_weak_ptr_factory_(this) {}
34 ImageRasterWorkerPool::~ImageRasterWorkerPool() {}
36 Rasterizer
* ImageRasterWorkerPool::AsRasterizer() { return this; }
38 void ImageRasterWorkerPool::SetClient(RasterizerClient
* client
) {
42 void ImageRasterWorkerPool::Shutdown() {
43 TRACE_EVENT0("cc", "ImageRasterWorkerPool::Shutdown");
46 task_graph_runner_
->ScheduleTasks(namespace_token_
, &empty
);
47 task_graph_runner_
->WaitForTasksToFinishRunning(namespace_token_
);
50 void ImageRasterWorkerPool::ScheduleTasks(RasterTaskQueue
* queue
) {
51 TRACE_EVENT0("cc", "ImageRasterWorkerPool::ScheduleTasks");
53 DCHECK_EQ(queue
->required_for_activation_count
,
55 std::count_if(queue
->items
.begin(),
57 RasterTaskQueue::Item::IsRequiredForActivation
)));
59 if (!raster_tasks_pending_
)
60 TRACE_EVENT_ASYNC_BEGIN0("cc", "ScheduledTasks", this);
62 raster_tasks_pending_
= true;
63 raster_tasks_required_for_activation_pending_
= true;
65 unsigned priority
= kRasterTaskPriorityBase
;
69 // Cancel existing OnRasterFinished callbacks.
70 raster_finished_weak_ptr_factory_
.InvalidateWeakPtrs();
72 scoped_refptr
<RasterizerTask
>
73 new_raster_required_for_activation_finished_task(
74 CreateRasterRequiredForActivationFinishedTask(
75 queue
->required_for_activation_count
,
78 &ImageRasterWorkerPool::OnRasterRequiredForActivationFinished
,
79 raster_finished_weak_ptr_factory_
.GetWeakPtr())));
80 scoped_refptr
<RasterizerTask
> new_raster_finished_task(
81 CreateRasterFinishedTask(
83 base::Bind(&ImageRasterWorkerPool::OnRasterFinished
,
84 raster_finished_weak_ptr_factory_
.GetWeakPtr())));
86 for (RasterTaskQueue::Item::Vector::const_iterator it
= queue
->items
.begin();
87 it
!= queue
->items
.end();
89 const RasterTaskQueue::Item
& item
= *it
;
90 RasterTask
* task
= item
.task
;
91 DCHECK(!task
->HasCompleted());
93 if (item
.required_for_activation
) {
94 graph_
.edges
.push_back(TaskGraph::Edge(
95 task
, new_raster_required_for_activation_finished_task
.get()));
98 InsertNodesForRasterTask(&graph_
, task
, task
->dependencies(), priority
++);
100 graph_
.edges
.push_back(
101 TaskGraph::Edge(task
, new_raster_finished_task
.get()));
104 InsertNodeForTask(&graph_
,
105 new_raster_required_for_activation_finished_task
.get(),
106 kRasterRequiredForActivationFinishedTaskPriority
,
107 queue
->required_for_activation_count
);
108 InsertNodeForTask(&graph_
,
109 new_raster_finished_task
.get(),
110 kRasterFinishedTaskPriority
,
111 queue
->items
.size());
113 ScheduleTasksOnOriginThread(this, &graph_
);
114 task_graph_runner_
->ScheduleTasks(namespace_token_
, &graph_
);
116 raster_finished_task_
= new_raster_finished_task
;
117 raster_required_for_activation_finished_task_
=
118 new_raster_required_for_activation_finished_task
;
120 TRACE_EVENT_ASYNC_STEP_INTO1(
126 TracedValue::FromValue(StateAsValue().release()));
129 void ImageRasterWorkerPool::CheckForCompletedTasks() {
130 TRACE_EVENT0("cc", "ImageRasterWorkerPool::CheckForCompletedTasks");
132 task_graph_runner_
->CollectCompletedTasks(namespace_token_
,
134 for (Task::Vector::const_iterator it
= completed_tasks_
.begin();
135 it
!= completed_tasks_
.end();
137 RasterizerTask
* task
= static_cast<RasterizerTask
*>(it
->get());
139 task
->WillComplete();
140 task
->CompleteOnOriginThread(this);
143 task
->RunReplyOnOriginThread();
145 completed_tasks_
.clear();
148 SkCanvas
* ImageRasterWorkerPool::AcquireCanvasForRaster(RasterTask
* task
) {
149 return resource_provider_
->MapImageRasterBuffer(task
->resource()->id());
152 void ImageRasterWorkerPool::ReleaseCanvasForRaster(RasterTask
* task
) {
153 resource_provider_
->UnmapImageRasterBuffer(task
->resource()->id());
155 // Map/UnmapImageRasterBuffer provides direct access to the memory used by the
156 // GPU. Read lock fences are required to ensure that we're not trying to map a
157 // resource that is currently in-use by the GPU.
158 resource_provider_
->EnableReadLockFences(task
->resource()->id(), true);
161 void ImageRasterWorkerPool::OnRasterFinished() {
162 TRACE_EVENT0("cc", "ImageRasterWorkerPool::OnRasterFinished");
164 DCHECK(raster_tasks_pending_
);
165 raster_tasks_pending_
= false;
166 TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this);
167 client_
->DidFinishRunningTasks();
170 void ImageRasterWorkerPool::OnRasterRequiredForActivationFinished() {
172 "ImageRasterWorkerPool::OnRasterRequiredForActivationFinished");
174 DCHECK(raster_tasks_required_for_activation_pending_
);
175 raster_tasks_required_for_activation_pending_
= false;
176 TRACE_EVENT_ASYNC_STEP_INTO1(
182 TracedValue::FromValue(StateAsValue().release()));
183 client_
->DidFinishRunningTasksRequiredForActivation();
186 scoped_ptr
<base::Value
> ImageRasterWorkerPool::StateAsValue() const {
187 scoped_ptr
<base::DictionaryValue
> state(new base::DictionaryValue
);
189 state
->SetBoolean("tasks_required_for_activation_pending",
190 raster_tasks_required_for_activation_pending_
);
191 return state
.PassAs
<base::Value
>();