Upstream version 5.34.92.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
10 #include "base/time/time.h"
11 #include "cc/base/math_util.h"
12 #include "cc/base/util.h"
13 #include "cc/debug/debug_colors.h"
14 #include "cc/debug/micro_benchmark_impl.h"
15 #include "cc/debug/traced_value.h"
16 #include "cc/layers/append_quads_data.h"
17 #include "cc/layers/quad_sink.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 "ui/gfx/quad_f.h"
26 #include "ui/gfx/rect_conversions.h"
27 #include "ui/gfx/size_conversions.h"
28
29 namespace {
30 const float kMaxScaleRatioDuringPinch = 2.0f;
31
32 // When creating a new tiling during pinch, snap to an existing
33 // tiling's scale if the desired scale is within this ratio.
34 const float kSnapToExistingTilingRatio = 0.2f;
35 }
36
37 namespace cc {
38
39 PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* tree_impl, int id)
40     : LayerImpl(tree_impl, id),
41       twin_layer_(NULL),
42       pile_(PicturePileImpl::Create()),
43       last_content_scale_(0),
44       is_mask_(false),
45       ideal_page_scale_(0.f),
46       ideal_device_scale_(0.f),
47       ideal_source_scale_(0.f),
48       ideal_contents_scale_(0.f),
49       raster_page_scale_(0.f),
50       raster_device_scale_(0.f),
51       raster_source_scale_(0.f),
52       raster_contents_scale_(0.f),
53       low_res_raster_contents_scale_(0.f),
54       raster_source_scale_was_animating_(false),
55       is_using_lcd_text_(tree_impl->settings().can_use_lcd_text),
56       needs_post_commit_initialization_(true),
57       should_update_tile_priorities_(false),
58       should_use_gpu_rasterization_(tree_impl->settings().gpu_rasterization) {}
59
60 PictureLayerImpl::~PictureLayerImpl() {}
61
62 const char* PictureLayerImpl::LayerTypeAsString() const {
63   return "cc::PictureLayerImpl";
64 }
65
66 scoped_ptr<LayerImpl> PictureLayerImpl::CreateLayerImpl(
67     LayerTreeImpl* tree_impl) {
68   return PictureLayerImpl::Create(tree_impl, id()).PassAs<LayerImpl>();
69 }
70
71 void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) {
72   // It's possible this layer was never drawn or updated (e.g. because it was
73   // a descendant of an opacity 0 layer).
74   DoPostCommitInitializationIfNeeded();
75   PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer);
76
77   // We have already synced the important bits from the the active layer, and
78   // we will soon swap out its tilings and use them for recycling. However,
79   // there are now tiles in this layer's tilings that were unref'd and replaced
80   // with new tiles (due to invalidation). This resets all active priorities on
81   // the to-be-recycled tiling to ensure replaced tiles don't linger and take
82   // memory (due to a stale 'active' priority).
83   if (layer_impl->tilings_)
84     layer_impl->tilings_->DidBecomeRecycled();
85
86   LayerImpl::PushPropertiesTo(base_layer);
87
88   // When the pending tree pushes to the active tree, the pending twin
89   // disappears.
90   layer_impl->twin_layer_ = NULL;
91   twin_layer_ = NULL;
92
93   layer_impl->SetIsMask(is_mask_);
94   layer_impl->pile_ = pile_;
95
96   // Tilings would be expensive to push, so we swap.  This optimization requires
97   // an extra invalidation in SyncFromActiveLayer.
98   layer_impl->tilings_.swap(tilings_);
99   layer_impl->tilings_->SetClient(layer_impl);
100   if (tilings_)
101     tilings_->SetClient(this);
102
103   layer_impl->raster_page_scale_ = raster_page_scale_;
104   layer_impl->raster_device_scale_ = raster_device_scale_;
105   layer_impl->raster_source_scale_ = raster_source_scale_;
106   layer_impl->raster_contents_scale_ = raster_contents_scale_;
107   layer_impl->low_res_raster_contents_scale_ = low_res_raster_contents_scale_;
108
109   layer_impl->UpdateLCDTextStatus(is_using_lcd_text_);
110   layer_impl->needs_post_commit_initialization_ = false;
111
112   // The invalidation on this soon-to-be-recycled layer must be cleared to
113   // mirror clearing the invalidation in PictureLayer's version of this function
114   // in case push properties is skipped.
115   layer_impl->invalidation_.Swap(&invalidation_);
116   invalidation_.Clear();
117   needs_post_commit_initialization_ = true;
118
119   // We always need to push properties.
120   // See http://crbug.com/303943
121   needs_push_properties_ = true;
122 }
123
124 void PictureLayerImpl::AppendQuads(QuadSink* quad_sink,
125                                    AppendQuadsData* append_quads_data) {
126   DCHECK(!needs_post_commit_initialization_);
127   gfx::Rect rect(visible_content_rect());
128   gfx::Rect content_rect(content_bounds());
129
130   SharedQuadState* shared_quad_state =
131       quad_sink->UseSharedQuadState(CreateSharedQuadState());
132
133   if (current_draw_mode_ == DRAW_MODE_RESOURCELESS_SOFTWARE) {
134     AppendDebugBorderQuad(
135         quad_sink,
136         shared_quad_state,
137         append_quads_data,
138         DebugColors::DirectPictureBorderColor(),
139         DebugColors::DirectPictureBorderWidth(layer_tree_impl()));
140
141     gfx::Rect geometry_rect = rect;
142     gfx::Rect opaque_rect = contents_opaque() ? geometry_rect : gfx::Rect();
143     gfx::Size texture_size = rect.size();
144     gfx::RectF texture_rect = gfx::RectF(texture_size);
145     gfx::Rect quad_content_rect = rect;
146     float contents_scale = contents_scale_x();
147
148     scoped_ptr<PictureDrawQuad> quad = PictureDrawQuad::Create();
149     quad->SetNew(shared_quad_state,
150                  geometry_rect,
151                  opaque_rect,
152                  texture_rect,
153                  texture_size,
154                  RGBA_8888,
155                  quad_content_rect,
156                  contents_scale,
157                  pile_);
158     if (quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data))
159       append_quads_data->num_missing_tiles++;
160     return;
161   }
162
163   AppendDebugBorderQuad(quad_sink, shared_quad_state, append_quads_data);
164
165   if (ShowDebugBorders()) {
166     for (PictureLayerTilingSet::CoverageIterator iter(
167         tilings_.get(), contents_scale_x(), rect, ideal_contents_scale_);
168          iter;
169          ++iter) {
170       SkColor color;
171       float width;
172       if (*iter && iter->IsReadyToDraw()) {
173         ManagedTileState::TileVersion::Mode mode =
174             iter->GetTileVersionForDrawing().mode();
175         if (mode == ManagedTileState::TileVersion::SOLID_COLOR_MODE) {
176           color = DebugColors::SolidColorTileBorderColor();
177           width = DebugColors::SolidColorTileBorderWidth(layer_tree_impl());
178         } else if (mode == ManagedTileState::TileVersion::PICTURE_PILE_MODE) {
179           color = DebugColors::PictureTileBorderColor();
180           width = DebugColors::PictureTileBorderWidth(layer_tree_impl());
181         } else if (iter->priority(ACTIVE_TREE).resolution == HIGH_RESOLUTION) {
182           color = DebugColors::HighResTileBorderColor();
183           width = DebugColors::HighResTileBorderWidth(layer_tree_impl());
184         } else if (iter->priority(ACTIVE_TREE).resolution == LOW_RESOLUTION) {
185           color = DebugColors::LowResTileBorderColor();
186           width = DebugColors::LowResTileBorderWidth(layer_tree_impl());
187         } else if (iter->contents_scale() > contents_scale_x()) {
188           color = DebugColors::ExtraHighResTileBorderColor();
189           width = DebugColors::ExtraHighResTileBorderWidth(layer_tree_impl());
190         } else {
191           color = DebugColors::ExtraLowResTileBorderColor();
192           width = DebugColors::ExtraLowResTileBorderWidth(layer_tree_impl());
193         }
194       } else {
195         color = DebugColors::MissingTileBorderColor();
196         width = DebugColors::MissingTileBorderWidth(layer_tree_impl());
197       }
198
199       scoped_ptr<DebugBorderDrawQuad> debug_border_quad =
200           DebugBorderDrawQuad::Create();
201       gfx::Rect geometry_rect = iter.geometry_rect();
202       debug_border_quad->SetNew(shared_quad_state, geometry_rect, color, width);
203       quad_sink->Append(debug_border_quad.PassAs<DrawQuad>(),
204                         append_quads_data);
205     }
206   }
207
208   // Keep track of the tilings that were used so that tilings that are
209   // unused can be considered for removal.
210   std::vector<PictureLayerTiling*> seen_tilings;
211
212   for (PictureLayerTilingSet::CoverageIterator iter(
213       tilings_.get(), contents_scale_x(), rect, ideal_contents_scale_);
214        iter;
215        ++iter) {
216     gfx::Rect geometry_rect = iter.geometry_rect();
217     if (!*iter || !iter->IsReadyToDraw()) {
218       if (DrawCheckerboardForMissingTiles()) {
219         // TODO(enne): Figure out how to show debug "invalidated checker" color
220         scoped_ptr<CheckerboardDrawQuad> quad = CheckerboardDrawQuad::Create();
221         SkColor color = DebugColors::DefaultCheckerboardColor();
222         quad->SetNew(shared_quad_state, geometry_rect, color);
223         if (quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data))
224           append_quads_data->num_missing_tiles++;
225       } else {
226         SkColor color = SafeOpaqueBackgroundColor();
227         scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create();
228         quad->SetNew(shared_quad_state, geometry_rect, color, false);
229         if (quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data))
230           append_quads_data->num_missing_tiles++;
231       }
232
233       append_quads_data->had_incomplete_tile = true;
234       continue;
235     }
236
237     const ManagedTileState::TileVersion& tile_version =
238         iter->GetTileVersionForDrawing();
239     scoped_ptr<DrawQuad> draw_quad;
240     switch (tile_version.mode()) {
241       case ManagedTileState::TileVersion::RESOURCE_MODE: {
242         gfx::RectF texture_rect = iter.texture_rect();
243         gfx::Rect opaque_rect = iter->opaque_rect();
244         opaque_rect.Intersect(geometry_rect);
245
246         if (iter->contents_scale() != ideal_contents_scale_)
247           append_quads_data->had_incomplete_tile = true;
248
249         scoped_ptr<TileDrawQuad> quad = TileDrawQuad::Create();
250         quad->SetNew(shared_quad_state,
251                      geometry_rect,
252                      opaque_rect,
253                      tile_version.get_resource_id(),
254                      texture_rect,
255                      iter.texture_size(),
256                      tile_version.contents_swizzled());
257         draw_quad = quad.PassAs<DrawQuad>();
258         break;
259       }
260       case ManagedTileState::TileVersion::PICTURE_PILE_MODE: {
261         gfx::RectF texture_rect = iter.texture_rect();
262         gfx::Rect opaque_rect = iter->opaque_rect();
263         opaque_rect.Intersect(geometry_rect);
264
265         ResourceProvider* resource_provider =
266             layer_tree_impl()->resource_provider();
267         ResourceFormat format =
268             resource_provider->memory_efficient_texture_format();
269         scoped_ptr<PictureDrawQuad> quad = PictureDrawQuad::Create();
270         quad->SetNew(shared_quad_state,
271                      geometry_rect,
272                      opaque_rect,
273                      texture_rect,
274                      iter.texture_size(),
275                      format,
276                      iter->content_rect(),
277                      iter->contents_scale(),
278                      pile_);
279         draw_quad = quad.PassAs<DrawQuad>();
280         break;
281       }
282       case ManagedTileState::TileVersion::SOLID_COLOR_MODE: {
283         scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create();
284         quad->SetNew(shared_quad_state,
285                      geometry_rect,
286                      tile_version.get_solid_color(),
287                      false);
288         draw_quad = quad.PassAs<DrawQuad>();
289         break;
290       }
291     }
292
293     DCHECK(draw_quad);
294     quad_sink->Append(draw_quad.Pass(), append_quads_data);
295
296     if (seen_tilings.empty() || seen_tilings.back() != iter.CurrentTiling())
297       seen_tilings.push_back(iter.CurrentTiling());
298   }
299
300   // Aggressively remove any tilings that are not seen to save memory. Note
301   // that this is at the expense of doing cause more frequent re-painting. A
302   // better scheme would be to maintain a tighter visible_content_rect for the
303   // finer tilings.
304   CleanUpTilingsOnActiveLayer(seen_tilings);
305 }
306
307 void PictureLayerImpl::UpdateTilePriorities() {
308   DCHECK(!needs_post_commit_initialization_);
309   CHECK(should_update_tile_priorities_);
310
311   if (!layer_tree_impl()->device_viewport_valid_for_tile_management()) {
312     for (size_t i = 0; i < tilings_->num_tilings(); ++i)
313       DCHECK(tilings_->tiling_at(i)->has_ever_been_updated());
314     return;
315   }
316
317   if (!tilings_->num_tilings())
318     return;
319
320   double current_frame_time_in_seconds =
321       (layer_tree_impl()->CurrentFrameTimeTicks() -
322        base::TimeTicks()).InSecondsF();
323
324   bool tiling_needs_update = false;
325   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
326     if (tilings_->tiling_at(i)->NeedsUpdateForFrameAtTime(
327             current_frame_time_in_seconds)) {
328       tiling_needs_update = true;
329       break;
330     }
331   }
332   if (!tiling_needs_update)
333     return;
334
335   UpdateLCDTextStatus(can_use_lcd_text());
336
337   gfx::Transform current_screen_space_transform = screen_space_transform();
338
339   gfx::Size viewport_size = layer_tree_impl()->DrawViewportSize();
340   gfx::Rect viewport_in_content_space;
341   gfx::Transform screen_to_layer(gfx::Transform::kSkipInitialization);
342   if (screen_space_transform().GetInverse(&screen_to_layer)) {
343     viewport_in_content_space =
344         gfx::ToEnclosingRect(MathUtil::ProjectClippedRect(
345             screen_to_layer, gfx::Rect(viewport_size)));
346   }
347
348   WhichTree tree =
349       layer_tree_impl()->IsActiveTree() ? ACTIVE_TREE : PENDING_TREE;
350   size_t max_tiles_for_interest_area =
351       layer_tree_impl()->settings().max_tiles_for_interest_area;
352   tilings_->UpdateTilePriorities(
353       tree,
354       viewport_size,
355       viewport_in_content_space,
356       visible_content_rect(),
357       last_bounds_,
358       bounds(),
359       last_content_scale_,
360       contents_scale_x(),
361       last_screen_space_transform_,
362       current_screen_space_transform,
363       current_frame_time_in_seconds,
364       max_tiles_for_interest_area);
365
366   if (layer_tree_impl()->IsPendingTree())
367     MarkVisibleResourcesAsRequired();
368
369   last_screen_space_transform_ = current_screen_space_transform;
370   last_bounds_ = bounds();
371   last_content_scale_ = contents_scale_x();
372
373   // Tile priorities were modified.
374   layer_tree_impl()->DidModifyTilePriorities();
375 }
376
377 void PictureLayerImpl::DidBecomeActive() {
378   LayerImpl::DidBecomeActive();
379   tilings_->DidBecomeActive();
380   layer_tree_impl()->DidModifyTilePriorities();
381 }
382
383 void PictureLayerImpl::DidBeginTracing() {
384   pile_->DidBeginTracing();
385 }
386
387 void PictureLayerImpl::ReleaseResources() {
388   if (tilings_)
389     RemoveAllTilings();
390
391   ResetRasterScale();
392 }
393
394 void PictureLayerImpl::CalculateContentsScale(
395     float ideal_contents_scale,
396     float device_scale_factor,
397     float page_scale_factor,
398     bool animating_transform_to_screen,
399     float* contents_scale_x,
400     float* contents_scale_y,
401     gfx::Size* content_bounds) {
402   DoPostCommitInitializationIfNeeded();
403
404   // This function sets valid raster scales and manages tilings, so tile
405   // priorities can now be updated.
406   should_update_tile_priorities_ = true;
407
408   if (!CanHaveTilings()) {
409     ideal_page_scale_ = page_scale_factor;
410     ideal_device_scale_ = device_scale_factor;
411     ideal_contents_scale_ = ideal_contents_scale;
412     ideal_source_scale_ =
413         ideal_contents_scale_ / ideal_page_scale_ / ideal_device_scale_;
414     *contents_scale_x = ideal_contents_scale_;
415     *contents_scale_y = ideal_contents_scale_;
416     *content_bounds = gfx::ToCeiledSize(gfx::ScaleSize(bounds(),
417                                                        ideal_contents_scale_,
418                                                        ideal_contents_scale_));
419     return;
420   }
421
422   float min_contents_scale = MinimumContentsScale();
423   DCHECK_GT(min_contents_scale, 0.f);
424   float min_page_scale = layer_tree_impl()->min_page_scale_factor();
425   DCHECK_GT(min_page_scale, 0.f);
426   float min_device_scale = 1.f;
427   float min_source_scale =
428       min_contents_scale / min_page_scale / min_device_scale;
429
430   float ideal_page_scale = page_scale_factor;
431   float ideal_device_scale = device_scale_factor;
432   float ideal_source_scale =
433       ideal_contents_scale / ideal_page_scale / ideal_device_scale;
434
435   ideal_contents_scale_ = std::max(ideal_contents_scale, min_contents_scale);
436   ideal_page_scale_ = ideal_page_scale;
437   ideal_device_scale_ = ideal_device_scale;
438   ideal_source_scale_ = std::max(ideal_source_scale, min_source_scale);
439
440   ManageTilings(animating_transform_to_screen);
441
442   // The content scale and bounds for a PictureLayerImpl is somewhat fictitious.
443   // There are (usually) several tilings at different scales.  However, the
444   // content bounds is the (integer!) space in which quads are generated.
445   // In order to guarantee that we can fill this integer space with any set of
446   // tilings (and then map back to floating point texture coordinates), the
447   // contents scale must be at least as large as the largest of the tilings.
448   float max_contents_scale = min_contents_scale;
449   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
450     const PictureLayerTiling* tiling = tilings_->tiling_at(i);
451     max_contents_scale = std::max(max_contents_scale, tiling->contents_scale());
452   }
453
454   *contents_scale_x = max_contents_scale;
455   *contents_scale_y = max_contents_scale;
456   *content_bounds = gfx::ToCeiledSize(
457       gfx::ScaleSize(bounds(), max_contents_scale, max_contents_scale));
458 }
459
460 skia::RefPtr<SkPicture> PictureLayerImpl::GetPicture() {
461   return pile_->GetFlattenedPicture();
462 }
463
464 void PictureLayerImpl::SetShouldUseGpuRasterization(
465     bool should_use_gpu_rasterization) {
466   if (should_use_gpu_rasterization != should_use_gpu_rasterization_) {
467     should_use_gpu_rasterization_ = should_use_gpu_rasterization;
468     RemoveAllTilings();
469   } else {
470     should_use_gpu_rasterization_ = should_use_gpu_rasterization;
471   }
472 }
473
474 scoped_refptr<Tile> PictureLayerImpl::CreateTile(PictureLayerTiling* tiling,
475                                                const gfx::Rect& content_rect) {
476   if (!pile_->CanRaster(tiling->contents_scale(), content_rect))
477     return scoped_refptr<Tile>();
478
479   int flags = 0;
480   if (is_using_lcd_text_)
481     flags |= Tile::USE_LCD_TEXT;
482   if (should_use_gpu_rasterization())
483     flags |= Tile::USE_GPU_RASTERIZATION;
484   return layer_tree_impl()->tile_manager()->CreateTile(
485       pile_.get(),
486       content_rect.size(),
487       content_rect,
488       contents_opaque() ? content_rect : gfx::Rect(),
489       tiling->contents_scale(),
490       id(),
491       layer_tree_impl()->source_frame_number(),
492       flags);
493 }
494
495 void PictureLayerImpl::UpdatePile(Tile* tile) {
496   tile->set_picture_pile(pile_);
497 }
498
499 const Region* PictureLayerImpl::GetInvalidation() {
500   return &invalidation_;
501 }
502
503 const PictureLayerTiling* PictureLayerImpl::GetTwinTiling(
504     const PictureLayerTiling* tiling) const {
505
506   if (!twin_layer_ || twin_layer_->should_use_gpu_rasterization() !=
507       should_use_gpu_rasterization())
508     return NULL;
509   for (size_t i = 0; i < twin_layer_->tilings_->num_tilings(); ++i)
510     if (twin_layer_->tilings_->tiling_at(i)->contents_scale() ==
511         tiling->contents_scale())
512       return twin_layer_->tilings_->tiling_at(i);
513   return NULL;
514 }
515
516 gfx::Size PictureLayerImpl::CalculateTileSize(
517     gfx::Size content_bounds) const {
518   if (is_mask_) {
519     int max_size = layer_tree_impl()->MaxTextureSize();
520     return gfx::Size(
521         std::min(max_size, content_bounds.width()),
522         std::min(max_size, content_bounds.height()));
523   }
524
525   int max_texture_size =
526       layer_tree_impl()->resource_provider()->max_texture_size();
527
528   gfx::Size default_tile_size = layer_tree_impl()->settings().default_tile_size;
529   default_tile_size.SetToMin(gfx::Size(max_texture_size, max_texture_size));
530
531   gfx::Size max_untiled_content_size =
532       layer_tree_impl()->settings().max_untiled_layer_size;
533   max_untiled_content_size.SetToMin(
534       gfx::Size(max_texture_size, max_texture_size));
535
536   bool any_dimension_too_large =
537       content_bounds.width() > max_untiled_content_size.width() ||
538       content_bounds.height() > max_untiled_content_size.height();
539
540   bool any_dimension_one_tile =
541       content_bounds.width() <= default_tile_size.width() ||
542       content_bounds.height() <= default_tile_size.height();
543
544   // If long and skinny, tile at the max untiled content size, and clamp
545   // the smaller dimension to the content size, e.g. 1000x12 layer with
546   // 500x500 max untiled size would get 500x12 tiles.  Also do this
547   // if the layer is small.
548   if (any_dimension_one_tile || !any_dimension_too_large) {
549     int width =
550         std::min(max_untiled_content_size.width(), content_bounds.width());
551     int height =
552         std::min(max_untiled_content_size.height(), content_bounds.height());
553     // Round width and height up to the closest multiple of 64, or 56 if
554     // we should avoid power-of-two textures. This helps reduce the number
555     // of different textures sizes to help recycling, and also keeps all
556     // textures multiple-of-eight, which is preferred on some drivers (IMG).
557     bool avoid_pow2 =
558         layer_tree_impl()->GetRendererCapabilities().avoid_pow2_textures;
559     int round_up_to = avoid_pow2 ? 56 : 64;
560     width = RoundUp(width, round_up_to);
561     height = RoundUp(height, round_up_to);
562     return gfx::Size(width, height);
563   }
564
565   return default_tile_size;
566 }
567
568 void PictureLayerImpl::SyncFromActiveLayer(const PictureLayerImpl* other) {
569   DCHECK(!other->needs_post_commit_initialization_);
570   DCHECK(other->tilings_);
571
572   UpdateLCDTextStatus(other->is_using_lcd_text_);
573
574   if (!DrawsContent()) {
575     RemoveAllTilings();
576     return;
577   }
578
579   raster_page_scale_ = other->raster_page_scale_;
580   raster_device_scale_ = other->raster_device_scale_;
581   raster_source_scale_ = other->raster_source_scale_;
582   raster_contents_scale_ = other->raster_contents_scale_;
583   low_res_raster_contents_scale_ = other->low_res_raster_contents_scale_;
584
585   // Add synthetic invalidations for any recordings that were dropped.  As
586   // tiles are updated to point to this new pile, this will force the dropping
587   // of tiles that can no longer be rastered.  This is not ideal, but is a
588   // trade-off for memory (use the same pile as much as possible, by switching
589   // during DidBecomeActive) and for time (don't bother checking every tile
590   // during activation to see if the new pile can still raster it).
591   for (int x = 0; x < pile_->num_tiles_x(); ++x) {
592     for (int y = 0; y < pile_->num_tiles_y(); ++y) {
593       bool previously_had = other->pile_->HasRecordingAt(x, y);
594       bool now_has = pile_->HasRecordingAt(x, y);
595       if (now_has || !previously_had)
596         continue;
597       gfx::Rect layer_rect = pile_->tile_bounds(x, y);
598       invalidation_.Union(layer_rect);
599     }
600   }
601
602   // Union in the other newly exposed regions as invalid.
603   Region difference_region = Region(gfx::Rect(bounds()));
604   difference_region.Subtract(gfx::Rect(other->bounds()));
605   invalidation_.Union(difference_region);
606
607   if (CanHaveTilings()) {
608     // The recycle tree's tiling set is two frames out of date, so it needs to
609     // have both this frame's invalidation and the previous frame's invalidation
610     // (stored on the active layer).
611     Region tiling_invalidation = other->invalidation_;
612     tiling_invalidation.Union(invalidation_);
613     tilings_->SyncTilings(*other->tilings_,
614                           bounds(),
615                           tiling_invalidation,
616                           MinimumContentsScale());
617   } else {
618     RemoveAllTilings();
619   }
620
621   SanityCheckTilingState();
622 }
623
624 void PictureLayerImpl::SyncTiling(
625     const PictureLayerTiling* tiling) {
626   if (!CanHaveTilingWithScale(tiling->contents_scale()))
627     return;
628   tilings_->AddTiling(tiling->contents_scale());
629
630   // If this tree needs update draw properties, then the tiling will
631   // get updated prior to drawing or activation.  If this tree does not
632   // need update draw properties, then its transforms are up to date and
633   // we can create tiles for this tiling immediately.
634   if (!layer_tree_impl()->needs_update_draw_properties() &&
635       should_update_tile_priorities_)
636     UpdateTilePriorities();
637 }
638
639 void PictureLayerImpl::SetIsMask(bool is_mask) {
640   if (is_mask_ == is_mask)
641     return;
642   is_mask_ = is_mask;
643   if (tilings_)
644     tilings_->RemoveAllTiles();
645 }
646
647 ResourceProvider::ResourceId PictureLayerImpl::ContentsResourceId() const {
648   gfx::Rect content_rect(content_bounds());
649   float scale = contents_scale_x();
650   PictureLayerTilingSet::CoverageIterator iter(
651       tilings_.get(), scale, content_rect, ideal_contents_scale_);
652
653   // Mask resource not ready yet.
654   if (!iter || !*iter)
655     return 0;
656
657   // Masks only supported if they fit on exactly one tile.
658   if (iter.geometry_rect() != content_rect)
659     return 0;
660
661   const ManagedTileState::TileVersion& tile_version =
662       iter->GetTileVersionForDrawing();
663   if (!tile_version.IsReadyToDraw() ||
664       tile_version.mode() != ManagedTileState::TileVersion::RESOURCE_MODE)
665     return 0;
666
667   return tile_version.get_resource_id();
668 }
669
670 void PictureLayerImpl::MarkVisibleResourcesAsRequired() const {
671   DCHECK(layer_tree_impl()->IsPendingTree());
672   DCHECK(!layer_tree_impl()->needs_update_draw_properties());
673   DCHECK(ideal_contents_scale_);
674   DCHECK_GT(tilings_->num_tilings(), 0u);
675
676   // The goal of this function is to find the minimum set of tiles that need to
677   // be ready to draw in order to activate without flashing content from a
678   // higher res on the active tree to a lower res on the pending tree.
679
680   gfx::Rect rect(visible_content_rect());
681
682   float min_acceptable_scale =
683       std::min(raster_contents_scale_, ideal_contents_scale_);
684
685   if (PictureLayerImpl* twin = twin_layer_) {
686     float twin_min_acceptable_scale =
687         std::min(twin->ideal_contents_scale_, twin->raster_contents_scale_);
688     // Ignore 0 scale in case CalculateContentsScale() has never been
689     // called for active twin.
690     if (twin_min_acceptable_scale != 0.0f) {
691       min_acceptable_scale =
692           std::min(min_acceptable_scale, twin_min_acceptable_scale);
693     }
694   }
695
696   PictureLayerTiling* high_res = NULL;
697   PictureLayerTiling* low_res = NULL;
698
699   // First pass: ready to draw tiles in acceptable but non-ideal tilings are
700   // marked as required for activation so that their textures are not thrown
701   // away; any non-ready tiles are not marked as required.
702   Region missing_region = rect;
703   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
704     PictureLayerTiling* tiling = tilings_->tiling_at(i);
705     DCHECK(tiling->has_ever_been_updated());
706
707     if (tiling->resolution() == LOW_RESOLUTION) {
708       DCHECK(!low_res) << "There can only be one low res tiling";
709       low_res = tiling;
710     }
711     if (tiling->contents_scale() < min_acceptable_scale)
712       continue;
713     if (tiling->resolution() == HIGH_RESOLUTION) {
714       DCHECK(!high_res) << "There can only be one high res tiling";
715       high_res = tiling;
716       continue;
717     }
718     for (PictureLayerTiling::CoverageIterator iter(tiling,
719                                                    contents_scale_x(),
720                                                    rect);
721          iter;
722          ++iter) {
723       if (!*iter || !iter->IsReadyToDraw())
724         continue;
725
726       // This iteration is over the visible content rect which is potentially
727       // less conservative than projecting the viewport into the layer.
728       // Ignore tiles that are know to be outside the viewport.
729       if (iter->priority(PENDING_TREE).distance_to_visible_in_pixels != 0)
730         continue;
731
732       missing_region.Subtract(iter.geometry_rect());
733       iter->MarkRequiredForActivation();
734     }
735   }
736   DCHECK(high_res) << "There must be one high res tiling";
737
738   // If these pointers are null (because no twin, no matching tiling, or the
739   // simpification just below), then high res tiles will be required to fill any
740   // holes left by the first pass above.  If the pointers are valid, then this
741   // layer is allowed to skip any tiles that are not ready on its twin.
742   const PictureLayerTiling* twin_high_res = NULL;
743   const PictureLayerTiling* twin_low_res = NULL;
744
745   // As a simplification, only allow activating to skip twin tiles that the
746   // active layer is also missing when both this layer and its twin have 2
747   // tilings (high and low).  This avoids having to iterate/track coverage of
748   // non-ideal tilings during the last draw call on the active layer.
749   if (high_res && low_res && tilings_->num_tilings() == 2 &&
750       twin_layer_ && twin_layer_->tilings_->num_tilings() == 2) {
751     twin_low_res = GetTwinTiling(low_res);
752     if (twin_low_res)
753       twin_high_res = GetTwinTiling(high_res);
754   }
755   // If this layer and its twin have different transforms, then don't compare
756   // them and only allow activating to high res tiles, since tiles on each layer
757   // will be in different places on screen.
758   if (!twin_high_res || !twin_low_res ||
759       draw_properties().screen_space_transform !=
760           twin_layer_->draw_properties().screen_space_transform) {
761     twin_high_res = NULL;
762     twin_low_res = NULL;
763   }
764
765   // As a second pass, mark as required any visible high res tiles not filled in
766   // by acceptable non-ideal tiles from the first pass.
767   if (MarkVisibleTilesAsRequired(
768       high_res, twin_high_res, contents_scale_x(), rect, missing_region)) {
769     // As an optional third pass, if a high res tile was skipped because its
770     // twin was also missing, then fall back to mark low res tiles as required
771     // in case the active twin is substituting those for missing high res
772     // content.
773     MarkVisibleTilesAsRequired(
774         low_res, twin_low_res, contents_scale_x(), rect, missing_region);
775   }
776 }
777
778 bool PictureLayerImpl::MarkVisibleTilesAsRequired(
779     PictureLayerTiling* tiling,
780     const PictureLayerTiling* optional_twin_tiling,
781     float contents_scale,
782     const gfx::Rect& rect,
783     const Region& missing_region) const {
784   bool twin_had_missing_tile = false;
785   for (PictureLayerTiling::CoverageIterator iter(tiling,
786                                                  contents_scale,
787                                                  rect);
788        iter;
789        ++iter) {
790     Tile* tile = *iter;
791     // A null tile (i.e. missing recording) can just be skipped.
792     if (!tile)
793       continue;
794
795     // This iteration is over the visible content rect which is potentially
796     // less conservative than projecting the viewport into the layer.
797     // Ignore tiles that are know to be outside the viewport.
798     if (tile->priority(PENDING_TREE).distance_to_visible_in_pixels != 0)
799       continue;
800
801     // If the missing region doesn't cover it, this tile is fully
802     // covered by acceptable tiles at other scales.
803     if (!missing_region.Intersects(iter.geometry_rect()))
804       continue;
805
806     // If the twin tile doesn't exist (i.e. missing recording or so far away
807     // that it is outside the visible tile rect) or this tile is shared between
808     // with the twin, then this tile isn't required to prevent flashing.
809     if (optional_twin_tiling) {
810       Tile* twin_tile = optional_twin_tiling->TileAt(iter.i(), iter.j());
811       if (!twin_tile || twin_tile == tile) {
812         twin_had_missing_tile = true;
813         continue;
814       }
815     }
816
817     tile->MarkRequiredForActivation();
818   }
819   return twin_had_missing_tile;
820 }
821
822 void PictureLayerImpl::DoPostCommitInitialization() {
823   DCHECK(needs_post_commit_initialization_);
824   DCHECK(layer_tree_impl()->IsPendingTree());
825
826   if (!tilings_)
827     tilings_.reset(new PictureLayerTilingSet(this, bounds()));
828
829   DCHECK(!twin_layer_);
830   twin_layer_ = static_cast<PictureLayerImpl*>(
831       layer_tree_impl()->FindActiveTreeLayerById(id()));
832   if (twin_layer_) {
833     DCHECK(!twin_layer_->twin_layer_);
834     twin_layer_->twin_layer_ = this;
835     // If the twin has never been pushed to, do not sync from it.
836     // This can happen if this function is called during activation.
837     if (!twin_layer_->needs_post_commit_initialization_)
838       SyncFromActiveLayer(twin_layer_);
839   }
840
841   needs_post_commit_initialization_ = false;
842 }
843
844 PictureLayerTiling* PictureLayerImpl::AddTiling(float contents_scale) {
845   DCHECK(CanHaveTilingWithScale(contents_scale)) <<
846       "contents_scale: " << contents_scale;
847
848   PictureLayerTiling* tiling = tilings_->AddTiling(contents_scale);
849
850   const Region& recorded = pile_->recorded_region();
851   DCHECK(!recorded.IsEmpty());
852
853   if (twin_layer_ && twin_layer_->should_use_gpu_rasterization() ==
854       should_use_gpu_rasterization())
855     twin_layer_->SyncTiling(tiling);
856
857   return tiling;
858 }
859
860 void PictureLayerImpl::RemoveTiling(float contents_scale) {
861   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
862     PictureLayerTiling* tiling = tilings_->tiling_at(i);
863     if (tiling->contents_scale() == contents_scale) {
864       tilings_->Remove(tiling);
865       break;
866     }
867   }
868   if (tilings_->num_tilings() == 0)
869     ResetRasterScale();
870   SanityCheckTilingState();
871 }
872
873 void PictureLayerImpl::RemoveAllTilings() {
874   tilings_->RemoveAllTilings();
875   // If there are no tilings, then raster scales are no longer meaningful.
876   ResetRasterScale();
877 }
878
879 namespace {
880
881 inline float PositiveRatio(float float1, float float2) {
882   DCHECK_GT(float1, 0);
883   DCHECK_GT(float2, 0);
884   return float1 > float2 ? float1 / float2 : float2 / float1;
885 }
886
887 }  // namespace
888
889 void PictureLayerImpl::ManageTilings(bool animating_transform_to_screen) {
890   DCHECK(ideal_contents_scale_);
891   DCHECK(ideal_page_scale_);
892   DCHECK(ideal_device_scale_);
893   DCHECK(ideal_source_scale_);
894   DCHECK(CanHaveTilings());
895   DCHECK(!needs_post_commit_initialization_);
896
897   bool change_target_tiling =
898       raster_page_scale_ == 0.f ||
899       raster_device_scale_ == 0.f ||
900       raster_source_scale_ == 0.f ||
901       raster_contents_scale_ == 0.f ||
902       low_res_raster_contents_scale_ == 0.f ||
903       ShouldAdjustRasterScale(animating_transform_to_screen);
904
905   if (tilings_->num_tilings() == 0) {
906     DCHECK(change_target_tiling)
907         << "A layer with no tilings shouldn't have valid raster scales";
908   }
909
910   // Store the value for the next time ShouldAdjustRasterScale is called.
911   raster_source_scale_was_animating_ = animating_transform_to_screen;
912
913   if (!change_target_tiling)
914     return;
915
916   if (!layer_tree_impl()->device_viewport_valid_for_tile_management())
917     return;
918
919   RecalculateRasterScales(animating_transform_to_screen);
920
921   PictureLayerTiling* high_res = NULL;
922   PictureLayerTiling* low_res = NULL;
923
924   PictureLayerTiling* previous_low_res = NULL;
925   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
926     PictureLayerTiling* tiling = tilings_->tiling_at(i);
927     if (tiling->contents_scale() == raster_contents_scale_)
928       high_res = tiling;
929     if (tiling->contents_scale() == low_res_raster_contents_scale_)
930       low_res = tiling;
931     if (tiling->resolution() == LOW_RESOLUTION)
932       previous_low_res = tiling;
933
934     // Reset all tilings to non-ideal until the end of this function.
935     tiling->set_resolution(NON_IDEAL_RESOLUTION);
936   }
937
938   if (!high_res) {
939     high_res = AddTiling(raster_contents_scale_);
940     if (raster_contents_scale_ == low_res_raster_contents_scale_)
941       low_res = high_res;
942   }
943
944   // Only create new low res tilings when the transform is static.  This
945   // prevents wastefully creating a paired low res tiling for every new high res
946   // tiling during a pinch or a CSS animation.
947   bool is_pinching = layer_tree_impl()->PinchGestureActive();
948   if (ShouldHaveLowResTiling() && !is_pinching &&
949       !animating_transform_to_screen &&
950       !low_res && low_res != high_res)
951     low_res = AddTiling(low_res_raster_contents_scale_);
952
953   // Set low-res if we have one.
954   if (!low_res)
955     low_res = previous_low_res;
956   if (low_res && low_res != high_res)
957     low_res->set_resolution(LOW_RESOLUTION);
958
959   // Make sure we always have one high-res (even if high == low).
960   high_res->set_resolution(HIGH_RESOLUTION);
961
962   SanityCheckTilingState();
963 }
964
965 bool PictureLayerImpl::ShouldAdjustRasterScale(
966     bool animating_transform_to_screen) const {
967   // TODO(danakj): Adjust raster source scale closer to ideal source scale at
968   // a throttled rate. Possibly make use of invalidation_.IsEmpty() on pending
969   // tree. This will allow CSS scale changes to get re-rastered at an
970   // appropriate rate.
971
972   if (raster_source_scale_was_animating_ && !animating_transform_to_screen)
973     return true;
974
975   bool is_pinching = layer_tree_impl()->PinchGestureActive();
976   if (is_pinching && raster_page_scale_) {
977     // We change our raster scale when it is:
978     // - Higher than ideal (need a lower-res tiling available)
979     // - Too far from ideal (need a higher-res tiling available)
980     float ratio = ideal_page_scale_ / raster_page_scale_;
981     if (raster_page_scale_ > ideal_page_scale_ ||
982         ratio > kMaxScaleRatioDuringPinch)
983       return true;
984   }
985
986   if (!is_pinching) {
987     // When not pinching, match the ideal page scale factor.
988     if (raster_page_scale_ != ideal_page_scale_)
989       return true;
990   }
991
992   // Always match the ideal device scale factor.
993   if (raster_device_scale_ != ideal_device_scale_)
994     return true;
995
996   return false;
997 }
998
999 float PictureLayerImpl::SnappedContentsScale(float scale) {
1000   // If a tiling exists within the max snapping ratio, snap to its scale.
1001   float snapped_contents_scale = scale;
1002   float snapped_ratio = kSnapToExistingTilingRatio;
1003   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
1004     float tiling_contents_scale = tilings_->tiling_at(i)->contents_scale();
1005     float ratio = PositiveRatio(tiling_contents_scale, scale);
1006     if (ratio < snapped_ratio) {
1007       snapped_contents_scale = tiling_contents_scale;
1008       snapped_ratio = ratio;
1009     }
1010   }
1011   return snapped_contents_scale;
1012 }
1013
1014 void PictureLayerImpl::RecalculateRasterScales(
1015     bool animating_transform_to_screen) {
1016   raster_device_scale_ = ideal_device_scale_;
1017   raster_source_scale_ = ideal_source_scale_;
1018
1019   bool is_pinching = layer_tree_impl()->PinchGestureActive();
1020   if (!is_pinching || raster_contents_scale_ == 0.f) {
1021     // When not pinching or when we have no previous scale, we use ideal scale:
1022     raster_page_scale_ = ideal_page_scale_;
1023     raster_contents_scale_ = ideal_contents_scale_;
1024   } else {
1025     // See ShouldAdjustRasterScale:
1026     // - When zooming out, preemptively create new tiling at lower resolution.
1027     // - When zooming in, approximate ideal using multiple of kMaxScaleRatio.
1028     bool zooming_out = raster_page_scale_ > ideal_page_scale_;
1029     float desired_contents_scale =
1030         zooming_out ? raster_contents_scale_ / kMaxScaleRatioDuringPinch
1031                     : raster_contents_scale_ * kMaxScaleRatioDuringPinch;
1032     raster_contents_scale_ = SnappedContentsScale(desired_contents_scale);
1033     raster_page_scale_ = raster_contents_scale_ / raster_device_scale_;
1034   }
1035
1036   raster_contents_scale_ =
1037       std::max(raster_contents_scale_, MinimumContentsScale());
1038
1039   // Don't allow animating CSS scales to drop below 1.  This is needed because
1040   // changes in raster source scale aren't handled.  See the comment in
1041   // ShouldAdjustRasterScale.
1042   if (animating_transform_to_screen) {
1043     raster_contents_scale_ = std::max(
1044         raster_contents_scale_, 1.f * ideal_page_scale_ * ideal_device_scale_);
1045   }
1046
1047   // If this layer would only create one tile at this content scale,
1048   // don't create a low res tiling.
1049   gfx::Size content_bounds =
1050       gfx::ToCeiledSize(gfx::ScaleSize(bounds(), raster_contents_scale_));
1051   gfx::Size tile_size = CalculateTileSize(content_bounds);
1052   if (tile_size.width() >= content_bounds.width() &&
1053       tile_size.height() >= content_bounds.height()) {
1054     low_res_raster_contents_scale_ = raster_contents_scale_;
1055     return;
1056   }
1057
1058   float low_res_factor =
1059       layer_tree_impl()->settings().low_res_contents_scale_factor;
1060   low_res_raster_contents_scale_ = std::max(
1061       raster_contents_scale_ * low_res_factor,
1062       MinimumContentsScale());
1063 }
1064
1065 void PictureLayerImpl::CleanUpTilingsOnActiveLayer(
1066     std::vector<PictureLayerTiling*> used_tilings) {
1067   DCHECK(layer_tree_impl()->IsActiveTree());
1068   if (tilings_->num_tilings() == 0)
1069     return;
1070
1071   float min_acceptable_high_res_scale = std::min(
1072       raster_contents_scale_, ideal_contents_scale_);
1073   float max_acceptable_high_res_scale = std::max(
1074       raster_contents_scale_, ideal_contents_scale_);
1075
1076   PictureLayerImpl* twin = twin_layer_;
1077   if (twin) {
1078     min_acceptable_high_res_scale = std::min(
1079         min_acceptable_high_res_scale,
1080         std::min(twin->raster_contents_scale_, twin->ideal_contents_scale_));
1081     max_acceptable_high_res_scale = std::max(
1082         max_acceptable_high_res_scale,
1083         std::max(twin->raster_contents_scale_, twin->ideal_contents_scale_));
1084   }
1085
1086   std::vector<PictureLayerTiling*> to_remove;
1087   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
1088     PictureLayerTiling* tiling = tilings_->tiling_at(i);
1089
1090     // Keep multiple high resolution tilings even if not used to help
1091     // activate earlier at non-ideal resolutions.
1092     if (tiling->contents_scale() >= min_acceptable_high_res_scale &&
1093         tiling->contents_scale() <= max_acceptable_high_res_scale)
1094       continue;
1095
1096     // Keep low resolution tilings, if the layer should have them.
1097     if (tiling->resolution() == LOW_RESOLUTION && ShouldHaveLowResTiling())
1098       continue;
1099
1100     // Don't remove tilings that are being used (and thus would cause a flash.)
1101     if (std::find(used_tilings.begin(), used_tilings.end(), tiling) !=
1102         used_tilings.end())
1103       continue;
1104
1105     to_remove.push_back(tiling);
1106   }
1107
1108   for (size_t i = 0; i < to_remove.size(); ++i) {
1109     const PictureLayerTiling* twin_tiling = GetTwinTiling(to_remove[i]);
1110     // Only remove tilings from the twin layer if they have
1111     // NON_IDEAL_RESOLUTION.
1112     if (twin_tiling && twin_tiling->resolution() == NON_IDEAL_RESOLUTION)
1113       twin->RemoveTiling(to_remove[i]->contents_scale());
1114     tilings_->Remove(to_remove[i]);
1115   }
1116   DCHECK_GT(tilings_->num_tilings(), 0u);
1117
1118   SanityCheckTilingState();
1119 }
1120
1121 float PictureLayerImpl::MinimumContentsScale() const {
1122   float setting_min = layer_tree_impl()->settings().minimum_contents_scale;
1123
1124   // If the contents scale is less than 1 / width (also for height),
1125   // then it will end up having less than one pixel of content in that
1126   // dimension.  Bump the minimum contents scale up in this case to prevent
1127   // this from happening.
1128   int min_dimension = std::min(bounds().width(), bounds().height());
1129   if (!min_dimension)
1130     return setting_min;
1131
1132   return std::max(1.f / min_dimension, setting_min);
1133 }
1134
1135 void PictureLayerImpl::UpdateLCDTextStatus(bool new_status) {
1136   // Once this layer is not using lcd text, don't switch back.
1137   if (!is_using_lcd_text_)
1138     return;
1139
1140   if (is_using_lcd_text_ == new_status)
1141     return;
1142
1143   is_using_lcd_text_ = new_status;
1144   tilings_->SetCanUseLCDText(is_using_lcd_text_);
1145 }
1146
1147 void PictureLayerImpl::ResetRasterScale() {
1148   raster_page_scale_ = 0.f;
1149   raster_device_scale_ = 0.f;
1150   raster_source_scale_ = 0.f;
1151   raster_contents_scale_ = 0.f;
1152   low_res_raster_contents_scale_ = 0.f;
1153
1154   // When raster scales aren't valid, don't update tile priorities until
1155   // this layer has been updated via UpdateDrawProperties.
1156   should_update_tile_priorities_ = false;
1157 }
1158
1159 bool PictureLayerImpl::CanHaveTilings() const {
1160   if (!DrawsContent())
1161     return false;
1162   if (pile_->recorded_region().IsEmpty())
1163     return false;
1164   return true;
1165 }
1166
1167 bool PictureLayerImpl::CanHaveTilingWithScale(float contents_scale) const {
1168   if (!CanHaveTilings())
1169     return false;
1170   if (contents_scale < MinimumContentsScale())
1171     return false;
1172   return true;
1173 }
1174
1175 void PictureLayerImpl::SanityCheckTilingState() const {
1176   if (!DCHECK_IS_ON())
1177     return;
1178
1179   if (!CanHaveTilings()) {
1180     DCHECK_EQ(0u, tilings_->num_tilings());
1181     return;
1182   }
1183   if (tilings_->num_tilings() == 0)
1184     return;
1185
1186   // MarkVisibleResourcesAsRequired depends on having exactly 1 high res
1187   // tiling to mark its tiles as being required for activation.
1188   DCHECK_EQ(1, tilings_->NumHighResTilings());
1189 }
1190
1191 void PictureLayerImpl::GetDebugBorderProperties(
1192     SkColor* color,
1193     float* width) const {
1194   *color = DebugColors::TiledContentLayerBorderColor();
1195   *width = DebugColors::TiledContentLayerBorderWidth(layer_tree_impl());
1196 }
1197
1198 void PictureLayerImpl::AsValueInto(base::DictionaryValue* state) const {
1199   const_cast<PictureLayerImpl*>(this)->DoPostCommitInitializationIfNeeded();
1200   LayerImpl::AsValueInto(state);
1201   state->SetDouble("ideal_contents_scale", ideal_contents_scale_);
1202   state->SetDouble("geometry_contents_scale", contents_scale_x());
1203   state->Set("tilings", tilings_->AsValue().release());
1204   state->Set("pictures", pile_->AsValue().release());
1205   state->Set("invalidation", invalidation_.AsValue().release());
1206
1207   Region unrecorded_region(gfx::Rect(pile_->size()));
1208   unrecorded_region.Subtract(pile_->recorded_region());
1209   if (!unrecorded_region.IsEmpty())
1210     state->Set("unrecorded_region", unrecorded_region.AsValue().release());
1211
1212   scoped_ptr<base::ListValue> coverage_tiles(new base::ListValue);
1213   for (PictureLayerTilingSet::CoverageIterator iter(tilings_.get(),
1214                                                     contents_scale_x(),
1215                                                     gfx::Rect(content_bounds()),
1216                                                     ideal_contents_scale_);
1217        iter;
1218        ++iter) {
1219     scoped_ptr<base::DictionaryValue> tile_data(new base::DictionaryValue);
1220     tile_data->Set("geometry_rect",
1221                    MathUtil::AsValue(iter.geometry_rect()).release());
1222     if (*iter)
1223       tile_data->Set("tile", TracedValue::CreateIDRef(*iter).release());
1224
1225     coverage_tiles->Append(tile_data.release());
1226   }
1227   state->Set("coverage_tiles", coverage_tiles.release());
1228   state->SetBoolean("is_using_lcd_text", is_using_lcd_text_);
1229 }
1230
1231 size_t PictureLayerImpl::GPUMemoryUsageInBytes() const {
1232   const_cast<PictureLayerImpl*>(this)->DoPostCommitInitializationIfNeeded();
1233   return tilings_->GPUMemoryUsageInBytes();
1234 }
1235
1236 void PictureLayerImpl::RunMicroBenchmark(MicroBenchmarkImpl* benchmark) {
1237   benchmark->RunOnLayer(this);
1238 }
1239
1240 }  // namespace cc