Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/layers/picture_layer_impl.h" | 5 #include "cc/layers/picture_layer_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <set> | 9 #include <set> |
| 10 | 10 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 68 ideal_source_scale_(0.f), | 68 ideal_source_scale_(0.f), |
| 69 ideal_contents_scale_(0.f), | 69 ideal_contents_scale_(0.f), |
| 70 raster_page_scale_(0.f), | 70 raster_page_scale_(0.f), |
| 71 raster_device_scale_(0.f), | 71 raster_device_scale_(0.f), |
| 72 raster_source_scale_(0.f), | 72 raster_source_scale_(0.f), |
| 73 raster_contents_scale_(0.f), | 73 raster_contents_scale_(0.f), |
| 74 low_res_raster_contents_scale_(0.f), | 74 low_res_raster_contents_scale_(0.f), |
| 75 raster_source_scale_is_fixed_(false), | 75 raster_source_scale_is_fixed_(false), |
| 76 was_screen_space_transform_animating_(false), | 76 was_screen_space_transform_animating_(false), |
| 77 needs_post_commit_initialization_(true), | 77 needs_post_commit_initialization_(true), |
| 78 should_update_tile_priorities_(false) { | 78 should_update_tile_priorities_(false), |
| 79 only_used_low_res_last_append_quads_(false) { | |
| 79 layer_tree_impl()->RegisterPictureLayerImpl(this); | 80 layer_tree_impl()->RegisterPictureLayerImpl(this); |
| 80 } | 81 } |
| 81 | 82 |
| 82 PictureLayerImpl::~PictureLayerImpl() { | 83 PictureLayerImpl::~PictureLayerImpl() { |
| 83 layer_tree_impl()->UnregisterPictureLayerImpl(this); | 84 layer_tree_impl()->UnregisterPictureLayerImpl(this); |
| 84 } | 85 } |
| 85 | 86 |
| 86 const char* PictureLayerImpl::LayerTypeAsString() const { | 87 const char* PictureLayerImpl::LayerTypeAsString() const { |
| 87 return "cc::PictureLayerImpl"; | 88 return "cc::PictureLayerImpl"; |
| 88 } | 89 } |
| 89 | 90 |
| 90 scoped_ptr<LayerImpl> PictureLayerImpl::CreateLayerImpl( | 91 scoped_ptr<LayerImpl> PictureLayerImpl::CreateLayerImpl( |
| 91 LayerTreeImpl* tree_impl) { | 92 LayerTreeImpl* tree_impl) { |
| 92 return PictureLayerImpl::Create(tree_impl, id()); | 93 return PictureLayerImpl::Create(tree_impl, id()); |
| 93 } | 94 } |
| 94 | 95 |
| 95 void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) { | 96 void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) { |
| 96 // It's possible this layer was never drawn or updated (e.g. because it was | 97 // It's possible this layer was never drawn or updated (e.g. because it was |
| 97 // a descendant of an opacity 0 layer). | 98 // a descendant of an opacity 0 layer). |
| 98 DoPostCommitInitializationIfNeeded(); | 99 DoPostCommitInitializationIfNeeded(); |
| 99 PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer); | 100 PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer); |
| 100 | 101 |
| 101 // We have already synced the important bits from the the active layer, and | |
| 102 // we will soon swap out its tilings and use them for recycling. However, | |
| 103 // there are now tiles in this layer's tilings that were unref'd and replaced | |
| 104 // with new tiles (due to invalidation). This resets all active priorities on | |
| 105 // the to-be-recycled tiling to ensure replaced tiles don't linger and take | |
| 106 // memory (due to a stale 'active' priority). | |
| 107 if (layer_impl->tilings_) | |
| 108 layer_impl->tilings_->DidBecomeRecycled(); | |
| 109 | |
| 110 LayerImpl::PushPropertiesTo(base_layer); | 102 LayerImpl::PushPropertiesTo(base_layer); |
| 111 | 103 |
| 112 // When the pending tree pushes to the active tree, the pending twin | 104 // When the pending tree pushes to the active tree, the pending twin |
| 113 // becomes recycled. | 105 // becomes recycled. |
| 114 layer_impl->twin_layer_ = NULL; | 106 layer_impl->twin_layer_ = NULL; |
| 115 twin_layer_ = NULL; | 107 twin_layer_ = NULL; |
| 116 | 108 |
| 117 layer_impl->pile_ = pile_; | 109 layer_impl->pile_ = pile_; |
| 118 | 110 |
| 119 DCHECK(!pile_->is_solid_color() || !tilings_->num_tilings()); | 111 DCHECK(!pile_->is_solid_color() || !tilings_->num_tilings()); |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 248 SkColor color; | 240 SkColor color; |
| 249 float width; | 241 float width; |
| 250 if (*iter && iter->IsReadyToDraw()) { | 242 if (*iter && iter->IsReadyToDraw()) { |
| 251 ManagedTileState::DrawInfo::Mode mode = iter->draw_info().mode(); | 243 ManagedTileState::DrawInfo::Mode mode = iter->draw_info().mode(); |
| 252 if (mode == ManagedTileState::DrawInfo::SOLID_COLOR_MODE) { | 244 if (mode == ManagedTileState::DrawInfo::SOLID_COLOR_MODE) { |
| 253 color = DebugColors::SolidColorTileBorderColor(); | 245 color = DebugColors::SolidColorTileBorderColor(); |
| 254 width = DebugColors::SolidColorTileBorderWidth(layer_tree_impl()); | 246 width = DebugColors::SolidColorTileBorderWidth(layer_tree_impl()); |
| 255 } else if (mode == ManagedTileState::DrawInfo::PICTURE_PILE_MODE) { | 247 } else if (mode == ManagedTileState::DrawInfo::PICTURE_PILE_MODE) { |
| 256 color = DebugColors::PictureTileBorderColor(); | 248 color = DebugColors::PictureTileBorderColor(); |
| 257 width = DebugColors::PictureTileBorderWidth(layer_tree_impl()); | 249 width = DebugColors::PictureTileBorderWidth(layer_tree_impl()); |
| 258 } else if (iter->priority(ACTIVE_TREE).resolution == HIGH_RESOLUTION) { | 250 } else if (iter.resolution() == HIGH_RESOLUTION) { |
| 259 color = DebugColors::HighResTileBorderColor(); | 251 color = DebugColors::HighResTileBorderColor(); |
| 260 width = DebugColors::HighResTileBorderWidth(layer_tree_impl()); | 252 width = DebugColors::HighResTileBorderWidth(layer_tree_impl()); |
| 261 } else if (iter->priority(ACTIVE_TREE).resolution == LOW_RESOLUTION) { | 253 } else if (iter.resolution() == LOW_RESOLUTION) { |
| 262 color = DebugColors::LowResTileBorderColor(); | 254 color = DebugColors::LowResTileBorderColor(); |
| 263 width = DebugColors::LowResTileBorderWidth(layer_tree_impl()); | 255 width = DebugColors::LowResTileBorderWidth(layer_tree_impl()); |
| 264 } else if (iter->contents_scale() > max_contents_scale) { | 256 } else if (iter->contents_scale() > max_contents_scale) { |
| 265 color = DebugColors::ExtraHighResTileBorderColor(); | 257 color = DebugColors::ExtraHighResTileBorderColor(); |
| 266 width = DebugColors::ExtraHighResTileBorderWidth(layer_tree_impl()); | 258 width = DebugColors::ExtraHighResTileBorderWidth(layer_tree_impl()); |
| 267 } else { | 259 } else { |
| 268 color = DebugColors::ExtraLowResTileBorderColor(); | 260 color = DebugColors::ExtraLowResTileBorderColor(); |
| 269 width = DebugColors::ExtraLowResTileBorderWidth(layer_tree_impl()); | 261 width = DebugColors::ExtraLowResTileBorderWidth(layer_tree_impl()); |
| 270 } | 262 } |
| 271 } else { | 263 } else { |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 290 std::vector<PictureLayerTiling*> seen_tilings; | 282 std::vector<PictureLayerTiling*> seen_tilings; |
| 291 | 283 |
| 292 // Ignore missing tiles outside of viewport for tile priority. This is | 284 // Ignore missing tiles outside of viewport for tile priority. This is |
| 293 // normally the same as draw viewport but can be independently overridden by | 285 // normally the same as draw viewport but can be independently overridden by |
| 294 // embedders like Android WebView with SetExternalDrawConstraints. | 286 // embedders like Android WebView with SetExternalDrawConstraints. |
| 295 gfx::Rect scaled_viewport_for_tile_priority = gfx::ScaleToEnclosingRect( | 287 gfx::Rect scaled_viewport_for_tile_priority = gfx::ScaleToEnclosingRect( |
| 296 GetViewportForTilePriorityInContentSpace(), max_contents_scale); | 288 GetViewportForTilePriorityInContentSpace(), max_contents_scale); |
| 297 | 289 |
| 298 size_t missing_tile_count = 0u; | 290 size_t missing_tile_count = 0u; |
| 299 size_t on_demand_missing_tile_count = 0u; | 291 size_t on_demand_missing_tile_count = 0u; |
| 292 only_used_low_res_last_append_quads_ = true; | |
| 300 for (PictureLayerTilingSet::CoverageIterator iter(tilings_.get(), | 293 for (PictureLayerTilingSet::CoverageIterator iter(tilings_.get(), |
| 301 max_contents_scale, | 294 max_contents_scale, |
| 302 scaled_visible_content_rect, | 295 scaled_visible_content_rect, |
| 303 ideal_contents_scale_); | 296 ideal_contents_scale_); |
| 304 iter; | 297 iter; |
| 305 ++iter) { | 298 ++iter) { |
| 306 gfx::Rect geometry_rect = iter.geometry_rect(); | 299 gfx::Rect geometry_rect = iter.geometry_rect(); |
| 307 gfx::Rect opaque_rect = contents_opaque() ? geometry_rect : gfx::Rect(); | 300 gfx::Rect opaque_rect = contents_opaque() ? geometry_rect : gfx::Rect(); |
| 308 gfx::Rect visible_geometry_rect = | 301 gfx::Rect visible_geometry_rect = |
| 309 occlusion.GetUnoccludedContentRect(geometry_rect); | 302 occlusion.GetUnoccludedContentRect(geometry_rect); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 408 | 401 |
| 409 if (geometry_rect.Intersects(scaled_viewport_for_tile_priority)) { | 402 if (geometry_rect.Intersects(scaled_viewport_for_tile_priority)) { |
| 410 append_quads_data->num_missing_tiles++; | 403 append_quads_data->num_missing_tiles++; |
| 411 ++missing_tile_count; | 404 ++missing_tile_count; |
| 412 } | 405 } |
| 413 append_quads_data->approximated_visible_content_area += | 406 append_quads_data->approximated_visible_content_area += |
| 414 visible_geometry_rect.width() * visible_geometry_rect.height(); | 407 visible_geometry_rect.width() * visible_geometry_rect.height(); |
| 415 continue; | 408 continue; |
| 416 } | 409 } |
| 417 | 410 |
| 418 if (iter->priority(ACTIVE_TREE).resolution != HIGH_RESOLUTION) { | 411 if (iter.resolution() != HIGH_RESOLUTION) { |
| 419 append_quads_data->approximated_visible_content_area += | 412 append_quads_data->approximated_visible_content_area += |
| 420 visible_geometry_rect.width() * visible_geometry_rect.height(); | 413 visible_geometry_rect.width() * visible_geometry_rect.height(); |
| 421 } | 414 } |
| 422 | 415 |
| 416 // If we have a draw quad, but it's not low resolution, then | |
| 417 // mark that we've used something other than low res to draw. | |
| 418 if (iter.resolution() != LOW_RESOLUTION) | |
| 419 only_used_low_res_last_append_quads_ = false; | |
| 420 | |
| 423 if (seen_tilings.empty() || seen_tilings.back() != iter.CurrentTiling()) | 421 if (seen_tilings.empty() || seen_tilings.back() != iter.CurrentTiling()) |
| 424 seen_tilings.push_back(iter.CurrentTiling()); | 422 seen_tilings.push_back(iter.CurrentTiling()); |
| 425 } | 423 } |
| 426 | 424 |
| 427 if (missing_tile_count) { | 425 if (missing_tile_count) { |
| 428 TRACE_EVENT_INSTANT2("cc", | 426 TRACE_EVENT_INSTANT2("cc", |
| 429 "PictureLayerImpl::AppendQuads checkerboard", | 427 "PictureLayerImpl::AppendQuads checkerboard", |
| 430 TRACE_EVENT_SCOPE_THREAD, | 428 TRACE_EVENT_SCOPE_THREAD, |
| 431 "missing_tile_count", | 429 "missing_tile_count", |
| 432 missing_tile_count, | 430 missing_tile_count, |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 484 DCHECK(raster_source_scale_); | 482 DCHECK(raster_source_scale_); |
| 485 DCHECK(raster_contents_scale_); | 483 DCHECK(raster_contents_scale_); |
| 486 DCHECK(low_res_raster_contents_scale_); | 484 DCHECK(low_res_raster_contents_scale_); |
| 487 | 485 |
| 488 was_screen_space_transform_animating_ = | 486 was_screen_space_transform_animating_ = |
| 489 draw_properties().screen_space_transform_is_animating; | 487 draw_properties().screen_space_transform_is_animating; |
| 490 | 488 |
| 491 should_update_tile_priorities_ = true; | 489 should_update_tile_priorities_ = true; |
| 492 | 490 |
| 493 UpdateTilePriorities(occlusion_in_content_space); | 491 UpdateTilePriorities(occlusion_in_content_space); |
| 494 | |
| 495 if (layer_tree_impl()->IsPendingTree()) | |
| 496 MarkVisibleResourcesAsRequired(); | |
| 497 } | 492 } |
| 498 | 493 |
| 499 void PictureLayerImpl::UpdateTilePriorities( | 494 void PictureLayerImpl::UpdateTilePriorities( |
| 500 const Occlusion& occlusion_in_content_space) { | 495 const Occlusion& occlusion_in_content_space) { |
| 501 DCHECK(!pile_->is_solid_color() || !tilings_->num_tilings()); | 496 DCHECK(!pile_->is_solid_color() || !tilings_->num_tilings()); |
| 502 | 497 |
| 503 TRACE_EVENT0("cc", "PictureLayerImpl::UpdateTilePriorities"); | 498 TRACE_EVENT0("cc", "PictureLayerImpl::UpdateTilePriorities"); |
| 504 | 499 |
| 505 double current_frame_time_in_seconds = | 500 double current_frame_time_in_seconds = |
| 506 (layer_tree_impl()->CurrentBeginFrameArgs().frame_time - | 501 (layer_tree_impl()->CurrentBeginFrameArgs().frame_time - |
| 507 base::TimeTicks()).InSecondsF(); | 502 base::TimeTicks()).InSecondsF(); |
| 508 | 503 |
| 509 bool tiling_needs_update = false; | 504 bool tiling_needs_update = false; |
| 510 for (size_t i = 0; i < tilings_->num_tilings(); ++i) { | 505 for (size_t i = 0; i < tilings_->num_tilings(); ++i) { |
| 511 if (tilings_->tiling_at(i)->NeedsUpdateForFrameAtTime( | 506 if (tilings_->tiling_at(i)->NeedsUpdateForFrameAtTime( |
| 512 current_frame_time_in_seconds)) { | 507 current_frame_time_in_seconds)) { |
| 513 tiling_needs_update = true; | 508 tiling_needs_update = true; |
| 514 break; | 509 break; |
| 515 } | 510 } |
| 516 } | 511 } |
| 517 if (!tiling_needs_update) | 512 if (!tiling_needs_update) |
| 518 return; | 513 return; |
| 519 | 514 |
| 520 gfx::Rect viewport_rect_in_layer_space = | 515 gfx::Rect viewport_rect_in_layer_space = |
| 521 GetViewportForTilePriorityInContentSpace(); | 516 GetViewportForTilePriorityInContentSpace(); |
| 522 WhichTree tree = | 517 WhichTree tree = |
| 523 layer_tree_impl()->IsActiveTree() ? ACTIVE_TREE : PENDING_TREE; | 518 layer_tree_impl()->IsActiveTree() ? ACTIVE_TREE : PENDING_TREE; |
| 519 bool can_require_tiles_for_activation = | |
| 520 !only_used_low_res_last_append_quads_ || RequiresHighResToDraw() || | |
| 521 !layer_tree_impl()->SmoothnessTakesPriority(); | |
| 524 for (size_t i = 0; i < tilings_->num_tilings(); ++i) { | 522 for (size_t i = 0; i < tilings_->num_tilings(); ++i) { |
| 523 PictureLayerTiling* tiling = tilings_->tiling_at(i); | |
| 524 | |
| 525 tiling->set_can_require_tiles_for_activation( | |
|
danakj
2014/10/08 18:46:25
is there a test that ensures we activate without r
vmpstr
2014/10/08 22:38:34
Not that one in particular.. I've added a test to
danakj
2014/10/08 23:38:01
OK, do we have a test that verifies we save the "o
vmpstr
2014/10/09 00:01:42
Makes sense, I'll add a test.
| |
| 526 can_require_tiles_for_activation); | |
| 527 | |
| 525 // Pass |occlusion_in_content_space| for |occlusion_in_layer_space| since | 528 // Pass |occlusion_in_content_space| for |occlusion_in_layer_space| since |
| 526 // they are the same space in picture lbayer, as contents scale is always 1. | 529 // they are the same space in picture layer, as contents scale is always 1. |
| 527 tilings_->tiling_at(i)->UpdateTilePriorities(tree, | 530 tiling->ComputeTilePriorityRects(tree, |
| 528 viewport_rect_in_layer_space, | 531 viewport_rect_in_layer_space, |
| 529 ideal_contents_scale_, | 532 ideal_contents_scale_, |
| 530 current_frame_time_in_seconds, | 533 current_frame_time_in_seconds, |
| 531 occlusion_in_content_space); | 534 occlusion_in_content_space); |
| 532 } | 535 } |
| 533 | 536 |
| 534 // Tile priorities were modified. | 537 // Tile priorities were modified. |
| 538 // TODO(vmpstr): See if this can be removed in favour of calling it from LTHI | |
| 535 layer_tree_impl()->DidModifyTilePriorities(); | 539 layer_tree_impl()->DidModifyTilePriorities(); |
| 536 } | 540 } |
| 537 | 541 |
| 538 gfx::Rect PictureLayerImpl::GetViewportForTilePriorityInContentSpace() const { | 542 gfx::Rect PictureLayerImpl::GetViewportForTilePriorityInContentSpace() const { |
| 539 // If visible_rect_for_tile_priority_ is empty or | 543 // If visible_rect_for_tile_priority_ is empty or |
| 540 // viewport_rect_for_tile_priority_ is set to be different from the device | 544 // viewport_rect_for_tile_priority_ is set to be different from the device |
| 541 // viewport, try to inverse project the viewport into layer space and use | 545 // viewport, try to inverse project the viewport into layer space and use |
| 542 // that. Otherwise just use visible_rect_for_tile_priority_ | 546 // that. Otherwise just use visible_rect_for_tile_priority_ |
| 543 gfx::Rect visible_rect_in_content_space = visible_rect_for_tile_priority_; | 547 gfx::Rect visible_rect_in_content_space = visible_rect_for_tile_priority_; |
| 544 | 548 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 565 void PictureLayerImpl::NotifyTileStateChanged(const Tile* tile) { | 569 void PictureLayerImpl::NotifyTileStateChanged(const Tile* tile) { |
| 566 if (layer_tree_impl()->IsActiveTree()) { | 570 if (layer_tree_impl()->IsActiveTree()) { |
| 567 gfx::RectF layer_damage_rect = | 571 gfx::RectF layer_damage_rect = |
| 568 gfx::ScaleRect(tile->content_rect(), 1.f / tile->contents_scale()); | 572 gfx::ScaleRect(tile->content_rect(), 1.f / tile->contents_scale()); |
| 569 AddDamageRect(layer_damage_rect); | 573 AddDamageRect(layer_damage_rect); |
| 570 } | 574 } |
| 571 } | 575 } |
| 572 | 576 |
| 573 void PictureLayerImpl::DidBecomeActive() { | 577 void PictureLayerImpl::DidBecomeActive() { |
| 574 LayerImpl::DidBecomeActive(); | 578 LayerImpl::DidBecomeActive(); |
| 575 tilings_->DidBecomeActive(); | 579 // TODO(vmpstr): See if this can be removed in favour of calling it from LTHI |
| 576 layer_tree_impl()->DidModifyTilePriorities(); | 580 layer_tree_impl()->DidModifyTilePriorities(); |
| 577 } | 581 } |
| 578 | 582 |
| 579 void PictureLayerImpl::DidBeginTracing() { | 583 void PictureLayerImpl::DidBeginTracing() { |
| 580 pile_->DidBeginTracing(); | 584 pile_->DidBeginTracing(); |
| 581 } | 585 } |
| 582 | 586 |
| 583 void PictureLayerImpl::ReleaseResources() { | 587 void PictureLayerImpl::ReleaseResources() { |
| 584 if (tilings_) | 588 if (tilings_) |
| 585 RemoveAllTilings(); | 589 RemoveAllTilings(); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 659 layer_tree_impl()->begin_impl_frame_interval().InSecondsF() * | 663 layer_tree_impl()->begin_impl_frame_interval().InSecondsF() * |
| 660 layer_tree_impl()->settings().skewport_target_time_multiplier; | 664 layer_tree_impl()->settings().skewport_target_time_multiplier; |
| 661 } | 665 } |
| 662 | 666 |
| 663 int PictureLayerImpl::GetSkewportExtrapolationLimitInContentPixels() const { | 667 int PictureLayerImpl::GetSkewportExtrapolationLimitInContentPixels() const { |
| 664 return layer_tree_impl() | 668 return layer_tree_impl() |
| 665 ->settings() | 669 ->settings() |
| 666 .skewport_extrapolation_limit_in_content_pixels; | 670 .skewport_extrapolation_limit_in_content_pixels; |
| 667 } | 671 } |
| 668 | 672 |
| 673 bool PictureLayerImpl::RequiresHighResToDraw() const { | |
| 674 const PictureLayerImpl* layer = this; | |
| 675 if (layer_tree_impl()->IsPendingTree()) | |
| 676 layer = twin_layer_; | |
| 677 if (layer) | |
|
danakj
2014/10/08 18:46:25
can you make this not depend on there being a twin
vmpstr
2014/10/08 22:38:34
Will do once https://codereview.chromium.org/64087
| |
| 678 return layer->layer_tree_impl()->RequiresHighResToDraw(); | |
| 679 return false; | |
| 680 } | |
| 681 | |
| 669 gfx::Size PictureLayerImpl::CalculateTileSize( | 682 gfx::Size PictureLayerImpl::CalculateTileSize( |
| 670 const gfx::Size& content_bounds) const { | 683 const gfx::Size& content_bounds) const { |
| 671 int max_texture_size = | 684 int max_texture_size = |
| 672 layer_tree_impl()->resource_provider()->max_texture_size(); | 685 layer_tree_impl()->resource_provider()->max_texture_size(); |
| 673 | 686 |
| 674 if (pile_->is_mask()) { | 687 if (pile_->is_mask()) { |
| 675 // Masks are not tiled, so if we can't cover the whole mask with one tile, | 688 // Masks are not tiled, so if we can't cover the whole mask with one tile, |
| 676 // don't make any tiles at all. Returning an empty size signals this. | 689 // don't make any tiles at all. Returning an empty size signals this. |
| 677 if (content_bounds.width() > max_texture_size || | 690 if (content_bounds.width() > max_texture_size || |
| 678 content_bounds.height() > max_texture_size) | 691 content_bounds.height() > max_texture_size) |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 796 << content_rect.ToString(); | 809 << content_rect.ToString(); |
| 797 | 810 |
| 798 const ManagedTileState::DrawInfo& draw_info = iter->draw_info(); | 811 const ManagedTileState::DrawInfo& draw_info = iter->draw_info(); |
| 799 if (!draw_info.IsReadyToDraw() || | 812 if (!draw_info.IsReadyToDraw() || |
| 800 draw_info.mode() != ManagedTileState::DrawInfo::RESOURCE_MODE) | 813 draw_info.mode() != ManagedTileState::DrawInfo::RESOURCE_MODE) |
| 801 return 0; | 814 return 0; |
| 802 | 815 |
| 803 return draw_info.get_resource_id(); | 816 return draw_info.get_resource_id(); |
| 804 } | 817 } |
| 805 | 818 |
| 806 void PictureLayerImpl::MarkVisibleResourcesAsRequired() const { | |
| 807 DCHECK(layer_tree_impl()->IsPendingTree()); | |
| 808 DCHECK(ideal_contents_scale_); | |
| 809 DCHECK_GT(tilings_->num_tilings(), 0u); | |
| 810 | |
| 811 // The goal of this function is to find the minimum set of tiles that need to | |
| 812 // be ready to draw in order to activate without flashing content from a | |
| 813 // higher res on the active tree to a lower res on the pending tree. | |
| 814 | |
| 815 // First, early out for layers with no visible content. | |
| 816 if (visible_rect_for_tile_priority_.IsEmpty()) | |
| 817 return; | |
| 818 | |
| 819 // Only mark tiles inside the viewport for tile priority as required for | |
| 820 // activation. This viewport is normally the same as the draw viewport but | |
| 821 // can be independently overridden by embedders like Android WebView with | |
| 822 // SetExternalDrawConstraints. | |
| 823 gfx::Rect rect = GetViewportForTilePriorityInContentSpace(); | |
| 824 rect.Intersect(visible_rect_for_tile_priority_); | |
| 825 | |
| 826 float min_acceptable_scale = | |
| 827 std::min(raster_contents_scale_, ideal_contents_scale_); | |
| 828 | |
| 829 if (PictureLayerImpl* twin = twin_layer_) { | |
| 830 float twin_min_acceptable_scale = | |
| 831 std::min(twin->ideal_contents_scale_, twin->raster_contents_scale_); | |
| 832 // Ignore 0 scale in case CalculateContentsScale() has never been | |
| 833 // called for active twin. | |
| 834 if (twin_min_acceptable_scale != 0.0f) { | |
| 835 min_acceptable_scale = | |
| 836 std::min(min_acceptable_scale, twin_min_acceptable_scale); | |
| 837 } | |
| 838 } | |
| 839 | |
| 840 PictureLayerTiling* high_res = NULL; | |
| 841 PictureLayerTiling* low_res = NULL; | |
| 842 | |
| 843 // First pass: ready to draw tiles in acceptable but non-ideal tilings are | |
| 844 // marked as required for activation so that their textures are not thrown | |
| 845 // away; any non-ready tiles are not marked as required. | |
| 846 Region missing_region = rect; | |
| 847 for (size_t i = 0; i < tilings_->num_tilings(); ++i) { | |
| 848 PictureLayerTiling* tiling = tilings_->tiling_at(i); | |
| 849 DCHECK(tiling->has_ever_been_updated()); | |
| 850 | |
| 851 if (tiling->resolution() == LOW_RESOLUTION) { | |
| 852 DCHECK(!low_res) << "There can only be one low res tiling"; | |
| 853 low_res = tiling; | |
| 854 } | |
| 855 if (tiling->contents_scale() < min_acceptable_scale) | |
| 856 continue; | |
| 857 if (tiling->resolution() == HIGH_RESOLUTION) { | |
| 858 DCHECK(!high_res) << "There can only be one high res tiling"; | |
| 859 high_res = tiling; | |
| 860 continue; | |
| 861 } | |
| 862 for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f, rect); iter; | |
| 863 ++iter) { | |
| 864 if (!*iter || !iter->IsReadyToDraw()) | |
| 865 continue; | |
| 866 | |
| 867 missing_region.Subtract(iter.geometry_rect()); | |
| 868 iter->MarkRequiredForActivation(); | |
| 869 } | |
| 870 } | |
| 871 DCHECK(high_res) << "There must be one high res tiling"; | |
| 872 | |
| 873 // If these pointers are null (because no twin, no matching tiling, or the | |
| 874 // simpification just below), then high res tiles will be required to fill any | |
| 875 // holes left by the first pass above. If the pointers are valid, then this | |
| 876 // layer is allowed to skip any tiles that are not ready on its twin. | |
| 877 const PictureLayerTiling* twin_high_res = NULL; | |
| 878 const PictureLayerTiling* twin_low_res = NULL; | |
| 879 | |
| 880 if (twin_layer_) { | |
| 881 // As a simplification, only allow activating to skip twin tiles that the | |
| 882 // active layer is also missing when both this layer and its twin have | |
| 883 // "simple" sets of tilings: only 2 tilings (high and low) or only 1 high | |
| 884 // res tiling. This avoids having to iterate/track coverage of non-ideal | |
| 885 // tilings during the last draw call on the active layer. | |
| 886 if (tilings_->num_tilings() <= 2 && | |
| 887 twin_layer_->tilings_->num_tilings() <= tilings_->num_tilings()) { | |
| 888 twin_low_res = low_res ? GetTwinTiling(low_res) : NULL; | |
| 889 twin_high_res = high_res ? GetTwinTiling(high_res) : NULL; | |
| 890 } | |
| 891 | |
| 892 // If this layer and its twin have different transforms, then don't compare | |
| 893 // them and only allow activating to high res tiles, since tiles on each | |
| 894 // layer will be in different places on screen. | |
| 895 if (twin_layer_->layer_tree_impl()->RequiresHighResToDraw() || | |
| 896 bounds() != twin_layer_->bounds() || | |
| 897 draw_properties().screen_space_transform != | |
| 898 twin_layer_->draw_properties().screen_space_transform) { | |
| 899 twin_high_res = NULL; | |
| 900 twin_low_res = NULL; | |
| 901 } | |
| 902 } | |
| 903 | |
| 904 // As a second pass, mark as required any visible high res tiles not filled in | |
| 905 // by acceptable non-ideal tiles from the first pass. | |
| 906 if (MarkVisibleTilesAsRequired( | |
| 907 high_res, twin_high_res, rect, missing_region)) { | |
| 908 // As an optional third pass, if a high res tile was skipped because its | |
| 909 // twin was also missing, then fall back to mark low res tiles as required | |
| 910 // in case the active twin is substituting those for missing high res | |
| 911 // content. Only suitable, when low res is enabled. | |
| 912 if (low_res) { | |
| 913 MarkVisibleTilesAsRequired(low_res, twin_low_res, rect, missing_region); | |
| 914 } | |
| 915 } | |
| 916 } | |
| 917 | |
| 918 bool PictureLayerImpl::MarkVisibleTilesAsRequired( | |
| 919 PictureLayerTiling* tiling, | |
| 920 const PictureLayerTiling* optional_twin_tiling, | |
| 921 const gfx::Rect& rect, | |
| 922 const Region& missing_region) const { | |
| 923 bool twin_had_missing_tile = false; | |
| 924 for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f, rect); iter; | |
| 925 ++iter) { | |
| 926 Tile* tile = *iter; | |
| 927 // A null tile (i.e. missing recording) can just be skipped. | |
| 928 if (!tile) | |
| 929 continue; | |
| 930 | |
| 931 // If the tile is occluded, don't mark it as required for activation. | |
| 932 if (tile->is_occluded(PENDING_TREE)) | |
| 933 continue; | |
| 934 | |
| 935 // If the missing region doesn't cover it, this tile is fully | |
| 936 // covered by acceptable tiles at other scales. | |
| 937 if (!missing_region.Intersects(iter.geometry_rect())) | |
| 938 continue; | |
| 939 | |
| 940 // If the twin tile doesn't exist (i.e. missing recording or so far away | |
| 941 // that it is outside the visible tile rect) or this tile is shared between | |
| 942 // with the twin, then this tile isn't required to prevent flashing. | |
| 943 if (optional_twin_tiling) { | |
| 944 Tile* twin_tile = optional_twin_tiling->TileAt(iter.i(), iter.j()); | |
| 945 if (!twin_tile || twin_tile == tile) { | |
| 946 // However if the shared tile is being used on the active tree, then | |
| 947 // there's no missing content in this place, and low res is not needed. | |
| 948 if (!twin_tile || !twin_tile->IsReadyToDraw()) | |
| 949 twin_had_missing_tile = true; | |
| 950 continue; | |
| 951 } | |
| 952 } | |
| 953 | |
| 954 tile->MarkRequiredForActivation(); | |
| 955 } | |
| 956 return twin_had_missing_tile; | |
| 957 } | |
| 958 | |
| 959 void PictureLayerImpl::DoPostCommitInitialization() { | 819 void PictureLayerImpl::DoPostCommitInitialization() { |
| 960 DCHECK(needs_post_commit_initialization_); | 820 DCHECK(needs_post_commit_initialization_); |
| 961 DCHECK(layer_tree_impl()->IsPendingTree()); | 821 DCHECK(layer_tree_impl()->IsPendingTree()); |
| 962 | 822 |
| 963 if (!tilings_) | 823 if (!tilings_) |
| 964 tilings_.reset(new PictureLayerTilingSet(this, bounds())); | 824 tilings_.reset(new PictureLayerTilingSet(this, bounds())); |
| 965 | 825 |
| 966 DCHECK(!twin_layer_); | 826 DCHECK(!twin_layer_); |
| 967 twin_layer_ = static_cast<PictureLayerImpl*>( | 827 twin_layer_ = static_cast<PictureLayerImpl*>( |
| 968 layer_tree_impl()->FindActiveTreeLayerById(id())); | 828 layer_tree_impl()->FindActiveTreeLayerById(id())); |
| (...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1346 if (layer_tree_impl()->IsRecycleTree()) | 1206 if (layer_tree_impl()->IsRecycleTree()) |
| 1347 return; | 1207 return; |
| 1348 | 1208 |
| 1349 if (!CanHaveTilings()) { | 1209 if (!CanHaveTilings()) { |
| 1350 DCHECK_EQ(0u, tilings_->num_tilings()); | 1210 DCHECK_EQ(0u, tilings_->num_tilings()); |
| 1351 return; | 1211 return; |
| 1352 } | 1212 } |
| 1353 if (tilings_->num_tilings() == 0) | 1213 if (tilings_->num_tilings() == 0) |
| 1354 return; | 1214 return; |
| 1355 | 1215 |
| 1356 // MarkVisibleResourcesAsRequired depends on having exactly 1 high res | 1216 // We should only have one high res tiling. |
| 1357 // tiling to mark its tiles as being required for activation. | |
| 1358 DCHECK_EQ(1, tilings_->NumHighResTilings()); | 1217 DCHECK_EQ(1, tilings_->NumHighResTilings()); |
| 1359 #endif | 1218 #endif |
| 1360 } | 1219 } |
| 1361 | 1220 |
| 1362 bool PictureLayerImpl::ShouldAdjustRasterScaleDuringScaleAnimations() const { | 1221 bool PictureLayerImpl::ShouldAdjustRasterScaleDuringScaleAnimations() const { |
| 1363 if (!layer_tree_impl()->use_gpu_rasterization()) | 1222 if (!layer_tree_impl()->use_gpu_rasterization()) |
| 1364 return false; | 1223 return false; |
| 1365 | 1224 |
| 1366 // Re-rastering text at different scales using GPU rasterization causes | 1225 // Re-rastering text at different scales using GPU rasterization causes |
| 1367 // texture uploads for glyphs at each scale (see crbug.com/366225). To | 1226 // texture uploads for glyphs at each scale (see crbug.com/366225). To |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1508 for (size_t i = 0; i < tilings_->num_tilings(); ++i) { | 1367 for (size_t i = 0; i < tilings_->num_tilings(); ++i) { |
| 1509 PictureLayerTiling* tiling = tilings_->tiling_at(i); | 1368 PictureLayerTiling* tiling = tilings_->tiling_at(i); |
| 1510 if (tiling->resolution() != HIGH_RESOLUTION && | 1369 if (tiling->resolution() != HIGH_RESOLUTION && |
| 1511 tiling->resolution() != LOW_RESOLUTION) | 1370 tiling->resolution() != LOW_RESOLUTION) |
| 1512 continue; | 1371 continue; |
| 1513 | 1372 |
| 1514 for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f, rect); iter; | 1373 for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f, rect); iter; |
| 1515 ++iter) { | 1374 ++iter) { |
| 1516 const Tile* tile = *iter; | 1375 const Tile* tile = *iter; |
| 1517 // A null tile (i.e. missing recording) can just be skipped. | 1376 // A null tile (i.e. missing recording) can just be skipped. |
| 1377 // TODO(vmpstr): Verify this is true if we create tiles in raster | |
| 1378 // iterators. | |
| 1518 if (!tile) | 1379 if (!tile) |
| 1519 continue; | 1380 continue; |
| 1520 | 1381 |
| 1521 if (tile->required_for_activation() && !tile->IsReadyToDraw()) | 1382 if (tiling->IsTileRequiredForActivation(tile) && !tile->IsReadyToDraw()) |
|
danakj
2014/10/08 18:46:25
Can you leave a comment here why this can't use re
vmpstr
2014/10/08 22:38:34
Done.
| |
| 1522 return false; | 1383 return false; |
| 1523 } | 1384 } |
| 1524 } | 1385 } |
| 1525 | 1386 |
| 1526 return true; | 1387 return true; |
| 1527 } | 1388 } |
| 1528 | 1389 |
| 1529 PictureLayerImpl::LayerRasterTileIterator::LayerRasterTileIterator() | 1390 PictureLayerImpl::LayerRasterTileIterator::LayerRasterTileIterator() |
| 1530 : layer_(NULL), current_stage_(arraysize(stages_)) { | 1391 : layer_(NULL), current_stage_(arraysize(stages_)) { |
| 1531 } | 1392 } |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1542 return; | 1403 return; |
| 1543 } | 1404 } |
| 1544 | 1405 |
| 1545 // Tiles without valid priority are treated as having lowest priority and | 1406 // Tiles without valid priority are treated as having lowest priority and |
| 1546 // never considered for raster. | 1407 // never considered for raster. |
| 1547 if (!layer_->HasValidTilePriorities()) { | 1408 if (!layer_->HasValidTilePriorities()) { |
| 1548 current_stage_ = arraysize(stages_); | 1409 current_stage_ = arraysize(stages_); |
| 1549 return; | 1410 return; |
| 1550 } | 1411 } |
| 1551 | 1412 |
| 1552 WhichTree tree = layer_->GetTree(); | |
| 1553 | |
| 1554 // Find high and low res tilings and initialize the iterators. | 1413 // Find high and low res tilings and initialize the iterators. |
| 1555 for (size_t i = 0; i < layer_->tilings_->num_tilings(); ++i) { | 1414 for (size_t i = 0; i < layer_->tilings_->num_tilings(); ++i) { |
| 1556 PictureLayerTiling* tiling = layer_->tilings_->tiling_at(i); | 1415 PictureLayerTiling* tiling = layer_->tilings_->tiling_at(i); |
| 1557 if (tiling->resolution() == HIGH_RESOLUTION) { | 1416 if (tiling->resolution() == HIGH_RESOLUTION) { |
| 1558 iterators_[HIGH_RES] = | 1417 iterators_[HIGH_RES] = |
| 1559 PictureLayerTiling::TilingRasterTileIterator(tiling, tree); | 1418 PictureLayerTiling::TilingRasterTileIterator(tiling); |
| 1560 } | 1419 } |
| 1561 | 1420 |
| 1562 if (tiling->resolution() == LOW_RESOLUTION) { | 1421 if (tiling->resolution() == LOW_RESOLUTION) { |
| 1563 iterators_[LOW_RES] = | 1422 iterators_[LOW_RES] = |
| 1564 PictureLayerTiling::TilingRasterTileIterator(tiling, tree); | 1423 PictureLayerTiling::TilingRasterTileIterator(tiling); |
| 1565 } | 1424 } |
| 1566 } | 1425 } |
| 1567 | 1426 |
| 1568 if (prioritize_low_res) { | 1427 if (prioritize_low_res) { |
| 1569 stages_[0].iterator_type = LOW_RES; | 1428 stages_[0].iterator_type = LOW_RES; |
| 1570 stages_[0].tile_type = TilePriority::NOW; | 1429 stages_[0].tile_type = TilePriority::NOW; |
| 1571 | 1430 |
| 1572 stages_[1].iterator_type = HIGH_RES; | 1431 stages_[1].iterator_type = HIGH_RES; |
| 1573 stages_[1].tile_type = TilePriority::NOW; | 1432 stages_[1].tile_type = TilePriority::NOW; |
| 1574 } else { | 1433 } else { |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1794 PictureLayerTilingSet::TilingRange tiling_range = CurrentTilingRange(); | 1653 PictureLayerTilingSet::TilingRange tiling_range = CurrentTilingRange(); |
| 1795 size_t current_tiling_range_offset = current_tiling_ - tiling_range.start; | 1654 size_t current_tiling_range_offset = current_tiling_ - tiling_range.start; |
| 1796 return tiling_range.end - 1 - current_tiling_range_offset; | 1655 return tiling_range.end - 1 - current_tiling_range_offset; |
| 1797 } | 1656 } |
| 1798 } | 1657 } |
| 1799 NOTREACHED(); | 1658 NOTREACHED(); |
| 1800 return 0; | 1659 return 0; |
| 1801 } | 1660 } |
| 1802 | 1661 |
| 1803 } // namespace cc | 1662 } // namespace cc |
| OLD | NEW |