summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/page/page_animator.cc
blob: 19099bd2b50bd1eb6c0091719ab4d6a17787d0bf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// 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 new 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) {
  LocalFrameView* view = root_frame.View();
  base::AutoReset<bool> servicing(&updating_layout_and_style_for_painting_,
                                  true);
  view->UpdateAllLifecyclePhases();
}

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