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 |