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