1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/apz/src/TaskThrottler.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,101 @@ 1.4 +/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 2; -*- */ 1.5 +/* vim: set sw=4 ts=8 et tw=80 : */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifndef mozilla_dom_TaskThrottler_h 1.11 +#define mozilla_dom_TaskThrottler_h 1.12 + 1.13 +#include <stdint.h> // for uint32_t 1.14 +#include "base/task.h" // for CancelableTask 1.15 +#include "mozilla/TimeStamp.h" // for TimeDuration, TimeStamp 1.16 +#include "mozilla/RollingMean.h" // for RollingMean 1.17 +#include "mozilla/mozalloc.h" // for operator delete 1.18 +#include "nsAutoPtr.h" // for nsAutoPtr 1.19 +#include "nsTArray.h" // for nsTArray 1.20 + 1.21 +namespace tracked_objects { 1.22 +class Location; 1.23 +} 1.24 + 1.25 +namespace mozilla { 1.26 +namespace layers { 1.27 + 1.28 +/** The TaskThrottler prevents update event overruns. It is used in cases where 1.29 + * you're sending an async message and waiting for a reply. You need to call 1.30 + * PostTask to queue a task and TaskComplete when you get a response. 1.31 + * 1.32 + * The call to TaskComplete will run the recent task posted since the last 1.33 + * request was sent, if any. This means that at any time there can be at most 1 1.34 + * outstanding request being processed and at most 1 queued behind it. 1.35 + * 1.36 + * This is used in the context of repainting a scrollable region. While another 1.37 + * process is painting you might get several updates from the UI thread but when 1.38 + * the paint is complete you want to send the most recent. 1.39 + */ 1.40 + 1.41 +class TaskThrottler { 1.42 +public: 1.43 + TaskThrottler(const TimeStamp& aTimeStamp); 1.44 + 1.45 + /** Post a task to be run as soon as there are no outstanding tasks. 1.46 + * 1.47 + * @param aLocation Use the macro FROM_HERE 1.48 + * @param aTask Ownership of this object is transferred to TaskThrottler 1.49 + * which will delete it when it is either run or becomes 1.50 + * obsolete or the TaskThrottler is destructed. 1.51 + */ 1.52 + void PostTask(const tracked_objects::Location& aLocation, 1.53 + CancelableTask* aTask, const TimeStamp& aTimeStamp); 1.54 + /** 1.55 + * Mark the task as complete and process the next queued task. 1.56 + */ 1.57 + void TaskComplete(const TimeStamp& aTimeStamp); 1.58 + 1.59 + /** 1.60 + * Calculate the average time between processing the posted task and getting 1.61 + * the TaskComplete() call back. 1.62 + */ 1.63 + TimeDuration AverageDuration() 1.64 + { 1.65 + return mMean.empty() ? TimeDuration() : mMean.mean(); 1.66 + } 1.67 + 1.68 + /** 1.69 + * return true if Throttler has an outstanding task 1.70 + */ 1.71 + bool IsOutstanding() { return mOutstanding; } 1.72 + 1.73 + /** 1.74 + * Return the time elapsed since the last request was processed 1.75 + */ 1.76 + TimeDuration TimeSinceLastRequest(const TimeStamp& aTimeStamp); 1.77 + 1.78 + /** 1.79 + * Clear average history. 1.80 + */ 1.81 + void ClearHistory() { mMean.clear(); } 1.82 + 1.83 + /** 1.84 + * @param aMaxDurations The maximum number of durations to measure. 1.85 + */ 1.86 + 1.87 + void SetMaxDurations(uint32_t aMaxDurations) 1.88 + { 1.89 + if (aMaxDurations != mMean.maxValues()) { 1.90 + mMean = RollingMean<TimeDuration, TimeDuration>(aMaxDurations); 1.91 + } 1.92 + } 1.93 + 1.94 +private: 1.95 + bool mOutstanding; 1.96 + nsAutoPtr<CancelableTask> mQueuedTask; 1.97 + TimeStamp mStartTime; 1.98 + RollingMean<TimeDuration, TimeDuration> mMean; 1.99 +}; 1.100 + 1.101 +} 1.102 +} 1.103 + 1.104 +#endif // mozilla_dom_TaskThrottler_h