Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1002)

Side by Side Diff: cc/layers/picture_layer_impl.cc

Issue 367833003: cc: Start using raster/eviction iterators. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698