Bug 1243547 - Route scroll position adjusting for surface shifting directly to APZC. r=rbarker

This commit is contained in:
Kartikaya Gupta 2016-01-28 16:00:05 -05:00
parent 3d9ecccf0b
commit 1c933c6cff
13 changed files with 130 additions and 3 deletions

View File

@ -1267,6 +1267,16 @@ APZCTreeManager::CancelAnimation(const ScrollableLayerGuid &aGuid)
} }
} }
void
APZCTreeManager::AdjustScrollForSurfaceShift(const ScreenPoint& aShift)
{
MonitorAutoLock lock(mTreeLock);
RefPtr<AsyncPanZoomController> apzc = FindRootContentOrRootApzc();
if (apzc) {
apzc->AdjustScrollForSurfaceShift(aShift);
}
}
void void
APZCTreeManager::ClearTree() APZCTreeManager::ClearTree()
{ {
@ -1742,6 +1752,33 @@ APZCTreeManager::FindRootContentApzcForLayersId(uint64_t aLayersId) const
return resultNode ? resultNode->GetApzc() : nullptr; return resultNode ? resultNode->GetApzc() : nullptr;
} }
AsyncPanZoomController*
APZCTreeManager::FindRootContentOrRootApzc() const
{
mTreeLock.AssertCurrentThreadOwns();
// Note: this is intended to find the same "root" that would be found
// by AsyncCompositionManager::ApplyAsyncContentTransformToTree inside
// the MOZ_ANDROID_APZ block. That is, it should find the RCD node if there
// is one, or the root APZC if there is not.
// Since BreadthFirstSearch is a pre-order search, we first do a search for
// the RCD, and then if we don't find one, we do a search for the root APZC.
HitTestingTreeNode* resultNode = BreadthFirstSearch(mRootNode.get(),
[](HitTestingTreeNode* aNode) {
AsyncPanZoomController* apzc = aNode->GetApzc();
return apzc && apzc->IsRootContent();
});
if (resultNode) {
return resultNode->GetApzc();
}
resultNode = BreadthFirstSearch(mRootNode.get(),
[](HitTestingTreeNode* aNode) {
AsyncPanZoomController* apzc = aNode->GetApzc();
return (apzc != nullptr);
});
return resultNode ? resultNode->GetApzc() : nullptr;
}
/* The methods GetScreenToApzcTransform() and GetApzcToGeckoTransform() return /* The methods GetScreenToApzcTransform() and GetApzcToGeckoTransform() return
some useful transformations that input events may need applied. This is best some useful transformations that input events may need applied. This is best
illustrated with an example. Consider a chain of layers, L, M, N, O, P, Q, R. Layer L illustrated with an example. Consider a chain of layers, L, M, N, O, P, Q, R. Layer L

View File

@ -261,6 +261,14 @@ public:
*/ */
void CancelAnimation(const ScrollableLayerGuid &aGuid); void CancelAnimation(const ScrollableLayerGuid &aGuid);
/**
* Adjusts the root APZC to compensate for a shift in the surface. See the
* documentation on AsyncPanZoomController::AdjustScrollForSurfaceShift for
* some more details. This is only currently needed due to surface shifts
* caused by the dynamic toolbar on Android.
*/
void AdjustScrollForSurfaceShift(const ScreenPoint& aShift);
/** /**
* Calls Destroy() on all APZC instances attached to the tree, and resets the * Calls Destroy() on all APZC instances attached to the tree, and resets the
* tree back to empty. This function may be called multiple times during the * tree back to empty. This function may be called multiple times during the
@ -450,6 +458,7 @@ private:
HitTestResult* aOutHitResult); HitTestResult* aOutHitResult);
AsyncPanZoomController* FindRootApzcForLayersId(uint64_t aLayersId) const; AsyncPanZoomController* FindRootApzcForLayersId(uint64_t aLayersId) const;
AsyncPanZoomController* FindRootContentApzcForLayersId(uint64_t aLayersId) const; AsyncPanZoomController* FindRootContentApzcForLayersId(uint64_t aLayersId) const;
AsyncPanZoomController* FindRootContentOrRootApzc() const;
already_AddRefed<AsyncPanZoomController> GetMultitouchTarget(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2) const; already_AddRefed<AsyncPanZoomController> GetMultitouchTarget(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2) const;
already_AddRefed<AsyncPanZoomController> CommonAncestor(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2) const; already_AddRefed<AsyncPanZoomController> CommonAncestor(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2) const;
already_AddRefed<AsyncPanZoomController> GetTouchInputBlockAPZC(const MultiTouchInput& aEvent, already_AddRefed<AsyncPanZoomController> GetTouchInputBlockAPZC(const MultiTouchInput& aEvent,

View File

@ -2639,6 +2639,19 @@ void AsyncPanZoomController::ShareFrameMetricsAcrossProcesses() {
mSharingFrameMetricsAcrossProcesses = true; mSharingFrameMetricsAcrossProcesses = true;
} }
void AsyncPanZoomController::AdjustScrollForSurfaceShift(const ScreenPoint& aShift)
{
ReentrantMonitorAutoEnter lock(mMonitor);
CSSPoint adjustment =
ViewAs<ParentLayerPixel>(aShift, PixelCastJustification::ScreenIsParentLayerForRoot)
/ mFrameMetrics.GetZoom();
APZC_LOG("%p adjusting scroll position by %s for surface shift\n",
this, Stringify(adjustment).c_str());
mFrameMetrics.ScrollBy(adjustment);
ScheduleCompositeAndMaybeRepaint();
UpdateSharedCompositorFrameMetrics();
}
void AsyncPanZoomController::ScrollBy(const CSSPoint& aOffset) { void AsyncPanZoomController::ScrollBy(const CSSPoint& aOffset) {
mFrameMetrics.ScrollBy(aOffset); mFrameMetrics.ScrollBy(aOffset);
} }

View File

@ -315,6 +315,15 @@ public:
*/ */
void CancelAnimation(CancelAnimationFlags aFlags = Default); void CancelAnimation(CancelAnimationFlags aFlags = Default);
/**
* Adjusts the scroll position to compensate for a shift in the surface, such
* that the content appears to remain visually in the same position. i.e. if
* the surface moves up by 10 screenpixels, the scroll position should also
* move up by 10 pixels so that what used to be at the top of the surface is
* now 10 pixels down the surface.
*/
void AdjustScrollForSurfaceShift(const ScreenPoint& aShift);
/** /**
* Clear any overscroll on this APZC. * Clear any overscroll on this APZC.
*/ */

