Home | History | Annotate | Download | only in page
      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
      3 // found in the LICENSE file.
      4 
      5 #include "config.h"
      6 #include "core/page/PageAnimator.h"
      7 
      8 #include "core/animation/DocumentAnimations.h"
      9 #include "core/dom/Document.h"
     10 #include "core/frame/FrameView.h"
     11 #include "core/frame/LocalFrame.h"
     12 #include "core/page/Chrome.h"
     13 #include "core/page/ChromeClient.h"
     14 #include "core/page/Page.h"
     15 #include "core/svg/SVGDocumentExtensions.h"
     16 
     17 namespace WebCore {
     18 
     19 PageAnimator::PageAnimator(Page* page)
     20     : m_page(page)
     21     , m_animationFramePending(false)
     22     , m_servicingAnimations(false)
     23     , m_updatingLayoutAndStyleForPainting(false)
     24 {
     25 }
     26 
     27 void PageAnimator::serviceScriptedAnimations(double monotonicAnimationStartTime)
     28 {
     29     m_animationFramePending = false;
     30     TemporaryChange<bool> servicing(m_servicingAnimations, true);
     31 
     32     for (RefPtr<Frame> frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
     33         if (frame->isLocalFrame()) {
     34             RefPtr<LocalFrame> localFrame = toLocalFrame(frame.get());
     35             localFrame->view()->serviceScrollAnimations();
     36 
     37             DocumentAnimations::updateAnimationTimingForAnimationFrame(*localFrame->document(), monotonicAnimationStartTime);
     38             SVGDocumentExtensions::serviceOnAnimationFrame(*localFrame->document(), monotonicAnimationStartTime);
     39         }
     40     }
     41 
     42     WillBeHeapVector<RefPtrWillBeMember<Document> > documents;
     43     for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
     44         if (frame->isLocalFrame())
     45             documents.append(toLocalFrame(frame)->document());
     46     }
     47 
     48     for (size_t i = 0; i < documents.size(); ++i)
     49         documents[i]->serviceScriptedAnimations(monotonicAnimationStartTime);
     50 }
     51 
     52 void PageAnimator::scheduleVisualUpdate()
     53 {
     54     // FIXME: also include m_animationFramePending here. It is currently not there due to crbug.com/353756.
     55     if (m_servicingAnimations || m_updatingLayoutAndStyleForPainting)
     56         return;
     57     m_page->chrome().scheduleAnimation();
     58 }
     59 
     60 void PageAnimator::updateLayoutAndStyleForPainting()
     61 {
     62     if (!m_page->mainFrame()->isLocalFrame())
     63         return;
     64 
     65     RefPtr<FrameView> view = m_page->deprecatedLocalMainFrame()->view();
     66 
     67     TemporaryChange<bool> servicing(m_updatingLayoutAndStyleForPainting, true);
     68 
     69     // In order for our child HWNDs (NativeWindowWidgets) to update properly,
     70     // they need to be told that we are updating the screen. The problem is that
     71     // the native widgets need to recalculate their clip region and not overlap
     72     // any of our non-native widgets. To force the resizing, call
     73     // setFrameRect(). This will be a quick operation for most frames, but the
     74     // NativeWindowWidgets will update a proper clipping region.
     75     view->setFrameRect(view->frameRect());
     76 
     77     // setFrameRect may have the side-effect of causing existing page layout to
     78     // be invalidated, so layout needs to be called last.
     79     view->updateLayoutAndStyleForPainting();
     80 }
     81 
     82 }
     83