Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / cc / resources / direct_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/direct_raster_worker_pool.h"
6
7 #include "base/debug/trace_event.h"
8 #include "cc/output/context_provider.h"
9 #include "cc/resources/resource.h"
10 #include "cc/resources/resource_provider.h"
11 #include "gpu/command_buffer/client/gles2_interface.h"
12 #include "third_party/skia/include/gpu/GrContext.h"
13
14 namespace cc {
15
16 // static
17 scoped_ptr<RasterWorkerPool> DirectRasterWorkerPool::Create(
18     base::SequencedTaskRunner* task_runner,
19     ResourceProvider* resource_provider,
20     ContextProvider* context_provider) {
21   return make_scoped_ptr<RasterWorkerPool>(new DirectRasterWorkerPool(
22       task_runner, resource_provider, context_provider));
23 }
24
25 DirectRasterWorkerPool::DirectRasterWorkerPool(
26     base::SequencedTaskRunner* task_runner,
27     ResourceProvider* resource_provider,
28     ContextProvider* context_provider)
29     : task_runner_(task_runner),
30       task_graph_runner_(new TaskGraphRunner),
31       namespace_token_(task_graph_runner_->GetNamespaceToken()),
32       resource_provider_(resource_provider),
33       context_provider_(context_provider),
34       run_tasks_on_origin_thread_pending_(false),
35       raster_tasks_pending_(false),
36       raster_tasks_required_for_activation_pending_(false),
37       raster_finished_weak_ptr_factory_(this),
38       weak_ptr_factory_(this) {}
39
40 DirectRasterWorkerPool::~DirectRasterWorkerPool() {
41   DCHECK_EQ(0u, completed_tasks_.size());
42 }
43
44 Rasterizer* DirectRasterWorkerPool::AsRasterizer() { return this; }
45
46 void DirectRasterWorkerPool::SetClient(RasterizerClient* client) {
47   client_ = client;
48 }
49
50 void DirectRasterWorkerPool::Shutdown() {
51   TRACE_EVENT0("cc", "DirectRasterWorkerPool::Shutdown");
52
53   TaskGraph empty;
54   task_graph_runner_->ScheduleTasks(namespace_token_, &empty);
55   task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_);
56 }
57
58 void DirectRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) {
59   TRACE_EVENT0("cc", "DirectRasterWorkerPool::ScheduleTasks");
60
61   DCHECK_EQ(queue->required_for_activation_count,
62             static_cast<size_t>(
63                 std::count_if(queue->items.begin(),
64                               queue->items.end(),
65                               RasterTaskQueue::Item::IsRequiredForActivation)));
66
67   raster_tasks_pending_ = true;
68   raster_tasks_required_for_activation_pending_ = true;
69
70   unsigned priority = kRasterTaskPriorityBase;
71
72   graph_.Reset();
73
74   // Cancel existing OnRasterFinished callbacks.
75   raster_finished_weak_ptr_factory_.InvalidateWeakPtrs();
76
77   scoped_refptr<RasterizerTask>
78       new_raster_required_for_activation_finished_task(
79           CreateRasterRequiredForActivationFinishedTask(
80               queue->required_for_activation_count,
81               task_runner_.get(),
82               base::Bind(&DirectRasterWorkerPool::
83                              OnRasterRequiredForActivationFinished,
84                          raster_finished_weak_ptr_factory_.GetWeakPtr())));
85   scoped_refptr<RasterizerTask> new_raster_finished_task(
86       CreateRasterFinishedTask(
87           task_runner_.get(),
88           base::Bind(&DirectRasterWorkerPool::OnRasterFinished,
89                      raster_finished_weak_ptr_factory_.GetWeakPtr())));
90
91   for (RasterTaskQueue::Item::Vector::const_iterator it = queue->items.begin();
92        it != queue->items.end();
93        ++it) {
94     const RasterTaskQueue::Item& item = *it;
95     RasterTask* task = item.task;
96     DCHECK(!task->HasCompleted());
97
98     if (item.required_for_activation) {
99       graph_.edges.push_back(TaskGraph::Edge(
100           task, new_raster_required_for_activation_finished_task.get()));
101     }
102
103     InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++);
104
105     graph_.edges.push_back(
106         TaskGraph::Edge(task, new_raster_finished_task.get()));
107   }
108
109   InsertNodeForTask(&graph_,
110                     new_raster_required_for_activation_finished_task.get(),
111                     kRasterRequiredForActivationFinishedTaskPriority,
112                     queue->required_for_activation_count);
113   InsertNodeForTask(&graph_,
114                     new_raster_finished_task.get(),
115                     kRasterFinishedTaskPriority,
116                     queue->items.size());
117
118   ScheduleTasksOnOriginThread(this, &graph_);
119   task_graph_runner_->ScheduleTasks(namespace_token_, &graph_);
120
121   ScheduleRunTasksOnOriginThread();
122
123   raster_finished_task_ = new_raster_finished_task;
124   raster_required_for_activation_finished_task_ =
125       new_raster_required_for_activation_finished_task;
126 }
127
128 void DirectRasterWorkerPool::CheckForCompletedTasks() {
129   TRACE_EVENT0("cc", "DirectRasterWorkerPool::CheckForCompletedTasks");
130
131   task_graph_runner_->CollectCompletedTasks(namespace_token_,
132                                             &completed_tasks_);
133   for (Task::Vector::const_iterator it = completed_tasks_.begin();
134        it != completed_tasks_.end();
135        ++it) {
136     RasterizerTask* task = static_cast<RasterizerTask*>(it->get());
137
138     task->WillComplete();
139     task->CompleteOnOriginThread(this);
140     task->DidComplete();
141
142     task->RunReplyOnOriginThread();
143   }
144   completed_tasks_.clear();
145 }
146
147 SkCanvas* DirectRasterWorkerPool::AcquireCanvasForRaster(RasterTask* task) {
148   return resource_provider_->MapDirectRasterBuffer(task->resource()->id());
149 }
150
151 void DirectRasterWorkerPool::ReleaseCanvasForRaster(RasterTask* task) {
152   resource_provider_->UnmapDirectRasterBuffer(task->resource()->id());
153 }
154
155 void DirectRasterWorkerPool::OnRasterFinished() {
156   TRACE_EVENT0("cc", "DirectRasterWorkerPool::OnRasterFinished");
157
158   DCHECK(raster_tasks_pending_);
159   raster_tasks_pending_ = false;
160   client_->DidFinishRunningTasks();
161 }
162
163 void DirectRasterWorkerPool::OnRasterRequiredForActivationFinished() {
164   TRACE_EVENT0("cc",
165                "DirectRasterWorkerPool::OnRasterRequiredForActivationFinished");
166
167   DCHECK(raster_tasks_required_for_activation_pending_);
168   raster_tasks_required_for_activation_pending_ = false;
169   client_->DidFinishRunningTasksRequiredForActivation();
170 }
171
172 void DirectRasterWorkerPool::ScheduleRunTasksOnOriginThread() {
173   if (run_tasks_on_origin_thread_pending_)
174     return;
175
176   task_runner_->PostTask(
177       FROM_HERE,
178       base::Bind(&DirectRasterWorkerPool::RunTasksOnOriginThread,
179                  weak_ptr_factory_.GetWeakPtr()));
180   run_tasks_on_origin_thread_pending_ = true;
181 }
182
183 void DirectRasterWorkerPool::RunTasksOnOriginThread() {
184   TRACE_EVENT0("cc", "DirectRasterWorkerPool::RunTasksOnOriginThread");
185
186   DCHECK(run_tasks_on_origin_thread_pending_);
187   run_tasks_on_origin_thread_pending_ = false;
188
189   if (context_provider_) {
190     DCHECK(context_provider_->ContextGL());
191     // TODO(alokp): Use a trace macro to push/pop markers.
192     // Using push/pop functions directly incurs cost to evaluate function
193     // arguments even when tracing is disabled.
194     context_provider_->ContextGL()->PushGroupMarkerEXT(
195         0, "DirectRasterWorkerPool::RunTasksOnOriginThread");
196
197     GrContext* gr_context = context_provider_->GrContext();
198     // TODO(alokp): Implement TestContextProvider::GrContext().
199     if (gr_context)
200       gr_context->resetContext();
201   }
202
203   task_graph_runner_->RunUntilIdle();
204
205   if (context_provider_) {
206     GrContext* gr_context = context_provider_->GrContext();
207     // TODO(alokp): Implement TestContextProvider::GrContext().
208     if (gr_context)
209       gr_context->flush();
210
211     context_provider_->ContextGL()->PopGroupMarkerEXT();
212   }
213 }
214
215 }  // namespace cc