Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / cc / resources / gpu_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/gpu_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 "cc/resources/scoped_gpu_raster.h"
12 #include "gpu/command_buffer/client/gles2_interface.h"
13 #include "third_party/skia/include/gpu/GrContext.h"
14
15 namespace cc {
16
17 // static
18 scoped_ptr<RasterWorkerPool> GpuRasterWorkerPool::Create(
19     base::SequencedTaskRunner* task_runner,
20     ContextProvider* context_provider,
21     ResourceProvider* resource_provider) {
22   return make_scoped_ptr<RasterWorkerPool>(new GpuRasterWorkerPool(
23       task_runner, context_provider, resource_provider));
24 }
25
26 GpuRasterWorkerPool::GpuRasterWorkerPool(base::SequencedTaskRunner* task_runner,
27                                          ContextProvider* context_provider,
28                                          ResourceProvider* resource_provider)
29     : task_runner_(task_runner),
30       task_graph_runner_(new TaskGraphRunner),
31       namespace_token_(task_graph_runner_->GetNamespaceToken()),
32       context_provider_(context_provider),
33       resource_provider_(resource_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   DCHECK(context_provider_);
40 }
41
42 GpuRasterWorkerPool::~GpuRasterWorkerPool() {
43   DCHECK_EQ(0u, completed_tasks_.size());
44 }
45
46 Rasterizer* GpuRasterWorkerPool::AsRasterizer() {
47   return this;
48 }
49
50 void GpuRasterWorkerPool::SetClient(RasterizerClient* client) {
51   client_ = client;
52 }
53
54 void GpuRasterWorkerPool::Shutdown() {
55   TRACE_EVENT0("cc", "GpuRasterWorkerPool::Shutdown");
56
57   TaskGraph empty;
58   task_graph_runner_->ScheduleTasks(namespace_token_, &empty);
59   task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_);
60 }
61
62 void GpuRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) {
63   TRACE_EVENT0("cc", "GpuRasterWorkerPool::ScheduleTasks");
64
65   DCHECK_EQ(queue->required_for_activation_count,
66             static_cast<size_t>(
67                 std::count_if(queue->items.begin(),
68                               queue->items.end(),
69                               RasterTaskQueue::Item::IsRequiredForActivation)));
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(
87                   &GpuRasterWorkerPool::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(&GpuRasterWorkerPool::OnRasterFinished,
93                      raster_finished_weak_ptr_factory_.GetWeakPtr())));
94
95   for (RasterTaskQueue::Item::Vector::const_iterator it = queue->items.begin();
96        it != queue->items.end();
97        ++it) {
98     const RasterTaskQueue::Item& item = *it;
99     RasterTask* task = item.task;
100     DCHECK(!task->HasCompleted());
101
102     if (item.required_for_activation) {
103       graph_.edges.push_back(TaskGraph::Edge(
104           task, new_raster_required_for_activation_finished_task.get()));
105     }
106
107     InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++);
108
109     graph_.edges.push_back(
110         TaskGraph::Edge(task, new_raster_finished_task.get()));
111   }
112
113   InsertNodeForTask(&graph_,
114                     new_raster_required_for_activation_finished_task.get(),
115                     kRasterRequiredForActivationFinishedTaskPriority,
116                     queue->required_for_activation_count);
117   InsertNodeForTask(&graph_,
118                     new_raster_finished_task.get(),
119                     kRasterFinishedTaskPriority,
120                     queue->items.size());
121
122   ScheduleTasksOnOriginThread(this, &graph_);
123   task_graph_runner_->ScheduleTasks(namespace_token_, &graph_);
124
125   ScheduleRunTasksOnOriginThread();
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
132 void GpuRasterWorkerPool::CheckForCompletedTasks() {
133   TRACE_EVENT0("cc", "GpuRasterWorkerPool::CheckForCompletedTasks");
134
135   task_graph_runner_->CollectCompletedTasks(namespace_token_,
136                                             &completed_tasks_);
137   for (Task::Vector::const_iterator it = completed_tasks_.begin();
138        it != completed_tasks_.end();
139        ++it) {
140     RasterizerTask* task = static_cast<RasterizerTask*>(it->get());
141
142     task->WillComplete();
143     task->CompleteOnOriginThread(this);
144     task->DidComplete();
145
146     task->RunReplyOnOriginThread();
147   }
148   completed_tasks_.clear();
149 }
150
151 SkCanvas* GpuRasterWorkerPool::AcquireCanvasForRaster(RasterTask* task) {
152   return resource_provider_->MapGpuRasterBuffer(task->resource()->id());
153 }
154
155 void GpuRasterWorkerPool::ReleaseCanvasForRaster(RasterTask* task) {
156   resource_provider_->UnmapGpuRasterBuffer(task->resource()->id());
157 }
158
159 void GpuRasterWorkerPool::OnRasterFinished() {
160   TRACE_EVENT0("cc", "GpuRasterWorkerPool::OnRasterFinished");
161
162   DCHECK(raster_tasks_pending_);
163   raster_tasks_pending_ = false;
164   client_->DidFinishRunningTasks();
165 }
166
167 void GpuRasterWorkerPool::OnRasterRequiredForActivationFinished() {
168   TRACE_EVENT0("cc",
169                "GpuRasterWorkerPool::OnRasterRequiredForActivationFinished");
170
171   DCHECK(raster_tasks_required_for_activation_pending_);
172   raster_tasks_required_for_activation_pending_ = false;
173   client_->DidFinishRunningTasksRequiredForActivation();
174 }
175
176 void GpuRasterWorkerPool::ScheduleRunTasksOnOriginThread() {
177   if (run_tasks_on_origin_thread_pending_)
178     return;
179
180   task_runner_->PostTask(
181       FROM_HERE,
182       base::Bind(&GpuRasterWorkerPool::RunTasksOnOriginThread,
183                  weak_ptr_factory_.GetWeakPtr()));
184   run_tasks_on_origin_thread_pending_ = true;
185 }
186
187 void GpuRasterWorkerPool::RunTasksOnOriginThread() {
188   TRACE_EVENT0("cc", "GpuRasterWorkerPool::RunTasksOnOriginThread");
189
190   DCHECK(run_tasks_on_origin_thread_pending_);
191   run_tasks_on_origin_thread_pending_ = false;
192
193   ScopedGpuRaster gpu_raster(context_provider_);
194   task_graph_runner_->RunUntilIdle();
195 }
196
197 }  // namespace cc