LCOV - code coverage report
Current view: top level - gfx/thebes - SoftwareVsyncSource.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 63 77 81.8 %
Date: 2017-07-14 16:53:18 Functions: 9 14 64.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 20; 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             : 
       7             : #include "SoftwareVsyncSource.h"
       8             : #include "base/task.h"
       9             : #include "gfxPlatform.h"
      10             : #include "nsThreadUtils.h"
      11             : 
      12             : using namespace mozilla;
      13             : 
      14           1 : SoftwareVsyncSource::SoftwareVsyncSource()
      15             : {
      16           1 :   MOZ_ASSERT(NS_IsMainThread());
      17           1 :   mGlobalDisplay = new SoftwareDisplay();
      18           1 : }
      19             : 
      20           0 : SoftwareVsyncSource::~SoftwareVsyncSource()
      21             : {
      22           0 :   MOZ_ASSERT(NS_IsMainThread());
      23           0 :   mGlobalDisplay = nullptr;
      24           0 : }
      25             : 
      26           1 : SoftwareDisplay::SoftwareDisplay()
      27           1 :   : mVsyncEnabled(false)
      28             : {
      29             :   // Mimic 60 fps
      30           1 :   MOZ_ASSERT(NS_IsMainThread());
      31           1 :   const double rate = 1000.0 / (double) gfxPlatform::GetSoftwareVsyncRate();
      32           1 :   mVsyncRate = mozilla::TimeDuration::FromMilliseconds(rate);
      33           1 :   mVsyncThread = new base::Thread("SoftwareVsyncThread");
      34           1 :   MOZ_RELEASE_ASSERT(mVsyncThread->Start(), "GFX: Could not start software vsync thread");
      35           1 : }
      36             : 
      37           0 : SoftwareDisplay::~SoftwareDisplay() {}
      38             : 
      39             : void
      40          28 : SoftwareDisplay::EnableVsync()
      41             : {
      42          28 :   MOZ_ASSERT(mVsyncThread->IsRunning());
      43          28 :   if (NS_IsMainThread()) {
      44          25 :     if (mVsyncEnabled) {
      45          22 :       return;
      46             :     }
      47           3 :     mVsyncEnabled = true;
      48             : 
      49           6 :     mVsyncThread->message_loop()->PostTask(NewRunnableMethod(
      50           3 :       "SoftwareDisplay::EnableVsync", this, &SoftwareDisplay::EnableVsync));
      51           3 :     return;
      52             :   }
      53             : 
      54           3 :   MOZ_ASSERT(IsInSoftwareVsyncThread());
      55           3 :   NotifyVsync(mozilla::TimeStamp::Now());
      56             : }
      57             : 
      58             : void
      59           6 : SoftwareDisplay::DisableVsync()
      60             : {
      61           6 :   MOZ_ASSERT(mVsyncThread->IsRunning());
      62           6 :   if (NS_IsMainThread()) {
      63           3 :     if (!mVsyncEnabled) {
      64           0 :       return;
      65             :     }
      66           3 :     mVsyncEnabled = false;
      67             : 
      68           6 :     mVsyncThread->message_loop()->PostTask(NewRunnableMethod(
      69           3 :       "SoftwareDisplay::DisableVsync", this, &SoftwareDisplay::DisableVsync));
      70           3 :     return;
      71             :   }
      72             : 
      73           3 :   MOZ_ASSERT(IsInSoftwareVsyncThread());
      74           3 :   if (mCurrentVsyncTask) {
      75           3 :     mCurrentVsyncTask->Cancel();
      76           3 :     mCurrentVsyncTask = nullptr;
      77             :   }
      78             : }
      79             : 
      80             : bool
      81          28 : SoftwareDisplay::IsVsyncEnabled()
      82             : {
      83          28 :   MOZ_ASSERT(NS_IsMainThread());
      84          28 :   return mVsyncEnabled;
      85             : }
      86             : 
      87             : bool
      88        1044 : SoftwareDisplay::IsInSoftwareVsyncThread()
      89             : {
      90        1044 :   return mVsyncThread->thread_id() == PlatformThread::CurrentId();
      91             : }
      92             : 
      93             : void
      94         519 : SoftwareDisplay::NotifyVsync(mozilla::TimeStamp aVsyncTimestamp)
      95             : {
      96         519 :   MOZ_ASSERT(IsInSoftwareVsyncThread());
      97             : 
      98         519 :   mozilla::TimeStamp displayVsyncTime = aVsyncTimestamp;
      99         519 :   mozilla::TimeStamp now = mozilla::TimeStamp::Now();
     100             :   // Posted tasks can only have integer millisecond delays
     101             :   // whereas TimeDurations can have floating point delays.
     102             :   // Thus the vsync timestamp can be in the future, which large parts
     103             :   // of the system can't handle, including animations. Force the timestamp to be now.
     104         519 :   if (aVsyncTimestamp > now) {
     105         465 :     displayVsyncTime = now;
     106             :   }
     107             : 
     108         519 :   Display::NotifyVsync(displayVsyncTime);
     109             : 
     110             :   // Prevent skew by still scheduling based on the original
     111             :   // vsync timestamp
     112         519 :   ScheduleNextVsync(aVsyncTimestamp);
     113         519 : }
     114             : 
     115             : mozilla::TimeDuration
     116           3 : SoftwareDisplay::GetVsyncRate()
     117             : {
     118           3 :   return mVsyncRate;
     119             : }
     120             : 
     121             : void
     122         519 : SoftwareDisplay::ScheduleNextVsync(mozilla::TimeStamp aVsyncTimestamp)
     123             : {
     124         519 :   MOZ_ASSERT(IsInSoftwareVsyncThread());
     125         519 :   mozilla::TimeStamp nextVsync = aVsyncTimestamp + mVsyncRate;
     126         519 :   mozilla::TimeDuration delay = nextVsync - mozilla::TimeStamp::Now();
     127         519 :   if (delay.ToMilliseconds() < 0) {
     128           0 :     delay = mozilla::TimeDuration::FromMilliseconds(0);
     129           0 :     nextVsync = mozilla::TimeStamp::Now();
     130             :   }
     131             : 
     132        1038 :   mCurrentVsyncTask = NewCancelableRunnableMethod<mozilla::TimeStamp>(
     133             :     "SoftwareDisplay::NotifyVsync",
     134             :     this,
     135             :     &SoftwareDisplay::NotifyVsync,
     136         519 :     nextVsync);
     137             : 
     138        1038 :   RefPtr<Runnable> addrefedTask = mCurrentVsyncTask;
     139        1557 :   mVsyncThread->message_loop()->PostDelayedTask(
     140        1038 :     addrefedTask.forget(),
     141        1038 :     delay.ToMilliseconds());
     142         519 : }
     143             : 
     144             : void
     145           0 : SoftwareDisplay::Shutdown()
     146             : {
     147           0 :   MOZ_ASSERT(NS_IsMainThread());
     148           0 :   DisableVsync();
     149           0 :   mVsyncThread->Stop();
     150           0 :   delete mVsyncThread;
     151           0 : }

Generated by: LCOV version 1.13