summaryrefslogtreecommitdiffstats
path: root/gfx/layers/apz/src/AndroidAPZ.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/layers/apz/src/AndroidAPZ.cpp')
-rw-r--r--gfx/layers/apz/src/AndroidAPZ.cpp273
1 files changed, 0 insertions, 273 deletions
diff --git a/gfx/layers/apz/src/AndroidAPZ.cpp b/gfx/layers/apz/src/AndroidAPZ.cpp
deleted file mode 100644
index 3a2baff86..000000000
--- a/gfx/layers/apz/src/AndroidAPZ.cpp
+++ /dev/null
@@ -1,273 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "AndroidAPZ.h"
-
-#include "AsyncPanZoomController.h"
-#include "GeneratedJNIWrappers.h"
-#include "gfxPrefs.h"
-#include "OverscrollHandoffState.h"
-#include "ViewConfiguration.h"
-
-#define ANDROID_APZ_LOG(...)
-// #define ANDROID_APZ_LOG(...) printf_stderr("ANDROID_APZ: " __VA_ARGS__)
-
-static float sMaxFlingSpeed = 0.0f;
-
-namespace mozilla {
-namespace layers {
-
-AndroidSpecificState::AndroidSpecificState() {
- using namespace mozilla::java;
-
- sdk::ViewConfiguration::LocalRef config;
- if (sdk::ViewConfiguration::Get(GeckoAppShell::GetApplicationContext(), &config) == NS_OK) {
- int32_t speed = 0;
- if (config->GetScaledMaximumFlingVelocity(&speed) == NS_OK) {
- sMaxFlingSpeed = (float)speed * 0.001f;
- } else {
- ANDROID_APZ_LOG("%p Failed to query ViewConfiguration for scaled maximum fling velocity\n", this);
- }
- } else {
- ANDROID_APZ_LOG("%p Failed to get ViewConfiguration\n", this);
- }
-
- StackScroller::LocalRef scroller;
- if (StackScroller::New(GeckoAppShell::GetApplicationContext(), &scroller) != NS_OK) {
- ANDROID_APZ_LOG("%p Failed to create Android StackScroller\n", this);
- return;
- }
- mOverScroller = scroller;
-}
-
-const float BOUNDS_EPSILON = 1.0f;
-
-// This function is used to convert the scroll offset from a float to an integer
-// suitable for using with the Android OverScroller Class.
-// The Android OverScroller class (unfortunately) operates in integers instead of floats.
-// When casting a float value such as 1.5 to an integer, the value is converted to 1.
-// If this value represents the max scroll offset, the OverScroller class will never scroll
-// to the end of the page as it will always be 0.5 pixels short. To work around this issue,
-// the min and max scroll extents are floor/ceil to convert them to the nearest integer
-// just outside of the actual scroll extents. This means, the starting
-// scroll offset must be converted the same way so that if the frame has already been
-// scrolled 1.5 pixels, it won't be snapped back when converted to an integer. This integer
-// rounding error was one of several causes of Bug 1276463.
-static int32_t
-ClampStart(float aOrigin, float aMin, float aMax)
-{
- if (aOrigin <= aMin) {
- return (int32_t)floor(aMin);
- } else if (aOrigin >= aMax) {
- return (int32_t)ceil(aMax);
- }
- return (int32_t)aOrigin;
-}
-
-AndroidFlingAnimation::AndroidFlingAnimation(AsyncPanZoomController& aApzc,
- PlatformSpecificStateBase* aPlatformSpecificState,
- const RefPtr<const OverscrollHandoffChain>& aOverscrollHandoffChain,
- bool aFlingIsHandoff,
- const RefPtr<const AsyncPanZoomController>& aScrolledApzc)
- : mApzc(aApzc)
- , mOverscrollHandoffChain(aOverscrollHandoffChain)
- , mScrolledApzc(aScrolledApzc)
- , mSentBounceX(false)
- , mSentBounceY(false)
- , mFlingDuration(0)
-{
- MOZ_ASSERT(mOverscrollHandoffChain);
- AndroidSpecificState* state = aPlatformSpecificState->AsAndroidSpecificState();
- MOZ_ASSERT(state);
- mOverScroller = state->mOverScroller;
- MOZ_ASSERT(mOverScroller);
-
- // Drop any velocity on axes where we don't have room to scroll anyways
- // (in this APZC, or an APZC further in the handoff chain).
- // This ensures that we don't take the 'overscroll' path in Sample()
- // on account of one axis which can't scroll having a velocity.
- if (!mOverscrollHandoffChain->CanScrollInDirection(&mApzc, Layer::HORIZONTAL)) {
- ReentrantMonitorAutoEnter lock(mApzc.mMonitor);
- mApzc.mX.SetVelocity(0);
- }
- if (!mOverscrollHandoffChain->CanScrollInDirection(&mApzc, Layer::VERTICAL)) {
- ReentrantMonitorAutoEnter lock(mApzc.mMonitor);
- mApzc.mY.SetVelocity(0);
- }
-
- ParentLayerPoint velocity = mApzc.GetVelocityVector();
-
- float scrollRangeStartX = mApzc.mX.GetPageStart().value;
- float scrollRangeEndX = mApzc.mX.GetScrollRangeEnd().value;
- float scrollRangeStartY = mApzc.mY.GetPageStart().value;
- float scrollRangeEndY = mApzc.mY.GetScrollRangeEnd().value;
- mStartOffset.x = mPreviousOffset.x = mApzc.mX.GetOrigin().value;
- mStartOffset.y = mPreviousOffset.y = mApzc.mY.GetOrigin().value;
- float length = velocity.Length();
- if (length > 0.0f) {
- mFlingDirection = velocity / length;
-
- if ((sMaxFlingSpeed > 0.0f) && (length > sMaxFlingSpeed)) {
- velocity = mFlingDirection * sMaxFlingSpeed;
- }
- }
-
- mPreviousVelocity = velocity;
-
- int32_t originX = ClampStart(mStartOffset.x, scrollRangeStartX, scrollRangeEndX);
- int32_t originY = ClampStart(mStartOffset.y, scrollRangeStartY, scrollRangeEndY);
- if (!state->mLastFling.IsNull()) {
- // If it's been too long since the previous fling, or if the new fling's
- // velocity is too low, don't allow flywheel to kick in. If we do allow
- // flywheel to kick in, then we need to update the timestamp on the
- // StackScroller because otherwise it might use a stale velocity.
- TimeDuration flingDuration = TimeStamp::Now() - state->mLastFling;
- if (flingDuration.ToMilliseconds() < gfxPrefs::APZFlingAccelInterval()
- && velocity.Length() >= gfxPrefs::APZFlingAccelMinVelocity()) {
- bool unused = false;
- mOverScroller->ComputeScrollOffset(flingDuration.ToMilliseconds(), &unused);
- } else {
- mOverScroller->ForceFinished(true);
- }
- }
- mOverScroller->Fling(originX, originY,
- // Android needs the velocity in pixels per second and it is in pixels per ms.
- (int32_t)(velocity.x * 1000.0f), (int32_t)(velocity.y * 1000.0f),
- (int32_t)floor(scrollRangeStartX), (int32_t)ceil(scrollRangeEndX),
- (int32_t)floor(scrollRangeStartY), (int32_t)ceil(scrollRangeEndY),
- 0, 0, 0);
- state->mLastFling = TimeStamp::Now();
-}
-
-/**
- * Advances a fling by an interpolated amount based on the Android OverScroller.
- * This should be called whenever sampling the content transform for this
- * frame. Returns true if the fling animation should be advanced by one frame,
- * or false if there is no fling or the fling has ended.
- */
-bool
-AndroidFlingAnimation::DoSample(FrameMetrics& aFrameMetrics,
- const TimeDuration& aDelta)
-{
- bool shouldContinueFling = true;
-
- mFlingDuration += aDelta.ToMilliseconds();
- mOverScroller->ComputeScrollOffset(mFlingDuration, &shouldContinueFling);
-
- int32_t currentX = 0;
- int32_t currentY = 0;
- mOverScroller->GetCurrX(&currentX);
- mOverScroller->GetCurrY(&currentY);
- ParentLayerPoint offset((float)currentX, (float)currentY);
- ParentLayerPoint preCheckedOffset(offset);
-
- bool hitBoundX = CheckBounds(mApzc.mX, offset.x, mFlingDirection.x, &(offset.x));
- bool hitBoundY = CheckBounds(mApzc.mY, offset.y, mFlingDirection.y, &(offset.y));
-
- ParentLayerPoint velocity = mPreviousVelocity;
-
- // Sometimes the OverScroller fails to update the offset for a frame.
- // If the frame can still scroll we just use the velocity from the previous
- // frame. However, if the frame can no longer scroll in the direction
- // of the fling, then end the animation.
- if (offset != mPreviousOffset) {
- if (aDelta.ToMilliseconds() > 0) {
- mOverScroller->GetCurrSpeedX(&velocity.x);
- mOverScroller->GetCurrSpeedY(&velocity.y);
-
- velocity.x /= 1000;
- velocity.y /= 1000;
-
- mPreviousVelocity = velocity;
- }
- } else if ((fabsf(offset.x - preCheckedOffset.x) > BOUNDS_EPSILON) || (fabsf(offset.y - preCheckedOffset.y) > BOUNDS_EPSILON)) {
- // The page is no longer scrolling but the fling animation is still animating beyond the page bounds. If it goes
- // beyond the BOUNDS_EPSILON then it has overflowed and will never stop. In that case, stop the fling animation.
- shouldContinueFling = false;
- } else if (hitBoundX && hitBoundY) {
- // We can't scroll any farther along either axis.
- shouldContinueFling = false;
- }
-
- float speed = velocity.Length();
-
- // gfxPrefs::APZFlingStoppedThreshold is only used in tests.
- if (!shouldContinueFling || (speed < gfxPrefs::APZFlingStoppedThreshold())) {
- if (shouldContinueFling) {
- // The OverScroller thinks it should continue but the speed is below
- // the stopping threshold so abort the animation.
- mOverScroller->AbortAnimation();
- }
- // This animation is going to end. If DeferHandleFlingOverscroll
- // has not been called and there is still some velocity left,
- // call it so that fling hand off may occur if applicable.
- if (!mSentBounceX && !mSentBounceY && (speed > 0.0f)) {
- DeferHandleFlingOverscroll(velocity);
- }
- return false;
- }
-
- mPreviousOffset = offset;
-
- mApzc.SetVelocityVector(velocity);
- aFrameMetrics.SetScrollOffset(offset / aFrameMetrics.GetZoom());
-
- // If we hit a bounds while flinging, send the velocity so that the bounce
- // animation can play.
- if (hitBoundX || hitBoundY) {
- ParentLayerPoint bounceVelocity = velocity;
-
- if (!mSentBounceX && hitBoundX && fabsf(offset.x - mStartOffset.x) > BOUNDS_EPSILON) {
- mSentBounceX = true;
- } else {
- bounceVelocity.x = 0.0f;
- }
-
- if (!mSentBounceY && hitBoundY && fabsf(offset.y - mStartOffset.y) > BOUNDS_EPSILON) {
- mSentBounceY = true;
- } else {
- bounceVelocity.y = 0.0f;
- }
- if (!IsZero(bounceVelocity)) {
- DeferHandleFlingOverscroll(bounceVelocity);
- }
- }
-
- return true;
-}
-
-void
-AndroidFlingAnimation::DeferHandleFlingOverscroll(ParentLayerPoint& aVelocity)
-{
- mDeferredTasks.AppendElement(
- NewRunnableMethod<ParentLayerPoint,
- RefPtr<const OverscrollHandoffChain>,
- RefPtr<const AsyncPanZoomController>>(&mApzc,
- &AsyncPanZoomController::HandleFlingOverscroll,
- aVelocity,
- mOverscrollHandoffChain,
- mScrolledApzc));
-
-}
-
-bool
-AndroidFlingAnimation::CheckBounds(Axis& aAxis, float aValue, float aDirection, float* aClamped)
-{
- if ((aDirection < 0.0f) && (aValue <= aAxis.GetPageStart().value)) {
- if (aClamped) {
- *aClamped = aAxis.GetPageStart().value;
- }
- return true;
- } else if ((aDirection > 0.0f) && (aValue >= aAxis.GetScrollRangeEnd().value)) {
- if (aClamped) {
- *aClamped = aAxis.GetScrollRangeEnd().value;
- }
- return true;
- }
- return false;
-}
-
-} // namespace layers
-} // namespace mozilla