OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "cc/resources/gpu_tile_task_worker_pool.h" | 5 #include "cc/resources/gpu_tile_task_worker_pool.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
| 9 #include "base/threading/platform_thread.h" |
9 #include "base/trace_event/trace_event.h" | 10 #include "base/trace_event/trace_event.h" |
| 11 #include "cc/output/context_provider.h" |
10 #include "cc/resources/raster_buffer.h" | 12 #include "cc/resources/raster_buffer.h" |
11 #include "cc/resources/raster_source.h" | 13 #include "cc/resources/raster_source.h" |
12 #include "cc/resources/resource.h" | 14 #include "cc/resources/resource.h" |
13 #include "cc/resources/scoped_gpu_raster.h" | 15 #include "cc/resources/scoped_gpu_raster.h" |
14 #include "gpu/command_buffer/client/gles2_interface.h" | 16 #include "gpu/command_buffer/client/gles2_interface.h" |
15 #include "third_party/skia/include/core/SkMultiPictureDraw.h" | 17 #include "third_party/skia/include/core/SkMultiPictureDraw.h" |
16 #include "third_party/skia/include/core/SkPictureRecorder.h" | 18 #include "third_party/skia/include/core/SkPictureRecorder.h" |
17 #include "third_party/skia/include/core/SkSurface.h" | 19 #include "third_party/skia/include/core/SkSurface.h" |
18 #include "third_party/skia/include/gpu/GrContext.h" | 20 #include "third_party/skia/include/gpu/GrContext.h" |
| 21 using gpu::gles2::GLES2Interface; |
19 | 22 |
20 namespace cc { | 23 namespace cc { |
21 namespace { | 24 namespace { |
22 | 25 |
23 class RasterBufferImpl : public RasterBuffer { | 26 class RasterBufferImpl : public RasterBuffer { |
24 public: | 27 public: |
25 RasterBufferImpl() {} | 28 RasterBufferImpl(ResourceProvider* resource_provider, |
| 29 const Resource* resource, |
| 30 bool use_distance_field_text) |
| 31 : lock_(resource_provider, resource->id()), |
| 32 resource_provider_(resource_provider), |
| 33 resource_(resource), |
| 34 sk_surface_(nullptr), |
| 35 use_distance_field_text_(use_distance_field_text) {} |
26 | 36 |
27 // Overridden from RasterBuffer: | 37 // Overridden from RasterBuffer: |
28 void Playback(const RasterSource* raster_source, | 38 void Playback(const RasterSource* raster_source, |
29 const gfx::Rect& rect, | 39 const gfx::Rect& rect, |
30 float scale) override { | 40 float scale) override { |
31 // Don't do anything. | 41 TRACE_EVENT0("cc", "RasterBufferImpl::Playback"); |
| 42 |
| 43 // Play back raster_source into temp SkPicture. |
| 44 SkPictureRecorder recorder; |
| 45 gfx::Size size = resource_->size(); |
| 46 const int flags = SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag; |
| 47 skia::RefPtr<SkCanvas> canvas = skia::SharePtr( |
| 48 recorder.beginRecording(size.width(), size.height(), NULL, flags)); |
| 49 |
| 50 canvas->save(); |
| 51 raster_source->PlaybackToCanvas(canvas.get(), rect, scale); |
| 52 canvas->restore(); |
| 53 |
| 54 skia::RefPtr<SkPicture> picture = skia::AdoptRef(recorder.endRecording()); |
| 55 |
| 56 // Bind ContextProvider to current thread. |
| 57 resource_provider_->output_surface() |
| 58 ->worker_context_provider() |
| 59 ->RebindToCurrentThread(); |
| 60 |
| 61 // Draw picture to Resource's texture. |
| 62 { |
| 63 ScopedGpuRaster gpu_raster( |
| 64 resource_provider_->output_surface()->worker_context_provider()); |
| 65 |
| 66 skia::RefPtr<SkSurface> sk_surface = skia::AdoptRef( |
| 67 lock_.GetSkSurface(use_distance_field_text_, false, 0)); |
| 68 |
| 69 #ifdef TODO_VMIURA_SINGLE_PICTURE_PLAYBACK |
| 70 // This doesn't work if layer hoisting is enabled :(. |
| 71 picture->playback(sk_surface->getCanvas(), nullptr); |
| 72 #else |
| 73 // This works... |
| 74 SkMultiPictureDraw multi_picture_draw; |
| 75 multi_picture_draw.add(sk_surface->getCanvas(), picture.get()); |
| 76 multi_picture_draw.draw(false); |
| 77 #endif |
| 78 sk_surface.clear(); |
| 79 } |
| 80 |
| 81 // Save Flush point after this tile, which the cc thread executes |
| 82 // via SafeFlush(). |
| 83 resource_provider_->output_surface() |
| 84 ->worker_context_provider() |
| 85 ->ContextGL() |
| 86 ->SetSafeFlushPoint(); |
32 } | 87 } |
33 | 88 |
34 private: | 89 private: |
| 90 ResourceProvider::ScopedWriteLockGr lock_; |
| 91 ResourceProvider* resource_provider_; |
| 92 const Resource* resource_; |
| 93 SkSurface* sk_surface_; |
| 94 bool use_distance_field_text_; |
| 95 |
35 DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl); | 96 DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl); |
36 }; | 97 }; |
37 | 98 |
38 } // namespace | 99 } // namespace |
| 100 |
39 // static | 101 // static |
40 scoped_ptr<TileTaskWorkerPool> GpuTileTaskWorkerPool::Create( | 102 scoped_ptr<TileTaskWorkerPool> GpuTileTaskWorkerPool::Create( |
41 base::SequencedTaskRunner* task_runner, | 103 base::SequencedTaskRunner* task_runner, |
42 TaskGraphRunner* task_graph_runner, | 104 TaskGraphRunner* task_graph_runner, |
43 ResourceProvider* resource_provider) { | 105 ResourceProvider* resource_provider) { |
44 return make_scoped_ptr<TileTaskWorkerPool>( | 106 return make_scoped_ptr<TileTaskWorkerPool>(new GpuTileTaskWorkerPool( |
45 new GpuTileTaskWorkerPool( | 107 task_runner, task_graph_runner, resource_provider)); |
46 task_runner, task_graph_runner, resource_provider)); | |
47 } | 108 } |
48 | 109 |
49 // TODO(hendrikw): This class should be removed. See crbug.com/444938. | 110 // TODO(hendrikw): This class should be removed. See crbug.com/444938. |
50 GpuTileTaskWorkerPool::GpuTileTaskWorkerPool( | 111 GpuTileTaskWorkerPool::GpuTileTaskWorkerPool( |
51 base::SequencedTaskRunner* task_runner, | 112 base::SequencedTaskRunner* task_runner, |
52 TaskGraphRunner* task_graph_runner, | 113 TaskGraphRunner* task_graph_runner, |
53 ResourceProvider* resource_provider) | 114 ResourceProvider* resource_provider) |
54 : task_runner_(task_runner), | 115 : task_runner_(task_runner), |
55 task_graph_runner_(task_graph_runner), | 116 task_graph_runner_(task_graph_runner), |
| 117 resource_provider_(resource_provider), |
56 namespace_token_(task_graph_runner_->GetNamespaceToken()), | 118 namespace_token_(task_graph_runner_->GetNamespaceToken()), |
57 resource_provider_(resource_provider), | |
58 task_set_finished_weak_ptr_factory_(this), | 119 task_set_finished_weak_ptr_factory_(this), |
59 weak_ptr_factory_(this) { | 120 weak_ptr_factory_(this) { |
60 } | 121 } |
61 | 122 |
62 GpuTileTaskWorkerPool::~GpuTileTaskWorkerPool() { | 123 GpuTileTaskWorkerPool::~GpuTileTaskWorkerPool() { |
63 DCHECK_EQ(0u, completed_tasks_.size()); | 124 DCHECK_EQ(0u, completed_tasks_.size()); |
64 } | 125 } |
65 | 126 |
66 TileTaskRunner* GpuTileTaskWorkerPool::AsTileTaskRunner() { | 127 TileTaskRunner* GpuTileTaskWorkerPool::AsTileTaskRunner() { |
67 return this; | 128 return this; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) { | 160 for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) { |
100 new_task_set_finished_tasks[task_set] = CreateTaskSetFinishedTask( | 161 new_task_set_finished_tasks[task_set] = CreateTaskSetFinishedTask( |
101 task_runner_.get(), | 162 task_runner_.get(), |
102 base::Bind(&GpuTileTaskWorkerPool::OnTaskSetFinished, | 163 base::Bind(&GpuTileTaskWorkerPool::OnTaskSetFinished, |
103 task_set_finished_weak_ptr_factory_.GetWeakPtr(), task_set)); | 164 task_set_finished_weak_ptr_factory_.GetWeakPtr(), task_set)); |
104 } | 165 } |
105 | 166 |
106 for (TileTaskQueue::Item::Vector::const_iterator it = queue->items.begin(); | 167 for (TileTaskQueue::Item::Vector::const_iterator it = queue->items.begin(); |
107 it != queue->items.end(); ++it) { | 168 it != queue->items.end(); ++it) { |
108 const TileTaskQueue::Item& item = *it; | 169 const TileTaskQueue::Item& item = *it; |
109 RasterTask* task = item.task; | 170 RasterTask* task = item.task->AsRasterTask(); |
| 171 DCHECK(task); |
110 DCHECK(!task->HasCompleted()); | 172 DCHECK(!task->HasCompleted()); |
111 | 173 |
112 for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) { | 174 for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) { |
113 if (!item.task_sets[task_set]) | 175 if (!item.task_sets[task_set]) |
114 continue; | 176 continue; |
115 | 177 |
116 ++task_count[task_set]; | 178 ++task_count[task_set]; |
117 | 179 |
118 graph_.edges.push_back( | 180 graph_.edges.push_back( |
119 TaskGraph::Edge(task, new_task_set_finished_tasks[task_set].get())); | 181 TaskGraph::Edge(task, new_task_set_finished_tasks[task_set].get())); |
120 } | 182 } |
121 | 183 |
122 InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++); | 184 InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++); |
123 } | 185 } |
124 | 186 |
125 for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) { | 187 for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) { |
126 InsertNodeForTask(&graph_, new_task_set_finished_tasks[task_set].get(), | 188 InsertNodeForTask(&graph_, new_task_set_finished_tasks[task_set].get(), |
127 kTaskSetFinishedTaskPriorityBase + task_set, | 189 kTaskSetFinishedTaskPriorityBase + task_set, |
128 task_count[task_set]); | 190 task_count[task_set]); |
129 } | 191 } |
130 | 192 |
131 ScheduleTasksOnOriginThread(this, &graph_); | 193 ScheduleTasksOnOriginThread(this, &graph_); |
| 194 |
| 195 // Flush compositor context to sync resources to worker context. |
| 196 resource_provider_->output_surface() |
| 197 ->context_provider() |
| 198 ->ContextGL() |
| 199 ->ShallowFlushCHROMIUM(); |
| 200 |
132 task_graph_runner_->ScheduleTasks(namespace_token_, &graph_); | 201 task_graph_runner_->ScheduleTasks(namespace_token_, &graph_); |
133 | 202 |
134 std::copy(new_task_set_finished_tasks, | 203 std::copy(new_task_set_finished_tasks, |
135 new_task_set_finished_tasks + kNumberOfTaskSets, | 204 new_task_set_finished_tasks + kNumberOfTaskSets, |
136 task_set_finished_tasks_); | 205 task_set_finished_tasks_); |
137 } | 206 } |
138 | 207 |
139 void GpuTileTaskWorkerPool::CheckForCompletedTasks() { | 208 void GpuTileTaskWorkerPool::CheckForCompletedTasks() { |
140 TRACE_EVENT0("cc", "GpuTileTaskWorkerPool::CheckForCompletedTasks"); | 209 TRACE_EVENT0("cc", "GpuTileTaskWorkerPool::CheckForCompletedTasks"); |
141 | 210 |
142 task_graph_runner_->CollectCompletedTasks(namespace_token_, | 211 task_graph_runner_->CollectCompletedTasks(namespace_token_, |
143 &completed_tasks_); | 212 &completed_tasks_); |
| 213 |
| 214 // Flush worker context so raster outputs are synced to the compositor |
| 215 // context. |
| 216 resource_provider_->output_surface() |
| 217 ->worker_context_provider() |
| 218 ->ContextGL() |
| 219 ->SafeFlush(); |
| 220 |
144 CompleteTasks(completed_tasks_); | 221 CompleteTasks(completed_tasks_); |
145 completed_tasks_.clear(); | 222 completed_tasks_.clear(); |
146 } | 223 } |
147 | 224 |
148 ResourceFormat GpuTileTaskWorkerPool::GetResourceFormat() { | 225 ResourceFormat GpuTileTaskWorkerPool::GetResourceFormat() { |
149 return resource_provider_->best_texture_format(); | 226 return resource_provider_->best_texture_format(); |
150 } | 227 } |
151 | 228 |
152 void GpuTileTaskWorkerPool::CompleteTasks(const Task::Vector& tasks) { | 229 void GpuTileTaskWorkerPool::CompleteTasks(const Task::Vector& tasks) { |
153 for (auto& task : tasks) { | 230 for (auto& task : tasks) { |
154 RasterTask* raster_task = static_cast<RasterTask*>(task.get()); | 231 RasterTask* raster_task = static_cast<RasterTask*>(task.get()); |
155 | 232 |
156 raster_task->WillComplete(); | 233 raster_task->WillComplete(); |
157 raster_task->CompleteOnOriginThread(this); | 234 raster_task->CompleteOnOriginThread(this); |
158 raster_task->DidComplete(); | 235 raster_task->DidComplete(); |
159 | 236 |
160 raster_task->RunReplyOnOriginThread(); | 237 raster_task->RunReplyOnOriginThread(); |
161 } | 238 } |
162 completed_tasks_.clear(); | 239 completed_tasks_.clear(); |
163 } | 240 } |
164 | 241 |
165 scoped_ptr<RasterBuffer> GpuTileTaskWorkerPool::AcquireBufferForRaster( | 242 scoped_ptr<RasterBuffer> GpuTileTaskWorkerPool::AcquireBufferForRaster( |
166 const Resource* resource) { | 243 const Resource* resource) { |
167 return make_scoped_ptr<RasterBuffer>(new RasterBufferImpl()); | 244 bool use_distance_field_text = false; |
| 245 return make_scoped_ptr<RasterBuffer>(new RasterBufferImpl( |
| 246 resource_provider_, resource, use_distance_field_text)); |
168 } | 247 } |
169 | 248 |
170 void GpuTileTaskWorkerPool::ReleaseBufferForRaster( | 249 void GpuTileTaskWorkerPool::ReleaseBufferForRaster( |
171 scoped_ptr<RasterBuffer> buffer) { | 250 scoped_ptr<RasterBuffer> buffer) { |
172 // Nothing to do here. RasterBufferImpl destructor cleans up after itself. | 251 // Nothing to do here. RasterBufferImpl destructor cleans up after itself. |
173 } | 252 } |
174 | 253 |
175 void GpuTileTaskWorkerPool::OnTaskSetFinished(TaskSet task_set) { | 254 void GpuTileTaskWorkerPool::OnTaskSetFinished(TaskSet task_set) { |
176 TRACE_EVENT1("cc", "GpuTileTaskWorkerPool::OnTaskSetFinished", "task_set", | 255 TRACE_EVENT1("cc", "GpuTileTaskWorkerPool::OnTaskSetFinished", "task_set", |
177 task_set); | 256 task_set); |
178 | 257 |
179 DCHECK(tasks_pending_[task_set]); | 258 DCHECK(tasks_pending_[task_set]); |
180 tasks_pending_[task_set] = false; | 259 tasks_pending_[task_set] = false; |
181 client_->DidFinishRunningTileTasks(task_set); | 260 client_->DidFinishRunningTileTasks(task_set); |
182 } | 261 } |
183 | 262 |
184 } // namespace cc | 263 } // namespace cc |
OLD | NEW |