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
APZCTreeManager::ClearTree()
{
@ -1742,6 +1752,33 @@ APZCTreeManager::FindRootContentApzcForLayersId(uint64_t aLayersId) const
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
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

View File

@ -261,6 +261,14 @@ public:
*/
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
* tree back to empty. This function may be called multiple times during the
@ -450,6 +458,7 @@ private:
HitTestResult* aOutHitResult);
AsyncPanZoomController* FindRootApzcForLayersId(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> CommonAncestor(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2) const;
already_AddRefed<AsyncPanZoomController> GetTouchInputBlockAPZC(const MultiTouchInput& aEvent,

View File

@ -2639,6 +2639,19 @@ void AsyncPanZoomController::ShareFrameMetricsAcrossProcesses() {
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) {
mFrameMetrics.ScrollBy(aOffset);
}

View File

@ -315,6 +315,15 @@ public:
*/
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.
*/

View File

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

View File

@ -1467,4 +1467,9 @@ class JavaPanZoomController
public void setOverscrollHandler(final Overscroll 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)
private void updateOverscrollVelocity(final float x, final float y) {
if (mOverscroll != null) {

View File

@ -51,4 +51,6 @@ public interface PanZoomController {
public void setOverscrollHandler(final Overscroll controller);
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 windowUtils = window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
windowUtils.setNextPaintSyncId(scrollChange.id);
let win = BrowserApp.selectedTab.browser.contentWindow;
win.scrollBy(scrollChange.x, scrollChange.y);
if (!AppConstants.MOZ_ANDROID_APZ) {
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:
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::NativeStub<NativePanZoomController::DisposeNative_t, Impl>
::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::AdjustScrollForSurfaceShift_t::name[];
constexpr char NativePanZoomController::AdjustScrollForSurfaceShift_t::signature[];
constexpr char NativePanZoomController::Destroy_t::name[];
constexpr char NativePanZoomController::Destroy_t::signature[];

View File

@ -3981,6 +3981,23 @@ public:
protected:
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:
struct Destroy_t {
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)
{
MOZ_ASSERT(AndroidBridge::IsJavaUiThread());