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

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: addressing comments 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 15 matching lines...) Expand all
94 104
95 int num_pending_tasks_; 105 int num_pending_tasks_;
96 106
97 DISALLOW_COPY_AND_ASSIGN(RasterThread); 107 DISALLOW_COPY_AND_ASSIGN(RasterThread);
98 }; 108 };
99 109
100 ManagedTileState::ManagedTileState() 110 ManagedTileState::ManagedTileState()
101 : can_use_gpu_memory(false), 111 : can_use_gpu_memory(false),
102 can_be_freed(true), 112 can_be_freed(true),
103 resource_is_being_initialized(false), 113 resource_is_being_initialized(false),
104 contents_swizzled(false) { 114 contents_swizzled(false),
115 need_to_gather_pixel_refs(true) {
105 } 116 }
106 117
107 ManagedTileState::~ManagedTileState() { 118 ManagedTileState::~ManagedTileState() {
108 DCHECK(!resource); 119 DCHECK(!resource);
109 DCHECK(!resource_is_being_initialized); 120 DCHECK(!resource_is_being_initialized);
110 } 121 }
111 122
112 TileManager::TileManager( 123 TileManager::TileManager(
113 TileManagerClient* client, 124 TileManagerClient* client,
114 ResourceProvider* resource_provider, 125 ResourceProvider* resource_provider,
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 tile->managed_state().bin = bin; 288 tile->managed_state().bin = bin;
278 } 289 }
279 290
280 // Sort by bin. 291 // Sort by bin.
281 std::sort(tiles_.begin(), tiles_.end(), BinComparator()); 292 std::sort(tiles_.begin(), tiles_.end(), BinComparator());
282 293
283 // Assign gpu memory and determine what tiles need to be rasterized. 294 // Assign gpu memory and determine what tiles need to be rasterized.
284 AssignGpuMemoryToTiles(); 295 AssignGpuMemoryToTiles();
285 296
286 // Finally, kick the rasterizer. 297 // Finally, kick the rasterizer.
287 DispatchMoreRasterTasks(); 298 DispatchMoreTasks();
288 } 299 }
289 300
290 void TileManager::CheckForCompletedSetPixels() { 301 void TileManager::CheckForCompletedSetPixels() {
291 check_for_completed_set_pixels_pending_ = false; 302 check_for_completed_set_pixels_pending_ = false;
292 303
293 while (!tiles_with_pending_set_pixels_.empty()) { 304 while (!tiles_with_pending_set_pixels_.empty()) {
294 Tile* tile = tiles_with_pending_set_pixels_.front(); 305 Tile* tile = tiles_with_pending_set_pixels_.front();
295 DCHECK(tile->managed_state().resource); 306 DCHECK(tile->managed_state().resource);
296 307
297 // Set pixel tasks complete in the order they are posted. 308 // Set pixel tasks complete in the order they are posted.
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 tiles_that_need_to_be_rasterized_.end()); 374 tiles_that_need_to_be_rasterized_.end());
364 } 375 }
365 376
366 void TileManager::FreeResourcesForTile(Tile* tile) { 377 void TileManager::FreeResourcesForTile(Tile* tile) {
367 ManagedTileState& managed_tile_state = tile->managed_state(); 378 ManagedTileState& managed_tile_state = tile->managed_state();
368 DCHECK(managed_tile_state.can_be_freed); 379 DCHECK(managed_tile_state.can_be_freed);
369 if (managed_tile_state.resource) 380 if (managed_tile_state.resource)
370 resource_pool_->ReleaseResource(managed_tile_state.resource.Pass()); 381 resource_pool_->ReleaseResource(managed_tile_state.resource.Pass());
371 } 382 }
372 383
373 void TileManager::DispatchMoreRasterTasks() { 384 RasterThread* TileManager::GetFreeRasterThread() {
385 RasterThread* thread = 0;
386 for (RasterThreadVector::iterator it = raster_threads_.begin();
387 it != raster_threads_.end(); ++it) {
388 if ((*it)->num_pending_tasks() == kNumPendingRasterTasksPerThread)
389 continue;
390 // Check if this is the best thread we've found so far.
391 if (!thread || (*it)->num_pending_tasks() < thread->num_pending_tasks())
392 thread = *it;
393 }
394 return thread;
395 }
396
397 void TileManager::DispatchMoreTasks() {
398 // Because tiles in the image decoding list have higher priorities, we
399 // need to process those tiles first before we start to handle the tiles
400 // in the need_to_be_rasterized queue.
401 std::list<Tile*>::iterator it = tiles_with_image_decoding_tasks_.begin();
402 while (it != tiles_with_image_decoding_tasks_.end()) {
403 DispatchImageDecodingTasksForTile(*it);
404 ManagedTileState& managed_state = (*it)->managed_state();
405 if (managed_state.pending_pixel_refs.empty()) {
406 RasterThread* thread = GetFreeRasterThread();
407 if (!thread)
408 return;
409 DispatchOneRasterTask(thread, *it);
410 tiles_with_image_decoding_tasks_.erase(it++);
411 } else {
412 ++it;
413 }
414 }
415
416 // Process all tiles in the need_to_be_rasterized queue. If a tile has
417 // image decoding tasks, put it to the back of the image decoding list.
374 while (!tiles_that_need_to_be_rasterized_.empty()) { 418 while (!tiles_that_need_to_be_rasterized_.empty()) {
375 RasterThread* thread = 0; 419 Tile* tile = tiles_that_need_to_be_rasterized_.back();
376 420 DispatchImageDecodingTasksForTile(tile);
377 for (RasterThreadVector::iterator it = raster_threads_.begin(); 421 ManagedTileState& managed_state = tile->managed_state();
378 it != raster_threads_.end(); ++it) { 422 if (!managed_state.pending_pixel_refs.empty())
379 if ((*it)->num_pending_tasks() == kNumPendingRasterTasksPerThread) 423 tiles_with_image_decoding_tasks_.push_back(tile);
380 continue; 424 else {
reveman 2012/12/11 05:07:18 nit: curly braces around both IF and ELSE required
qinmin 2012/12/11 05:36:20 Done.
381 // Check if this is the best thread we've found so far. 425 RasterThread* thread = GetFreeRasterThread();
382 if (!thread || (*it)->num_pending_tasks() < thread->num_pending_tasks()) 426 if (!thread)
383 thread = *it; 427 return;
428 DispatchOneRasterTask(thread, tile);
384 } 429 }
385
386 // Stop dispatching tasks when all threads are busy.
387 if (!thread)
388 return;
389
390 DispatchOneRasterTask(thread, tiles_that_need_to_be_rasterized_.back());
391 tiles_that_need_to_be_rasterized_.pop_back(); 430 tiles_that_need_to_be_rasterized_.pop_back();
392 } 431 }
393 } 432 }
394 433
434 void TileManager::DispatchImageDecodingTasksForTile(Tile* tile) {
435 ManagedTileState& managed_state = tile->managed_state();
436 if (!managed_state.need_to_gather_pixel_refs) {
437 const_cast<PicturePileImpl *>(tile->picture_pile())->GatherPixelRefs(
438 tile->content_rect_, managed_state.pending_pixel_refs);
439 managed_state.need_to_gather_pixel_refs = false;
440 }
441
442 RasterThread* thread = 0;
reveman 2012/12/11 05:07:18 nit: |thread| is not needed in this scope. please
qinmin 2012/12/11 05:36:20 Done.
443 std::list<skia::LazyPixelRef*>& pending_pixel_refs =
444 tile->managed_state().pending_pixel_refs;
445 std::list<skia::LazyPixelRef*>::iterator it = pending_pixel_refs.begin();
446 while (it != pending_pixel_refs.end()) {
447 if (pending_decode_tasks_.end() != pending_decode_tasks_.find(
448 (*it)->getGenerationID())) {
449 ++it;
450 continue;
451 }
452 if ((*it)->PrepareToDecode(skia::LazyPixelRef::PrepareParams()))
453 pending_pixel_refs.erase(it++);
454 else {
reveman 2012/12/11 05:07:18 nit: curly braces around both IF and ELSE required
qinmin 2012/12/11 05:36:20 Done.
455 thread = GetFreeRasterThread();
456 if (thread)
457 DispatchOneImageDecodingTask(thread, tile, *it);
458 ++it;
459 }
460 }
461 }
462
463 void TileManager::DispatchOneImageDecodingTask(RasterThread* thread,
464 scoped_refptr<Tile> tile,
465 skia::LazyPixelRef* pixel_ref) {
466 TRACE_EVENT0("cc", "TileManager::DispatchOneImageDecodingTask");
467 uint32_t pixel_ref_id = pixel_ref->getGenerationID();
468 DCHECK(pending_decode_tasks_.end() ==
469 pending_decode_tasks_.find(pixel_ref_id));
470 pending_decode_tasks_[pixel_ref_id] = pixel_ref;
471
472 thread->PostImageDecodingTaskAndReply(
473 FROM_HERE,
474 pixel_ref,
475 base::Bind(&TileManager::OnImageDecodingTaskCompleted,
476 base::Unretained(this),
477 tile,
478 pixel_ref_id));
479 }
480
481 void TileManager::OnImageDecodingTaskCompleted(scoped_refptr<Tile> tile,
482 uint32_t pixel_ref_id) {
483 TRACE_EVENT0("cc", "TileManager::OnImageDecoded");
484 pending_decode_tasks_.erase(pixel_ref_id);
485
486 for (TileList::iterator it = tiles_with_image_decoding_tasks_.begin();
487 it != tiles_with_image_decoding_tasks_.end(); ++it) {
488 std::list<skia::LazyPixelRef*>& pixel_refs =
489 (*it)->managed_state().pending_pixel_refs;
490 for (std::list<skia::LazyPixelRef*>::iterator pixel_it =
491 pixel_refs.begin(); pixel_it != pixel_refs.end(); ++pixel_it) {
492 if (pixel_ref_id == (*pixel_it)->getGenerationID()) {
493 pixel_refs.erase(pixel_it);
494 break;
495 }
496 }
497 }
498 DispatchMoreTasks();
499 }
500
395 void TileManager::DispatchOneRasterTask( 501 void TileManager::DispatchOneRasterTask(
396 RasterThread* thread, scoped_refptr<Tile> tile) { 502 RasterThread* thread, scoped_refptr<Tile> tile) {
397 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask"); 503 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask");
398 ManagedTileState& managed_tile_state = tile->managed_state(); 504 ManagedTileState& managed_tile_state = tile->managed_state();
399 DCHECK(managed_tile_state.can_use_gpu_memory); 505 DCHECK(managed_tile_state.can_use_gpu_memory);
400 scoped_ptr<ResourcePool::Resource> resource = 506 scoped_ptr<ResourcePool::Resource> resource =
401 resource_pool_->AcquireResource(tile->tile_size_.size(), tile->format_); 507 resource_pool_->AcquireResource(tile->tile_size_.size(), tile->format_);
402 resource_pool_->resource_provider()->acquirePixelBuffer(resource->id()); 508 resource_pool_->resource_provider()->acquirePixelBuffer(resource->id());
403 509
404 managed_tile_state.resource_is_being_initialized = true; 510 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()); 545 resource_pool_->resource_provider()->unmapPixelBuffer(resource->id());
440 546
441 ManagedTileState& managed_tile_state = tile->managed_state(); 547 ManagedTileState& managed_tile_state = tile->managed_state();
442 managed_tile_state.can_be_freed = true; 548 managed_tile_state.can_be_freed = true;
443 549
444 // Tile can be freed after the completion of the raster task. Call 550 // Tile can be freed after the completion of the raster task. Call
445 // AssignGpuMemoryToTiles() to re-assign gpu memory to highest priority 551 // AssignGpuMemoryToTiles() to re-assign gpu memory to highest priority
446 // tiles. The result of this could be that this tile is no longer 552 // 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 553 // allowed to use gpu memory and in that case we need to abort
448 // initialization and free all associated resources before calling 554 // initialization and free all associated resources before calling
449 // DispatchMoreRasterTasks(). 555 // DispatchMoreTasks().
450 AssignGpuMemoryToTiles(); 556 AssignGpuMemoryToTiles();
451 557
452 // Finish resource initialization if |can_use_gpu_memory| is true. 558 // Finish resource initialization if |can_use_gpu_memory| is true.
453 if (managed_tile_state.can_use_gpu_memory) { 559 if (managed_tile_state.can_use_gpu_memory) {
454 // The component order may be bgra if we're uploading bgra pixels to rgba 560 // 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 561 // texture. Mark contents as swizzled if image component order is
456 // different than texture format. 562 // different than texture format.
457 managed_tile_state.contents_swizzled = 563 managed_tile_state.contents_swizzled =
458 !PlatformColor::sameComponentOrder(tile->format_); 564 !PlatformColor::sameComponentOrder(tile->format_);
459 565
460 // Tile resources can't be freed until upload has completed. 566 // Tile resources can't be freed until upload has completed.
461 managed_tile_state.can_be_freed = false; 567 managed_tile_state.can_be_freed = false;
462 568
463 resource_pool_->resource_provider()->beginSetPixels(resource->id()); 569 resource_pool_->resource_provider()->beginSetPixels(resource->id());
464 managed_tile_state.resource = resource.Pass(); 570 managed_tile_state.resource = resource.Pass();
465 tiles_with_pending_set_pixels_.push(tile); 571 tiles_with_pending_set_pixels_.push(tile);
466 572
467 ScheduleCheckForCompletedSetPixels(); 573 ScheduleCheckForCompletedSetPixels();
468 } else { 574 } else {
469 resource_pool_->resource_provider()->releasePixelBuffer(resource->id()); 575 resource_pool_->resource_provider()->releasePixelBuffer(resource->id());
470 resource_pool_->ReleaseResource(resource.Pass()); 576 resource_pool_->ReleaseResource(resource.Pass());
471 managed_tile_state.resource_is_being_initialized = false; 577 managed_tile_state.resource_is_being_initialized = false;
472 } 578 }
473 579 DispatchMoreTasks();
474 DispatchMoreRasterTasks();
475 } 580 }
476 581
477 void TileManager::DidFinishTileInitialization(Tile* tile) { 582 void TileManager::DidFinishTileInitialization(Tile* tile) {
478 ManagedTileState& managed_tile_state = tile->managed_state(); 583 ManagedTileState& managed_tile_state = tile->managed_state();
479 DCHECK(managed_tile_state.resource); 584 DCHECK(managed_tile_state.resource);
480 managed_tile_state.resource_is_being_initialized = false; 585 managed_tile_state.resource_is_being_initialized = false;
481 managed_tile_state.can_be_freed = true; 586 managed_tile_state.can_be_freed = true;
482 } 587 }
483 588
484 } 589 }
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