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