Upstream version 11.39.250.0
[platform/framework/web/crosswalk.git] / src / cc / layers / picture_layer_impl.cc
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/layers/picture_layer_impl.h"
6
7 #include <algorithm>
8 #include <limits>
9 #include <set>
10
11 #include "base/debug/trace_event_argument.h"
12 #include "base/time/time.h"
13 #include "cc/base/math_util.h"
14 #include "cc/base/util.h"
15 #include "cc/debug/debug_colors.h"
16 #include "cc/debug/micro_benchmark_impl.h"
17 #include "cc/debug/traced_value.h"
18 #include "cc/layers/append_quads_data.h"
19 #include "cc/layers/solid_color_layer_impl.h"
20 #include "cc/output/begin_frame_args.h"
21 #include "cc/quads/checkerboard_draw_quad.h"
22 #include "cc/quads/debug_border_draw_quad.h"
23 #include "cc/quads/picture_draw_quad.h"
24 #include "cc/quads/solid_color_draw_quad.h"
25 #include "cc/quads/tile_draw_quad.h"
26 #include "cc/resources/tile_manager.h"
27 #include "cc/trees/layer_tree_impl.h"
28 #include "cc/trees/occlusion_tracker.h"
29 #include "ui/gfx/quad_f.h"
30 #include "ui/gfx/rect_conversions.h"
31 #include "ui/gfx/size_conversions.h"
32
33 namespace {
34 const float kMaxScaleRatioDuringPinch = 2.0f;
35
36 // When creating a new tiling during pinch, snap to an existing
37 // tiling's scale if the desired scale is within this ratio.
38 const float kSnapToExistingTilingRatio = 1.2f;
39
40 // Estimate skewport 60 frames ahead for pre-rasterization on the CPU.
41 const float kCpuSkewportTargetTimeInFrames = 60.0f;
42
43 // Don't pre-rasterize on the GPU (except for kBackflingGuardDistancePixels in
44 // TileManager::BinFromTilePriority).
45 const float kGpuSkewportTargetTimeInFrames = 0.0f;
46
47 }  // namespace
48
49 namespace cc {
50
51 PictureLayerImpl::Pair::Pair() : active(NULL), pending(NULL) {
52 }
53
54 PictureLayerImpl::Pair::Pair(PictureLayerImpl* active_layer,
55                              PictureLayerImpl* pending_layer)
56     : active(active_layer), pending(pending_layer) {
57 }
58
59 PictureLayerImpl::Pair::~Pair() {
60 }
61
62 PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* tree_impl, int id)
63     : LayerImpl(tree_impl, id),
64       twin_layer_(NULL),
65       pile_(PicturePileImpl::Create()),
66       ideal_page_scale_(0.f),
67       ideal_device_scale_(0.f),
68       ideal_source_scale_(0.f),
69       ideal_contents_scale_(0.f),
70       raster_page_scale_(0.f),
71       raster_device_scale_(0.f),
72       raster_source_scale_(0.f),
73       raster_contents_scale_(0.f),
74       low_res_raster_contents_scale_(0.f),
75       raster_source_scale_is_fixed_(false),
76       was_screen_space_transform_animating_(false),
77       needs_post_commit_initialization_(true),
78       should_update_tile_priorities_(false) {
79   layer_tree_impl()->RegisterPictureLayerImpl(this);
80 }
81
82 PictureLayerImpl::~PictureLayerImpl() {
83   layer_tree_impl()->UnregisterPictureLayerImpl(this);
84 }
85
86 const char* PictureLayerImpl::LayerTypeAsString() const {
87   return "cc::PictureLayerImpl";
88 }
89
90 scoped_ptr<LayerImpl> PictureLayerImpl::CreateLayerImpl(
91     LayerTreeImpl* tree_impl) {
92   return PictureLayerImpl::Create(tree_impl, id()).PassAs<LayerImpl>();
93 }
94
95 void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) {
96   // It's possible this layer was never drawn or updated (e.g. because it was
97   // a descendant of an opacity 0 layer).
98   DoPostCommitInitializationIfNeeded();
99   PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer);
100
101   // We have already synced the important bits from the the active layer, and
102   // we will soon swap out its tilings and use them for recycling. However,
103   // there are now tiles in this layer's tilings that were unref'd and replaced
104   // with new tiles (due to invalidation). This resets all active priorities on
105   // the to-be-recycled tiling to ensure replaced tiles don't linger and take
106   // memory (due to a stale 'active' priority).
107   if (layer_impl->tilings_)
108     layer_impl->tilings_->DidBecomeRecycled();
109
110   LayerImpl::PushPropertiesTo(base_layer);
111
112   // When the pending tree pushes to the active tree, the pending twin
113   // becomes recycled.
114   layer_impl->twin_layer_ = NULL;
115   twin_layer_ = NULL;
116
117   layer_impl->UpdatePile(pile_);
118
119   DCHECK(!pile_->is_solid_color() || !tilings_->num_tilings());
120   // Tilings would be expensive to push, so we swap.
121   layer_impl->tilings_.swap(tilings_);
122   layer_impl->tilings_->SetClient(layer_impl);
123   if (tilings_)
124     tilings_->SetClient(this);
125
126   // Ensure that the recycle tree doesn't have any unshared tiles.
127   if (tilings_ && pile_->is_solid_color())
128     tilings_->RemoveAllTilings();
129
130   // Remove invalidated tiles from what will become a recycle tree.
131   if (tilings_)
132     tilings_->RemoveTilesInRegion(invalidation_);
133
134   layer_impl->raster_page_scale_ = raster_page_scale_;
135   layer_impl->raster_device_scale_ = raster_device_scale_;
136   layer_impl->raster_source_scale_ = raster_source_scale_;
137   layer_impl->raster_contents_scale_ = raster_contents_scale_;
138   layer_impl->low_res_raster_contents_scale_ = low_res_raster_contents_scale_;
139   layer_impl->needs_post_commit_initialization_ = false;
140
141   // The invalidation on this soon-to-be-recycled layer must be cleared to
142   // mirror clearing the invalidation in PictureLayer's version of this function
143   // in case push properties is skipped.
144   layer_impl->invalidation_.Swap(&invalidation_);
145   invalidation_.Clear();
146   needs_post_commit_initialization_ = true;
147
148   // We always need to push properties.
149   // See http://crbug.com/303943
150   needs_push_properties_ = true;
151 }
152
153 void PictureLayerImpl::UpdatePile(scoped_refptr<PicturePileImpl> pile) {
154   bool could_have_tilings = CanHaveTilings();
155   pile_.swap(pile);
156
157   // Need to call UpdateTiles again if CanHaveTilings changed.
158   if (could_have_tilings != CanHaveTilings()) {
159     layer_tree_impl()->set_needs_update_draw_properties();
160   }
161 }
162
163 void PictureLayerImpl::AppendQuads(
164     RenderPass* render_pass,
165     const OcclusionTracker<LayerImpl>& occlusion_tracker,
166     AppendQuadsData* append_quads_data) {
167   DCHECK(!needs_post_commit_initialization_);
168
169   SharedQuadState* shared_quad_state =
170       render_pass->CreateAndAppendSharedQuadState();
171
172   if (pile_->is_solid_color()) {
173     PopulateSharedQuadState(shared_quad_state);
174
175     AppendDebugBorderQuad(
176         render_pass, content_bounds(), shared_quad_state, append_quads_data);
177
178     SolidColorLayerImpl::AppendSolidQuads(
179         render_pass,
180         occlusion_tracker,
181         shared_quad_state,
182         visible_content_rect(),
183         draw_properties().target_space_transform,
184         pile_->solid_color());
185     return;
186   }
187
188   float max_contents_scale = MaximumTilingContentsScale();
189   gfx::Transform scaled_draw_transform = draw_transform();
190   scaled_draw_transform.Scale(SK_MScalar1 / max_contents_scale,
191                               SK_MScalar1 / max_contents_scale);
192   gfx::Size scaled_content_bounds =
193       gfx::ToCeiledSize(gfx::ScaleSize(content_bounds(), max_contents_scale));
194
195   gfx::Rect scaled_visible_content_rect =
196       gfx::ScaleToEnclosingRect(visible_content_rect(), max_contents_scale);
197   scaled_visible_content_rect.Intersect(gfx::Rect(scaled_content_bounds));
198
199   Occlusion occlusion =
200       occlusion_tracker.GetCurrentOcclusionForLayer(scaled_draw_transform);
201
202   shared_quad_state->SetAll(scaled_draw_transform,
203                             scaled_content_bounds,
204                             scaled_visible_content_rect,
205                             draw_properties().clip_rect,
206                             draw_properties().is_clipped,
207                             draw_properties().opacity,
208                             blend_mode(),
209                             sorting_context_id_);
210
211   if (current_draw_mode_ == DRAW_MODE_RESOURCELESS_SOFTWARE) {
212     AppendDebugBorderQuad(
213         render_pass,
214         scaled_content_bounds,
215         shared_quad_state,
216         append_quads_data,
217         DebugColors::DirectPictureBorderColor(),
218         DebugColors::DirectPictureBorderWidth(layer_tree_impl()));
219
220     gfx::Rect geometry_rect = scaled_visible_content_rect;
221     gfx::Rect opaque_rect = contents_opaque() ? geometry_rect : gfx::Rect();
222     gfx::Rect visible_geometry_rect =
223         occlusion.GetUnoccludedContentRect(geometry_rect);
224     if (visible_geometry_rect.IsEmpty())
225       return;
226
227     gfx::Size texture_size = scaled_visible_content_rect.size();
228     gfx::RectF texture_rect = gfx::RectF(texture_size);
229     gfx::Rect quad_content_rect = scaled_visible_content_rect;
230
231     PictureDrawQuad* quad =
232         render_pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
233     quad->SetNew(shared_quad_state,
234                  geometry_rect,
235                  opaque_rect,
236                  visible_geometry_rect,
237                  texture_rect,
238                  texture_size,
239                  RGBA_8888,
240                  quad_content_rect,
241                  max_contents_scale,
242                  pile_);
243     return;
244   }
245
246   AppendDebugBorderQuad(
247       render_pass, scaled_content_bounds, shared_quad_state, append_quads_data);
248
249   if (ShowDebugBorders()) {
250     for (PictureLayerTilingSet::CoverageIterator iter(
251              tilings_.get(),
252              max_contents_scale,
253              scaled_visible_content_rect,
254              ideal_contents_scale_);
255          iter;
256          ++iter) {
257       SkColor color;
258       float width;
259       if (*iter && iter->IsReadyToDraw()) {
260         ManagedTileState::TileVersion::Mode mode =
261             iter->GetTileVersionForDrawing().mode();
262         if (mode == ManagedTileState::TileVersion::SOLID_COLOR_MODE) {
263           color = DebugColors::SolidColorTileBorderColor();
264           width = DebugColors::SolidColorTileBorderWidth(layer_tree_impl());
265         } else if (mode == ManagedTileState::TileVersion::PICTURE_PILE_MODE) {
266           color = DebugColors::PictureTileBorderColor();
267           width = DebugColors::PictureTileBorderWidth(layer_tree_impl());
268         } else if (iter->priority(ACTIVE_TREE).resolution == HIGH_RESOLUTION) {
269           color = DebugColors::HighResTileBorderColor();
270           width = DebugColors::HighResTileBorderWidth(layer_tree_impl());
271         } else if (iter->priority(ACTIVE_TREE).resolution == LOW_RESOLUTION) {
272           color = DebugColors::LowResTileBorderColor();
273           width = DebugColors::LowResTileBorderWidth(layer_tree_impl());
274         } else if (iter->contents_scale() > max_contents_scale) {
275           color = DebugColors::ExtraHighResTileBorderColor();
276           width = DebugColors::ExtraHighResTileBorderWidth(layer_tree_impl());
277         } else {
278           color = DebugColors::ExtraLowResTileBorderColor();
279           width = DebugColors::ExtraLowResTileBorderWidth(layer_tree_impl());
280         }
281       } else {
282         color = DebugColors::MissingTileBorderColor();
283         width = DebugColors::MissingTileBorderWidth(layer_tree_impl());
284       }
285
286       DebugBorderDrawQuad* debug_border_quad =
287           render_pass->CreateAndAppendDrawQuad<DebugBorderDrawQuad>();
288       gfx::Rect geometry_rect = iter.geometry_rect();
289       gfx::Rect visible_geometry_rect = geometry_rect;
290       debug_border_quad->SetNew(shared_quad_state,
291                                 geometry_rect,
292                                 visible_geometry_rect,
293                                 color,
294                                 width);
295     }
296   }
297
298   // Keep track of the tilings that were used so that tilings that are
299   // unused can be considered for removal.
300   std::vector<PictureLayerTiling*> seen_tilings;
301
302   // Ignore missing tiles outside of viewport for tile priority. This is
303   // normally the same as draw viewport but can be independently overridden by
304   // embedders like Android WebView with SetExternalDrawConstraints.
305   gfx::Rect scaled_viewport_for_tile_priority = gfx::ScaleToEnclosingRect(
306       GetViewportForTilePriorityInContentSpace(), max_contents_scale);
307
308   size_t missing_tile_count = 0u;
309   size_t on_demand_missing_tile_count = 0u;
310   for (PictureLayerTilingSet::CoverageIterator iter(tilings_.get(),
311                                                     max_contents_scale,
312                                                     scaled_visible_content_rect,
313                                                     ideal_contents_scale_);
314        iter;
315        ++iter) {
316     gfx::Rect geometry_rect = iter.geometry_rect();
317     gfx::Rect opaque_rect = contents_opaque() ? geometry_rect : gfx::Rect();
318     gfx::Rect visible_geometry_rect =
319         occlusion.GetUnoccludedContentRect(geometry_rect);
320     if (visible_geometry_rect.IsEmpty())
321       continue;
322
323     append_quads_data->visible_content_area +=
324         visible_geometry_rect.width() * visible_geometry_rect.height();
325
326     bool has_draw_quad = false;
327     if (*iter && iter->IsReadyToDraw()) {
328       const ManagedTileState::TileVersion& tile_version =
329           iter->GetTileVersionForDrawing();
330       switch (tile_version.mode()) {
331         case ManagedTileState::TileVersion::RESOURCE_MODE: {
332           gfx::RectF texture_rect = iter.texture_rect();
333
334           // The raster_contents_scale_ is the best scale that the layer is
335           // trying to produce, even though it may not be ideal. Since that's
336           // the best the layer can promise in the future, consider those as
337           // complete. But if a tile is ideal scale, we don't want to consider
338           // it incomplete and trying to replace it with a tile at a worse
339           // scale.
340           if (iter->contents_scale() != raster_contents_scale_ &&
341               iter->contents_scale() != ideal_contents_scale_ &&
342               geometry_rect.Intersects(scaled_viewport_for_tile_priority)) {
343             append_quads_data->num_incomplete_tiles++;
344           }
345
346           TileDrawQuad* quad =
347               render_pass->CreateAndAppendDrawQuad<TileDrawQuad>();
348           quad->SetNew(shared_quad_state,
349                        geometry_rect,
350                        opaque_rect,
351                        visible_geometry_rect,
352                        tile_version.get_resource_id(),
353                        texture_rect,
354                        iter.texture_size(),
355                        tile_version.contents_swizzled());
356           has_draw_quad = true;
357           break;
358         }
359         case ManagedTileState::TileVersion::PICTURE_PILE_MODE: {
360           if (!layer_tree_impl()
361                    ->GetRendererCapabilities()
362                    .allow_rasterize_on_demand) {
363             ++on_demand_missing_tile_count;
364             break;
365           }
366
367           gfx::RectF texture_rect = iter.texture_rect();
368
369           ResourceProvider* resource_provider =
370               layer_tree_impl()->resource_provider();
371           ResourceFormat format =
372               resource_provider->memory_efficient_texture_format();
373           PictureDrawQuad* quad =
374               render_pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
375           quad->SetNew(shared_quad_state,
376                        geometry_rect,
377                        opaque_rect,
378                        visible_geometry_rect,
379                        texture_rect,
380                        iter.texture_size(),
381                        format,
382                        iter->content_rect(),
383                        iter->contents_scale(),
384                        pile_);
385           has_draw_quad = true;
386           break;
387         }
388         case ManagedTileState::TileVersion::SOLID_COLOR_MODE: {
389           SolidColorDrawQuad* quad =
390               render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
391           quad->SetNew(shared_quad_state,
392                        geometry_rect,
393                        visible_geometry_rect,
394                        tile_version.get_solid_color(),
395                        false);
396           has_draw_quad = true;
397           break;
398         }
399       }
400     }
401
402     if (!has_draw_quad) {
403       if (draw_checkerboard_for_missing_tiles()) {
404         CheckerboardDrawQuad* quad =
405             render_pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
406         SkColor color = DebugColors::DefaultCheckerboardColor();
407         quad->SetNew(
408             shared_quad_state, geometry_rect, visible_geometry_rect, color);
409       } else {
410         SkColor color = SafeOpaqueBackgroundColor();
411         SolidColorDrawQuad* quad =
412             render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
413         quad->SetNew(shared_quad_state,
414                      geometry_rect,
415                      visible_geometry_rect,
416                      color,
417                      false);
418       }
419
420       if (geometry_rect.Intersects(scaled_viewport_for_tile_priority)) {
421         append_quads_data->num_missing_tiles++;
422         ++missing_tile_count;
423       }
424       append_quads_data->approximated_visible_content_area +=
425           visible_geometry_rect.width() * visible_geometry_rect.height();
426       continue;
427     }
428
429     if (iter->priority(ACTIVE_TREE).resolution != HIGH_RESOLUTION) {
430       append_quads_data->approximated_visible_content_area +=
431           visible_geometry_rect.width() * visible_geometry_rect.height();
432     }
433
434     if (seen_tilings.empty() || seen_tilings.back() != iter.CurrentTiling())
435       seen_tilings.push_back(iter.CurrentTiling());
436   }
437
438   if (missing_tile_count) {
439     TRACE_EVENT_INSTANT2("cc",
440                          "PictureLayerImpl::AppendQuads checkerboard",
441                          TRACE_EVENT_SCOPE_THREAD,
442                          "missing_tile_count",
443                          missing_tile_count,
444                          "on_demand_missing_tile_count",
445                          on_demand_missing_tile_count);
446   }
447
448   // Aggressively remove any tilings that are not seen to save memory. Note
449   // that this is at the expense of doing cause more frequent re-painting. A
450   // better scheme would be to maintain a tighter visible_content_rect for the
451   // finer tilings.
452   CleanUpTilingsOnActiveLayer(seen_tilings);
453 }
454
455 void PictureLayerImpl::UpdateTiles(const Occlusion& occlusion_in_content_space,
456                                    bool resourceless_software_draw) {
457   TRACE_EVENT0("cc", "PictureLayerImpl::UpdateTiles");
458   DCHECK_EQ(1.f, contents_scale_x());
459   DCHECK_EQ(1.f, contents_scale_y());
460
461   DoPostCommitInitializationIfNeeded();
462
463   // Any draw properties derived from |transform|, |viewport|, and |clip|
464   // parameters in LayerTreeHostImpl::SetExternalDrawConstraints are not valid
465   // for prioritizing tiles during resourceless software draws. This is because
466   // resourceless software draws can have wildly different transforms/viewports
467   // from regular draws.
468   if (!resourceless_software_draw) {
469     visible_rect_for_tile_priority_ = visible_content_rect();
470   }
471   viewport_rect_for_tile_priority_ =
472       layer_tree_impl()->ViewportRectForTilePriority();
473   screen_space_transform_for_tile_priority_ = screen_space_transform();
474
475   if (!CanHaveTilings()) {
476     ideal_page_scale_ = 0.f;
477     ideal_device_scale_ = 0.f;
478     ideal_contents_scale_ = 0.f;
479     ideal_source_scale_ = 0.f;
480     SanityCheckTilingState();
481     return;
482   }
483
484   UpdateIdealScales();
485
486   DCHECK(tilings_->num_tilings() > 0 || raster_contents_scale_ == 0.f)
487       << "A layer with no tilings shouldn't have valid raster scales";
488   if (!raster_contents_scale_ || ShouldAdjustRasterScale()) {
489     RecalculateRasterScales();
490     AddTilingsForRasterScale();
491   }
492
493   DCHECK(raster_page_scale_);
494   DCHECK(raster_device_scale_);
495   DCHECK(raster_source_scale_);
496   DCHECK(raster_contents_scale_);
497   DCHECK(low_res_raster_contents_scale_);
498
499   was_screen_space_transform_animating_ =
500       draw_properties().screen_space_transform_is_animating;
501
502   should_update_tile_priorities_ = true;
503
504   UpdateTilePriorities(occlusion_in_content_space);
505
506   if (layer_tree_impl()->IsPendingTree())
507     MarkVisibleResourcesAsRequired();
508 }
509
510 void PictureLayerImpl::UpdateTilePriorities(
511     const Occlusion& occlusion_in_content_space) {
512   DCHECK(!pile_->is_solid_color() || !tilings_->num_tilings());
513
514   TRACE_EVENT0("cc", "PictureLayerImpl::UpdateTilePriorities");
515
516   double current_frame_time_in_seconds =
517       (layer_tree_impl()->CurrentBeginFrameArgs().frame_time -
518        base::TimeTicks()).InSecondsF();
519
520   gfx::Rect viewport_rect_in_layer_space =
521       GetViewportForTilePriorityInContentSpace();
522   bool tiling_needs_update = false;
523   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
524     if (tilings_->tiling_at(i)->NeedsUpdateForFrameAtTimeAndViewport(
525             current_frame_time_in_seconds, viewport_rect_in_layer_space)) {
526       tiling_needs_update = true;
527       break;
528     }
529   }
530   if (!tiling_needs_update)
531     return;
532
533   WhichTree tree =
534       layer_tree_impl()->IsActiveTree() ? ACTIVE_TREE : PENDING_TREE;
535   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
536     // Pass |occlusion_in_content_space| for |occlusion_in_layer_space| since
537     // they are the same space in picture lbayer, as contents scale is always 1.
538     tilings_->tiling_at(i)->UpdateTilePriorities(tree,
539                                                  viewport_rect_in_layer_space,
540                                                  ideal_contents_scale_,
541                                                  current_frame_time_in_seconds,
542                                                  occlusion_in_content_space);
543   }
544
545   // Tile priorities were modified.
546   layer_tree_impl()->DidModifyTilePriorities();
547 }
548
549 gfx::Rect PictureLayerImpl::GetViewportForTilePriorityInContentSpace() const {
550   // If visible_rect_for_tile_priority_ is empty or
551   // viewport_rect_for_tile_priority_ is set to be different from the device
552   // viewport, try to inverse project the viewport into layer space and use
553   // that. Otherwise just use visible_rect_for_tile_priority_
554   gfx::Rect visible_rect_in_content_space = visible_rect_for_tile_priority_;
555
556   if (visible_rect_in_content_space.IsEmpty() ||
557       layer_tree_impl()->DeviceViewport() != viewport_rect_for_tile_priority_) {
558     gfx::Transform view_to_layer(gfx::Transform::kSkipInitialization);
559
560     if (screen_space_transform_for_tile_priority_.GetInverse(&view_to_layer)) {
561       // Transform from view space to content space.
562       visible_rect_in_content_space =
563           gfx::ToEnclosingRect(MathUtil::ProjectClippedRect(
564               view_to_layer, viewport_rect_for_tile_priority_));
565     }
566   }
567   return visible_rect_in_content_space;
568 }
569
570 PictureLayerImpl* PictureLayerImpl::GetRecycledTwinLayer() {
571   // TODO(vmpstr): Maintain recycled twin as a member. crbug.com/407418
572   return static_cast<PictureLayerImpl*>(
573       layer_tree_impl()->FindRecycleTreeLayerById(id()));
574 }
575
576 void PictureLayerImpl::NotifyTileStateChanged(const Tile* tile) {
577   if (layer_tree_impl()->IsActiveTree()) {
578     gfx::RectF layer_damage_rect =
579         gfx::ScaleRect(tile->content_rect(), 1.f / tile->contents_scale());
580     AddDamageRect(layer_damage_rect);
581   }
582 }
583
584 void PictureLayerImpl::DidBecomeActive() {
585   LayerImpl::DidBecomeActive();
586   tilings_->DidBecomeActive();
587   layer_tree_impl()->DidModifyTilePriorities();
588 }
589
590 void PictureLayerImpl::DidBeginTracing() {
591   pile_->DidBeginTracing();
592 }
593
594 void PictureLayerImpl::ReleaseResources() {
595   if (tilings_)
596     RemoveAllTilings();
597
598   ResetRasterScale();
599
600   // To avoid an edge case after lost context where the tree is up to date but
601   // the tilings have not been managed, request an update draw properties
602   // to force tilings to get managed.
603   layer_tree_impl()->set_needs_update_draw_properties();
604 }
605
606 skia::RefPtr<SkPicture> PictureLayerImpl::GetPicture() {
607   return pile_->GetFlattenedPicture();
608 }
609
610 scoped_refptr<Tile> PictureLayerImpl::CreateTile(PictureLayerTiling* tiling,
611                                                const gfx::Rect& content_rect) {
612   DCHECK(!pile_->is_solid_color());
613   if (!pile_->CanRaster(tiling->contents_scale(), content_rect))
614     return scoped_refptr<Tile>();
615
616   int flags = 0;
617
618   // TODO(vmpstr): Revisit this. For now, enabling analysis means that we get as
619   // much savings on memory as we can. However, for some cases like ganesh or
620   // small layers, the amount of time we spend analyzing might not justify
621   // memory savings that we can get. Note that we don't handle solid color
622   // masks, so we shouldn't bother analyzing those.
623   // Bugs: crbug.com/397198, crbug.com/396908
624   if (!pile_->is_mask())
625     flags = Tile::USE_PICTURE_ANALYSIS;
626
627   return layer_tree_impl()->tile_manager()->CreateTile(
628       pile_.get(),
629       content_rect.size(),
630       content_rect,
631       tiling->contents_scale(),
632       id(),
633       layer_tree_impl()->source_frame_number(),
634       flags);
635 }
636
637 PicturePileImpl* PictureLayerImpl::GetPile() {
638   return pile_.get();
639 }
640
641 const Region* PictureLayerImpl::GetInvalidation() {
642   return &invalidation_;
643 }
644
645 const PictureLayerTiling* PictureLayerImpl::GetTwinTiling(
646     const PictureLayerTiling* tiling) const {
647   if (!twin_layer_)
648     return NULL;
649   return twin_layer_->tilings_->TilingAtScale(tiling->contents_scale());
650 }
651
652 PictureLayerTiling* PictureLayerImpl::GetRecycledTwinTiling(
653     const PictureLayerTiling* tiling) {
654   PictureLayerImpl* recycled_twin = GetRecycledTwinLayer();
655   if (!recycled_twin || !recycled_twin->tilings_)
656     return NULL;
657   return recycled_twin->tilings_->TilingAtScale(tiling->contents_scale());
658 }
659
660 size_t PictureLayerImpl::GetMaxTilesForInterestArea() const {
661   return layer_tree_impl()->settings().max_tiles_for_interest_area;
662 }
663
664 float PictureLayerImpl::GetSkewportTargetTimeInSeconds() const {
665   float skewport_target_time_in_frames =
666       layer_tree_impl()->use_gpu_rasterization()
667           ? kGpuSkewportTargetTimeInFrames
668           : kCpuSkewportTargetTimeInFrames;
669   return skewport_target_time_in_frames *
670          layer_tree_impl()->begin_impl_frame_interval().InSecondsF() *
671          layer_tree_impl()->settings().skewport_target_time_multiplier;
672 }
673
674 int PictureLayerImpl::GetSkewportExtrapolationLimitInContentPixels() const {
675   return layer_tree_impl()
676       ->settings()
677       .skewport_extrapolation_limit_in_content_pixels;
678 }
679
680 gfx::Size PictureLayerImpl::CalculateTileSize(
681     const gfx::Size& content_bounds) const {
682   int max_texture_size =
683       layer_tree_impl()->resource_provider()->max_texture_size();
684
685   if (pile_->is_mask()) {
686     // Masks are not tiled, so if we can't cover the whole mask with one tile,
687     // don't make any tiles at all. Returning an empty size signals this.
688     if (content_bounds.width() > max_texture_size ||
689         content_bounds.height() > max_texture_size)
690       return gfx::Size();
691     return content_bounds;
692   }
693
694   gfx::Size default_tile_size = layer_tree_impl()->settings().default_tile_size;
695   if (layer_tree_impl()->use_gpu_rasterization()) {
696     // TODO(ernstm) crbug.com/365877: We need a unified way to override the
697     // default-tile-size.
698     default_tile_size =
699         gfx::Size(layer_tree_impl()->device_viewport_size().width(),
700                   layer_tree_impl()->device_viewport_size().height() / 4);
701   }
702   default_tile_size.SetToMin(gfx::Size(max_texture_size, max_texture_size));
703
704   gfx::Size max_untiled_content_size =
705       layer_tree_impl()->settings().max_untiled_layer_size;
706   max_untiled_content_size.SetToMin(
707       gfx::Size(max_texture_size, max_texture_size));
708
709   bool any_dimension_too_large =
710       content_bounds.width() > max_untiled_content_size.width() ||
711       content_bounds.height() > max_untiled_content_size.height();
712
713   bool any_dimension_one_tile =
714       content_bounds.width() <= default_tile_size.width() ||
715       content_bounds.height() <= default_tile_size.height();
716
717   // If long and skinny, tile at the max untiled content size, and clamp
718   // the smaller dimension to the content size, e.g. 1000x12 layer with
719   // 500x500 max untiled size would get 500x12 tiles.  Also do this
720   // if the layer is small.
721   if (any_dimension_one_tile || !any_dimension_too_large) {
722     int width = std::min(
723         std::max(max_untiled_content_size.width(), default_tile_size.width()),
724         content_bounds.width());
725     int height = std::min(
726         std::max(max_untiled_content_size.height(), default_tile_size.height()),
727         content_bounds.height());
728     // Round up to the closest multiple of 64. This improves recycling and
729     // avoids odd texture sizes.
730     width = RoundUp(width, 64);
731     height = RoundUp(height, 64);
732     return gfx::Size(width, height);
733   }
734
735   return default_tile_size;
736 }
737
738 void PictureLayerImpl::SyncFromActiveLayer(const PictureLayerImpl* other) {
739   TRACE_EVENT0("cc", "SyncFromActiveLayer");
740   DCHECK(!other->needs_post_commit_initialization_);
741   DCHECK(other->tilings_);
742
743   if (!DrawsContent()) {
744     RemoveAllTilings();
745     return;
746   }
747
748   raster_page_scale_ = other->raster_page_scale_;
749   raster_device_scale_ = other->raster_device_scale_;
750   raster_source_scale_ = other->raster_source_scale_;
751   raster_contents_scale_ = other->raster_contents_scale_;
752   low_res_raster_contents_scale_ = other->low_res_raster_contents_scale_;
753
754   bool synced_high_res_tiling = false;
755   if (CanHaveTilings()) {
756     synced_high_res_tiling = tilings_->SyncTilings(
757         *other->tilings_, bounds(), invalidation_, MinimumContentsScale());
758   } else {
759     RemoveAllTilings();
760   }
761
762   // If our MinimumContentsScale has changed to prevent the twin's high res
763   // tiling from being synced, we should reset the raster scale and let it be
764   // recalculated (1) again. This can happen if our bounds shrink to the point
765   // where min contents scale grows.
766   // (1) - TODO(vmpstr) Instead of hoping that this will be recalculated, we
767   // should refactor this code a little bit and actually recalculate this.
768   // However, this is a larger undertaking, so this will work for now.
769   if (!synced_high_res_tiling)
770     ResetRasterScale();
771   else
772     SanityCheckTilingState();
773 }
774
775 void PictureLayerImpl::SyncTiling(
776     const PictureLayerTiling* tiling) {
777   if (!CanHaveTilingWithScale(tiling->contents_scale()))
778     return;
779   tilings_->AddTiling(tiling->contents_scale());
780
781   // If this tree needs update draw properties, then the tiling will
782   // get updated prior to drawing or activation.  If this tree does not
783   // need update draw properties, then its transforms are up to date and
784   // we can create tiles for this tiling immediately.
785   if (!layer_tree_impl()->needs_update_draw_properties() &&
786       should_update_tile_priorities_) {
787     // TODO(danakj): Add a DCHECK() that we are not using occlusion tracking
788     // when we stop using the pending tree in the browser compositor. If we want
789     // to support occlusion tracking here, we need to dirty the draw properties
790     // or save occlusion as a draw property.
791     UpdateTilePriorities(Occlusion());
792   }
793 }
794
795 ResourceProvider::ResourceId PictureLayerImpl::ContentsResourceId() const {
796   gfx::Rect content_rect(content_bounds());
797   PictureLayerTilingSet::CoverageIterator iter(
798       tilings_.get(), 1.f, content_rect, ideal_contents_scale_);
799
800   // Mask resource not ready yet.
801   if (!iter || !*iter)
802     return 0;
803
804   // Masks only supported if they fit on exactly one tile.
805   DCHECK(iter.geometry_rect() == content_rect)
806       << "iter rect " << iter.geometry_rect().ToString() << " content rect "
807       << content_rect.ToString();
808
809   const ManagedTileState::TileVersion& tile_version =
810       iter->GetTileVersionForDrawing();
811   if (!tile_version.IsReadyToDraw() ||
812       tile_version.mode() != ManagedTileState::TileVersion::RESOURCE_MODE)
813     return 0;
814
815   return tile_version.get_resource_id();
816 }
817
818 void PictureLayerImpl::MarkVisibleResourcesAsRequired() const {
819   DCHECK(layer_tree_impl()->IsPendingTree());
820   DCHECK(ideal_contents_scale_);
821   DCHECK_GT(tilings_->num_tilings(), 0u);
822
823   // The goal of this function is to find the minimum set of tiles that need to
824   // be ready to draw in order to activate without flashing content from a
825   // higher res on the active tree to a lower res on the pending tree.
826
827   // First, early out for layers with no visible content.
828   if (visible_rect_for_tile_priority_.IsEmpty())
829     return;
830
831   // Only mark tiles inside the viewport for tile priority as required for
832   // activation. This viewport is normally the same as the draw viewport but
833   // can be independently overridden by embedders like Android WebView with
834   // SetExternalDrawConstraints.
835   gfx::Rect rect = GetViewportForTilePriorityInContentSpace();
836   rect.Intersect(visible_rect_for_tile_priority_);
837
838   float min_acceptable_scale =
839       std::min(raster_contents_scale_, ideal_contents_scale_);
840
841   if (PictureLayerImpl* twin = twin_layer_) {
842     float twin_min_acceptable_scale =
843         std::min(twin->ideal_contents_scale_, twin->raster_contents_scale_);
844     // Ignore 0 scale in case CalculateContentsScale() has never been
845     // called for active twin.
846     if (twin_min_acceptable_scale != 0.0f) {
847       min_acceptable_scale =
848           std::min(min_acceptable_scale, twin_min_acceptable_scale);
849     }
850   }
851
852   PictureLayerTiling* high_res = NULL;
853   PictureLayerTiling* low_res = NULL;
854
855   // First pass: ready to draw tiles in acceptable but non-ideal tilings are
856   // marked as required for activation so that their textures are not thrown
857   // away; any non-ready tiles are not marked as required.
858   Region missing_region = rect;
859   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
860     PictureLayerTiling* tiling = tilings_->tiling_at(i);
861     DCHECK(tiling->has_ever_been_updated());
862
863     if (tiling->resolution() == LOW_RESOLUTION) {
864       DCHECK(!low_res) << "There can only be one low res tiling";
865       low_res = tiling;
866     }
867     if (tiling->contents_scale() < min_acceptable_scale)
868       continue;
869     if (tiling->resolution() == HIGH_RESOLUTION) {
870       DCHECK(!high_res) << "There can only be one high res tiling";
871       high_res = tiling;
872       continue;
873     }
874     for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f, rect); iter;
875          ++iter) {
876       if (!*iter || !iter->IsReadyToDraw())
877         continue;
878
879       missing_region.Subtract(iter.geometry_rect());
880       iter->MarkRequiredForActivation();
881     }
882   }
883   DCHECK(high_res) << "There must be one high res tiling";
884
885   // If these pointers are null (because no twin, no matching tiling, or the
886   // simpification just below), then high res tiles will be required to fill any
887   // holes left by the first pass above.  If the pointers are valid, then this
888   // layer is allowed to skip any tiles that are not ready on its twin.
889   const PictureLayerTiling* twin_high_res = NULL;
890   const PictureLayerTiling* twin_low_res = NULL;
891
892   if (twin_layer_) {
893     // As a simplification, only allow activating to skip twin tiles that the
894     // active layer is also missing when both this layer and its twin have
895     // "simple" sets of tilings: only 2 tilings (high and low) or only 1 high
896     // res tiling. This avoids having to iterate/track coverage of non-ideal
897     // tilings during the last draw call on the active layer.
898     if (tilings_->num_tilings() <= 2 &&
899         twin_layer_->tilings_->num_tilings() <= tilings_->num_tilings()) {
900       twin_low_res = low_res ? GetTwinTiling(low_res) : NULL;
901       twin_high_res = high_res ? GetTwinTiling(high_res) : NULL;
902     }
903
904     // If this layer and its twin have different transforms, then don't compare
905     // them and only allow activating to high res tiles, since tiles on each
906     // layer will be in different places on screen.
907     if (twin_layer_->layer_tree_impl()->RequiresHighResToDraw() ||
908         bounds() != twin_layer_->bounds() ||
909         draw_properties().screen_space_transform !=
910             twin_layer_->draw_properties().screen_space_transform) {
911       twin_high_res = NULL;
912       twin_low_res = NULL;
913     }
914   }
915
916   // As a second pass, mark as required any visible high res tiles not filled in
917   // by acceptable non-ideal tiles from the first pass.
918   if (MarkVisibleTilesAsRequired(
919           high_res, twin_high_res, rect, missing_region)) {
920     // As an optional third pass, if a high res tile was skipped because its
921     // twin was also missing, then fall back to mark low res tiles as required
922     // in case the active twin is substituting those for missing high res
923     // content. Only suitable, when low res is enabled.
924     if (low_res) {
925       MarkVisibleTilesAsRequired(low_res, twin_low_res, rect, missing_region);
926     }
927   }
928 }
929
930 bool PictureLayerImpl::MarkVisibleTilesAsRequired(
931     PictureLayerTiling* tiling,
932     const PictureLayerTiling* optional_twin_tiling,
933     const gfx::Rect& rect,
934     const Region& missing_region) const {
935   bool twin_had_missing_tile = false;
936   for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f, rect); iter;
937        ++iter) {
938     Tile* tile = *iter;
939     // A null tile (i.e. missing recording) can just be skipped.
940     if (!tile)
941       continue;
942
943     // If the tile is occluded, don't mark it as required for activation.
944     if (tile->is_occluded(PENDING_TREE))
945       continue;
946
947     // If the missing region doesn't cover it, this tile is fully
948     // covered by acceptable tiles at other scales.
949     if (!missing_region.Intersects(iter.geometry_rect()))
950       continue;
951
952     // If the twin tile doesn't exist (i.e. missing recording or so far away
953     // that it is outside the visible tile rect) or this tile is shared between
954     // with the twin, then this tile isn't required to prevent flashing.
955     if (optional_twin_tiling) {
956       Tile* twin_tile = optional_twin_tiling->TileAt(iter.i(), iter.j());
957       if (!twin_tile || twin_tile == tile) {
958         // However if the shared tile is being used on the active tree, then
959         // there's no missing content in this place, and low res is not needed.
960         if (!twin_tile || !twin_tile->IsReadyToDraw())
961           twin_had_missing_tile = true;
962         continue;
963       }
964     }
965
966     tile->MarkRequiredForActivation();
967   }
968   return twin_had_missing_tile;
969 }
970
971 void PictureLayerImpl::DoPostCommitInitialization() {
972   DCHECK(needs_post_commit_initialization_);
973   DCHECK(layer_tree_impl()->IsPendingTree());
974
975   if (!tilings_)
976     tilings_.reset(new PictureLayerTilingSet(this, bounds()));
977
978   DCHECK(!twin_layer_);
979   twin_layer_ = static_cast<PictureLayerImpl*>(
980       layer_tree_impl()->FindActiveTreeLayerById(id()));
981   if (twin_layer_) {
982     DCHECK(!twin_layer_->twin_layer_);
983     twin_layer_->twin_layer_ = this;
984     // If the twin has never been pushed to, do not sync from it.
985     // This can happen if this function is called during activation.
986     if (!twin_layer_->needs_post_commit_initialization_)
987       SyncFromActiveLayer(twin_layer_);
988   }
989
990   needs_post_commit_initialization_ = false;
991 }
992
993 PictureLayerTiling* PictureLayerImpl::AddTiling(float contents_scale) {
994   DCHECK(CanHaveTilingWithScale(contents_scale)) <<
995       "contents_scale: " << contents_scale;
996
997   PictureLayerTiling* tiling = tilings_->AddTiling(contents_scale);
998
999   DCHECK(pile_->HasRecordings());
1000
1001   if (twin_layer_)
1002     twin_layer_->SyncTiling(tiling);
1003
1004   return tiling;
1005 }
1006
1007 void PictureLayerImpl::RemoveTiling(float contents_scale) {
1008   if (!tilings_ || tilings_->num_tilings() == 0)
1009     return;
1010
1011   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
1012     PictureLayerTiling* tiling = tilings_->tiling_at(i);
1013     if (tiling->contents_scale() == contents_scale) {
1014       tilings_->Remove(tiling);
1015       break;
1016     }
1017   }
1018   if (tilings_->num_tilings() == 0)
1019     ResetRasterScale();
1020   SanityCheckTilingState();
1021 }
1022
1023 void PictureLayerImpl::RemoveAllTilings() {
1024   if (tilings_)
1025     tilings_->RemoveAllTilings();
1026   // If there are no tilings, then raster scales are no longer meaningful.
1027   ResetRasterScale();
1028 }
1029
1030 namespace {
1031
1032 inline float PositiveRatio(float float1, float float2) {
1033   DCHECK_GT(float1, 0);
1034   DCHECK_GT(float2, 0);
1035   return float1 > float2 ? float1 / float2 : float2 / float1;
1036 }
1037
1038 }  // namespace
1039
1040 void PictureLayerImpl::AddTilingsForRasterScale() {
1041   PictureLayerTiling* high_res = NULL;
1042   PictureLayerTiling* low_res = NULL;
1043
1044   PictureLayerTiling* previous_low_res = NULL;
1045   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
1046     PictureLayerTiling* tiling = tilings_->tiling_at(i);
1047     if (tiling->contents_scale() == raster_contents_scale_)
1048       high_res = tiling;
1049     if (tiling->contents_scale() == low_res_raster_contents_scale_)
1050       low_res = tiling;
1051     if (tiling->resolution() == LOW_RESOLUTION)
1052       previous_low_res = tiling;
1053
1054     // Reset all tilings to non-ideal until the end of this function.
1055     tiling->set_resolution(NON_IDEAL_RESOLUTION);
1056   }
1057
1058   if (!high_res) {
1059     high_res = AddTiling(raster_contents_scale_);
1060     if (raster_contents_scale_ == low_res_raster_contents_scale_)
1061       low_res = high_res;
1062   }
1063
1064   // Only create new low res tilings when the transform is static.  This
1065   // prevents wastefully creating a paired low res tiling for every new high res
1066   // tiling during a pinch or a CSS animation.
1067   bool is_pinching = layer_tree_impl()->PinchGestureActive();
1068   if (layer_tree_impl()->create_low_res_tiling() && !is_pinching &&
1069       !draw_properties().screen_space_transform_is_animating && !low_res &&
1070       low_res != high_res)
1071     low_res = AddTiling(low_res_raster_contents_scale_);
1072
1073   // Set low-res if we have one.
1074   if (!low_res)
1075     low_res = previous_low_res;
1076   if (low_res && low_res != high_res)
1077     low_res->set_resolution(LOW_RESOLUTION);
1078
1079   // Make sure we always have one high-res (even if high == low).
1080   high_res->set_resolution(HIGH_RESOLUTION);
1081
1082   SanityCheckTilingState();
1083 }
1084
1085 bool PictureLayerImpl::ShouldAdjustRasterScale() const {
1086   if (was_screen_space_transform_animating_ !=
1087       draw_properties().screen_space_transform_is_animating)
1088     return true;
1089
1090   if (draw_properties().screen_space_transform_is_animating &&
1091       raster_contents_scale_ != ideal_contents_scale_ &&
1092       ShouldAdjustRasterScaleDuringScaleAnimations())
1093     return true;
1094
1095   bool is_pinching = layer_tree_impl()->PinchGestureActive();
1096   if (is_pinching && raster_page_scale_) {
1097     // We change our raster scale when it is:
1098     // - Higher than ideal (need a lower-res tiling available)
1099     // - Too far from ideal (need a higher-res tiling available)
1100     float ratio = ideal_page_scale_ / raster_page_scale_;
1101     if (raster_page_scale_ > ideal_page_scale_ ||
1102         ratio > kMaxScaleRatioDuringPinch)
1103       return true;
1104   }
1105
1106   if (!is_pinching) {
1107     // When not pinching, match the ideal page scale factor.
1108     if (raster_page_scale_ != ideal_page_scale_)
1109       return true;
1110   }
1111
1112   // Always match the ideal device scale factor.
1113   if (raster_device_scale_ != ideal_device_scale_)
1114     return true;
1115
1116   // When the source scale changes we want to match it, but not when animating
1117   // or when we've fixed the scale in place.
1118   if (!draw_properties().screen_space_transform_is_animating &&
1119       !raster_source_scale_is_fixed_ &&
1120       raster_source_scale_ != ideal_source_scale_)
1121     return true;
1122
1123   return false;
1124 }
1125
1126 float PictureLayerImpl::SnappedContentsScale(float scale) {
1127   // If a tiling exists within the max snapping ratio, snap to its scale.
1128   float snapped_contents_scale = scale;
1129   float snapped_ratio = kSnapToExistingTilingRatio;
1130   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
1131     float tiling_contents_scale = tilings_->tiling_at(i)->contents_scale();
1132     float ratio = PositiveRatio(tiling_contents_scale, scale);
1133     if (ratio < snapped_ratio) {
1134       snapped_contents_scale = tiling_contents_scale;
1135       snapped_ratio = ratio;
1136     }
1137   }
1138   return snapped_contents_scale;
1139 }
1140
1141 void PictureLayerImpl::RecalculateRasterScales() {
1142   float old_raster_contents_scale = raster_contents_scale_;
1143   float old_raster_page_scale = raster_page_scale_;
1144   float old_raster_source_scale = raster_source_scale_;
1145
1146   raster_device_scale_ = ideal_device_scale_;
1147   raster_page_scale_ = ideal_page_scale_;
1148   raster_source_scale_ = ideal_source_scale_;
1149   raster_contents_scale_ = ideal_contents_scale_;
1150
1151   // If we're not animating, or leaving an animation, and the
1152   // ideal_source_scale_ changes, then things are unpredictable, and we fix
1153   // the raster_source_scale_ in place.
1154   if (old_raster_source_scale &&
1155       !draw_properties().screen_space_transform_is_animating &&
1156       !was_screen_space_transform_animating_ &&
1157       old_raster_source_scale != ideal_source_scale_)
1158     raster_source_scale_is_fixed_ = true;
1159
1160   // TODO(danakj): Adjust raster source scale closer to ideal source scale at
1161   // a throttled rate. Possibly make use of invalidation_.IsEmpty() on pending
1162   // tree. This will allow CSS scale changes to get re-rastered at an
1163   // appropriate rate. (crbug.com/413636)
1164   if (raster_source_scale_is_fixed_) {
1165     raster_contents_scale_ /= raster_source_scale_;
1166     raster_source_scale_ = 1.f;
1167   }
1168
1169   // During pinch we completely ignore the current ideal scale, and just use
1170   // a multiple of the previous scale.
1171   // TODO(danakj): This seems crazy, we should use the current ideal, no?
1172   bool is_pinching = layer_tree_impl()->PinchGestureActive();
1173   if (is_pinching && old_raster_contents_scale) {
1174     // See ShouldAdjustRasterScale:
1175     // - When zooming out, preemptively create new tiling at lower resolution.
1176     // - When zooming in, approximate ideal using multiple of kMaxScaleRatio.
1177     bool zooming_out = old_raster_page_scale > ideal_page_scale_;
1178     float desired_contents_scale =
1179         zooming_out ? old_raster_contents_scale / kMaxScaleRatioDuringPinch
1180                     : old_raster_contents_scale * kMaxScaleRatioDuringPinch;
1181     raster_contents_scale_ = SnappedContentsScale(desired_contents_scale);
1182     raster_page_scale_ =
1183         raster_contents_scale_ / raster_device_scale_ / raster_source_scale_;
1184   }
1185
1186   raster_contents_scale_ =
1187       std::max(raster_contents_scale_, MinimumContentsScale());
1188
1189   // If we're not re-rasterizing during animation, rasterize at the maximum
1190   // scale that will occur during the animation, if the maximum scale is
1191   // known. However we want to avoid excessive memory use. If the scale is
1192   // smaller than what we would choose otherwise, then it's always better off
1193   // for us memory-wise. But otherwise, we don't choose a scale at which this
1194   // layer's rastered content would become larger than the viewport.
1195   if (draw_properties().screen_space_transform_is_animating &&
1196       !ShouldAdjustRasterScaleDuringScaleAnimations()) {
1197     bool can_raster_at_maximum_scale = false;
1198     // TODO(ajuma): If we need to deal with scale-down animations starting right
1199     // as a layer gets promoted, then we'd want to have the
1200     // |starting_animation_contents_scale| passed in here as a separate draw
1201     // property so we could try use that when the max is too large.
1202     // See crbug.com/422341.
1203     float maximum_scale = draw_properties().maximum_animation_contents_scale;
1204     if (maximum_scale) {
1205       gfx::Size bounds_at_maximum_scale =
1206           gfx::ToCeiledSize(gfx::ScaleSize(bounds(), maximum_scale));
1207       if (bounds_at_maximum_scale.GetArea() <=
1208           layer_tree_impl()->device_viewport_size().GetArea())
1209         can_raster_at_maximum_scale = true;
1210     }
1211     // Use the computed scales for the raster scale directly, do not try to use
1212     // the ideal scale here. The current ideal scale may be way too large in the
1213     // case of an animation with scale, and will be constantly changing.
1214     if (can_raster_at_maximum_scale)
1215       raster_contents_scale_ = maximum_scale;
1216     else
1217       raster_contents_scale_ = 1.f * ideal_page_scale_ * ideal_device_scale_;
1218   }
1219
1220   // If this layer would create zero or one tiles at this content scale,
1221   // don't create a low res tiling.
1222   gfx::Size content_bounds =
1223       gfx::ToCeiledSize(gfx::ScaleSize(bounds(), raster_contents_scale_));
1224   gfx::Size tile_size = CalculateTileSize(content_bounds);
1225   bool tile_covers_bounds = tile_size.width() >= content_bounds.width() &&
1226                             tile_size.height() >= content_bounds.height();
1227   if (tile_size.IsEmpty() || tile_covers_bounds) {
1228     low_res_raster_contents_scale_ = raster_contents_scale_;
1229     return;
1230   }
1231
1232   float low_res_factor =
1233       layer_tree_impl()->settings().low_res_contents_scale_factor;
1234   low_res_raster_contents_scale_ = std::max(
1235       raster_contents_scale_ * low_res_factor,
1236       MinimumContentsScale());
1237 }
1238
1239 void PictureLayerImpl::CleanUpTilingsOnActiveLayer(
1240     std::vector<PictureLayerTiling*> used_tilings) {
1241   DCHECK(layer_tree_impl()->IsActiveTree());
1242   if (tilings_->num_tilings() == 0)
1243     return;
1244
1245   float min_acceptable_high_res_scale = std::min(
1246       raster_contents_scale_, ideal_contents_scale_);
1247   float max_acceptable_high_res_scale = std::max(
1248       raster_contents_scale_, ideal_contents_scale_);
1249   float twin_low_res_scale = 0.f;
1250
1251   PictureLayerImpl* twin = twin_layer_;
1252   if (twin && twin->CanHaveTilings()) {
1253     min_acceptable_high_res_scale = std::min(
1254         min_acceptable_high_res_scale,
1255         std::min(twin->raster_contents_scale_, twin->ideal_contents_scale_));
1256     max_acceptable_high_res_scale = std::max(
1257         max_acceptable_high_res_scale,
1258         std::max(twin->raster_contents_scale_, twin->ideal_contents_scale_));
1259
1260     for (size_t i = 0; i < twin->tilings_->num_tilings(); ++i) {
1261       PictureLayerTiling* tiling = twin->tilings_->tiling_at(i);
1262       if (tiling->resolution() == LOW_RESOLUTION)
1263         twin_low_res_scale = tiling->contents_scale();
1264     }
1265   }
1266
1267   std::vector<PictureLayerTiling*> to_remove;
1268   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
1269     PictureLayerTiling* tiling = tilings_->tiling_at(i);
1270
1271     // Keep multiple high resolution tilings even if not used to help
1272     // activate earlier at non-ideal resolutions.
1273     if (tiling->contents_scale() >= min_acceptable_high_res_scale &&
1274         tiling->contents_scale() <= max_acceptable_high_res_scale)
1275       continue;
1276
1277     // Keep low resolution tilings, if the layer should have them.
1278     if (layer_tree_impl()->create_low_res_tiling()) {
1279       if (tiling->resolution() == LOW_RESOLUTION ||
1280           tiling->contents_scale() == twin_low_res_scale)
1281         continue;
1282     }
1283
1284     // Don't remove tilings that are being used (and thus would cause a flash.)
1285     if (std::find(used_tilings.begin(), used_tilings.end(), tiling) !=
1286         used_tilings.end())
1287       continue;
1288
1289     to_remove.push_back(tiling);
1290   }
1291
1292   if (to_remove.empty())
1293     return;
1294
1295   PictureLayerImpl* recycled_twin = GetRecycledTwinLayer();
1296   // Remove tilings on this tree and the twin tree.
1297   for (size_t i = 0; i < to_remove.size(); ++i) {
1298     const PictureLayerTiling* twin_tiling = GetTwinTiling(to_remove[i]);
1299     // Only remove tilings from the twin layer if they have
1300     // NON_IDEAL_RESOLUTION.
1301     if (twin_tiling && twin_tiling->resolution() == NON_IDEAL_RESOLUTION)
1302       twin->RemoveTiling(to_remove[i]->contents_scale());
1303     // Remove the tiling from the recycle tree. Note that we ignore resolution,
1304     // since we don't need to maintain high/low res on the recycle tree.
1305     if (recycled_twin)
1306       recycled_twin->RemoveTiling(to_remove[i]->contents_scale());
1307     // TODO(enne): temporary sanity CHECK for http://crbug.com/358350
1308     CHECK_NE(HIGH_RESOLUTION, to_remove[i]->resolution());
1309     tilings_->Remove(to_remove[i]);
1310   }
1311
1312   DCHECK_GT(tilings_->num_tilings(), 0u);
1313   SanityCheckTilingState();
1314 }
1315
1316 float PictureLayerImpl::MinimumContentsScale() const {
1317   float setting_min = layer_tree_impl()->settings().minimum_contents_scale;
1318
1319   // If the contents scale is less than 1 / width (also for height),
1320   // then it will end up having less than one pixel of content in that
1321   // dimension.  Bump the minimum contents scale up in this case to prevent
1322   // this from happening.
1323   int min_dimension = std::min(bounds().width(), bounds().height());
1324   if (!min_dimension)
1325     return setting_min;
1326
1327   return std::max(1.f / min_dimension, setting_min);
1328 }
1329
1330 void PictureLayerImpl::ResetRasterScale() {
1331   raster_page_scale_ = 0.f;
1332   raster_device_scale_ = 0.f;
1333   raster_source_scale_ = 0.f;
1334   raster_contents_scale_ = 0.f;
1335   low_res_raster_contents_scale_ = 0.f;
1336   raster_source_scale_is_fixed_ = false;
1337
1338   // When raster scales aren't valid, don't update tile priorities until
1339   // this layer has been updated via UpdateDrawProperties.
1340   should_update_tile_priorities_ = false;
1341 }
1342
1343 bool PictureLayerImpl::CanHaveTilings() const {
1344   if (pile_->is_solid_color())
1345     return false;
1346   if (!DrawsContent())
1347     return false;
1348   if (!pile_->HasRecordings())
1349     return false;
1350   return true;
1351 }
1352
1353 bool PictureLayerImpl::CanHaveTilingWithScale(float contents_scale) const {
1354   if (!CanHaveTilings())
1355     return false;
1356   if (contents_scale < MinimumContentsScale())
1357     return false;
1358   return true;
1359 }
1360
1361 void PictureLayerImpl::SanityCheckTilingState() const {
1362 #if DCHECK_IS_ON
1363   // Recycle tree doesn't have any restrictions.
1364   if (layer_tree_impl()->IsRecycleTree())
1365     return;
1366
1367   if (!CanHaveTilings()) {
1368     DCHECK_EQ(0u, tilings_->num_tilings());
1369     return;
1370   }
1371   if (tilings_->num_tilings() == 0)
1372     return;
1373
1374   // MarkVisibleResourcesAsRequired depends on having exactly 1 high res
1375   // tiling to mark its tiles as being required for activation.
1376   DCHECK_EQ(1, tilings_->NumHighResTilings());
1377 #endif
1378 }
1379
1380 bool PictureLayerImpl::ShouldAdjustRasterScaleDuringScaleAnimations() const {
1381   if (!layer_tree_impl()->use_gpu_rasterization())
1382     return false;
1383
1384   // Re-rastering text at different scales using GPU rasterization causes
1385   // texture uploads for glyphs at each scale (see crbug.com/366225). To
1386   // workaround this performance issue, we don't re-rasterize layers with
1387   // text during scale animations.
1388   // TODO(ajuma): Remove this workaround once text can be efficiently
1389   // re-rastered at different scales (e.g. by using distance-field fonts).
1390   if (pile_->has_text())
1391     return false;
1392
1393   return true;
1394 }
1395
1396 float PictureLayerImpl::MaximumTilingContentsScale() const {
1397   float max_contents_scale = MinimumContentsScale();
1398   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
1399     const PictureLayerTiling* tiling = tilings_->tiling_at(i);
1400     max_contents_scale = std::max(max_contents_scale, tiling->contents_scale());
1401   }
1402   return max_contents_scale;
1403 }
1404
1405 void PictureLayerImpl::UpdateIdealScales() {
1406   DCHECK(CanHaveTilings());
1407
1408   float min_contents_scale = MinimumContentsScale();
1409   DCHECK_GT(min_contents_scale, 0.f);
1410   float min_page_scale = layer_tree_impl()->min_page_scale_factor();
1411   DCHECK_GT(min_page_scale, 0.f);
1412   float min_device_scale = 1.f;
1413   float min_source_scale =
1414       min_contents_scale / min_page_scale / min_device_scale;
1415
1416   float ideal_page_scale = draw_properties().page_scale_factor;
1417   float ideal_device_scale = draw_properties().device_scale_factor;
1418   float ideal_source_scale = draw_properties().ideal_contents_scale /
1419                              ideal_page_scale / ideal_device_scale;
1420   ideal_contents_scale_ =
1421       std::max(draw_properties().ideal_contents_scale, min_contents_scale);
1422   ideal_page_scale_ = draw_properties().page_scale_factor;
1423   ideal_device_scale_ = draw_properties().device_scale_factor;
1424   ideal_source_scale_ = std::max(ideal_source_scale, min_source_scale);
1425 }
1426
1427 void PictureLayerImpl::GetDebugBorderProperties(
1428     SkColor* color,
1429     float* width) const {
1430   *color = DebugColors::TiledContentLayerBorderColor();
1431   *width = DebugColors::TiledContentLayerBorderWidth(layer_tree_impl());
1432 }
1433
1434 void PictureLayerImpl::GetAllTilesForTracing(
1435     std::set<const Tile*>* tiles) const {
1436   if (!tilings_)
1437     return;
1438
1439   for (size_t i = 0; i < tilings_->num_tilings(); ++i)
1440     tilings_->tiling_at(i)->GetAllTilesForTracing(tiles);
1441 }
1442
1443 void PictureLayerImpl::AsValueInto(base::debug::TracedValue* state) const {
1444   const_cast<PictureLayerImpl*>(this)->DoPostCommitInitializationIfNeeded();
1445   LayerImpl::AsValueInto(state);
1446   state->SetDouble("ideal_contents_scale", ideal_contents_scale_);
1447   state->SetDouble("geometry_contents_scale", MaximumTilingContentsScale());
1448   state->BeginArray("tilings");
1449   tilings_->AsValueInto(state);
1450   state->EndArray();
1451
1452   state->BeginArray("tile_priority_rect");
1453   MathUtil::AddToTracedValue(GetViewportForTilePriorityInContentSpace(), state);
1454   state->EndArray();
1455
1456   state->BeginArray("visible_rect");
1457   MathUtil::AddToTracedValue(visible_content_rect(), state);
1458   state->EndArray();
1459
1460   state->BeginArray("pictures");
1461   pile_->AsValueInto(state);
1462   state->EndArray();
1463
1464   state->BeginArray("invalidation");
1465   invalidation_.AsValueInto(state);
1466   state->EndArray();
1467
1468   state->BeginArray("coverage_tiles");
1469   for (PictureLayerTilingSet::CoverageIterator iter(tilings_.get(),
1470                                                     1.f,
1471                                                     gfx::Rect(content_bounds()),
1472                                                     ideal_contents_scale_);
1473        iter;
1474        ++iter) {
1475     state->BeginDictionary();
1476
1477     state->BeginArray("geometry_rect");
1478     MathUtil::AddToTracedValue(iter.geometry_rect(), state);
1479     state->EndArray();
1480
1481     if (*iter)
1482       TracedValue::SetIDRef(*iter, state, "tile");
1483
1484     state->EndDictionary();
1485   }
1486   state->EndArray();
1487 }
1488
1489 size_t PictureLayerImpl::GPUMemoryUsageInBytes() const {
1490   const_cast<PictureLayerImpl*>(this)->DoPostCommitInitializationIfNeeded();
1491   return tilings_->GPUMemoryUsageInBytes();
1492 }
1493
1494 void PictureLayerImpl::RunMicroBenchmark(MicroBenchmarkImpl* benchmark) {
1495   benchmark->RunOnLayer(this);
1496 }
1497
1498 WhichTree PictureLayerImpl::GetTree() const {
1499   return layer_tree_impl()->IsActiveTree() ? ACTIVE_TREE : PENDING_TREE;
1500 }
1501
1502 bool PictureLayerImpl::IsOnActiveOrPendingTree() const {
1503   return !layer_tree_impl()->IsRecycleTree();
1504 }
1505
1506 bool PictureLayerImpl::HasValidTilePriorities() const {
1507   return IsOnActiveOrPendingTree() && IsDrawnRenderSurfaceLayerListMember();
1508 }
1509
1510 bool PictureLayerImpl::AllTilesRequiredForActivationAreReadyToDraw() const {
1511   if (!layer_tree_impl()->IsPendingTree())
1512     return true;
1513
1514   if (!HasValidTilePriorities())
1515     return true;
1516
1517   if (!tilings_)
1518     return true;
1519
1520   if (visible_rect_for_tile_priority_.IsEmpty())
1521     return true;
1522
1523   gfx::Rect rect = GetViewportForTilePriorityInContentSpace();
1524   rect.Intersect(visible_rect_for_tile_priority_);
1525
1526   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
1527     PictureLayerTiling* tiling = tilings_->tiling_at(i);
1528     if (tiling->resolution() != HIGH_RESOLUTION &&
1529         tiling->resolution() != LOW_RESOLUTION)
1530       continue;
1531
1532     for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f, rect); iter;
1533          ++iter) {
1534       const Tile* tile = *iter;
1535       // A null tile (i.e. missing recording) can just be skipped.
1536       if (!tile)
1537         continue;
1538
1539       if (tile->required_for_activation() && !tile->IsReadyToDraw())
1540         return false;
1541     }
1542   }
1543
1544   return true;
1545 }
1546
1547 PictureLayerImpl::LayerRasterTileIterator::LayerRasterTileIterator()
1548     : layer_(NULL), current_stage_(arraysize(stages_)) {
1549 }
1550
1551 PictureLayerImpl::LayerRasterTileIterator::LayerRasterTileIterator(
1552     PictureLayerImpl* layer,
1553     bool prioritize_low_res)
1554     : layer_(layer), current_stage_(0) {
1555   DCHECK(layer_);
1556
1557   // Early out if the layer has no tilings.
1558   if (!layer_->tilings_ || !layer_->tilings_->num_tilings()) {
1559     current_stage_ = arraysize(stages_);
1560     return;
1561   }
1562
1563   // Tiles without valid priority are treated as having lowest priority and
1564   // never considered for raster.
1565   if (!layer_->HasValidTilePriorities()) {
1566     current_stage_ = arraysize(stages_);
1567     return;
1568   }
1569
1570   WhichTree tree = layer_->GetTree();
1571
1572   // Find high and low res tilings and initialize the iterators.
1573   for (size_t i = 0; i < layer_->tilings_->num_tilings(); ++i) {
1574     PictureLayerTiling* tiling = layer_->tilings_->tiling_at(i);
1575     if (tiling->resolution() == HIGH_RESOLUTION) {
1576       iterators_[HIGH_RES] =
1577           PictureLayerTiling::TilingRasterTileIterator(tiling, tree);
1578     }
1579
1580     if (tiling->resolution() == LOW_RESOLUTION) {
1581       iterators_[LOW_RES] =
1582           PictureLayerTiling::TilingRasterTileIterator(tiling, tree);
1583     }
1584   }
1585
1586   if (prioritize_low_res) {
1587     stages_[0].iterator_type = LOW_RES;
1588     stages_[0].tile_type = TilePriority::NOW;
1589
1590     stages_[1].iterator_type = HIGH_RES;
1591     stages_[1].tile_type = TilePriority::NOW;
1592   } else {
1593     stages_[0].iterator_type = HIGH_RES;
1594     stages_[0].tile_type = TilePriority::NOW;
1595
1596     stages_[1].iterator_type = LOW_RES;
1597     stages_[1].tile_type = TilePriority::NOW;
1598   }
1599
1600   stages_[2].iterator_type = HIGH_RES;
1601   stages_[2].tile_type = TilePriority::SOON;
1602
1603   stages_[3].iterator_type = HIGH_RES;
1604   stages_[3].tile_type = TilePriority::EVENTUALLY;
1605
1606   IteratorType index = stages_[current_stage_].iterator_type;
1607   TilePriority::PriorityBin tile_type = stages_[current_stage_].tile_type;
1608   if (!iterators_[index] || iterators_[index].get_type() != tile_type)
1609     AdvanceToNextStage();
1610 }
1611
1612 PictureLayerImpl::LayerRasterTileIterator::~LayerRasterTileIterator() {}
1613
1614 PictureLayerImpl::LayerRasterTileIterator::operator bool() const {
1615   return current_stage_ < arraysize(stages_);
1616 }
1617
1618 PictureLayerImpl::LayerRasterTileIterator&
1619 PictureLayerImpl::LayerRasterTileIterator::
1620 operator++() {
1621   IteratorType index = stages_[current_stage_].iterator_type;
1622   TilePriority::PriorityBin tile_type = stages_[current_stage_].tile_type;
1623
1624   // First advance the iterator.
1625   DCHECK(iterators_[index]);
1626   DCHECK(iterators_[index].get_type() == tile_type);
1627   ++iterators_[index];
1628
1629   if (!iterators_[index] || iterators_[index].get_type() != tile_type)
1630     AdvanceToNextStage();
1631
1632   return *this;
1633 }
1634
1635 Tile* PictureLayerImpl::LayerRasterTileIterator::operator*() {
1636   DCHECK(*this);
1637
1638   IteratorType index = stages_[current_stage_].iterator_type;
1639   DCHECK(iterators_[index]);
1640   DCHECK(iterators_[index].get_type() == stages_[current_stage_].tile_type);
1641
1642   return *iterators_[index];
1643 }
1644
1645 const Tile* PictureLayerImpl::LayerRasterTileIterator::operator*() const {
1646   DCHECK(*this);
1647
1648   IteratorType index = stages_[current_stage_].iterator_type;
1649   DCHECK(iterators_[index]);
1650   DCHECK(iterators_[index].get_type() == stages_[current_stage_].tile_type);
1651
1652   return *iterators_[index];
1653 }
1654
1655 void PictureLayerImpl::LayerRasterTileIterator::AdvanceToNextStage() {
1656   DCHECK_LT(current_stage_, arraysize(stages_));
1657   ++current_stage_;
1658   while (current_stage_ < arraysize(stages_)) {
1659     IteratorType index = stages_[current_stage_].iterator_type;
1660     TilePriority::PriorityBin tile_type = stages_[current_stage_].tile_type;
1661
1662     if (iterators_[index] && iterators_[index].get_type() == tile_type)
1663       break;
1664     ++current_stage_;
1665   }
1666 }
1667
1668 PictureLayerImpl::LayerEvictionTileIterator::LayerEvictionTileIterator()
1669     : layer_(NULL),
1670       tree_priority_(SAME_PRIORITY_FOR_BOTH_TREES),
1671       current_category_(PictureLayerTiling::EVENTUALLY),
1672       current_tiling_range_type_(PictureLayerTilingSet::HIGHER_THAN_HIGH_RES),
1673       current_tiling_(0u) {
1674 }
1675
1676 PictureLayerImpl::LayerEvictionTileIterator::LayerEvictionTileIterator(
1677     PictureLayerImpl* layer,
1678     TreePriority tree_priority)
1679     : layer_(layer),
1680       tree_priority_(tree_priority),
1681       current_category_(PictureLayerTiling::EVENTUALLY),
1682       current_tiling_range_type_(PictureLayerTilingSet::HIGHER_THAN_HIGH_RES),
1683       current_tiling_(CurrentTilingRange().start - 1u) {
1684   // TODO(vmpstr): Once tile priorities are determined by the iterators, ensure
1685   // that layers that don't have valid tile priorities have lowest priorities so
1686   // they evict their tiles first (crbug.com/381704)
1687   DCHECK(layer_->tilings_);
1688   do {
1689     if (!AdvanceToNextTiling())
1690       break;
1691
1692     current_iterator_ = PictureLayerTiling::TilingEvictionTileIterator(
1693         layer_->tilings_->tiling_at(CurrentTilingIndex()),
1694         tree_priority,
1695         current_category_);
1696   } while (!current_iterator_);
1697 }
1698
1699 PictureLayerImpl::LayerEvictionTileIterator::~LayerEvictionTileIterator() {
1700 }
1701
1702 Tile* PictureLayerImpl::LayerEvictionTileIterator::operator*() {
1703   DCHECK(*this);
1704   return *current_iterator_;
1705 }
1706
1707 const Tile* PictureLayerImpl::LayerEvictionTileIterator::operator*() const {
1708   DCHECK(*this);
1709   return *current_iterator_;
1710 }
1711
1712 PictureLayerImpl::LayerEvictionTileIterator&
1713 PictureLayerImpl::LayerEvictionTileIterator::
1714 operator++() {
1715   DCHECK(*this);
1716   ++current_iterator_;
1717   while (!current_iterator_) {
1718     if (!AdvanceToNextTiling())
1719       break;
1720
1721     current_iterator_ = PictureLayerTiling::TilingEvictionTileIterator(
1722         layer_->tilings_->tiling_at(CurrentTilingIndex()),
1723         tree_priority_,
1724         current_category_);
1725   }
1726   return *this;
1727 }
1728
1729 PictureLayerImpl::LayerEvictionTileIterator::operator bool() const {
1730   return !!current_iterator_;
1731 }
1732
1733 bool PictureLayerImpl::LayerEvictionTileIterator::AdvanceToNextCategory() {
1734   switch (current_category_) {
1735     case PictureLayerTiling::EVENTUALLY:
1736       current_category_ =
1737           PictureLayerTiling::EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION;
1738       return true;
1739     case PictureLayerTiling::EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION:
1740       current_category_ = PictureLayerTiling::SOON;
1741       return true;
1742     case PictureLayerTiling::SOON:
1743       current_category_ = PictureLayerTiling::SOON_AND_REQUIRED_FOR_ACTIVATION;
1744       return true;
1745     case PictureLayerTiling::SOON_AND_REQUIRED_FOR_ACTIVATION:
1746       current_category_ = PictureLayerTiling::NOW;
1747       return true;
1748     case PictureLayerTiling::NOW:
1749       current_category_ = PictureLayerTiling::NOW_AND_REQUIRED_FOR_ACTIVATION;
1750       return true;
1751     case PictureLayerTiling::NOW_AND_REQUIRED_FOR_ACTIVATION:
1752       return false;
1753   }
1754   NOTREACHED();
1755   return false;
1756 }
1757
1758 bool
1759 PictureLayerImpl::LayerEvictionTileIterator::AdvanceToNextTilingRangeType() {
1760   switch (current_tiling_range_type_) {
1761     case PictureLayerTilingSet::HIGHER_THAN_HIGH_RES:
1762       current_tiling_range_type_ = PictureLayerTilingSet::LOWER_THAN_LOW_RES;
1763       return true;
1764     case PictureLayerTilingSet::LOWER_THAN_LOW_RES:
1765       current_tiling_range_type_ =
1766           PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES;
1767       return true;
1768     case PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES:
1769       current_tiling_range_type_ = PictureLayerTilingSet::LOW_RES;
1770       return true;
1771     case PictureLayerTilingSet::LOW_RES:
1772       current_tiling_range_type_ = PictureLayerTilingSet::HIGH_RES;
1773       return true;
1774     case PictureLayerTilingSet::HIGH_RES:
1775       if (!AdvanceToNextCategory())
1776         return false;
1777
1778       current_tiling_range_type_ = PictureLayerTilingSet::HIGHER_THAN_HIGH_RES;
1779       return true;
1780   }
1781   NOTREACHED();
1782   return false;
1783 }
1784
1785 bool PictureLayerImpl::LayerEvictionTileIterator::AdvanceToNextTiling() {
1786   DCHECK_NE(current_tiling_, CurrentTilingRange().end);
1787   ++current_tiling_;
1788   while (current_tiling_ == CurrentTilingRange().end) {
1789     if (!AdvanceToNextTilingRangeType())
1790       return false;
1791
1792     current_tiling_ = CurrentTilingRange().start;
1793   }
1794   return true;
1795 }
1796
1797 PictureLayerTilingSet::TilingRange
1798 PictureLayerImpl::LayerEvictionTileIterator::CurrentTilingRange() const {
1799   return layer_->tilings_->GetTilingRange(current_tiling_range_type_);
1800 }
1801
1802 size_t PictureLayerImpl::LayerEvictionTileIterator::CurrentTilingIndex() const {
1803   DCHECK_NE(current_tiling_, CurrentTilingRange().end);
1804   switch (current_tiling_range_type_) {
1805     case PictureLayerTilingSet::HIGHER_THAN_HIGH_RES:
1806     case PictureLayerTilingSet::LOW_RES:
1807     case PictureLayerTilingSet::HIGH_RES:
1808       return current_tiling_;
1809     // Tilings in the following ranges are accessed in reverse order.
1810     case PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES:
1811     case PictureLayerTilingSet::LOWER_THAN_LOW_RES: {
1812       PictureLayerTilingSet::TilingRange tiling_range = CurrentTilingRange();
1813       size_t current_tiling_range_offset = current_tiling_ - tiling_range.start;
1814       return tiling_range.end - 1 - current_tiling_range_offset;
1815     }
1816   }
1817   NOTREACHED();
1818   return 0;
1819 }
1820
1821 }  // namespace cc