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