blob: 23f48306296d610907e839d80a40a1cee9e7ab5e [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/core/paint/paint_timing_detector.h"
#include "third_party/blink/public/platform/web_input_event.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/loader/document_loader.h"
#include "third_party/blink/renderer/core/paint/image_paint_timing_detector.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/paint/text_paint_timing_detector.h"
#include "third_party/blink/renderer/platform/geometry/int_rect.h"
namespace blink {
PaintTimingDetector::PaintTimingDetector(LocalFrameView* frame_view)
: frame_view_(frame_view),
text_paint_timing_detector_(
MakeGarbageCollected<TextPaintTimingDetector>(frame_view)),
image_paint_timing_detector_(
MakeGarbageCollected<ImagePaintTimingDetector>(frame_view)){};
void PaintTimingDetector::NotifyPrePaintFinished() {
text_paint_timing_detector_->OnPrePaintFinished();
image_paint_timing_detector_->OnPrePaintFinished();
}
void PaintTimingDetector::NotifyObjectPrePaint(
const LayoutObject& object,
const PaintLayer& painting_layer) {
// Todo(maxlg): incoperate iframe's statistics
if (!frame_view_->GetFrame().IsMainFrame())
return;
if (object.IsText()) {
text_paint_timing_detector_->RecordText(object, painting_layer);
}
if (object.IsImage() || object.IsVideo() || object.IsSVGImage() ||
ImagePaintTimingDetector::HasContentfulBackgroundImage(object)) {
image_paint_timing_detector_->RecordImage(object, painting_layer);
}
// Todo(maxlg): add other detectors here.
}
void PaintTimingDetector::NotifyNodeRemoved(const LayoutObject& object) {
if (!object.GetNode())
return;
text_paint_timing_detector_->NotifyNodeRemoved(
DOMNodeIds::IdForNode(object.GetNode()));
image_paint_timing_detector_->NotifyNodeRemoved(
DOMNodeIds::IdForNode(object.GetNode()));
}
void PaintTimingDetector::NotifyInputEvent(WebInputEvent::Type type) {
if (type == WebInputEvent::kMouseMove || type == WebInputEvent::kMouseEnter ||
type == WebInputEvent::kMouseLeave ||
WebInputEvent::IsPinchGestureEventType(type)) {
return;
}
text_paint_timing_detector_->StopRecordEntries();
image_paint_timing_detector_->StopRecordEntries();
}
void PaintTimingDetector::NotifyScroll(ScrollType scroll_type) {
if (scroll_type != kUserScroll && scroll_type != kCompositorScroll)
return;
text_paint_timing_detector_->StopRecordEntries();
image_paint_timing_detector_->StopRecordEntries();
}
bool PaintTimingDetector::NeedToNotifyInputOrScroll() {
return text_paint_timing_detector_->IsRecording() ||
image_paint_timing_detector_->IsRecording();
}
void PaintTimingDetector::DidChangePerformanceTiming() {
Document* document = frame_view_->GetFrame().GetDocument();
if (!document)
return;
DocumentLoader* loader = document->Loader();
if (!loader)
return;
loader->DidChangePerformanceTiming();
}
uint64_t PaintTimingDetector::CalculateVisualSize(
const LayoutRect& invalidated_rect,
const PaintLayer& painting_layer) const {
// This case should be dealt with outside the function.
DCHECK(!invalidated_rect.IsEmpty());
// As Layout objects live in different transform spaces, the object's rect
// should be projected to the viewport's transform space.
IntRect visual_rect = SaturatedRect(EnclosedIntRect(invalidated_rect));
painting_layer.GetLayoutObject().FirstFragment().MapRectToFragment(
painting_layer.GetLayoutObject().View()->FirstFragment(), visual_rect);
// A visual rect means the part of the rect that's visible within
// the viewport. We define the size of it as visual size.
ScrollableArea* scrollable_area = frame_view_->GetScrollableArea();
DCHECK(scrollable_area);
IntRect viewport = scrollable_area->VisibleContentRect();
// Use saturated rect to avoid integer-overflow.
visual_rect.Intersect(SaturatedRect(viewport));
return visual_rect.Size().Area();
}
void PaintTimingDetector::Dispose() {
text_paint_timing_detector_->Dispose();
}
void PaintTimingDetector::Trace(Visitor* visitor) {
visitor->Trace(text_paint_timing_detector_);
visitor->Trace(image_paint_timing_detector_);
visitor->Trace(frame_view_);
}
} // namespace blink