LCOV - code coverage report
Current view: top level - widget - VsyncDispatcher.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 71 87 81.6 %
Date: 2017-07-14 16:53:18 Functions: 13 18 72.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #include "MainThreadUtils.h"
       7             : #include "VsyncDispatcher.h"
       8             : #include "VsyncSource.h"
       9             : #include "gfxPlatform.h"
      10             : #include "mozilla/layers/Compositor.h"
      11             : #include "mozilla/layers/CompositorBridgeParent.h"
      12             : #include "mozilla/layers/CompositorThread.h"
      13             : 
      14             : using namespace mozilla::layers;
      15             : 
      16             : namespace mozilla {
      17             : 
      18           1 : CompositorVsyncDispatcher::CompositorVsyncDispatcher()
      19             :   : mCompositorObserverLock("CompositorObserverLock")
      20           1 :   , mDidShutdown(false)
      21             : {
      22           1 :   MOZ_ASSERT(XRE_IsParentProcess());
      23           1 :   MOZ_ASSERT(NS_IsMainThread());
      24           1 : }
      25             : 
      26           0 : CompositorVsyncDispatcher::~CompositorVsyncDispatcher()
      27             : {
      28           0 :   MOZ_ASSERT(XRE_IsParentProcess());
      29             :   // We auto remove this vsync dispatcher from the vsync source in the nsBaseWidget
      30           0 : }
      31             : 
      32             : void
      33         296 : CompositorVsyncDispatcher::NotifyVsync(TimeStamp aVsyncTimestamp)
      34             : {
      35             :   // In vsync thread
      36         296 :   layers::CompositorBridgeParent::PostInsertVsyncProfilerMarker(aVsyncTimestamp);
      37             : 
      38         592 :   MutexAutoLock lock(mCompositorObserverLock);
      39         296 :   if (mCompositorVsyncObserver) {
      40         142 :     mCompositorVsyncObserver->NotifyVsync(aVsyncTimestamp);
      41             :   }
      42         296 : }
      43             : 
      44             : void
      45          16 : CompositorVsyncDispatcher::ObserveVsync(bool aEnable)
      46             : {
      47          16 :   MOZ_ASSERT(NS_IsMainThread());
      48          16 :   MOZ_ASSERT(XRE_IsParentProcess());
      49          16 :   if (mDidShutdown) {
      50           0 :     return;
      51             :   }
      52             : 
      53          16 :   if (aEnable) {
      54           8 :     gfxPlatform::GetPlatform()->GetHardwareVsync()->AddCompositorVsyncDispatcher(this);
      55             :   } else {
      56           8 :     gfxPlatform::GetPlatform()->GetHardwareVsync()->RemoveCompositorVsyncDispatcher(this);
      57             :   }
      58             : }
      59             : 
      60             : void
      61          17 : CompositorVsyncDispatcher::SetCompositorVsyncObserver(VsyncObserver* aVsyncObserver)
      62             : {
      63             :   // When remote compositing or running gtests, vsync observation is
      64             :   // initiated on the main thread. Otherwise, it is initiated from the compositor
      65             :   // thread.
      66          17 :   MOZ_ASSERT(NS_IsMainThread() || CompositorThreadHolder::IsInCompositorThread());
      67             : 
      68             :   { // scope lock
      69          34 :     MutexAutoLock lock(mCompositorObserverLock);
      70          17 :     mCompositorVsyncObserver = aVsyncObserver;
      71             :   }
      72             : 
      73          17 :   bool observeVsync = aVsyncObserver != nullptr;
      74             :   nsCOMPtr<nsIRunnable> vsyncControl =
      75          34 :     NewRunnableMethod<bool>("CompositorVsyncDispatcher::ObserveVsync",
      76             :                             this,
      77             :                             &CompositorVsyncDispatcher::ObserveVsync,
      78          34 :                             observeVsync);
      79          17 :   NS_DispatchToMainThread(vsyncControl);
      80          17 : }
      81             : 
      82             : void
      83           0 : CompositorVsyncDispatcher::Shutdown()
      84             : {
      85             :   // Need to explicitly remove CompositorVsyncDispatcher when the nsBaseWidget shuts down.
      86             :   // Otherwise, we would get dead vsync notifications between when the nsBaseWidget
      87             :   // shuts down and the CompositorBridgeParent shuts down.
      88           0 :   MOZ_ASSERT(XRE_IsParentProcess());
      89           0 :   MOZ_ASSERT(NS_IsMainThread());
      90           0 :   ObserveVsync(false);
      91           0 :   mDidShutdown = true;
      92             :   { // scope lock
      93           0 :     MutexAutoLock lock(mCompositorObserverLock);
      94           0 :     mCompositorVsyncObserver = nullptr;
      95             :   }
      96           0 : }
      97             : 
      98           1 : RefreshTimerVsyncDispatcher::RefreshTimerVsyncDispatcher()
      99           1 :   : mRefreshTimersLock("RefreshTimers lock")
     100             : {
     101           1 :   MOZ_ASSERT(XRE_IsParentProcess());
     102           1 :   MOZ_ASSERT(NS_IsMainThread());
     103           1 : }
     104             : 
     105           0 : RefreshTimerVsyncDispatcher::~RefreshTimerVsyncDispatcher()
     106             : {
     107           0 :   MOZ_ASSERT(XRE_IsParentProcess());
     108           0 :   MOZ_ASSERT(NS_IsMainThread());
     109           0 : }
     110             : 
     111             : void
     112         510 : RefreshTimerVsyncDispatcher::NotifyVsync(TimeStamp aVsyncTimestamp)
     113             : {
     114        1020 :   MutexAutoLock lock(mRefreshTimersLock);
     115             : 
     116         554 :   for (size_t i = 0; i < mChildRefreshTimers.Length(); i++) {
     117          44 :     mChildRefreshTimers[i]->NotifyVsync(aVsyncTimestamp);
     118             :   }
     119             : 
     120         510 :   if (mParentRefreshTimer) {
     121         508 :     mParentRefreshTimer->NotifyVsync(aVsyncTimestamp);
     122             :   }
     123         510 : }
     124             : 
     125             : void
     126           9 : RefreshTimerVsyncDispatcher::SetParentRefreshTimer(VsyncObserver* aVsyncObserver)
     127             : {
     128           9 :   MOZ_ASSERT(NS_IsMainThread());
     129             :   { // lock scope because UpdateVsyncStatus runs on main thread and will deadlock
     130          18 :     MutexAutoLock lock(mRefreshTimersLock);
     131           9 :     mParentRefreshTimer = aVsyncObserver;
     132             :   }
     133             : 
     134           9 :   UpdateVsyncStatus();
     135           9 : }
     136             : 
     137             : void
     138           2 : RefreshTimerVsyncDispatcher::AddChildRefreshTimer(VsyncObserver* aVsyncObserver)
     139             : {
     140             :   { // scope lock - called on pbackground thread
     141           4 :     MutexAutoLock lock(mRefreshTimersLock);
     142           2 :     MOZ_ASSERT(aVsyncObserver);
     143           2 :     if (!mChildRefreshTimers.Contains(aVsyncObserver)) {
     144           2 :       mChildRefreshTimers.AppendElement(aVsyncObserver);
     145             :     }
     146             :   }
     147             : 
     148           2 :   UpdateVsyncStatus();
     149           2 : }
     150             : 
     151             : void
     152           2 : RefreshTimerVsyncDispatcher::RemoveChildRefreshTimer(VsyncObserver* aVsyncObserver)
     153             : {
     154             :   { // scope lock - called on pbackground thread
     155           4 :     MutexAutoLock lock(mRefreshTimersLock);
     156           2 :     MOZ_ASSERT(aVsyncObserver);
     157           2 :     mChildRefreshTimers.RemoveElement(aVsyncObserver);
     158             :   }
     159             : 
     160           2 :   UpdateVsyncStatus();
     161           2 : }
     162             : 
     163             : void
     164          16 : RefreshTimerVsyncDispatcher::UpdateVsyncStatus()
     165             : {
     166          16 :   if (!NS_IsMainThread()) {
     167           8 :     NS_DispatchToMainThread(
     168           8 :       NewRunnableMethod("RefreshTimerVsyncDispatcher::UpdateVsyncStatus",
     169             :                         this,
     170           4 :                         &RefreshTimerVsyncDispatcher::UpdateVsyncStatus));
     171           4 :     return;
     172             :   }
     173             : 
     174          12 :   gfx::VsyncSource::Display& display = gfxPlatform::GetPlatform()->GetHardwareVsync()->GetGlobalDisplay();
     175          12 :   display.NotifyRefreshTimerVsyncStatus(NeedsVsync());
     176             : }
     177             : 
     178             : bool
     179          12 : RefreshTimerVsyncDispatcher::NeedsVsync()
     180             : {
     181          12 :   MOZ_ASSERT(NS_IsMainThread());
     182          24 :   MutexAutoLock lock(mRefreshTimersLock);
     183          24 :   return (mParentRefreshTimer != nullptr) || !mChildRefreshTimers.IsEmpty();
     184             : }
     185             : 
     186           9 : } // namespace mozilla

Generated by: LCOV version 1.13