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/gpu_tile_task_worker_pool.h" | |
6 | |
7 #include <algorithm> | |
8 | |
9 #include "base/trace_event/trace_event.h" | |
10 #include "cc/resources/gpu_rasterizer.h" | |
11 #include "cc/resources/raster_buffer.h" | |
12 #include "cc/resources/raster_source.h" | |
13 #include "cc/resources/resource.h" | |
14 #include "cc/resources/scoped_gpu_raster.h" | |
15 #include "gpu/command_buffer/client/gles2_interface.h" | |
16 #include "third_party/skia/include/core/SkMultiPictureDraw.h" | |
17 #include "third_party/skia/include/core/SkPictureRecorder.h" | |
18 #include "third_party/skia/include/core/SkSurface.h" | |
19 #include "third_party/skia/include/gpu/GrContext.h" | |
20 | |
21 namespace cc { | |
22 namespace { | |
23 | |
24 class RasterBufferImpl : public RasterBuffer { | |
25 public: | |
26 RasterBufferImpl(GpuRasterizer* rasterizer, const Resource* resource) | |
27 : rasterizer_(rasterizer), | |
28 lock_(rasterizer->resource_provider(), resource->id()), | |
29 resource_(resource) {} | |
30 | |
31 // Overridden from RasterBuffer: | |
32 void Playback(const RasterSource* raster_source, | |
33 const gfx::Rect& rect, | |
34 float scale) override { | |
35 TRACE_EVENT0("cc", "RasterBufferImpl::Playback"); | |
36 ContextProvider* context_provider = rasterizer_->resource_provider() | |
37 ->output_surface() | |
38 ->worker_context_provider(); | |
39 | |
40 // The context lock must be held while accessing the context on a | |
41 // worker thread. | |
42 base::AutoLock context_lock(*context_provider->GetLock()); | |
43 | |
44 // Allow this worker thread to bind to context_provider. | |
45 context_provider->DetachFromThread(); | |
46 | |
47 // Rasterize source into resource. | |
48 rasterizer_->RasterizeSource(true, &lock_, raster_source, rect, scale); | |
49 | |
50 // Barrier to sync worker context output to cc context. | |
51 context_provider->ContextGL()->OrderingBarrierCHROMIUM(); | |
52 | |
53 // Allow compositor thread to bind to context_provider. | |
54 context_provider->DetachFromThread(); | |
55 } | |
56 | |
57 private: | |
58 GpuRasterizer* rasterizer_; | |
59 ResourceProvider::ScopedWriteLockGr lock_; | |
60 const Resource* resource_; | |
61 | |
62 DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl); | |
63 }; | |
64 | |
65 } // namespace | |
66 | |
67 // static | |
68 scoped_ptr<TileTaskWorkerPool> GpuTileTaskWorkerPool::Create( | |
69 base::SequencedTaskRunner* task_runner, | |
70 TaskGraphRunner* task_graph_runner, | |
71 GpuRasterizer* rasterizer) { | |
72 return make_scoped_ptr<TileTaskWorkerPool>( | |
73 new GpuTileTaskWorkerPool(task_runner, task_graph_runner, rasterizer)); | |
74 } | |
75 | |
76 GpuTileTaskWorkerPool::GpuTileTaskWorkerPool( | |
77 base::SequencedTaskRunner* task_runner, | |
78 TaskGraphRunner* task_graph_runner, | |
79 GpuRasterizer* rasterizer) | |
80 : task_runner_(task_runner), | |
81 task_graph_runner_(task_graph_runner), | |
82 namespace_token_(task_graph_runner_->GetNamespaceToken()), | |
83 rasterizer_(rasterizer), | |
84 task_set_finished_weak_ptr_factory_(this), | |
85 weak_ptr_factory_(this) { | |
86 } | |
87 | |
88 GpuTileTaskWorkerPool::~GpuTileTaskWorkerPool() { | |
89 DCHECK_EQ(0u, completed_tasks_.size()); | |
90 } | |
91 | |
92 TileTaskRunner* GpuTileTaskWorkerPool::AsTileTaskRunner() { | |
93 return this; | |
94 } | |
95 | |
96 void GpuTileTaskWorkerPool::SetClient(TileTaskRunnerClient* client) { | |
97 client_ = client; | |
98 } | |
99 | |
100 void GpuTileTaskWorkerPool::Shutdown() { | |
101 TRACE_EVENT0("cc", "GpuTileTaskWorkerPool::Shutdown"); | |
102 | |
103 TaskGraph empty; | |
104 task_graph_runner_->ScheduleTasks(namespace_token_, &empty); | |
105 task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_); | |
106 } | |
107 | |
108 void GpuTileTaskWorkerPool::ScheduleTasks(TileTaskQueue* queue) { | |
109 TRACE_EVENT0("cc", "GpuTileTaskWorkerPool::ScheduleTasks"); | |
110 | |
111 // Mark all task sets as pending. | |
112 tasks_pending_.set(); | |
113 | |
114 unsigned priority = kTileTaskPriorityBase; | |
115 | |
116 graph_.Reset(); | |
117 | |
118 // Cancel existing OnTaskSetFinished callbacks. | |
119 task_set_finished_weak_ptr_factory_.InvalidateWeakPtrs(); | |
120 | |
121 scoped_refptr<TileTask> new_task_set_finished_tasks[kNumberOfTaskSets]; | |
122 | |
123 size_t task_count[kNumberOfTaskSets] = {0}; | |
124 | |
125 for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) { | |
126 new_task_set_finished_tasks[task_set] = CreateTaskSetFinishedTask( | |
127 task_runner_.get(), | |
128 base::Bind(&GpuTileTaskWorkerPool::OnTaskSetFinished, | |
129 task_set_finished_weak_ptr_factory_.GetWeakPtr(), task_set)); | |
130 } | |
131 | |
132 for (TileTaskQueue::Item::Vector::const_iterator it = queue->items.begin(); | |
133 it != queue->items.end(); ++it) { | |
134 const TileTaskQueue::Item& item = *it; | |
135 RasterTask* task = item.task; | |
136 DCHECK(!task->HasCompleted()); | |
137 | |
138 for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) { | |
139 if (!item.task_sets[task_set]) | |
140 continue; | |
141 | |
142 ++task_count[task_set]; | |
143 | |
144 graph_.edges.push_back( | |
145 TaskGraph::Edge(task, new_task_set_finished_tasks[task_set].get())); | |
146 } | |
147 | |
148 InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++); | |
149 } | |
150 | |
151 for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) { | |
152 InsertNodeForTask(&graph_, new_task_set_finished_tasks[task_set].get(), | |
153 kTaskSetFinishedTaskPriorityBase + task_set, | |
154 task_count[task_set]); | |
155 } | |
156 | |
157 ScheduleTasksOnOriginThread(this, &graph_); | |
158 | |
159 // Barrier to sync any new resources to the worker context. | |
160 rasterizer_->resource_provider() | |
161 ->output_surface() | |
162 ->context_provider() | |
163 ->ContextGL() | |
164 ->OrderingBarrierCHROMIUM(); | |
165 | |
166 task_graph_runner_->ScheduleTasks(namespace_token_, &graph_); | |
167 | |
168 std::copy(new_task_set_finished_tasks, | |
169 new_task_set_finished_tasks + kNumberOfTaskSets, | |
170 task_set_finished_tasks_); | |
171 } | |
172 | |
173 void GpuTileTaskWorkerPool::CheckForCompletedTasks() { | |
174 TRACE_EVENT0("cc", "GpuTileTaskWorkerPool::CheckForCompletedTasks"); | |
175 | |
176 task_graph_runner_->CollectCompletedTasks(namespace_token_, | |
177 &completed_tasks_); | |
178 CompleteTasks(completed_tasks_); | |
179 completed_tasks_.clear(); | |
180 } | |
181 | |
182 ResourceFormat GpuTileTaskWorkerPool::GetResourceFormat() { | |
183 return rasterizer_->resource_provider()->best_texture_format(); | |
184 } | |
185 | |
186 void GpuTileTaskWorkerPool::CompleteTasks(const Task::Vector& tasks) { | |
187 for (auto& task : tasks) { | |
188 RasterTask* raster_task = static_cast<RasterTask*>(task.get()); | |
189 | |
190 raster_task->WillComplete(); | |
191 raster_task->CompleteOnOriginThread(this); | |
192 raster_task->DidComplete(); | |
193 | |
194 raster_task->RunReplyOnOriginThread(); | |
195 } | |
196 completed_tasks_.clear(); | |
197 } | |
198 | |
199 scoped_ptr<RasterBuffer> GpuTileTaskWorkerPool::AcquireBufferForRaster( | |
200 const Resource* resource) { | |
201 return make_scoped_ptr<RasterBuffer>( | |
202 new RasterBufferImpl(rasterizer_, resource)); | |
203 } | |
204 | |
205 void GpuTileTaskWorkerPool::ReleaseBufferForRaster( | |
206 scoped_ptr<RasterBuffer> buffer) { | |
207 // Nothing to do here. RasterBufferImpl destructor cleans up after itself. | |
208 } | |
209 | |
210 void GpuTileTaskWorkerPool::OnTaskSetFinished(TaskSet task_set) { | |
211 TRACE_EVENT1("cc", "GpuTileTaskWorkerPool::OnTaskSetFinished", "task_set", | |
212 task_set); | |
213 | |
214 DCHECK(tasks_pending_[task_set]); | |
215 tasks_pending_[task_set] = false; | |
216 client_->DidFinishRunningTileTasks(task_set); | |
217 } | |
218 | |
219 } // namespace cc | |
OLD | NEW |