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" |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |