Bug 1615858 - Add MultiTouchInput::SingleTouchData::mHistoricalData. r=kats
authorMarkus Stange <mstange.moz@gmail.com>
Tue, 03 Nov 2020 16:46:19 +0000
changeset 555691 4c5fdaab5f27e72bfddeba2d17d62589c6cd92b3
parent 555690 e4aeb40526cc5ba0717a0c1e835e1f88fe5d8a01
child 555692 b4f668a31f18226c7183d538d55da73a8c56e55b
push id130102
push usermstange@themasta.com
push dateTue, 03 Nov 2020 20:46:18 +0000
treeherderautoland@bf8313268c20 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs1615858
milestone84.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1615858 - Add MultiTouchInput::SingleTouchData::mHistoricalData. r=kats Differential Revision: https://phabricator.services.mozilla.com/D95649
widget/InputData.cpp
widget/InputData.h
widget/nsGUIEventIPC.h
--- a/widget/InputData.cpp
+++ b/widget/InputData.cpp
@@ -141,18 +141,21 @@ MultiTouchInput::MultiTouchInput(const W
     mTouches.AppendElement(data);
   }
 }
 
 void MultiTouchInput::Translate(const ScreenPoint& aTranslation) {
   const int32_t xTranslation = (int32_t)(aTranslation.x + 0.5f);
   const int32_t yTranslation = (int32_t)(aTranslation.y + 0.5f);
 
-  for (auto iter = mTouches.begin(); iter != mTouches.end(); iter++) {
-    iter->mScreenPoint.MoveBy(xTranslation, yTranslation);
+  for (auto& touchData : mTouches) {
+    for (auto& historicalData : touchData.mHistoricalData) {
+      historicalData.mScreenPoint.MoveBy(xTranslation, yTranslation);
+    }
+    touchData.mScreenPoint.MoveBy(xTranslation, yTranslation);
   }
 }
 
 WidgetTouchEvent MultiTouchInput::ToWidgetTouchEvent(nsIWidget* aWidget) const {
   MOZ_ASSERT(NS_IsMainThread(),
              "Can only convert To WidgetTouchEvent on main thread");
 
   EventMessage touchEventMessage = eVoidEvent;
@@ -200,23 +203,31 @@ int32_t MultiTouchInput::IndexOfTouch(in
       return (int32_t)i;
     }
   }
   return -1;
 }
 
 bool MultiTouchInput::TransformToLocal(
     const ScreenToParentLayerMatrix4x4& aTransform) {
-  for (size_t i = 0; i < mTouches.Length(); i++) {
+  for (auto& touchData : mTouches) {
+    for (auto& historicalData : touchData.mHistoricalData) {
+      Maybe<ParentLayerIntPoint> historicalPoint =
+          UntransformBy(aTransform, historicalData.mScreenPoint);
+      if (!historicalPoint) {
+        return false;
+      }
+      historicalData.mLocalScreenPoint = *historicalPoint;
+    }
     Maybe<ParentLayerIntPoint> point =
-        UntransformBy(aTransform, mTouches[i].mScreenPoint);
+        UntransformBy(aTransform, touchData.mScreenPoint);
     if (!point) {
       return false;
     }
-    mTouches[i].mLocalScreenPoint = *point;
+    touchData.mLocalScreenPoint = *point;
   }
   return true;
 }
 
 MouseInput::MouseInput()
     : InputData(MOUSE_INPUT),
       mType(MOUSE_NONE),
       mButtonType(NONE),
--- a/widget/InputData.h
+++ b/widget/InputData.h
@@ -144,16 +144,38 @@ class SingleTouchData {
 
   SingleTouchData();
 
   already_AddRefed<dom::Touch> ToNewDOMTouch() const;
 
   // Warning, this class is serialized and sent over IPC. Any change to its
   // fields must be reflected in its ParamTraits<>, in nsGUIEventIPC.h
 
+  // Historical data of this touch, which  was coalesced into this event.
+  // Touch event coalescing can happen at the system level when the touch
+  // screen's sampling frequency is higher than the vsync rate, or when the
+  // UI thread is busy. When multiple "samples" of touch data are coalesced into
+  // one touch event, the touch event's regular position information is the
+  // information from the last sample. And the previous, "coalesced-away"
+  // samples are stored in mHistoricalData.
+
+  struct HistoricalTouchData {
+    // The timestamp at which the information in this "sample" was originally
+    // sampled.
+    TimeStamp mTimeStamp;
+
+    // The touch data of this historical sample.
+    ScreenIntPoint mScreenPoint;
+    ParentLayerPoint mLocalScreenPoint;
+    ScreenSize mRadius;
+    float mRotationAngle = 0.0f;
+    float mForce = 0.0f;
+  };
+  CopyableTArray<HistoricalTouchData> mHistoricalData;
+
   // A unique number assigned to each SingleTouchData within a MultiTouchInput
   // so that they can be easily distinguished when handling a touch
   // start/move/end.
   int32_t mIdentifier;
 
   // Point on the screen that the touch hit, in device pixels. They are
   // coordinates on the screen.
   ScreenIntPoint mScreenPoint;
--- a/widget/nsGUIEventIPC.h
+++ b/widget/nsGUIEventIPC.h
@@ -1120,31 +1120,57 @@ struct ParamTraits<mozilla::InputData> {
            ReadParam(aMsg, aIter, &aResult->mTimeStamp) &&
            ReadParam(aMsg, aIter, &aResult->modifiers) &&
            ReadParam(aMsg, aIter, &aResult->mFocusSequenceNumber) &&
            ReadParam(aMsg, aIter, &aResult->mLayersId);
   }
 };
 
 template <>
+struct ParamTraits<mozilla::SingleTouchData::HistoricalTouchData> {
+  typedef mozilla::SingleTouchData::HistoricalTouchData paramType;
+
+  static void Write(Message* aMsg, const paramType& aParam) {
+    WriteParam(aMsg, aParam.mTimeStamp);
+    WriteParam(aMsg, aParam.mScreenPoint);
+    WriteParam(aMsg, aParam.mLocalScreenPoint);
+    WriteParam(aMsg, aParam.mRadius);
+    WriteParam(aMsg, aParam.mRotationAngle);
+    WriteParam(aMsg, aParam.mForce);
+  }
+
+  static bool Read(const Message* aMsg, PickleIterator* aIter,
+                   paramType* aResult) {
+    return (ReadParam(aMsg, aIter, &aResult->mTimeStamp) &&
+            ReadParam(aMsg, aIter, &aResult->mScreenPoint) &&
+            ReadParam(aMsg, aIter, &aResult->mLocalScreenPoint) &&
+            ReadParam(aMsg, aIter, &aResult->mRadius) &&
+            ReadParam(aMsg, aIter, &aResult->mRotationAngle) &&
+            ReadParam(aMsg, aIter, &aResult->mForce));
+  }
+};
+
+template <>
 struct ParamTraits<mozilla::SingleTouchData> {
   typedef mozilla::SingleTouchData paramType;
 
   static void Write(Message* aMsg, const paramType& aParam) {
+    WriteParam(aMsg, aParam.mHistoricalData);
     WriteParam(aMsg, aParam.mIdentifier);
     WriteParam(aMsg, aParam.mScreenPoint);
     WriteParam(aMsg, aParam.mLocalScreenPoint);
     WriteParam(aMsg, aParam.mRadius);
     WriteParam(aMsg, aParam.mRotationAngle);
     WriteParam(aMsg, aParam.mForce);
   }
 
   static bool Read(const Message* aMsg, PickleIterator* aIter,
                    paramType* aResult) {
-    return (ReadParam(aMsg, aIter, &aResult->mIdentifier) &&
+    return (ReadParam(aMsg, aIter, &aResult->mHistoricalData) &&
+            ReadParam(aMsg, aIter, &aResult->mIdentifier) &&
             ReadParam(aMsg, aIter, &aResult->mScreenPoint) &&
             ReadParam(aMsg, aIter, &aResult->mLocalScreenPoint) &&
             ReadParam(aMsg, aIter, &aResult->mRadius) &&
             ReadParam(aMsg, aIter, &aResult->mRotationAngle) &&
             ReadParam(aMsg, aIter, &aResult->mForce));
   }
 };