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

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: vmpstr's review and a number of other fixes Created 7 years, 6 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/resources/resource.h" 8 #include "cc/resources/resource.h"
9 #include "third_party/skia/include/core/SkDevice.h" 9 #include "third_party/skia/include/core/SkDevice.h"
10 10
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 77
78 const int kCheckForCompletedRasterTasksDelayMs = 6; 78 const int kCheckForCompletedRasterTasksDelayMs = 6;
79 79
80 const size_t kMaxPendingRasterBytes = 80 const size_t kMaxPendingRasterBytes =
81 kMaxBytesUploadedPerMs * kCheckForCompletedRasterTasksDelayMs; 81 kMaxBytesUploadedPerMs * kCheckForCompletedRasterTasksDelayMs;
82 82
83 } // namespace 83 } // namespace
84 84
85 PixelBufferRasterWorkerPool::PixelBufferRasterWorkerPool( 85 PixelBufferRasterWorkerPool::PixelBufferRasterWorkerPool(
86 ResourceProvider* resource_provider, 86 ResourceProvider* resource_provider,
87 size_t num_threads) : RasterWorkerPool(resource_provider, num_threads), 87 size_t num_threads)
88 shutdown_(false), 88 : RasterWorkerPool(resource_provider, num_threads),
89 bytes_pending_upload_(0), 89 shutdown_(false),
90 has_performed_uploads_since_last_flush_(false), 90 bytes_pending_upload_(0),
91 check_for_completed_raster_tasks_pending_(false) { 91 has_performed_uploads_since_last_flush_(false),
92 check_for_completed_raster_tasks_pending_(false),
93 finished_running_tasks_pending_(false),
94 finished_running_tasks_required_for_activation_pending_(false) {
92 } 95 }
93 96
94 PixelBufferRasterWorkerPool::~PixelBufferRasterWorkerPool() { 97 PixelBufferRasterWorkerPool::~PixelBufferRasterWorkerPool() {
95 DCHECK(shutdown_); 98 DCHECK(shutdown_);
96 DCHECK(!check_for_completed_raster_tasks_pending_); 99 DCHECK(!check_for_completed_raster_tasks_pending_);
97 DCHECK_EQ(0u, pixel_buffer_tasks_.size()); 100 DCHECK_EQ(0u, pixel_buffer_tasks_.size());
98 DCHECK_EQ(0u, tasks_with_pending_upload_.size()); 101 DCHECK_EQ(0u, tasks_with_pending_upload_.size());
99 DCHECK_EQ(0u, completed_tasks_.size()); 102 DCHECK_EQ(0u, completed_tasks_.size());
100 } 103 }
101 104
102 void PixelBufferRasterWorkerPool::Shutdown() { 105 void PixelBufferRasterWorkerPool::Shutdown() {
103 shutdown_ = true; 106 shutdown_ = true;
104 RasterWorkerPool::Shutdown(); 107 RasterWorkerPool::Shutdown();
105 CheckForCompletedRasterTasks(); 108 RasterWorkerPool::CheckForCompletedTasks();
109 CheckForCompletedUploads();
110 check_for_completed_raster_tasks_callback_.Cancel();
111 check_for_completed_raster_tasks_pending_ = false;
106 for (TaskMap::iterator it = pixel_buffer_tasks_.begin(); 112 for (TaskMap::iterator it = pixel_buffer_tasks_.begin();
107 it != pixel_buffer_tasks_.end(); ++it) { 113 it != pixel_buffer_tasks_.end(); ++it) {
108 internal::RasterWorkerPoolTask* task = it->first; 114 internal::RasterWorkerPoolTask* task = it->first;
109 internal::WorkerPoolTask* pixel_buffer_task = it->second.get(); 115 internal::WorkerPoolTask* pixel_buffer_task = it->second.get();
110 116
111 // All inactive tasks needs to be canceled. 117 // All inactive tasks needs to be canceled.
112 if (!pixel_buffer_task && !task->HasFinishedRunning()) { 118 if (!pixel_buffer_task && !task->HasFinishedRunning()) {
113 task->DidRun(true); 119 task->DidRun(true);
114 completed_tasks_.push_back(task); 120 completed_tasks_.push_back(task);
115 } 121 }
116 } 122 }
123 DCHECK_EQ(completed_tasks_.size(), pixel_buffer_tasks_.size());
117 } 124 }
118 125
119 void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTask::Queue* queue) { 126 void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTask::Queue* queue) {
120 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleTasks"); 127 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleTasks");
121 128
122 RasterWorkerPool::SetRasterTasks(queue); 129 RasterWorkerPool::SetRasterTasks(queue);
123 130
131 finished_running_tasks_pending_ = true;
132 finished_running_tasks_required_for_activation_pending_ = true;
133
124 // Build new pixel buffer task set. 134 // Build new pixel buffer task set.
125 TaskMap new_pixel_buffer_tasks; 135 TaskMap new_pixel_buffer_tasks;
126 for (RasterTaskVector::const_iterator it = raster_tasks().begin(); 136 for (RasterTaskVector::const_iterator it = raster_tasks().begin();
127 it != raster_tasks().end(); ++it) { 137 it != raster_tasks().end(); ++it) {
128 internal::RasterWorkerPoolTask* task = it->get(); 138 internal::RasterWorkerPoolTask* task = it->get();
129 DCHECK(new_pixel_buffer_tasks.find(task) == new_pixel_buffer_tasks.end()); 139 DCHECK(new_pixel_buffer_tasks.find(task) == new_pixel_buffer_tasks.end());
130 DCHECK(!task->HasCompleted()); 140 DCHECK(!task->HasCompleted());
131 141
132 // Use existing pixel buffer task if available. 142 // Use existing pixel buffer task if available.
133 TaskMap::iterator pixel_buffer_it = pixel_buffer_tasks_.find(task); 143 TaskMap::iterator pixel_buffer_it = pixel_buffer_tasks_.find(task);
(...skipping 19 matching lines...) Expand all
153 // Inactive task can be canceled. 163 // Inactive task can be canceled.
154 if (!pixel_buffer_task && !task->HasFinishedRunning()) { 164 if (!pixel_buffer_task && !task->HasFinishedRunning()) {
155 task->DidRun(true); 165 task->DidRun(true);
156 DCHECK(std::find(completed_tasks_.begin(), 166 DCHECK(std::find(completed_tasks_.begin(),
157 completed_tasks_.end(), 167 completed_tasks_.end(),
158 task) == completed_tasks_.end()); 168 task) == completed_tasks_.end());
159 completed_tasks_.push_back(task); 169 completed_tasks_.push_back(task);
160 } 170 }
161 } 171 }
162 172
173 tasks_required_for_activation_.clear();
174 for (TaskMap::iterator it = new_pixel_buffer_tasks.begin();
175 it != new_pixel_buffer_tasks.end(); ++it) {
176 internal::RasterWorkerPoolTask* task = it->first;
177 if (IsRasterTaskRequiredForActivation(task))
178 tasks_required_for_activation_.insert(task);
179 }
180
163 pixel_buffer_tasks_.swap(new_pixel_buffer_tasks); 181 pixel_buffer_tasks_.swap(new_pixel_buffer_tasks);
164 182
165 // This will schedule more tasks after checking for completed raster 183 // Check for completed tasks when ScheduleTasks() is called as
166 // tasks. It's worth checking for completed tasks when ScheduleTasks() 184 // priorities might have changed and this maximizes the number
167 // is called as priorities might have changed and this allows us to 185 // of top priority tasks that are scheduled.
168 // schedule as many new top priority tasks as possible. 186 RasterWorkerPool::CheckForCompletedTasks();
169 CheckForCompletedRasterTasks(); 187 CheckForCompletedUploads();
188 FlushUploads();
189
190 // Schedule new tasks.
191 ScheduleMoreTasks();
192
193 // Cancel any pending check for completed raster tasks and schedule
194 // another check.
195 check_for_completed_raster_tasks_callback_.Cancel();
196 check_for_completed_raster_tasks_pending_ = false;
197 ScheduleCheckForCompletedRasterTasks();
170 } 198 }
171 199
172 void PixelBufferRasterWorkerPool::CheckForCompletedTasks() { 200 void PixelBufferRasterWorkerPool::CheckForCompletedTasks() {
173 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::CheckForCompletedTasks"); 201 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::CheckForCompletedTasks");
174 202
175 RasterWorkerPool::CheckForCompletedTasks(); 203 RasterWorkerPool::CheckForCompletedTasks();
176 CheckForCompletedUploads(); 204 CheckForCompletedUploads();
177 FlushUploads(); 205 FlushUploads();
178 206
179 while (!completed_tasks_.empty()) { 207 TaskDeque completed_tasks;
180 internal::RasterWorkerPoolTask* task = completed_tasks_.front().get(); 208 completed_tasks_.swap(completed_tasks);
209
210 while (!completed_tasks.empty()) {
211 internal::RasterWorkerPoolTask* task = completed_tasks.front().get();
181 DCHECK(pixel_buffer_tasks_.find(task) != pixel_buffer_tasks_.end()); 212 DCHECK(pixel_buffer_tasks_.find(task) != pixel_buffer_tasks_.end());
182 213
183 pixel_buffer_tasks_.erase(task); 214 pixel_buffer_tasks_.erase(task);
184 215
185 task->DidComplete(); 216 task->DidComplete();
186 task->DispatchCompletionCallback(); 217 task->DispatchCompletionCallback();
187 218
188 completed_tasks_.pop_front(); 219 completed_tasks.pop_front();
189 } 220 }
190 } 221 }
191 222
192 void PixelBufferRasterWorkerPool::OnRasterTasksFinished() { 223 void PixelBufferRasterWorkerPool::OnRasterTasksFinished() {
193 // Call CheckForCompletedTasks() when we've finished running all raster 224 // Call CheckForCompletedTasks() when we've finished running all raster
194 // tasks needed since last time ScheduleMoreTasks() was called. This 225 // tasks needed since last time ScheduleMoreTasks() was called. This
195 // reduces latency when processing only a small number of raster tasks. 226 // reduces latency when processing only a small number of raster tasks.
196 CheckForCompletedRasterTasks(); 227 CheckForCompletedRasterTasks();
197 } 228 }
198 229
230 void PixelBufferRasterWorkerPool::
231 OnRasterTasksRequiredForActivationFinished() {
vmpstr 2013/06/24 16:34:03 nit: I _think_ this might just fit on one line?
reveman 2013/06/24 19:05:17 Done.
232 if (tasks_required_for_activation_.empty())
233 return;
234 OnRasterTasksFinished();
235 }
236
199 void PixelBufferRasterWorkerPool::FlushUploads() { 237 void PixelBufferRasterWorkerPool::FlushUploads() {
200 if (!has_performed_uploads_since_last_flush_) 238 if (!has_performed_uploads_since_last_flush_)
201 return; 239 return;
202 240
203 resource_provider()->ShallowFlushIfSupported(); 241 resource_provider()->ShallowFlushIfSupported();
204 has_performed_uploads_since_last_flush_ = false; 242 has_performed_uploads_since_last_flush_ = false;
205 } 243 }
206 244
207 void PixelBufferRasterWorkerPool::CheckForCompletedUploads() { 245 void PixelBufferRasterWorkerPool::CheckForCompletedUploads() {
208 TaskDeque tasks_with_completed_uploads; 246 TaskDeque tasks_with_completed_uploads;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 294
257 bytes_pending_upload_ -= task->resource()->bytes(); 295 bytes_pending_upload_ -= task->resource()->bytes();
258 296
259 task->DidRun(false); 297 task->DidRun(false);
260 298
261 DCHECK(std::find(completed_tasks_.begin(), 299 DCHECK(std::find(completed_tasks_.begin(),
262 completed_tasks_.end(), 300 completed_tasks_.end(),
263 task) == completed_tasks_.end()); 301 task) == completed_tasks_.end());
264 completed_tasks_.push_back(task); 302 completed_tasks_.push_back(task);
265 303
304 tasks_required_for_activation_.erase(task);
305
266 tasks_with_completed_uploads.pop_front(); 306 tasks_with_completed_uploads.pop_front();
267 } 307 }
268 } 308 }
269 309
270 void PixelBufferRasterWorkerPool::ScheduleCheckForCompletedRasterTasks() { 310 void PixelBufferRasterWorkerPool::ScheduleCheckForCompletedRasterTasks() {
271 if (check_for_completed_raster_tasks_pending_) 311 if (check_for_completed_raster_tasks_pending_)
272 return; 312 return;
273 313
274 check_for_completed_raster_tasks_callback_.Reset( 314 check_for_completed_raster_tasks_callback_.Reset(
275 base::Bind(&PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks, 315 base::Bind(&PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks,
276 base::Unretained(this))); 316 base::Unretained(this)));
277 base::MessageLoopProxy::current()->PostDelayedTask( 317 base::MessageLoopProxy::current()->PostDelayedTask(
278 FROM_HERE, 318 FROM_HERE,
279 check_for_completed_raster_tasks_callback_.callback(), 319 check_for_completed_raster_tasks_callback_.callback(),
280 base::TimeDelta::FromMilliseconds(kCheckForCompletedRasterTasksDelayMs)); 320 base::TimeDelta::FromMilliseconds(kCheckForCompletedRasterTasksDelayMs));
281 check_for_completed_raster_tasks_pending_ = true; 321 check_for_completed_raster_tasks_pending_ = true;
282 } 322 }
283 323
284 void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() { 324 void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() {
285 TRACE_EVENT0( 325 TRACE_EVENT0(
286 "cc", "PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks"); 326 "cc", "PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks");
287 327
288 check_for_completed_raster_tasks_callback_.Cancel(); 328 check_for_completed_raster_tasks_callback_.Cancel();
289 check_for_completed_raster_tasks_pending_ = false; 329 check_for_completed_raster_tasks_pending_ = false;
290 330
291 RasterWorkerPool::CheckForCompletedTasks(); 331 RasterWorkerPool::CheckForCompletedTasks();
292 CheckForCompletedUploads(); 332 CheckForCompletedUploads();
293 FlushUploads(); 333 FlushUploads();
294 334
295 ScheduleMoreTasks(); 335 if (PendingRasterTaskCount())
336 ScheduleMoreTasks();
296 337
297 // Make sure another check for completed uploads is scheduled 338 // Schedule another check for completed raster tasks while there are
298 // while there is still pending uploads left. 339 // pending raster tasks or pending uploads.
299 if (!tasks_with_pending_upload_.empty()) 340 if (PendingRasterTaskCount() || !tasks_with_pending_upload_.empty())
300 ScheduleCheckForCompletedRasterTasks(); 341 ScheduleCheckForCompletedRasterTasks();
342
343 NotifyClientIfFinishedRunningTasksRequiredForActivation();
344 NotifyClientIfFinishedRunningTasks();
301 } 345 }
302 346
303 void PixelBufferRasterWorkerPool::ScheduleMoreTasks() { 347 void PixelBufferRasterWorkerPool::ScheduleMoreTasks() {
304 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleMoreTasks"); 348 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleMoreTasks");
305 349
306 size_t bytes_pending_upload = bytes_pending_upload_; 350 size_t bytes_pending_upload = bytes_pending_upload_;
307 size_t bytes_pending_raster = 0; 351 size_t bytes_pending_raster = 0;
308 352
309 RasterTaskGraph graph; 353 RasterTaskGraph graph;
310 for (RasterTaskVector::const_iterator it = raster_tasks().begin(); 354 for (RasterTaskVector::const_iterator it = raster_tasks().begin();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 if (new_bytes_pending_raster > kMaxPendingRasterBytes) 389 if (new_bytes_pending_raster > kMaxPendingRasterBytes)
346 break; 390 break;
347 391
348 // Update both |bytes_pending_raster| and |bytes_pending_upload| 392 // Update both |bytes_pending_raster| and |bytes_pending_upload|
349 // now that task has cleared all throttling limits. 393 // now that task has cleared all throttling limits.
350 bytes_pending_raster = new_bytes_pending_raster; 394 bytes_pending_raster = new_bytes_pending_raster;
351 bytes_pending_upload = new_bytes_pending_upload; 395 bytes_pending_upload = new_bytes_pending_upload;
352 396
353 // Use existing pixel buffer task if available. 397 // Use existing pixel buffer task if available.
354 if (pixel_buffer_task) { 398 if (pixel_buffer_task) {
355 graph.InsertRasterTask(pixel_buffer_task, task->dependencies()); 399 graph.InsertRasterTask(pixel_buffer_task,
400 task->dependencies(),
401 IsRasterTaskRequiredForActivation(task));
356 continue; 402 continue;
357 } 403 }
358 404
359 // Request a pixel buffer. This will reserve shared memory. 405 // Request a pixel buffer. This will reserve shared memory.
360 resource_provider()->AcquirePixelBuffer(task->resource()->id()); 406 resource_provider()->AcquirePixelBuffer(task->resource()->id());
361 407
362 // MapPixelBuffer() returns NULL if context was lost at the time 408 // MapPixelBuffer() returns NULL if context was lost at the time
363 // AcquirePixelBuffer() was called. For simplicity we still post 409 // AcquirePixelBuffer() was called. For simplicity we still post
364 // a raster task that is essentially a noop in these situations. 410 // a raster task that is essentially a noop in these situations.
365 uint8* buffer = resource_provider()->MapPixelBuffer( 411 uint8* buffer = resource_provider()->MapPixelBuffer(
366 task->resource()->id()); 412 task->resource()->id());
367 413
368 scoped_refptr<internal::WorkerPoolTask> new_pixel_buffer_task( 414 scoped_refptr<internal::WorkerPoolTask> new_pixel_buffer_task(
369 new PixelBufferWorkerPoolTaskImpl( 415 new PixelBufferWorkerPoolTaskImpl(
370 task, 416 task,
371 buffer, 417 buffer,
372 base::Bind(&PixelBufferRasterWorkerPool::OnRasterTaskCompleted, 418 base::Bind(&PixelBufferRasterWorkerPool::OnRasterTaskCompleted,
373 base::Unretained(this), 419 base::Unretained(this),
374 make_scoped_refptr(task)))); 420 make_scoped_refptr(task))));
375 pixel_buffer_tasks_[task] = new_pixel_buffer_task; 421 pixel_buffer_tasks_[task] = new_pixel_buffer_task;
376 graph.InsertRasterTask(new_pixel_buffer_task.get(), task->dependencies()); 422 graph.InsertRasterTask(new_pixel_buffer_task.get(),
423 task->dependencies(),
424 IsRasterTaskRequiredForActivation(task));
377 } 425 }
378 426
379 SetRasterTaskGraph(&graph); 427 SetRasterTaskGraph(&graph);
380
381 // At least one task that could need an upload is now pending, schedule
382 // a check for completed raster tasks to ensure this upload is dispatched
383 // without too much latency.
384 if (bytes_pending_raster)
385 ScheduleCheckForCompletedRasterTasks();
386 } 428 }
387 429
388 void PixelBufferRasterWorkerPool::OnRasterTaskCompleted( 430 void PixelBufferRasterWorkerPool::OnRasterTaskCompleted(
389 scoped_refptr<internal::RasterWorkerPoolTask> task, 431 scoped_refptr<internal::RasterWorkerPoolTask> task,
390 bool was_canceled, 432 bool was_canceled,
391 bool needs_upload) { 433 bool needs_upload) {
392 TRACE_EVENT2("cc", "PixelBufferRasterWorkerPool::OnRasterTaskCompleted", 434 TRACE_EVENT2("cc", "PixelBufferRasterWorkerPool::OnRasterTaskCompleted",
393 "was_canceled", was_canceled, 435 "was_canceled", was_canceled,
394 "needs_upload", needs_upload); 436 "needs_upload", needs_upload);
395 437
396 DCHECK(pixel_buffer_tasks_.find(task.get()) != pixel_buffer_tasks_.end()); 438 DCHECK(pixel_buffer_tasks_.find(task.get()) != pixel_buffer_tasks_.end());
397 439
398 // Balanced with MapPixelBuffer() call in ScheduleMoreTasks(). 440 // Balanced with MapPixelBuffer() call in ScheduleMoreTasks().
399 resource_provider()->UnmapPixelBuffer(task->resource()->id()); 441 resource_provider()->UnmapPixelBuffer(task->resource()->id());
400 442
401 if (!needs_upload) { 443 if (!needs_upload) {
402 resource_provider()->ReleasePixelBuffer(task->resource()->id()); 444 resource_provider()->ReleasePixelBuffer(task->resource()->id());
403 task->DidRun(was_canceled); 445 task->DidRun(was_canceled);
404 DCHECK(std::find(completed_tasks_.begin(), 446 DCHECK(std::find(completed_tasks_.begin(),
405 completed_tasks_.end(), 447 completed_tasks_.end(),
406 task) == completed_tasks_.end()); 448 task) == completed_tasks_.end());
407 completed_tasks_.push_back(task); 449 completed_tasks_.push_back(task);
450 tasks_required_for_activation_.erase(task);
408 return; 451 return;
409 } 452 }
410 453
411 resource_provider()->BeginSetPixels(task->resource()->id()); 454 resource_provider()->BeginSetPixels(task->resource()->id());
412 has_performed_uploads_since_last_flush_ = true; 455 has_performed_uploads_since_last_flush_ = true;
413 456
414 bytes_pending_upload_ += task->resource()->bytes(); 457 bytes_pending_upload_ += task->resource()->bytes();
415 tasks_with_pending_upload_.push_back(task); 458 tasks_with_pending_upload_.push_back(task);
416 } 459 }
417 460
461 unsigned PixelBufferRasterWorkerPool::PendingRasterTaskCount() const {
462 unsigned num_completed_raster_tasks =
463 tasks_with_pending_upload_.size() + completed_tasks_.size();
464 DCHECK_GE(pixel_buffer_tasks_.size(), num_completed_raster_tasks);
465 return pixel_buffer_tasks_.size() - num_completed_raster_tasks;
466 }
467
468 void PixelBufferRasterWorkerPool::
469 NotifyClientIfFinishedRunningTasksRequiredForActivation() {
470 if (!finished_running_tasks_required_for_activation_pending_)
471 return;
472
473 if (!tasks_required_for_activation_.empty())
474 return;
475
476 client()->DidFinishedRunningTasksRequiredForActivation();
477 finished_running_tasks_required_for_activation_pending_ = false;
478 }
479
480 void PixelBufferRasterWorkerPool::NotifyClientIfFinishedRunningTasks() {
481 if (!finished_running_tasks_pending_)
482 return;
483
484 if (PendingRasterTaskCount())
485 return;
486
487 if (!tasks_with_pending_upload_.empty())
488 return;
489
490 client()->DidFinishedRunningTasks();
491 finished_running_tasks_pending_ = false;
492 }
493
418 } // namespace cc 494 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698