Bug 1257959 - Dynamic toolbar transition seems to slow down flings r=kats

This commit is contained in:
Randall Barker 2016-04-05 15:12:48 -07:00
parent 285235dfaa
commit d2124b8263
15 changed files with 131 additions and 8 deletions

View File

@ -1077,6 +1077,14 @@ APZCTreeManager::ProcessMouseEvent(WidgetMouseEventBase& aEvent,
return status;
}
void
APZCTreeManager::ProcessTouchVelocity(uint32_t aTimestampMs, float aSpeedY)
{
if (mApzcForInputBlock) {
mApzcForInputBlock->HandleTouchVelocity(aTimestampMs, aSpeedY);
}
}
nsEventStatus
APZCTreeManager::ProcessWheelEvent(WidgetWheelEvent& aEvent,
ScrollableLayerGuid* aOutTargetGuid,

View File

@ -442,6 +442,14 @@ public:
bool* aOutHitScrollbar = nullptr);
ScreenToParentLayerMatrix4x4 GetScreenToApzcTransform(const AsyncPanZoomController *aApzc) const;
ParentLayerToScreenMatrix4x4 GetApzcToGeckoTransform(const AsyncPanZoomController *aApzc) const;
/**
* Process touch velocity.
* Sometimes the touch move event will have a velocity even though no scrolling
* is occurring such as when the toolbar is being hidden/shown in Fennec.
* This function can be called to have the y axis' velocity queue updated.
*/
void ProcessTouchVelocity(uint32_t aTimestampMs, float aSpeedY);
private:
typedef bool (*GuidComparator)(const ScrollableLayerGuid&, const ScrollableLayerGuid&);

View File

