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