View File

@ -226,7 +226,7 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
} }
mViewportMetrics = mViewportMetrics.setViewportSize(width, height); mViewportMetrics = mViewportMetrics.setViewportSize(width, height);
if (scrollChange != null) { if (scrollChange != null) {
mViewportMetrics = mViewportMetrics.offsetViewportByAndClamp(scrollChange.x, scrollChange.y); mViewportMetrics = mPanZoomController.adjustScrollForSurfaceShift(mViewportMetrics, scrollChange);
} }
if (mGeckoIsReady) { if (mGeckoIsReady) {

View File

@ -1467,4 +1467,9 @@ class JavaPanZoomController
public void setOverscrollHandler(final Overscroll handler) { public void setOverscrollHandler(final Overscroll handler) {
mOverscroll = handler; mOverscroll = handler;
} }
@Override
public ImmutableViewportMetrics adjustScrollForSurfaceShift(ImmutableViewportMetrics aMetrics, PointF aShift) {
return aMetrics.offsetViewportByAndClamp(aShift.x, aShift.y);
}
} }

View File

@ -184,6 +184,15 @@ class NativePanZoomController extends JNIObject implements PanZoomController {
} }
} }
@WrapForJNI(stubName = "AdjustScrollForSurfaceShift")
private native void adjustScrollForSurfaceShift(float aX, float aY);
@Override // PanZoomController
public ImmutableViewportMetrics adjustScrollForSurfaceShift(ImmutableViewportMetrics aMetrics, PointF aShift) {
adjustScrollForSurfaceShift(aShift.x, aShift.y);
return aMetrics;
}
@WrapForJNI(allowMultithread = true) @WrapForJNI(allowMultithread = true)
private void updateOverscrollVelocity(final float x, final float y) { private void updateOverscrollVelocity(final float x, final float y) {
if (mOverscroll != null) { if (mOverscroll != null) {

View File

@ -51,4 +51,6 @@ public interface PanZoomController {
public void setOverscrollHandler(final Overscroll controller); public void setOverscrollHandler(final Overscroll controller);
public void setIsLongpressEnabled(boolean isLongpressEnabled); public void setIsLongpressEnabled(boolean isLongpressEnabled);
public ImmutableViewportMetrics adjustScrollForSurfaceShift(ImmutableViewportMetrics aMetrics, PointF aShift);
} }

View File

@ -6044,8 +6044,10 @@ var ViewportHandler = {
let scrollChange = JSON.parse(aData); let scrollChange = JSON.parse(aData);
let windowUtils = window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils); let windowUtils = window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
windowUtils.setNextPaintSyncId(scrollChange.id); windowUtils.setNextPaintSyncId(scrollChange.id);
let win = BrowserApp.selectedTab.browser.contentWindow; if (!AppConstants.MOZ_ANDROID_APZ) {
win.scrollBy(scrollChange.x, scrollChange.y); let win = BrowserApp.selectedTab.browser.contentWindow;
win.scrollBy(scrollChange.x, scrollChange.y);
}
} }
}, },

