LCOV - code coverage report
Current view: directory - layout/base - nsRefreshDriver.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 227 3 1.3 %
Date: 2012-06-02 Functions: 33 1 3.0 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
       3                 : /* ***** BEGIN LICENSE BLOCK *****
       4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       5                 :  *
       6                 :  * The contents of this file are subject to the Mozilla Public License Version
       7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       8                 :  * the License. You may obtain a copy of the License at
       9                 :  * http://www.mozilla.org/MPL/
      10                 :  *
      11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      13                 :  * for the specific language governing rights and limitations under the
      14                 :  * License.
      15                 :  *
      16                 :  * The Original Code is nsRefreshDriver.
      17                 :  *
      18                 :  * The Initial Developer of the Original Code is the Mozilla Foundation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 2009
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   L. David Baron <dbaron@dbaron.org>, Mozilla Corporation (original author)
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      27                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : /*
      40                 :  * Code to notify things that animate before a refresh, at an appropriate
      41                 :  * refresh rate.  (Perhaps temporary, until replaced by compositor.)
      42                 :  */
      43                 : 
      44                 : #include "mozilla/Util.h"
      45                 : 
      46                 : #include "nsRefreshDriver.h"
      47                 : #include "nsPresContext.h"
      48                 : #include "nsComponentManagerUtils.h"
      49                 : #include "prlog.h"
      50                 : #include "nsAutoPtr.h"
      51                 : #include "nsCSSFrameConstructor.h"
      52                 : #include "nsIDocument.h"
      53                 : #include "nsGUIEvent.h"
      54                 : #include "nsEventDispatcher.h"
      55                 : #include "jsapi.h"
      56                 : #include "nsContentUtils.h"
      57                 : #include "mozilla/Preferences.h"
      58                 : #include "nsIViewManager.h"
      59                 : 
      60                 : using mozilla::TimeStamp;
      61                 : using mozilla::TimeDuration;
      62                 : 
      63                 : using namespace mozilla;
      64                 : 
      65                 : #define DEFAULT_FRAME_RATE 60
      66                 : #define DEFAULT_THROTTLED_FRAME_RATE 1
      67                 : 
      68                 : static bool sPrecisePref;
      69                 : 
      70                 : /* static */ void
      71            1404 : nsRefreshDriver::InitializeStatics()
      72                 : {
      73                 :   Preferences::AddBoolVarCache(&sPrecisePref,
      74                 :                                "layout.frame_rate.precise",
      75            1404 :                                false);
      76            1404 : }
      77                 : 
      78                 : /* static */ PRInt32
      79               0 : nsRefreshDriver::DefaultInterval()
      80                 : {
      81               0 :   return NSToIntRound(1000.0 / DEFAULT_FRAME_RATE);
      82                 : }
      83                 : 
      84                 : // Compute the interval to use for the refresh driver timer, in
      85                 : // milliseconds
      86                 : PRInt32
      87               0 : nsRefreshDriver::GetRefreshTimerInterval() const
      88                 : {
      89                 :   const char* prefName =
      90               0 :     mThrottled ? "layout.throttled_frame_rate" : "layout.frame_rate";
      91               0 :   PRInt32 rate = Preferences::GetInt(prefName, -1);
      92               0 :   if (rate <= 0) {
      93                 :     // TODO: get the rate from the platform
      94               0 :     rate = mThrottled ? DEFAULT_THROTTLED_FRAME_RATE : DEFAULT_FRAME_RATE;
      95                 :   }
      96               0 :   NS_ASSERTION(rate > 0, "Must have positive rate here");
      97               0 :   PRInt32 interval = NSToIntRound(1000.0/rate);
      98               0 :   if (mThrottled) {
      99               0 :     interval = NS_MAX(interval, mLastTimerInterval * 2);
     100                 :   }
     101               0 :   mLastTimerInterval = interval;
     102               0 :   return interval;
     103                 : }
     104                 : 
     105                 : PRInt32
     106               0 : nsRefreshDriver::GetRefreshTimerType() const
     107                 : {
     108               0 :   if (mThrottled) {
     109               0 :     return nsITimer::TYPE_ONE_SHOT;
     110                 :   }
     111               0 :   if (HaveFrameRequestCallbacks() || sPrecisePref) {
     112               0 :     return nsITimer::TYPE_REPEATING_PRECISE_CAN_SKIP;
     113                 :   }
     114               0 :   return nsITimer::TYPE_REPEATING_SLACK;
     115                 : }
     116                 : 
     117               0 : nsRefreshDriver::nsRefreshDriver(nsPresContext *aPresContext)
     118                 :   : mPresContext(aPresContext),
     119                 :     mFrozen(false),
     120                 :     mThrottled(false),
     121                 :     mTestControllingRefreshes(false),
     122                 :     mTimerIsPrecise(false),
     123                 :     mViewManagerFlushIsPending(false),
     124               0 :     mLastTimerInterval(0)
     125                 : {
     126               0 :   mRequests.Init();
     127               0 : }
     128                 : 
     129               0 : nsRefreshDriver::~nsRefreshDriver()
     130                 : {
     131               0 :   NS_ABORT_IF_FALSE(ObserverCount() == 0,
     132                 :                     "observers should have unregistered");
     133               0 :   NS_ABORT_IF_FALSE(!mTimer, "timer should be gone");
     134               0 : }
     135                 : 
     136                 : // Method for testing.  See nsIDOMWindowUtils.advanceTimeAndRefresh
     137                 : // for description.
     138                 : void
     139               0 : nsRefreshDriver::AdvanceTimeAndRefresh(PRInt64 aMilliseconds)
     140                 : {
     141               0 :   mTestControllingRefreshes = true;
     142               0 :   mMostRecentRefreshEpochTime += aMilliseconds * 1000;
     143               0 :   mMostRecentRefresh += TimeDuration::FromMilliseconds(aMilliseconds);
     144               0 :   nsCxPusher pusher;
     145               0 :   if (pusher.PushNull()) {
     146               0 :     Notify(nsnull);
     147               0 :     pusher.Pop();
     148                 :   }
     149               0 : }
     150                 : 
     151                 : void
     152               0 : nsRefreshDriver::RestoreNormalRefresh()
     153                 : {
     154               0 :   mTestControllingRefreshes = false;
     155               0 :   nsCxPusher pusher;
     156               0 :   if (pusher.PushNull()) {
     157               0 :     Notify(nsnull); // will call UpdateMostRecentRefresh()
     158               0 :     pusher.Pop();
     159                 :   }
     160               0 : }
     161                 : 
     162                 : TimeStamp
     163               0 : nsRefreshDriver::MostRecentRefresh() const
     164                 : {
     165               0 :   const_cast<nsRefreshDriver*>(this)->EnsureTimerStarted(false);
     166                 : 
     167               0 :   return mMostRecentRefresh;
     168                 : }
     169                 : 
     170                 : PRInt64
     171               0 : nsRefreshDriver::MostRecentRefreshEpochTime() const
     172                 : {
     173               0 :   const_cast<nsRefreshDriver*>(this)->EnsureTimerStarted(false);
     174                 : 
     175               0 :   return mMostRecentRefreshEpochTime;
     176                 : }
     177                 : 
     178                 : bool
     179               0 : nsRefreshDriver::AddRefreshObserver(nsARefreshObserver *aObserver,
     180                 :                                     mozFlushType aFlushType)
     181                 : {
     182               0 :   ObserverArray& array = ArrayFor(aFlushType);
     183               0 :   bool success = array.AppendElement(aObserver) != nsnull;
     184                 : 
     185               0 :   EnsureTimerStarted(false);
     186                 : 
     187               0 :   return success;
     188                 : }
     189                 : 
     190                 : bool
     191               0 : nsRefreshDriver::RemoveRefreshObserver(nsARefreshObserver *aObserver,
     192                 :                                        mozFlushType aFlushType)
     193                 : {
     194               0 :   ObserverArray& array = ArrayFor(aFlushType);
     195               0 :   return array.RemoveElement(aObserver);
     196                 : }
     197                 : 
     198                 : bool
     199               0 : nsRefreshDriver::AddImageRequest(imgIRequest* aRequest)
     200                 : {
     201               0 :   if (!mRequests.PutEntry(aRequest)) {
     202               0 :     return false;
     203                 :   }
     204                 : 
     205               0 :   EnsureTimerStarted(false);
     206                 : 
     207               0 :   return true;
     208                 : }
     209                 : 
     210                 : void
     211               0 : nsRefreshDriver::RemoveImageRequest(imgIRequest* aRequest)
     212                 : {
     213               0 :   mRequests.RemoveEntry(aRequest);
     214               0 : }
     215                 : 
     216               0 : void nsRefreshDriver::ClearAllImageRequests()
     217                 : {
     218               0 :   mRequests.Clear();
     219               0 : }
     220                 : 
     221                 : void
     222               0 : nsRefreshDriver::EnsureTimerStarted(bool aAdjustingTimer)
     223                 : {
     224               0 :   if (mTimer || mFrozen || !mPresContext) {
     225                 :     // It's already been started, or we don't want to start it now or
     226                 :     // we've been disconnected.
     227               0 :     return;
     228                 :   }
     229                 : 
     230               0 :   if (!aAdjustingTimer) {
     231                 :     // If we didn't already have a timer and aAdjustingTimer is false,
     232                 :     // then we just got our first observer (or an explicit call to
     233                 :     // MostRecentRefresh by a caller who's likely to add an observer
     234                 :     // shortly).  This means we should fake a most-recent-refresh time
     235                 :     // of now so that said observer gets a reasonable refresh time, so
     236                 :     // things behave as though the timer had always been running.
     237               0 :     UpdateMostRecentRefresh();
     238                 :   }
     239                 : 
     240               0 :   mTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
     241               0 :   if (!mTimer) {
     242               0 :     return;
     243                 :   }
     244                 : 
     245               0 :   PRInt32 timerType = GetRefreshTimerType();
     246               0 :   mTimerIsPrecise = (timerType == nsITimer::TYPE_REPEATING_PRECISE_CAN_SKIP);
     247                 : 
     248               0 :   nsresult rv = mTimer->InitWithCallback(this,
     249               0 :                                          GetRefreshTimerInterval(),
     250               0 :                                          timerType);
     251               0 :   if (NS_FAILED(rv)) {
     252               0 :     mTimer = nsnull;
     253                 :   }
     254                 : }
     255                 : 
     256                 : void
     257               0 : nsRefreshDriver::StopTimer()
     258                 : {
     259               0 :   if (!mTimer) {
     260               0 :     return;
     261                 :   }
     262                 : 
     263               0 :   mTimer->Cancel();
     264               0 :   mTimer = nsnull;
     265                 : }
     266                 : 
     267                 : PRUint32
     268               0 : nsRefreshDriver::ObserverCount() const
     269                 : {
     270               0 :   PRUint32 sum = 0;
     271               0 :   for (PRUint32 i = 0; i < ArrayLength(mObservers); ++i) {
     272               0 :     sum += mObservers[i].Length();
     273                 :   }
     274                 : 
     275                 :   // Even while throttled, we need to process layout and style changes.  Style
     276                 :   // changes can trigger transitions which fire events when they complete, and
     277                 :   // layout changes can affect media queries on child documents, triggering
     278                 :   // style changes, etc.
     279               0 :   sum += mStyleFlushObservers.Length();
     280               0 :   sum += mLayoutFlushObservers.Length();
     281               0 :   sum += mFrameRequestCallbackDocs.Length();
     282               0 :   sum += mViewManagerFlushIsPending;
     283               0 :   return sum;
     284                 : }
     285                 : 
     286                 : PRUint32
     287               0 : nsRefreshDriver::ImageRequestCount() const
     288                 : {
     289               0 :   return mRequests.Count();
     290                 : }
     291                 : 
     292                 : void
     293               0 : nsRefreshDriver::UpdateMostRecentRefresh()
     294                 : {
     295               0 :   if (mTestControllingRefreshes) {
     296               0 :     return;
     297                 :   }
     298                 : 
     299                 :   // Call JS_Now first, since that can have nonzero latency in some rare cases.
     300               0 :   mMostRecentRefreshEpochTime = JS_Now();
     301               0 :   mMostRecentRefresh = TimeStamp::Now();
     302                 : }
     303                 : 
     304                 : nsRefreshDriver::ObserverArray&
     305               0 : nsRefreshDriver::ArrayFor(mozFlushType aFlushType)
     306                 : {
     307               0 :   switch (aFlushType) {
     308                 :     case Flush_Style:
     309               0 :       return mObservers[0];
     310                 :     case Flush_Layout:
     311               0 :       return mObservers[1];
     312                 :     case Flush_Display:
     313               0 :       return mObservers[2];
     314                 :     default:
     315               0 :       NS_ABORT_IF_FALSE(false, "bad flush type");
     316               0 :       return *static_cast<ObserverArray*>(nsnull);
     317                 :   }
     318                 : }
     319                 : 
     320                 : /*
     321                 :  * nsISupports implementation
     322                 :  */
     323                 : 
     324               0 : NS_IMPL_ISUPPORTS1(nsRefreshDriver, nsITimerCallback)
     325                 : 
     326                 : /*
     327                 :  * nsITimerCallback implementation
     328                 :  */
     329                 : 
     330                 : NS_IMETHODIMP
     331               0 : nsRefreshDriver::Notify(nsITimer *aTimer)
     332                 : {
     333               0 :   NS_PRECONDITION(!mFrozen, "Why are we notified while frozen?");
     334               0 :   NS_PRECONDITION(mPresContext, "Why are we notified after disconnection?");
     335               0 :   NS_PRECONDITION(!nsContentUtils::GetCurrentJSContext(),
     336                 :                   "Shouldn't have a JSContext on the stack");
     337                 : 
     338               0 :   if (mTestControllingRefreshes && aTimer) {
     339                 :     // Ignore real refreshes from our timer (but honor the others).
     340               0 :     return NS_OK;
     341                 :   }
     342                 : 
     343               0 :   UpdateMostRecentRefresh();
     344                 : 
     345               0 :   nsCOMPtr<nsIPresShell> presShell = mPresContext->GetPresShell();
     346               0 :   if (!presShell || (ObserverCount() == 0 && ImageRequestCount() == 0)) {
     347                 :     // Things are being destroyed, or we no longer have any observers.
     348                 :     // We don't want to stop the timer when observers are initially
     349                 :     // removed, because sometimes observers can be added and removed
     350                 :     // often depending on what other things are going on and in that
     351                 :     // situation we don't want to thrash our timer.  So instead we
     352                 :     // wait until we get a Notify() call when we have no observers
     353                 :     // before stopping the timer.
     354               0 :     StopTimer();
     355               0 :     return NS_OK;
     356                 :   }
     357                 : 
     358                 :   /*
     359                 :    * The timer holds a reference to |this| while calling |Notify|.
     360                 :    * However, implementations of |WillRefresh| are permitted to destroy
     361                 :    * the pres context, which will cause our |mPresContext| to become
     362                 :    * null.  If this happens, we must stop notifying observers.
     363                 :    */
     364               0 :   for (PRUint32 i = 0; i < ArrayLength(mObservers); ++i) {
     365               0 :     ObserverArray::EndLimitedIterator etor(mObservers[i]);
     366               0 :     while (etor.HasMore()) {
     367               0 :       nsRefPtr<nsARefreshObserver> obs = etor.GetNext();
     368               0 :       obs->WillRefresh(mMostRecentRefresh);
     369                 :       
     370               0 :       if (!mPresContext || !mPresContext->GetPresShell()) {
     371               0 :         StopTimer();
     372               0 :         return NS_OK;
     373                 :       }
     374                 :     }
     375                 : 
     376               0 :     if (i == 0) {
     377                 :       // Grab all of our frame request callbacks up front.
     378               0 :       nsIDocument::FrameRequestCallbackList frameRequestCallbacks;
     379               0 :       for (PRUint32 i = 0; i < mFrameRequestCallbackDocs.Length(); ++i) {
     380               0 :         mFrameRequestCallbackDocs[i]->
     381               0 :           TakeFrameRequestCallbacks(frameRequestCallbacks);
     382                 :       }
     383                 :       // OK, now reset mFrameRequestCallbackDocs so they can be
     384                 :       // readded as needed.
     385               0 :       mFrameRequestCallbackDocs.Clear();
     386                 : 
     387               0 :       PRInt64 eventTime = mMostRecentRefreshEpochTime / PR_USEC_PER_MSEC;
     388               0 :       for (PRUint32 i = 0; i < frameRequestCallbacks.Length(); ++i) {
     389               0 :         frameRequestCallbacks[i]->Sample(eventTime);
     390                 :       }
     391                 : 
     392                 :       // This is the Flush_Style case.
     393               0 :       if (mPresContext && mPresContext->GetPresShell()) {
     394               0 :         nsAutoTArray<nsIPresShell*, 16> observers;
     395               0 :         observers.AppendElements(mStyleFlushObservers);
     396               0 :         for (PRUint32 j = observers.Length();
     397               0 :              j && mPresContext && mPresContext->GetPresShell(); --j) {
     398                 :           // Make sure to not process observers which might have been removed
     399                 :           // during previous iterations.
     400               0 :           nsIPresShell* shell = observers[j - 1];
     401               0 :           if (!mStyleFlushObservers.Contains(shell))
     402               0 :             continue;
     403               0 :           NS_ADDREF(shell);
     404               0 :           mStyleFlushObservers.RemoveElement(shell);
     405               0 :           shell->FrameConstructor()->mObservingRefreshDriver = false;
     406               0 :           shell->FlushPendingNotifications(Flush_Style);
     407               0 :           NS_RELEASE(shell);
     408                 :         }
     409                 :       }
     410               0 :     } else if  (i == 1) {
     411                 :       // This is the Flush_Layout case.
     412               0 :       if (mPresContext && mPresContext->GetPresShell()) {
     413               0 :         nsAutoTArray<nsIPresShell*, 16> observers;
     414               0 :         observers.AppendElements(mLayoutFlushObservers);
     415               0 :         for (PRUint32 j = observers.Length();
     416               0 :              j && mPresContext && mPresContext->GetPresShell(); --j) {
     417                 :           // Make sure to not process observers which might have been removed
     418                 :           // during previous iterations.
     419               0 :           nsIPresShell* shell = observers[j - 1];
     420               0 :           if (!mLayoutFlushObservers.Contains(shell))
     421               0 :             continue;
     422               0 :           NS_ADDREF(shell);
     423               0 :           mLayoutFlushObservers.RemoveElement(shell);
     424               0 :           shell->mReflowScheduled = false;
     425               0 :           shell->mSuppressInterruptibleReflows = false;
     426               0 :           shell->FlushPendingNotifications(Flush_InterruptibleLayout);
     427               0 :           NS_RELEASE(shell);
     428                 :         }
     429                 :       }
     430                 :     }
     431                 :   }
     432                 : 
     433                 :   /*
     434                 :    * Perform notification to imgIRequests subscribed to listen
     435                 :    * for refresh events.
     436                 :    */
     437                 : 
     438               0 :   ImageRequestParameters parms = {mMostRecentRefresh};
     439               0 :   if (mRequests.Count()) {
     440               0 :     mRequests.EnumerateEntries(nsRefreshDriver::ImageRequestEnumerator, &parms);
     441               0 :     EnsureTimerStarted(false);
     442                 :   }
     443                 : 
     444               0 :   if (mViewManagerFlushIsPending) {
     445               0 :     mViewManagerFlushIsPending = false;
     446               0 :     mPresContext->GetPresShell()->GetViewManager()->ProcessPendingUpdates();
     447                 :   }
     448                 : 
     449               0 :   if (mThrottled ||
     450                 :       (mTimerIsPrecise !=
     451               0 :        (GetRefreshTimerType() == nsITimer::TYPE_REPEATING_PRECISE_CAN_SKIP))) {
     452                 :     // Stop the timer now and restart it here.  Stopping is in the mThrottled
     453                 :     // case ok because either it's already one-shot, and it just fired, and all
     454                 :     // we need to do is null it out, or it's repeating and we need to reset it
     455                 :     // to be one-shot.  Stopping and restarting in the case when we need to
     456                 :     // switch from precise to slack timers or vice versa is unfortunately
     457                 :     // required.
     458                 : 
     459                 :     // Note that the EnsureTimerStarted() call here is ok because
     460                 :     // EnsureTimerStarted makes sure to not start the timer if it shouldn't be
     461                 :     // started.
     462               0 :     StopTimer();
     463               0 :     EnsureTimerStarted(true);
     464                 :   }
     465                 : 
     466               0 :   return NS_OK;
     467                 : }
     468                 : 
     469                 : PLDHashOperator
     470               0 : nsRefreshDriver::ImageRequestEnumerator(nsISupportsHashKey* aEntry,
     471                 :                                         void* aUserArg)
     472                 : {
     473                 :   ImageRequestParameters* parms =
     474               0 :     static_cast<ImageRequestParameters*> (aUserArg);
     475               0 :   mozilla::TimeStamp mostRecentRefresh = parms->ts;
     476               0 :   imgIRequest* req = static_cast<imgIRequest*>(aEntry->GetKey());
     477               0 :   NS_ABORT_IF_FALSE(req, "Unable to retrieve the image request");
     478               0 :   nsCOMPtr<imgIContainer> image;
     479               0 :   req->GetImage(getter_AddRefs(image));
     480               0 :   if (image) {
     481               0 :     image->RequestRefresh(mostRecentRefresh);
     482                 :   }
     483                 : 
     484               0 :   return PL_DHASH_NEXT;
     485                 : }
     486                 : 
     487                 : void
     488               0 : nsRefreshDriver::Freeze()
     489                 : {
     490               0 :   NS_ASSERTION(!mFrozen, "Freeze called on already-frozen refresh driver");
     491               0 :   StopTimer();
     492               0 :   mFrozen = true;
     493               0 : }
     494                 : 
     495                 : void
     496               0 : nsRefreshDriver::Thaw()
     497                 : {
     498               0 :   NS_ASSERTION(mFrozen, "Thaw called on an unfrozen refresh driver");
     499               0 :   mFrozen = false;
     500               0 :   if (ObserverCount() || ImageRequestCount()) {
     501                 :     // FIXME: This isn't quite right, since our EnsureTimerStarted call
     502                 :     // updates our mMostRecentRefresh, but the DoRefresh call won't run
     503                 :     // and notify our observers until we get back to the event loop.
     504                 :     // Thus MostRecentRefresh() will lie between now and the DoRefresh.
     505               0 :     NS_DispatchToCurrentThread(NS_NewRunnableMethod(this, &nsRefreshDriver::DoRefresh));
     506               0 :     EnsureTimerStarted(false);
     507                 :   }
     508               0 : }
     509                 : 
     510                 : void
     511               0 : nsRefreshDriver::SetThrottled(bool aThrottled)
     512                 : {
     513               0 :   if (aThrottled != mThrottled) {
     514               0 :     mThrottled = aThrottled;
     515               0 :     if (mTimer) {
     516                 :       // We want to switch our timer type here, so just stop and
     517                 :       // restart the timer.
     518               0 :       StopTimer();
     519               0 :       EnsureTimerStarted(true);
     520                 :     }
     521                 :   }
     522               0 : }
     523                 : 
     524                 : void
     525               0 : nsRefreshDriver::DoRefresh()
     526                 : {
     527                 :   // Don't do a refresh unless we're in a state where we should be refreshing.
     528               0 :   if (!mFrozen && mPresContext && mTimer) {
     529               0 :     Notify(nsnull);
     530                 :   }
     531               0 : }
     532                 : 
     533                 : #ifdef DEBUG
     534                 : bool
     535               0 : nsRefreshDriver::IsRefreshObserver(nsARefreshObserver *aObserver,
     536                 :                                    mozFlushType aFlushType)
     537                 : {
     538               0 :   ObserverArray& array = ArrayFor(aFlushType);
     539               0 :   return array.Contains(aObserver);
     540                 : }
     541                 : #endif
     542                 : 
     543                 : void
     544               0 : nsRefreshDriver::ScheduleFrameRequestCallbacks(nsIDocument* aDocument)
     545                 : {
     546               0 :   NS_ASSERTION(mFrameRequestCallbackDocs.IndexOf(aDocument) ==
     547                 :                mFrameRequestCallbackDocs.NoIndex,
     548                 :                "Don't schedule the same document multiple times");
     549               0 :   mFrameRequestCallbackDocs.AppendElement(aDocument);
     550                 :   // No need to worry about restarting our timer in precise mode if it's
     551                 :   // already running; that will happen automatically when it fires.
     552               0 :   EnsureTimerStarted(false);
     553               0 : }
     554                 : 
     555                 : void
     556               0 : nsRefreshDriver::RevokeFrameRequestCallbacks(nsIDocument* aDocument)
     557                 : {
     558               0 :   mFrameRequestCallbackDocs.RemoveElement(aDocument);
     559                 :   // No need to worry about restarting our timer in slack mode if it's already
     560                 :   // running; that will happen automatically when it fires.
     561               0 : }

Generated by: LCOV version 1.7