1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #include "InputEventStatistics.h"
8 
9 #include "nsRefreshDriver.h"
10 
11 namespace mozilla {
12 
Get()13 /*static*/ InputEventStatistics& InputEventStatistics::Get() {
14   static UniquePtr<InputEventStatistics> sInstance;
15   if (!sInstance) {
16     sInstance = MakeUnique<InputEventStatistics>(ConstructorCookie());
17     ClearOnShutdown(&sInstance);
18   }
19   return *sInstance;
20 }
21 
GetMean()22 TimeDuration InputEventStatistics::TimeDurationCircularBuffer::GetMean() {
23   return mTotal / (int64_t)mSize;
24 }
25 
InputEventStatistics(ConstructorCookie &&)26 InputEventStatistics::InputEventStatistics(ConstructorCookie&&)
27     : mEnable(false) {
28   MOZ_ASSERT(Preferences::IsServiceAvailable());
29   uint32_t inputDuration = Preferences::GetUint(
30       "input_event_queue.default_duration_per_event", sDefaultInputDuration);
31 
32   TimeDuration defaultDuration = TimeDuration::FromMilliseconds(inputDuration);
33 
34   uint32_t count = Preferences::GetUint(
35       "input_event_queue.count_for_prediction", sInputCountForPrediction);
36 
37   mLastInputDurations =
38       MakeUnique<TimeDurationCircularBuffer>(count, defaultDuration);
39 
40   uint32_t maxDuration = Preferences::GetUint("input_event_queue.duration.max",
41                                               sMaxReservedTimeForHandlingInput);
42 
43   uint32_t minDuration = Preferences::GetUint("input_event_queue.duration.min",
44                                               sMinReservedTimeForHandlingInput);
45 
46   mMaxInputDuration = TimeDuration::FromMilliseconds(maxDuration);
47   mMinInputDuration = TimeDuration::FromMilliseconds(minDuration);
48 }
49 
GetInputHandlingStartTime(uint32_t aInputCount)50 TimeStamp InputEventStatistics::GetInputHandlingStartTime(
51     uint32_t aInputCount) {
52   MOZ_ASSERT(mEnable);
53   Maybe<TimeStamp> nextTickHint = nsRefreshDriver::GetNextTickHint();
54 
55   if (nextTickHint.isNothing()) {
56     // Return a past time to process input events immediately.
57     return TimeStamp::Now() - TimeDuration::FromMilliseconds(1);
58   }
59   TimeDuration inputCost = mLastInputDurations->GetMean() * aInputCount;
60   inputCost =
61       inputCost > mMaxInputDuration
62           ? mMaxInputDuration
63           : inputCost < mMinInputDuration ? mMinInputDuration : inputCost;
64 
65   return nextTickHint.value() - inputCost;
66 }
67 
68 }  // namespace mozilla
69