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/image_copy_raster_worker_pool.h" | 5 #include "cc/resources/image_copy_raster_worker_pool.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
10 #include "base/debug/trace_event_argument.h" | 10 #include "base/debug/trace_event_argument.h" |
11 #include "base/strings/stringprintf.h" | 11 #include "base/strings/stringprintf.h" |
12 #include "cc/debug/traced_value.h" | 12 #include "cc/debug/traced_value.h" |
| 13 #include "cc/resources/raster_buffer.h" |
13 #include "cc/resources/resource_pool.h" | 14 #include "cc/resources/resource_pool.h" |
14 #include "cc/resources/scoped_resource.h" | 15 #include "cc/resources/scoped_resource.h" |
15 #include "gpu/command_buffer/client/gles2_interface.h" | 16 #include "gpu/command_buffer/client/gles2_interface.h" |
| 17 #include "third_party/skia/include/utils/SkNullCanvas.h" |
16 | 18 |
17 namespace cc { | 19 namespace cc { |
| 20 namespace { |
| 21 |
| 22 class RasterBufferImpl : public RasterBuffer { |
| 23 public: |
| 24 RasterBufferImpl(ResourceProvider* resource_provider, |
| 25 ResourcePool* resource_pool, |
| 26 const Resource* resource) |
| 27 : resource_provider_(resource_provider), |
| 28 resource_pool_(resource_pool), |
| 29 resource_(resource), |
| 30 raster_resource_(resource_pool->AcquireResource(resource->size())), |
| 31 buffer_(NULL), |
| 32 stride_(0) { |
| 33 // Acquire and map image for raster resource. |
| 34 resource_provider_->AcquireImage(raster_resource_->id()); |
| 35 buffer_ = resource_provider_->MapImage(raster_resource_->id(), &stride_); |
| 36 } |
| 37 |
| 38 virtual ~RasterBufferImpl() { |
| 39 // First unmap image for raster resource. |
| 40 resource_provider_->UnmapImage(raster_resource_->id()); |
| 41 |
| 42 // Copy contents of raster resource to |resource_|. |
| 43 resource_provider_->CopyResource(raster_resource_->id(), resource_->id()); |
| 44 |
| 45 // This RasterBuffer implementation provides direct access to the memory |
| 46 // used by the GPU. Read lock fences are required to ensure that we're not |
| 47 // trying to map a resource that is currently in-use by the GPU. |
| 48 resource_provider_->EnableReadLockFences(raster_resource_->id()); |
| 49 |
| 50 // Return raster resource to pool so it can be used by another RasterBuffer |
| 51 // instance. |
| 52 resource_pool_->ReleaseResource(raster_resource_.Pass()); |
| 53 } |
| 54 |
| 55 // Overridden from RasterBuffer: |
| 56 virtual skia::RefPtr<SkCanvas> AcquireSkCanvas() OVERRIDE { |
| 57 if (!buffer_) |
| 58 return skia::AdoptRef(SkCreateNullCanvas()); |
| 59 |
| 60 RasterWorkerPool::AcquireBitmapForBuffer( |
| 61 &bitmap_, buffer_, resource_->format(), resource_->size(), stride_); |
| 62 return skia::AdoptRef(new SkCanvas(bitmap_)); |
| 63 } |
| 64 virtual void ReleaseSkCanvas(const skia::RefPtr<SkCanvas>& canvas) OVERRIDE { |
| 65 if (!buffer_) |
| 66 return; |
| 67 |
| 68 RasterWorkerPool::ReleaseBitmapForBuffer( |
| 69 &bitmap_, buffer_, resource_->format()); |
| 70 } |
| 71 |
| 72 private: |
| 73 ResourceProvider* resource_provider_; |
| 74 ResourcePool* resource_pool_; |
| 75 const Resource* resource_; |
| 76 scoped_ptr<ScopedResource> raster_resource_; |
| 77 uint8_t* buffer_; |
| 78 int stride_; |
| 79 SkBitmap bitmap_; |
| 80 |
| 81 DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl); |
| 82 }; |
| 83 |
| 84 } // namespace |
18 | 85 |
19 // static | 86 // static |
20 scoped_ptr<RasterWorkerPool> ImageCopyRasterWorkerPool::Create( | 87 scoped_ptr<RasterWorkerPool> ImageCopyRasterWorkerPool::Create( |
21 base::SequencedTaskRunner* task_runner, | 88 base::SequencedTaskRunner* task_runner, |
22 TaskGraphRunner* task_graph_runner, | 89 TaskGraphRunner* task_graph_runner, |
23 ContextProvider* context_provider, | 90 ContextProvider* context_provider, |
24 ResourceProvider* resource_provider, | 91 ResourceProvider* resource_provider, |
25 ResourcePool* resource_pool) { | 92 ResourcePool* resource_pool) { |
26 return make_scoped_ptr<RasterWorkerPool>( | 93 return make_scoped_ptr<RasterWorkerPool>( |
27 new ImageCopyRasterWorkerPool(task_runner, | 94 new ImageCopyRasterWorkerPool(task_runner, |
28 task_graph_runner, | 95 task_graph_runner, |
29 context_provider, | 96 context_provider, |
30 resource_provider, | 97 resource_provider, |
31 resource_pool)); | 98 resource_pool)); |
32 } | 99 } |
33 | 100 |
34 ImageCopyRasterWorkerPool::ImageCopyRasterWorkerPool( | 101 ImageCopyRasterWorkerPool::ImageCopyRasterWorkerPool( |
35 base::SequencedTaskRunner* task_runner, | 102 base::SequencedTaskRunner* task_runner, |
36 TaskGraphRunner* task_graph_runner, | 103 TaskGraphRunner* task_graph_runner, |
37 ContextProvider* context_provider, | 104 ContextProvider* context_provider, |
38 ResourceProvider* resource_provider, | 105 ResourceProvider* resource_provider, |
39 ResourcePool* resource_pool) | 106 ResourcePool* resource_pool) |
40 : task_runner_(task_runner), | 107 : task_runner_(task_runner), |
41 task_graph_runner_(task_graph_runner), | 108 task_graph_runner_(task_graph_runner), |
42 namespace_token_(task_graph_runner->GetNamespaceToken()), | 109 namespace_token_(task_graph_runner->GetNamespaceToken()), |
43 context_provider_(context_provider), | 110 context_provider_(context_provider), |
44 resource_provider_(resource_provider), | 111 resource_provider_(resource_provider), |
45 resource_pool_(resource_pool), | 112 resource_pool_(resource_pool), |
46 has_performed_copy_since_last_flush_(false), | |
47 raster_finished_weak_ptr_factory_(this) { | 113 raster_finished_weak_ptr_factory_(this) { |
48 DCHECK(context_provider_); | 114 DCHECK(context_provider_); |
49 } | 115 } |
50 | 116 |
51 ImageCopyRasterWorkerPool::~ImageCopyRasterWorkerPool() { | 117 ImageCopyRasterWorkerPool::~ImageCopyRasterWorkerPool() { |
52 DCHECK_EQ(0u, raster_task_states_.size()); | |
53 } | 118 } |
54 | 119 |
55 Rasterizer* ImageCopyRasterWorkerPool::AsRasterizer() { return this; } | 120 Rasterizer* ImageCopyRasterWorkerPool::AsRasterizer() { return this; } |
56 | 121 |
57 void ImageCopyRasterWorkerPool::SetClient(RasterizerClient* client) { | 122 void ImageCopyRasterWorkerPool::SetClient(RasterizerClient* client) { |
58 client_ = client; | 123 client_ = client; |
59 } | 124 } |
60 | 125 |
61 void ImageCopyRasterWorkerPool::Shutdown() { | 126 void ImageCopyRasterWorkerPool::Shutdown() { |
62 TRACE_EVENT0("cc", "ImageCopyRasterWorkerPool::Shutdown"); | 127 TRACE_EVENT0("cc", "ImageCopyRasterWorkerPool::Shutdown"); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 RasterizerTask* task = static_cast<RasterizerTask*>(it->get()); | 212 RasterizerTask* task = static_cast<RasterizerTask*>(it->get()); |
148 | 213 |
149 task->WillComplete(); | 214 task->WillComplete(); |
150 task->CompleteOnOriginThread(this); | 215 task->CompleteOnOriginThread(this); |
151 task->DidComplete(); | 216 task->DidComplete(); |
152 | 217 |
153 task->RunReplyOnOriginThread(); | 218 task->RunReplyOnOriginThread(); |
154 } | 219 } |
155 completed_tasks_.clear(); | 220 completed_tasks_.clear(); |
156 | 221 |
157 FlushCopies(); | 222 context_provider_->ContextGL()->ShallowFlushCHROMIUM(); |
158 } | 223 } |
159 | 224 |
160 RasterBuffer* ImageCopyRasterWorkerPool::AcquireBufferForRaster( | 225 scoped_ptr<RasterBuffer> ImageCopyRasterWorkerPool::AcquireBufferForRaster( |
161 RasterTask* task) { | 226 const Resource* resource) { |
162 DCHECK_EQ(task->resource()->format(), resource_pool_->resource_format()); | 227 DCHECK_EQ(resource->format(), resource_pool_->resource_format()); |
163 scoped_ptr<ScopedResource> resource( | 228 return make_scoped_ptr<RasterBuffer>( |
164 resource_pool_->AcquireResource(task->resource()->size())); | 229 new RasterBufferImpl(resource_provider_, resource_pool_, resource)); |
165 RasterBuffer* raster_buffer = | |
166 resource_provider_->AcquireImageRasterBuffer(resource->id()); | |
167 DCHECK(std::find_if(raster_task_states_.begin(), | |
168 raster_task_states_.end(), | |
169 RasterTaskState::TaskComparator(task)) == | |
170 raster_task_states_.end()); | |
171 raster_task_states_.push_back(RasterTaskState(task, resource.release())); | |
172 return raster_buffer; | |
173 } | 230 } |
174 | 231 |
175 void ImageCopyRasterWorkerPool::ReleaseBufferForRaster(RasterTask* task) { | 232 void ImageCopyRasterWorkerPool::ReleaseBufferForRaster( |
176 RasterTaskState::Vector::iterator it = | 233 scoped_ptr<RasterBuffer> buffer) { |
177 std::find_if(raster_task_states_.begin(), | 234 // Nothing to do here. RasterBufferImpl destructor cleans up after itself. |
178 raster_task_states_.end(), | |
179 RasterTaskState::TaskComparator(task)); | |
180 DCHECK(it != raster_task_states_.end()); | |
181 scoped_ptr<ScopedResource> resource(it->resource); | |
182 std::swap(*it, raster_task_states_.back()); | |
183 raster_task_states_.pop_back(); | |
184 | |
185 bool content_has_changed = | |
186 resource_provider_->ReleaseImageRasterBuffer(resource->id()); | |
187 | |
188 // |content_has_changed| can be false as result of task being canceled or | |
189 // task implementation deciding not to modify bitmap (ie. analysis of raster | |
190 // commands detected content as a solid color). | |
191 if (content_has_changed) { | |
192 resource_provider_->CopyResource(resource->id(), task->resource()->id()); | |
193 has_performed_copy_since_last_flush_ = true; | |
194 } | |
195 | |
196 resource_pool_->ReleaseResource(resource.Pass()); | |
197 } | 235 } |
198 | 236 |
199 void ImageCopyRasterWorkerPool::OnRasterFinished(TaskSet task_set) { | 237 void ImageCopyRasterWorkerPool::OnRasterFinished(TaskSet task_set) { |
200 TRACE_EVENT1("cc", | 238 TRACE_EVENT1("cc", |
201 "ImageCopyRasterWorkerPool::OnRasterFinished", | 239 "ImageCopyRasterWorkerPool::OnRasterFinished", |
202 "task_set", | 240 "task_set", |
203 task_set); | 241 task_set); |
204 | 242 |
205 DCHECK(raster_pending_[task_set]); | 243 DCHECK(raster_pending_[task_set]); |
206 raster_pending_[task_set] = false; | 244 raster_pending_[task_set] = false; |
207 if (raster_pending_.any()) { | 245 if (raster_pending_.any()) { |
208 TRACE_EVENT_ASYNC_STEP_INTO1( | 246 TRACE_EVENT_ASYNC_STEP_INTO1( |
209 "cc", "ScheduledTasks", this, "rasterizing", "state", StateAsValue()); | 247 "cc", "ScheduledTasks", this, "rasterizing", "state", StateAsValue()); |
210 } else { | 248 } else { |
211 TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this); | 249 TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this); |
212 } | 250 } |
213 client_->DidFinishRunningTasks(task_set); | 251 client_->DidFinishRunningTasks(task_set); |
214 } | 252 } |
215 | 253 |
216 void ImageCopyRasterWorkerPool::FlushCopies() { | |
217 if (!has_performed_copy_since_last_flush_) | |
218 return; | |
219 | |
220 context_provider_->ContextGL()->ShallowFlushCHROMIUM(); | |
221 has_performed_copy_since_last_flush_ = false; | |
222 } | |
223 | |
224 scoped_refptr<base::debug::ConvertableToTraceFormat> | 254 scoped_refptr<base::debug::ConvertableToTraceFormat> |
225 ImageCopyRasterWorkerPool::StateAsValue() const { | 255 ImageCopyRasterWorkerPool::StateAsValue() const { |
226 scoped_refptr<base::debug::TracedValue> state = | 256 scoped_refptr<base::debug::TracedValue> state = |
227 new base::debug::TracedValue(); | 257 new base::debug::TracedValue(); |
228 | 258 |
229 state->BeginArray("tasks_pending"); | 259 state->BeginArray("tasks_pending"); |
230 for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) | 260 for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) |
231 state->AppendBoolean(raster_pending_[task_set]); | 261 state->AppendBoolean(raster_pending_[task_set]); |
232 state->EndArray(); | 262 state->EndArray(); |
233 state->BeginDictionary("staging_state"); | 263 state->BeginDictionary("staging_state"); |
(...skipping 10 matching lines...) Expand all Loading... |
244 resource_pool_->total_memory_usage_bytes()); | 274 resource_pool_->total_memory_usage_bytes()); |
245 staging_state->SetInteger("pending_copy_count", | 275 staging_state->SetInteger("pending_copy_count", |
246 resource_pool_->total_resource_count() - | 276 resource_pool_->total_resource_count() - |
247 resource_pool_->acquired_resource_count()); | 277 resource_pool_->acquired_resource_count()); |
248 staging_state->SetInteger("bytes_pending_copy", | 278 staging_state->SetInteger("bytes_pending_copy", |
249 resource_pool_->total_memory_usage_bytes() - | 279 resource_pool_->total_memory_usage_bytes() - |
250 resource_pool_->acquired_memory_usage_bytes()); | 280 resource_pool_->acquired_memory_usage_bytes()); |
251 } | 281 } |
252 | 282 |
253 } // namespace cc | 283 } // namespace cc |
OLD | NEW |