bug 1083530. Part 2 Refactor GeckoTouchDispacher to use mozilla::Timestamp instead of nsecs_t. r=mwu

This commit is contained in:
Mason Chang 2014-10-29 13:37:06 -07:00
parent 97ebd4c29a
commit fb2714672f
8 changed files with 65 additions and 63 deletions

View File

@ -206,11 +206,11 @@ private:
DECL_GFX_PREF(Once, "gfx.vsync.hw-vsync.enabled", HardwareVsyncEnabled, bool, false);
DECL_GFX_PREF(Once, "gfx.vsync.compositor", VsyncAlignedCompositor, bool, false);
DECL_GFX_PREF(Once, "gfx.touch.resample", TouchResampling, bool, false);
// These times should be in nanoseconds
DECL_GFX_PREF(Once, "gfx.touch.resample.max-predict", TouchResampleMaxPredict, int32_t, 8000000);
DECL_GFX_PREF(Once, "gfx.touch.resample.vsync-adjust", TouchVsyncSampleAdjust, int32_t, 5000000);
DECL_GFX_PREF(Once, "gfx.touch.resample.min-resample", TouchResampleMinTime, int32_t, 2000000);
DECL_GFX_PREF(Once, "gfx.touch.resample.delay-threshold", TouchResampleVsyncDelayThreshold, int32_t, 20000000);
// These times should be in milliseconds
DECL_GFX_PREF(Once, "gfx.touch.resample.max-predict", TouchResampleMaxPredict, int32_t, 8);
DECL_GFX_PREF(Once, "gfx.touch.resample.vsync-adjust", TouchVsyncSampleAdjust, int32_t, 5);
DECL_GFX_PREF(Once, "gfx.touch.resample.min-resample", TouchResampleMinTime, int32_t, 2);
DECL_GFX_PREF(Once, "gfx.touch.resample.delay-threshold", TouchResampleVsyncDelayThreshold, int32_t, 20);
DECL_GFX_PREF(Live, "gl.msaa-level", MSAALevel, uint32_t, 2);

View File

