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