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

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 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::OnRasterTasksRequiredForActivationFinished() {
231 if (tasks_required_for_activation_.empty())
232 return;
233 OnRasterTasksFinished();
234 }
235
199 void PixelBufferRasterWorkerPool::FlushUploads() { 236 void PixelBufferRasterWorkerPool::FlushUploads() {
200 if (!has_performed_uploads_since_last_flush_) 237 if (!has_performed_uploads_since_last_flush_)
201 return; 238 return;
202 239
203 resource_provider()->ShallowFlushIfSupported(); 240 resource_provider()->ShallowFlushIfSupported();
204 has_performed_uploads_since_last_flush_ = false; 241 has_performed_uploads_since_last_flush_ = false;
205 } 242 }
206 243
207 void PixelBufferRasterWorkerPool::CheckForCompletedUploads() { 244 void PixelBufferRasterWorkerPool::CheckForCompletedUploads() {
208 TaskDeque tasks_with_completed_uploads; 245 TaskDeque tasks_with_completed_uploads;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 293
257 bytes_pending_upload_ -= task->resource()->bytes(); 294 bytes_pending_upload_ -= task->resource()->bytes();
258 295
259 task->DidRun(false); 296 task->DidRun(false);
260 297
261 DCHECK(std::find(completed_tasks_.begin(), 298 DCHECK(std::find(completed_tasks_.begin(),
262 completed_tasks_.end(), 299 completed_tasks_.end(),
263 task) == completed_tasks_.end()); 300 task) == completed_tasks_.end());
264 completed_tasks_.push_back(task); 301 completed_tasks_.push_back(task);
265 302
303 tasks_required_for_activation_.erase(task);
304
266 tasks_with_completed_uploads.pop_front(); 305 tasks_with_completed_uploads.pop_front();
267 } 306 }
268 } 307 }
269 308
270 void PixelBufferRasterWorkerPool::ScheduleCheckForCompletedRasterTasks() { 309 void PixelBufferRasterWorkerPool::ScheduleCheckForCompletedRasterTasks() {
271 if (check_for_completed_raster_tasks_pending_) 310 if (check_for_completed_raster_tasks_pending_)
272 return; 311 return;
273 312
274 check_for_completed_raster_tasks_callback_.Reset( 313 check_for_completed_raster_tasks_callback_.Reset(
275 base::Bind(&PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks, 314 base::Bind(&PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks,
276 base::Unretained(this))); 315 base::Unretained(this)));
277 base::MessageLoopProxy::current()->PostDelayedTask( 316 base::MessageLoopProxy::current()->PostDelayedTask(
278 FROM_HERE, 317 FROM_HERE,
279 check_for_completed_raster_tasks_callback_.callback(), 318 check_for_completed_raster_tasks_callback_.callback(),
280 base::TimeDelta::FromMilliseconds(kCheckForCompletedRasterTasksDelayMs)); 319 base::TimeDelta::FromMilliseconds(kCheckForCompletedRasterTasksDelayMs));
281 check_for_completed_raster_tasks_pending_ = true; 320 check_for_completed_raster_tasks_pending_ = true;
282 } 321 }
283 322
284 void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() { 323 void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() {
285 TRACE_EVENT0( 324 TRACE_EVENT0(
286 "cc", "PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks"); 325 "cc", "PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks");
287 326
288 check_for_completed_raster_tasks_callback_.Cancel(); 327 check_for_completed_raster_tasks_callback_.Cancel();
289 check_for_completed_raster_tasks_pending_ = false; 328 check_for_completed_raster_tasks_pending_ = false;
290 329
291 RasterWorkerPool::CheckForCompletedTasks(); 330 RasterWorkerPool::CheckForCompletedTasks();
292 CheckForCompletedUploads(); 331 CheckForCompletedUploads();
293 FlushUploads(); 332 FlushUploads();
294 333
295 ScheduleMoreTasks(); 334 if (PendingRasterTaskCount())
335 ScheduleMoreTasks();
296 336
297 // Make sure another check for completed uploads is scheduled 337 // Schedule another check for completed raster tasks while there are
298 // while there is still pending uploads left. 338 // pending raster tasks or pending uploads.
299 if (!tasks_with_pending_upload_.empty()) 339 if (PendingRasterTaskCount() || !tasks_with_pending_upload_.empty())
300 ScheduleCheckForCompletedRasterTasks(); 340 ScheduleCheckForCompletedRasterTasks();
341
342 NotifyClientIfFinishedRunningTasksRequiredForActivation();
343 NotifyClientIfFinishedRunningTasks();
301 } 344 }
302 345
303 void PixelBufferRasterWorkerPool::ScheduleMoreTasks() { 346 void PixelBufferRasterWorkerPool::ScheduleMoreTasks() {
304 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleMoreTasks"); 347 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleMoreTasks");
305 348
306 size_t bytes_pending_upload = bytes_pending_upload_; 349 size_t bytes_pending_upload = bytes_pending_upload_;
307 size_t bytes_pending_raster = 0; 350 size_t bytes_pending_raster = 0;
308 351
309 RasterTaskGraph graph; 352 RasterTaskGraph graph;
310 for (RasterTaskVector::const_iterator it = raster_tasks().begin(); 353 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) 388 if (new_bytes_pending_raster > kMaxPendingRasterBytes)
346 break; 389 break;
347 390
348 // Update both |bytes_pending_raster| and |bytes_pending_upload| 391 // Update both |bytes_pending_raster| and |bytes_pending_upload|
349 // now that task has cleared all throttling limits. 392 // now that task has cleared all throttling limits.
350 bytes_pending_raster = new_bytes_pending_raster; 393 bytes_pending_raster = new_bytes_pending_raster;
351 bytes_pending_upload = new_bytes_pending_upload; 394 bytes_pending_upload = new_bytes_pending_upload;
352 395
353 // Use existing pixel buffer task if available. 396 // Use existing pixel buffer task if available.
354 if (pixel_buffer_task) { 397 if (pixel_buffer_task) {
355 graph.InsertRasterTask(pixel_buffer_task, task->dependencies()); 398 graph.InsertRasterTask(pixel_buffer_task,
399 task->dependencies(),
400 IsRasterTaskRequiredForActivation(task));
356 continue; 401 continue;
357 } 402 }
358 403
359 // Request a pixel buffer. This will reserve shared memory. 404 // Request a pixel buffer. This will reserve shared memory.
360 resource_provider()->AcquirePixelBuffer(task->resource()->id()); 405 resource_provider()->AcquirePixelBuffer(task->resource()->id());
361 406
362 // MapPixelBuffer() returns NULL if context was lost at the time 407 // MapPixelBuffer() returns NULL if context was lost at the time
363 // AcquirePixelBuffer() was called. For simplicity we still post 408 // AcquirePixelBuffer() was called. For simplicity we still post
364 // a raster task that is essentially a noop in these situations. 409 // a raster task that is essentially a noop in these situations.
365 uint8* buffer = resource_provider()->MapPixelBuffer( 410 uint8* buffer = resource_provider()->MapPixelBuffer(
366 task->resource()->id()); 411 task->resource()->id());
367 412
368 scoped_refptr<internal::WorkerPoolTask> new_pixel_buffer_task( 413 scoped_refptr<internal::WorkerPoolTask> new_pixel_buffer_task(
369 new PixelBufferWorkerPoolTaskImpl( 414 new PixelBufferWorkerPoolTaskImpl(
370 task, 415 task,
371 buffer, 416 buffer,
372 base::Bind(&PixelBufferRasterWorkerPool::OnRasterTaskCompleted, 417 base::Bind(&PixelBufferRasterWorkerPool::OnRasterTaskCompleted,
373 base::Unretained(this), 418 base::Unretained(this),
374 make_scoped_refptr(task)))); 419 make_scoped_refptr(task))));
375 pixel_buffer_tasks_[task] = new_pixel_buffer_task; 420 pixel_buffer_tasks_[task] = new_pixel_buffer_task;
376 graph.InsertRasterTask(new_pixel_buffer_task.get(), task->dependencies()); 421 graph.InsertRasterTask(new_pixel_buffer_task.get(),
422 task->dependencies(),
423 IsRasterTaskRequiredForActivation(task));
377 } 424 }
378 425
379 SetRasterTaskGraph(&graph); 426 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 } 427 }
387 428
388 void PixelBufferRasterWorkerPool::OnRasterTaskCompleted( 429 void PixelBufferRasterWorkerPool::OnRasterTaskCompleted(
389 scoped_refptr<internal::RasterWorkerPoolTask> task, 430 scoped_refptr<internal::RasterWorkerPoolTask> task,
390 bool was_canceled, 431 bool was_canceled,
391 bool needs_upload) { 432 bool needs_upload) {
392 TRACE_EVENT2("cc", "PixelBufferRasterWorkerPool::OnRasterTaskCompleted", 433 TRACE_EVENT2("cc", "PixelBufferRasterWorkerPool::OnRasterTaskCompleted",
393 "was_canceled", was_canceled, 434 "was_canceled", was_canceled,
394 "needs_upload", needs_upload); 435 "needs_upload", needs_upload);
395 436
396 DCHECK(pixel_buffer_tasks_.find(task.get()) != pixel_buffer_tasks_.end()); 437 DCHECK(pixel_buffer_tasks_.find(task.get()) != pixel_buffer_tasks_.end());
397 438
398 // Balanced with MapPixelBuffer() call in ScheduleMoreTasks(). 439 // Balanced with MapPixelBuffer() call in ScheduleMoreTasks().
399 resource_provider()->UnmapPixelBuffer(task->resource()->id()); 440 resource_provider()->UnmapPixelBuffer(task->resource()->id());
400 441
401 if (!needs_upload) { 442 if (!needs_upload) {
402 resource_provider()->ReleasePixelBuffer(task->resource()->id()); 443 resource_provider()->ReleasePixelBuffer(task->resource()->id());
403 task->DidRun(was_canceled); 444 task->DidRun(was_canceled);
404 DCHECK(std::find(completed_tasks_.begin(), 445 DCHECK(std::find(completed_tasks_.begin(),
405 completed_tasks_.end(), 446 completed_tasks_.end(),
406 task) == completed_tasks_.end()); 447 task) == completed_tasks_.end());
407 completed_tasks_.push_back(task); 448 completed_tasks_.push_back(task);
449 tasks_required_for_activation_.erase(task);
408 return; 450 return;
409 } 451 }
410 452
411 resource_provider()->BeginSetPixels(task->resource()->id()); 453 resource_provider()->BeginSetPixels(task->resource()->id());
412 has_performed_uploads_since_last_flush_ = true; 454 has_performed_uploads_since_last_flush_ = true;
413 455
414 bytes_pending_upload_ += task->resource()->bytes(); 456 bytes_pending_upload_ += task->resource()->bytes();
415 tasks_with_pending_upload_.push_back(task); 457 tasks_with_pending_upload_.push_back(task);
416 } 458 }
417 459
460 unsigned PixelBufferRasterWorkerPool::PendingRasterTaskCount() const {
461 unsigned num_completed_raster_tasks =
462 tasks_with_pending_upload_.size() + completed_tasks_.size();
463 DCHECK_GE(pixel_buffer_tasks_.size(), num_completed_raster_tasks);
464 return pixel_buffer_tasks_.size() - num_completed_raster_tasks;
465 }
466
467 void PixelBufferRasterWorkerPool::
468 NotifyClientIfFinishedRunningTasksRequiredForActivation() {
469 if (!finished_running_tasks_required_for_activation_pending_)
470 return;
471
472 if (!tasks_required_for_activation_.empty())
473 return;
474
475 client()->DidFinishedRunningTasksRequiredForActivation();
476 finished_running_tasks_required_for_activation_pending_ = false;
477 }
478
479 void PixelBufferRasterWorkerPool::NotifyClientIfFinishedRunningTasks() {
480 if (!finished_running_tasks_pending_)
481 return;
482
483 if (PendingRasterTaskCount())
484 return;
485
486 if (!tasks_with_pending_upload_.empty())
487 return;
488
489 client()->DidFinishedRunningTasks();
490 finished_running_tasks_pending_ = false;
491 }
492
418 } // namespace cc 493 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698