@ -42,19 +42,19 @@ VsyncDispatcher::~VsyncDispatcher()
}
void
VsyncDispatcher::DispatchTouchEvents(bool aNotifiedCompositors, nsecs_t aAndroidVsyncTime)
VsyncDispatcher::DispatchTouchEvents(bool aNotifiedCompositors, TimeStamp aVsyncTime)
{
// Touch events can sometimes start a composite, so make sure we dispatch touches
// even if we don't composite
#ifdef MOZ_WIDGET_GONK
if (!aNotifiedCompositors && gfxPrefs::TouchResampling()) {
GeckoTouchDispatcher::NotifyVsync(aAndroidVsyncTime);
GeckoTouchDispatcher::NotifyVsync(aVsyncTime);
}
#endif
}
void
VsyncDispatcher::NotifyVsync(TimeStamp aVsyncTimestamp, nsecs_t aAndroidVsyncTime)
VsyncDispatcher::NotifyVsync(TimeStamp aVsyncTimestamp)
{
bool notifiedCompositors = false;
if (gfxPrefs::VsyncAlignedCompositor()) {
@ -62,7 +62,7 @@ VsyncDispatcher::NotifyVsync(TimeStamp aVsyncTimestamp, nsecs_t aAndroidVsyncTim
notifiedCompositors = NotifyVsyncObservers(aVsyncTimestamp, mCompositorObservers);
}
DispatchTouchEvents(notifiedCompositors, aAndroidVsyncTime);
DispatchTouchEvents(notifiedCompositors, aVsyncTimestamp);
}
bool
@ -72,7 +72,7 @@ VsyncDispatcher::NotifyVsyncObservers(TimeStamp aVsyncTimestamp, nsTArray<nsRefP
for (size_t i = 0; i < aObservers.Length(); i++) {
aObservers[i]->NotifyVsync(aVsyncTimestamp);
}
return aObservers.IsEmpty();
return !aObservers.IsEmpty();
}
void

View File

@ -12,8 +12,6 @@
#include "nsTArray.h"
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
typedef int64_t nsecs_t; // nano-seconds
class MessageLoop;
namespace mozilla {
@ -46,7 +44,7 @@ class VsyncDispatcher
public:
static VsyncDispatcher* GetInstance();
// Called on the vsync thread when a hardware vsync occurs
void NotifyVsync(TimeStamp aVsyncTimestamp, nsecs_t aAndroidVsyncTime);
void NotifyVsync(TimeStamp aVsyncTimestamp);
// Compositor vsync observers must be added/removed on the compositor thread
void AddCompositorVsyncObserver(VsyncObserver* aVsyncObserver);
@ -55,7 +53,7 @@ public:
private:
VsyncDispatcher();
virtual ~VsyncDispatcher();
void DispatchTouchEvents(bool aNotifiedCompositors, nsecs_t aAndroidVSyncTime);
void DispatchTouchEvents(bool aNotifiedCompositors, TimeStamp aVsyncTime);
// Called on the vsync thread. Returns true if observers were notified
bool NotifyVsyncObservers(TimeStamp aVsyncTimestamp, nsTArray<nsRefPtr<VsyncObserver>>& aObservers);

View File

@ -47,7 +47,7 @@ namespace mozilla {
// Amount of time in MS before an input is considered expired.
static const uint64_t kInputExpirationThresholdMs = 1000;
static int32_t nanosecToMillisec(int64_t nanosec) { return nanosec / 1000000; }
static int32_t microsecToMillisec(int64_t microsec) { return microsec / 1000; }
static StaticRefPtr<GeckoTouchDispatcher> sTouchDispatcher;
@ -55,7 +55,7 @@ GeckoTouchDispatcher::GeckoTouchDispatcher()
: mTouchQueueLock("GeckoTouchDispatcher::mTouchQueueLock")
, mTouchEventsFiltered(false)
, mTouchTimeDiff(0)
, mLastTouchTime(0)
, mLastTouchTime(TimeStamp::Now())
{
// Since GeckoTouchDispatcher is initialized when input is initialized
// and reads gfxPrefs, it is the first thing to touch gfxPrefs.
@ -68,10 +68,10 @@ GeckoTouchDispatcher::GeckoTouchDispatcher()
mEnabledUniformityInfo = gfxPrefs::UniformityInfo();
mResamplingEnabled = gfxPrefs::TouchResampling() &&
gfxPrefs::HardwareVsyncEnabled();
mVsyncAdjust = gfxPrefs::TouchVsyncSampleAdjust();
mMaxPredict = gfxPrefs::TouchResampleMaxPredict();
mMinResampleTime = gfxPrefs::TouchResampleMinTime();
mDelayedVsyncThreshold = gfxPrefs::TouchResampleVsyncDelayThreshold();
mVsyncAdjust = TimeDuration::FromMilliseconds(gfxPrefs::TouchVsyncSampleAdjust());
mMaxPredict = TimeDuration::FromMilliseconds(gfxPrefs::TouchResampleMaxPredict());
mMinResampleTime = TimeDuration::FromMilliseconds(gfxPrefs::TouchResampleMinTime());
mDelayedVsyncThreshold = TimeDuration::FromMilliseconds(gfxPrefs::TouchResampleVsyncDelayThreshold());
sTouchDispatcher = this;
ClearOnShutdown(&sTouchDispatcher);
}
@ -80,7 +80,7 @@ class DispatchTouchEventsMainThread : public nsRunnable
{
public:
DispatchTouchEventsMainThread(GeckoTouchDispatcher* aTouchDispatcher,
uint64_t aVsyncTime)
TimeStamp aVsyncTime)
: mTouchDispatcher(aTouchDispatcher)
, mVsyncTime(aVsyncTime)
{
@ -94,7 +94,7 @@ public:
private:
nsRefPtr<GeckoTouchDispatcher> mTouchDispatcher;
uint64_t mVsyncTime;
TimeStamp mVsyncTime;
};
class DispatchSingleTouchMainThread : public nsRunnable
@ -120,7 +120,7 @@ private:
// Timestamp is in nanoseconds
/* static */ bool
GeckoTouchDispatcher::NotifyVsync(uint64_t aVsyncTimestamp)
GeckoTouchDispatcher::NotifyVsync(TimeStamp aVsyncTimestamp)
{
if (sTouchDispatcher == nullptr) {
return false;
@ -142,7 +142,7 @@ GeckoTouchDispatcher::NotifyVsync(uint64_t aVsyncTimestamp)
// Touch data timestamps are in milliseconds, aEventTime is in nanoseconds
void
GeckoTouchDispatcher::NotifyTouch(MultiTouchInput& aTouch, uint64_t aEventTime)
GeckoTouchDispatcher::NotifyTouch(MultiTouchInput& aTouch, TimeStamp aEventTime)
{
if (aTouch.mType == MultiTouchInput::MULTITOUCH_MOVE) {
MutexAutoLock lock(mTouchQueueLock);
@ -160,14 +160,14 @@ GeckoTouchDispatcher::NotifyTouch(MultiTouchInput& aTouch, uint64_t aEventTime)
mTouchMoveEvents.back() = aTouch;
}
NS_DispatchToMainThread(new DispatchTouchEventsMainThread(this, 0));
NS_DispatchToMainThread(new DispatchTouchEventsMainThread(this, TimeStamp::Now()));
} else {
NS_DispatchToMainThread(new DispatchSingleTouchMainThread(this, aTouch));
}
}
void
GeckoTouchDispatcher::DispatchTouchMoveEvents(uint64_t aVsyncTime)
GeckoTouchDispatcher::DispatchTouchMoveEvents(TimeStamp aVsyncTime)
{
MultiTouchInput touchMove;
@ -181,7 +181,7 @@ GeckoTouchDispatcher::DispatchTouchMoveEvents(uint64_t aVsyncTime)
int touchCount = mTouchMoveEvents.size();
// Both aVsynctime and mLastTouchTime are uint64_t
// Need to store as a signed int.
int64_t vsyncTouchDiff = aVsyncTime - mLastTouchTime;
TimeDuration vsyncTouchDiff = aVsyncTime - mLastTouchTime;
bool resample = (touchCount > 1) &&
(vsyncTouchDiff > mMinResampleTime);
// The delay threshold is a positive pref, but we're testing to see if the
@ -271,7 +271,7 @@ ResampleTouch(MultiTouchInput& aOutTouch, MultiTouchInput& aCurrent,
// Interpolates with the touch event prior to SampleTime
// and with the future touch event past sample time
int32_t
GeckoTouchDispatcher::InterpolateTouch(MultiTouchInput& aOutTouch, uint64_t aSampleTime)
GeckoTouchDispatcher::InterpolateTouch(MultiTouchInput& aOutTouch, TimeStamp aSampleTime)
{
MOZ_RELEASE_ASSERT(mTouchMoveEvents.size() >= 2);
mTouchQueueLock.AssertCurrentThreadOwns();
@ -284,17 +284,17 @@ GeckoTouchDispatcher::InterpolateTouch(MultiTouchInput& aOutTouch, uint64_t aSam
mTouchMoveEvents.clear();
mTouchMoveEvents.push_back(futureTouch);
uint64_t currentTouchTime = mLastTouchTime - mTouchTimeDiff;
int64_t frameDiff = aSampleTime - currentTouchTime;
ResampleTouch(aOutTouch, currentTouch, futureTouch, frameDiff, mTouchTimeDiff, true);
TimeStamp currentTouchTime = mLastTouchTime - mTouchTimeDiff;
int64_t frameDiff = (aSampleTime - currentTouchTime).ToMicroseconds();
ResampleTouch(aOutTouch, currentTouch, futureTouch, frameDiff, mTouchTimeDiff.ToMicroseconds(), true);
return nanosecToMillisec(frameDiff);
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, uint64_t aSampleTime)
GeckoTouchDispatcher::ExtrapolateTouch(MultiTouchInput& aOutTouch, TimeStamp aSampleTime)
{
MOZ_RELEASE_ASSERT(mTouchMoveEvents.size() >= 2);
mTouchQueueLock.AssertCurrentThreadOwns();
@ -306,9 +306,11 @@ GeckoTouchDispatcher::ExtrapolateTouch(MultiTouchInput& aOutTouch, uint64_t aSam
mTouchMoveEvents.clear();
mTouchMoveEvents.push_back(currentTouch);
uint64_t currentTouchTime = mLastTouchTime;
int64_t maxResampleTime = std::min(mTouchTimeDiff / 2, (int64_t) mMaxPredict);
uint64_t maxTimestamp = currentTouchTime + maxResampleTime;
TimeStamp currentTouchTime = mLastTouchTime;
TimeDuration maxResampleTime = TimeDuration::FromMicroseconds(
std::min(mTouchTimeDiff.ToMicroseconds() / 2,
mMaxPredict.ToMicroseconds()));
TimeStamp maxTimestamp = currentTouchTime + maxResampleTime;
if (aSampleTime > maxTimestamp) {
aSampleTime = maxTimestamp;
@ -318,15 +320,15 @@ GeckoTouchDispatcher::ExtrapolateTouch(MultiTouchInput& aOutTouch, uint64_t aSam
}
// This has to be signed int since it is negative
int64_t frameDiff = currentTouchTime - aSampleTime;
ResampleTouch(aOutTouch, currentTouch, prevTouch, frameDiff, mTouchTimeDiff, false);
return -nanosecToMillisec(frameDiff);
int64_t frameDiff = (currentTouchTime - aSampleTime).ToMicroseconds();
ResampleTouch(aOutTouch, currentTouch, prevTouch, frameDiff, mTouchTimeDiff.ToMicroseconds(), false);
return -microsecToMillisec(frameDiff);
}
void
GeckoTouchDispatcher::ResampleTouchMoves(MultiTouchInput& aOutTouch, uint64_t aVsyncTime)
GeckoTouchDispatcher::ResampleTouchMoves(MultiTouchInput& aOutTouch, TimeStamp aVsyncTime)
{
uint64_t sampleTime = aVsyncTime - mVsyncAdjust;
TimeStamp sampleTime = aVsyncTime - mVsyncAdjust;
int32_t touchTimeAdjust = 0;
if (mLastTouchTime > sampleTime) {
@ -335,7 +337,7 @@ GeckoTouchDispatcher::ResampleTouchMoves(MultiTouchInput& aOutTouch, uint64_t aV
touchTimeAdjust = ExtrapolateTouch(aOutTouch, sampleTime);
}
aOutTouch.mTimeStamp += TimeDuration::FromMilliseconds(touchTimeAdjust);
aOutTouch.mTimeStamp = sampleTime;
aOutTouch.mTime += touchTimeAdjust;
}

View File

@ -44,15 +44,15 @@ class GeckoTouchDispatcher
public:
GeckoTouchDispatcher();
void NotifyTouch(MultiTouchInput& aTouch, uint64_t aEventTime);
void NotifyTouch(MultiTouchInput& aTouch, TimeStamp aEventTime);
void DispatchTouchEvent(MultiTouchInput& aMultiTouch);
void DispatchTouchMoveEvents(uint64_t aVsyncTime);
static bool NotifyVsync(uint64_t aVsyncTimestamp);
void DispatchTouchMoveEvents(TimeStamp aVsyncTime);
static bool NotifyVsync(TimeStamp aVsyncTimestamp);
private:
int32_t InterpolateTouch(MultiTouchInput& aOutTouch, uint64_t aSampleTime);
int32_t ExtrapolateTouch(MultiTouchInput& aOutTouch, uint64_t aSampleTime);
void ResampleTouchMoves(MultiTouchInput& aOutTouch, uint64_t vsyncTime);
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,
bool aForwardToChildren);
@ -68,21 +68,21 @@ private:
bool mEnabledUniformityInfo;
// All times below are in nanoseconds
int32_t mVsyncAdjust; // Time from vsync we create sample times from
int32_t mMaxPredict; // How far into the future we're allowed to extrapolate
TimeDuration mVsyncAdjust; // Time from vsync we create sample times from
TimeDuration mMaxPredict; // How far into the future we're allowed to extrapolate
// Amount of time between vsync and the last event that is required before we
// resample
int32_t mMinResampleTime;
TimeDuration mMinResampleTime;
// The time difference between the last two touch move events
int64_t mTouchTimeDiff;
TimeDuration mTouchTimeDiff;
// The system time at which the last touch event occured
uint64_t mLastTouchTime;
TimeStamp mLastTouchTime;
// Threshold if a vsync event runs too far behind touch events
uint64_t mDelayedVsyncThreshold;
TimeDuration mDelayedVsyncThreshold;
};
} // namespace mozilla

View File

@ -75,8 +75,6 @@ using namespace mozilla::layers;
namespace mozilla {
#if ANDROID_VERSION >= 17
nsecs_t sAndroidInitTime = 0;
mozilla::TimeStamp sMozInitTime;
static void
HookInvalidate(const struct hwc_procs* aProcs)
{
@ -116,6 +114,7 @@ HwcComposer2D::HwcComposer2D()
#if ANDROID_VERSION >= 17
, mPrevRetireFence(Fence::NO_FENCE)
, mPrevDisplayFence(Fence::NO_FENCE)
, mLastVsyncTime(0)
#endif
, mPrepared(false)
, mHasHWVsync(false)
@ -161,8 +160,6 @@ HwcComposer2D::Init(hwc_display_t dpy, hwc_surface_t sur, gl::GLContext* aGLCont
}
if (RegisterHwcEventCallback()) {
sAndroidInitTime = systemTime(SYSTEM_TIME_MONOTONIC);
sMozInitTime = TimeStamp::Now();
EnableVsync(true);
}
#else
@ -240,8 +237,12 @@ HwcComposer2D::RunVsyncEventControl(bool aEnable)
void
HwcComposer2D::Vsync(int aDisplay, nsecs_t aVsyncTimestamp)
{
nsecs_t timeSinceInit = aVsyncTimestamp - sAndroidInitTime;
TimeStamp vsyncTime = sMozInitTime + TimeDuration::FromMicroseconds(timeSinceInit / 1000);
TimeStamp vsyncTime = mozilla::TimeStamp(aVsyncTimestamp);
nsecs_t vsyncInterval = aVsyncTimestamp - mLastVsyncTime;
if (vsyncInterval < 16000000 || vsyncInterval > 17000000) {
LOGE("Non-uniform vsync interval: %lld\n", vsyncInterval);
}
mLastVsyncTime = aVsyncTimestamp;
#ifdef MOZ_ENABLE_PROFILER_SPS
if (profiler_is_active()) {
@ -249,7 +250,7 @@ HwcComposer2D::Vsync(int aDisplay, nsecs_t aVsyncTimestamp)
}
#endif
VsyncDispatcher::GetInstance()->NotifyVsync(vsyncTime, aVsyncTimestamp);
VsyncDispatcher::GetInstance()->NotifyVsync(vsyncTime);
}
// Called on the "invalidator" thread (run from HAL).

View File

@ -129,6 +129,7 @@ private:
#if ANDROID_VERSION >= 17
android::sp<android::Fence> mPrevRetireFence;
android::sp<android::Fence> mPrevDisplayFence;
nsecs_t mLastVsyncTime;
#endif
nsTArray<layers::LayerComposite*> mHwcLayerMap;
bool mPrepared;

View File

@ -715,7 +715,7 @@ GeckoInputDispatcher::notifyMotion(const NotifyMotionArgs* args)
int32_t action = args->action & AMOTION_EVENT_ACTION_MASK;
int touchCount = args->pointerCount;
MOZ_ASSERT(touchCount <= MAX_POINTERS);
TimeStamp timestamp = TimeStamp::Now();
TimeStamp timestamp = TimeStamp(args->eventTime);
Modifiers modifiers = getDOMModifiers(args->metaState);
MultiTouchInput::MultiTouchType touchType = MultiTouchInput::MULTITOUCH_CANCEL;
@ -760,7 +760,7 @@ GeckoInputDispatcher::notifyMotion(const NotifyMotionArgs* args)
}
}
mTouchDispatcher->NotifyTouch(touchData, args->eventTime);
mTouchDispatcher->NotifyTouch(touchData, timestamp);
}
void GeckoInputDispatcher::notifySwitch(const NotifySwitchArgs* args)