| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "platform/graphics/paint/PaintController.h" | 5 #include "platform/graphics/paint/PaintController.h" |
| 6 | 6 |
| 7 #include "platform/graphics/GraphicsLayer.h" | 7 #include "platform/graphics/GraphicsLayer.h" |
| 8 #include "platform/graphics/paint/DrawingDisplayItem.h" | 8 #include "platform/graphics/paint/DrawingDisplayItem.h" |
| 9 #include "platform/instrumentation/tracing/TraceEvent.h" | 9 #include "platform/instrumentation/tracing/TraceEvent.h" |
| 10 #include "platform/wtf/AutoReset.h" | 10 #include "platform/wtf/AutoReset.h" |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 // Mark the client shouldKeepAlive under the current subsequence. | 238 // Mark the client shouldKeepAlive under the current subsequence. |
| 239 // The status will end when the subsequence owner is invalidated or | 239 // The status will end when the subsequence owner is invalidated or |
| 240 // deleted. | 240 // deleted. |
| 241 client.BeginShouldKeepAlive(current_subsequence_clients_.back()); | 241 client.BeginShouldKeepAlive(current_subsequence_clients_.back()); |
| 242 } | 242 } |
| 243 } | 243 } |
| 244 } | 244 } |
| 245 #endif | 245 #endif |
| 246 | 246 |
| 247 void PaintController::ProcessNewItem(DisplayItem& display_item) { | 247 void PaintController::ProcessNewItem(DisplayItem& display_item) { |
| 248 #if DCHECK_IS_ON() |
| 248 DCHECK(!construction_disabled_); | 249 DCHECK(!construction_disabled_); |
| 249 | 250 |
| 251 if (display_item.VisualRect() != display_item.Client().VisualRect()) { |
| 252 LOG(ERROR) << "Visual rect changed without invalidation: " |
| 253 << display_item.Client().DebugName() |
| 254 << " old=" << display_item.VisualRect().ToString() |
| 255 << " new=" << display_item.Client().VisualRect().ToString(); |
| 256 if (RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled()) |
| 257 NOTREACHED(); |
| 258 } |
| 259 #endif |
| 260 |
| 250 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS | 261 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS |
| 251 if (display_item.IsCacheable()) { | 262 if (display_item.IsCacheable()) { |
| 252 BeginShouldKeepAlive(display_item.Client()); | 263 BeginShouldKeepAlive(display_item.Client()); |
| 253 } | 264 } |
| 254 #endif | 265 #endif |
| 255 | 266 |
| 256 if (IsSkippingCache()) | 267 if (IsSkippingCache()) |
| 257 display_item.SetSkippedCache(); | 268 display_item.SetSkippedCache(); |
| 258 | 269 |
| 259 if (raster_invalidation_tracking_info_) { | 270 if (raster_invalidation_tracking_info_) { |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 522 new_paint_chunks_.LastChunk().Matches(*cached_chunk)); | 533 new_paint_chunks_.LastChunk().Matches(*cached_chunk)); |
| 523 } | 534 } |
| 524 } | 535 } |
| 525 | 536 |
| 526 if (RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled()) { | 537 if (RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled()) { |
| 527 under_invalidation_checking_end_ = end_index + 1; | 538 under_invalidation_checking_end_ = end_index + 1; |
| 528 DCHECK(IsCheckingUnderInvalidation()); | 539 DCHECK(IsCheckingUnderInvalidation()); |
| 529 } | 540 } |
| 530 } | 541 } |
| 531 | 542 |
| 532 DISABLE_CFI_PERF | |
| 533 static IntRect VisualRectForDisplayItem( | |
| 534 const DisplayItem& display_item, | |
| 535 const LayoutSize& offset_from_layout_object) { | |
| 536 LayoutRect visual_rect = display_item.Client().VisualRect(); | |
| 537 visual_rect.Move(-offset_from_layout_object); | |
| 538 return EnclosingIntRect(visual_rect); | |
| 539 } | |
| 540 | |
| 541 void PaintController::ResetCurrentListIndices() { | 543 void PaintController::ResetCurrentListIndices() { |
| 542 next_item_to_match_ = 0; | 544 next_item_to_match_ = 0; |
| 543 next_item_to_index_ = 0; | 545 next_item_to_index_ = 0; |
| 544 next_chunk_to_match_ = 0; | 546 next_chunk_to_match_ = 0; |
| 545 under_invalidation_checking_begin_ = 0; | 547 under_invalidation_checking_begin_ = 0; |
| 546 under_invalidation_checking_end_ = 0; | 548 under_invalidation_checking_end_ = 0; |
| 547 skipped_probable_under_invalidation_count_ = 0; | 549 skipped_probable_under_invalidation_count_ = 0; |
| 548 } | 550 } |
| 549 | 551 |
| 550 DISABLE_CFI_PERF | 552 DISABLE_CFI_PERF |
| 551 void PaintController::CommitNewDisplayItems( | 553 void PaintController::CommitNewDisplayItems() { |
| 552 const LayoutSize& offset_from_layout_object) { | |
| 553 TRACE_EVENT2("blink,benchmark", "PaintController::commitNewDisplayItems", | 554 TRACE_EVENT2("blink,benchmark", "PaintController::commitNewDisplayItems", |
| 554 "current_display_list_size", | 555 "current_display_list_size", |
| 555 (int)current_paint_artifact_.GetDisplayItemList().size(), | 556 (int)current_paint_artifact_.GetDisplayItemList().size(), |
| 556 "num_non_cached_new_items", | 557 "num_non_cached_new_items", |
| 557 (int)new_display_item_list_.size() - num_cached_new_items_); | 558 (int)new_display_item_list_.size() - num_cached_new_items_); |
| 559 |
| 558 num_cached_new_items_ = 0; | 560 num_cached_new_items_ = 0; |
| 559 // These data structures are used during painting only. | 561 // These data structures are used during painting only. |
| 560 DCHECK(!IsSkippingCache()); | 562 DCHECK(!IsSkippingCache()); |
| 561 #if DCHECK_IS_ON() | 563 #if DCHECK_IS_ON() |
| 562 new_display_item_indices_by_client_.clear(); | 564 new_display_item_indices_by_client_.clear(); |
| 563 #endif | 565 #endif |
| 564 | 566 |
| 565 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && | 567 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && |
| 566 !new_display_item_list_.IsEmpty()) | 568 !new_display_item_list_.IsEmpty()) |
| 567 GenerateRasterInvalidations(new_paint_chunks_.LastChunk()); | 569 GenerateRasterInvalidations(new_paint_chunks_.LastChunk()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 581 DCHECK(current_subsequence_clients_.IsEmpty()); | 583 DCHECK(current_subsequence_clients_.IsEmpty()); |
| 582 #endif | 584 #endif |
| 583 } | 585 } |
| 584 | 586 |
| 585 Vector<const DisplayItemClient*> skipped_cache_clients; | 587 Vector<const DisplayItemClient*> skipped_cache_clients; |
| 586 for (const auto& item : new_display_item_list_) { | 588 for (const auto& item : new_display_item_list_) { |
| 587 // No reason to continue the analysis once we have a veto. | 589 // No reason to continue the analysis once we have a veto. |
| 588 if (num_slow_paths <= kMaxNumberOfSlowPathsBeforeVeto) | 590 if (num_slow_paths <= kMaxNumberOfSlowPathsBeforeVeto) |
| 589 num_slow_paths += item.NumberOfSlowPaths(); | 591 num_slow_paths += item.NumberOfSlowPaths(); |
| 590 | 592 |
| 591 // TODO(wkorman): Only compute and append visual rect for drawings. | |
| 592 new_display_item_list_.AppendVisualRect( | |
| 593 VisualRectForDisplayItem(item, offset_from_layout_object)); | |
| 594 | |
| 595 if (item.IsCacheable()) { | 593 if (item.IsCacheable()) { |
| 596 item.Client().SetDisplayItemsCached(current_cache_generation_); | 594 item.Client().SetDisplayItemsCached(current_cache_generation_); |
| 597 } else { | 595 } else { |
| 598 if (item.Client().IsJustCreated()) | 596 if (item.Client().IsJustCreated()) |
| 599 item.Client().ClearIsJustCreated(); | 597 item.Client().ClearIsJustCreated(); |
| 600 if (item.SkippedCache()) | 598 if (item.SkippedCache()) |
| 601 skipped_cache_clients.push_back(&item.Client()); | 599 skipped_cache_clients.push_back(&item.Client()); |
| 602 } | 600 } |
| 603 } | 601 } |
| 604 | 602 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 669 // Memory outside this class due to m_newDisplayItemList. | 667 // Memory outside this class due to m_newDisplayItemList. |
| 670 DCHECK(new_display_item_list_.IsEmpty()); | 668 DCHECK(new_display_item_list_.IsEmpty()); |
| 671 memory_usage += new_display_item_list_.MemoryUsageInBytes(); | 669 memory_usage += new_display_item_list_.MemoryUsageInBytes(); |
| 672 | 670 |
| 673 return memory_usage; | 671 return memory_usage; |
| 674 } | 672 } |
| 675 | 673 |
| 676 void PaintController::AppendDebugDrawingAfterCommit( | 674 void PaintController::AppendDebugDrawingAfterCommit( |
| 677 const DisplayItemClient& display_item_client, | 675 const DisplayItemClient& display_item_client, |
| 678 sk_sp<PaintRecord> record, | 676 sk_sp<PaintRecord> record, |
| 679 const FloatRect& record_bounds, | 677 const FloatRect& record_bounds) { |
| 680 const LayoutSize& offset_from_layout_object) { | |
| 681 DCHECK(new_display_item_list_.IsEmpty()); | 678 DCHECK(new_display_item_list_.IsEmpty()); |
| 682 DrawingDisplayItem& display_item = | 679 DrawingDisplayItem& display_item = |
| 683 current_paint_artifact_.GetDisplayItemList() | 680 current_paint_artifact_.GetDisplayItemList() |
| 684 .AllocateAndConstruct<DrawingDisplayItem>( | 681 .AllocateAndConstruct<DrawingDisplayItem>( |
| 685 display_item_client, DisplayItem::kDebugDrawing, | 682 display_item_client, DisplayItem::kDebugDrawing, |
| 686 std::move(record), record_bounds); | 683 std::move(record), record_bounds); |
| 687 display_item.SetSkippedCache(); | 684 display_item.SetSkippedCache(); |
| 688 // TODO(wkorman): Only compute and append visual rect for drawings. | |
| 689 current_paint_artifact_.GetDisplayItemList().AppendVisualRect( | |
| 690 VisualRectForDisplayItem(display_item, offset_from_layout_object)); | |
| 691 } | 685 } |
| 692 | 686 |
| 693 void PaintController::GenerateRasterInvalidations(PaintChunk& new_chunk) { | 687 void PaintController::GenerateRasterInvalidations(PaintChunk& new_chunk) { |
| 694 DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); | 688 DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); |
| 695 if (new_chunk.begin_index >= | 689 if (new_chunk.begin_index >= |
| 696 current_cached_subsequence_begin_index_in_new_list_) | 690 current_cached_subsequence_begin_index_in_new_list_) |
| 697 return; | 691 return; |
| 698 | 692 |
| 699 static FloatRect infinite_float_rect(LayoutRect::InfiniteIntRect()); | 693 static FloatRect infinite_float_rect(LayoutRect::InfiniteIntRect()); |
| 700 if (!new_chunk.id) { | 694 if (!new_chunk.id) { |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 794 current_paint_artifact_.GetDisplayItemList()[old_index]; | 788 current_paint_artifact_.GetDisplayItemList()[old_index]; |
| 795 const DisplayItemClient* client_to_invalidate = nullptr; | 789 const DisplayItemClient* client_to_invalidate = nullptr; |
| 796 | 790 |
| 797 if (!old_item.HasValidClient()) { | 791 if (!old_item.HasValidClient()) { |
| 798 size_t moved_to_index = items_moved_into_new_list_[old_index]; | 792 size_t moved_to_index = items_moved_into_new_list_[old_index]; |
| 799 if (new_display_item_list_[moved_to_index].DrawsContent()) { | 793 if (new_display_item_list_[moved_to_index].DrawsContent()) { |
| 800 if (moved_to_index < new_chunk.begin_index || | 794 if (moved_to_index < new_chunk.begin_index || |
| 801 moved_to_index >= new_chunk.end_index) { | 795 moved_to_index >= new_chunk.end_index) { |
| 802 // The item has been moved into another chunk, so need to invalidate | 796 // The item has been moved into another chunk, so need to invalidate |
| 803 // it in the old chunk. | 797 // it in the old chunk. |
| 804 client_to_invalidate = | 798 const auto& new_item = new_display_item_list_[moved_to_index]; |
| 805 &new_display_item_list_[moved_to_index].Client(); | 799 client_to_invalidate = &new_item.Client(); |
| 806 // And invalidate in the new chunk into which the item was moved. | 800 // And invalidate in the new chunk into which the item was moved. |
| 807 PaintChunk& moved_to_chunk = | 801 PaintChunk& moved_to_chunk = |
| 808 new_paint_chunks_.FindChunkByDisplayItemIndex(moved_to_index); | 802 new_paint_chunks_.FindChunkByDisplayItemIndex(moved_to_index); |
| 809 AddRasterInvalidation(*client_to_invalidate, moved_to_chunk, | 803 AddRasterInvalidation(*client_to_invalidate, moved_to_chunk, |
| 810 FloatRect(client_to_invalidate->VisualRect())); | 804 FloatRect(new_item.VisualRect())); |
| 811 } else if (moved_to_index < highest_moved_to_index) { | 805 } else if (moved_to_index < highest_moved_to_index) { |
| 812 // The item has been moved behind other cached items, so need to | 806 // The item has been moved behind other cached items, so need to |
| 813 // invalidate the area that is probably exposed by the item moved | 807 // invalidate the area that is probably exposed by the item moved |
| 814 // earlier. | 808 // earlier. |
| 815 client_to_invalidate = | 809 client_to_invalidate = |
| 816 &new_display_item_list_[moved_to_index].Client(); | 810 &new_display_item_list_[moved_to_index].Client(); |
| 817 } else { | 811 } else { |
| 818 highest_moved_to_index = moved_to_index; | 812 highest_moved_to_index = moved_to_index; |
| 819 } | 813 } |
| 820 } | 814 } |
| 821 } else if (old_item.DrawsContent()) { | 815 } else if (old_item.DrawsContent()) { |
| 822 client_to_invalidate = &old_item.Client(); | 816 client_to_invalidate = &old_item.Client(); |
| 823 } | 817 } |
| 824 if (client_to_invalidate && | 818 if (client_to_invalidate && |
| 825 invalidated_clients_in_old_chunk.insert(client_to_invalidate) | 819 invalidated_clients_in_old_chunk.insert(client_to_invalidate) |
| 826 .is_new_entry) { | 820 .is_new_entry) { |
| 827 AddRasterInvalidation( | 821 AddRasterInvalidation(*client_to_invalidate, new_chunk, |
| 828 *client_to_invalidate, new_chunk, | 822 FloatRect(old_item.VisualRect())); |
| 829 FloatRect(current_paint_artifact_.GetDisplayItemList().VisualRect( | |
| 830 old_index))); | |
| 831 } | 823 } |
| 832 } | 824 } |
| 833 | 825 |
| 834 HashSet<const DisplayItemClient*> invalidated_clients_in_new_chunk; | 826 HashSet<const DisplayItemClient*> invalidated_clients_in_new_chunk; |
| 835 for (size_t new_index = new_chunk.begin_index; | 827 for (size_t new_index = new_chunk.begin_index; |
| 836 new_index < new_chunk.end_index; ++new_index) { | 828 new_index < new_chunk.end_index; ++new_index) { |
| 837 const DisplayItem& new_item = new_display_item_list_[new_index]; | 829 const DisplayItem& new_item = new_display_item_list_[new_index]; |
| 838 if (new_item.DrawsContent() && !ClientCacheIsValid(new_item.Client()) && | 830 if (new_item.DrawsContent() && !ClientCacheIsValid(new_item.Client()) && |
| 839 invalidated_clients_in_new_chunk.insert(&new_item.Client()) | 831 invalidated_clients_in_new_chunk.insert(&new_item.Client()) |
| 840 .is_new_entry) { | 832 .is_new_entry) { |
| 841 AddRasterInvalidation(new_item.Client(), new_chunk, | 833 AddRasterInvalidation(new_item.Client(), new_chunk, |
| 842 FloatRect(new_item.Client().VisualRect())); | 834 FloatRect(new_item.VisualRect())); |
| 843 } | 835 } |
| 844 } | 836 } |
| 845 } | 837 } |
| 846 | 838 |
| 847 void PaintController::ShowUnderInvalidationError( | 839 void PaintController::ShowUnderInvalidationError( |
| 848 const char* reason, | 840 const char* reason, |
| 849 const DisplayItem& new_item, | 841 const DisplayItem& new_item, |
| 850 const DisplayItem* old_item) const { | 842 const DisplayItem* old_item) const { |
| 851 LOG(ERROR) << under_invalidation_message_prefix_ << " " << reason; | 843 LOG(ERROR) << under_invalidation_message_prefix_ << " " << reason; |
| 852 #ifndef NDEBUG | 844 #ifndef NDEBUG |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1005 } | 997 } |
| 1006 | 998 |
| 1007 FrameFirstPaint PaintController::EndFrame(const void* frame) { | 999 FrameFirstPaint PaintController::EndFrame(const void* frame) { |
| 1008 FrameFirstPaint result = frame_first_paints_.back(); | 1000 FrameFirstPaint result = frame_first_paints_.back(); |
| 1009 DCHECK(result.frame == frame); | 1001 DCHECK(result.frame == frame); |
| 1010 frame_first_paints_.pop_back(); | 1002 frame_first_paints_.pop_back(); |
| 1011 return result; | 1003 return result; |
| 1012 } | 1004 } |
| 1013 | 1005 |
| 1014 } // namespace blink | 1006 } // namespace blink |
| OLD | NEW |