picture_layer_impl.cc revision ca12bfac764ba476d6cd062bf1dde12cc64c3f40
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
9#include "base/time/time.h"
10#include "cc/base/math_util.h"
11#include "cc/base/util.h"
12#include "cc/debug/debug_colors.h"
13#include "cc/debug/traced_value.h"
14#include "cc/layers/append_quads_data.h"
15#include "cc/layers/quad_sink.h"
16#include "cc/quads/checkerboard_draw_quad.h"
17#include "cc/quads/debug_border_draw_quad.h"
18#include "cc/quads/picture_draw_quad.h"
19#include "cc/quads/solid_color_draw_quad.h"
20#include "cc/quads/tile_draw_quad.h"
21#include "cc/trees/layer_tree_impl.h"
22#include "ui/gfx/quad_f.h"
23#include "ui/gfx/rect_conversions.h"
24#include "ui/gfx/size_conversions.h"
25
26namespace {
27const float kMaxScaleRatioDuringPinch = 2.0f;
28}
29
30namespace cc {
31
32PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* tree_impl, int id)
33    : LayerImpl(tree_impl, id),
34      twin_layer_(NULL),
35      pile_(PicturePileImpl::Create()),
36      last_content_scale_(0),
37      is_mask_(false),
38      ideal_page_scale_(0.f),
39      ideal_device_scale_(0.f),
40      ideal_source_scale_(0.f),
41      ideal_contents_scale_(0.f),
42      raster_page_scale_(0.f),
43      raster_device_scale_(0.f),
44      raster_source_scale_(0.f),
45      raster_contents_scale_(0.f),
46      low_res_raster_contents_scale_(0.f),
47      raster_source_scale_was_animating_(false),
48      is_using_lcd_text_(tree_impl->settings().can_use_lcd_text) {
49}
50
51PictureLayerImpl::~PictureLayerImpl() {
52}
53
54const char* PictureLayerImpl::LayerTypeAsString() const {
55  return "cc::PictureLayerImpl";
56}
57
58scoped_ptr<LayerImpl> PictureLayerImpl::CreateLayerImpl(
59    LayerTreeImpl* tree_impl) {
60  return PictureLayerImpl::Create(tree_impl, id()).PassAs<LayerImpl>();
61}
62
63void PictureLayerImpl::CreateTilingSetIfNeeded() {
64  DCHECK(layer_tree_impl()->IsPendingTree());
65  if (!tilings_)
66    tilings_.reset(new PictureLayerTilingSet(this, bounds()));
67}
68
69void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) {
70  LayerImpl::PushPropertiesTo(base_layer);
71
72  PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer);
73
74  // When the pending tree pushes to the active tree, the pending twin
75  // disappears.
76  layer_impl->twin_layer_ = NULL;
77  twin_layer_ = NULL;
78
79  layer_impl->SetIsMask(is_mask_);
80  layer_impl->pile_ = pile_;
81  pile_ = NULL;
82
83  layer_impl->tilings_.swap(tilings_);
84  layer_impl->tilings_->SetClient(layer_impl);
85  if (tilings_)
86    tilings_->SetClient(this);
87
88  layer_impl->raster_page_scale_ = raster_page_scale_;
89  layer_impl->raster_device_scale_ = raster_device_scale_;
90  layer_impl->raster_source_scale_ = raster_source_scale_;
91  layer_impl->raster_contents_scale_ = raster_contents_scale_;
92  layer_impl->low_res_raster_contents_scale_ = low_res_raster_contents_scale_;
93
94  layer_impl->UpdateLCDTextStatus(is_using_lcd_text_);
95
96  // As an optimization, don't make a copy of this potentially complex region,
97  // and swap it directly from the pending to the active layer.  In general, any
98  // property pushed to a LayerImpl continues to live on that LayerImpl.
99  // However, invalidation is the difference between two main thread frames, so
100  // it no longer makes sense once the pending tree gets recycled.  It will
101  // always get pushed during PictureLayer::PushPropertiesTo.
102  layer_impl->invalidation_.Swap(&invalidation_);
103  invalidation_.Clear();
104}
105
106void PictureLayerImpl::AppendQuads(QuadSink* quad_sink,
107                                   AppendQuadsData* append_quads_data) {
108  gfx::Rect rect(visible_content_rect());
109  gfx::Rect content_rect(content_bounds());
110
111  SharedQuadState* shared_quad_state =
112      quad_sink->UseSharedQuadState(CreateSharedQuadState());
113
114  bool draw_direct_to_backbuffer =
115      draw_properties().can_draw_directly_to_backbuffer &&
116      layer_tree_impl()->settings().force_direct_layer_drawing;
117
118  if (draw_direct_to_backbuffer ||
119      current_draw_mode_ == DRAW_MODE_RESOURCELESS_SOFTWARE) {
120    AppendDebugBorderQuad(
121        quad_sink,
122        shared_quad_state,
123        append_quads_data,
124        DebugColors::DirectPictureBorderColor(),
125        DebugColors::DirectPictureBorderWidth(layer_tree_impl()));
126
127    gfx::Rect geometry_rect = rect;
128    gfx::Rect opaque_rect = contents_opaque() ? geometry_rect : gfx::Rect();
129    gfx::Size texture_size = rect.size();
130    gfx::RectF texture_rect = gfx::RectF(texture_size);
131    gfx::Rect quad_content_rect = rect;
132    float contents_scale = contents_scale_x();
133
134    scoped_ptr<PictureDrawQuad> quad = PictureDrawQuad::Create();
135    quad->SetNew(shared_quad_state,
136                 geometry_rect,
137                 opaque_rect,
138                 texture_rect,
139                 texture_size,
140                 false,
141                 quad_content_rect,
142                 contents_scale,
143                 draw_direct_to_backbuffer,
144                 pile_);
145    if (quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data))
146      append_quads_data->num_missing_tiles++;
147    return;
148  }
149
150  AppendDebugBorderQuad(quad_sink, shared_quad_state, append_quads_data);
151
152  bool clipped = false;
153  gfx::QuadF target_quad = MathUtil::MapQuad(
154      draw_transform(),
155      gfx::QuadF(rect),
156      &clipped);
157  if (ShowDebugBorders()) {
158    for (PictureLayerTilingSet::CoverageIterator iter(
159        tilings_.get(), contents_scale_x(), rect, ideal_contents_scale_);
160         iter;
161         ++iter) {
162      SkColor color;
163      float width;
164      if (*iter && iter->IsReadyToDraw()) {
165        ManagedTileState::TileVersion::Mode mode =
166            iter->GetTileVersionForDrawing().mode();
167        if (mode == ManagedTileState::TileVersion::SOLID_COLOR_MODE) {
168          color = DebugColors::SolidColorTileBorderColor();
169          width = DebugColors::SolidColorTileBorderWidth(layer_tree_impl());
170        } else if (mode == ManagedTileState::TileVersion::PICTURE_PILE_MODE) {
171          color = DebugColors::PictureTileBorderColor();
172          width = DebugColors::PictureTileBorderWidth(layer_tree_impl());
173        } else if (iter->priority(ACTIVE_TREE).resolution == HIGH_RESOLUTION) {
174          color = DebugColors::HighResTileBorderColor();
175          width = DebugColors::HighResTileBorderWidth(layer_tree_impl());
176        } else if (iter->priority(ACTIVE_TREE).resolution == LOW_RESOLUTION) {
177          color = DebugColors::LowResTileBorderColor();
178          width = DebugColors::LowResTileBorderWidth(layer_tree_impl());
179        } else if (iter->contents_scale() > contents_scale_x()) {
180          color = DebugColors::ExtraHighResTileBorderColor();
181          width = DebugColors::ExtraHighResTileBorderWidth(layer_tree_impl());
182        } else {
183          color = DebugColors::ExtraLowResTileBorderColor();
184          width = DebugColors::ExtraLowResTileBorderWidth(layer_tree_impl());
185        }
186      } else {
187        color = DebugColors::MissingTileBorderColor();
188        width = DebugColors::MissingTileBorderWidth(layer_tree_impl());
189      }
190
191      scoped_ptr<DebugBorderDrawQuad> debug_border_quad =
192          DebugBorderDrawQuad::Create();
193      gfx::Rect geometry_rect = iter.geometry_rect();
194      debug_border_quad->SetNew(shared_quad_state, geometry_rect, color, width);
195      quad_sink->Append(debug_border_quad.PassAs<DrawQuad>(),
196                        append_quads_data);
197    }
198  }
199
200  // Keep track of the tilings that were used so that tilings that are
201  // unused can be considered for removal.
202  std::vector<PictureLayerTiling*> seen_tilings;
203
204  for (PictureLayerTilingSet::CoverageIterator iter(
205      tilings_.get(), contents_scale_x(), rect, ideal_contents_scale_);
206       iter;
207       ++iter) {
208    gfx::Rect geometry_rect = iter.geometry_rect();
209    if (!*iter || !iter->IsReadyToDraw()) {
210      if (DrawCheckerboardForMissingTiles()) {
211        // TODO(enne): Figure out how to show debug "invalidated checker" color
212        scoped_ptr<CheckerboardDrawQuad> quad = CheckerboardDrawQuad::Create();
213        SkColor color = DebugColors::DefaultCheckerboardColor();
214        quad->SetNew(shared_quad_state, geometry_rect, color);
215        if (quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data))
216          append_quads_data->num_missing_tiles++;
217      } else {
218        SkColor color = SafeOpaqueBackgroundColor();
219        scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create();
220        quad->SetNew(shared_quad_state, geometry_rect, color, false);
221        if (quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data))
222          append_quads_data->num_missing_tiles++;
223      }
224
225      append_quads_data->had_incomplete_tile = true;
226      continue;
227    }
228
229    const ManagedTileState::TileVersion& tile_version =
230        iter->GetTileVersionForDrawing();
231    switch (tile_version.mode()) {
232      case ManagedTileState::TileVersion::RESOURCE_MODE: {
233        gfx::RectF texture_rect = iter.texture_rect();
234        gfx::Rect opaque_rect = iter->opaque_rect();
235        opaque_rect.Intersect(content_rect);
236
237        if (iter->contents_scale() != ideal_contents_scale_)
238          append_quads_data->had_incomplete_tile = true;
239
240        scoped_ptr<TileDrawQuad> quad = TileDrawQuad::Create();
241        quad->SetNew(shared_quad_state,
242                     geometry_rect,
243                     opaque_rect,
244                     tile_version.get_resource_id(),
245                     texture_rect,
246                     iter.texture_size(),
247                     tile_version.contents_swizzled());
248        quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data);
249        break;
250      }
251      case ManagedTileState::TileVersion::PICTURE_PILE_MODE: {
252        gfx::RectF texture_rect = iter.texture_rect();
253        gfx::Rect opaque_rect = iter->opaque_rect();
254        opaque_rect.Intersect(content_rect);
255
256        scoped_ptr<PictureDrawQuad> quad = PictureDrawQuad::Create();
257        quad->SetNew(shared_quad_state,
258                     geometry_rect,
259                     opaque_rect,
260                     texture_rect,
261                     iter.texture_size(),
262                     // TODO(reveman): This assumes the renderer will use
263                     // GL_RGBA as format of temporary resource. The need
264                     // to swizzle should instead be determined by the
265                     // renderer.
266                     !PlatformColor::SameComponentOrder(GL_RGBA),
267                     iter->content_rect(),
268                     iter->contents_scale(),
269                     draw_direct_to_backbuffer,
270                     pile_);
271        quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data);
272        break;
273      }
274      case ManagedTileState::TileVersion::SOLID_COLOR_MODE: {
275        scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create();
276        quad->SetNew(shared_quad_state,
277                     geometry_rect,
278                     tile_version.get_solid_color(),
279                     false);
280        quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data);
281        break;
282      }
283      default:
284        NOTREACHED();
285    }
286
287    if (!seen_tilings.size() || seen_tilings.back() != iter.CurrentTiling())
288      seen_tilings.push_back(iter.CurrentTiling());
289  }
290
291  // Aggressively remove any tilings that are not seen to save memory. Note
292  // that this is at the expense of doing cause more frequent re-painting. A
293  // better scheme would be to maintain a tighter visible_content_rect for the
294  // finer tilings.
295  CleanUpTilingsOnActiveLayer(seen_tilings);
296}
297
298void PictureLayerImpl::UpdateTilePriorities() {
299  if (!tilings_->num_tilings())
300    return;
301
302  double current_frame_time_in_seconds =
303      (layer_tree_impl()->CurrentFrameTimeTicks() -
304       base::TimeTicks()).InSecondsF();
305
306  bool tiling_needs_update = false;
307  for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
308    if (tilings_->tiling_at(i)->NeedsUpdateForFrameAtTime(
309            current_frame_time_in_seconds)) {
310      tiling_needs_update = true;
311      break;
312    }
313  }
314  if (!tiling_needs_update)
315    return;
316
317  // At this point, tile priorities are going to be modified.
318  layer_tree_impl()->WillModifyTilePriorities();
319
320  UpdateLCDTextStatus(can_use_lcd_text());
321
322  gfx::Transform current_screen_space_transform = screen_space_transform();
323
324  gfx::Rect viewport_in_content_space;
325  gfx::Transform screen_to_layer(gfx::Transform::kSkipInitialization);
326  if (screen_space_transform().GetInverse(&screen_to_layer)) {
327    gfx::Rect device_viewport(layer_tree_impl()->device_viewport_size());
328    viewport_in_content_space = gfx::ToEnclosingRect(
329        MathUtil::ProjectClippedRect(screen_to_layer, device_viewport));
330  }
331
332  WhichTree tree =
333      layer_tree_impl()->IsActiveTree() ? ACTIVE_TREE : PENDING_TREE;
334  size_t max_tiles_for_interest_area =
335      layer_tree_impl()->settings().max_tiles_for_interest_area;
336  tilings_->UpdateTilePriorities(
337      tree,
338      layer_tree_impl()->device_viewport_size(),
339      viewport_in_content_space,
340      visible_content_rect(),
341      last_bounds_,
342      bounds(),
343      last_content_scale_,
344      contents_scale_x(),
345      last_screen_space_transform_,
346      current_screen_space_transform,
347      current_frame_time_in_seconds,
348      max_tiles_for_interest_area);
349
350  if (layer_tree_impl()->IsPendingTree())
351    MarkVisibleResourcesAsRequired();
352
353  last_screen_space_transform_ = current_screen_space_transform;
354  last_bounds_ = bounds();
355  last_content_scale_ = contents_scale_x();
356}
357
358void PictureLayerImpl::DidBecomeActive() {
359  LayerImpl::DidBecomeActive();
360  tilings_->DidBecomeActive();
361  layer_tree_impl()->WillModifyTilePriorities();
362}
363
364void PictureLayerImpl::DidBeginTracing() {
365  pile_->DidBeginTracing();
366}
367
368void PictureLayerImpl::DidLoseOutputSurface() {
369  if (tilings_)
370    tilings_->RemoveAllTilings();
371
372  ResetRasterScale();
373}
374
375void PictureLayerImpl::CalculateContentsScale(
376    float ideal_contents_scale,
377    float device_scale_factor,
378    float page_scale_factor,
379    bool animating_transform_to_screen,
380    float* contents_scale_x,
381    float* contents_scale_y,
382    gfx::Size* content_bounds) {
383  if (!CanHaveTilings()) {
384    ideal_page_scale_ = page_scale_factor;
385    ideal_device_scale_ = device_scale_factor;
386    ideal_contents_scale_ = ideal_contents_scale;
387    ideal_source_scale_ =
388        ideal_contents_scale_ / ideal_page_scale_ / ideal_device_scale_;
389    *contents_scale_x = ideal_contents_scale_;
390    *contents_scale_y = ideal_contents_scale_;
391    *content_bounds = gfx::ToCeiledSize(gfx::ScaleSize(bounds(),
392                                                       ideal_contents_scale_,
393                                                       ideal_contents_scale_));
394    return;
395  }
396
397  float min_contents_scale = MinimumContentsScale();
398  DCHECK_GT(min_contents_scale, 0.f);
399  float min_page_scale = layer_tree_impl()->min_page_scale_factor();
400  DCHECK_GT(min_page_scale, 0.f);
401  float min_device_scale = 1.f;
402  float min_source_scale =
403      min_contents_scale / min_page_scale / min_device_scale;
404
405  float ideal_page_scale = page_scale_factor;
406  float ideal_device_scale = device_scale_factor;
407  float ideal_source_scale =
408      ideal_contents_scale / ideal_page_scale / ideal_device_scale;
409
410  ideal_contents_scale_ = std::max(ideal_contents_scale, min_contents_scale);
411  ideal_page_scale_ = ideal_page_scale;
412  ideal_device_scale_ = ideal_device_scale;
413  ideal_source_scale_ = std::max(ideal_source_scale, min_source_scale);
414
415  ManageTilings(animating_transform_to_screen);
416
417  // The content scale and bounds for a PictureLayerImpl is somewhat fictitious.
418  // There are (usually) several tilings at different scales.  However, the
419  // content bounds is the (integer!) space in which quads are generated.
420  // In order to guarantee that we can fill this integer space with any set of
421  // tilings (and then map back to floating point texture coordinates), the
422  // contents scale must be at least as large as the largest of the tilings.
423  float max_contents_scale = min_contents_scale;
424  for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
425    const PictureLayerTiling* tiling = tilings_->tiling_at(i);
426    max_contents_scale = std::max(max_contents_scale, tiling->contents_scale());
427  }
428
429  *contents_scale_x = max_contents_scale;
430  *contents_scale_y = max_contents_scale;
431  *content_bounds = gfx::ToCeiledSize(
432      gfx::ScaleSize(bounds(), max_contents_scale, max_contents_scale));
433}
434
435skia::RefPtr<SkPicture> PictureLayerImpl::GetPicture() {
436  return pile_->GetFlattenedPicture();
437}
438
439scoped_refptr<Tile> PictureLayerImpl::CreateTile(PictureLayerTiling* tiling,
440                                                 gfx::Rect content_rect) {
441  if (!pile_->CanRaster(tiling->contents_scale(), content_rect))
442    return scoped_refptr<Tile>();
443
444  return make_scoped_refptr(new Tile(
445      layer_tree_impl()->tile_manager(),
446      pile_.get(),
447      content_rect.size(),
448      content_rect,
449      contents_opaque() ? content_rect : gfx::Rect(),
450      tiling->contents_scale(),
451      id(),
452      layer_tree_impl()->source_frame_number(),
453      is_using_lcd_text_));
454}
455
456void PictureLayerImpl::UpdatePile(Tile* tile) {
457  tile->set_picture_pile(pile_);
458}
459
460const Region* PictureLayerImpl::GetInvalidation() {
461  return &invalidation_;
462}
463
464const PictureLayerTiling* PictureLayerImpl::GetTwinTiling(
465    const PictureLayerTiling* tiling) {
466
467  if (!twin_layer_)
468    return NULL;
469  for (size_t i = 0; i < twin_layer_->tilings_->num_tilings(); ++i)
470    if (twin_layer_->tilings_->tiling_at(i)->contents_scale() ==
471        tiling->contents_scale())
472      return twin_layer_->tilings_->tiling_at(i);
473  return NULL;
474}
475
476gfx::Size PictureLayerImpl::CalculateTileSize(
477    gfx::Size content_bounds) const {
478  if (is_mask_) {
479    int max_size = layer_tree_impl()->MaxTextureSize();
480    return gfx::Size(
481        std::min(max_size, content_bounds.width()),
482        std::min(max_size, content_bounds.height()));
483  }
484
485  int max_texture_size =
486      layer_tree_impl()->resource_provider()->max_texture_size();
487
488  gfx::Size default_tile_size = layer_tree_impl()->settings().default_tile_size;
489  default_tile_size.SetToMin(gfx::Size(max_texture_size, max_texture_size));
490
491  gfx::Size max_untiled_content_size =
492      layer_tree_impl()->settings().max_untiled_layer_size;
493  max_untiled_content_size.SetToMin(
494      gfx::Size(max_texture_size, max_texture_size));
495
496  bool any_dimension_too_large =
497      content_bounds.width() > max_untiled_content_size.width() ||
498      content_bounds.height() > max_untiled_content_size.height();
499
500  bool any_dimension_one_tile =
501      content_bounds.width() <= default_tile_size.width() ||
502      content_bounds.height() <= default_tile_size.height();
503
504  // If long and skinny, tile at the max untiled content size, and clamp
505  // the smaller dimension to the content size, e.g. 1000x12 layer with
506  // 500x500 max untiled size would get 500x12 tiles.  Also do this
507  // if the layer is small.
508  if (any_dimension_one_tile || !any_dimension_too_large) {
509    int width =
510        std::min(max_untiled_content_size.width(), content_bounds.width());
511    int height =
512        std::min(max_untiled_content_size.height(), content_bounds.height());
513    // Round width and height up to the closest multiple of 64, or 56 if
514    // we should avoid power-of-two textures. This helps reduce the number
515    // of different textures sizes to help recycling, and also keeps all
516    // textures multiple-of-eight, which is preferred on some drivers (IMG).
517    bool avoid_pow2 =
518        layer_tree_impl()->GetRendererCapabilities().avoid_pow2_textures;
519    int round_up_to = avoid_pow2 ? 56 : 64;
520    width = RoundUp(width, round_up_to);
521    height = RoundUp(height, round_up_to);
522    return gfx::Size(width, height);
523  }
524
525  return default_tile_size;
526}
527
528void PictureLayerImpl::SyncFromActiveLayer() {
529  DCHECK(layer_tree_impl()->IsPendingTree());
530
531  if (twin_layer_)
532    SyncFromActiveLayer(twin_layer_);
533}
534
535void PictureLayerImpl::SyncFromActiveLayer(const PictureLayerImpl* other) {
536  UpdateLCDTextStatus(other->is_using_lcd_text_);
537
538  if (!DrawsContent()) {
539    ResetRasterScale();
540    return;
541  }
542
543  raster_page_scale_ = other->raster_page_scale_;
544  raster_device_scale_ = other->raster_device_scale_;
545  raster_source_scale_ = other->raster_source_scale_;
546  raster_contents_scale_ = other->raster_contents_scale_;
547  low_res_raster_contents_scale_ = other->low_res_raster_contents_scale_;
548
549  // Add synthetic invalidations for any recordings that were dropped.  As
550  // tiles are updated to point to this new pile, this will force the dropping
551  // of tiles that can no longer be rastered.  This is not ideal, but is a
552  // trade-off for memory (use the same pile as much as possible, by switching
553  // during DidBecomeActive) and for time (don't bother checking every tile
554  // during activation to see if the new pile can still raster it).
555  for (int x = 0; x < pile_->num_tiles_x(); ++x) {
556    for (int y = 0; y < pile_->num_tiles_y(); ++y) {
557      bool previously_had = other->pile_->HasRecordingAt(x, y);
558      bool now_has = pile_->HasRecordingAt(x, y);
559      if (now_has || !previously_had)
560        continue;
561      gfx::Rect layer_rect = pile_->tile_bounds(x, y);
562      invalidation_.Union(layer_rect);
563    }
564  }
565
566  // Union in the other newly exposed regions as invalid.
567  Region difference_region = Region(gfx::Rect(bounds()));
568  difference_region.Subtract(gfx::Rect(other->bounds()));
569  invalidation_.Union(difference_region);
570
571  if (CanHaveTilings()) {
572    // The recycle tree's tiling set is two frames out of date, so it needs to
573    // have both this frame's invalidation and the previous frame's invalidation
574    // (stored on the active layer).
575    Region tiling_invalidation = other->invalidation_;
576    tiling_invalidation.Union(invalidation_);
577    tilings_->SyncTilings(*other->tilings_,
578                          bounds(),
579                          tiling_invalidation,
580                          MinimumContentsScale());
581  } else {
582    tilings_->RemoveAllTilings();
583  }
584}
585
586void PictureLayerImpl::SyncTiling(
587    const PictureLayerTiling* tiling) {
588  if (!CanHaveTilingWithScale(tiling->contents_scale()))
589    return;
590  tilings_->AddTiling(tiling->contents_scale());
591
592  // If this tree needs update draw properties, then the tiling will
593  // get updated prior to drawing or activation.  If this tree does not
594  // need update draw properties, then its transforms are up to date and
595  // we can create tiles for this tiling immediately.
596  if (!layer_tree_impl()->needs_update_draw_properties())
597    UpdateTilePriorities();
598}
599
600void PictureLayerImpl::UpdateTwinLayer() {
601  DCHECK(layer_tree_impl()->IsPendingTree());
602
603  twin_layer_ = static_cast<PictureLayerImpl*>(
604      layer_tree_impl()->FindActiveTreeLayerById(id()));
605  if (twin_layer_)
606    twin_layer_->twin_layer_ = this;
607}
608
609void PictureLayerImpl::SetIsMask(bool is_mask) {
610  if (is_mask_ == is_mask)
611    return;
612  is_mask_ = is_mask;
613  if (tilings_)
614    tilings_->RemoveAllTiles();
615}
616
617ResourceProvider::ResourceId PictureLayerImpl::ContentsResourceId() const {
618  gfx::Rect content_rect(content_bounds());
619  float scale = contents_scale_x();
620  for (PictureLayerTilingSet::CoverageIterator
621           iter(tilings_.get(), scale, content_rect, ideal_contents_scale_);
622       iter;
623       ++iter) {
624    // Mask resource not ready yet.
625    if (!*iter)
626      return 0;
627
628    const ManagedTileState::TileVersion& tile_version =
629        iter->GetTileVersionForDrawing();
630    if (!tile_version.IsReadyToDraw() ||
631        tile_version.mode() != ManagedTileState::TileVersion::RESOURCE_MODE)
632      return 0;
633
634    // Masks only supported if they fit on exactly one tile.
635    if (iter.geometry_rect() != content_rect)
636      return 0;
637
638    return tile_version.get_resource_id();
639  }
640  return 0;
641}
642
643void PictureLayerImpl::MarkVisibleResourcesAsRequired() const {
644  DCHECK(layer_tree_impl()->IsPendingTree());
645  DCHECK(!layer_tree_impl()->needs_update_draw_properties());
646  DCHECK(ideal_contents_scale_);
647  DCHECK_GT(tilings_->num_tilings(), 0u);
648
649  gfx::Rect rect(visible_content_rect());
650
651  float min_acceptable_scale =
652      std::min(raster_contents_scale_, ideal_contents_scale_);
653
654  if (PictureLayerImpl* twin = twin_layer_) {
655    float twin_min_acceptable_scale =
656        std::min(twin->ideal_contents_scale_, twin->raster_contents_scale_);
657    // Ignore 0 scale in case CalculateContentsScale() has never been
658    // called for active twin.
659    if (twin_min_acceptable_scale != 0.0f) {
660      min_acceptable_scale =
661          std::min(min_acceptable_scale, twin_min_acceptable_scale);
662    }
663  }
664
665  // Mark tiles for activation in two passes.  Ready to draw tiles in acceptable
666  // but non-ideal tilings are marked as required for activation, but any
667  // non-ready tiles are not marked as required.  From there, any missing holes
668  // will need to be filled in from the high res tiling.
669
670  PictureLayerTiling* high_res = NULL;
671  Region missing_region = rect;
672  for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
673    PictureLayerTiling* tiling = tilings_->tiling_at(i);
674    DCHECK(tiling->has_ever_been_updated());
675
676    if (tiling->contents_scale() < min_acceptable_scale)
677      continue;
678    if (tiling->resolution() == HIGH_RESOLUTION) {
679      DCHECK(!high_res) << "There can only be one high res tiling";
680      high_res = tiling;
681      continue;
682    }
683    for (PictureLayerTiling::CoverageIterator iter(tiling,
684                                                   contents_scale_x(),
685                                                   rect);
686         iter;
687         ++iter) {
688      if (!*iter || !iter->IsReadyToDraw())
689        continue;
690
691      // This iteration is over the visible content rect which is potentially
692      // less conservative than projecting the viewport into the layer.
693      // Ignore tiles that are know to be outside the viewport.
694      if (iter->priority(PENDING_TREE).distance_to_visible_in_pixels != 0)
695        continue;
696
697      missing_region.Subtract(iter.geometry_rect());
698      iter->mark_required_for_activation();
699    }
700  }
701
702  DCHECK(high_res) << "There must be one high res tiling";
703  for (PictureLayerTiling::CoverageIterator iter(high_res,
704                                                 contents_scale_x(),
705                                                 rect);
706       iter;
707       ++iter) {
708    // A null tile (i.e. missing recording) can just be skipped.
709    if (!*iter)
710      continue;
711
712    // This iteration is over the visible content rect which is potentially
713    // less conservative than projecting the viewport into the layer.
714    // Ignore tiles that are know to be outside the viewport.
715    if (iter->priority(PENDING_TREE).distance_to_visible_in_pixels != 0)
716      continue;
717
718    // If the missing region doesn't cover it, this tile is fully
719    // covered by acceptable tiles at other scales.
720    if (!missing_region.Intersects(iter.geometry_rect()))
721      continue;
722
723    iter->mark_required_for_activation();
724  }
725}
726
727PictureLayerTiling* PictureLayerImpl::AddTiling(float contents_scale) {
728  DCHECK(CanHaveTilingWithScale(contents_scale)) <<
729      "contents_scale: " << contents_scale;
730
731  PictureLayerTiling* tiling = tilings_->AddTiling(contents_scale);
732
733  const Region& recorded = pile_->recorded_region();
734  DCHECK(!recorded.IsEmpty());
735
736  if (twin_layer_)
737    twin_layer_->SyncTiling(tiling);
738
739  return tiling;
740}
741
742void PictureLayerImpl::RemoveTiling(float contents_scale) {
743  for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
744    PictureLayerTiling* tiling = tilings_->tiling_at(i);
745    if (tiling->contents_scale() == contents_scale) {
746      tilings_->Remove(tiling);
747      break;
748    }
749  }
750}
751
752namespace {
753
754inline float PositiveRatio(float float1, float float2) {
755  DCHECK_GT(float1, 0);
756  DCHECK_GT(float2, 0);
757  return float1 > float2 ? float1 / float2 : float2 / float1;
758}
759
760inline bool IsCloserToThan(
761    PictureLayerTiling* layer1,
762    PictureLayerTiling* layer2,
763    float contents_scale) {
764  // Absolute value for ratios.
765  float ratio1 = PositiveRatio(layer1->contents_scale(), contents_scale);
766  float ratio2 = PositiveRatio(layer2->contents_scale(), contents_scale);
767  return ratio1 < ratio2;
768}
769
770}  // namespace
771
772void PictureLayerImpl::ManageTilings(bool animating_transform_to_screen) {
773  DCHECK(ideal_contents_scale_);
774  DCHECK(ideal_page_scale_);
775  DCHECK(ideal_device_scale_);
776  DCHECK(ideal_source_scale_);
777  DCHECK(CanHaveTilings());
778
779  bool change_target_tiling =
780      raster_page_scale_ == 0.f ||
781      raster_device_scale_ == 0.f ||
782      raster_source_scale_ == 0.f ||
783      raster_contents_scale_ == 0.f ||
784      low_res_raster_contents_scale_ == 0.f ||
785      ShouldAdjustRasterScale(animating_transform_to_screen);
786
787  // Store the value for the next time ShouldAdjustRasterScale is called.
788  raster_source_scale_was_animating_ = animating_transform_to_screen;
789
790  if (!change_target_tiling)
791    return;
792
793  raster_page_scale_ = ideal_page_scale_;
794  raster_device_scale_ = ideal_device_scale_;
795  raster_source_scale_ = ideal_source_scale_;
796
797  CalculateRasterContentsScale(animating_transform_to_screen,
798                               &raster_contents_scale_,
799                               &low_res_raster_contents_scale_);
800
801  PictureLayerTiling* high_res = NULL;
802  PictureLayerTiling* low_res = NULL;
803
804  PictureLayerTiling* previous_low_res = NULL;
805  for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
806    PictureLayerTiling* tiling = tilings_->tiling_at(i);
807    if (tiling->contents_scale() == raster_contents_scale_)
808      high_res = tiling;
809    if (tiling->contents_scale() == low_res_raster_contents_scale_)
810      low_res = tiling;
811    if (tiling->resolution() == LOW_RESOLUTION)
812      previous_low_res = tiling;
813
814    // Reset all tilings to non-ideal until the end of this function.
815    tiling->set_resolution(NON_IDEAL_RESOLUTION);
816  }
817
818  if (!high_res) {
819    high_res = AddTiling(raster_contents_scale_);
820    if (raster_contents_scale_ == low_res_raster_contents_scale_)
821      low_res = high_res;
822  }
823
824  // Only create new low res tilings when the transform is static.  This
825  // prevents wastefully creating a paired low res tiling for every new high res
826  // tiling during a pinch or a CSS animation.
827  bool is_pinching = layer_tree_impl()->PinchGestureActive();
828  if (!is_pinching && !animating_transform_to_screen && !low_res &&
829      low_res != high_res)
830    low_res = AddTiling(low_res_raster_contents_scale_);
831
832  if (high_res)
833    high_res->set_resolution(HIGH_RESOLUTION);
834  if (low_res && low_res != high_res)
835    low_res->set_resolution(LOW_RESOLUTION);
836  else if (!low_res && previous_low_res)
837    previous_low_res->set_resolution(LOW_RESOLUTION);
838}
839
840bool PictureLayerImpl::ShouldAdjustRasterScale(
841    bool animating_transform_to_screen) const {
842  // TODO(danakj): Adjust raster source scale closer to ideal source scale at
843  // a throttled rate. Possibly make use of invalidation_.IsEmpty() on pending
844  // tree. This will allow CSS scale changes to get re-rastered at an
845  // appropriate rate.
846
847  if (raster_source_scale_was_animating_ && !animating_transform_to_screen)
848    return true;
849
850  bool is_pinching = layer_tree_impl()->PinchGestureActive();
851  if (is_pinching && raster_page_scale_) {
852    // If the page scale diverges too far during pinch, change raster target to
853    // the current page scale.
854    float ratio = PositiveRatio(ideal_page_scale_, raster_page_scale_);
855    if (ratio >= kMaxScaleRatioDuringPinch)
856      return true;
857  }
858
859  if (!is_pinching) {
860    // When not pinching, match the ideal page scale factor.
861    if (raster_page_scale_ != ideal_page_scale_)
862      return true;
863  }
864
865  // Always match the ideal device scale factor.
866  if (raster_device_scale_ != ideal_device_scale_)
867    return true;
868
869  return false;
870}
871
872void PictureLayerImpl::CalculateRasterContentsScale(
873    bool animating_transform_to_screen,
874    float* raster_contents_scale,
875    float* low_res_raster_contents_scale) const {
876  *raster_contents_scale = ideal_contents_scale_;
877
878  // Don't allow animating CSS scales to drop below 1.  This is needed because
879  // changes in raster source scale aren't handled.  See the comment in
880  // ShouldAdjustRasterScale.
881  if (animating_transform_to_screen) {
882    *raster_contents_scale = std::max(
883        *raster_contents_scale, 1.f * ideal_page_scale_ * ideal_device_scale_);
884  }
885
886  // If this layer would only create one tile at this content scale,
887  // don't create a low res tiling.
888  gfx::Size content_bounds =
889      gfx::ToCeiledSize(gfx::ScaleSize(bounds(), *raster_contents_scale));
890  gfx::Size tile_size = CalculateTileSize(content_bounds);
891  if (tile_size == content_bounds) {
892    *low_res_raster_contents_scale = *raster_contents_scale;
893    return;
894  }
895
896  float low_res_factor =
897      layer_tree_impl()->settings().low_res_contents_scale_factor;
898  *low_res_raster_contents_scale = std::max(
899      *raster_contents_scale * low_res_factor,
900      MinimumContentsScale());
901}
902
903void PictureLayerImpl::CleanUpTilingsOnActiveLayer(
904    std::vector<PictureLayerTiling*> used_tilings) {
905  DCHECK(layer_tree_impl()->IsActiveTree());
906
907  float min_acceptable_high_res_scale = std::min(
908      raster_contents_scale_, ideal_contents_scale_);
909  float max_acceptable_high_res_scale = std::max(
910      raster_contents_scale_, ideal_contents_scale_);
911
912  PictureLayerImpl* twin = twin_layer_;
913  if (twin) {
914    min_acceptable_high_res_scale = std::min(
915        min_acceptable_high_res_scale,
916        std::min(twin->raster_contents_scale_, twin->ideal_contents_scale_));
917    max_acceptable_high_res_scale = std::max(
918        max_acceptable_high_res_scale,
919        std::max(twin->raster_contents_scale_, twin->ideal_contents_scale_));
920  }
921
922  std::vector<PictureLayerTiling*> to_remove;
923  for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
924    PictureLayerTiling* tiling = tilings_->tiling_at(i);
925
926    // Keep multiple high resolution tilings even if not used to help
927    // activate earlier at non-ideal resolutions.
928    if (tiling->contents_scale() >= min_acceptable_high_res_scale &&
929        tiling->contents_scale() <= max_acceptable_high_res_scale)
930      continue;
931
932    // Low resolution can't activate, so only keep one around.
933    if (tiling->resolution() == LOW_RESOLUTION)
934      continue;
935
936    // Don't remove tilings that are being used (and thus would cause a flash.)
937    if (std::find(used_tilings.begin(), used_tilings.end(), tiling) !=
938        used_tilings.end())
939      continue;
940
941    to_remove.push_back(tiling);
942  }
943
944  for (size_t i = 0; i < to_remove.size(); ++i) {
945    if (twin)
946      twin->RemoveTiling(to_remove[i]->contents_scale());
947    tilings_->Remove(to_remove[i]);
948  }
949}
950
951float PictureLayerImpl::MinimumContentsScale() const {
952  float setting_min = layer_tree_impl()->settings().minimum_contents_scale;
953
954  // If the contents scale is less than 1 / width (also for height),
955  // then it will end up having less than one pixel of content in that
956  // dimension.  Bump the minimum contents scale up in this case to prevent
957  // this from happening.
958  int min_dimension = std::min(bounds().width(), bounds().height());
959  if (!min_dimension)
960    return setting_min;
961
962  return std::max(1.f / min_dimension, setting_min);
963}
964
965void PictureLayerImpl::UpdateLCDTextStatus(bool new_status) {
966  // Once this layer is not using lcd text, don't switch back.
967  if (!is_using_lcd_text_)
968    return;
969
970  if (is_using_lcd_text_ == new_status)
971    return;
972
973  is_using_lcd_text_ = new_status;
974  tilings_->SetCanUseLCDText(is_using_lcd_text_);
975}
976
977void PictureLayerImpl::ResetRasterScale() {
978  raster_page_scale_ = 0.f;
979  raster_device_scale_ = 0.f;
980  raster_source_scale_ = 0.f;
981  raster_contents_scale_ = 0.f;
982  low_res_raster_contents_scale_ = 0.f;
983}
984
985bool PictureLayerImpl::CanHaveTilings() const {
986  if (!DrawsContent())
987    return false;
988  if (pile_->recorded_region().IsEmpty())
989    return false;
990  if (draw_properties().can_draw_directly_to_backbuffer &&
991      layer_tree_impl()->settings().force_direct_layer_drawing)
992    return false;
993  return true;
994}
995
996bool PictureLayerImpl::CanHaveTilingWithScale(float contents_scale) const {
997  if (!CanHaveTilings())
998    return false;
999  if (contents_scale < MinimumContentsScale())
1000    return false;
1001  return true;
1002}
1003
1004void PictureLayerImpl::GetDebugBorderProperties(
1005    SkColor* color,
1006    float* width) const {
1007  *color = DebugColors::TiledContentLayerBorderColor();
1008  *width = DebugColors::TiledContentLayerBorderWidth(layer_tree_impl());
1009}
1010
1011void PictureLayerImpl::AsValueInto(base::DictionaryValue* state) const {
1012  LayerImpl::AsValueInto(state);
1013  state->SetDouble("ideal_contents_scale", ideal_contents_scale_);
1014  state->Set("tilings", tilings_->AsValue().release());
1015  state->Set("pictures", pile_->AsValue().release());
1016  state->Set("invalidation", invalidation_.AsValue().release());
1017
1018  scoped_ptr<base::ListValue> coverage_tiles(new base::ListValue);
1019  for (PictureLayerTilingSet::CoverageIterator iter(tilings_.get(),
1020                                                    contents_scale_x(),
1021                                                    gfx::Rect(bounds()),
1022                                                    ideal_contents_scale_);
1023       iter;
1024       ++iter) {
1025    scoped_ptr<base::DictionaryValue> tile_data(new base::DictionaryValue);
1026    tile_data->Set("geometry_rect",
1027                   MathUtil::AsValue(iter.geometry_rect()).release());
1028    if (*iter)
1029      tile_data->Set("tile", TracedValue::CreateIDRef(*iter).release());
1030
1031    coverage_tiles->Append(tile_data.release());
1032  }
1033  state->Set("coverage_tiles", coverage_tiles.release());
1034}
1035
1036size_t PictureLayerImpl::GPUMemoryUsageInBytes() const {
1037  return tilings_->GPUMemoryUsageInBytes();
1038}
1039
1040}  // namespace cc
1041