1 // Copyright 2014 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_copy_raster_worker_pool.h"
9 #include "base/debug/trace_event.h"
10 #include "base/debug/trace_event_argument.h"
11 #include "cc/debug/traced_value.h"
12 #include "cc/resources/resource_pool.h"
13 #include "cc/resources/scoped_resource.h"
14 #include "gpu/command_buffer/client/gles2_interface.h"
19 scoped_ptr
<RasterWorkerPool
> ImageCopyRasterWorkerPool::Create(
20 base::SequencedTaskRunner
* task_runner
,
21 TaskGraphRunner
* task_graph_runner
,
22 ContextProvider
* context_provider
,
23 ResourceProvider
* resource_provider
,
24 ResourcePool
* resource_pool
) {
25 return make_scoped_ptr
<RasterWorkerPool
>(
26 new ImageCopyRasterWorkerPool(task_runner
,
33 ImageCopyRasterWorkerPool::ImageCopyRasterWorkerPool(
34 base::SequencedTaskRunner
* task_runner
,
35 TaskGraphRunner
* task_graph_runner
,
36 ContextProvider
* context_provider
,
37 ResourceProvider
* resource_provider
,
38 ResourcePool
* resource_pool
)
39 : task_runner_(task_runner
),
40 task_graph_runner_(task_graph_runner
),
41 namespace_token_(task_graph_runner
->GetNamespaceToken()),
42 context_provider_(context_provider
),
43 resource_provider_(resource_provider
),
44 resource_pool_(resource_pool
),
45 has_performed_copy_since_last_flush_(false),
46 raster_tasks_pending_(false),
47 raster_tasks_required_for_activation_pending_(false),
48 raster_finished_weak_ptr_factory_(this) {
49 DCHECK(context_provider_
);
52 ImageCopyRasterWorkerPool::~ImageCopyRasterWorkerPool() {
53 DCHECK_EQ(0u, raster_task_states_
.size());
56 Rasterizer
* ImageCopyRasterWorkerPool::AsRasterizer() { return this; }
58 void ImageCopyRasterWorkerPool::SetClient(RasterizerClient
* client
) {
62 void ImageCopyRasterWorkerPool::Shutdown() {
63 TRACE_EVENT0("cc", "ImageCopyRasterWorkerPool::Shutdown");
66 task_graph_runner_
->ScheduleTasks(namespace_token_
, &empty
);
67 task_graph_runner_
->WaitForTasksToFinishRunning(namespace_token_
);
70 void ImageCopyRasterWorkerPool::ScheduleTasks(RasterTaskQueue
* queue
) {
71 TRACE_EVENT0("cc", "ImageCopyRasterWorkerPool::ScheduleTasks");
73 DCHECK_EQ(queue
->required_for_activation_count
,
75 std::count_if(queue
->items
.begin(),
77 RasterTaskQueue::Item::IsRequiredForActivation
)));
79 if (!raster_tasks_pending_
)
80 TRACE_EVENT_ASYNC_BEGIN0("cc", "ScheduledTasks", this);
82 raster_tasks_pending_
= true;
83 raster_tasks_required_for_activation_pending_
= true;
85 unsigned priority
= kRasterTaskPriorityBase
;
89 // Cancel existing OnRasterFinished callbacks.
90 raster_finished_weak_ptr_factory_
.InvalidateWeakPtrs();
92 scoped_refptr
<RasterizerTask
>
93 new_raster_required_for_activation_finished_task(
94 CreateRasterRequiredForActivationFinishedTask(
95 queue
->required_for_activation_count
,
97 base::Bind(&ImageCopyRasterWorkerPool::
98 OnRasterRequiredForActivationFinished
,
99 raster_finished_weak_ptr_factory_
.GetWeakPtr())));
100 scoped_refptr
<RasterizerTask
> new_raster_finished_task(
101 CreateRasterFinishedTask(
103 base::Bind(&ImageCopyRasterWorkerPool::OnRasterFinished
,
104 raster_finished_weak_ptr_factory_
.GetWeakPtr())));
106 resource_pool_
->CheckBusyResources();
108 for (RasterTaskQueue::Item::Vector::const_iterator it
= queue
->items
.begin();
109 it
!= queue
->items
.end();
111 const RasterTaskQueue::Item
& item
= *it
;
112 RasterTask
* task
= item
.task
;
113 DCHECK(!task
->HasCompleted());
115 if (item
.required_for_activation
) {
116 graph_
.edges
.push_back(TaskGraph::Edge(
117 task
, new_raster_required_for_activation_finished_task
.get()));
120 InsertNodesForRasterTask(&graph_
, task
, task
->dependencies(), priority
++);
122 graph_
.edges
.push_back(
123 TaskGraph::Edge(task
, new_raster_finished_task
.get()));
126 InsertNodeForTask(&graph_
,
127 new_raster_required_for_activation_finished_task
.get(),
128 kRasterRequiredForActivationFinishedTaskPriority
,
129 queue
->required_for_activation_count
);
130 InsertNodeForTask(&graph_
,
131 new_raster_finished_task
.get(),
132 kRasterFinishedTaskPriority
,
133 queue
->items
.size());
135 ScheduleTasksOnOriginThread(this, &graph_
);
136 task_graph_runner_
->ScheduleTasks(namespace_token_
, &graph_
);
138 raster_finished_task_
= new_raster_finished_task
;
139 raster_required_for_activation_finished_task_
=
140 new_raster_required_for_activation_finished_task
;
142 resource_pool_
->ReduceResourceUsage();
144 TRACE_EVENT_ASYNC_STEP_INTO1(
145 "cc", "ScheduledTasks", this, "rasterizing", "state", StateAsValue());
148 void ImageCopyRasterWorkerPool::CheckForCompletedTasks() {
149 TRACE_EVENT0("cc", "ImageCopyRasterWorkerPool::CheckForCompletedTasks");
151 task_graph_runner_
->CollectCompletedTasks(namespace_token_
,
153 for (Task::Vector::const_iterator it
= completed_tasks_
.begin();
154 it
!= completed_tasks_
.end();
156 RasterizerTask
* task
= static_cast<RasterizerTask
*>(it
->get());
158 task
->WillComplete();
159 task
->CompleteOnOriginThread(this);
162 task
->RunReplyOnOriginThread();
164 completed_tasks_
.clear();
169 RasterBuffer
* ImageCopyRasterWorkerPool::AcquireBufferForRaster(
171 DCHECK_EQ(task
->resource()->format(), resource_pool_
->resource_format());
172 scoped_ptr
<ScopedResource
> resource(
173 resource_pool_
->AcquireResource(task
->resource()->size()));
174 RasterBuffer
* raster_buffer
=
175 resource_provider_
->AcquireImageRasterBuffer(resource
->id());
176 DCHECK(std::find_if(raster_task_states_
.begin(),
177 raster_task_states_
.end(),
178 RasterTaskState::TaskComparator(task
)) ==
179 raster_task_states_
.end());
180 raster_task_states_
.push_back(RasterTaskState(task
, resource
.release()));
181 return raster_buffer
;
184 void ImageCopyRasterWorkerPool::ReleaseBufferForRaster(RasterTask
* task
) {
185 RasterTaskState::Vector::iterator it
=
186 std::find_if(raster_task_states_
.begin(),
187 raster_task_states_
.end(),
188 RasterTaskState::TaskComparator(task
));
189 DCHECK(it
!= raster_task_states_
.end());
190 scoped_ptr
<ScopedResource
> resource(it
->resource
);
191 std::swap(*it
, raster_task_states_
.back());
192 raster_task_states_
.pop_back();
194 bool content_has_changed
=
195 resource_provider_
->ReleaseImageRasterBuffer(resource
->id());
197 // |content_has_changed| can be false as result of task being canceled or
198 // task implementation deciding not to modify bitmap (ie. analysis of raster
199 // commands detected content as a solid color).
200 if (content_has_changed
) {
201 resource_provider_
->CopyResource(resource
->id(), task
->resource()->id());
202 has_performed_copy_since_last_flush_
= true;
205 resource_pool_
->ReleaseResource(resource
.Pass());
208 void ImageCopyRasterWorkerPool::OnRasterFinished() {
209 TRACE_EVENT0("cc", "ImageCopyRasterWorkerPool::OnRasterFinished");
211 DCHECK(raster_tasks_pending_
);
212 raster_tasks_pending_
= false;
213 TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this);
214 client_
->DidFinishRunningTasks();
217 void ImageCopyRasterWorkerPool::OnRasterRequiredForActivationFinished() {
219 "cc", "ImageCopyRasterWorkerPool::OnRasterRequiredForActivationFinished");
221 DCHECK(raster_tasks_required_for_activation_pending_
);
222 raster_tasks_required_for_activation_pending_
= false;
223 TRACE_EVENT_ASYNC_STEP_INTO1(
224 "cc", "ScheduledTasks", this, "rasterizing", "state", StateAsValue());
225 client_
->DidFinishRunningTasksRequiredForActivation();
228 void ImageCopyRasterWorkerPool::FlushCopies() {
229 if (!has_performed_copy_since_last_flush_
)
232 context_provider_
->ContextGL()->ShallowFlushCHROMIUM();
233 has_performed_copy_since_last_flush_
= false;
236 scoped_refptr
<base::debug::ConvertableToTraceFormat
>
237 ImageCopyRasterWorkerPool::StateAsValue() const {
238 scoped_refptr
<base::debug::TracedValue
> state
=
239 new base::debug::TracedValue();
241 state
->SetInteger("pending_count", raster_task_states_
.size());
242 state
->SetBoolean("tasks_required_for_activation_pending",
243 raster_tasks_required_for_activation_pending_
);
244 state
->BeginDictionary("staging_state");
245 StagingStateAsValueInto(state
.get());
246 state
->EndDictionary();
250 void ImageCopyRasterWorkerPool::StagingStateAsValueInto(
251 base::debug::TracedValue
* staging_state
) const {
252 staging_state
->SetInteger("staging_resource_count",
253 resource_pool_
->total_resource_count());
254 staging_state
->SetInteger("bytes_used_for_staging_resources",
255 resource_pool_
->total_memory_usage_bytes());
256 staging_state
->SetInteger("pending_copy_count",
257 resource_pool_
->total_resource_count() -
258 resource_pool_
->acquired_resource_count());
259 staging_state
->SetInteger("bytes_pending_copy",
260 resource_pool_
->total_memory_usage_bytes() -
261 resource_pool_
->acquired_memory_usage_bytes());