зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1094525 - Simplify touch resampling code in GeckoTouchDispatcher, r=kats
This commit is contained in:
Родитель
083547dbdc
Коммит
23699318aa
|
@ -47,7 +47,6 @@ namespace mozilla {
|
|||
|
||||
// Amount of time in MS before an input is considered expired.
|
||||
static const uint64_t kInputExpirationThresholdMs = 1000;
|
||||
static int32_t microsecToMillisec(int64_t microsec) { return microsec / 1000; }
|
||||
|
||||
static StaticRefPtr<GeckoTouchDispatcher> sTouchDispatcher;
|
||||
|
||||
|
@ -207,9 +206,9 @@ GeckoTouchDispatcher::DispatchTouchMoveEvents(TimeStamp aVsyncTime)
|
|||
}
|
||||
|
||||
static int
|
||||
Interpolate(int start, int end, int64_t aFrameDiff, int64_t aTouchDiff)
|
||||
Interpolate(int start, int end, TimeDuration aFrameDiff, TimeDuration aTouchDiff)
|
||||
{
|
||||
return start + (((end - start) * aFrameDiff) / aTouchDiff);
|
||||
return start + (((end - start) * aFrameDiff.ToMicroseconds()) / aTouchDiff.ToMicroseconds());
|
||||
}
|
||||
|
||||
static const SingleTouchData&
|
||||
|
@ -230,115 +229,96 @@ GetTouchByID(const SingleTouchData& aCurrentTouch, MultiTouchInput& aOtherTouch)
|
|||
return aCurrentTouch;
|
||||
}
|
||||
|
||||
|
||||
// aTouchDiff is the duration between the base and current touch times
|
||||
// aFrameDiff is the duration between the base and the time we're resampling to
|
||||
static void
|
||||
ResampleTouch(MultiTouchInput& aOutTouch, MultiTouchInput& aCurrent,
|
||||
MultiTouchInput& aOther, int64_t aFrameDiff,
|
||||
int64_t aTouchDiff, bool aInterpolate)
|
||||
ResampleTouch(MultiTouchInput& aOutTouch,
|
||||
MultiTouchInput& aBase, MultiTouchInput& aCurrent,
|
||||
TimeDuration aFrameDiff, TimeDuration aTouchDiff)
|
||||
{
|
||||
aOutTouch = aCurrent;
|
||||
|
||||
// Make sure we only resample the correct finger.
|
||||
for (size_t i = 0; i < aOutTouch.mTouches.Length(); i++) {
|
||||
const SingleTouchData& current = aCurrent.mTouches[i];
|
||||
const SingleTouchData& other = GetTouchByID(current, aOther);
|
||||
const SingleTouchData& base = aBase.mTouches[i];
|
||||
const SingleTouchData& current = GetTouchByID(base, aCurrent);
|
||||
|
||||
const ScreenIntPoint& baseTouchPoint = base.mScreenPoint;
|
||||
const ScreenIntPoint& currentTouchPoint = current.mScreenPoint;
|
||||
const ScreenIntPoint& otherTouchPoint = other.mScreenPoint;
|
||||
|
||||
ScreenIntPoint newSamplePoint;
|
||||
newSamplePoint.x = Interpolate(currentTouchPoint.x, otherTouchPoint.x, aFrameDiff, aTouchDiff);
|
||||
newSamplePoint.y = Interpolate(currentTouchPoint.y, otherTouchPoint.y, aFrameDiff, aTouchDiff);
|
||||
newSamplePoint.x = Interpolate(baseTouchPoint.x, currentTouchPoint.x, aFrameDiff, aTouchDiff);
|
||||
newSamplePoint.y = Interpolate(baseTouchPoint.y, currentTouchPoint.y, aFrameDiff, aTouchDiff);
|
||||
|
||||
aOutTouch.mTouches[i].mScreenPoint = newSamplePoint;
|
||||
|
||||
#ifdef LOG_RESAMPLE_DATA
|
||||
const char* type = "extrapolate";
|
||||
if (aInterpolate) {
|
||||
if (aFrameDiff < aTouchDiff) {
|
||||
type = "interpolate";
|
||||
}
|
||||
|
||||
float alpha = (double) aFrameDiff / (double) aTouchDiff;
|
||||
LOG("%s current (%d, %d), other (%d, %d) to (%d, %d) alpha %f, touch diff %llu, frame diff %lld\n",
|
||||
float alpha = aFrameDiff / aTouchDiff;
|
||||
LOG("%s base (%d, %d), current (%d, %d) to (%d, %d) alpha %f, touch diff %d, frame diff %d\n",
|
||||
type,
|
||||
baseTouchPoint.x, baseTouchPoint.y,
|
||||
currentTouchPoint.x, currentTouchPoint.y,
|
||||
otherTouchPoint.x, otherTouchPoint.y,
|
||||
newSamplePoint.x, newSamplePoint.y,
|
||||
alpha, aTouchDiff, aFrameDiff);
|
||||
alpha, (int)aTouchDiff.ToMilliseconds(), (int)aFrameDiff.ToMilliseconds());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// Interpolates with the touch event prior to SampleTime
|
||||
// and with the future touch event past sample time
|
||||
int32_t
|
||||
GeckoTouchDispatcher::InterpolateTouch(MultiTouchInput& aOutTouch, TimeStamp aSampleTime)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(mTouchMoveEvents.size() >= 2);
|
||||
mTouchQueueLock.AssertCurrentThreadOwns();
|
||||
|
||||
// currentTouch < SampleTime < futureTouch
|
||||
MultiTouchInput futureTouch = mTouchMoveEvents.back();
|
||||
mTouchMoveEvents.pop_back();
|
||||
MultiTouchInput currentTouch = mTouchMoveEvents.back();
|
||||
|
||||
mTouchMoveEvents.clear();
|
||||
mTouchMoveEvents.push_back(futureTouch);
|
||||
|
||||
TimeStamp currentTouchTime = mLastTouchTime - mTouchTimeDiff;
|
||||
int64_t frameDiff = (aSampleTime - currentTouchTime).ToMicroseconds();
|
||||
ResampleTouch(aOutTouch, currentTouch, futureTouch, frameDiff, mTouchTimeDiff.ToMicroseconds(), true);
|
||||
|
||||
return microsecToMillisec(frameDiff);
|
||||
}
|
||||
|
||||
// Extrapolates from the previous two touch events before sample time
|
||||
// and extrapolates them to sample time.
|
||||
int32_t
|
||||
GeckoTouchDispatcher::ExtrapolateTouch(MultiTouchInput& aOutTouch, TimeStamp aSampleTime)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(mTouchMoveEvents.size() >= 2);
|
||||
mTouchQueueLock.AssertCurrentThreadOwns();
|
||||
|
||||
// prevTouch < currentTouch < SampleTime
|
||||
MultiTouchInput currentTouch = mTouchMoveEvents.back();
|
||||
mTouchMoveEvents.pop_back();
|
||||
MultiTouchInput prevTouch = mTouchMoveEvents.back();
|
||||
mTouchMoveEvents.clear();
|
||||
mTouchMoveEvents.push_back(currentTouch);
|
||||
|
||||
TimeStamp currentTouchTime = mLastTouchTime;
|
||||
TimeDuration maxResampleTime = TimeDuration::FromMicroseconds(
|
||||
std::min(mTouchTimeDiff.ToMicroseconds() / 2,
|
||||
mMaxPredict.ToMicroseconds()));
|
||||
TimeStamp maxTimestamp = currentTouchTime + maxResampleTime;
|
||||
|
||||
if (aSampleTime > maxTimestamp) {
|
||||
aSampleTime = maxTimestamp;
|
||||
#ifdef LOG_RESAMPLE_DATA
|
||||
LOG("Overshot extrapolation time, adjusting sample time\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
// This has to be signed int since it is negative
|
||||
int64_t frameDiff = (currentTouchTime - aSampleTime).ToMicroseconds();
|
||||
ResampleTouch(aOutTouch, currentTouch, prevTouch, frameDiff, mTouchTimeDiff.ToMicroseconds(), false);
|
||||
return -microsecToMillisec(frameDiff);
|
||||
}
|
||||
/*
|
||||
* +> Base touch (The touch before current touch)
|
||||
* |
|
||||
* | +> Current touch (Latest touch)
|
||||
* | |
|
||||
* | | +> Maximum resample time
|
||||
* | | |
|
||||
* +-----+------+--------------------> Time
|
||||
* ^ ^
|
||||
* | |
|
||||
* +------+--> Potential vsync events which the touches are resampled to
|
||||
* | |
|
||||
* | +> Extrapolation
|
||||
* |
|
||||
* +> Interpolation
|
||||
*/
|
||||
|
||||
void
|
||||
GeckoTouchDispatcher::ResampleTouchMoves(MultiTouchInput& aOutTouch, TimeStamp aVsyncTime)
|
||||
{
|
||||
TimeStamp sampleTime = aVsyncTime - mVsyncAdjust;
|
||||
int32_t touchTimeAdjust = 0;
|
||||
MOZ_RELEASE_ASSERT(mTouchMoveEvents.size() >= 2);
|
||||
mTouchQueueLock.AssertCurrentThreadOwns();
|
||||
|
||||
if (mLastTouchTime > sampleTime) {
|
||||
touchTimeAdjust = InterpolateTouch(aOutTouch, sampleTime);
|
||||
} else {
|
||||
touchTimeAdjust = ExtrapolateTouch(aOutTouch, sampleTime);
|
||||
MultiTouchInput currentTouch = mTouchMoveEvents.back();
|
||||
mTouchMoveEvents.pop_back();
|
||||
MultiTouchInput baseTouch = mTouchMoveEvents.back();
|
||||
mTouchMoveEvents.clear();
|
||||
mTouchMoveEvents.push_back(currentTouch);
|
||||
|
||||
TimeStamp sampleTime = aVsyncTime - mVsyncAdjust;
|
||||
|
||||
if (mLastTouchTime < sampleTime) {
|
||||
TimeDuration maxResampleTime = std::min(mTouchTimeDiff / 2, mMaxPredict);
|
||||
TimeStamp maxTimestamp = mLastTouchTime + maxResampleTime;
|
||||
if (sampleTime > maxTimestamp) {
|
||||
sampleTime = maxTimestamp;
|
||||
#ifdef LOG_RESAMPLE_DATA
|
||||
LOG("Overshot extrapolation time, adjusting sample time\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
ResampleTouch(aOutTouch, baseTouch, currentTouch, sampleTime - (mLastTouchTime - mTouchTimeDiff), mTouchTimeDiff);
|
||||
|
||||
// Both mTimeStamp and mTime are being updated to sampleTime here.
|
||||
// mTime needs to be updated using a delta since TimeStamp doesn't
|
||||
// provide a way to obtain a raw value.
|
||||
aOutTouch.mTime += (sampleTime - aOutTouch.mTimeStamp).ToMilliseconds();
|
||||
aOutTouch.mTimeStamp = sampleTime;
|
||||
aOutTouch.mTime += touchTimeAdjust;
|
||||
}
|
||||
|
||||
// Some touch events get sent as mouse events. If APZ doesn't capture the event
|
||||
|
|
|
@ -50,8 +50,6 @@ public:
|
|||
static bool NotifyVsync(TimeStamp aVsyncTimestamp);
|
||||
|
||||
private:
|
||||
int32_t InterpolateTouch(MultiTouchInput& aOutTouch, TimeStamp aSampleTime);
|
||||
int32_t ExtrapolateTouch(MultiTouchInput& aOutTouch, TimeStamp aSampleTime);
|
||||
void ResampleTouchMoves(MultiTouchInput& aOutTouch, TimeStamp vsyncTime);
|
||||
void SendTouchEvent(MultiTouchInput& aData);
|
||||
void DispatchMouseEvent(MultiTouchInput& aMultiTouch,
|
||||
|
|
Загрузка…
Ссылка в новой задаче