OLD | NEW |
---|---|
(Empty) | |
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. | |
4 | |
5 #include "cc/resources/image_copy_raster_worker_pool.h" | |
6 | |
7 #include <algorithm> | |
8 | |
9 #include "base/debug/trace_event.h" | |
10 #include "cc/debug/traced_value.h" | |
11 #include "cc/resources/resource_pool.h" | |
12 #include "cc/resources/scoped_resource.h" | |
13 | |
14 namespace cc { | |
15 | |
16 // static | |
17 scoped_ptr<RasterWorkerPool> ImageCopyRasterWorkerPool::Create( | |
18 base::SequencedTaskRunner* task_runner, | |
19 TaskGraphRunner* task_graph_runner, | |
20 ResourceProvider* resource_provider, | |
21 ResourcePool* resource_pool) { | |
22 return make_scoped_ptr<RasterWorkerPool>(new ImageCopyRasterWorkerPool( | |
23 task_runner, task_graph_runner, resource_provider, resource_pool)); | |
24 } | |
25 | |
26 ImageCopyRasterWorkerPool::ImageCopyRasterWorkerPool( | |
27 base::SequencedTaskRunner* task_runner, | |
28 TaskGraphRunner* task_graph_runner, | |
29 ResourceProvider* resource_provider, | |
30 ResourcePool* resource_pool) | |
31 : task_runner_(task_runner), | |
32 task_graph_runner_(task_graph_runner), | |
33 namespace_token_(task_graph_runner->GetNamespaceToken()), | |
34 resource_provider_(resource_provider), | |
35 resource_pool_(resource_pool), | |
36 has_performed_copy_since_last_flush_(false), | |
37 raster_tasks_pending_(false), | |
38 raster_tasks_required_for_activation_pending_(false), | |
39 raster_finished_weak_ptr_factory_(this) {} | |
40 | |
41 ImageCopyRasterWorkerPool::~ImageCopyRasterWorkerPool() { | |
42 DCHECK_EQ(0u, raster_task_states_.size()); | |
43 } | |
44 | |
45 Rasterizer* ImageCopyRasterWorkerPool::AsRasterizer() { return this; } | |
46 | |
47 void ImageCopyRasterWorkerPool::SetClient(RasterizerClient* client) { | |
48 client_ = client; | |
49 } | |
50 | |
51 void ImageCopyRasterWorkerPool::Shutdown() { | |
52 TRACE_EVENT0("cc", "ImageCopyRasterWorkerPool::Shutdown"); | |
53 | |
54 TaskGraph empty; | |
55 task_graph_runner_->ScheduleTasks(namespace_token_, &empty); | |
56 task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_); | |
57 } | |
58 | |
59 void ImageCopyRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) { | |
60 TRACE_EVENT0("cc", "ImageCopyRasterWorkerPool::ScheduleTasks"); | |
61 | |
62 DCHECK_EQ(queue->required_for_activation_count, | |
63 static_cast<size_t>( | |
64 std::count_if(queue->items.begin(), | |
65 queue->items.end(), | |
66 RasterTaskQueue::Item::IsRequiredForActivation))); | |
67 | |
68 if (!raster_tasks_pending_) | |
69 TRACE_EVENT_ASYNC_BEGIN0("cc", "ScheduledTasks", this); | |
70 | |
71 raster_tasks_pending_ = true; | |
72 raster_tasks_required_for_activation_pending_ = true; | |
73 | |
74 unsigned priority = kRasterTaskPriorityBase; | |
75 | |
76 graph_.Reset(); | |
77 | |
78 // Cancel existing OnRasterFinished callbacks. | |
79 raster_finished_weak_ptr_factory_.InvalidateWeakPtrs(); | |
80 | |
81 scoped_refptr<RasterizerTask> | |
82 new_raster_required_for_activation_finished_task( | |
83 CreateRasterRequiredForActivationFinishedTask( | |
84 queue->required_for_activation_count, | |
85 task_runner_.get(), | |
86 base::Bind(&ImageCopyRasterWorkerPool:: | |
87 OnRasterRequiredForActivationFinished, | |
88 raster_finished_weak_ptr_factory_.GetWeakPtr()))); | |
89 scoped_refptr<RasterizerTask> new_raster_finished_task( | |
90 CreateRasterFinishedTask( | |
91 task_runner_.get(), | |
92 base::Bind(&ImageCopyRasterWorkerPool::OnRasterFinished, | |
93 raster_finished_weak_ptr_factory_.GetWeakPtr()))); | |
94 | |
95 resource_pool_->CheckBusyResources(); | |
96 | |
97 for (RasterTaskQueue::Item::Vector::const_iterator it = queue->items.begin(); | |
98 it != queue->items.end(); | |
99 ++it) { | |
100 const RasterTaskQueue::Item& item = *it; | |
101 RasterTask* task = item.task; | |
102 DCHECK(!task->HasCompleted()); | |
103 | |
104 if (item.required_for_activation) { | |
105 graph_.edges.push_back(TaskGraph::Edge( | |
106 task, new_raster_required_for_activation_finished_task.get())); | |
107 } | |
108 | |
109 InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++); | |
110 | |
111 graph_.edges.push_back( | |
112 TaskGraph::Edge(task, new_raster_finished_task.get())); | |
113 } | |
114 | |
115 InsertNodeForTask(&graph_, | |
116 new_raster_required_for_activation_finished_task.get(), | |
117 kRasterRequiredForActivationFinishedTaskPriority, | |
118 queue->required_for_activation_count); | |
119 InsertNodeForTask(&graph_, | |
120 new_raster_finished_task.get(), | |
121 kRasterFinishedTaskPriority, | |
122 queue->items.size()); | |
123 | |
124 ScheduleTasksOnOriginThread(this, &graph_); | |
125 task_graph_runner_->ScheduleTasks(namespace_token_, &graph_); | |
126 | |
127 raster_finished_task_ = new_raster_finished_task; | |
128 raster_required_for_activation_finished_task_ = | |
129 new_raster_required_for_activation_finished_task; | |
130 | |
131 resource_pool_->ReduceResourceUsage(); | |
132 | |
133 TRACE_EVENT_ASYNC_STEP_INTO1( | |
134 "cc", | |
135 "ScheduledTasks", | |
136 this, | |
137 "rasterizing", | |
138 "state", | |
139 TracedValue::FromValue(StateAsValue().release())); | |
140 } | |
141 | |
142 void ImageCopyRasterWorkerPool::CheckForCompletedTasks() { | |
143 TRACE_EVENT0("cc", "ImageCopyRasterWorkerPool::CheckForCompletedTasks"); | |
144 | |
145 task_graph_runner_->CollectCompletedTasks(namespace_token_, | |
146 &completed_tasks_); | |
147 for (Task::Vector::const_iterator it = completed_tasks_.begin(); | |
148 it != completed_tasks_.end(); | |
149 ++it) { | |
150 RasterizerTask* task = static_cast<RasterizerTask*>(it->get()); | |
151 | |
152 task->WillComplete(); | |
153 task->CompleteOnOriginThread(this); | |
154 task->DidComplete(); | |
155 | |
156 task->RunReplyOnOriginThread(); | |
157 } | |
158 completed_tasks_.clear(); | |
159 | |
160 FlushCopies(); | |
161 } | |
162 | |
163 SkCanvas* ImageCopyRasterWorkerPool::AcquireCanvasForRaster(RasterTask* task) { | |
164 DCHECK_EQ(task->resource()->format(), resource_pool_->resource_format()); | |
165 scoped_ptr<ScopedResource> resource( | |
166 resource_pool_->AcquireResource(task->resource()->size())); | |
167 SkCanvas* canvas = resource_provider_->MapImageRasterBuffer(resource->id()); | |
168 DCHECK(std::find_if(raster_task_states_.begin(), | |
169 raster_task_states_.end(), | |
170 RasterTaskState::TaskComparator(task)) == | |
171 raster_task_states_.end()); | |
172 raster_task_states_.push_back(RasterTaskState(task, resource.release())); | |
173 return canvas; | |
174 } | |
175 | |
176 void ImageCopyRasterWorkerPool::ReleaseCanvasForRaster(RasterTask* task) { | |
177 RasterTaskState::Vector::iterator it = | |
178 std::find_if(raster_task_states_.begin(), | |
179 raster_task_states_.end(), | |
180 RasterTaskState::TaskComparator(task)); | |
181 DCHECK(it != raster_task_states_.end()); | |
182 scoped_ptr<ScopedResource> resource(it->resource); | |
183 std::swap(*it, raster_task_states_.back()); | |
184 raster_task_states_.pop_back(); | |
185 | |
186 bool content_has_changed = | |
187 resource_provider_->UnmapImageRasterBuffer(resource->id()); | |
188 | |
189 // |content_has_changed| can be false as result of task being canceled or | |
190 // task implementation deciding not to modify bitmap (ie. analysis of raster | |
191 // commands detected content as a solid color). | |
192 if (content_has_changed) { | |
193 resource_provider_->CopyResource(resource->id(), task->resource()->id()); | |
194 has_performed_copy_since_last_flush_ = true; | |
195 } | |
196 | |
197 resource_pool_->ReleaseResource(resource.Pass()); | |
vmpstr
2014/04/23 17:25:46
Will this do the right thing if copy is in progres
reveman
2014/04/24 19:20:43
Yes, the resource will be busy until the sync quer
| |
198 } | |
199 | |
200 void ImageCopyRasterWorkerPool::OnRasterFinished() { | |
201 TRACE_EVENT0("cc", "ImageCopyRasterWorkerPool::OnRasterFinished"); | |
202 | |
203 DCHECK(raster_tasks_pending_); | |
204 raster_tasks_pending_ = false; | |
205 TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this); | |
206 client_->DidFinishRunningTasks(); | |
207 } | |
208 | |
209 void ImageCopyRasterWorkerPool::OnRasterRequiredForActivationFinished() { | |
210 TRACE_EVENT0( | |
211 "cc", "ImageCopyRasterWorkerPool::OnRasterRequiredForActivationFinished"); | |
212 | |
213 DCHECK(raster_tasks_required_for_activation_pending_); | |
214 raster_tasks_required_for_activation_pending_ = false; | |
215 TRACE_EVENT_ASYNC_STEP_INTO1( | |
216 "cc", | |
217 "ScheduledTasks", | |
218 this, | |
219 "rasterizing", | |
220 "state", | |
221 TracedValue::FromValue(StateAsValue().release())); | |
222 client_->DidFinishRunningTasksRequiredForActivation(); | |
223 } | |
224 | |
225 void ImageCopyRasterWorkerPool::FlushCopies() { | |
226 if (!has_performed_copy_since_last_flush_) | |
227 return; | |
228 | |
229 resource_provider_->ShallowFlushIfSupported(); | |
230 has_performed_copy_since_last_flush_ = false; | |
231 } | |
232 | |
233 scoped_ptr<base::Value> ImageCopyRasterWorkerPool::StateAsValue() const { | |
234 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue); | |
235 | |
236 state->SetInteger("pending_count", raster_task_states_.size()); | |
237 state->SetBoolean("tasks_required_for_activation_pending", | |
238 raster_tasks_required_for_activation_pending_); | |
239 state->Set("staging_state", StagingStateAsValue().release()); | |
240 | |
241 return state.PassAs<base::Value>(); | |
242 } | |
243 scoped_ptr<base::Value> ImageCopyRasterWorkerPool::StagingStateAsValue() const { | |
244 scoped_ptr<base::DictionaryValue> staging_state(new base::DictionaryValue); | |
245 | |
246 staging_state->SetInteger("staging_resource_count", | |
247 resource_pool_->total_resource_count()); | |
248 staging_state->SetInteger("bytes_used_for_staging_resources", | |
249 resource_pool_->total_memory_usage_bytes()); | |
250 staging_state->SetInteger("pending_copy_count", | |
251 resource_pool_->total_resource_count() - | |
252 resource_pool_->acquired_resource_count()); | |
253 staging_state->SetInteger("bytes_pending_copy", | |
254 resource_pool_->total_memory_usage_bytes() - | |
255 resource_pool_->acquired_memory_usage_bytes()); | |
256 | |
257 return staging_state.PassAs<base::Value>(); | |
258 } | |
259 | |
260 } // namespace cc | |
OLD | NEW |