Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: cc/resources/image_copy_raster_worker_pool.cc

Issue 562833004: cc: Move RasterBuffer implementations from ResourceProvider to RasterWorkerPool implementations. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: build fix Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 #include <limits>
8 9
9 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
10 #include "base/debug/trace_event_argument.h" 11 #include "base/debug/trace_event_argument.h"
11 #include "cc/debug/traced_value.h" 12 #include "cc/debug/traced_value.h"
13 #include "cc/resources/raster_buffer.h"
12 #include "cc/resources/resource_pool.h" 14 #include "cc/resources/resource_pool.h"
13 #include "cc/resources/scoped_resource.h" 15 #include "cc/resources/scoped_resource.h"
14 #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"
15 18
16 namespace cc { 19 namespace cc {
20 namespace {
21
22 // Number of resources to copy at a time.
23 const int kBatchSize = 8;
24
25 class RasterBufferImpl : public RasterBuffer {
26 public:
27 RasterBufferImpl(ImageCopyRasterWorkerPool* worker_pool,
28 const Resource* resource,
29 const base::Closure& copy_batch_of_resources_callback)
30 : worker_pool_(worker_pool),
vmpstr 2014/09/16 22:15:55 client? Up to you.
reveman 2014/09/17 14:40:56 This is different in latest patch. PTAL.
31 resource_(resource),
32 copy_batch_of_resources_callback_(copy_batch_of_resources_callback),
33 raster_resource_(
34 worker_pool->resource_pool()->AcquireResource(resource->size())),
35 buffer_(NULL),
36 stride_(0) {
37 // This RasterBuffer implementation provides direct access to the memory
38 // used by the GPU. Read lock fences are required to ensure that we're not
39 // trying to map a resource that is currently in-use by the GPU.
40 worker_pool_->resource_provider()->EnableReadLockFences(
41 raster_resource_->id());
42
43 // Acquire and map image for raster resource.
44 worker_pool_->resource_provider()->AcquireImage(raster_resource_->id());
45 buffer_ = worker_pool_->resource_provider()->MapImage(
46 raster_resource_->id(), &stride_);
47 }
48
49 virtual ~RasterBufferImpl() {
50 if (!raster_resource_)
51 return;
52
53 // Unmap image for raster resource if a copy operation was never scheduled.
54 worker_pool_->resource_provider()->UnmapImage(raster_resource_->id());
55
56 // Return resource to pool so it can be used for another RasterBuffer
57 // instance.
58 worker_pool_->resource_pool()->ReleaseResource(raster_resource_.Pass());
59 }
60
61 // Overridden from RasterBuffer:
62 virtual skia::RefPtr<SkCanvas> AcquireSkCanvas() OVERRIDE {
63 if (!buffer_)
64 return skia::AdoptRef(SkCreateNullCanvas());
65
66 RasterWorkerPool::AcquireBitmapForBuffer(
67 &bitmap_, buffer_, resource_->format(), resource_->size(), stride_);
68 return skia::AdoptRef(new SkCanvas(bitmap_));
69 }
70 virtual void ReleaseSkCanvas(const skia::RefPtr<SkCanvas>& canvas) OVERRIDE {
71 if (!buffer_)
72 return;
73
74 RasterWorkerPool::ReleaseBitmapForBuffer(
75 &bitmap_, buffer_, resource_->format());
76
77 size_t pending_copy_operations =
78 worker_pool_->ScheduleCopy(raster_resource_.Pass(), resource_);
79
80 // Post task that will copy a batch of resources whenever the number of
81 // pending copy operations is a multiple of the batch size.
82 if ((pending_copy_operations % kBatchSize) == 0) {
83 worker_pool_->task_runner()->PostTask(FROM_HERE,
84 copy_batch_of_resources_callback_);
85 }
86 }
87
88 private:
89 ImageCopyRasterWorkerPool* worker_pool_;
90 const Resource* resource_;
91 const base::Closure copy_batch_of_resources_callback_;
92 scoped_ptr<ScopedResource> raster_resource_;
93 uint8_t* buffer_;
94 int stride_;
95 SkBitmap bitmap_;
96
97 DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl);
98 };
99
100 } // namespace
101
102 ImageCopyRasterWorkerPool::ResourceCopyOperation::ResourceCopyOperation(
103 scoped_ptr<ScopedResource> src,
104 const Resource* dst)
105 : src(src.Pass()), dst(dst) {
106 }
107
108 ImageCopyRasterWorkerPool::ResourceCopyOperation::~ResourceCopyOperation() {
109 }
17 110
18 // static 111 // static
19 scoped_ptr<RasterWorkerPool> ImageCopyRasterWorkerPool::Create( 112 scoped_ptr<RasterWorkerPool> ImageCopyRasterWorkerPool::Create(
20 base::SequencedTaskRunner* task_runner, 113 base::SequencedTaskRunner* task_runner,
21 TaskGraphRunner* task_graph_runner, 114 TaskGraphRunner* task_graph_runner,
22 ContextProvider* context_provider, 115 ContextProvider* context_provider,
23 ResourceProvider* resource_provider, 116 ResourceProvider* resource_provider,
24 ResourcePool* resource_pool) { 117 ResourcePool* resource_pool) {
25 return make_scoped_ptr<RasterWorkerPool>( 118 return make_scoped_ptr<RasterWorkerPool>(
26 new ImageCopyRasterWorkerPool(task_runner, 119 new ImageCopyRasterWorkerPool(task_runner,
27 task_graph_runner, 120 task_graph_runner,
28 context_provider, 121 context_provider,
29 resource_provider, 122 resource_provider,
30 resource_pool)); 123 resource_pool));
31 } 124 }
32 125
33 ImageCopyRasterWorkerPool::ImageCopyRasterWorkerPool( 126 ImageCopyRasterWorkerPool::ImageCopyRasterWorkerPool(
34 base::SequencedTaskRunner* task_runner, 127 base::SequencedTaskRunner* task_runner,
35 TaskGraphRunner* task_graph_runner, 128 TaskGraphRunner* task_graph_runner,
36 ContextProvider* context_provider, 129 ContextProvider* context_provider,
37 ResourceProvider* resource_provider, 130 ResourceProvider* resource_provider,
38 ResourcePool* resource_pool) 131 ResourcePool* resource_pool)
39 : task_runner_(task_runner), 132 : task_runner_(task_runner),
40 task_graph_runner_(task_graph_runner), 133 task_graph_runner_(task_graph_runner),
41 namespace_token_(task_graph_runner->GetNamespaceToken()), 134 namespace_token_(task_graph_runner->GetNamespaceToken()),
42 context_provider_(context_provider), 135 context_provider_(context_provider),
43 resource_provider_(resource_provider), 136 resource_provider_(resource_provider),
44 resource_pool_(resource_pool), 137 resource_pool_(resource_pool),
45 has_performed_copy_since_last_flush_(false),
46 raster_tasks_pending_(false), 138 raster_tasks_pending_(false),
47 raster_tasks_required_for_activation_pending_(false), 139 raster_tasks_required_for_activation_pending_(false),
48 raster_finished_weak_ptr_factory_(this) { 140 raster_finished_weak_ptr_factory_(this),
141 copy_batch_of_resources_weak_ptr_factory_(this) {
49 DCHECK(context_provider_); 142 DCHECK(context_provider_);
143 copy_batch_of_resources_callback_ =
144 base::Bind(&ImageCopyRasterWorkerPool::CopyResources,
145 copy_batch_of_resources_weak_ptr_factory_.GetWeakPtr(),
146 kBatchSize);
50 } 147 }
51 148
52 ImageCopyRasterWorkerPool::~ImageCopyRasterWorkerPool() { 149 ImageCopyRasterWorkerPool::~ImageCopyRasterWorkerPool() {
53 DCHECK_EQ(0u, raster_task_states_.size());
54 } 150 }
55 151
56 Rasterizer* ImageCopyRasterWorkerPool::AsRasterizer() { return this; } 152 Rasterizer* ImageCopyRasterWorkerPool::AsRasterizer() { return this; }
57 153
58 void ImageCopyRasterWorkerPool::SetClient(RasterizerClient* client) { 154 void ImageCopyRasterWorkerPool::SetClient(RasterizerClient* client) {
59 client_ = client; 155 client_ = client;
60 } 156 }
61 157
62 void ImageCopyRasterWorkerPool::Shutdown() { 158 void ImageCopyRasterWorkerPool::Shutdown() {
63 TRACE_EVENT0("cc", "ImageCopyRasterWorkerPool::Shutdown"); 159 TRACE_EVENT0("cc", "ImageCopyRasterWorkerPool::Shutdown");
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 234
139 TRACE_EVENT_ASYNC_STEP_INTO1( 235 TRACE_EVENT_ASYNC_STEP_INTO1(
140 "cc", "ScheduledTasks", this, "rasterizing", "state", StateAsValue()); 236 "cc", "ScheduledTasks", this, "rasterizing", "state", StateAsValue());
141 } 237 }
142 238
143 void ImageCopyRasterWorkerPool::CheckForCompletedTasks() { 239 void ImageCopyRasterWorkerPool::CheckForCompletedTasks() {
144 TRACE_EVENT0("cc", "ImageCopyRasterWorkerPool::CheckForCompletedTasks"); 240 TRACE_EVENT0("cc", "ImageCopyRasterWorkerPool::CheckForCompletedTasks");
145 241
146 task_graph_runner_->CollectCompletedTasks(namespace_token_, 242 task_graph_runner_->CollectCompletedTasks(namespace_token_,
147 &completed_tasks_); 243 &completed_tasks_);
244
245 // Copy all remaining resources.
246 CopyResources(std::numeric_limits<size_t>::max());
247
248 // Cancel existing CopyResources callbacks.
249 copy_batch_of_resources_weak_ptr_factory_.InvalidateWeakPtrs();
250 copy_batch_of_resources_callback_ =
251 base::Bind(&ImageCopyRasterWorkerPool::CopyResources,
252 copy_batch_of_resources_weak_ptr_factory_.GetWeakPtr(),
253 kBatchSize);
254
255 // We can now process completed tasks after having copied all resources.
148 for (Task::Vector::const_iterator it = completed_tasks_.begin(); 256 for (Task::Vector::const_iterator it = completed_tasks_.begin();
149 it != completed_tasks_.end(); 257 it != completed_tasks_.end();
150 ++it) { 258 ++it) {
151 RasterizerTask* task = static_cast<RasterizerTask*>(it->get()); 259 RasterizerTask* task = static_cast<RasterizerTask*>(it->get());
152 260
153 task->WillComplete(); 261 task->WillComplete();
154 task->CompleteOnOriginThread(this); 262 task->CompleteOnOriginThread(this);
155 task->DidComplete(); 263 task->DidComplete();
156 264
157 task->RunReplyOnOriginThread(); 265 task->RunReplyOnOriginThread();
158 } 266 }
159 completed_tasks_.clear(); 267 completed_tasks_.clear();
160
161 FlushCopies();
162 } 268 }
163 269
164 RasterBuffer* ImageCopyRasterWorkerPool::AcquireBufferForRaster( 270 scoped_ptr<RasterBuffer> ImageCopyRasterWorkerPool::AcquireBufferForRaster(
165 RasterTask* task) { 271 const Resource* resource) {
166 DCHECK_EQ(task->resource()->format(), resource_pool_->resource_format()); 272 DCHECK_EQ(resource->format(), resource_pool_->resource_format());
167 scoped_ptr<ScopedResource> resource( 273 return make_scoped_ptr<RasterBuffer>(
168 resource_pool_->AcquireResource(task->resource()->size())); 274 new RasterBufferImpl(this, resource, copy_batch_of_resources_callback_));
169 RasterBuffer* raster_buffer =
170 resource_provider_->AcquireImageRasterBuffer(resource->id());
171 DCHECK(std::find_if(raster_task_states_.begin(),
172 raster_task_states_.end(),
173 RasterTaskState::TaskComparator(task)) ==
174 raster_task_states_.end());
175 raster_task_states_.push_back(RasterTaskState(task, resource.release()));
176 return raster_buffer;
177 } 275 }
178 276
179 void ImageCopyRasterWorkerPool::ReleaseBufferForRaster(RasterTask* task) { 277 void ImageCopyRasterWorkerPool::ReleaseBufferForRaster(
180 RasterTaskState::Vector::iterator it = 278 scoped_ptr<RasterBuffer> buffer) {
181 std::find_if(raster_task_states_.begin(), 279 // Nothing to do here. RasterBufferImpl destructor cleans up after itself.
182 raster_task_states_.end(), 280 }
183 RasterTaskState::TaskComparator(task));
184 DCHECK(it != raster_task_states_.end());
185 scoped_ptr<ScopedResource> resource(it->resource);
186 std::swap(*it, raster_task_states_.back());
187 raster_task_states_.pop_back();
188 281
189 bool content_has_changed = 282 size_t ImageCopyRasterWorkerPool::ScheduleCopy(scoped_ptr<ScopedResource> src,
190 resource_provider_->ReleaseImageRasterBuffer(resource->id()); 283 const Resource* dst) {
191 284 base::AutoLock lock(pending_resource_copy_operations_lock_);
192 // |content_has_changed| can be false as result of task being canceled or 285 pending_resource_copy_operations_.push_back(
193 // task implementation deciding not to modify bitmap (ie. analysis of raster 286 make_scoped_ptr(new ResourceCopyOperation(src.Pass(), dst)));
194 // commands detected content as a solid color). 287 return pending_resource_copy_operations_.size();
195 if (content_has_changed) {
196 resource_provider_->CopyResource(resource->id(), task->resource()->id());
197 has_performed_copy_since_last_flush_ = true;
198 }
199
200 resource_pool_->ReleaseResource(resource.Pass());
201 } 288 }
202 289
203 void ImageCopyRasterWorkerPool::OnRasterFinished() { 290 void ImageCopyRasterWorkerPool::OnRasterFinished() {
204 TRACE_EVENT0("cc", "ImageCopyRasterWorkerPool::OnRasterFinished"); 291 TRACE_EVENT0("cc", "ImageCopyRasterWorkerPool::OnRasterFinished");
205 292
206 DCHECK(raster_tasks_pending_); 293 DCHECK(raster_tasks_pending_);
207 raster_tasks_pending_ = false; 294 raster_tasks_pending_ = false;
208 TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this); 295 TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this);
209 client_->DidFinishRunningTasks(); 296 client_->DidFinishRunningTasks();
210 } 297 }
211 298
212 void ImageCopyRasterWorkerPool::OnRasterRequiredForActivationFinished() { 299 void ImageCopyRasterWorkerPool::OnRasterRequiredForActivationFinished() {
213 TRACE_EVENT0( 300 TRACE_EVENT0(
214 "cc", "ImageCopyRasterWorkerPool::OnRasterRequiredForActivationFinished"); 301 "cc", "ImageCopyRasterWorkerPool::OnRasterRequiredForActivationFinished");
215 302
216 DCHECK(raster_tasks_required_for_activation_pending_); 303 DCHECK(raster_tasks_required_for_activation_pending_);
217 raster_tasks_required_for_activation_pending_ = false; 304 raster_tasks_required_for_activation_pending_ = false;
218 TRACE_EVENT_ASYNC_STEP_INTO1( 305 TRACE_EVENT_ASYNC_STEP_INTO1(
219 "cc", "ScheduledTasks", this, "rasterizing", "state", StateAsValue()); 306 "cc", "ScheduledTasks", this, "rasterizing", "state", StateAsValue());
220 client_->DidFinishRunningTasksRequiredForActivation(); 307 client_->DidFinishRunningTasksRequiredForActivation();
221 } 308 }
222 309
223 void ImageCopyRasterWorkerPool::FlushCopies() { 310 void ImageCopyRasterWorkerPool::CopyResources(size_t count) {
224 if (!has_performed_copy_since_last_flush_) 311 TRACE_EVENT1(
312 "cc", "ImageCopyRasterWorkerPool::CopyResources", "count", count);
313
314 ResourceCopyOperation::Deque resource_copy_operations;
315
316 {
317 base::AutoLock lock(pending_resource_copy_operations_lock_);
318
319 for (size_t i = 0; i < count; ++i) {
vmpstr 2014/09/16 22:15:55 maybe: while (count-- && !pending_resource_copy_o
reveman 2014/09/17 14:40:56 I prefer to pick one variable that is used as the
320 if (pending_resource_copy_operations_.empty())
321 break;
322
323 resource_copy_operations.push_back(
324 pending_resource_copy_operations_.take_front());
325 }
326 }
327
328 // Early out to avoid unnecessary ShallowFlushCHROMIUM call.
329 if (resource_copy_operations.empty())
225 return; 330 return;
226 331
332 while (!resource_copy_operations.empty()) {
333 scoped_ptr<ResourceCopyOperation> resource_copy_operation =
334 resource_copy_operations.take_front();
335
336 // First unmap source resource image.
337 resource_provider_->UnmapImage(resource_copy_operation->src->id());
338
339 // Copy contents of source resource to destination resource.
340 resource_provider_->CopyResource(resource_copy_operation->src->id(),
341 resource_copy_operation->dst->id());
342
343 // Return source resource to pool.
344 resource_pool_->ReleaseResource(resource_copy_operation->src.Pass());
345 }
346
227 context_provider_->ContextGL()->ShallowFlushCHROMIUM(); 347 context_provider_->ContextGL()->ShallowFlushCHROMIUM();
228 has_performed_copy_since_last_flush_ = false;
229 } 348 }
230 349
231 scoped_refptr<base::debug::ConvertableToTraceFormat> 350 scoped_refptr<base::debug::ConvertableToTraceFormat>
232 ImageCopyRasterWorkerPool::StateAsValue() const { 351 ImageCopyRasterWorkerPool::StateAsValue() const {
233 scoped_refptr<base::debug::TracedValue> state = 352 scoped_refptr<base::debug::TracedValue> state =
234 new base::debug::TracedValue(); 353 new base::debug::TracedValue();
235 354
236 state->SetInteger("pending_count", raster_task_states_.size());
237 state->SetBoolean("tasks_required_for_activation_pending", 355 state->SetBoolean("tasks_required_for_activation_pending",
238 raster_tasks_required_for_activation_pending_); 356 raster_tasks_required_for_activation_pending_);
239 state->BeginDictionary("staging_state"); 357 state->BeginDictionary("staging_state");
240 StagingStateAsValueInto(state.get()); 358 StagingStateAsValueInto(state.get());
241 state->EndDictionary(); 359 state->EndDictionary();
242 360
243 return state; 361 return state;
244 } 362 }
245 void ImageCopyRasterWorkerPool::StagingStateAsValueInto( 363 void ImageCopyRasterWorkerPool::StagingStateAsValueInto(
246 base::debug::TracedValue* staging_state) const { 364 base::debug::TracedValue* staging_state) const {
247 staging_state->SetInteger("staging_resource_count", 365 staging_state->SetInteger("staging_resource_count",
248 resource_pool_->total_resource_count()); 366 resource_pool_->total_resource_count());
249 staging_state->SetInteger("bytes_used_for_staging_resources", 367 staging_state->SetInteger("bytes_used_for_staging_resources",
250 resource_pool_->total_memory_usage_bytes()); 368 resource_pool_->total_memory_usage_bytes());
251 staging_state->SetInteger("pending_copy_count", 369 staging_state->SetInteger("pending_copy_count",
252 resource_pool_->total_resource_count() - 370 resource_pool_->total_resource_count() -
253 resource_pool_->acquired_resource_count()); 371 resource_pool_->acquired_resource_count());
254 staging_state->SetInteger("bytes_pending_copy", 372 staging_state->SetInteger("bytes_pending_copy",
255 resource_pool_->total_memory_usage_bytes() - 373 resource_pool_->total_memory_usage_bytes() -
256 resource_pool_->acquired_memory_usage_bytes()); 374 resource_pool_->acquired_memory_usage_bytes());
257 } 375 }
258 376
259 } // namespace cc 377 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698