Upstream version 10.38.222.0
[platform/framework/web/crosswalk.git] / src / cc / resources / image_copy_raster_worker_pool.cc
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 "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"
15
16 namespace cc {
17
18 // static
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,
27                                     task_graph_runner,
28                                     context_provider,
29                                     resource_provider,
30                                     resource_pool));
31 }
32
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_);
50 }
51
52 ImageCopyRasterWorkerPool::~ImageCopyRasterWorkerPool() {
53   DCHECK_EQ(0u, raster_task_states_.size());
54 }
55
56 Rasterizer* ImageCopyRasterWorkerPool::AsRasterizer() { return this; }
57
58 void ImageCopyRasterWorkerPool::SetClient(RasterizerClient* client) {
59   client_ = client;
60 }
61
62 void ImageCopyRasterWorkerPool::Shutdown() {
63   TRACE_EVENT0("cc", "ImageCopyRasterWorkerPool::Shutdown");
64
65   TaskGraph empty;
66   task_graph_runner_->ScheduleTasks(namespace_token_, &empty);
67   task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_);
68 }
69
70 void ImageCopyRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) {
71   TRACE_EVENT0("cc", "ImageCopyRasterWorkerPool::ScheduleTasks");
72
73   DCHECK_EQ(queue->required_for_activation_count,
74             static_cast<size_t>(
75                 std::count_if(queue->items.begin(),
76                               queue->items.end(),
77                               RasterTaskQueue::Item::IsRequiredForActivation)));
78
79   if (!raster_tasks_pending_)
80     TRACE_EVENT_ASYNC_BEGIN0("cc", "ScheduledTasks", this);
81
82   raster_tasks_pending_ = true;
83   raster_tasks_required_for_activation_pending_ = true;
84
85   unsigned priority = kRasterTaskPriorityBase;
86
87   graph_.Reset();
88
89   // Cancel existing OnRasterFinished callbacks.
90   raster_finished_weak_ptr_factory_.InvalidateWeakPtrs();
91
92   scoped_refptr<RasterizerTask>
93       new_raster_required_for_activation_finished_task(
94           CreateRasterRequiredForActivationFinishedTask(
95               queue->required_for_activation_count,
96               task_runner_.get(),
97               base::Bind(&ImageCopyRasterWorkerPool::
98                              OnRasterRequiredForActivationFinished,
99                          raster_finished_weak_ptr_factory_.GetWeakPtr())));
100   scoped_refptr<RasterizerTask> new_raster_finished_task(
101       CreateRasterFinishedTask(
102           task_runner_.get(),
103           base::Bind(&ImageCopyRasterWorkerPool::OnRasterFinished,
104                      raster_finished_weak_ptr_factory_.GetWeakPtr())));
105
106   resource_pool_->CheckBusyResources();
107
108   for (RasterTaskQueue::Item::Vector::const_iterator it = queue->items.begin();
109        it != queue->items.end();
110        ++it) {
111     const RasterTaskQueue::Item& item = *it;
112     RasterTask* task = item.task;
113     DCHECK(!task->HasCompleted());
114
115     if (item.required_for_activation) {
116       graph_.edges.push_back(TaskGraph::Edge(
117           task, new_raster_required_for_activation_finished_task.get()));
118     }
119
120     InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++);
121
122     graph_.edges.push_back(
123         TaskGraph::Edge(task, new_raster_finished_task.get()));
124   }
125
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());
134
135   ScheduleTasksOnOriginThread(this, &graph_);
136   task_graph_runner_->ScheduleTasks(namespace_token_, &graph_);
137
138   raster_finished_task_ = new_raster_finished_task;
139   raster_required_for_activation_finished_task_ =
140       new_raster_required_for_activation_finished_task;
141
142   resource_pool_->ReduceResourceUsage();
143
144   TRACE_EVENT_ASYNC_STEP_INTO1(
145       "cc", "ScheduledTasks", this, "rasterizing", "state", StateAsValue());
146 }
147
148 void ImageCopyRasterWorkerPool::CheckForCompletedTasks() {
149   TRACE_EVENT0("cc", "ImageCopyRasterWorkerPool::CheckForCompletedTasks");
150
151   task_graph_runner_->CollectCompletedTasks(namespace_token_,
152                                             &completed_tasks_);
153   for (Task::Vector::const_iterator it = completed_tasks_.begin();
154        it != completed_tasks_.end();
155        ++it) {
156     RasterizerTask* task = static_cast<RasterizerTask*>(it->get());
157
158     task->WillComplete();
159     task->CompleteOnOriginThread(this);
160     task->DidComplete();
161
162     task->RunReplyOnOriginThread();
163   }
164   completed_tasks_.clear();
165
166   FlushCopies();
167 }
168
169 SkCanvas* ImageCopyRasterWorkerPool::AcquireCanvasForRaster(RasterTask* task) {
170   DCHECK_EQ(task->resource()->format(), resource_pool_->resource_format());
171   scoped_ptr<ScopedResource> resource(
172       resource_pool_->AcquireResource(task->resource()->size()));
173   SkCanvas* canvas = resource_provider_->MapImageRasterBuffer(resource->id());
174   DCHECK(std::find_if(raster_task_states_.begin(),
175                       raster_task_states_.end(),
176                       RasterTaskState::TaskComparator(task)) ==
177          raster_task_states_.end());
178   raster_task_states_.push_back(RasterTaskState(task, resource.release()));
179   return canvas;
180 }
181
182 void ImageCopyRasterWorkerPool::ReleaseCanvasForRaster(RasterTask* task) {
183   RasterTaskState::Vector::iterator it =
184       std::find_if(raster_task_states_.begin(),
185                    raster_task_states_.end(),
186                    RasterTaskState::TaskComparator(task));
187   DCHECK(it != raster_task_states_.end());
188   scoped_ptr<ScopedResource> resource(it->resource);
189   std::swap(*it, raster_task_states_.back());
190   raster_task_states_.pop_back();
191
192   bool content_has_changed =
193       resource_provider_->UnmapImageRasterBuffer(resource->id());
194
195   // |content_has_changed| can be false as result of task being canceled or
196   // task implementation deciding not to modify bitmap (ie. analysis of raster
197   // commands detected content as a solid color).
198   if (content_has_changed) {
199     resource_provider_->CopyResource(resource->id(), task->resource()->id());
200     has_performed_copy_since_last_flush_ = true;
201   }
202
203   resource_pool_->ReleaseResource(resource.Pass());
204 }
205
206 void ImageCopyRasterWorkerPool::OnRasterFinished() {
207   TRACE_EVENT0("cc", "ImageCopyRasterWorkerPool::OnRasterFinished");
208
209   DCHECK(raster_tasks_pending_);
210   raster_tasks_pending_ = false;
211   TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this);
212   client_->DidFinishRunningTasks();
213 }
214
215 void ImageCopyRasterWorkerPool::OnRasterRequiredForActivationFinished() {
216   TRACE_EVENT0(
217       "cc", "ImageCopyRasterWorkerPool::OnRasterRequiredForActivationFinished");
218
219   DCHECK(raster_tasks_required_for_activation_pending_);
220   raster_tasks_required_for_activation_pending_ = false;
221   TRACE_EVENT_ASYNC_STEP_INTO1(
222       "cc", "ScheduledTasks", this, "rasterizing", "state", StateAsValue());
223   client_->DidFinishRunningTasksRequiredForActivation();
224 }
225
226 void ImageCopyRasterWorkerPool::FlushCopies() {
227   if (!has_performed_copy_since_last_flush_)
228     return;
229
230   context_provider_->ContextGL()->ShallowFlushCHROMIUM();
231   has_performed_copy_since_last_flush_ = false;
232 }
233
234 scoped_refptr<base::debug::ConvertableToTraceFormat>
235 ImageCopyRasterWorkerPool::StateAsValue() const {
236   scoped_refptr<base::debug::TracedValue> state =
237       new base::debug::TracedValue();
238
239   state->SetInteger("pending_count", raster_task_states_.size());
240   state->SetBoolean("tasks_required_for_activation_pending",
241                     raster_tasks_required_for_activation_pending_);
242   state->BeginDictionary("staging_state");
243   StagingStateAsValueInto(state.get());
244   state->EndDictionary();
245
246   return state;
247 }
248 void ImageCopyRasterWorkerPool::StagingStateAsValueInto(
249     base::debug::TracedValue* staging_state) const {
250   staging_state->SetInteger("staging_resource_count",
251                             resource_pool_->total_resource_count());
252   staging_state->SetInteger("bytes_used_for_staging_resources",
253                             resource_pool_->total_memory_usage_bytes());
254   staging_state->SetInteger("pending_copy_count",
255                             resource_pool_->total_resource_count() -
256                                 resource_pool_->acquired_resource_count());
257   staging_state->SetInteger("bytes_pending_copy",
258                             resource_pool_->total_memory_usage_bytes() -
259                                 resource_pool_->acquired_memory_usage_bytes());
260 }
261
262 }  // namespace cc