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/tile_manager.cc

Issue 11453014: Implement the logic to kick off image decoding jobs for TileManager (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: moving pending_pixel_refs to the persistent section Created 8 years 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 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/tile_manager.h" 5 #include "cc/tile_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 from_here, 59 from_here,
60 base::Bind(&RunRasterTask, 60 base::Bind(&RunRasterTask,
61 base::Unretained(picture_pile), 61 base::Unretained(picture_pile),
62 mapped_buffer, 62 mapped_buffer,
63 rect, 63 rect,
64 contents_scale, 64 contents_scale,
65 stats), 65 stats),
66 base::Bind(&RasterThread::RunReply, base::Unretained(this), reply)); 66 base::Bind(&RasterThread::RunReply, base::Unretained(this), reply));
67 } 67 }
68 68
69 void PostImageDecodingTaskAndReply(const tracked_objects::Location& from_here,
70 skia::LazyPixelRef* pixel_ref,
71 const base::Closure& reply) {
72 ++num_pending_tasks_;
73 message_loop_proxy()->PostTaskAndReply(
74 from_here,
75 base::Bind(&skia::LazyPixelRef::Decode, base::Unretained(pixel_ref)),
76 base::Bind(&RasterThread::RunReply, base::Unretained(this), reply));
77 }
78
69 private: 79 private:
70 static void RunRasterTask(PicturePileImpl* picture_pile, 80 static void RunRasterTask(PicturePileImpl* picture_pile,
71 uint8_t* mapped_buffer, 81 uint8_t* mapped_buffer,
72 const gfx::Rect& rect, 82 const gfx::Rect& rect,
73 float contents_scale, 83 float contents_scale,
74 RenderingStats* stats) { 84 RenderingStats* stats) {
75 TRACE_EVENT0("cc", "RasterThread::RunRasterTask"); 85 TRACE_EVENT0("cc", "RasterThread::RunRasterTask");
76 DCHECK(picture_pile); 86 DCHECK(picture_pile);
77 DCHECK(mapped_buffer); 87 DCHECK(mapped_buffer);
78 SkBitmap bitmap; 88 SkBitmap bitmap;
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 mts.bin = NOW_BIN; 249 mts.bin = NOW_BIN;
240 continue; 250 continue;
241 } 251 }
242 252
243 if (prio.time_to_needed_in_seconds() < prepainting_window_time_seconds) { 253 if (prio.time_to_needed_in_seconds() < prepainting_window_time_seconds) {
244 mts.bin = SOON_BIN; 254 mts.bin = SOON_BIN;
245 continue; 255 continue;
246 } 256 }
247 257
248 mts.bin = EVENTUALLY_BIN; 258 mts.bin = EVENTUALLY_BIN;
259
260 // Update all the SkPixelRefs this tile intersects.
261 mts.pending_pixel_refs.clear();
262 mts.has_image_decoding_info = false;
reveman 2012/12/11 01:35:42 Why do you clear this here? Shouldn't we just init
qinmin 2012/12/11 04:30:15 moved it to the ctor On 2012/12/11 01:35:42, David
249 } 263 }
250 264
251 // Memory limit policy works by mapping some bin states to the NEVER bin. 265 // Memory limit policy works by mapping some bin states to the NEVER bin.
252 TileManagerBin bin_map[NUM_BINS]; 266 TileManagerBin bin_map[NUM_BINS];
253 if (global_state_.memory_limit_policy == ALLOW_NOTHING) { 267 if (global_state_.memory_limit_policy == ALLOW_NOTHING) {
254 bin_map[NOW_BIN] = NEVER_BIN; 268 bin_map[NOW_BIN] = NEVER_BIN;
255 bin_map[SOON_BIN] = NEVER_BIN; 269 bin_map[SOON_BIN] = NEVER_BIN;
256 bin_map[EVENTUALLY_BIN] = NEVER_BIN; 270 bin_map[EVENTUALLY_BIN] = NEVER_BIN;
257 bin_map[NEVER_BIN] = NEVER_BIN; 271 bin_map[NEVER_BIN] = NEVER_BIN;
258 } else if (global_state_.memory_limit_policy == ALLOW_ABSOLUTE_MINIMUM) { 272 } else if (global_state_.memory_limit_policy == ALLOW_ABSOLUTE_MINIMUM) {
(...skipping 18 matching lines...) Expand all
277 tile->managed_state().bin = bin; 291 tile->managed_state().bin = bin;
278 } 292 }
279 293
280 // Sort by bin. 294 // Sort by bin.
281 std::sort(tiles_.begin(), tiles_.end(), BinComparator()); 295 std::sort(tiles_.begin(), tiles_.end(), BinComparator());
282 296
283 // Assign gpu memory and determine what tiles need to be rasterized. 297 // Assign gpu memory and determine what tiles need to be rasterized.
284 AssignGpuMemoryToTiles(); 298 AssignGpuMemoryToTiles();
285 299
286 // Finally, kick the rasterizer. 300 // Finally, kick the rasterizer.
287 DispatchMoreRasterTasks(); 301 DispatchMoreTasks();
288 } 302 }
289 303
290 void TileManager::CheckForCompletedSetPixels() { 304 void TileManager::CheckForCompletedSetPixels() {
291 check_for_completed_set_pixels_pending_ = false; 305 check_for_completed_set_pixels_pending_ = false;
292 306
293 while (!tiles_with_pending_set_pixels_.empty()) { 307 while (!tiles_with_pending_set_pixels_.empty()) {
294 Tile* tile = tiles_with_pending_set_pixels_.front(); 308 Tile* tile = tiles_with_pending_set_pixels_.front();
295 DCHECK(tile->managed_state().resource); 309 DCHECK(tile->managed_state().resource);
296 310
297 // Set pixel tasks complete in the order they are posted. 311 // Set pixel tasks complete in the order they are posted.
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 tiles_that_need_to_be_rasterized_.push_back(tile); 370 tiles_that_need_to_be_rasterized_.push_back(tile);
357 } 371 }
358 372
359 // Reverse two tiles_that_need_* vectors such that pop_back gets 373 // Reverse two tiles_that_need_* vectors such that pop_back gets
360 // the highest priority tile. 374 // the highest priority tile.
361 std::reverse( 375 std::reverse(
362 tiles_that_need_to_be_rasterized_.begin(), 376 tiles_that_need_to_be_rasterized_.begin(),
363 tiles_that_need_to_be_rasterized_.end()); 377 tiles_that_need_to_be_rasterized_.end());
364 } 378 }
365 379
380 void TileManager::GetImageInformationForTile(Tile* tile) {
reveman 2012/12/11 01:35:42 I don't think having this in a separate function i
qinmin 2012/12/11 04:30:15 Done.
381 ManagedTileState& managed_state = tile->managed_state();
382 if (!managed_state.has_image_decoding_info) {
383 const_cast<PicturePileImpl *>(tile->picture_pile())->GatherPixelRefs(
384 tile->content_rect_, managed_state.pending_pixel_refs);
385 managed_state.has_image_decoding_info = true;
386 }
387 }
388
366 void TileManager::FreeResourcesForTile(Tile* tile) { 389 void TileManager::FreeResourcesForTile(Tile* tile) {
367 ManagedTileState& managed_tile_state = tile->managed_state(); 390 ManagedTileState& managed_tile_state = tile->managed_state();
368 DCHECK(managed_tile_state.can_be_freed); 391 DCHECK(managed_tile_state.can_be_freed);
369 if (managed_tile_state.resource) 392 if (managed_tile_state.resource)
370 resource_pool_->ReleaseResource(managed_tile_state.resource.Pass()); 393 resource_pool_->ReleaseResource(managed_tile_state.resource.Pass());
371 } 394 }
372 395
373 void TileManager::DispatchMoreRasterTasks() { 396 RasterThread* TileManager::GetFreeRasterThread() {
397 RasterThread* thread = 0;
398 for (RasterThreadVector::iterator it = raster_threads_.begin();
399 it != raster_threads_.end(); ++it) {
400 if ((*it)->num_pending_tasks() == kNumPendingRasterTasksPerThread)
401 continue;
402 // Check if this is the best thread we've found so far.
403 if (!thread || (*it)->num_pending_tasks() < thread->num_pending_tasks())
404 thread = *it;
405 }
406 return thread;
407 }
408
409 void TileManager::DispatchMoreTasks() {
410 // Because tiles in the image decoding list have higher priorities, we
411 // need to process those tiles first before we start to handle the tiles
412 // in the need_to_be_rasterized queue.
413 for (TileList::iterator it = tiles_have_image_decoding_tasks_.begin();
414 it != tiles_have_image_decoding_tasks_.end(); ++it) {
415 if (!HasImageDecodingTasks(*it)) {
416 RasterThread* thread = GetFreeRasterThread();
417 if (!thread)
418 return;
419 DispatchOneRasterTask(thread, *it);
420 tiles_have_image_decoding_tasks_.erase(it);
reveman 2012/12/11 01:35:42 do you need a temporary "to be removed" list here?
qinmin 2012/12/11 04:30:15 Changed the code to erase(it++). On 2012/12/11 01
421 }
422 }
423
424 // Process all tiles in the need_to_be_rasterized queue. If a tile has
425 // image decoding tasks, put it to the back of the image decoding list.
374 while (!tiles_that_need_to_be_rasterized_.empty()) { 426 while (!tiles_that_need_to_be_rasterized_.empty()) {
375 RasterThread* thread = 0; 427 RasterThread* thread = GetFreeRasterThread();
376
377 for (RasterThreadVector::iterator it = raster_threads_.begin();
378 it != raster_threads_.end(); ++it) {
379 if ((*it)->num_pending_tasks() == kNumPendingRasterTasksPerThread)
380 continue;
381 // Check if this is the best thread we've found so far.
382 if (!thread || (*it)->num_pending_tasks() < thread->num_pending_tasks())
383 thread = *it;
384 }
385
386 // Stop dispatching tasks when all threads are busy.
387 if (!thread) 428 if (!thread)
388 return; 429 return;
389 430
390 DispatchOneRasterTask(thread, tiles_that_need_to_be_rasterized_.back()); 431 Tile* tile = tiles_that_need_to_be_rasterized_.back();
432 if (HasImageDecodingTasks(tile))
433 tiles_have_image_decoding_tasks_.push_back(tile);
434 else
435 DispatchOneRasterTask(thread, tile);
reveman 2012/12/11 01:35:42 hm, thread might not be the correct thread to disp
qinmin 2012/12/11 04:30:15 You are right, somehow i missed that when rewritin
391 tiles_that_need_to_be_rasterized_.pop_back(); 436 tiles_that_need_to_be_rasterized_.pop_back();
392 } 437 }
393 } 438 }
394 439
440 bool TileManager::HasImageDecodingTasks(Tile* tile) {
reveman 2012/12/11 01:35:42 Can you change this to something like: void Dispat
qinmin 2012/12/11 04:30:15 Done. On 2012/12/11 01:35:42, David Reveman wrote
441 if (!tile->managed_state().has_image_decoding_info)
442 GetImageInformationForTile(tile);
443
444 RasterThread* thread = 0;
445 std::list<skia::LazyPixelRef*>& pending_pixel_refs =
446 tile->managed_state().pending_pixel_refs;
447 for (std::list<skia::LazyPixelRef*>::iterator it = pending_pixel_refs.begin();
448 it != pending_pixel_refs.end(); ++it) {
449 if (pending_decode_tasks_.end() != pending_decode_tasks_.find(
450 (*it)->getGenerationID()))
451 continue;
452 if ((*it)->PrepareToDecode(skia::LazyPixelRef::PrepareParams())) {
453 pending_pixel_refs.erase(it);
454 } else {
455 thread = GetFreeRasterThread();
456 if (thread)
457 DispatchOneImageDecodingTask(thread, tile, *it);
458 }
459 }
460
461 return !pending_pixel_refs.empty();
462 }
463
464 void TileManager::DispatchOneImageDecodingTask(RasterThread* thread,
465 scoped_refptr<Tile> tile,
466 skia::LazyPixelRef* pixel_ref) {
467 TRACE_EVENT0("cc", "TileManager::DispatchOneImageDecodingTask");
468 uint32_t pixel_ref_id = pixel_ref->getGenerationID();
469 DCHECK(pending_decode_tasks_.end() ==
470 pending_decode_tasks_.find(pixel_ref_id));
471 pending_decode_tasks_[pixel_ref_id] = pixel_ref;
472
473 thread->PostImageDecodingTaskAndReply(
474 FROM_HERE,
475 pixel_ref,
476 base::Bind(&TileManager::OnImageDecodingTaskCompleted,
477 base::Unretained(this),
478 tile,
479 pixel_ref_id));
480 }
481
482 void TileManager::OnImageDecodingTaskCompleted(scoped_refptr<Tile> tile,
483 uint32_t pixel_ref_id) {
484 TRACE_EVENT0("cc", "TileManager::OnImageDecoded");
485 pending_decode_tasks_.erase(pixel_ref_id);
486
487 for (TileList::iterator it = tiles_have_image_decoding_tasks_.begin();
488 it != tiles_have_image_decoding_tasks_.end(); ++it) {
489 std::list<skia::LazyPixelRef*>& pixel_refs =
490 (*it)->managed_state().pending_pixel_refs;
491 for (std::list<skia::LazyPixelRef*>::iterator pixel_it =
492 pixel_refs.begin(); pixel_it != pixel_refs.end(); ++pixel_it) {
493 if (pixel_ref_id == (*pixel_it)->getGenerationID()) {
494 pixel_refs.erase(pixel_it);
495 break;
496 }
497 }
498 }
499
500 DispatchMoreTasks();
501 }
502
395 void TileManager::DispatchOneRasterTask( 503 void TileManager::DispatchOneRasterTask(
396 RasterThread* thread, scoped_refptr<Tile> tile) { 504 RasterThread* thread, scoped_refptr<Tile> tile) {
397 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask"); 505 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask");
398 ManagedTileState& managed_tile_state = tile->managed_state(); 506 ManagedTileState& managed_tile_state = tile->managed_state();
399 DCHECK(managed_tile_state.can_use_gpu_memory); 507 DCHECK(managed_tile_state.can_use_gpu_memory);
400 scoped_ptr<ResourcePool::Resource> resource = 508 scoped_ptr<ResourcePool::Resource> resource =
401 resource_pool_->AcquireResource(tile->tile_size_.size(), tile->format_); 509 resource_pool_->AcquireResource(tile->tile_size_.size(), tile->format_);
402 resource_pool_->resource_provider()->acquirePixelBuffer(resource->id()); 510 resource_pool_->resource_provider()->acquirePixelBuffer(resource->id());
403 511
404 managed_tile_state.resource_is_being_initialized = true; 512 managed_tile_state.resource_is_being_initialized = true;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 resource_pool_->resource_provider()->unmapPixelBuffer(resource->id()); 547 resource_pool_->resource_provider()->unmapPixelBuffer(resource->id());
440 548
441 ManagedTileState& managed_tile_state = tile->managed_state(); 549 ManagedTileState& managed_tile_state = tile->managed_state();
442 managed_tile_state.can_be_freed = true; 550 managed_tile_state.can_be_freed = true;
443 551
444 // Tile can be freed after the completion of the raster task. Call 552 // Tile can be freed after the completion of the raster task. Call
445 // AssignGpuMemoryToTiles() to re-assign gpu memory to highest priority 553 // AssignGpuMemoryToTiles() to re-assign gpu memory to highest priority
446 // tiles. The result of this could be that this tile is no longer 554 // tiles. The result of this could be that this tile is no longer
447 // allowed to use gpu memory and in that case we need to abort 555 // allowed to use gpu memory and in that case we need to abort
448 // initialization and free all associated resources before calling 556 // initialization and free all associated resources before calling
449 // DispatchMoreRasterTasks(). 557 // DispatchMoreTasks().
450 AssignGpuMemoryToTiles(); 558 AssignGpuMemoryToTiles();
451 559
452 // Finish resource initialization if |can_use_gpu_memory| is true. 560 // Finish resource initialization if |can_use_gpu_memory| is true.
453 if (managed_tile_state.can_use_gpu_memory) { 561 if (managed_tile_state.can_use_gpu_memory) {
454 // The component order may be bgra if we're uploading bgra pixels to rgba 562 // The component order may be bgra if we're uploading bgra pixels to rgba
455 // texture. Mark contents as swizzled if image component order is 563 // texture. Mark contents as swizzled if image component order is
456 // different than texture format. 564 // different than texture format.
457 managed_tile_state.contents_swizzled = 565 managed_tile_state.contents_swizzled =
458 !PlatformColor::sameComponentOrder(tile->format_); 566 !PlatformColor::sameComponentOrder(tile->format_);
459 567
460 // Tile resources can't be freed until upload has completed. 568 // Tile resources can't be freed until upload has completed.
461 managed_tile_state.can_be_freed = false; 569 managed_tile_state.can_be_freed = false;
462 570
463 resource_pool_->resource_provider()->beginSetPixels(resource->id()); 571 resource_pool_->resource_provider()->beginSetPixels(resource->id());
464 managed_tile_state.resource = resource.Pass(); 572 managed_tile_state.resource = resource.Pass();
465 tiles_with_pending_set_pixels_.push(tile); 573 tiles_with_pending_set_pixels_.push(tile);
466 574
467 ScheduleCheckForCompletedSetPixels(); 575 ScheduleCheckForCompletedSetPixels();
468 } else { 576 } else {
469 resource_pool_->resource_provider()->releasePixelBuffer(resource->id()); 577 resource_pool_->resource_provider()->releasePixelBuffer(resource->id());
470 resource_pool_->ReleaseResource(resource.Pass()); 578 resource_pool_->ReleaseResource(resource.Pass());
471 managed_tile_state.resource_is_being_initialized = false; 579 managed_tile_state.resource_is_being_initialized = false;
472 } 580 }
473 581
474 DispatchMoreRasterTasks(); 582 DispatchMoreTasks();
475 } 583 }
476 584
477 void TileManager::DidFinishTileInitialization(Tile* tile) { 585 void TileManager::DidFinishTileInitialization(Tile* tile) {
478 ManagedTileState& managed_tile_state = tile->managed_state(); 586 ManagedTileState& managed_tile_state = tile->managed_state();
479 DCHECK(managed_tile_state.resource); 587 DCHECK(managed_tile_state.resource);
480 managed_tile_state.resource_is_being_initialized = false; 588 managed_tile_state.resource_is_being_initialized = false;
481 managed_tile_state.can_be_freed = true; 589 managed_tile_state.can_be_freed = true;
482 } 590 }
483 591
484 } 592 }
OLDNEW
« cc/tile_manager.h ('K') | « cc/tile_manager.h ('k') | skia/skia.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698