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

Side by Side Diff: third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp

Issue 2876923002: Track client debug names for raster invalidation tracking (Closed)
Patch Set: Rebaseline virtual/spv2/paint/invalidation/margin.html Created 3 years, 7 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
« no previous file with comments | « third_party/WebKit/Source/platform/graphics/paint/PaintController.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
11 #include "platform/wtf/text/StringBuilder.h" 11 #include "platform/wtf/text/StringBuilder.h"
12 #include "third_party/skia/include/core/SkPictureAnalyzer.h" 12 #include "third_party/skia/include/core/SkPictureAnalyzer.h"
13 13
14 #ifndef NDEBUG 14 #ifndef NDEBUG
15 #include "platform/graphics/LoggingCanvas.h" 15 #include "platform/graphics/LoggingCanvas.h"
16 #include <stdio.h> 16 #include <stdio.h>
17 #endif 17 #endif
18 18
19 static constexpr int kMaxNumberOfSlowPathsBeforeVeto = 5; 19 static constexpr int kMaxNumberOfSlowPathsBeforeVeto = 5;
20 20
21 namespace blink { 21 namespace blink {
22 22
23 void PaintController::SetTracksRasterInvalidations(bool value) { 23 void PaintController::SetTracksRasterInvalidations(bool value) {
24 if (value || 24 if (value ||
25 RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled()) { 25 RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled()) {
26 raster_invalidation_tracking_map_ = 26 raster_invalidation_tracking_info_ =
27 WTF::WrapUnique(new RasterInvalidationTrackingMap<const PaintChunk>); 27 WTF::MakeUnique<RasterInvalidationTrackingInfo>();
28
29 // This is called just after a full document cycle update, so all clients in
30 // current_paint_artifact_ should be still alive.
31 DCHECK(new_display_item_list_.IsEmpty());
32 for (const auto& item : current_paint_artifact_.GetDisplayItemList()) {
33 raster_invalidation_tracking_info_->old_client_debug_names.Set(
34 &item.Client(), item.Client().DebugName());
35 }
28 } else { 36 } else {
29 raster_invalidation_tracking_map_ = nullptr; 37 raster_invalidation_tracking_info_ = nullptr;
30 } 38 }
31 } 39 }
32 40
33 const PaintArtifact& PaintController::GetPaintArtifact() const { 41 const PaintArtifact& PaintController::GetPaintArtifact() const {
34 DCHECK(new_display_item_list_.IsEmpty()); 42 DCHECK(new_display_item_list_.IsEmpty());
35 DCHECK(new_paint_chunks_.IsInInitialState()); 43 DCHECK(new_paint_chunks_.IsInInitialState());
36 return current_paint_artifact_; 44 return current_paint_artifact_;
37 } 45 }
38 46
39 bool PaintController::UseCachedDrawingIfPossible( 47 bool PaintController::UseCachedDrawingIfPossible(
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 249
242 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS 250 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
243 if (display_item.IsCacheable()) { 251 if (display_item.IsCacheable()) {
244 BeginShouldKeepAlive(display_item.Client()); 252 BeginShouldKeepAlive(display_item.Client());
245 } 253 }
246 #endif 254 #endif
247 255
248 if (IsSkippingCache()) 256 if (IsSkippingCache())
249 display_item.SetSkippedCache(); 257 display_item.SetSkippedCache();
250 258
259 if (raster_invalidation_tracking_info_) {
260 raster_invalidation_tracking_info_->new_client_debug_names.insert(
261 &display_item.Client(), display_item.Client().DebugName());
262 }
263
251 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { 264 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
252 size_t last_chunk_index = new_paint_chunks_.LastChunkIndex(); 265 size_t last_chunk_index = new_paint_chunks_.LastChunkIndex();
253 if (new_paint_chunks_.IncrementDisplayItemIndex(display_item)) { 266 if (new_paint_chunks_.IncrementDisplayItemIndex(display_item)) {
254 DCHECK(last_chunk_index != new_paint_chunks_.LastChunkIndex()); 267 DCHECK(last_chunk_index != new_paint_chunks_.LastChunkIndex());
255 if (last_chunk_index != kNotFound) { 268 if (last_chunk_index != kNotFound) {
256 GenerateRasterInvalidations( 269 GenerateRasterInvalidations(
257 new_paint_chunks_.PaintChunkAt(last_chunk_index)); 270 new_paint_chunks_.PaintChunkAt(last_chunk_index));
258 } 271 }
259 } 272 }
260 } 273 }
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 } 606 }
594 } 607 }
595 } 608 }
596 609
597 for (auto* client : skipped_cache_clients) 610 for (auto* client : skipped_cache_clients)
598 client->SetDisplayItemsUncached(); 611 client->SetDisplayItemsUncached();
599 612
600 // The new list will not be appended to again so we can release unused memory. 613 // The new list will not be appended to again so we can release unused memory.
601 new_display_item_list_.ShrinkToFit(); 614 new_display_item_list_.ShrinkToFit();
602 615
603 if (raster_invalidation_tracking_map_) { 616 if (raster_invalidation_tracking_info_) {
604 for (const auto& chunk : current_paint_artifact_.PaintChunks()) 617 for (const auto& chunk : current_paint_artifact_.PaintChunks())
605 raster_invalidation_tracking_map_->Remove(&chunk); 618 raster_invalidation_tracking_info_->map.Remove(&chunk);
606 } 619 }
607 current_paint_artifact_ = PaintArtifact( 620 current_paint_artifact_ = PaintArtifact(
608 std::move(new_display_item_list_), new_paint_chunks_.ReleasePaintChunks(), 621 std::move(new_display_item_list_), new_paint_chunks_.ReleasePaintChunks(),
609 num_slow_paths <= kMaxNumberOfSlowPathsBeforeVeto); 622 num_slow_paths <= kMaxNumberOfSlowPathsBeforeVeto);
610 623
611 ResetCurrentListIndices(); 624 ResetCurrentListIndices();
612 out_of_order_item_indices_.clear(); 625 out_of_order_item_indices_.clear();
613 out_of_order_chunk_indices_.clear(); 626 out_of_order_chunk_indices_.clear();
614 items_moved_into_new_list_.clear(); 627 items_moved_into_new_list_.clear();
615 628
616 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { 629 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
617 for (const auto& chunk : current_paint_artifact_.PaintChunks()) { 630 for (const auto& chunk : current_paint_artifact_.PaintChunks()) {
618 if (chunk.id && chunk.id->client.IsJustCreated()) 631 if (chunk.id && chunk.id->client.IsJustCreated())
619 chunk.id->client.ClearIsJustCreated(); 632 chunk.id->client.ClearIsJustCreated();
620 } 633 }
621 } 634 }
622 635
623 // We'll allocate the initial buffer when we start the next paint. 636 // We'll allocate the initial buffer when we start the next paint.
624 new_display_item_list_ = DisplayItemList(0); 637 new_display_item_list_ = DisplayItemList(0);
625 638
626 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS 639 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
627 DisplayItemClient::EndShouldKeepAliveAllClients(this); 640 DisplayItemClient::EndShouldKeepAliveAllClients(this);
628 #endif 641 #endif
629 642
630 #ifndef NDEBUG 643 #ifndef NDEBUG
631 num_sequential_matches_ = 0; 644 num_sequential_matches_ = 0;
632 num_out_of_order_matches_ = 0; 645 num_out_of_order_matches_ = 0;
633 num_indexed_items_ = 0; 646 num_indexed_items_ = 0;
634 #endif 647 #endif
648
649 if (raster_invalidation_tracking_info_) {
650 raster_invalidation_tracking_info_->old_client_debug_names.clear();
651 std::swap(raster_invalidation_tracking_info_->old_client_debug_names,
652 raster_invalidation_tracking_info_->new_client_debug_names);
653 }
635 } 654 }
636 655
637 size_t PaintController::ApproximateUnsharedMemoryUsage() const { 656 size_t PaintController::ApproximateUnsharedMemoryUsage() const {
638 size_t memory_usage = sizeof(*this); 657 size_t memory_usage = sizeof(*this);
639 658
640 // Memory outside this class due to m_currentPaintArtifact. 659 // Memory outside this class due to m_currentPaintArtifact.
641 memory_usage += current_paint_artifact_.ApproximateUnsharedMemoryUsage() - 660 memory_usage += current_paint_artifact_.ApproximateUnsharedMemoryUsage() -
642 sizeof(current_paint_artifact_); 661 sizeof(current_paint_artifact_);
643 662
644 // TODO(jbroman): If display items begin to have significant external memory 663 // TODO(jbroman): If display items begin to have significant external memory
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 } 695 }
677 696
678 void PaintController::GenerateRasterInvalidations(PaintChunk& new_chunk) { 697 void PaintController::GenerateRasterInvalidations(PaintChunk& new_chunk) {
679 DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); 698 DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
680 if (new_chunk.begin_index >= 699 if (new_chunk.begin_index >=
681 current_cached_subsequence_begin_index_in_new_list_) 700 current_cached_subsequence_begin_index_in_new_list_)
682 return; 701 return;
683 702
684 static FloatRect infinite_float_rect(LayoutRect::InfiniteIntRect()); 703 static FloatRect infinite_float_rect(LayoutRect::InfiniteIntRect());
685 if (!new_chunk.id) { 704 if (!new_chunk.id) {
686 AddRasterInvalidation(nullptr, new_chunk, infinite_float_rect); 705 // This chunk is not cacheable, so always invalidate the whole chunk.
706 AddRasterInvalidation(
707 new_display_item_list_[new_chunk.begin_index].Client(), new_chunk,
708 infinite_float_rect);
687 return; 709 return;
688 } 710 }
689 711
690 // Try to match old chunk sequentially first. 712 // Try to match old chunk sequentially first.
691 const auto& old_chunks = current_paint_artifact_.PaintChunks(); 713 const auto& old_chunks = current_paint_artifact_.PaintChunks();
692 while (next_chunk_to_match_ < old_chunks.size()) { 714 while (next_chunk_to_match_ < old_chunks.size()) {
693 const PaintChunk& old_chunk = old_chunks[next_chunk_to_match_]; 715 const PaintChunk& old_chunk = old_chunks[next_chunk_to_match_];
694 if (new_chunk.Matches(old_chunk)) { 716 if (new_chunk.Matches(old_chunk)) {
695 GenerateRasterInvalidationsComparingChunks(new_chunk, old_chunk); 717 GenerateRasterInvalidationsComparingChunks(new_chunk, old_chunk);
696 ++next_chunk_to_match_; 718 ++next_chunk_to_match_;
(...skipping 19 matching lines...) Expand all
716 if (it != out_of_order_chunk_indices_.end()) { 738 if (it != out_of_order_chunk_indices_.end()) {
717 for (size_t i : it->value) { 739 for (size_t i : it->value) {
718 if (new_chunk.Matches(old_chunks[i])) { 740 if (new_chunk.Matches(old_chunks[i])) {
719 GenerateRasterInvalidationsComparingChunks(new_chunk, old_chunks[i]); 741 GenerateRasterInvalidationsComparingChunks(new_chunk, old_chunks[i]);
720 return; 742 return;
721 } 743 }
722 } 744 }
723 } 745 }
724 746
725 // We reach here because the chunk is new. 747 // We reach here because the chunk is new.
726 AddRasterInvalidation(nullptr, new_chunk, infinite_float_rect); 748 AddRasterInvalidation(new_display_item_list_[new_chunk.begin_index].Client(),
749 new_chunk, infinite_float_rect);
727 } 750 }
728 751
729 void PaintController::AddRasterInvalidation(const DisplayItemClient* client, 752 void PaintController::AddRasterInvalidation(const DisplayItemClient& client,
730 PaintChunk& chunk, 753 PaintChunk& chunk,
731 const FloatRect& rect) { 754 const FloatRect& rect) {
732 chunk.raster_invalidation_rects.push_back(rect); 755 chunk.raster_invalidation_rects.push_back(rect);
733 if (raster_invalidation_tracking_map_) 756 if (raster_invalidation_tracking_info_)
734 TrackRasterInvalidation(client, chunk, rect); 757 TrackRasterInvalidation(client, chunk, rect);
735 } 758 }
736 759
737 void PaintController::TrackRasterInvalidation(const DisplayItemClient* client, 760 void PaintController::TrackRasterInvalidation(const DisplayItemClient& client,
738 PaintChunk& chunk, 761 PaintChunk& chunk,
739 const FloatRect& rect) { 762 const FloatRect& rect) {
740 DCHECK(raster_invalidation_tracking_map_); 763 DCHECK(raster_invalidation_tracking_info_);
741 764
742 RasterInvalidationInfo info; 765 RasterInvalidationInfo info;
743 info.rect = EnclosingIntRect(rect); 766 info.rect = EnclosingIntRect(rect);
744 info.client = client; 767 info.client = &client;
745 if (client) { 768 auto it =
746 info.client_debug_name = client->DebugName(); 769 raster_invalidation_tracking_info_->new_client_debug_names.find(&client);
747 info.reason = client->GetPaintInvalidationReason(); 770 if (it == raster_invalidation_tracking_info_->new_client_debug_names.end()) {
771 it = raster_invalidation_tracking_info_->old_client_debug_names.find(
772 &client);
773 // The client should be either in new list or in old list.
774 DCHECK(it !=
775 raster_invalidation_tracking_info_->old_client_debug_names.end());
776 info.reason = kPaintInvalidationLayoutObjectRemoval;
777 } else {
778 info.reason = client.GetPaintInvalidationReason();
748 } 779 }
749 raster_invalidation_tracking_map_->Add(&chunk).invalidations.push_back(info); 780 info.client_debug_name = it->value;
781 raster_invalidation_tracking_info_->map.Add(&chunk).invalidations.push_back(
782 info);
750 } 783 }
751 784
752 void PaintController::GenerateRasterInvalidationsComparingChunks( 785 void PaintController::GenerateRasterInvalidationsComparingChunks(
753 PaintChunk& new_chunk, 786 PaintChunk& new_chunk,
754 const PaintChunk& old_chunk) { 787 const PaintChunk& old_chunk) {
755 DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); 788 DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
756 789
757 // TODO(wangxianzhu): Handle PaintInvalidationIncremental. 790 // TODO(wangxianzhu): Handle PaintInvalidationIncremental.
758 // TODO(wangxianzhu): Optimize paint offset change. 791 // TODO(wangxianzhu): Optimize paint offset change.
759 792
760 HashSet<const DisplayItemClient*> invalidated_clients_in_old_chunk; 793 HashSet<const DisplayItemClient*> invalidated_clients_in_old_chunk;
761 size_t highest_moved_to_index = 0; 794 size_t highest_moved_to_index = 0;
762 for (size_t old_index = old_chunk.begin_index; 795 for (size_t old_index = old_chunk.begin_index;
763 old_index < old_chunk.end_index; ++old_index) { 796 old_index < old_chunk.end_index; ++old_index) {
764 const DisplayItem& old_item = 797 const DisplayItem& old_item =
765 current_paint_artifact_.GetDisplayItemList()[old_index]; 798 current_paint_artifact_.GetDisplayItemList()[old_index];
766 const DisplayItemClient* client_to_invalidate = nullptr; 799 const DisplayItemClient* client_to_invalidate = nullptr;
767 bool is_potentially_invalid_client = false; 800
768 if (!old_item.HasValidClient()) { 801 if (!old_item.HasValidClient()) {
769 size_t moved_to_index = items_moved_into_new_list_[old_index]; 802 size_t moved_to_index = items_moved_into_new_list_[old_index];
770 if (new_display_item_list_[moved_to_index].DrawsContent()) { 803 if (new_display_item_list_[moved_to_index].DrawsContent()) {
771 if (moved_to_index < new_chunk.begin_index || 804 if (moved_to_index < new_chunk.begin_index ||
772 moved_to_index >= new_chunk.end_index) { 805 moved_to_index >= new_chunk.end_index) {
773 // The item has been moved into another chunk, so need to invalidate 806 // The item has been moved into another chunk, so need to invalidate
774 // it in the old chunk. 807 // it in the old chunk.
775 client_to_invalidate = 808 client_to_invalidate =
776 &new_display_item_list_[moved_to_index].Client(); 809 &new_display_item_list_[moved_to_index].Client();
777 // And invalidate in the new chunk into which the item was moved. 810 // And invalidate in the new chunk into which the item was moved.
778 PaintChunk& moved_to_chunk = 811 PaintChunk& moved_to_chunk =
779 new_paint_chunks_.FindChunkByDisplayItemIndex(moved_to_index); 812 new_paint_chunks_.FindChunkByDisplayItemIndex(moved_to_index);
780 AddRasterInvalidation(client_to_invalidate, moved_to_chunk, 813 AddRasterInvalidation(*client_to_invalidate, moved_to_chunk,
781 FloatRect(client_to_invalidate->VisualRect())); 814 FloatRect(client_to_invalidate->VisualRect()));
782 } else if (moved_to_index < highest_moved_to_index) { 815 } else if (moved_to_index < highest_moved_to_index) {
783 // The item has been moved behind other cached items, so need to 816 // The item has been moved behind other cached items, so need to
784 // invalidate the area that is probably exposed by the item moved 817 // invalidate the area that is probably exposed by the item moved
785 // earlier. 818 // earlier.
786 client_to_invalidate = 819 client_to_invalidate =
787 &new_display_item_list_[moved_to_index].Client(); 820 &new_display_item_list_[moved_to_index].Client();
788 } else { 821 } else {
789 highest_moved_to_index = moved_to_index; 822 highest_moved_to_index = moved_to_index;
790 } 823 }
791 } 824 }
792 } else if (old_item.DrawsContent()) { 825 } else if (old_item.DrawsContent()) {
793 is_potentially_invalid_client = true;
794 client_to_invalidate = &old_item.Client(); 826 client_to_invalidate = &old_item.Client();
795 } 827 }
796 if (client_to_invalidate && 828 if (client_to_invalidate &&
797 invalidated_clients_in_old_chunk.insert(client_to_invalidate) 829 invalidated_clients_in_old_chunk.insert(client_to_invalidate)
798 .is_new_entry) { 830 .is_new_entry) {
799 AddRasterInvalidation( 831 AddRasterInvalidation(
800 is_potentially_invalid_client ? nullptr : client_to_invalidate, 832 *client_to_invalidate, new_chunk,
801 new_chunk,
802 FloatRect(current_paint_artifact_.GetDisplayItemList().VisualRect( 833 FloatRect(current_paint_artifact_.GetDisplayItemList().VisualRect(
803 old_index))); 834 old_index)));
804 } 835 }
805 } 836 }
806 837
807 HashSet<const DisplayItemClient*> invalidated_clients_in_new_chunk; 838 HashSet<const DisplayItemClient*> invalidated_clients_in_new_chunk;
808 for (size_t new_index = new_chunk.begin_index; 839 for (size_t new_index = new_chunk.begin_index;
809 new_index < new_chunk.end_index; ++new_index) { 840 new_index < new_chunk.end_index; ++new_index) {
810 const DisplayItem& new_item = new_display_item_list_[new_index]; 841 const DisplayItem& new_item = new_display_item_list_[new_index];
811 if (new_item.DrawsContent() && !ClientCacheIsValid(new_item.Client()) && 842 if (new_item.DrawsContent() && !ClientCacheIsValid(new_item.Client()) &&
812 invalidated_clients_in_new_chunk.insert(&new_item.Client()) 843 invalidated_clients_in_new_chunk.insert(&new_item.Client())
813 .is_new_entry) { 844 .is_new_entry) {
814 AddRasterInvalidation(&new_item.Client(), new_chunk, 845 AddRasterInvalidation(new_item.Client(), new_chunk,
815 FloatRect(new_item.Client().VisualRect())); 846 FloatRect(new_item.Client().VisualRect()));
816 } 847 }
817 } 848 }
818 } 849 }
819 850
820 void PaintController::ShowUnderInvalidationError( 851 void PaintController::ShowUnderInvalidationError(
821 const char* reason, 852 const char* reason,
822 const DisplayItem& new_item, 853 const DisplayItem& new_item,
823 const DisplayItem* old_item) const { 854 const DisplayItem* old_item) const {
824 LOG(ERROR) << under_invalidation_message_prefix_ << " " << reason; 855 LOG(ERROR) << under_invalidation_message_prefix_ << " " << reason;
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
947 show_paint_records 978 show_paint_records
948 ? (DisplayItemList::JsonOptions::kShowPaintRecords | 979 ? (DisplayItemList::JsonOptions::kShowPaintRecords |
949 DisplayItemList::JsonOptions::kShowClientDebugName) 980 DisplayItemList::JsonOptions::kShowClientDebugName)
950 : DisplayItemList::JsonOptions::kShowClientDebugName) 981 : DisplayItemList::JsonOptions::kShowClientDebugName)
951 ->ToPrettyJSONString() 982 ->ToPrettyJSONString()
952 .Utf8() 983 .Utf8()
953 .data()); 984 .data());
954 } 985 }
955 986
956 } // namespace blink 987 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/graphics/paint/PaintController.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698