View File

@ -274,6 +274,10 @@ class NativePanZoomController::Natives : public mozilla::jni::NativeImpl<NativeP
public: public:
static constexpr JNINativeMethod methods[] = { static constexpr JNINativeMethod methods[] = {
mozilla::jni::MakeNativeMethod<NativePanZoomController::AdjustScrollForSurfaceShift_t>(
mozilla::jni::NativeStub<NativePanZoomController::AdjustScrollForSurfaceShift_t, Impl>
::template Wrap<&Impl::AdjustScrollForSurfaceShift>),
mozilla::jni::MakeNativeMethod<NativePanZoomController::DisposeNative_t>( mozilla::jni::MakeNativeMethod<NativePanZoomController::DisposeNative_t>(
mozilla::jni::NativeStub<NativePanZoomController::DisposeNative_t, Impl> mozilla::jni::NativeStub<NativePanZoomController::DisposeNative_t, Impl>
::template Wrap<&Impl::DisposeNative>), ::template Wrap<&Impl::DisposeNative>),

View File

@ -1442,6 +1442,9 @@ auto LayerView::updateZoomedView(mozilla::jni::Object::Param a0) -> void
constexpr char NativePanZoomController::name[]; constexpr char NativePanZoomController::name[];
constexpr char NativePanZoomController::AdjustScrollForSurfaceShift_t::name[];
constexpr char NativePanZoomController::AdjustScrollForSurfaceShift_t::signature[];
constexpr char NativePanZoomController::Destroy_t::name[]; constexpr char NativePanZoomController::Destroy_t::name[];
constexpr char NativePanZoomController::Destroy_t::signature[]; constexpr char NativePanZoomController::Destroy_t::signature[];

View File

@ -3981,6 +3981,23 @@ public:
protected: protected:
NativePanZoomController(jobject instance) : Class(instance) {} NativePanZoomController(jobject instance) : Class(instance) {}
public:
struct AdjustScrollForSurfaceShift_t {
typedef NativePanZoomController Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<
float,
float> Args;
static constexpr char name[] = "adjustScrollForSurfaceShift";
static constexpr char signature[] =
"(FF)V";
static const bool isStatic = false;
static const bool isMultithreaded = false;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
};
public: public:
struct Destroy_t { struct Destroy_t {
typedef NativePanZoomController Owner; typedef NativePanZoomController Owner;

View File

@ -490,6 +490,23 @@ public:
} }
} }
void AdjustScrollForSurfaceShift(float aX, float aY)
{
MOZ_ASSERT(AndroidBridge::IsJavaUiThread());
MutexAutoLock lock(mWindowLock);
if (!mWindow) {
// We already shut down.
return;
}
RefPtr<APZCTreeManager> controller = mWindow->mAPZC;
if (controller) {
controller->AdjustScrollForSurfaceShift(
ScreenPoint(aX, aY));
}
}
void SetIsLongpressEnabled(bool aIsLongpressEnabled) void SetIsLongpressEnabled(bool aIsLongpressEnabled)
{ {
MOZ_ASSERT(AndroidBridge::IsJavaUiThread()); MOZ_ASSERT(AndroidBridge::IsJavaUiThread());