1 // Copyright 2018 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_IMAGE_ELEMENT_TIMING_H_ 6 #define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_IMAGE_ELEMENT_TIMING_H_ 7 8 #include <utility> 9 10 #include "third_party/blink/public/web/web_swap_result.h" 11 #include "third_party/blink/renderer/core/dom/element.h" 12 #include "third_party/blink/renderer/core/frame/local_dom_window.h" 13 #include "third_party/blink/renderer/platform/heap/heap_allocator.h" 14 #include "third_party/blink/renderer/platform/supplementable.h" 15 #include "third_party/blink/renderer/platform/wtf/functional.h" 16 #include "third_party/blink/renderer/platform/wtf/hash_set.h" 17 18 #include "third_party/blink/renderer/platform/wtf/vector.h" 19 20 namespace blink { 21 22 class ImageResourceContent; 23 class PropertyTreeStateOrAlias; 24 class StyleFetchedImage; 25 26 // ImageElementTiming is responsible for tracking the paint timings for <img> 27 // elements for a given window. 28 class CORE_EXPORT ImageElementTiming final 29 : public GarbageCollected<ImageElementTiming>, 30 public Supplement<LocalDOMWindow> { 31 public: 32 static const char kSupplementName[]; 33 34 // The maximum amount of characters included in Element Timing and Largest 35 // Contentful Paint for inline images. 36 static constexpr const unsigned kInlineImageMaxChars = 100; 37 38 explicit ImageElementTiming(LocalDOMWindow&); 39 ImageElementTiming(const ImageElementTiming&) = delete; 40 ImageElementTiming& operator=(const ImageElementTiming&) = delete; 41 virtual ~ImageElementTiming() = default; 42 43 static ImageElementTiming& From(LocalDOMWindow&); 44 45 void NotifyImageFinished(const LayoutObject&, const ImageResourceContent*); 46 47 void NotifyBackgroundImageFinished(const StyleFetchedImage*); 48 base::TimeTicks GetBackgroundImageLoadTime(const StyleFetchedImage*); 49 50 // Called when the LayoutObject has been painted. This method might queue a 51 // swap promise to compute and report paint timestamps. 52 void NotifyImagePainted( 53 const LayoutObject*, 54 const ImageResourceContent* cached_image, 55 const PropertyTreeStateOrAlias& current_paint_chunk_properties, 56 const IntRect& image_border); 57 58 void NotifyBackgroundImagePainted( 59 Node*, 60 const StyleFetchedImage* background_image, 61 const PropertyTreeStateOrAlias& current_paint_chunk_properties, 62 const IntRect& image_border); 63 64 void NotifyImageRemoved(const LayoutObject*, 65 const ImageResourceContent* image); 66 67 void Trace(Visitor*) const override; 68 69 private: 70 friend class ImageElementTimingTest; 71 72 void NotifyImagePaintedInternal( 73 Node*, 74 const LayoutObject&, 75 const ImageResourceContent& cached_image, 76 const PropertyTreeStateOrAlias& current_paint_chunk_properties, 77 base::TimeTicks load_time, 78 const IntRect& image_border); 79 80 // Callback for the swap promise. Reports paint timestamps. 81 void ReportImagePaintSwapTime(WebSwapResult, base::TimeTicks timestamp); 82 83 // Class containing information about image element timing. 84 class ElementTimingInfo final : public GarbageCollected<ElementTimingInfo> { 85 public: ElementTimingInfo(const String & url,const FloatRect & rect,const base::TimeTicks & response_end,const AtomicString & identifier,const IntSize & intrinsic_size,const AtomicString & id,Element * element)86 ElementTimingInfo(const String& url, 87 const FloatRect& rect, 88 const base::TimeTicks& response_end, 89 const AtomicString& identifier, 90 const IntSize& intrinsic_size, 91 const AtomicString& id, 92 Element* element) 93 : url(url), 94 rect(rect), 95 response_end(response_end), 96 identifier(identifier), 97 intrinsic_size(intrinsic_size), 98 id(id), 99 element(element) {} 100 ElementTimingInfo(const ElementTimingInfo&) = delete; 101 ElementTimingInfo& operator=(const ElementTimingInfo&) = delete; 102 ~ElementTimingInfo() = default; 103 Trace(Visitor * visitor)104 void Trace(Visitor* visitor) const { visitor->Trace(element); } 105 106 String url; 107 FloatRect rect; 108 base::TimeTicks response_end; 109 AtomicString identifier; 110 IntSize intrinsic_size; 111 AtomicString id; 112 Member<Element> element; 113 }; 114 115 // Vector containing the element timing infos that will be reported during the 116 // next swap promise callback. 117 HeapVector<Member<ElementTimingInfo>> element_timings_; 118 struct ImageInfo { ImageInfoImageInfo119 ImageInfo() {} 120 121 base::TimeTicks load_time_; 122 bool is_painted_ = false; 123 }; 124 typedef std::pair<const LayoutObject*, const ImageResourceContent*> RecordId; 125 // Hashmap of pairs of elements, LayoutObjects (for the elements) and 126 // ImageResourceContent (for the src) which correspond to either images or 127 // background images whose paint has been observed. For background images, 128 // only the |is_painted_| bit is used, as the timestamp needs to be tracked by 129 // |background_image_timestamps_|. 130 WTF::HashMap<RecordId, ImageInfo> images_notified_; 131 132 // Hashmap of background images which contain information about the load time 133 // of the background image. 134 HeapHashMap<WeakMember<const StyleFetchedImage>, base::TimeTicks> 135 background_image_timestamps_; 136 }; 137 138 } // namespace blink 139 140 #endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_IMAGE_ELEMENT_TIMING_H_ 141