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

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

Issue 17351017: Re-land: cc: Add raster finished signals to RasterWorkerPool. (Closed) Base URL: http://git.chromium.org/chromium/src.git@new-graph-build
Patch Set: new approach Created 7 years, 5 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/pixel_buffer_raster_worker_pool.h" 5 #include "cc/resources/pixel_buffer_raster_worker_pool.h"
6 6
7 #include "base/debug/trace_event.h" 7 #include "base/debug/trace_event.h"
8 #include "cc/base/scoped_ptr_deque.h"
8 #include "cc/resources/resource.h" 9 #include "cc/resources/resource.h"
9 #include "third_party/skia/include/core/SkDevice.h" 10 #include "third_party/skia/include/core/SkDevice.h"
10 11
11 namespace cc { 12 namespace cc {
12 13
13 namespace { 14 namespace {
14 15
15 class PixelBufferWorkerPoolTaskImpl : public internal::WorkerPoolTask { 16 class PixelBufferWorkerPoolTaskImpl : public internal::WorkerPoolTask {
16 public: 17 public:
17 typedef base::Callback<void(bool was_canceled, bool needs_upload)> Reply; 18 typedef base::Callback<void(bool was_canceled, bool needs_upload)> Reply;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 virtual ~PixelBufferWorkerPoolTaskImpl() {} 53 virtual ~PixelBufferWorkerPoolTaskImpl() {}
53 54
54 scoped_refptr<internal::RasterWorkerPoolTask> task_; 55 scoped_refptr<internal::RasterWorkerPoolTask> task_;
55 uint8_t* buffer_; 56 uint8_t* buffer_;
56 const Reply reply_; 57 const Reply reply_;
57 bool needs_upload_; 58 bool needs_upload_;
58 59
59 DISALLOW_COPY_AND_ASSIGN(PixelBufferWorkerPoolTaskImpl); 60 DISALLOW_COPY_AND_ASSIGN(PixelBufferWorkerPoolTaskImpl);
60 }; 61 };
61 62
63 class RasterFinishedWorkerPoolTaskImpl : public internal::WorkerPoolTask {
64 public:
65 RasterFinishedWorkerPoolTaskImpl(
66 base::MessageLoopProxy* origin_loop,
67 const base::Closure& on_raster_finished_callback)
68 : origin_loop_(origin_loop),
69 on_raster_finished_callback_(on_raster_finished_callback) {
70 }
71
72 // Overridden from internal::WorkerPoolTask:
73 virtual void RunOnWorkerThread(unsigned thread_index) OVERRIDE {
74 TRACE_EVENT0("cc", "RasterFinishedWorkerPoolTaskImpl::RunOnWorkerThread");
75 origin_loop_->PostTask(FROM_HERE, on_raster_finished_callback_);
76 }
77 virtual void CompleteOnOriginThread() OVERRIDE {}
78
79 private:
80 virtual ~RasterFinishedWorkerPoolTaskImpl() {}
81
82 scoped_refptr<base::MessageLoopProxy> origin_loop_;
83 const base::Closure on_raster_finished_callback_;
84
85 DISALLOW_COPY_AND_ASSIGN(RasterFinishedWorkerPoolTaskImpl);
86 };
87
62 // If we raster too fast we become upload bound, and pending 88 // If we raster too fast we become upload bound, and pending
63 // uploads consume memory. For maximum upload throughput, we would 89 // uploads consume memory. For maximum upload throughput, we would
64 // want to allow for upload_throughput * pipeline_time of pending 90 // want to allow for upload_throughput * pipeline_time of pending
65 // uploads, after which we are just wasting memory. Since we don't 91 // uploads, after which we are just wasting memory. Since we don't
66 // know our upload throughput yet, this just caps our memory usage. 92 // know our upload throughput yet, this just caps our memory usage.
67 #if defined(OS_ANDROID) 93 #if defined(OS_ANDROID)
68 // For reference Nexus10 can upload 1MB in about 2.5ms. 94 // For reference Nexus10 can upload 1MB in about 2.5ms.
69 const size_t kMaxBytesUploadedPerMs = (2 * 1024 * 1024) / 5; 95 const size_t kMaxBytesUploadedPerMs = (2 * 1024 * 1024) / 5;
70 #else 96 #else
71 // For reference Chromebook Pixel can upload 1MB in about 0.5ms. 97 // For reference Chromebook Pixel can upload 1MB in about 0.5ms.
72 const size_t kMaxBytesUploadedPerMs = 1024 * 1024 * 2; 98 const size_t kMaxBytesUploadedPerMs = 1024 * 1024 * 2;
73 #endif 99 #endif
74 100
75 // Assuming a two frame deep pipeline. 101 // Assuming a two frame deep pipeline.
76 const size_t kMaxPendingUploadBytes = 16 * 2 * kMaxBytesUploadedPerMs; 102 const size_t kMaxPendingUploadBytes = 16 * 2 * kMaxBytesUploadedPerMs;
77 103
78 const int kCheckForCompletedRasterTasksDelayMs = 6; 104 const int kCheckForCompletedRasterTasksDelayMs = 6;
79 105
80 const size_t kMaxPendingRasterBytes = 106 const size_t kMaxPendingRasterBytes =
81 kMaxBytesUploadedPerMs * kCheckForCompletedRasterTasksDelayMs; 107 kMaxBytesUploadedPerMs * kCheckForCompletedRasterTasksDelayMs;
82 108
83 } // namespace 109 } // namespace
84 110
85 PixelBufferRasterWorkerPool::PixelBufferRasterWorkerPool( 111 PixelBufferRasterWorkerPool::PixelBufferRasterWorkerPool(
86 ResourceProvider* resource_provider, 112 ResourceProvider* resource_provider,
87 size_t num_threads) : RasterWorkerPool(resource_provider, num_threads), 113 size_t num_threads)
88 shutdown_(false), 114 : RasterWorkerPool(resource_provider, num_threads),
89 bytes_pending_upload_(0), 115 shutdown_(false),
90 has_performed_uploads_since_last_flush_(false), 116 bytes_pending_upload_(0),
91 check_for_completed_raster_tasks_pending_(false) { 117 has_performed_uploads_since_last_flush_(false),
118 check_for_completed_raster_tasks_pending_(false),
119 weak_ptr_factory_(this),
120 schedule_raster_tasks_count_(0),
121 finished_running_tasks_pending_(false),
122 finished_running_tasks_required_for_activation_pending_(false) {
92 } 123 }
93 124
94 PixelBufferRasterWorkerPool::~PixelBufferRasterWorkerPool() { 125 PixelBufferRasterWorkerPool::~PixelBufferRasterWorkerPool() {
95 DCHECK(shutdown_); 126 DCHECK(shutdown_);
96 DCHECK(!check_for_completed_raster_tasks_pending_); 127 DCHECK(!check_for_completed_raster_tasks_pending_);
97 DCHECK_EQ(0u, pixel_buffer_tasks_.size()); 128 DCHECK_EQ(0u, pixel_buffer_tasks_.size());
98 DCHECK_EQ(0u, tasks_with_pending_upload_.size()); 129 DCHECK_EQ(0u, tasks_with_pending_upload_.size());
99 DCHECK_EQ(0u, completed_tasks_.size()); 130 DCHECK_EQ(0u, completed_tasks_.size());
100 } 131 }
101 132
102 void PixelBufferRasterWorkerPool::Shutdown() { 133 void PixelBufferRasterWorkerPool::Shutdown() {
103 shutdown_ = true; 134 shutdown_ = true;
135 weak_ptr_factory_.InvalidateWeakPtrs();
104 RasterWorkerPool::Shutdown(); 136 RasterWorkerPool::Shutdown();
105 CheckForCompletedRasterTasks(); 137 RasterWorkerPool::CheckForCompletedTasks();
138 CheckForCompletedUploads();
139 check_for_completed_raster_tasks_callback_.Cancel();
140 check_for_completed_raster_tasks_pending_ = false;
106 for (TaskMap::iterator it = pixel_buffer_tasks_.begin(); 141 for (TaskMap::iterator it = pixel_buffer_tasks_.begin();
107 it != pixel_buffer_tasks_.end(); ++it) { 142 it != pixel_buffer_tasks_.end(); ++it) {
108 internal::RasterWorkerPoolTask* task = it->first; 143 internal::RasterWorkerPoolTask* task = it->first;
109 internal::WorkerPoolTask* pixel_buffer_task = it->second.get(); 144 internal::WorkerPoolTask* pixel_buffer_task = it->second.get();
110 145
111 // All inactive tasks needs to be canceled. 146 // All inactive tasks needs to be canceled.
112 if (!pixel_buffer_task && !task->HasFinishedRunning()) { 147 if (!pixel_buffer_task && !task->HasFinishedRunning()) {
113 task->DidRun(true); 148 task->DidRun(true);
114 completed_tasks_.push_back(task); 149 completed_tasks_.push_back(task);
115 } 150 }
116 } 151 }
152 DCHECK_EQ(completed_tasks_.size(), pixel_buffer_tasks_.size());
117 } 153 }
118 154
119 void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTask::Queue* queue) { 155 void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTask::Queue* queue) {
120 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleTasks"); 156 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleTasks");
121 157
122 RasterWorkerPool::SetRasterTasks(queue); 158 RasterWorkerPool::SetRasterTasks(queue);
123 159
160 finished_running_tasks_pending_ = true;
161 finished_running_tasks_required_for_activation_pending_ = true;
162
124 // Build new pixel buffer task set. 163 // Build new pixel buffer task set.
125 TaskMap new_pixel_buffer_tasks; 164 TaskMap new_pixel_buffer_tasks;
126 for (RasterTaskVector::const_iterator it = raster_tasks().begin(); 165 for (RasterTaskVector::const_iterator it = raster_tasks().begin();
127 it != raster_tasks().end(); ++it) { 166 it != raster_tasks().end(); ++it) {
128 internal::RasterWorkerPoolTask* task = it->get(); 167 internal::RasterWorkerPoolTask* task = it->get();
129 DCHECK(new_pixel_buffer_tasks.find(task) == new_pixel_buffer_tasks.end()); 168 DCHECK(new_pixel_buffer_tasks.find(task) == new_pixel_buffer_tasks.end());
130 DCHECK(!task->HasCompleted()); 169 DCHECK(!task->HasCompleted());
131 170
132 // Use existing pixel buffer task if available. 171 // Use existing pixel buffer task if available.
133 TaskMap::iterator pixel_buffer_it = pixel_buffer_tasks_.find(task); 172 TaskMap::iterator pixel_buffer_it = pixel_buffer_tasks_.find(task);
(...skipping 19 matching lines...) Expand all
153 // Inactive task can be canceled. 192 // Inactive task can be canceled.
154 if (!pixel_buffer_task && !task->HasFinishedRunning()) { 193 if (!pixel_buffer_task && !task->HasFinishedRunning()) {
155 task->DidRun(true); 194 task->DidRun(true);
156 DCHECK(std::find(completed_tasks_.begin(), 195 DCHECK(std::find(completed_tasks_.begin(),
157 completed_tasks_.end(), 196 completed_tasks_.end(),
158 task) == completed_tasks_.end()); 197 task) == completed_tasks_.end());
159 completed_tasks_.push_back(task); 198 completed_tasks_.push_back(task);
160 } 199 }
161 } 200 }
162 201
202 tasks_required_for_activation_.clear();
203 for (TaskMap::iterator it = new_pixel_buffer_tasks.begin();
204 it != new_pixel_buffer_tasks.end(); ++it) {
205 internal::RasterWorkerPoolTask* task = it->first;
206 if (IsRasterTaskRequiredForActivation(task))
207 tasks_required_for_activation_.insert(task);
208 }
209
163 pixel_buffer_tasks_.swap(new_pixel_buffer_tasks); 210 pixel_buffer_tasks_.swap(new_pixel_buffer_tasks);
164 211
165 // This will schedule more tasks after checking for completed raster 212 // Check for completed tasks when ScheduleTasks() is called as
166 // tasks. It's worth checking for completed tasks when ScheduleTasks() 213 // priorities might have changed and this maximizes the number
167 // is called as priorities might have changed and this allows us to 214 // of top priority tasks that are scheduled.
168 // schedule as many new top priority tasks as possible. 215 RasterWorkerPool::CheckForCompletedTasks();
169 CheckForCompletedRasterTasks(); 216 CheckForCompletedUploads();
217 FlushUploads();
218
219 // Schedule new tasks.
220 ScheduleMoreTasks();
221
222 // Cancel any pending check for completed raster tasks and schedule
223 // another check.
224 check_for_completed_raster_tasks_callback_.Cancel();
225 check_for_completed_raster_tasks_pending_ = false;
226 ScheduleCheckForCompletedRasterTasks();
170 } 227 }
171 228
172 void PixelBufferRasterWorkerPool::CheckForCompletedTasks() { 229 void PixelBufferRasterWorkerPool::CheckForCompletedTasks() {
173 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::CheckForCompletedTasks"); 230 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::CheckForCompletedTasks");
174 231
175 RasterWorkerPool::CheckForCompletedTasks(); 232 RasterWorkerPool::CheckForCompletedTasks();
176 CheckForCompletedUploads(); 233 CheckForCompletedUploads();
177 FlushUploads(); 234 FlushUploads();
178 235
179 while (!completed_tasks_.empty()) { 236 TaskDeque completed_tasks;
180 internal::RasterWorkerPoolTask* task = completed_tasks_.front().get(); 237 completed_tasks_.swap(completed_tasks);
238
239 while (!completed_tasks.empty()) {
240 internal::RasterWorkerPoolTask* task = completed_tasks.front().get();
181 DCHECK(pixel_buffer_tasks_.find(task) != pixel_buffer_tasks_.end()); 241 DCHECK(pixel_buffer_tasks_.find(task) != pixel_buffer_tasks_.end());
182 242
183 pixel_buffer_tasks_.erase(task); 243 pixel_buffer_tasks_.erase(task);
184 244
185 task->WillComplete(); 245 task->WillComplete();
186 task->CompleteOnOriginThread(); 246 task->CompleteOnOriginThread();
187 task->DidComplete(); 247 task->DidComplete();
188 248
189 completed_tasks_.pop_front(); 249 completed_tasks.pop_front();
190 } 250 }
191 } 251 }
192 252
193 void PixelBufferRasterWorkerPool::OnRasterTasksFinished() {
194 // Call CheckForCompletedTasks() when we've finished running all raster
195 // tasks needed since last time ScheduleMoreTasks() was called. This
196 // reduces latency when processing only a small number of raster tasks.
197 CheckForCompletedRasterTasks();
198 }
199
200 void PixelBufferRasterWorkerPool::FlushUploads() { 253 void PixelBufferRasterWorkerPool::FlushUploads() {
201 if (!has_performed_uploads_since_last_flush_) 254 if (!has_performed_uploads_since_last_flush_)
202 return; 255 return;
203 256
204 resource_provider()->ShallowFlushIfSupported(); 257 resource_provider()->ShallowFlushIfSupported();
205 has_performed_uploads_since_last_flush_ = false; 258 has_performed_uploads_since_last_flush_ = false;
206 } 259 }
207 260
208 void PixelBufferRasterWorkerPool::CheckForCompletedUploads() { 261 void PixelBufferRasterWorkerPool::CheckForCompletedUploads() {
209 TaskDeque tasks_with_completed_uploads; 262 TaskDeque tasks_with_completed_uploads;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 318
266 bytes_pending_upload_ -= task->resource()->bytes(); 319 bytes_pending_upload_ -= task->resource()->bytes();
267 320
268 task->DidRun(false); 321 task->DidRun(false);
269 322
270 DCHECK(std::find(completed_tasks_.begin(), 323 DCHECK(std::find(completed_tasks_.begin(),
271 completed_tasks_.end(), 324 completed_tasks_.end(),
272 task) == completed_tasks_.end()); 325 task) == completed_tasks_.end());
273 completed_tasks_.push_back(task); 326 completed_tasks_.push_back(task);
274 327
328 tasks_required_for_activation_.erase(task);
329
275 tasks_with_completed_uploads.pop_front(); 330 tasks_with_completed_uploads.pop_front();
276 } 331 }
277 } 332 }
278 333
279 void PixelBufferRasterWorkerPool::ScheduleCheckForCompletedRasterTasks() { 334 void PixelBufferRasterWorkerPool::ScheduleCheckForCompletedRasterTasks() {
280 if (check_for_completed_raster_tasks_pending_) 335 if (check_for_completed_raster_tasks_pending_)
281 return; 336 return;
282 337
283 check_for_completed_raster_tasks_callback_.Reset( 338 check_for_completed_raster_tasks_callback_.Reset(
284 base::Bind(&PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks, 339 base::Bind(&PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks,
285 base::Unretained(this))); 340 base::Unretained(this)));
286 base::MessageLoopProxy::current()->PostDelayedTask( 341 base::MessageLoopProxy::current()->PostDelayedTask(
287 FROM_HERE, 342 FROM_HERE,
288 check_for_completed_raster_tasks_callback_.callback(), 343 check_for_completed_raster_tasks_callback_.callback(),
289 base::TimeDelta::FromMilliseconds(kCheckForCompletedRasterTasksDelayMs)); 344 base::TimeDelta::FromMilliseconds(kCheckForCompletedRasterTasksDelayMs));
290 check_for_completed_raster_tasks_pending_ = true; 345 check_for_completed_raster_tasks_pending_ = true;
291 } 346 }
292 347
293 void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() { 348 void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() {
294 TRACE_EVENT0( 349 TRACE_EVENT0(
295 "cc", "PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks"); 350 "cc", "PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks");
296 351
297 check_for_completed_raster_tasks_callback_.Cancel(); 352 check_for_completed_raster_tasks_callback_.Cancel();
298 check_for_completed_raster_tasks_pending_ = false; 353 check_for_completed_raster_tasks_pending_ = false;
299 354
300 RasterWorkerPool::CheckForCompletedTasks(); 355 RasterWorkerPool::CheckForCompletedTasks();
301 CheckForCompletedUploads(); 356 CheckForCompletedUploads();
302 FlushUploads(); 357 FlushUploads();
303 358
304 ScheduleMoreTasks(); 359 // Determine if client should be notified and update pending notification
360 // status before scheduling more raster tasks.
361 bool notify_client_that_finished_running_tasks_required_for_activation =
362 NotifyClientThatFinishedRunningTasksRequiredForActivation();
vmpstr 2013/06/27 23:31:21 ShouldNotify... I think we have to rethink the nam
reveman 2013/06/28 17:26:07 I agree. I'll come up with a better name asap. Let
363 bool notify_client_that_finished_running_tasks =
364 NotifyClientThatFinishedRunningTasks();
305 365
306 // Make sure another check for completed uploads is scheduled 366 if (PendingRasterTaskCount())
307 // while there is still pending uploads left. 367 ScheduleMoreTasks();
308 if (!tasks_with_pending_upload_.empty()) 368
369 // Schedule another check for completed raster tasks while there are
370 // pending raster tasks or pending uploads.
371 if (PendingRasterTaskCount() || !tasks_with_pending_upload_.empty())
309 ScheduleCheckForCompletedRasterTasks(); 372 ScheduleCheckForCompletedRasterTasks();
373
374 if (notify_client_that_finished_running_tasks_required_for_activation)
375 client()->DidFinishedRunningTasksRequiredForActivation();
376 if (notify_client_that_finished_running_tasks)
377 client()->DidFinishedRunningTasks();
310 } 378 }
311 379
312 void PixelBufferRasterWorkerPool::ScheduleMoreTasks() { 380 void PixelBufferRasterWorkerPool::ScheduleMoreTasks() {
313 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleMoreTasks"); 381 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleMoreTasks");
314 382
383 ++schedule_raster_tasks_count_;
384
385 enum RasterTaskType {
386 PREPAINT_TYPE = 0,
387 REQUIRED_FOR_ACTIVATION_TYPE = 1,
388 NUM_TYPES = 2
389 };
390 ScopedPtrDeque<GraphNode> tasks[NUM_TYPES];
391 unsigned priority = 2u; // 0-1 reserved for RasterFinished tasks.
392 TaskGraph graph;
393
315 size_t bytes_pending_upload = bytes_pending_upload_; 394 size_t bytes_pending_upload = bytes_pending_upload_;
316 size_t bytes_pending_raster = 0; 395 size_t bytes_pending_raster = 0;
317 396
318 RasterTaskGraph graph;
319 for (RasterTaskVector::const_iterator it = raster_tasks().begin(); 397 for (RasterTaskVector::const_iterator it = raster_tasks().begin();
320 it != raster_tasks().end(); ++it) { 398 it != raster_tasks().end(); ++it) {
321 internal::RasterWorkerPoolTask* task = it->get(); 399 internal::RasterWorkerPoolTask* task = it->get();
322 400
323 // |pixel_buffer_tasks_| contains all tasks that have not yet completed. 401 // |pixel_buffer_tasks_| contains all tasks that have not yet completed.
324 TaskMap::iterator pixel_buffer_it = pixel_buffer_tasks_.find(task); 402 TaskMap::iterator pixel_buffer_it = pixel_buffer_tasks_.find(task);
325 if (pixel_buffer_it == pixel_buffer_tasks_.end()) 403 if (pixel_buffer_it == pixel_buffer_tasks_.end())
326 continue; 404 continue;
327 405
328 // HasFinishedRunning() will return true when set pixels has completed. 406 // HasFinishedRunning() will return true when set pixels has completed.
(...skipping 23 matching lines...) Expand all
352 size_t new_bytes_pending_raster = bytes_pending_raster; 430 size_t new_bytes_pending_raster = bytes_pending_raster;
353 new_bytes_pending_raster += task->resource()->bytes(); 431 new_bytes_pending_raster += task->resource()->bytes();
354 if (new_bytes_pending_raster > kMaxPendingRasterBytes) 432 if (new_bytes_pending_raster > kMaxPendingRasterBytes)
355 break; 433 break;
356 434
357 // Update both |bytes_pending_raster| and |bytes_pending_upload| 435 // Update both |bytes_pending_raster| and |bytes_pending_upload|
358 // now that task has cleared all throttling limits. 436 // now that task has cleared all throttling limits.
359 bytes_pending_raster = new_bytes_pending_raster; 437 bytes_pending_raster = new_bytes_pending_raster;
360 bytes_pending_upload = new_bytes_pending_upload; 438 bytes_pending_upload = new_bytes_pending_upload;
361 439
440 RasterTaskType type = IsRasterTaskRequiredForActivation(task) ?
441 REQUIRED_FOR_ACTIVATION_TYPE :
442 PREPAINT_TYPE;
443
362 // Use existing pixel buffer task if available. 444 // Use existing pixel buffer task if available.
363 if (pixel_buffer_task) { 445 if (pixel_buffer_task) {
364 graph.InsertRasterTask(pixel_buffer_task, task->dependencies()); 446 tasks[type].push_back(
447 CreateRasterTaskGraphNode(pixel_buffer_task,
448 task->dependencies(),
449 priority++,
450 &graph));
365 continue; 451 continue;
366 } 452 }
367 453
368 // Request a pixel buffer. This will reserve shared memory. 454 // Request a pixel buffer. This will reserve shared memory.
369 resource_provider()->AcquirePixelBuffer(task->resource()->id()); 455 resource_provider()->AcquirePixelBuffer(task->resource()->id());
370 456
371 // MapPixelBuffer() returns NULL if context was lost at the time 457 // MapPixelBuffer() returns NULL if context was lost at the time
372 // AcquirePixelBuffer() was called. For simplicity we still post 458 // AcquirePixelBuffer() was called. For simplicity we still post
373 // a raster task that is essentially a noop in these situations. 459 // a raster task that is essentially a noop in these situations.
374 uint8* buffer = resource_provider()->MapPixelBuffer( 460 uint8* buffer = resource_provider()->MapPixelBuffer(
375 task->resource()->id()); 461 task->resource()->id());
376 462
377 scoped_refptr<internal::WorkerPoolTask> new_pixel_buffer_task( 463 scoped_refptr<internal::WorkerPoolTask> new_pixel_buffer_task(
378 new PixelBufferWorkerPoolTaskImpl( 464 new PixelBufferWorkerPoolTaskImpl(
379 task, 465 task,
380 buffer, 466 buffer,
381 base::Bind(&PixelBufferRasterWorkerPool::OnRasterTaskCompleted, 467 base::Bind(&PixelBufferRasterWorkerPool::OnRasterTaskCompleted,
382 base::Unretained(this), 468 base::Unretained(this),
383 make_scoped_refptr(task)))); 469 make_scoped_refptr(task))));
384 pixel_buffer_tasks_[task] = new_pixel_buffer_task; 470 pixel_buffer_tasks_[task] = new_pixel_buffer_task;
385 graph.InsertRasterTask(new_pixel_buffer_task.get(), task->dependencies()); 471 tasks[type].push_back(
472 CreateRasterTaskGraphNode(new_pixel_buffer_task.get(),
473 task->dependencies(),
474 priority++,
475 &graph));
386 } 476 }
387 477
388 SetRasterTaskGraph(&graph); 478 scoped_refptr<internal::WorkerPoolTask> new_raster_finished_task;
389 479
390 // At least one task that could need an upload is now pending, schedule 480 DCHECK_LE(tasks[PREPAINT_TYPE].size() +
vmpstr 2013/06/27 23:31:21 The comments from irwp apply in in this area as we
reveman 2013/06/28 17:26:07 PTAL.
391 // a check for completed raster tasks to ensure this upload is dispatched 481 tasks[REQUIRED_FOR_ACTIVATION_TYPE].size(),
392 // without too much latency. 482 PendingRasterTaskCount());
393 if (bytes_pending_raster) 483 // Schedule OnRasterFinished call when notification is pending
394 ScheduleCheckForCompletedRasterTasks(); 484 // and throttling is not preventing all pending tasks from
485 // being scheduled.
486 if ((tasks[PREPAINT_TYPE].size() +
487 tasks[REQUIRED_FOR_ACTIVATION_TYPE].size()) ==
488 PendingRasterTaskCount() &&
489 finished_running_tasks_pending_) {
490 new_raster_finished_task = make_scoped_refptr(
491 new RasterFinishedWorkerPoolTaskImpl(
492 base::MessageLoopProxy::current(),
493 base::Bind(&PixelBufferRasterWorkerPool::OnRasterFinished,
494 weak_ptr_factory_.GetWeakPtr(),
495 schedule_raster_tasks_count_)));
496 scoped_ptr<GraphNode> raster_finished_node(
497 new GraphNode(new_raster_finished_task.get(),
498 1u)); // Priority 1
499 for (unsigned i = 0; i < NUM_TYPES; ++i) {
500 for (unsigned j = 0; j < tasks[i].size(); ++j) {
501 raster_finished_node->add_dependency();
502 tasks[i][j]->add_dependent(raster_finished_node.get());
503 }
504 }
505 graph.set(new_raster_finished_task.get(), raster_finished_node.Pass());
506 }
507
508 scoped_refptr<internal::WorkerPoolTask>
509 new_raster_required_for_activation_finished_task;
510
511 DCHECK_LE(tasks[REQUIRED_FOR_ACTIVATION_TYPE].size(),
512 tasks_required_for_activation_.size());
513 // Schedule OnRasterRequiredForActivationFinished call when
514 // notification is pending and throttling is not preventing
515 // all pending tasks required for activation from being scheduled.
516 if (tasks[REQUIRED_FOR_ACTIVATION_TYPE].size() ==
517 tasks_required_for_activation_.size() &&
518 finished_running_tasks_required_for_activation_pending_) {
519 new_raster_required_for_activation_finished_task = make_scoped_refptr(
520 new RasterFinishedWorkerPoolTaskImpl(
521 base::MessageLoopProxy::current(),
522 base::Bind(&PixelBufferRasterWorkerPool::
523 OnRasterRequiredForActivationFinished,
524 weak_ptr_factory_.GetWeakPtr(),
525 schedule_raster_tasks_count_)));
526
527 scoped_ptr<GraphNode> raster_required_for_activation_finished_node(
528 new GraphNode(new_raster_required_for_activation_finished_task.get(),
529 0u)); // Priority 0
530 for (unsigned j = 0;
531 j < tasks[REQUIRED_FOR_ACTIVATION_TYPE].size();
532 ++j) {
533 raster_required_for_activation_finished_node->add_dependency();
534 tasks[REQUIRED_FOR_ACTIVATION_TYPE][j]->add_dependent(
535 raster_required_for_activation_finished_node.get());
536 }
537 graph.set(new_raster_required_for_activation_finished_task.get(),
538 raster_required_for_activation_finished_node.Pass());
539 }
540
541 for (unsigned i = 0; i < NUM_TYPES; ++i) {
542 while (!tasks[i].empty()) {
543 scoped_ptr<GraphNode> node = tasks[i].take_front();
544 internal::WorkerPoolTask* task = node->task();
545 graph.set(task, node.Pass());
546 }
547 }
548
549 SetTaskGraph(&graph);
550
551 raster_finished_task_.swap(new_raster_finished_task);
552 raster_required_for_activation_finished_task_.swap(
553 new_raster_required_for_activation_finished_task);
554 }
555
556 void PixelBufferRasterWorkerPool::OnRasterFinished(
557 int64 schedule_raster_tasks_count) {
558 TRACE_EVENT1("cc", "PixelBufferRasterWorkerPool::OnRasterFinished",
559 "schedule_raster_tasks_count", schedule_raster_tasks_count);
560 DCHECK_GE(schedule_raster_tasks_count_, schedule_raster_tasks_count);
561 // Call CheckForCompletedRasterTasks() if this callback is
562 // associated with the last call to SetRasterTaskGraph().
563 if (schedule_raster_tasks_count_ == schedule_raster_tasks_count)
564 CheckForCompletedRasterTasks();
565 }
566
567 void PixelBufferRasterWorkerPool::OnRasterRequiredForActivationFinished(
568 int64 schedule_raster_tasks_count) {
569 TRACE_EVENT1(
570 "cc",
571 "PixelBufferRasterWorkerPool::OnRasterRequiredForActivationFinished",
572 "schedule_raster_tasks_count", schedule_raster_tasks_count);
573 DCHECK_GE(schedule_raster_tasks_count_, schedule_raster_tasks_count);
574 // Call CheckForCompletedRasterTasks() if this callback is
575 // associated with the last call to SetRasterTaskGraph().
576 if (schedule_raster_tasks_count_ == schedule_raster_tasks_count)
577 CheckForCompletedRasterTasks();
395 } 578 }
396 579
397 void PixelBufferRasterWorkerPool::OnRasterTaskCompleted( 580 void PixelBufferRasterWorkerPool::OnRasterTaskCompleted(
398 scoped_refptr<internal::RasterWorkerPoolTask> task, 581 scoped_refptr<internal::RasterWorkerPoolTask> task,
399 bool was_canceled, 582 bool was_canceled,
400 bool needs_upload) { 583 bool needs_upload) {
401 TRACE_EVENT2("cc", "PixelBufferRasterWorkerPool::OnRasterTaskCompleted", 584 TRACE_EVENT2("cc", "PixelBufferRasterWorkerPool::OnRasterTaskCompleted",
402 "was_canceled", was_canceled, 585 "was_canceled", was_canceled,
403 "needs_upload", needs_upload); 586 "needs_upload", needs_upload);
404 587
405 DCHECK(pixel_buffer_tasks_.find(task.get()) != pixel_buffer_tasks_.end()); 588 DCHECK(pixel_buffer_tasks_.find(task.get()) != pixel_buffer_tasks_.end());
406 589
407 // Balanced with MapPixelBuffer() call in ScheduleMoreTasks(). 590 // Balanced with MapPixelBuffer() call in ScheduleMoreTasks().
408 resource_provider()->UnmapPixelBuffer(task->resource()->id()); 591 resource_provider()->UnmapPixelBuffer(task->resource()->id());
409 592
410 if (!needs_upload) { 593 if (!needs_upload) {
411 resource_provider()->ReleasePixelBuffer(task->resource()->id()); 594 resource_provider()->ReleasePixelBuffer(task->resource()->id());
412 task->DidRun(was_canceled); 595 task->DidRun(was_canceled);
413 DCHECK(std::find(completed_tasks_.begin(), 596 DCHECK(std::find(completed_tasks_.begin(),
414 completed_tasks_.end(), 597 completed_tasks_.end(),
415 task) == completed_tasks_.end()); 598 task) == completed_tasks_.end());
416 completed_tasks_.push_back(task); 599 completed_tasks_.push_back(task);
600 tasks_required_for_activation_.erase(task);
417 return; 601 return;
418 } 602 }
419 603
420 resource_provider()->BeginSetPixels(task->resource()->id()); 604 resource_provider()->BeginSetPixels(task->resource()->id());
421 has_performed_uploads_since_last_flush_ = true; 605 has_performed_uploads_since_last_flush_ = true;
422 606
423 bytes_pending_upload_ += task->resource()->bytes(); 607 bytes_pending_upload_ += task->resource()->bytes();
424 tasks_with_pending_upload_.push_back(task); 608 tasks_with_pending_upload_.push_back(task);
425 } 609 }
426 610
611 unsigned PixelBufferRasterWorkerPool::PendingRasterTaskCount() const {
612 unsigned num_completed_raster_tasks =
613 tasks_with_pending_upload_.size() + completed_tasks_.size();
614 DCHECK_GE(pixel_buffer_tasks_.size(), num_completed_raster_tasks);
615 return pixel_buffer_tasks_.size() - num_completed_raster_tasks;
616 }
617
618 bool PixelBufferRasterWorkerPool::
619 NotifyClientThatFinishedRunningTasksRequiredForActivation() {
620 if (!finished_running_tasks_required_for_activation_pending_)
621 return false;
622
623 if (!tasks_required_for_activation_.empty())
624 return false;
625
626 finished_running_tasks_required_for_activation_pending_ = false;
627 return true;
628 }
629
630 bool PixelBufferRasterWorkerPool::NotifyClientThatFinishedRunningTasks() {
631 if (!finished_running_tasks_pending_)
632 return false;
633
634 if (PendingRasterTaskCount())
635 return false;
636
637 if (!tasks_with_pending_upload_.empty())
638 return false;
639
640 finished_running_tasks_pending_ = false;
641 return true;
642 }
643
427 } // namespace cc 644 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698