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

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

Issue 2874553002: [SPv2] Fix layout test crashes about raster invalidation (Closed)
Patch Set: - 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
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 paint_chunks_raster_invalidation_tracking_map_ = 25 RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled()) {
26 raster_invalidation_tracking_map_ =
26 WTF::WrapUnique(new RasterInvalidationTrackingMap<const PaintChunk>); 27 WTF::WrapUnique(new RasterInvalidationTrackingMap<const PaintChunk>);
27 } else { 28 return;
28 paint_chunks_raster_invalidation_tracking_map_ = nullptr;
29 } 29 }
30 raster_invalidation_tracking_map_ = nullptr;
30 } 31 }
31 32
32 const PaintArtifact& PaintController::GetPaintArtifact() const { 33 const PaintArtifact& PaintController::GetPaintArtifact() const {
33 DCHECK(new_display_item_list_.IsEmpty()); 34 DCHECK(new_display_item_list_.IsEmpty());
34 DCHECK(new_paint_chunks_.IsInInitialState()); 35 DCHECK(new_paint_chunks_.IsInInitialState());
35 return current_paint_artifact_; 36 return current_paint_artifact_;
36 } 37 }
37 38
38 bool PaintController::UseCachedDrawingIfPossible( 39 bool PaintController::UseCachedDrawingIfPossible(
39 const DisplayItemClient& client, 40 const DisplayItemClient& client,
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 break; 591 break;
591 } 592 }
592 } 593 }
593 } 594 }
594 595
595 for (auto* client : skipped_cache_clients) 596 for (auto* client : skipped_cache_clients)
596 client->SetDisplayItemsUncached(); 597 client->SetDisplayItemsUncached();
597 598
598 // The new list will not be appended to again so we can release unused memory. 599 // The new list will not be appended to again so we can release unused memory.
599 new_display_item_list_.ShrinkToFit(); 600 new_display_item_list_.ShrinkToFit();
601
602 if (raster_invalidation_tracking_map_) {
603 for (const auto& chunk : current_paint_artifact_.PaintChunks())
604 raster_invalidation_tracking_map_->Remove(&chunk);
605 }
600 current_paint_artifact_ = PaintArtifact( 606 current_paint_artifact_ = PaintArtifact(
601 std::move(new_display_item_list_), new_paint_chunks_.ReleasePaintChunks(), 607 std::move(new_display_item_list_), new_paint_chunks_.ReleasePaintChunks(),
602 num_slow_paths <= kMaxNumberOfSlowPathsBeforeVeto); 608 num_slow_paths <= kMaxNumberOfSlowPathsBeforeVeto);
609
603 ResetCurrentListIndices(); 610 ResetCurrentListIndices();
604 out_of_order_item_indices_.clear(); 611 out_of_order_item_indices_.clear();
605 out_of_order_chunk_indices_.clear(); 612 out_of_order_chunk_indices_.clear();
606 items_moved_into_new_list_.clear(); 613 items_moved_into_new_list_.clear();
607 614
608 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { 615 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
609 for (const auto& chunk : current_paint_artifact_.PaintChunks()) { 616 for (const auto& chunk : current_paint_artifact_.PaintChunks()) {
610 if (chunk.id && chunk.id->client.IsJustCreated()) 617 if (chunk.id && chunk.id->client.IsJustCreated())
611 chunk.id->client.ClearIsJustCreated(); 618 chunk.id->client.ClearIsJustCreated();
612 } 619 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
669 676
670 void PaintController::GenerateChunkRasterInvalidationRects( 677 void PaintController::GenerateChunkRasterInvalidationRects(
671 PaintChunk& new_chunk) { 678 PaintChunk& new_chunk) {
672 DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); 679 DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
673 if (new_chunk.begin_index >= 680 if (new_chunk.begin_index >=
674 current_cached_subsequence_begin_index_in_new_list_) 681 current_cached_subsequence_begin_index_in_new_list_)
675 return; 682 return;
676 683
677 static FloatRect infinite_float_rect(LayoutRect::InfiniteIntRect()); 684 static FloatRect infinite_float_rect(LayoutRect::InfiniteIntRect());
678 if (!new_chunk.id) { 685 if (!new_chunk.id) {
679 AddRasterInvalidationInfo(nullptr, new_chunk, infinite_float_rect); 686 AddRasterInvalidation(nullptr, new_chunk, infinite_float_rect);
680 return; 687 return;
681 } 688 }
682 689
683 // Try to match old chunk sequentially first. 690 // Try to match old chunk sequentially first.
684 const auto& old_chunks = current_paint_artifact_.PaintChunks(); 691 const auto& old_chunks = current_paint_artifact_.PaintChunks();
685 while (next_chunk_to_match_ < old_chunks.size()) { 692 while (next_chunk_to_match_ < old_chunks.size()) {
686 const PaintChunk& old_chunk = old_chunks[next_chunk_to_match_]; 693 const PaintChunk& old_chunk = old_chunks[next_chunk_to_match_];
687 if (new_chunk.Matches(old_chunk)) { 694 if (new_chunk.Matches(old_chunk)) {
688 GenerateChunkRasterInvalidationRectsComparingOldChunk(new_chunk, 695 GenerateChunkRasterInvalidationRectsComparingOldChunk(new_chunk,
689 old_chunk); 696 old_chunk);
(...skipping 21 matching lines...) Expand all
711 for (size_t i : it->value) { 718 for (size_t i : it->value) {
712 if (new_chunk.Matches(old_chunks[i])) { 719 if (new_chunk.Matches(old_chunks[i])) {
713 GenerateChunkRasterInvalidationRectsComparingOldChunk(new_chunk, 720 GenerateChunkRasterInvalidationRectsComparingOldChunk(new_chunk,
714 old_chunks[i]); 721 old_chunks[i]);
715 return; 722 return;
716 } 723 }
717 } 724 }
718 } 725 }
719 726
720 // We reach here because the chunk is new. 727 // We reach here because the chunk is new.
721 AddRasterInvalidationInfo(nullptr, new_chunk, infinite_float_rect); 728 AddRasterInvalidation(nullptr, new_chunk, infinite_float_rect);
722 } 729 }
723 730
724 void PaintController::AddRasterInvalidationInfo(const DisplayItemClient* client, 731 void PaintController::AddRasterInvalidation(const DisplayItemClient* client,
725 PaintChunk& chunk, 732 PaintChunk& chunk,
726 const FloatRect& rect) { 733 const FloatRect& rect) {
727 chunk.raster_invalidation_rects.push_back(rect); 734 chunk.raster_invalidation_rects.push_back(rect);
728 if (!paint_chunks_raster_invalidation_tracking_map_) 735 if (!raster_invalidation_tracking_map_)
729 return; 736 return;
730 RasterInvalidationInfo info; 737 RasterInvalidationInfo info;
731 info.rect = EnclosingIntRect(rect); 738 info.rect = EnclosingIntRect(rect);
732 info.client = client; 739 info.client = client;
733 if (client) { 740 if (client) {
734 info.client_debug_name = client->DebugName(); 741 info.client_debug_name = client->DebugName();
735 info.reason = client->GetPaintInvalidationReason(); 742 info.reason = client->GetPaintInvalidationReason();
736 } 743 }
737 RasterInvalidationTracking& tracking = 744 raster_invalidation_tracking_map_->AddInvalidation(&chunk, info);
738 paint_chunks_raster_invalidation_tracking_map_->Add(&chunk);
739 tracking.tracked_raster_invalidations.push_back(info);
740 } 745 }
741 746
742 void PaintController::GenerateChunkRasterInvalidationRectsComparingOldChunk( 747 void PaintController::GenerateChunkRasterInvalidationRectsComparingOldChunk(
743 PaintChunk& new_chunk, 748 PaintChunk& new_chunk,
744 const PaintChunk& old_chunk) { 749 const PaintChunk& old_chunk) {
745 DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); 750 DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
746 751
747 // TODO(wangxianzhu): Handle PaintInvalidationIncremental. 752 // TODO(wangxianzhu): Handle PaintInvalidationIncremental.
748 // TODO(wangxianzhu): Optimize paint offset change. 753 // TODO(wangxianzhu): Optimize paint offset change.
749 754
755 // We may track raster invalidations across multiple paints. The new chunk
756 // should contain all previously tracked invalidations.
757 if (raster_invalidation_tracking_map_) {
758 // Add() must be before Find() otherwise Add() might invalidate the pointer
759 // returned from Find().
760 auto& new_tracking = raster_invalidation_tracking_map_->Add(&new_chunk);
761 if (auto* old_tracking =
762 raster_invalidation_tracking_map_->Find(&old_chunk)) {
763 new_tracking.tracked_invalidations.AppendVector(
764 old_tracking->tracked_invalidations);
765 }
766 }
767
750 HashSet<const DisplayItemClient*> invalidated_clients_in_old_chunk; 768 HashSet<const DisplayItemClient*> invalidated_clients_in_old_chunk;
751 size_t highest_moved_to_index = 0; 769 size_t highest_moved_to_index = 0;
752 for (size_t old_index = old_chunk.begin_index; 770 for (size_t old_index = old_chunk.begin_index;
753 old_index < old_chunk.end_index; ++old_index) { 771 old_index < old_chunk.end_index; ++old_index) {
754 const DisplayItem& old_item = 772 const DisplayItem& old_item =
755 current_paint_artifact_.GetDisplayItemList()[old_index]; 773 current_paint_artifact_.GetDisplayItemList()[old_index];
756 const DisplayItemClient* client_to_invalidate = nullptr; 774 const DisplayItemClient* client_to_invalidate = nullptr;
757 bool is_potentially_invalid_client = false; 775 bool is_potentially_invalid_client = false;
758 if (!old_item.HasValidClient()) { 776 if (!old_item.HasValidClient()) {
759 size_t moved_to_index = items_moved_into_new_list_[old_index]; 777 size_t moved_to_index = items_moved_into_new_list_[old_index];
760 if (new_display_item_list_[moved_to_index].DrawsContent()) { 778 if (new_display_item_list_[moved_to_index].DrawsContent()) {
761 if (moved_to_index < new_chunk.begin_index || 779 if (moved_to_index < new_chunk.begin_index ||
762 moved_to_index >= new_chunk.end_index) { 780 moved_to_index >= new_chunk.end_index) {
763 // The item has been moved into another chunk, so need to invalidate 781 // The item has been moved into another chunk, so need to invalidate
764 // it in the old chunk. 782 // it in the old chunk.
765 client_to_invalidate = 783 client_to_invalidate =
766 &new_display_item_list_[moved_to_index].Client(); 784 &new_display_item_list_[moved_to_index].Client();
767 // And invalidate in the new chunk into which the item was moved. 785 // And invalidate in the new chunk into which the item was moved.
768 PaintChunk& moved_to_chunk = 786 PaintChunk& moved_to_chunk =
769 new_paint_chunks_.FindChunkByDisplayItemIndex(moved_to_index); 787 new_paint_chunks_.FindChunkByDisplayItemIndex(moved_to_index);
770 AddRasterInvalidationInfo( 788 AddRasterInvalidation(client_to_invalidate, moved_to_chunk,
771 client_to_invalidate, moved_to_chunk, 789 FloatRect(client_to_invalidate->VisualRect()));
772 FloatRect(client_to_invalidate->VisualRect()));
773 } else if (moved_to_index < highest_moved_to_index) { 790 } else if (moved_to_index < highest_moved_to_index) {
774 // The item has been moved behind other cached items, so need to 791 // The item has been moved behind other cached items, so need to
775 // invalidate the area that is probably exposed by the item moved 792 // invalidate the area that is probably exposed by the item moved
776 // earlier. 793 // earlier.
777 client_to_invalidate = 794 client_to_invalidate =
778 &new_display_item_list_[moved_to_index].Client(); 795 &new_display_item_list_[moved_to_index].Client();
779 } else { 796 } else {
780 highest_moved_to_index = moved_to_index; 797 highest_moved_to_index = moved_to_index;
781 } 798 }
782 } 799 }
783 } else if (old_item.DrawsContent()) { 800 } else if (old_item.DrawsContent()) {
784 is_potentially_invalid_client = true; 801 is_potentially_invalid_client = true;
785 client_to_invalidate = &old_item.Client(); 802 client_to_invalidate = &old_item.Client();
786 } 803 }
787 if (client_to_invalidate && 804 if (client_to_invalidate &&
788 invalidated_clients_in_old_chunk.insert(client_to_invalidate) 805 invalidated_clients_in_old_chunk.insert(client_to_invalidate)
789 .is_new_entry) { 806 .is_new_entry) {
790 AddRasterInvalidationInfo( 807 AddRasterInvalidation(
791 is_potentially_invalid_client ? nullptr : client_to_invalidate, 808 is_potentially_invalid_client ? nullptr : client_to_invalidate,
792 new_chunk, 809 new_chunk,
793 FloatRect(current_paint_artifact_.GetDisplayItemList().VisualRect( 810 FloatRect(current_paint_artifact_.GetDisplayItemList().VisualRect(
794 old_index))); 811 old_index)));
795 } 812 }
796 } 813 }
797 814
798 HashSet<const DisplayItemClient*> invalidated_clients_in_new_chunk; 815 HashSet<const DisplayItemClient*> invalidated_clients_in_new_chunk;
799 for (size_t new_index = new_chunk.begin_index; 816 for (size_t new_index = new_chunk.begin_index;
800 new_index < new_chunk.end_index; ++new_index) { 817 new_index < new_chunk.end_index; ++new_index) {
801 const DisplayItem& new_item = new_display_item_list_[new_index]; 818 const DisplayItem& new_item = new_display_item_list_[new_index];
802 if (new_item.DrawsContent() && !ClientCacheIsValid(new_item.Client()) && 819 if (new_item.DrawsContent() && !ClientCacheIsValid(new_item.Client()) &&
803 invalidated_clients_in_new_chunk.insert(&new_item.Client()) 820 invalidated_clients_in_new_chunk.insert(&new_item.Client())
804 .is_new_entry) { 821 .is_new_entry) {
805 AddRasterInvalidationInfo(&new_item.Client(), new_chunk, 822 AddRasterInvalidation(&new_item.Client(), new_chunk,
806 FloatRect(new_item.Client().VisualRect())); 823 FloatRect(new_item.Client().VisualRect()));
807 } 824 }
808 } 825 }
809 } 826 }
810 827
811 void PaintController::ShowUnderInvalidationError( 828 void PaintController::ShowUnderInvalidationError(
812 const char* reason, 829 const char* reason,
813 const DisplayItem& new_item, 830 const DisplayItem& new_item,
814 const DisplayItem* old_item) const { 831 const DisplayItem* old_item) const {
815 LOG(ERROR) << under_invalidation_message_prefix_ << " " << reason; 832 LOG(ERROR) << under_invalidation_message_prefix_ << " " << reason;
816 #ifndef NDEBUG 833 #ifndef NDEBUG
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
938 show_paint_records 955 show_paint_records
939 ? (DisplayItemList::JsonOptions::kShowPaintRecords | 956 ? (DisplayItemList::JsonOptions::kShowPaintRecords |
940 DisplayItemList::JsonOptions::kShowClientDebugName) 957 DisplayItemList::JsonOptions::kShowClientDebugName)
941 : DisplayItemList::JsonOptions::kShowClientDebugName) 958 : DisplayItemList::JsonOptions::kShowClientDebugName)
942 ->ToPrettyJSONString() 959 ->ToPrettyJSONString()
943 .Utf8() 960 .Utf8()
944 .data()); 961 .data());
945 } 962 }
946 963
947 } // namespace blink 964 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698