@ -1236,6 +1236,11 @@ nsEventStatus AsyncPanZoomController::HandleGestureEvent(const InputData& aEvent
return rv;
}
void AsyncPanZoomController::HandleTouchVelocity(uint32_t aTimesampMs, float aSpeedY)
{
mY.HandleTouchVelocity(aTimesampMs, aSpeedY);
}
nsEventStatus AsyncPanZoomController::OnTouchStart(const MultiTouchInput& aEvent) {
APZC_LOG("%p got a touch-start in state %d\n", this, mState);
mPanDirRestricted = false;

View File

@ -263,6 +263,14 @@ public:
*/
nsEventStatus HandleGestureEvent(const InputData& aEvent);
/**
* Handler for touch velocity.
* Sometimes the touch move event will have a velocity even though no scrolling
* is occurring such as when the toolbar is being hidden/shown in Fennec.
* This function can be called to have the y axis' velocity queue updated.
*/
void HandleTouchVelocity(uint32_t aTimesampMs, float aSpeedY);
/**
* Populates the provided object (if non-null) with the scrollable guid of this apzc.
*/

View File

@ -89,6 +89,21 @@ void Axis::UpdateWithTouchAtDevicePoint(ParentLayerCoord aPos, ParentLayerCoord
}
float newVelocity = mAxisLocked ? 0.0f : (float)(mVelocitySamplePos - aPos + aAdditionalDelta) / (float)(aTimestampMs - mVelocitySampleTimeMs);
newVelocity = ApplyFlingCurveToVelocity(newVelocity);
AXIS_LOG("%p|%s updating velocity to %f with touch\n",
mAsyncPanZoomController, Name(), newVelocity);
mVelocity = newVelocity;
mPos = aPos;
mVelocitySampleTimeMs = aTimestampMs;
mVelocitySamplePos = aPos;
AddVelocityToQueue(aTimestampMs, mVelocity);
}
float Axis::ApplyFlingCurveToVelocity(float aVelocity) const {
float newVelocity = aVelocity;
if (gfxPrefs::APZMaxVelocity() > 0.0f) {
bool velocityIsNegative = (newVelocity < 0);
newVelocity = fabs(newVelocity);
@ -117,20 +132,26 @@ void Axis::UpdateWithTouchAtDevicePoint(ParentLayerCoord aPos, ParentLayerCoord
}
}
AXIS_LOG("%p|%s updating velocity to %f with touch\n",
mAsyncPanZoomController, Name(), newVelocity);
mVelocity = newVelocity;
mPos = aPos;
mVelocitySampleTimeMs = aTimestampMs;
mVelocitySamplePos = aPos;
return newVelocity;
}
// Limit queue size pased on pref
mVelocityQueue.AppendElement(std::make_pair(aTimestampMs, mVelocity));
void Axis::AddVelocityToQueue(uint32_t aTimestampMs, float aVelocity) {
mVelocityQueue.AppendElement(std::make_pair(aTimestampMs, aVelocity));
if (mVelocityQueue.Length() > gfxPrefs::APZMaxVelocityQueueSize()) {
mVelocityQueue.RemoveElementAt(0);
}
}
void Axis::HandleTouchVelocity(uint32_t aTimestampMs, float aSpeed) {
// mVelocityQueue is controller-thread only
APZThreadUtils::AssertOnControllerThread();
mVelocity = ApplyFlingCurveToVelocity(aSpeed);
mVelocitySampleTimeMs = aTimestampMs;
AddVelocityToQueue(aTimestampMs, mVelocity);
}
void Axis::StartTouch(ParentLayerCoord aPos, uint32_t aTimestampMs) {
mStartPos = aPos;
mPos = aPos;

View File

@ -49,6 +49,13 @@ public:
*/
void UpdateWithTouchAtDevicePoint(ParentLayerCoord aPos, ParentLayerCoord aAdditionalDelta, uint32_t aTimestampMs);
protected:
float ApplyFlingCurveToVelocity(float aVelocity) const;
void AddVelocityToQueue(uint32_t aTimestampMs, float aVelocity);
public:
void HandleTouchVelocity(uint32_t aTimestampMs, float aSpeed);
/**
* Notify this Axis that a touch has begun, i.e. the user has put their finger
* on the screen but has not yet tried to pan.

View File

@ -378,6 +378,11 @@ public class DynamicToolbarAnimator {
return 0;
}
// Timestamp of the start of the touch event used to calculate toolbar velocity
private long mLastEventTime;
// Current velocity of the toolbar. Used to populate the velocity queue in C++APZ.
private float mVelocity;
boolean onInterceptTouchEvent(MotionEvent event) {
if (isPinned()) {
return false;
@ -398,6 +403,7 @@ public class DynamicToolbarAnimator {
if (mTouchStart != null) {
Log.v(LOGTAG, "Resetting touch sequence due to non-move");
mTouchStart = null;
mVelocity = 0.0f;
}
if (event.getActionMasked() == MotionEvent.ACTION_UP) {
@ -418,16 +424,26 @@ public class DynamicToolbarAnimator {
// If the direction of movement changed, reset the travel
// distance properties.
mTouchStart = null;
mVelocity = 0.0f;
}
}
if (mTouchStart == null) {
mTouchStart = new PointF(event.getRawX(), event.getRawY());
mLastTouch = event.getRawY();
mLastEventTime = event.getEventTime();
return false;
}
float deltaY = event.getRawY() - mLastTouch;
long currentTime = event.getEventTime();
float deltaTime = (float)(currentTime - mLastEventTime);
mLastEventTime = currentTime;
if (deltaTime > 0.0f) {
mVelocity = -deltaY / deltaTime;
} else {
mVelocity = 0.0f;
}
mLastTouch = event.getRawY();
float travelDistance = event.getRawY() - mTouchStart.y;
@ -465,6 +481,11 @@ public class DynamicToolbarAnimator {
return true;
}
// Get the current velocity of the toolbar.
float getVelocity() {
return mVelocity;
}
public PointF getVisibleEndOfLayerView() {
return new PointF(mTarget.getView().getWidth(),
mTarget.getView().getHeight() - mMaxTranslation + mLayerViewTranslation);

View File

@ -322,6 +322,9 @@ class JavaPanZoomController
return false;
}
// Ignore MontionEvent velocity. Needed for C++APZ
public void onMotionEventVelocity(final long aEventTime, final float aSpeedY) {}
/** This function MUST be called on the UI thread */
@Override
public boolean onMotionEvent(MotionEvent event) {

View File

@ -225,6 +225,9 @@ public class LayerView extends ScrollView implements Tabs.OnTabsChangedListener
event.offsetLocation(0, -mSurfaceTranslation);
if (mToolbarAnimator != null && mToolbarAnimator.onInterceptTouchEvent(event)) {
if (mPanZoomController != null) {
mPanZoomController.onMotionEventVelocity(event.getEventTime(), mToolbarAnimator.getVelocity());
}
return true;
}
if (AppConstants.MOZ_ANDROID_APZ && !mLayerClient.isGeckoReady()) {

View File

@ -51,6 +51,9 @@ class NativePanZoomController extends JNIObject implements PanZoomController {
int action, long time, int metaState,
float x, float y, int buttons);
@WrapForJNI
private native void handleMotionEventVelocity(long time, float ySpeed);
private boolean handleMotionEvent(MotionEvent event) {
if (mDestroyed) {
return false;
@ -194,6 +197,11 @@ class NativePanZoomController extends JNIObject implements PanZoomController {
return false;
}
@Override
public void onMotionEventVelocity(final long aEventTime, final float aSpeedY) {
handleMotionEventVelocity(aEventTime, aSpeedY);
}
@Override
public PointF getVelocityVector() {
// FIXME implement this

View File

@ -36,6 +36,7 @@ public interface PanZoomController {
public boolean onTouchEvent(MotionEvent event);
public boolean onMotionEvent(MotionEvent event);
public boolean onKeyEvent(KeyEvent event);
public void onMotionEventVelocity(final long aEventTime, final float aSpeedY);
public void notifyDefaultActionPrevented(boolean prevented);
public boolean getRedrawHint();

View File

@ -329,6 +329,10 @@ public:
mozilla::jni::NativeStub<NativePanZoomController::HandleMotionEvent_t, Impl>
::template Wrap<&Impl::HandleMotionEvent>),
mozilla::jni::MakeNativeMethod<NativePanZoomController::HandleMotionEventVelocity_t>(
mozilla::jni::NativeStub<NativePanZoomController::HandleMotionEventVelocity_t, Impl>
::template Wrap<&Impl::HandleMotionEventVelocity>),
mozilla::jni::MakeNativeMethod<NativePanZoomController::HandleMouseEvent_t>(
mozilla::jni::NativeStub<NativePanZoomController::HandleMouseEvent_t, Impl>
::template Wrap<&Impl::HandleMouseEvent>),

View File

@ -1529,6 +1529,9 @@ constexpr char NativePanZoomController::DisposeNative_t::signature[];
constexpr char NativePanZoomController::HandleMotionEvent_t::name[];
constexpr char NativePanZoomController::HandleMotionEvent_t::signature[];
constexpr char NativePanZoomController::HandleMotionEventVelocity_t::name[];
constexpr char NativePanZoomController::HandleMotionEventVelocity_t::signature[];
constexpr char NativePanZoomController::HandleMouseEvent_t::name[];
constexpr char NativePanZoomController::HandleMouseEvent_t::signature[];

View File

@ -3663,6 +3663,21 @@ public:
mozilla::jni::ExceptionMode::ABORT;
};
struct HandleMotionEventVelocity_t {
typedef NativePanZoomController Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<
int64_t,
float> Args;
static constexpr char name[] = "handleMotionEventVelocity";
static constexpr char signature[] =
"(JF)V";
static const bool isStatic = false;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
};
struct HandleMouseEvent_t {
typedef NativePanZoomController Owner;
typedef bool ReturnType;

View File

@ -807,6 +807,14 @@ public:
return true;
}
void HandleMotionEventVelocity(int64_t aTime, float aSpeedY)
{
RefPtr<APZCTreeManager> controller = mWindow->mAPZC;
if (controller) {
controller->ProcessTouchVelocity((uint32_t)aTime, aSpeedY);
}
}
void UpdateOverscrollVelocity(const float x, const float y)
{
mNPZC->UpdateOverscrollVelocity(x, y);