Home | History | Annotate | Download | only in resources
      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
      3 // found in the LICENSE file.
      4 
      5 #include "cc/resources/tile_manager.h"
      6 
      7 #include <algorithm>
      8 #include <limits>
      9 #include <string>
     10 
     11 #include "base/bind.h"
     12 #include "base/debug/trace_event_argument.h"
     13 #include "base/json/json_writer.h"
     14 #include "base/logging.h"
     15 #include "base/metrics/histogram.h"
     16 #include "cc/debug/devtools_instrumentation.h"
     17 #include "cc/debug/frame_viewer_instrumentation.h"
     18 #include "cc/debug/traced_value.h"
     19 #include "cc/layers/picture_layer_impl.h"
     20 #include "cc/resources/raster_buffer.h"
     21 #include "cc/resources/rasterizer.h"
     22 #include "cc/resources/tile.h"
     23 #include "skia/ext/paint_simplifier.h"
     24 #include "third_party/skia/include/core/SkBitmap.h"
     25 #include "third_party/skia/include/core/SkPixelRef.h"
     26 #include "ui/gfx/rect_conversions.h"
     27 
     28 namespace cc {
     29 namespace {
     30 
     31 // Flag to indicate whether we should try and detect that
     32 // a tile is of solid color.
     33 const bool kUseColorEstimator = true;
     34 
     35 class RasterTaskImpl : public RasterTask {
     36  public:
     37   RasterTaskImpl(
     38       const Resource* resource,
     39       PicturePileImpl* picture_pile,
     40       const gfx::Rect& content_rect,
     41       float contents_scale,
     42       RasterMode raster_mode,
     43       TileResolution tile_resolution,
     44       int layer_id,
     45       const void* tile_id,
     46       int source_frame_number,
     47       bool analyze_picture,
     48       RenderingStatsInstrumentation* rendering_stats,
     49       const base::Callback<void(const PicturePileImpl::Analysis&, bool)>& reply,
     50       ImageDecodeTask::Vector* dependencies)
     51       : RasterTask(resource, dependencies),
     52         picture_pile_(picture_pile),
     53         content_rect_(content_rect),
     54         contents_scale_(contents_scale),
     55         raster_mode_(raster_mode),
     56         tile_resolution_(tile_resolution),
     57         layer_id_(layer_id),
     58         tile_id_(tile_id),
     59         source_frame_number_(source_frame_number),
     60         analyze_picture_(analyze_picture),
     61         rendering_stats_(rendering_stats),
     62         reply_(reply) {}
     63 
     64   // Overridden from Task:
     65   virtual void RunOnWorkerThread() OVERRIDE {
     66     TRACE_EVENT0("cc", "RasterizerTaskImpl::RunOnWorkerThread");
     67 
     68     DCHECK(picture_pile_.get());
     69     DCHECK(raster_buffer_);
     70 
     71     if (analyze_picture_) {
     72       Analyze(picture_pile_.get());
     73       if (analysis_.is_solid_color)
     74         return;
     75     }
     76 
     77     Raster(picture_pile_.get());
     78   }
     79 
     80   // Overridden from RasterizerTask:
     81   virtual void ScheduleOnOriginThread(RasterizerTaskClient* client) OVERRIDE {
     82     DCHECK(!raster_buffer_);
     83     raster_buffer_ = client->AcquireBufferForRaster(resource());
     84   }
     85   virtual void CompleteOnOriginThread(RasterizerTaskClient* client) OVERRIDE {
     86     client->ReleaseBufferForRaster(raster_buffer_.Pass());
     87   }
     88   virtual void RunReplyOnOriginThread() OVERRIDE {
     89     DCHECK(!raster_buffer_);
     90     reply_.Run(analysis_, !HasFinishedRunning());
     91   }
     92 
     93  protected:
     94   virtual ~RasterTaskImpl() { DCHECK(!raster_buffer_); }
     95 
     96  private:
     97   void Analyze(const PicturePileImpl* picture_pile) {
     98     frame_viewer_instrumentation::ScopedAnalyzeTask analyze_task(
     99         tile_id_, tile_resolution_, source_frame_number_, layer_id_);
    100 
    101     DCHECK(picture_pile);
    102 
    103     picture_pile->AnalyzeInRect(
    104         content_rect_, contents_scale_, &analysis_, rendering_stats_);
    105 
    106     // Record the solid color prediction.
    107     UMA_HISTOGRAM_BOOLEAN("Renderer4.SolidColorTilesAnalyzed",
    108                           analysis_.is_solid_color);
    109 
    110     // Clear the flag if we're not using the estimator.
    111     analysis_.is_solid_color &= kUseColorEstimator;
    112   }
    113 
    114   void Raster(const PicturePileImpl* picture_pile) {
    115     frame_viewer_instrumentation::ScopedRasterTask raster_task(
    116         tile_id_,
    117         tile_resolution_,
    118         source_frame_number_,
    119         layer_id_,
    120         raster_mode_);
    121     devtools_instrumentation::ScopedLayerTask layer_task(
    122         devtools_instrumentation::kRasterTask, layer_id_);
    123 
    124     skia::RefPtr<SkCanvas> canvas = raster_buffer_->AcquireSkCanvas();
    125     DCHECK(canvas);
    126 
    127     skia::RefPtr<SkDrawFilter> draw_filter;
    128     switch (raster_mode_) {
    129       case LOW_QUALITY_RASTER_MODE:
    130         draw_filter = skia::AdoptRef(new skia::PaintSimplifier);
    131         break;
    132       case HIGH_QUALITY_RASTER_MODE:
    133         break;
    134       case NUM_RASTER_MODES:
    135       default:
    136         NOTREACHED();
    137     }
    138     canvas->setDrawFilter(draw_filter.get());
    139 
    140     base::TimeDelta prev_rasterize_time =
    141         rendering_stats_->impl_thread_rendering_stats().rasterize_time;
    142 
    143     // Only record rasterization time for highres tiles, because
    144     // lowres tiles are not required for activation and therefore
    145     // introduce noise in the measurement (sometimes they get rasterized
    146     // before we draw and sometimes they aren't)
    147     RenderingStatsInstrumentation* stats =
    148         tile_resolution_ == HIGH_RESOLUTION ? rendering_stats_ : NULL;
    149     DCHECK(picture_pile);
    150     picture_pile->RasterToBitmap(
    151         canvas.get(), content_rect_, contents_scale_, stats);
    152 
    153     if (rendering_stats_->record_rendering_stats()) {
    154       base::TimeDelta current_rasterize_time =
    155           rendering_stats_->impl_thread_rendering_stats().rasterize_time;
    156       LOCAL_HISTOGRAM_CUSTOM_COUNTS(
    157           "Renderer4.PictureRasterTimeUS",
    158           (current_rasterize_time - prev_rasterize_time).InMicroseconds(),
    159           0,
    160           100000,
    161           100);
    162     }
    163 
    164     raster_buffer_->ReleaseSkCanvas(canvas);
    165   }
    166 
    167   PicturePileImpl::Analysis analysis_;
    168   scoped_refptr<PicturePileImpl> picture_pile_;
    169   gfx::Rect content_rect_;
    170   float contents_scale_;
    171   RasterMode raster_mode_;
    172   TileResolution tile_resolution_;
    173   int layer_id_;
    174   const void* tile_id_;
    175   int source_frame_number_;
    176   bool analyze_picture_;
    177   RenderingStatsInstrumentation* rendering_stats_;
    178   const base::Callback<void(const PicturePileImpl::Analysis&, bool)> reply_;
    179   scoped_ptr<RasterBuffer> raster_buffer_;
    180 
    181   DISALLOW_COPY_AND_ASSIGN(RasterTaskImpl);
    182 };
    183 
    184 class ImageDecodeTaskImpl : public ImageDecodeTask {
    185  public:
    186   ImageDecodeTaskImpl(SkPixelRef* pixel_ref,
    187                       int layer_id,
    188                       RenderingStatsInstrumentation* rendering_stats,
    189                       const base::Callback<void(bool was_canceled)>& reply)
    190       : pixel_ref_(skia::SharePtr(pixel_ref)),
    191         layer_id_(layer_id),
    192         rendering_stats_(rendering_stats),
    193         reply_(reply) {}
    194 
    195   // Overridden from Task:
    196   virtual void RunOnWorkerThread() OVERRIDE {
    197     TRACE_EVENT0("cc", "ImageDecodeTaskImpl::RunOnWorkerThread");
    198 
    199     devtools_instrumentation::ScopedImageDecodeTask image_decode_task(
    200         pixel_ref_.get());
    201     // This will cause the image referred to by pixel ref to be decoded.
    202     pixel_ref_->lockPixels();
    203     pixel_ref_->unlockPixels();
    204   }
    205 
    206   // Overridden from RasterizerTask:
    207   virtual void ScheduleOnOriginThread(RasterizerTaskClient* client) OVERRIDE {}
    208   virtual void CompleteOnOriginThread(RasterizerTaskClient* client) OVERRIDE {}
    209   virtual void RunReplyOnOriginThread() OVERRIDE {
    210     reply_.Run(!HasFinishedRunning());
    211   }
    212 
    213  protected:
    214   virtual ~ImageDecodeTaskImpl() {}
    215 
    216  private:
    217   skia::RefPtr<SkPixelRef> pixel_ref_;
    218   int layer_id_;
    219   RenderingStatsInstrumentation* rendering_stats_;
    220   const base::Callback<void(bool was_canceled)> reply_;
    221 
    222   DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl);
    223 };
    224 
    225 const size_t kScheduledRasterTasksLimit = 32u;
    226 
    227 // Memory limit policy works by mapping some bin states to the NEVER bin.
    228 const ManagedTileBin kBinPolicyMap[NUM_TILE_MEMORY_LIMIT_POLICIES][NUM_BINS] = {
    229     // [ALLOW_NOTHING]
    230     {NEVER_BIN,  // [NOW_AND_READY_TO_DRAW_BIN]
    231      NEVER_BIN,  // [NOW_BIN]
    232      NEVER_BIN,  // [SOON_BIN]
    233      NEVER_BIN,  // [EVENTUALLY_AND_ACTIVE_BIN]
    234      NEVER_BIN,  // [EVENTUALLY_BIN]
    235      NEVER_BIN,  // [AT_LAST_AND_ACTIVE_BIN]
    236      NEVER_BIN,  // [AT_LAST_BIN]
    237      NEVER_BIN   // [NEVER_BIN]
    238     },
    239     // [ALLOW_ABSOLUTE_MINIMUM]
    240     {NOW_AND_READY_TO_DRAW_BIN,  // [NOW_AND_READY_TO_DRAW_BIN]
    241      NOW_BIN,                    // [NOW_BIN]
    242      NEVER_BIN,                  // [SOON_BIN]
    243      NEVER_BIN,                  // [EVENTUALLY_AND_ACTIVE_BIN]
    244      NEVER_BIN,                  // [EVENTUALLY_BIN]
    245      NEVER_BIN,                  // [AT_LAST_AND_ACTIVE_BIN]
    246      NEVER_BIN,                  // [AT_LAST_BIN]
    247      NEVER_BIN                   // [NEVER_BIN]
    248     },
    249     // [ALLOW_PREPAINT_ONLY]
    250     {NOW_AND_READY_TO_DRAW_BIN,  // [NOW_AND_READY_TO_DRAW_BIN]
    251      NOW_BIN,                    // [NOW_BIN]
    252      SOON_BIN,                   // [SOON_BIN]
    253      NEVER_BIN,                  // [EVENTUALLY_AND_ACTIVE_BIN]
    254      NEVER_BIN,                  // [EVENTUALLY_BIN]
    255      NEVER_BIN,                  // [AT_LAST_AND_ACTIVE_BIN]
    256      NEVER_BIN,                  // [AT_LAST_BIN]
    257      NEVER_BIN                   // [NEVER_BIN]
    258     },
    259     // [ALLOW_ANYTHING]
    260     {NOW_AND_READY_TO_DRAW_BIN,  // [NOW_AND_READY_TO_DRAW_BIN]
    261      NOW_BIN,                    // [NOW_BIN]
    262      SOON_BIN,                   // [SOON_BIN]
    263      EVENTUALLY_AND_ACTIVE_BIN,  // [EVENTUALLY_AND_ACTIVE_BIN]
    264      EVENTUALLY_BIN,             // [EVENTUALLY_BIN]
    265      AT_LAST_AND_ACTIVE_BIN,     // [AT_LAST_AND_ACTIVE_BIN]
    266      AT_LAST_BIN,                // [AT_LAST_BIN]
    267      NEVER_BIN                   // [NEVER_BIN]
    268     }};
    269 
    270 // Ready to draw works by mapping NOW_BIN to NOW_AND_READY_TO_DRAW_BIN.
    271 const ManagedTileBin kBinReadyToDrawMap[2][NUM_BINS] = {
    272     // Not ready
    273     {NOW_AND_READY_TO_DRAW_BIN,  // [NOW_AND_READY_TO_DRAW_BIN]
    274      NOW_BIN,                    // [NOW_BIN]
    275      SOON_BIN,                   // [SOON_BIN]
    276      EVENTUALLY_AND_ACTIVE_BIN,  // [EVENTUALLY_AND_ACTIVE_BIN]
    277      EVENTUALLY_BIN,             // [EVENTUALLY_BIN]
    278      AT_LAST_AND_ACTIVE_BIN,     // [AT_LAST_AND_ACTIVE_BIN]
    279      AT_LAST_BIN,                // [AT_LAST_BIN]
    280      NEVER_BIN                   // [NEVER_BIN]
    281     },
    282     // Ready
    283     {NOW_AND_READY_TO_DRAW_BIN,  // [NOW_AND_READY_TO_DRAW_BIN]
    284      NOW_AND_READY_TO_DRAW_BIN,  // [NOW_BIN]
    285      SOON_BIN,                   // [SOON_BIN]
    286      EVENTUALLY_AND_ACTIVE_BIN,  // [EVENTUALLY_AND_ACTIVE_BIN]
    287      EVENTUALLY_BIN,             // [EVENTUALLY_BIN]
    288      AT_LAST_AND_ACTIVE_BIN,     // [AT_LAST_AND_ACTIVE_BIN]
    289      AT_LAST_BIN,                // [AT_LAST_BIN]
    290      NEVER_BIN                   // [NEVER_BIN]
    291     }};
    292 
    293 // Active works by mapping some bin stats to equivalent _ACTIVE_BIN state.
    294 const ManagedTileBin kBinIsActiveMap[2][NUM_BINS] = {
    295     // Inactive
    296     {NOW_AND_READY_TO_DRAW_BIN,  // [NOW_AND_READY_TO_DRAW_BIN]
    297      NOW_BIN,                    // [NOW_BIN]
    298      SOON_BIN,                   // [SOON_BIN]
    299      EVENTUALLY_AND_ACTIVE_BIN,  // [EVENTUALLY_AND_ACTIVE_BIN]
    300      EVENTUALLY_BIN,             // [EVENTUALLY_BIN]
    301      AT_LAST_AND_ACTIVE_BIN,     // [AT_LAST_AND_ACTIVE_BIN]
    302      AT_LAST_BIN,                // [AT_LAST_BIN]
    303      NEVER_BIN                   // [NEVER_BIN]
    304     },
    305     // Active
    306     {NOW_AND_READY_TO_DRAW_BIN,  // [NOW_AND_READY_TO_DRAW_BIN]
    307      NOW_BIN,                    // [NOW_BIN]
    308      SOON_BIN,                   // [SOON_BIN]
    309      EVENTUALLY_AND_ACTIVE_BIN,  // [EVENTUALLY_AND_ACTIVE_BIN]
    310      EVENTUALLY_AND_ACTIVE_BIN,  // [EVENTUALLY_BIN]
    311      AT_LAST_AND_ACTIVE_BIN,     // [AT_LAST_AND_ACTIVE_BIN]
    312      AT_LAST_AND_ACTIVE_BIN,     // [AT_LAST_BIN]
    313      NEVER_BIN                   // [NEVER_BIN]
    314     }};
    315 
    316 // Determine bin based on three categories of tiles: things we need now,
    317 // things we need soon, and eventually.
    318 inline ManagedTileBin BinFromTilePriority(const TilePriority& prio) {
    319   if (prio.priority_bin == TilePriority::NOW)
    320     return NOW_BIN;
    321 
    322   if (prio.priority_bin == TilePriority::SOON)
    323     return SOON_BIN;
    324 
    325   if (prio.distance_to_visible == std::numeric_limits<float>::infinity())
    326     return NEVER_BIN;
    327 
    328   return EVENTUALLY_BIN;
    329 }
    330 
    331 }  // namespace
    332 
    333 RasterTaskCompletionStats::RasterTaskCompletionStats()
    334     : completed_count(0u), canceled_count(0u) {}
    335 
    336 scoped_refptr<base::debug::ConvertableToTraceFormat>
    337 RasterTaskCompletionStatsAsValue(const RasterTaskCompletionStats& stats) {
    338   scoped_refptr<base::debug::TracedValue> state =
    339       new base::debug::TracedValue();
    340   state->SetInteger("completed_count", stats.completed_count);
    341   state->SetInteger("canceled_count", stats.canceled_count);
    342   return state;
    343 }
    344 
    345 // static
    346 scoped_ptr<TileManager> TileManager::Create(
    347     TileManagerClient* client,
    348     base::SequencedTaskRunner* task_runner,
    349     ResourcePool* resource_pool,
    350     Rasterizer* rasterizer,
    351     RenderingStatsInstrumentation* rendering_stats_instrumentation) {
    352   return make_scoped_ptr(new TileManager(client,
    353                                          task_runner,
    354                                          resource_pool,
    355                                          rasterizer,
    356                                          rendering_stats_instrumentation));
    357 }
    358 
    359 TileManager::TileManager(
    360     TileManagerClient* client,
    361     const scoped_refptr<base::SequencedTaskRunner>& task_runner,
    362     ResourcePool* resource_pool,
    363     Rasterizer* rasterizer,
    364     RenderingStatsInstrumentation* rendering_stats_instrumentation)
    365     : client_(client),
    366       task_runner_(task_runner),
    367       resource_pool_(resource_pool),
    368       rasterizer_(rasterizer),
    369       prioritized_tiles_dirty_(false),
    370       all_tiles_that_need_to_be_rasterized_have_memory_(true),
    371       all_tiles_required_for_activation_have_memory_(true),
    372       bytes_releasable_(0),
    373       resources_releasable_(0),
    374       ever_exceeded_memory_budget_(false),
    375       rendering_stats_instrumentation_(rendering_stats_instrumentation),
    376       did_initialize_visible_tile_(false),
    377       did_check_for_completed_tasks_since_last_schedule_tasks_(true),
    378       did_oom_on_last_assign_(false),
    379       ready_to_activate_check_notifier_(
    380           task_runner_.get(),
    381           base::Bind(&TileManager::CheckIfReadyToActivate,
    382                      base::Unretained(this))) {
    383   rasterizer_->SetClient(this);
    384 }
    385 
    386 TileManager::~TileManager() {
    387   // Reset global state and manage. This should cause
    388   // our memory usage to drop to zero.
    389   global_state_ = GlobalStateThatImpactsTilePriority();
    390 
    391   RasterTaskQueue empty;
    392   rasterizer_->ScheduleTasks(&empty);
    393   orphan_raster_tasks_.clear();
    394 
    395   // This should finish all pending tasks and release any uninitialized
    396   // resources.
    397   rasterizer_->Shutdown();
    398   rasterizer_->CheckForCompletedTasks();
    399 
    400   prioritized_tiles_.Clear();
    401 
    402   FreeResourcesForReleasedTiles();
    403   CleanUpReleasedTiles();
    404 
    405   DCHECK_EQ(0u, bytes_releasable_);
    406   DCHECK_EQ(0u, resources_releasable_);
    407 }
    408 
    409 void TileManager::Release(Tile* tile) {
    410   DCHECK(TilePriority() == tile->combined_priority());
    411 
    412   prioritized_tiles_dirty_ = true;
    413   released_tiles_.push_back(tile);
    414 }
    415 
    416 void TileManager::DidChangeTilePriority(Tile* tile) {
    417   prioritized_tiles_dirty_ = true;
    418 }
    419 
    420 TaskSetCollection TileManager::TasksThatShouldBeForcedToComplete() const {
    421   TaskSetCollection tasks_that_should_be_forced_to_complete;
    422   if (global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY)
    423     tasks_that_should_be_forced_to_complete[REQUIRED_FOR_ACTIVATION] = true;
    424   return tasks_that_should_be_forced_to_complete;
    425 }
    426 
    427 void TileManager::FreeResourcesForReleasedTiles() {
    428   for (std::vector<Tile*>::iterator it = released_tiles_.begin();
    429        it != released_tiles_.end();
    430        ++it) {
    431     Tile* tile = *it;
    432     FreeResourcesForTile(tile);
    433   }
    434 }
    435 
    436 void TileManager::CleanUpReleasedTiles() {
    437   // Make sure |prioritized_tiles_| doesn't contain any of the tiles
    438   // we're about to delete.
    439   DCHECK(prioritized_tiles_.IsEmpty());
    440 
    441   std::vector<Tile*>::iterator it = released_tiles_.begin();
    442   while (it != released_tiles_.end()) {
    443     Tile* tile = *it;
    444 
    445     if (tile->HasRasterTask()) {
    446       ++it;
    447       continue;
    448     }
    449 
    450     DCHECK(!tile->HasResources());
    451     DCHECK(tiles_.find(tile->id()) != tiles_.end());
    452     tiles_.erase(tile->id());
    453 
    454     LayerCountMap::iterator layer_it =
    455         used_layer_counts_.find(tile->layer_id());
    456     DCHECK_GT(layer_it->second, 0);
    457     if (--layer_it->second == 0) {
    458       used_layer_counts_.erase(layer_it);
    459       image_decode_tasks_.erase(tile->layer_id());
    460     }
    461 
    462     delete tile;
    463     it = released_tiles_.erase(it);
    464   }
    465 }
    466 
    467 void TileManager::UpdatePrioritizedTileSetIfNeeded() {
    468   if (!prioritized_tiles_dirty_)
    469     return;
    470 
    471   prioritized_tiles_.Clear();
    472 
    473   FreeResourcesForReleasedTiles();
    474   CleanUpReleasedTiles();
    475 
    476   GetTilesWithAssignedBins(&prioritized_tiles_);
    477   prioritized_tiles_dirty_ = false;
    478 }
    479 
    480 void TileManager::DidFinishRunningTasks(TaskSet task_set) {
    481   if (task_set == ALL) {
    482     TRACE_EVENT1("cc", "TileManager::DidFinishRunningTasks", "task_set", "ALL");
    483 
    484     bool memory_usage_above_limit = resource_pool_->total_memory_usage_bytes() >
    485                                     global_state_.soft_memory_limit_in_bytes;
    486 
    487     // When OOM, keep re-assigning memory until we reach a steady state
    488     // where top-priority tiles are initialized.
    489     if (all_tiles_that_need_to_be_rasterized_have_memory_ &&
    490         !memory_usage_above_limit)
    491       return;
    492 
    493     rasterizer_->CheckForCompletedTasks();
    494     did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
    495 
    496     TileVector tiles_that_need_to_be_rasterized;
    497     AssignGpuMemoryToTiles(&prioritized_tiles_,
    498                            &tiles_that_need_to_be_rasterized);
    499 
    500     // |tiles_that_need_to_be_rasterized| will be empty when we reach a
    501     // steady memory state. Keep scheduling tasks until we reach this state.
    502     if (!tiles_that_need_to_be_rasterized.empty()) {
    503       ScheduleTasks(tiles_that_need_to_be_rasterized);
    504       return;
    505     }
    506 
    507     FreeResourcesForReleasedTiles();
    508 
    509     resource_pool_->ReduceResourceUsage();
    510 
    511     // We don't reserve memory for required-for-activation tiles during
    512     // accelerated gestures, so we just postpone activation when we don't
    513     // have these tiles, and activate after the accelerated gesture.
    514     // Likewise if we don't allow any tiles (as is the case when we're
    515     // invisible), if we have tiles that aren't ready, then we shouldn't
    516     // activate as activation can cause checkerboards.
    517     bool allow_rasterize_on_demand =
    518         global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY &&
    519         global_state_.memory_limit_policy != ALLOW_NOTHING;
    520 
    521     // Use on-demand raster for any required-for-activation tiles that have not
    522     // been been assigned memory after reaching a steady memory state. This
    523     // ensures that we activate even when OOM.
    524     for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
    525       Tile* tile = it->second;
    526       ManagedTileState& mts = tile->managed_state();
    527       ManagedTileState::TileVersion& tile_version =
    528           mts.tile_versions[mts.raster_mode];
    529 
    530       if (tile->required_for_activation() && !tile_version.IsReadyToDraw()) {
    531         // If we can't raster on demand, give up early (and don't activate).
    532         if (!allow_rasterize_on_demand)
    533           return;
    534 
    535         tile_version.set_rasterize_on_demand();
    536         client_->NotifyTileStateChanged(tile);
    537       }
    538     }
    539 
    540     DCHECK(IsReadyToActivate());
    541     ready_to_activate_check_notifier_.Schedule();
    542     return;
    543   }
    544 
    545   if (task_set == REQUIRED_FOR_ACTIVATION) {
    546     TRACE_EVENT2("cc",
    547                  "TileManager::DidFinishRunningTasks",
    548                  "task_set",
    549                  "REQUIRED_FOR_ACTIVATION",
    550                  "all_tiles_required_for_activation_have_memory",
    551                  all_tiles_required_for_activation_have_memory_);
    552     // This is only a true indication that all tiles required for
    553     // activation are initialized when no tiles are OOM. We need to
    554     // wait for DidFinishRunningTasks() to be called, try to re-assign
    555     // memory and in worst case use on-demand raster when tiles
    556     // required for activation are OOM.
    557     if (!all_tiles_required_for_activation_have_memory_)
    558       return;
    559 
    560     ready_to_activate_check_notifier_.Schedule();
    561   }
    562 }
    563 
    564 void TileManager::GetTilesWithAssignedBins(PrioritizedTileSet* tiles) {
    565   TRACE_EVENT0("cc", "TileManager::GetTilesWithAssignedBins");
    566 
    567   const TileMemoryLimitPolicy memory_policy = global_state_.memory_limit_policy;
    568   const TreePriority tree_priority = global_state_.tree_priority;
    569 
    570   // For each tree, bin into different categories of tiles.
    571   for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
    572     Tile* tile = it->second;
    573     ManagedTileState& mts = tile->managed_state();
    574 
    575     const ManagedTileState::TileVersion& tile_version =
    576         tile->GetTileVersionForDrawing();
    577     bool tile_is_ready_to_draw = tile_version.IsReadyToDraw();
    578     bool tile_is_active = tile_is_ready_to_draw ||
    579                           mts.tile_versions[mts.raster_mode].raster_task_.get();
    580 
    581     // Get the active priority and bin.
    582     TilePriority active_priority = tile->priority(ACTIVE_TREE);
    583     ManagedTileBin active_bin = BinFromTilePriority(active_priority);
    584 
    585     // Get the pending priority and bin.
    586     TilePriority pending_priority = tile->priority(PENDING_TREE);
    587     ManagedTileBin pending_bin = BinFromTilePriority(pending_priority);
    588 
    589     bool pending_is_low_res = pending_priority.resolution == LOW_RESOLUTION;
    590     bool pending_is_non_ideal =
    591         pending_priority.resolution == NON_IDEAL_RESOLUTION;
    592     bool active_is_non_ideal =
    593         active_priority.resolution == NON_IDEAL_RESOLUTION;
    594 
    595     // Adjust bin state based on if ready to draw.
    596     active_bin = kBinReadyToDrawMap[tile_is_ready_to_draw][active_bin];
    597     pending_bin = kBinReadyToDrawMap[tile_is_ready_to_draw][pending_bin];
    598 
    599     // Adjust bin state based on if active.
    600     active_bin = kBinIsActiveMap[tile_is_active][active_bin];
    601     pending_bin = kBinIsActiveMap[tile_is_active][pending_bin];
    602 
    603     // We never want to paint new non-ideal tiles, as we always have
    604     // a high-res tile covering that content (paint that instead).
    605     if (!tile_is_ready_to_draw && active_is_non_ideal)
    606       active_bin = NEVER_BIN;
    607     if (!tile_is_ready_to_draw && pending_is_non_ideal)
    608       pending_bin = NEVER_BIN;
    609 
    610     ManagedTileBin tree_bin[NUM_TREES];
    611     tree_bin[ACTIVE_TREE] = kBinPolicyMap[memory_policy][active_bin];
    612     tree_bin[PENDING_TREE] = kBinPolicyMap[memory_policy][pending_bin];
    613 
    614     // Adjust pending bin state for low res tiles. This prevents pending tree
    615     // low-res tiles from being initialized before high-res tiles.
    616     if (pending_is_low_res)
    617       tree_bin[PENDING_TREE] = std::max(tree_bin[PENDING_TREE], EVENTUALLY_BIN);
    618 
    619     TilePriority tile_priority;
    620     switch (tree_priority) {
    621       case SAME_PRIORITY_FOR_BOTH_TREES:
    622         mts.bin = std::min(tree_bin[ACTIVE_TREE], tree_bin[PENDING_TREE]);
    623         tile_priority = tile->combined_priority();
    624         break;
    625       case SMOOTHNESS_TAKES_PRIORITY:
    626         mts.bin = tree_bin[ACTIVE_TREE];
    627         tile_priority = active_priority;
    628         break;
    629       case NEW_CONTENT_TAKES_PRIORITY:
    630         mts.bin = tree_bin[PENDING_TREE];
    631         tile_priority = pending_priority;
    632         break;
    633       default:
    634         NOTREACHED();
    635     }
    636 
    637     // Bump up the priority if we determined it's NEVER_BIN on one tree,
    638     // but is still required on the other tree.
    639     bool is_in_never_bin_on_both_trees = tree_bin[ACTIVE_TREE] == NEVER_BIN &&
    640                                          tree_bin[PENDING_TREE] == NEVER_BIN;
    641 
    642     if (mts.bin == NEVER_BIN && !is_in_never_bin_on_both_trees)
    643       mts.bin = tile_is_active ? AT_LAST_AND_ACTIVE_BIN : AT_LAST_BIN;
    644 
    645     mts.resolution = tile_priority.resolution;
    646     mts.priority_bin = tile_priority.priority_bin;
    647     mts.distance_to_visible = tile_priority.distance_to_visible;
    648     mts.required_for_activation = tile_priority.required_for_activation;
    649 
    650     mts.visible_and_ready_to_draw =
    651         tree_bin[ACTIVE_TREE] == NOW_AND_READY_TO_DRAW_BIN;
    652 
    653     // Tiles that are required for activation shouldn't be in NEVER_BIN unless
    654     // smoothness takes priority or memory policy allows nothing to be
    655     // initialized.
    656     DCHECK(!mts.required_for_activation || mts.bin != NEVER_BIN ||
    657            tree_priority == SMOOTHNESS_TAKES_PRIORITY ||
    658            memory_policy == ALLOW_NOTHING);
    659 
    660     // If the tile is in NEVER_BIN and it does not have an active task, then we
    661     // can release the resources early. If it does have the task however, we
    662     // should keep it in the prioritized tile set to ensure that AssignGpuMemory
    663     // can visit it.
    664     if (mts.bin == NEVER_BIN &&
    665         !mts.tile_versions[mts.raster_mode].raster_task_.get()) {
    666       FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile);
    667       continue;
    668     }
    669 
    670     // Insert the tile into a priority set.
    671     tiles->InsertTile(tile, mts.bin);
    672   }
    673 }
    674 
    675 void TileManager::ManageTiles(const GlobalStateThatImpactsTilePriority& state) {
    676   TRACE_EVENT0("cc", "TileManager::ManageTiles");
    677 
    678   // Update internal state.
    679   if (state != global_state_) {
    680     global_state_ = state;
    681     prioritized_tiles_dirty_ = true;
    682   }
    683 
    684   // We need to call CheckForCompletedTasks() once in-between each call
    685   // to ScheduleTasks() to prevent canceled tasks from being scheduled.
    686   if (!did_check_for_completed_tasks_since_last_schedule_tasks_) {
    687     rasterizer_->CheckForCompletedTasks();
    688     did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
    689   }
    690 
    691   UpdatePrioritizedTileSetIfNeeded();
    692 
    693   TileVector tiles_that_need_to_be_rasterized;
    694   AssignGpuMemoryToTiles(&prioritized_tiles_,
    695                          &tiles_that_need_to_be_rasterized);
    696 
    697   // Finally, schedule rasterizer tasks.
    698   ScheduleTasks(tiles_that_need_to_be_rasterized);
    699 
    700   TRACE_EVENT_INSTANT1("cc",
    701                        "DidManage",
    702                        TRACE_EVENT_SCOPE_THREAD,
    703                        "state",
    704                        BasicStateAsValue());
    705 
    706   TRACE_COUNTER_ID1("cc",
    707                     "unused_memory_bytes",
    708                     this,
    709                     resource_pool_->total_memory_usage_bytes() -
    710                         resource_pool_->acquired_memory_usage_bytes());
    711 }
    712 
    713 bool TileManager::UpdateVisibleTiles() {
    714   TRACE_EVENT0("cc", "TileManager::UpdateVisibleTiles");
    715 
    716   rasterizer_->CheckForCompletedTasks();
    717   did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
    718 
    719   TRACE_EVENT_INSTANT1(
    720       "cc",
    721       "DidUpdateVisibleTiles",
    722       TRACE_EVENT_SCOPE_THREAD,
    723       "stats",
    724       RasterTaskCompletionStatsAsValue(update_visible_tiles_stats_));
    725   update_visible_tiles_stats_ = RasterTaskCompletionStats();
    726 
    727   bool did_initialize_visible_tile = did_initialize_visible_tile_;
    728   did_initialize_visible_tile_ = false;
    729   return did_initialize_visible_tile;
    730 }
    731 
    732 scoped_refptr<base::debug::ConvertableToTraceFormat>
    733 TileManager::BasicStateAsValue() const {
    734   scoped_refptr<base::debug::TracedValue> value =
    735       new base::debug::TracedValue();
    736   BasicStateAsValueInto(value.get());
    737   return value;
    738 }
    739 
    740 void TileManager::BasicStateAsValueInto(base::debug::TracedValue* state) const {
    741   state->SetInteger("tile_count", tiles_.size());
    742   state->SetBoolean("did_oom_on_last_assign", did_oom_on_last_assign_);
    743   state->BeginDictionary("global_state");
    744   global_state_.AsValueInto(state);
    745   state->EndDictionary();
    746 }
    747 
    748 void TileManager::AssignGpuMemoryToTiles(
    749     PrioritizedTileSet* tiles,
    750     TileVector* tiles_that_need_to_be_rasterized) {
    751   TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles");
    752 
    753   // Maintain the list of released resources that can potentially be re-used
    754   // or deleted.
    755   // If this operation becomes expensive too, only do this after some
    756   // resource(s) was returned. Note that in that case, one also need to
    757   // invalidate when releasing some resource from the pool.
    758   resource_pool_->CheckBusyResources();
    759 
    760   // Now give memory out to the tiles until we're out, and build
    761   // the needs-to-be-rasterized queue.
    762   all_tiles_that_need_to_be_rasterized_have_memory_ = true;
    763   all_tiles_required_for_activation_have_memory_ = true;
    764 
    765   // Cast to prevent overflow.
    766   int64 soft_bytes_available =
    767       static_cast<int64>(bytes_releasable_) +
    768       static_cast<int64>(global_state_.soft_memory_limit_in_bytes) -
    769       static_cast<int64>(resource_pool_->acquired_memory_usage_bytes());
    770   int64 hard_bytes_available =
    771       static_cast<int64>(bytes_releasable_) +
    772       static_cast<int64>(global_state_.hard_memory_limit_in_bytes) -
    773       static_cast<int64>(resource_pool_->acquired_memory_usage_bytes());
    774   int resources_available = resources_releasable_ +
    775                             global_state_.num_resources_limit -
    776                             resource_pool_->acquired_resource_count();
    777   size_t soft_bytes_allocatable =
    778       std::max(static_cast<int64>(0), soft_bytes_available);
    779   size_t hard_bytes_allocatable =
    780       std::max(static_cast<int64>(0), hard_bytes_available);
    781   size_t resources_allocatable = std::max(0, resources_available);
    782 
    783   size_t bytes_that_exceeded_memory_budget = 0;
    784   size_t soft_bytes_left = soft_bytes_allocatable;
    785   size_t hard_bytes_left = hard_bytes_allocatable;
    786 
    787   size_t resources_left = resources_allocatable;
    788   bool oomed_soft = false;
    789   bool oomed_hard = false;
    790   bool have_hit_soft_memory = false;  // Soft memory comes after hard.
    791 
    792   unsigned schedule_priority = 1u;
    793   for (PrioritizedTileSet::Iterator it(tiles, true); it; ++it) {
    794     Tile* tile = *it;
    795     ManagedTileState& mts = tile->managed_state();
    796 
    797     mts.scheduled_priority = schedule_priority++;
    798 
    799     mts.raster_mode = tile->DetermineOverallRasterMode();
    800 
    801     ManagedTileState::TileVersion& tile_version =
    802         mts.tile_versions[mts.raster_mode];
    803 
    804     // If this tile doesn't need a resource, then nothing to do.
    805     if (!tile_version.requires_resource())
    806       continue;
    807 
    808     // If the tile is not needed, free it up.
    809     if (mts.bin == NEVER_BIN) {
    810       FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile);
    811       continue;
    812     }
    813 
    814     const bool tile_uses_hard_limit = mts.bin <= NOW_BIN;
    815     const size_t bytes_if_allocated = BytesConsumedIfAllocated(tile);
    816     const size_t tile_bytes_left =
    817         (tile_uses_hard_limit) ? hard_bytes_left : soft_bytes_left;
    818 
    819     // Hard-limit is reserved for tiles that would cause a calamity
    820     // if they were to go away, so by definition they are the highest
    821     // priority memory, and must be at the front of the list.
    822     DCHECK(!(have_hit_soft_memory && tile_uses_hard_limit));
    823     have_hit_soft_memory |= !tile_uses_hard_limit;
    824 
    825     size_t tile_bytes = 0;
    826     size_t tile_resources = 0;
    827 
    828     // It costs to maintain a resource.
    829     for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) {
    830       if (mts.tile_versions[mode].resource_) {
    831         tile_bytes += bytes_if_allocated;
    832         tile_resources++;
    833       }
    834     }
    835 
    836     // Allow lower priority tiles with initialized resources to keep
    837     // their memory by only assigning memory to new raster tasks if
    838     // they can be scheduled.
    839     bool reached_scheduled_raster_tasks_limit =
    840         tiles_that_need_to_be_rasterized->size() >= kScheduledRasterTasksLimit;
    841     if (!reached_scheduled_raster_tasks_limit) {
    842       // If we don't have the required version, and it's not in flight
    843       // then we'll have to pay to create a new task.
    844       if (!tile_version.resource_ && !tile_version.raster_task_.get()) {
    845         tile_bytes += bytes_if_allocated;
    846         tile_resources++;
    847       }
    848     }
    849 
    850     // Tile is OOM.
    851     if (tile_bytes > tile_bytes_left || tile_resources > resources_left) {
    852       FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile);
    853 
    854       // This tile was already on screen and now its resources have been
    855       // released. In order to prevent checkerboarding, set this tile as
    856       // rasterize on demand immediately.
    857       if (mts.visible_and_ready_to_draw)
    858         tile_version.set_rasterize_on_demand();
    859 
    860       oomed_soft = true;
    861       if (tile_uses_hard_limit) {
    862         oomed_hard = true;
    863         bytes_that_exceeded_memory_budget += tile_bytes;
    864       }
    865     } else {
    866       resources_left -= tile_resources;
    867       hard_bytes_left -= tile_bytes;
    868       soft_bytes_left =
    869           (soft_bytes_left > tile_bytes) ? soft_bytes_left - tile_bytes : 0;
    870       if (tile_version.resource_)
    871         continue;
    872     }
    873 
    874     DCHECK(!tile_version.resource_);
    875 
    876     // Tile shouldn't be rasterized if |tiles_that_need_to_be_rasterized|
    877     // has reached it's limit or we've failed to assign gpu memory to this
    878     // or any higher priority tile. Preventing tiles that fit into memory
    879     // budget to be rasterized when higher priority tile is oom is
    880     // important for two reasons:
    881     // 1. Tile size should not impact raster priority.
    882     // 2. Tiles with existing raster task could otherwise incorrectly
    883     //    be added as they are not affected by |bytes_allocatable|.
    884     bool can_schedule_tile =
    885         !oomed_soft && !reached_scheduled_raster_tasks_limit;
    886 
    887     if (!can_schedule_tile) {
    888       all_tiles_that_need_to_be_rasterized_have_memory_ = false;
    889       if (tile->required_for_activation())
    890         all_tiles_required_for_activation_have_memory_ = false;
    891       it.DisablePriorityOrdering();
    892       continue;
    893     }
    894 
    895     tiles_that_need_to_be_rasterized->push_back(tile);
    896   }
    897 
    898   // OOM reporting uses hard-limit, soft-OOM is normal depending on limit.
    899   ever_exceeded_memory_budget_ |= oomed_hard;
    900   if (ever_exceeded_memory_budget_) {
    901     TRACE_COUNTER_ID2("cc",
    902                       "over_memory_budget",
    903                       this,
    904                       "budget",
    905                       global_state_.hard_memory_limit_in_bytes,
    906                       "over",
    907                       bytes_that_exceeded_memory_budget);
    908   }
    909   did_oom_on_last_assign_ = oomed_hard;
    910   UMA_HISTOGRAM_BOOLEAN("TileManager.ExceededMemoryBudget", oomed_hard);
    911   memory_stats_from_last_assign_.total_budget_in_bytes =
    912       global_state_.hard_memory_limit_in_bytes;
    913   memory_stats_from_last_assign_.bytes_allocated =
    914       hard_bytes_allocatable - hard_bytes_left;
    915   memory_stats_from_last_assign_.bytes_unreleasable =
    916       resource_pool_->acquired_memory_usage_bytes() - bytes_releasable_;
    917   memory_stats_from_last_assign_.bytes_over = bytes_that_exceeded_memory_budget;
    918 }
    919 
    920 void TileManager::FreeResourceForTile(Tile* tile, RasterMode mode) {
    921   ManagedTileState& mts = tile->managed_state();
    922   if (mts.tile_versions[mode].resource_) {
    923     resource_pool_->ReleaseResource(mts.tile_versions[mode].resource_.Pass());
    924 
    925     DCHECK_GE(bytes_releasable_, BytesConsumedIfAllocated(tile));
    926     DCHECK_GE(resources_releasable_, 1u);
    927 
    928     bytes_releasable_ -= BytesConsumedIfAllocated(tile);
    929     --resources_releasable_;
    930   }
    931 }
    932 
    933 void TileManager::FreeResourcesForTile(Tile* tile) {
    934   for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) {
    935     FreeResourceForTile(tile, static_cast<RasterMode>(mode));
    936   }
    937 }
    938 
    939 void TileManager::FreeUnusedResourcesForTile(Tile* tile) {
    940   DCHECK(tile->IsReadyToDraw());
    941   ManagedTileState& mts = tile->managed_state();
    942   RasterMode used_mode = LOW_QUALITY_RASTER_MODE;
    943   for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) {
    944     if (mts.tile_versions[mode].IsReadyToDraw()) {
    945       used_mode = static_cast<RasterMode>(mode);
    946       break;
    947     }
    948   }
    949 
    950   for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) {
    951     if (mode != used_mode)
    952       FreeResourceForTile(tile, static_cast<RasterMode>(mode));
    953   }
    954 }
    955 
    956 void TileManager::FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(
    957     Tile* tile) {
    958   bool was_ready_to_draw = tile->IsReadyToDraw();
    959   FreeResourcesForTile(tile);
    960   if (was_ready_to_draw)
    961     client_->NotifyTileStateChanged(tile);
    962 }
    963 
    964 void TileManager::ScheduleTasks(
    965     const TileVector& tiles_that_need_to_be_rasterized) {
    966   TRACE_EVENT1("cc",
    967                "TileManager::ScheduleTasks",
    968                "count",
    969                tiles_that_need_to_be_rasterized.size());
    970 
    971   DCHECK(did_check_for_completed_tasks_since_last_schedule_tasks_);
    972 
    973   raster_queue_.Reset();
    974 
    975   // Build a new task queue containing all task currently needed. Tasks
    976   // are added in order of priority, highest priority task first.
    977   for (TileVector::const_iterator it = tiles_that_need_to_be_rasterized.begin();
    978        it != tiles_that_need_to_be_rasterized.end();
    979        ++it) {
    980     Tile* tile = *it;
    981     ManagedTileState& mts = tile->managed_state();
    982     ManagedTileState::TileVersion& tile_version =
    983         mts.tile_versions[mts.raster_mode];
    984 
    985     DCHECK(tile_version.requires_resource());
    986     DCHECK(!tile_version.resource_);
    987 
    988     if (!tile_version.raster_task_.get())
    989       tile_version.raster_task_ = CreateRasterTask(tile);
    990 
    991     TaskSetCollection task_sets;
    992     if (tile->required_for_activation())
    993       task_sets.set(REQUIRED_FOR_ACTIVATION);
    994     task_sets.set(ALL);
    995     raster_queue_.items.push_back(
    996         RasterTaskQueue::Item(tile_version.raster_task_.get(), task_sets));
    997   }
    998 
    999   // We must reduce the amount of unused resoruces before calling
   1000   // ScheduleTasks to prevent usage from rising above limits.
   1001   resource_pool_->ReduceResourceUsage();
   1002 
   1003   // Schedule running of |raster_tasks_|. This replaces any previously
   1004   // scheduled tasks and effectively cancels all tasks not present
   1005   // in |raster_tasks_|.
   1006   rasterizer_->ScheduleTasks(&raster_queue_);
   1007 
   1008   // It's now safe to clean up orphan tasks as raster worker pool is not
   1009   // allowed to keep around unreferenced raster tasks after ScheduleTasks() has
   1010   // been called.
   1011   orphan_raster_tasks_.clear();
   1012 
   1013   did_check_for_completed_tasks_since_last_schedule_tasks_ = false;
   1014 }
   1015 
   1016 scoped_refptr<ImageDecodeTask> TileManager::CreateImageDecodeTask(
   1017     Tile* tile,
   1018     SkPixelRef* pixel_ref) {
   1019   return make_scoped_refptr(new ImageDecodeTaskImpl(
   1020       pixel_ref,
   1021       tile->layer_id(),
   1022       rendering_stats_instrumentation_,
   1023       base::Bind(&TileManager::OnImageDecodeTaskCompleted,
   1024                  base::Unretained(this),
   1025                  tile->layer_id(),
   1026                  base::Unretained(pixel_ref))));
   1027 }
   1028 
   1029 scoped_refptr<RasterTask> TileManager::CreateRasterTask(Tile* tile) {
   1030   ManagedTileState& mts = tile->managed_state();
   1031 
   1032   scoped_ptr<ScopedResource> resource =
   1033       resource_pool_->AcquireResource(tile->size());
   1034   const ScopedResource* const_resource = resource.get();
   1035 
   1036   // Create and queue all image decode tasks that this tile depends on.
   1037   ImageDecodeTask::Vector decode_tasks;
   1038   PixelRefTaskMap& existing_pixel_refs = image_decode_tasks_[tile->layer_id()];
   1039   for (PicturePileImpl::PixelRefIterator iter(
   1040            tile->content_rect(), tile->contents_scale(), tile->picture_pile());
   1041        iter;
   1042        ++iter) {
   1043     SkPixelRef* pixel_ref = *iter;
   1044     uint32_t id = pixel_ref->getGenerationID();
   1045 
   1046     // Append existing image decode task if available.
   1047     PixelRefTaskMap::iterator decode_task_it = existing_pixel_refs.find(id);
   1048     if (decode_task_it != existing_pixel_refs.end()) {
   1049       decode_tasks.push_back(decode_task_it->second);
   1050       continue;
   1051     }
   1052 
   1053     // Create and append new image decode task for this pixel ref.
   1054     scoped_refptr<ImageDecodeTask> decode_task =
   1055         CreateImageDecodeTask(tile, pixel_ref);
   1056     decode_tasks.push_back(decode_task);
   1057     existing_pixel_refs[id] = decode_task;
   1058   }
   1059 
   1060   return make_scoped_refptr(
   1061       new RasterTaskImpl(const_resource,
   1062                          tile->picture_pile(),
   1063                          tile->content_rect(),
   1064                          tile->contents_scale(),
   1065                          mts.raster_mode,
   1066                          mts.resolution,
   1067                          tile->layer_id(),
   1068                          static_cast<const void*>(tile),
   1069                          tile->source_frame_number(),
   1070                          tile->use_picture_analysis(),
   1071                          rendering_stats_instrumentation_,
   1072                          base::Bind(&TileManager::OnRasterTaskCompleted,
   1073                                     base::Unretained(this),
   1074                                     tile->id(),
   1075                                     base::Passed(&resource),
   1076                                     mts.raster_mode),
   1077                          &decode_tasks));
   1078 }
   1079 
   1080 void TileManager::OnImageDecodeTaskCompleted(int layer_id,
   1081                                              SkPixelRef* pixel_ref,
   1082                                              bool was_canceled) {
   1083   // If the task was canceled, we need to clean it up
   1084   // from |image_decode_tasks_|.
   1085   if (!was_canceled)
   1086     return;
   1087 
   1088   LayerPixelRefTaskMap::iterator layer_it = image_decode_tasks_.find(layer_id);
   1089   if (layer_it == image_decode_tasks_.end())
   1090     return;
   1091 
   1092   PixelRefTaskMap& pixel_ref_tasks = layer_it->second;
   1093   PixelRefTaskMap::iterator task_it =
   1094       pixel_ref_tasks.find(pixel_ref->getGenerationID());
   1095 
   1096   if (task_it != pixel_ref_tasks.end())
   1097     pixel_ref_tasks.erase(task_it);
   1098 }
   1099 
   1100 void TileManager::OnRasterTaskCompleted(
   1101     Tile::Id tile_id,
   1102     scoped_ptr<ScopedResource> resource,
   1103     RasterMode raster_mode,
   1104     const PicturePileImpl::Analysis& analysis,
   1105     bool was_canceled) {
   1106   DCHECK(tiles_.find(tile_id) != tiles_.end());
   1107 
   1108   Tile* tile = tiles_[tile_id];
   1109   ManagedTileState& mts = tile->managed_state();
   1110   ManagedTileState::TileVersion& tile_version = mts.tile_versions[raster_mode];
   1111   DCHECK(tile_version.raster_task_.get());
   1112   orphan_raster_tasks_.push_back(tile_version.raster_task_);
   1113   tile_version.raster_task_ = NULL;
   1114 
   1115   if (was_canceled) {
   1116     ++update_visible_tiles_stats_.canceled_count;
   1117     resource_pool_->ReleaseResource(resource.Pass());
   1118     return;
   1119   }
   1120 
   1121   ++update_visible_tiles_stats_.completed_count;
   1122 
   1123   if (analysis.is_solid_color) {
   1124     tile_version.set_solid_color(analysis.solid_color);
   1125     resource_pool_->ReleaseResource(resource.Pass());
   1126   } else {
   1127     tile_version.set_use_resource();
   1128     tile_version.resource_ = resource.Pass();
   1129 
   1130     bytes_releasable_ += BytesConsumedIfAllocated(tile);
   1131     ++resources_releasable_;
   1132   }
   1133 
   1134   FreeUnusedResourcesForTile(tile);
   1135   if (tile->priority(ACTIVE_TREE).distance_to_visible == 0.f)
   1136     did_initialize_visible_tile_ = true;
   1137 
   1138   client_->NotifyTileStateChanged(tile);
   1139 }
   1140 
   1141 scoped_refptr<Tile> TileManager::CreateTile(PicturePileImpl* picture_pile,
   1142                                             const gfx::Size& tile_size,
   1143                                             const gfx::Rect& content_rect,
   1144                                             float contents_scale,
   1145                                             int layer_id,
   1146                                             int source_frame_number,
   1147                                             int flags) {
   1148   scoped_refptr<Tile> tile = make_scoped_refptr(new Tile(this,
   1149                                                          picture_pile,
   1150                                                          tile_size,
   1151                                                          content_rect,
   1152                                                          contents_scale,
   1153                                                          layer_id,
   1154                                                          source_frame_number,
   1155                                                          flags));
   1156   DCHECK(tiles_.find(tile->id()) == tiles_.end());
   1157 
   1158   tiles_[tile->id()] = tile.get();
   1159   used_layer_counts_[tile->layer_id()]++;
   1160   prioritized_tiles_dirty_ = true;
   1161   return tile;
   1162 }
   1163 
   1164 void TileManager::SetRasterizerForTesting(Rasterizer* rasterizer) {
   1165   rasterizer_ = rasterizer;
   1166   rasterizer_->SetClient(this);
   1167 }
   1168 
   1169 bool TileManager::IsReadyToActivate() const {
   1170   const std::vector<PictureLayerImpl*>& layers = client_->GetPictureLayers();
   1171 
   1172   for (std::vector<PictureLayerImpl*>::const_iterator it = layers.begin();
   1173        it != layers.end();
   1174        ++it) {
   1175     if (!(*it)->AllTilesRequiredForActivationAreReadyToDraw())
   1176       return false;
   1177   }
   1178 
   1179   return true;
   1180 }
   1181 
   1182 void TileManager::CheckIfReadyToActivate() {
   1183   TRACE_EVENT0("cc", "TileManager::CheckIfReadyToActivate");
   1184 
   1185   rasterizer_->CheckForCompletedTasks();
   1186   did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
   1187 
   1188   if (IsReadyToActivate())
   1189     client_->NotifyReadyToActivate();
   1190 }
   1191 
   1192 }  // namespace cc
   1193