blob: 6482e12c2c476dadd305ec6305ba61eb95e72369 [file] [log] [blame]
// Copyright 2014 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/page/page_animator.h"
#include "base/auto_reset.h"
#include "third_party/blink/renderer/core/animation/document_animations.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/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/page/validation_message_client.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/core/svg/svg_document_extensions.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
namespace blink {
PageAnimator::PageAnimator(Page& page)
: page_(page),
servicing_animations_(false),
updating_layout_and_style_for_painting_(false) {}
PageAnimator* PageAnimator::Create(Page& page) {
return MakeGarbageCollected<PageAnimator>(page);
}
void PageAnimator::Trace(blink::Visitor* visitor) {
visitor->Trace(page_);
}
void PageAnimator::ServiceScriptedAnimations(
base::TimeTicks monotonic_animation_start_time) {
base::AutoReset<bool> servicing(&servicing_animations_, true);
Clock().UpdateTime(monotonic_animation_start_time);
HeapVector<Member<Document>, 32> documents;
for (Frame* frame = page_->MainFrame(); frame;
frame = frame->Tree().TraverseNext()) {
if (frame->IsLocalFrame())
documents.push_back(ToLocalFrame(frame)->GetDocument());
}
for (auto& document : documents) {
ScopedFrameBlamer frame_blamer(document->GetFrame());
TRACE_EVENT0("blink,rail", "PageAnimator::serviceScriptedAnimations");
DocumentAnimations::UpdateAnimationTimingForAnimationFrame(*document);
if (document->View()) {
if (document->View()->ShouldThrottleRendering())
continue;
// Disallow throttling in case any script needs to do a synchronous
// lifecycle update in other frames which are throttled.
DocumentLifecycle::DisallowThrottlingScope no_throttling_scope(
document->Lifecycle());
if (ScrollableArea* scrollable_area =
document->View()->GetScrollableArea()) {
scrollable_area->ServiceScrollAnimations(
monotonic_animation_start_time.since_origin().InSecondsF());
}
if (const LocalFrameView::ScrollableAreaSet* animating_scrollable_areas =
document->View()->AnimatingScrollableAreas()) {
// Iterate over a copy, since ScrollableAreas may deregister
// themselves during the iteration.
HeapVector<Member<PaintLayerScrollableArea>>
animating_scrollable_areas_copy;
CopyToVector(*animating_scrollable_areas,
animating_scrollable_areas_copy);
for (PaintLayerScrollableArea* scrollable_area :
animating_scrollable_areas_copy) {
scrollable_area->ServiceScrollAnimations(
monotonic_animation_start_time.since_origin().InSecondsF());
}
}
document->GetFrame()->AnimateSnapFling(monotonic_animation_start_time);
SVGDocumentExtensions::ServiceOnAnimationFrame(*document);
}
// TODO(skyostil): This function should not run for documents without views.
DocumentLifecycle::DisallowThrottlingScope no_throttling_scope(
document->Lifecycle());
document->ServiceScriptedAnimations(monotonic_animation_start_time);
}
page_->GetValidationMessageClient().LayoutOverlay();
}
void PageAnimator::SetSuppressFrameRequestsWorkaroundFor704763Only(
bool suppress_frame_requests) {
// If we are enabling the suppression and it was already enabled then we must
// have missed disabling it at the end of a previous frame.
DCHECK(!suppress_frame_requests_workaround_for704763_only_ ||
!suppress_frame_requests);
suppress_frame_requests_workaround_for704763_only_ = suppress_frame_requests;
}
DISABLE_CFI_PERF
void PageAnimator::ScheduleVisualUpdate(LocalFrame* frame) {
if (servicing_animations_ || updating_layout_and_style_for_painting_ ||
suppress_frame_requests_workaround_for704763_only_) {
return;
}
page_->GetChromeClient().ScheduleAnimation(frame->View());
}
void PageAnimator::UpdateAllLifecyclePhases(
LocalFrame& root_frame,
DocumentLifecycle::LifecycleUpdateReason reason) {
LocalFrameView* view = root_frame.View();
base::AutoReset<bool> servicing(&updating_layout_and_style_for_painting_,
true);
view->UpdateAllLifecyclePhases(reason);
}
void PageAnimator::UpdateAllLifecyclePhasesExceptPaint(LocalFrame& root_frame) {
LocalFrameView* view = root_frame.View();
base::AutoReset<bool> servicing(&updating_layout_and_style_for_painting_,
true);
view->UpdateAllLifecyclePhasesExceptPaint();
}
void PageAnimator::UpdateLifecycleToLayoutClean(LocalFrame& root_frame) {
LocalFrameView* view = root_frame.View();
base::AutoReset<bool> servicing(&updating_layout_and_style_for_painting_,
true);
view->UpdateLifecycleToLayoutClean();
}
} // namespace blink