Bug 1055741 - Unify the 'local Screen' and 'ParentLayer' coordinate systems. r=kats

--HG--
extra : rebase_source : af7323668fb54079e121755660da2121bec3d76b
This commit is contained in:
Botond Ballo 2014-11-10 14:35:11 -05:00
parent cbd6340638
commit 29b59b1060
27 changed files with 669 additions and 639 deletions

View File

@ -241,16 +241,16 @@ TabChildBase::InitializeRootMetrics()
mLastRootMetrics.SetViewport(CSSRect(CSSPoint(), kDefaultViewportSize));
mLastRootMetrics.mCompositionBounds = ParentLayerRect(
ParentLayerPoint(),
ParentLayerSize(ViewAs<ParentLayerPixel>(mInnerSize, PixelCastJustification::ScreenToParentLayerForRoot)));
ParentLayerSize(ViewAs<ParentLayerPixel>(mInnerSize, PixelCastJustification::ScreenIsParentLayerForRoot)));
mLastRootMetrics.SetZoom(mLastRootMetrics.CalculateIntrinsicScale());
mLastRootMetrics.mDevPixelsPerCSSPixel = WebWidget()->GetDefaultScale();
// We use ScreenToLayerScale(1) below in order to turn the
// We use ParentLayerToLayerScale(1) below in order to turn the
// async zoom amount into the gecko zoom amount.
mLastRootMetrics.mCumulativeResolution =
mLastRootMetrics.GetZoom() / mLastRootMetrics.mDevPixelsPerCSSPixel * ScreenToLayerScale(1);
mLastRootMetrics.GetZoom() / mLastRootMetrics.mDevPixelsPerCSSPixel * ParentLayerToLayerScale(1);
// This is the root layer, so the cumulative resolution is the same
// as the resolution.
mLastRootMetrics.mPresShellResolution = mLastRootMetrics.mCumulativeResolution / LayoutDeviceToParentLayerScale(1);
mLastRootMetrics.mPresShellResolution = mLastRootMetrics.mCumulativeResolution.scale;
mLastRootMetrics.SetScrollOffset(CSSPoint(0, 0));
TABC_LOG("After InitializeRootMetrics, mLastRootMetrics is %s\n",
@ -294,6 +294,20 @@ TabChildBase::GetPageSize(nsCOMPtr<nsIDocument> aDocument, const CSSSize& aViewp
std::max(htmlHeight, bodyHeight));
}
// For the root frame, Screen and ParentLayer pixels are interchangeable.
// nsViewportInfo stores zoom values as CSSToScreenScale (because it's a
// data structure specific to the root frame), while FrameMetrics and
// ZoomConstraints store zoom values as CSSToParentLayerScale (because they
// are not specific to the root frame). We define convenience functions for
// converting between the two. As the name suggests, they should only be used
// when dealing with the root frame!
CSSToScreenScale ConvertScaleForRoot(CSSToParentLayerScale aScale) {
return ViewTargetAs<ScreenPixel>(aScale, PixelCastJustification::ScreenIsParentLayerForRoot);
}
CSSToParentLayerScale ConvertScaleForRoot(CSSToScreenScale aScale) {
return ViewTargetAs<ParentLayerPixel>(aScale, PixelCastJustification::ScreenIsParentLayerForRoot);
}
bool
TabChildBase::HandlePossibleViewportChange(const ScreenIntSize& aOldScreenSize)
{
@ -316,8 +330,8 @@ TabChildBase::HandlePossibleViewportChange(const ScreenIntSize& aOldScreenSize)
ZoomConstraints constraints(
viewportInfo.IsZoomAllowed(),
viewportInfo.IsDoubleTapZoomAllowed(),
viewportInfo.GetMinZoom(),
viewportInfo.GetMaxZoom());
ConvertScaleForRoot(viewportInfo.GetMinZoom()),
ConvertScaleForRoot(viewportInfo.GetMaxZoom()));
DoUpdateZoomConstraints(presShellId,
viewId,
/* isRoot = */ true,
@ -366,7 +380,7 @@ TabChildBase::HandlePossibleViewportChange(const ScreenIntSize& aOldScreenSize)
metrics.SetViewport(CSSRect(CSSPoint(), viewport));
metrics.mCompositionBounds = ParentLayerRect(
ParentLayerPoint(),
ParentLayerSize(ViewAs<ParentLayerPixel>(mInnerSize, PixelCastJustification::ScreenToParentLayerForRoot)));
ParentLayerSize(ViewAs<ParentLayerPixel>(mInnerSize, PixelCastJustification::ScreenIsParentLayerForRoot)));
metrics.SetRootCompositionSize(
ScreenSize(mInnerSize) * ScreenToLayoutDeviceScale(1.0f) / metrics.mDevPixelsPerCSSPixel);
@ -396,13 +410,13 @@ TabChildBase::HandlePossibleViewportChange(const ScreenIntSize& aOldScreenSize)
// 0.0 to mean "did not calculate a zoom". In that case, we default
// it to the intrinsic scale.
if (viewportInfo.GetDefaultZoom().scale < 0.01f) {
viewportInfo.SetDefaultZoom(metrics.CalculateIntrinsicScale());
viewportInfo.SetDefaultZoom(ConvertScaleForRoot(metrics.CalculateIntrinsicScale()));
}
CSSToScreenScale defaultZoom = viewportInfo.GetDefaultZoom();
MOZ_ASSERT(viewportInfo.GetMinZoom() <= defaultZoom &&
defaultZoom <= viewportInfo.GetMaxZoom());
metrics.SetZoom(defaultZoom);
metrics.SetZoom(ConvertScaleForRoot(defaultZoom));
metrics.SetScrollId(viewId);
}
@ -414,11 +428,13 @@ TabChildBase::HandlePossibleViewportChange(const ScreenIntSize& aOldScreenSize)
}
}
metrics.mCumulativeResolution = metrics.GetZoom() / metrics.mDevPixelsPerCSSPixel * ScreenToLayerScale(1);
metrics.mCumulativeResolution = metrics.GetZoom()
/ metrics.mDevPixelsPerCSSPixel
* ParentLayerToLayerScale(1);
// This is the root layer, so the cumulative resolution is the same
// as the resolution.
metrics.mPresShellResolution = metrics.mCumulativeResolution / LayoutDeviceToParentLayerScale(1);
utils->SetResolution(metrics.mPresShellResolution.scale, metrics.mPresShellResolution.scale);
metrics.mPresShellResolution = metrics.mCumulativeResolution.scale;
utils->SetResolution(metrics.mPresShellResolution, metrics.mPresShellResolution);
CSSSize scrollPort = metrics.CalculateCompositedSizeInCssPixels();
utils->SetScrollPositionClampingScrollPortSize(scrollPort.width, scrollPort.height);
@ -440,7 +456,7 @@ TabChildBase::HandlePossibleViewportChange(const ScreenIntSize& aOldScreenSize)
// The page must have been refreshed in some way such as a new document or
// new CSS viewport, so we know that there's no velocity, acceleration, and
// we have no idea how long painting will take.
metrics, ScreenPoint(0.0f, 0.0f), 0.0));
metrics, ParentLayerPoint(0.0f, 0.0f), 0.0));
metrics.SetUseDisplayPortMargins();
// Force a repaint with these metrics. This, among other things, sets the
@ -457,8 +473,8 @@ TabChildBase::HandlePossibleViewportChange(const ScreenIntSize& aOldScreenSize)
ZoomConstraints constraints(
viewportInfo.IsZoomAllowed(),
viewportInfo.IsDoubleTapZoomAllowed(),
viewportInfo.GetMinZoom(),
viewportInfo.GetMaxZoom());
ConvertScaleForRoot(viewportInfo.GetMinZoom()),
ConvertScaleForRoot(viewportInfo.GetMaxZoom()));
DoUpdateZoomConstraints(presShellId,
viewId,
/* isRoot = */ true,
@ -907,8 +923,8 @@ TabChild::Observe(nsISupports *aSubject,
// until we we get an inner size.
if (HasValidInnerSize()) {
InitializeRootMetrics();
utils->SetResolution(mLastRootMetrics.mPresShellResolution.scale,
mLastRootMetrics.mPresShellResolution.scale);
utils->SetResolution(mLastRootMetrics.mPresShellResolution,
mLastRootMetrics.mPresShellResolution);
HandlePossibleViewportChange(mInnerSize);
}
}

View File

@ -752,7 +752,6 @@ struct ParamTraits<mozilla::layers::FrameMetrics>
WriteParam(aMsg, aParam.mHasScrollgrab);
WriteParam(aMsg, aParam.mUpdateScrollOffset);
WriteParam(aMsg, aParam.mScrollGeneration);
WriteParam(aMsg, aParam.mTransformScale);
WriteParam(aMsg, aParam.mExtraResolution);
WriteParam(aMsg, aParam.mBackgroundColor);
WriteParam(aMsg, aParam.mDoSmoothScroll);
@ -794,7 +793,6 @@ struct ParamTraits<mozilla::layers::FrameMetrics>
ReadParam(aMsg, aIter, &aResult->mHasScrollgrab) &&
ReadParam(aMsg, aIter, &aResult->mUpdateScrollOffset) &&
ReadParam(aMsg, aIter, &aResult->mScrollGeneration) &&
ReadParam(aMsg, aIter, &aResult->mTransformScale) &&
ReadParam(aMsg, aIter, &aResult->mExtraResolution) &&
ReadParam(aMsg, aIter, &aResult->mBackgroundColor) &&
ReadParam(aMsg, aIter, &aResult->mDoSmoothScroll) &&

View File

@ -21,38 +21,6 @@ template <typename T> struct ParamTraits;
namespace mozilla {
// The layer coordinates of the parent layer.
// This can be arrived at in two ways:
// - Start with the CSS coordinates of the parent layer (note: NOT the
// CSS coordinates of the current layer, that will give you the wrong
// answer), multiply by the device scale and the resolutions of all
// layers from the root down to and including the parent.
// - Start with global screen coordinates and unapply all CSS and async
// transforms from the root down to and including the parent.
// It's helpful to look at https://wiki.mozilla.org/Platform/GFX/APZ#Coordinate_systems
// to get a picture of how the various coordinate systems relate to each other.
struct ParentLayerPixel {};
template<> struct IsPixel<ParentLayerPixel> : TrueType {};
typedef gfx::MarginTyped<ParentLayerPixel> ParentLayerMargin;
typedef gfx::PointTyped<ParentLayerPixel> ParentLayerPoint;
typedef gfx::RectTyped<ParentLayerPixel> ParentLayerRect;
typedef gfx::SizeTyped<ParentLayerPixel> ParentLayerSize;
typedef gfx::IntMarginTyped<ParentLayerPixel> ParentLayerIntMargin;
typedef gfx::IntPointTyped<ParentLayerPixel> ParentLayerIntPoint;
typedef gfx::IntRectTyped<ParentLayerPixel> ParentLayerIntRect;
typedef gfx::IntSizeTyped<ParentLayerPixel> ParentLayerIntSize;
typedef gfx::ScaleFactor<CSSPixel, ParentLayerPixel> CSSToParentLayerScale;
typedef gfx::ScaleFactor<LayoutDevicePixel, ParentLayerPixel> LayoutDeviceToParentLayerScale;
typedef gfx::ScaleFactor<ScreenPixel, ParentLayerPixel> ScreenToParentLayerScale;
typedef gfx::ScaleFactor<ParentLayerPixel, LayerPixel> ParentLayerToLayerScale;
typedef gfx::ScaleFactor<ParentLayerPixel, ScreenPixel> ParentLayerToScreenScale;
namespace layers {
/**
@ -78,7 +46,6 @@ public:
, mScrollableRect(0, 0, 0, 0)
, mPresShellResolution(1)
, mCumulativeResolution(1)
, mTransformScale(1)
, mDevPixelsPerCSSPixel(1)
, mMayHaveTouchListeners(false)
, mMayHaveTouchCaret(false)
@ -156,14 +123,14 @@ public:
CSSToScreenScale DisplayportPixelsPerCSSPixel() const
{
// Note: use 'mZoom * ScreenToLayerScale(1.0f)' as the CSS-to-Layer scale
// Note: use 'mZoom * ParentLayerToLayerScale(1.0f)' as the CSS-to-Layer scale
// instead of LayersPixelsPerCSSPixel(), because displayport calculations
// are done in the context of a repaint request, where we ask Layout to
// repaint at a new resolution that includes any async zoom. Until this
// repaint request is processed, LayersPixelsPerCSSPixel() does not yet
// include the async zoom, but it will when the displayport is interpreted
// for the repaint.
return mZoom * ScreenToLayerScale(1.0f) / mExtraResolution;
return mZoom * ParentLayerToLayerScale(1.0f) / mExtraResolution;
}
CSSToLayerScale LayersPixelsPerCSSPixel() const
@ -172,7 +139,7 @@ public:
}
// Get the amount by which this frame has been zoomed since the last repaint.
LayerToScreenScale GetAsyncZoom() const
LayerToParentLayerScale GetAsyncZoom() const
{
return mZoom / LayersPixelsPerCSSPixel();
}
@ -204,31 +171,21 @@ public:
// Return the scale factor needed to fit the viewport
// into its composition bounds.
CSSToScreenScale CalculateIntrinsicScale() const
CSSToParentLayerScale CalculateIntrinsicScale() const
{
return CSSToScreenScale(
return CSSToParentLayerScale(
std::max(mCompositionBounds.width / mViewport.width,
mCompositionBounds.height / mViewport.height));
}
// Return the scale factor for converting from CSS pixels (for this layer)
// to layer pixels of our parent layer. Much as mZoom is used to interface
// between inputs we get in screen pixels and quantities in CSS pixels,
// this is used to interface between mCompositionBounds and quantities
// in CSS pixels.
CSSToParentLayerScale GetZoomToParent() const
{
return mZoom * mTransformScale;
}
CSSSize CalculateCompositedSizeInCssPixels() const
{
return mCompositionBounds.Size() / GetZoomToParent();
return mCompositionBounds.Size() / GetZoom();
}
CSSRect CalculateCompositedRectInCssPixels() const
{
return mCompositionBounds / GetZoomToParent();
return mCompositionBounds / GetZoom();
}
CSSSize CalculateBoundedCompositedSizeInCssPixels() const
@ -344,7 +301,9 @@ public:
// user action, or choosing an initial zoom level on page load). This can
// only be different from 1.0 for frames that are zoomable, which currently
// is just the root content document's root scroll frame (mIsRoot = true).
ParentLayerToLayerScale mPresShellResolution;
// This is a plain float rather than a ScaleFactor because in and of itself
// it does not convert between any coordinate spaces for which we have names.
float mPresShellResolution;
// The cumulative resolution that the current frame has been painted at.
// This is the product of the pres-shell resolutions of the document
@ -352,9 +311,6 @@ public:
// resolution. This information is provided by Gecko at layout/paint time.
LayoutDeviceToLayerScale mCumulativeResolution;
// TODO(botond): This is now always 1 and should be removed (see bug 1055741).
ScreenToParentLayerScale mTransformScale;
// The conversion factor between CSS pixels and device pixels for this frame.
// This can vary based on a variety of things, such as reflowing-zoom. The
// conversion factor for device pixels to layers pixels is just the
@ -402,12 +358,12 @@ public:
return mSmoothScrollOffset;
}
void SetZoom(const CSSToScreenScale& aZoom)
void SetZoom(const CSSToParentLayerScale& aZoom)
{
mZoom = aZoom;
}
CSSToScreenScale GetZoom() const
CSSToParentLayerScale GetZoom() const
{
return mZoom;
}
@ -602,7 +558,7 @@ private:
// but will be drawn to the screen at mZoom. In the steady state, the
// two will be the same, but during an async zoom action the two may
// diverge. This information is initialized in Gecko but updated in the APZC.
CSSToScreenScale mZoom;
CSSToParentLayerScale mZoom;
// Whether mScrollOffset was updated by something other than the APZ code, and
// if the APZC receiving this metrics should update its local copy.
@ -740,8 +696,8 @@ gfx::Log<LogLevel>& operator<<(gfx::Log<LogLevel>& log, const ScrollableLayerGui
struct ZoomConstraints {
bool mAllowZoom;
bool mAllowDoubleTapZoom;
CSSToScreenScale mMinZoom;
CSSToScreenScale mMaxZoom;
CSSToParentLayerScale mMinZoom;
CSSToParentLayerScale mMaxZoom;
ZoomConstraints()
: mAllowZoom(true)
@ -752,8 +708,8 @@ struct ZoomConstraints {
ZoomConstraints(bool aAllowZoom,
bool aAllowDoubleTapZoom,
const CSSToScreenScale& aMinZoom,
const CSSToScreenScale& aMaxZoom)
const CSSToParentLayerScale& aMinZoom,
const CSSToParentLayerScale& aMaxZoom)
: mAllowZoom(aAllowZoom)
, mAllowDoubleTapZoom(aAllowDoubleTapZoom)
, mMinZoom(aMinZoom)

View File

@ -158,10 +158,10 @@ AppendToString(std::stringstream& aStream, const FrameMetrics& m,
aStream << nsPrintfCString(" um=%d", m.GetUseDisplayPortMargins()).get();
AppendToString(aStream, m.GetRootCompositionSize(), " rcs=");
AppendToString(aStream, m.GetViewport(), " v=");
aStream << nsPrintfCString(" z=(ld=%.3f r=%.3f cr=%.3f z=%.3f ts=%.3f)",
m.mDevPixelsPerCSSPixel.scale, m.mPresShellResolution.scale,
aStream << nsPrintfCString(" z=(ld=%.3f r=%.3f cr=%.3f z=%.3f er=%.3f)",
m.mDevPixelsPerCSSPixel.scale, m.mPresShellResolution,
m.mCumulativeResolution.scale, m.GetZoom().scale,
m.mTransformScale.scale).get();
m.GetExtraResolution().scale).get();
aStream << nsPrintfCString(" u=(%d %d %lu)",
m.GetScrollOffsetUpdated(), m.GetDoSmoothScroll(),
m.GetScrollGeneration()).get();

View File

@ -64,7 +64,7 @@ struct APZCTreeManager::TreeBuildingState {
/*static*/ const ScreenMargin
APZCTreeManager::CalculatePendingDisplayPort(
const FrameMetrics& aFrameMetrics,
const ScreenPoint& aVelocity,
const ParentLayerPoint& aVelocity,
double aEstimatedPaintDuration)
{
return AsyncPanZoomController::CalculatePendingDisplayPort(
@ -204,7 +204,8 @@ ComputeTouchSensitiveRegion(GeckoContentController* aController,
// this approximation may not be accurate in the presence of a css-driven
// resolution.
LayoutDeviceToParentLayerScale parentCumulativeResolution =
aMetrics.mCumulativeResolution / aMetrics.mPresShellResolution;
aMetrics.mCumulativeResolution
/ ParentLayerToLayerScale(aMetrics.mPresShellResolution);
visible = visible.Intersect(touchSensitiveRegion
* aMetrics.mDevPixelsPerCSSPixel
* parentCumulativeResolution);
@ -489,36 +490,6 @@ APZCTreeManager::UpdatePanZoomControllerTree(TreeBuildingState& aState,
return aNextSibling;
}
/*static*/ template<class T> void
ApplyTransform(gfx::PointTyped<T>* aPoint, const Matrix4x4& aMatrix)
{
Point result = aMatrix * aPoint->ToUnknownPoint();
*aPoint = ViewAs<T>(result);
}
/*static*/ template<class T> void
ApplyTransform(gfx::IntPointTyped<T>* aPoint, const Matrix4x4& aMatrix)
{
Point result = aMatrix * aPoint->ToUnknownPoint();
*aPoint = TruncatedToInt(ViewAs<T>(result));
}
/*static*/ void
ApplyTransform(nsIntPoint* aPoint, const Matrix4x4& aMatrix)
{
Point result = aMatrix * Point(aPoint->x, aPoint->y);
aPoint->x = NS_lround(result.x);
aPoint->y = NS_lround(result.y);
}
/*static*/ template<class T> void
TransformScreenToGecko(T* aPoint, AsyncPanZoomController* aApzc, APZCTreeManager* aApzcTm)
{
Matrix4x4 transformToApzc = aApzcTm->GetScreenToApzcTransform(aApzc);
Matrix4x4 transformToGecko = aApzcTm->GetApzcToGeckoTransform(aApzc);
ApplyTransform(aPoint, transformToApzc * transformToGecko);
}
nsEventStatus
APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
ScrollableLayerGuid* aOutTargetGuid,
@ -542,53 +513,53 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(panInput.mPanStartPoint,
&inOverscrolledApzc);
if (apzc) {
// When passing the event to the APZC, we need to apply a different
// transform than the one in TransformScreenToGecko, so we need to
// make a copy of the event.
PanGestureInput inputForApzc(panInput);
transformToApzc = GetScreenToApzcTransform(apzc);
ApplyTransform(&(inputForApzc.mPanStartPoint), transformToApzc);
result = mInputQueue->ReceiveInputEvent(apzc, inputForApzc, aOutInputBlockId);
panInput.mLocalPanStartPoint = TransformTo<ParentLayerPixel>(
transformToApzc, panInput.mPanStartPoint);
panInput.mLocalPanDisplacement = TransformVector<ParentLayerPixel>(
transformToApzc, panInput.mPanDisplacement, panInput.mPanStartPoint);
result = mInputQueue->ReceiveInputEvent(apzc, panInput, aOutInputBlockId);
// Update the out-parameters so they are what the caller expects.
apzc->GetGuid(aOutTargetGuid);
TransformScreenToGecko(&(panInput.mPanStartPoint), apzc, this);
Matrix4x4 transformToGecko = transformToApzc * GetApzcToGeckoTransform(apzc);
panInput.mPanStartPoint = TransformTo<ScreenPixel>(
transformToGecko, panInput.mPanStartPoint);
panInput.mPanDisplacement = TransformVector<ScreenPixel>(
transformToGecko, panInput.mPanDisplacement, panInput.mPanStartPoint);
}
break;
} case PINCHGESTURE_INPUT: {
} case PINCHGESTURE_INPUT: { // note: no one currently sends these
PinchGestureInput& pinchInput = aEvent.AsPinchGestureInput();
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(pinchInput.mFocusPoint,
&inOverscrolledApzc);
if (apzc) {
// When passing the event to the APZC, we need to apply a different
// transform than the one in TransformScreenToGecko, so we need to
// make a copy of the event.
PinchGestureInput inputForApzc(pinchInput);
transformToApzc = GetScreenToApzcTransform(apzc);
ApplyTransform(&(inputForApzc.mFocusPoint), transformToApzc);
result = mInputQueue->ReceiveInputEvent(apzc, inputForApzc, aOutInputBlockId);
pinchInput.mLocalFocusPoint = TransformTo<ParentLayerPixel>(
transformToApzc, pinchInput.mFocusPoint);
result = mInputQueue->ReceiveInputEvent(apzc, pinchInput, aOutInputBlockId);
// Update the out-parameters so they are what the caller expects.
apzc->GetGuid(aOutTargetGuid);
TransformScreenToGecko(&(pinchInput.mFocusPoint), apzc, this);
Matrix4x4 outTransform = transformToApzc * GetApzcToGeckoTransform(apzc);
pinchInput.mFocusPoint = TransformTo<ScreenPixel>(
outTransform, pinchInput.mFocusPoint);
}
break;
} case TAPGESTURE_INPUT: {
} case TAPGESTURE_INPUT: { // note: no one currently sends these
TapGestureInput& tapInput = aEvent.AsTapGestureInput();
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(ScreenPoint(tapInput.mPoint),
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(tapInput.mPoint,
&inOverscrolledApzc);
if (apzc) {
// When passing the event to the APZC, we need to apply a different
// transform than the one in TransformScreenToGecko, so we need to
// make a copy of the event.
TapGestureInput inputForApzc(tapInput);
transformToApzc = GetScreenToApzcTransform(apzc);
ApplyTransform(&(inputForApzc.mPoint), transformToApzc);
result = mInputQueue->ReceiveInputEvent(apzc, inputForApzc, aOutInputBlockId);
tapInput.mLocalPoint = TransformTo<ParentLayerPixel>(
transformToApzc, tapInput.mPoint);
result = mInputQueue->ReceiveInputEvent(apzc, tapInput, aOutInputBlockId);
// Update the out-parameters so they are what the caller expects.
apzc->GetGuid(aOutTargetGuid);
TransformScreenToGecko(&(tapInput.mPoint), apzc, this);
Matrix4x4 outTransform = transformToApzc * GetApzcToGeckoTransform(apzc);
tapInput.mPoint = TransformTo<ScreenPixel>(outTransform, tapInput.mPoint);
}
break;
}
@ -709,11 +680,12 @@ APZCTreeManager::ProcessTouchInput(MultiTouchInput& aInput,
// This ensures that the sequence of touch points an APZC sees in an
// input block are all in the same coordinate space.
Matrix4x4 transformToApzc = mCachedTransformToApzcForInputBlock;
MultiTouchInput inputForApzc(aInput);
for (size_t i = 0; i < inputForApzc.mTouches.Length(); i++) {
ApplyTransform(&(inputForApzc.mTouches[i].mScreenPoint), transformToApzc);
for (size_t i = 0; i < aInput.mTouches.Length(); i++) {
SingleTouchData& touchData = aInput.mTouches[i];
touchData.mLocalScreenPoint = TransformTo<ParentLayerPixel>(
transformToApzc, ScreenPoint(touchData.mScreenPoint));
}
result = mInputQueue->ReceiveInputEvent(mApzcForInputBlock, inputForApzc, aOutInputBlockId);
result = mInputQueue->ReceiveInputEvent(mApzcForInputBlock, aInput, aOutInputBlockId);
// For computing the event to pass back to Gecko, use the up-to-date transforms.
// This ensures that transformToApzc and transformToGecko are in sync
@ -722,7 +694,9 @@ APZCTreeManager::ProcessTouchInput(MultiTouchInput& aInput,
Matrix4x4 transformToGecko = GetApzcToGeckoTransform(mApzcForInputBlock);
Matrix4x4 outTransform = transformToApzc * transformToGecko;
for (size_t i = 0; i < aInput.mTouches.Length(); i++) {
ApplyTransform(&(aInput.mTouches[i].mScreenPoint), outTransform);
SingleTouchData& touchData = aInput.mTouches[i];
touchData.mScreenPoint = TransformTo<ScreenPixel>(
outTransform, touchData.mScreenPoint);
}
}
if (mInOverscrolledApzc) {
@ -784,7 +758,7 @@ APZCTreeManager::ProcessEvent(WidgetInputEvent& aEvent,
Matrix4x4 transformToApzc = GetScreenToApzcTransform(apzc);
Matrix4x4 transformToGecko = GetApzcToGeckoTransform(apzc);
Matrix4x4 outTransform = transformToApzc * transformToGecko;
ApplyTransform(&(aEvent.refPoint), outTransform);
aEvent.refPoint = TransformTo<LayoutDevicePixel>(outTransform, aEvent.refPoint);
}
if (inOverscrolledApzc) {
result = nsEventStatus_eConsumeNoDefault;
@ -913,8 +887,8 @@ APZCTreeManager::ClearTree()
}
/**
* Transform a displacement from the screen coordinates of a source APZC to
* the screen coordinates of a target APZC.
* Transform a displacement from the ParentLayer coordinates of a source APZC
* to the ParentLayer coordinates of a target APZC.
* @param aTreeManager the tree manager for the APZC tree containing |aSource|
* and |aTarget|
* @param aSource the source APZC
@ -926,23 +900,23 @@ static void
TransformDisplacement(APZCTreeManager* aTreeManager,
AsyncPanZoomController* aSource,
AsyncPanZoomController* aTarget,
ScreenPoint& aStartPoint,
ScreenPoint& aEndPoint) {
// Convert start and end points to untransformed screen coordinates.
ParentLayerPoint& aStartPoint,
ParentLayerPoint& aEndPoint) {
// Convert start and end points to Screen coordinates.
Matrix4x4 untransformToApzc = aTreeManager->GetScreenToApzcTransform(aSource).Inverse();
ApplyTransform(&aStartPoint, untransformToApzc);
ApplyTransform(&aEndPoint, untransformToApzc);
ScreenPoint screenStart = TransformTo<ScreenPixel>(untransformToApzc, aStartPoint);
ScreenPoint screenEnd = TransformTo<ScreenPixel>(untransformToApzc, aEndPoint);
// Convert start and end points to aTarget's transformed screen coordinates.
// Convert start and end points to aTarget's ParentLayer coordinates.
Matrix4x4 transformToApzc = aTreeManager->GetScreenToApzcTransform(aTarget);
ApplyTransform(&aStartPoint, transformToApzc);
ApplyTransform(&aEndPoint, transformToApzc);
aStartPoint = TransformTo<ParentLayerPixel>(transformToApzc, screenStart);
aEndPoint = TransformTo<ParentLayerPixel>(transformToApzc, screenEnd);
}
bool
APZCTreeManager::DispatchScroll(AsyncPanZoomController* aPrev,
ScreenPoint aStartPoint,
ScreenPoint aEndPoint,
ParentLayerPoint aStartPoint,
ParentLayerPoint aEndPoint,
OverscrollHandoffState& aOverscrollHandoffState)
{
const OverscrollHandoffChain& overscrollHandoffChain = aOverscrollHandoffState.mChain;
@ -977,14 +951,14 @@ APZCTreeManager::DispatchScroll(AsyncPanZoomController* aPrev,
bool
APZCTreeManager::DispatchFling(AsyncPanZoomController* aPrev,
ScreenPoint aVelocity,
ParentLayerPoint aVelocity,
nsRefPtr<const OverscrollHandoffChain> aOverscrollHandoffChain,
bool aHandoff)
{
nsRefPtr<AsyncPanZoomController> current;
uint32_t aOverscrollHandoffChainLength = aOverscrollHandoffChain->Length();
uint32_t startIndex;
// The fling's velocity needs to be transformed from the screen coordinates
// of |aPrev| to the screen coordinates of |next|. To transform a velocity
// correctly, we need to convert it to a displacement. For now, we do this
@ -992,13 +966,13 @@ APZCTreeManager::DispatchFling(AsyncPanZoomController* aPrev,
// TODO: For this to be correct in the presence of 3D transforms, we should
// use the end point of the touch that started the fling as the start point
// rather than (0, 0).
ScreenPoint startPoint; // (0, 0)
ScreenPoint endPoint;
ScreenPoint transformedVelocity = aVelocity;
ParentLayerPoint startPoint; // (0, 0)
ParentLayerPoint endPoint;
ParentLayerPoint transformedVelocity = aVelocity;
if (aHandoff) {
startIndex = aOverscrollHandoffChain->IndexOf(aPrev) + 1;
// IndexOf will return aOverscrollHandoffChain->Length() if
// |aPrev| is not found.
if (startIndex >= aOverscrollHandoffChainLength) {
@ -1007,17 +981,17 @@ APZCTreeManager::DispatchFling(AsyncPanZoomController* aPrev,
} else {
startIndex = 0;
}
for (; startIndex < aOverscrollHandoffChainLength; startIndex++) {
current = aOverscrollHandoffChain->GetApzcAtIndex(startIndex);
// Make sure the apcz about to be handled can be handled
if (current == nullptr || current->IsDestroyed()) {
return false;
}
endPoint = startPoint + transformedVelocity;
// Only transform when current apcz can be transformed with previous
if (startIndex > 0) {
TransformDisplacement(this,
@ -1026,9 +1000,9 @@ APZCTreeManager::DispatchFling(AsyncPanZoomController* aPrev,
startPoint,
endPoint);
}
transformedVelocity = endPoint - startPoint;
bool handoff = (startIndex < 1) ? aHandoff : true;
if (current->AttemptFling(transformedVelocity,
aOverscrollHandoffChain,
@ -1036,7 +1010,7 @@ APZCTreeManager::DispatchFling(AsyncPanZoomController* aPrev,
return true;
}
}
return false;
}

View File

@ -247,7 +247,7 @@ public:
*/
static const ScreenMargin CalculatePendingDisplayPort(
const FrameMetrics& aFrameMetrics,
const ScreenPoint& aVelocity,
const ParentLayerPoint& aVelocity,
double aEstimatedPaintDuration);
/**
@ -327,8 +327,8 @@ public:
* a fling, use DispatchFling().
*/
bool DispatchScroll(AsyncPanZoomController* aApzc,
ScreenPoint aStartPoint,
ScreenPoint aEndPoint,
ParentLayerPoint aStartPoint,
ParentLayerPoint aEndPoint,
OverscrollHandoffState& aOverscrollHandoffState);
/**
@ -353,7 +353,7 @@ public:
* the excess fling itself by going into an overscroll fling.
*/
bool DispatchFling(AsyncPanZoomController* aApzc,
ScreenPoint aVelocity,
ParentLayerPoint aVelocity,
nsRefPtr<const OverscrollHandoffChain> aOverscrollHandoffChain,
bool aHandoff);

View File

@ -135,6 +135,7 @@ typedef mozilla::layers::AllowedTouchBehavior AllowedTouchBehavior;
typedef GeckoContentController::APZStateChange APZStateChange;
typedef mozilla::gfx::Point Point;
typedef mozilla::gfx::Matrix4x4 Matrix4x4;
using mozilla::gfx::PointTyped;
/**
* \page APZCPrefs APZ preferences
@ -389,12 +390,12 @@ StaticAutoPtr<ComputedTimingFunction> gVelocityCurveFunction;
/**
* Maximum zoom amount, always used, even if a page asks for higher.
*/
static const CSSToScreenScale MAX_ZOOM(8.0f);
static const CSSToParentLayerScale MAX_ZOOM(8.0f);
/**
* Minimum zoom amount, always used, even if a page asks for lower.
*/
static const CSSToScreenScale MIN_ZOOM(0.125f);
static const CSSToParentLayerScale MIN_ZOOM(0.125f);
/**
* Is aAngle within the given threshold of the horizontal axis?
@ -497,7 +498,7 @@ public:
}
}
ScreenPoint velocity(mApzc.mX.GetVelocity(), mApzc.mY.GetVelocity());
ParentLayerPoint velocity = mApzc.GetVelocityVector();
// If the last fling was very recent and in the same direction as this one,
// boost the velocity to be the sum of the two. Check separate axes separately
@ -570,18 +571,18 @@ public:
// AdjustDisplacement() zeroes out the Axis velocity if we're in overscroll.
// Since we need to hand off the velocity to the tree manager in such a case,
// we save it here. Would be ScreenVector instead of ScreenPoint if we had
// vector classes.
ScreenPoint velocity(mApzc.mX.GetVelocity(), mApzc.mY.GetVelocity());
// we save it here. Would be ParentLayerVector instead of ParentLayerPoint
// if we had vector classes.
ParentLayerPoint velocity = mApzc.GetVelocityVector();
ScreenPoint offset = velocity * aDelta.ToMilliseconds();
ParentLayerPoint offset = velocity * aDelta.ToMilliseconds();
// Ordinarily we might need to do a ScheduleComposite if either of
// the following AdjustDisplacement calls returns true, but this
// is already running as part of a FlingAnimation, so we'll be compositing
// per frame of animation anyway.
ScreenPoint overscroll;
ScreenPoint adjustedOffset;
ParentLayerPoint overscroll;
ParentLayerPoint adjustedOffset;
mApzc.mX.AdjustDisplacement(offset.x, adjustedOffset.x, overscroll.x);
mApzc.mY.AdjustDisplacement(offset.y, adjustedOffset.y, overscroll.y);
@ -645,8 +646,8 @@ private:
class ZoomAnimation: public AsyncPanZoomAnimation {
public:
ZoomAnimation(CSSPoint aStartOffset, CSSToScreenScale aStartZoom,
CSSPoint aEndOffset, CSSToScreenScale aEndZoom)
ZoomAnimation(CSSPoint aStartOffset, CSSToParentLayerScale aStartZoom,
CSSPoint aEndOffset, CSSToParentLayerScale aEndZoom)
: mTotalDuration(TimeDuration::FromMilliseconds(gfxPrefs::APZZoomAnimationDuration()))
, mStartOffset(aStartOffset)
, mStartZoom(aStartZoom)
@ -672,7 +673,7 @@ public:
// We scale the scrollOffset linearly with sampledPosition, so the zoom
// needs to scale inversely to match.
aFrameMetrics.SetZoom(CSSToScreenScale(1 /
aFrameMetrics.SetZoom(CSSToParentLayerScale(1 /
(sampledPosition / mEndZoom.scale +
(1 - sampledPosition) / mStartZoom.scale)));
@ -693,18 +694,18 @@ private:
// interpolate between the start and end frames. We only use the
// |mViewportScrollOffset| and |mResolution| fields on this.
CSSPoint mStartOffset;
CSSToScreenScale mStartZoom;
CSSToParentLayerScale mStartZoom;
// Target metrics for a zoom to animation. This is only valid when we are in
// the "ANIMATED_ZOOM" state. We only use the |mViewportScrollOffset| and
// |mResolution| fields on this.
CSSPoint mEndOffset;
CSSToScreenScale mEndZoom;
CSSToParentLayerScale mEndZoom;
};
class OverscrollAnimation: public AsyncPanZoomAnimation {
public:
explicit OverscrollAnimation(AsyncPanZoomController& aApzc, const ScreenPoint& aVelocity)
explicit OverscrollAnimation(AsyncPanZoomController& aApzc, const ParentLayerPoint& aVelocity)
: mApzc(aApzc)
{
mApzc.mX.SetVelocity(aVelocity.x);
@ -765,7 +766,7 @@ public:
mYAxisModel.GetVelocity()));
// Convert from points/second to points/ms
ScreenPoint velocity = ScreenPoint(css_velocity.x, css_velocity.y) / 1000.0f;
ParentLayerPoint velocity = ParentLayerPoint(css_velocity.x, css_velocity.y) / 1000.0f;
// Keep the velocity updated for the Axis class so that any animations
// chained off of the smooth scroll will inherit it.
@ -781,11 +782,11 @@ public:
}
// If we overscroll, hand off to a fling animation that will complete the
// spring back.
CSSToScreenScale zoom = aFrameMetrics.GetZoom();
ScreenPoint displacement = (position - aFrameMetrics.GetScrollOffset()) * zoom;
CSSToParentLayerScale zoom = aFrameMetrics.GetZoom();
ParentLayerPoint displacement = (position - aFrameMetrics.GetScrollOffset()) * zoom;
ScreenPoint overscroll;
ScreenPoint adjustedOffset;
ParentLayerPoint overscroll;
ParentLayerPoint adjustedOffset;
mApzc.mX.AdjustDisplacement(displacement.x, adjustedOffset.x, overscroll.x);
mApzc.mY.AdjustDisplacement(displacement.y, adjustedOffset.y, overscroll.y);
@ -1004,7 +1005,7 @@ AsyncPanZoomController::IsDestroyed() const
return mTreeManager == nullptr;
}
/* static */float
/* static */ScreenCoord
AsyncPanZoomController::GetTouchStartTolerance()
{
return (gfxPrefs::APZTouchStartTolerance() * APZCTreeManager::GetDPI());
@ -1131,7 +1132,7 @@ nsEventStatus AsyncPanZoomController::HandleGestureEvent(const InputData& aEvent
nsEventStatus AsyncPanZoomController::OnTouchStart(const MultiTouchInput& aEvent) {
APZC_LOG("%p got a touch-start in state %d\n", this, mState);
mPanDirRestricted = false;
ScreenPoint point = GetFirstTouchScreenPoint(aEvent);
ParentLayerPoint point = GetFirstTouchPoint(aEvent);
switch (mState) {
case FLING:
@ -1185,7 +1186,7 @@ nsEventStatus AsyncPanZoomController::OnTouchMove(const MultiTouchInput& aEvent)
return nsEventStatus_eIgnore;
case TOUCHING: {
float panThreshold = GetTouchStartTolerance();
ScreenCoord panThreshold = GetTouchStartTolerance();
UpdateWithTouchAtDevicePoint(aEvent);
if (PanDistance() < panThreshold) {
@ -1270,7 +1271,7 @@ nsEventStatus AsyncPanZoomController::OnTouchEnd(const MultiTouchInput& aEvent)
CurrentTouchBlock()->GetOverscrollHandoffChain()->FlushRepaints();
mX.EndTouch(aEvent.mTime);
mY.EndTouch(aEvent.mTime);
ScreenPoint flingVelocity(mX.GetVelocity(), mY.GetVelocity());
ParentLayerPoint flingVelocity = GetVelocityVector();
// Clear our velocities; if DispatchFling() gives the fling to us,
// the fling velocity gets *added* to our existing velocity in
// AcceptFling().
@ -1334,7 +1335,7 @@ nsEventStatus AsyncPanZoomController::OnScaleBegin(const PinchGestureInput& aEve
}
SetState(PINCHING);
mLastZoomFocus = ToParentLayerCoords(aEvent.mFocusPoint) - mFrameMetrics.mCompositionBounds.TopLeft();
mLastZoomFocus = aEvent.mLocalFocusPoint - mFrameMetrics.mCompositionBounds.TopLeft();
return nsEventStatus_eConsumeNoDefault;
}
@ -1361,9 +1362,9 @@ nsEventStatus AsyncPanZoomController::OnScale(const PinchGestureInput& aEvent) {
{
ReentrantMonitorAutoEnter lock(mMonitor);
CSSToParentLayerScale userZoom = mFrameMetrics.GetZoomToParent();
ParentLayerPoint focusPoint = ToParentLayerCoords(aEvent.mFocusPoint) - mFrameMetrics.mCompositionBounds.TopLeft();
CSSPoint cssFocusPoint = focusPoint / mFrameMetrics.GetZoomToParent();
CSSToParentLayerScale userZoom = mFrameMetrics.GetZoom();
ParentLayerPoint focusPoint = aEvent.mLocalFocusPoint - mFrameMetrics.mCompositionBounds.TopLeft();
CSSPoint cssFocusPoint = focusPoint / mFrameMetrics.GetZoom();
CSSPoint focusChange = (mLastZoomFocus - focusPoint) / userZoom;
// If displacing by the change in focus point will take us off page bounds,
@ -1377,8 +1378,8 @@ nsEventStatus AsyncPanZoomController::OnScale(const PinchGestureInput& aEvent) {
// either axis such that we don't overscroll the boundaries when zooming.
CSSPoint neededDisplacement;
CSSToParentLayerScale realMinZoom = mZoomConstraints.mMinZoom * mFrameMetrics.mTransformScale;
CSSToParentLayerScale realMaxZoom = mZoomConstraints.mMaxZoom * mFrameMetrics.mTransformScale;
CSSToParentLayerScale realMinZoom = mZoomConstraints.mMinZoom;
CSSToParentLayerScale realMaxZoom = mZoomConstraints.mMaxZoom;
realMinZoom.scale = std::max(realMinZoom.scale,
mFrameMetrics.mCompositionBounds.width / mFrameMetrics.mScrollableRect.width);
realMinZoom.scale = std::max(realMinZoom.scale,
@ -1453,14 +1454,13 @@ nsEventStatus AsyncPanZoomController::OnScaleEnd(const PinchGestureInput& aEvent
}
bool
AsyncPanZoomController::ConvertToGecko(const ScreenPoint& aPoint, CSSPoint* aOut)
AsyncPanZoomController::ConvertToGecko(const ParentLayerPoint& aPoint, CSSPoint* aOut)
{
if (APZCTreeManager* treeManagerLocal = GetApzcTreeManager()) {
Matrix4x4 transformToGecko = treeManagerLocal->GetApzcToGeckoTransform(this);
Point result = transformToGecko * Point(aPoint.x, aPoint.y);
// NOTE: This isn't *quite* LayoutDevicePoint, we just don't have a name
// for this coordinate space and it maps the closest to LayoutDevicePoint.
LayoutDevicePoint layoutPoint = LayoutDevicePoint(result.x, result.y);
LayoutDevicePoint layoutPoint = TransformTo<LayoutDevicePixel>(transformToGecko, aPoint);
{ // scoped lock to access mFrameMetrics
ReentrantMonitorAutoEnter lock(mMonitor);
*aOut = layoutPoint / mFrameMetrics.mDevPixelsPerCSSPixel;
@ -1473,8 +1473,8 @@ AsyncPanZoomController::ConvertToGecko(const ScreenPoint& aPoint, CSSPoint* aOut
nsEventStatus AsyncPanZoomController::OnPanMayBegin(const PanGestureInput& aEvent) {
APZC_LOG("%p got a pan-maybegin in state %d\n", this, mState);
mX.StartTouch(aEvent.mPanStartPoint.x, aEvent.mTime);
mY.StartTouch(aEvent.mPanStartPoint.y, aEvent.mTime);
mX.StartTouch(aEvent.mLocalPanStartPoint.x, aEvent.mTime);
mY.StartTouch(aEvent.mLocalPanStartPoint.y, aEvent.mTime);
if (mPanGestureState) {
mPanGestureState->GetOverscrollHandoffChain()->CancelAnimations();
} else {
@ -1504,8 +1504,8 @@ nsEventStatus AsyncPanZoomController::OnPanBegin(const PanGestureInput& aEvent)
mPanGestureState = MakeUnique<InputBlockState>(this);
mX.StartTouch(aEvent.mPanStartPoint.x, aEvent.mTime);
mY.StartTouch(aEvent.mPanStartPoint.y, aEvent.mTime);
mX.StartTouch(aEvent.mLocalPanStartPoint.x, aEvent.mTime);
mY.StartTouch(aEvent.mLocalPanStartPoint.y, aEvent.mTime);
if (GetAxisLockMode() == FREE) {
SetState(PANNING);
@ -1542,19 +1542,18 @@ nsEventStatus AsyncPanZoomController::OnPan(const PanGestureInput& aEvent, bool
// size and position. We need to do so even if this is a momentum pan (i.e.
// aFingersOnTouchpad == false); in that case the "with touch" part is not
// really appropriate, so we may want to rethink this at some point.
mX.UpdateWithTouchAtDevicePoint(aEvent.mPanStartPoint.x, aEvent.mTime);
mY.UpdateWithTouchAtDevicePoint(aEvent.mPanStartPoint.y, aEvent.mTime);
mX.UpdateWithTouchAtDevicePoint(aEvent.mLocalPanStartPoint.x, aEvent.mTime);
mY.UpdateWithTouchAtDevicePoint(aEvent.mLocalPanStartPoint.y, aEvent.mTime);
ScreenPoint panDisplacement = aEvent.mPanDisplacement;
ToGlobalScreenCoordinates(&panDisplacement, aEvent.mPanStartPoint);
HandlePanningUpdate(panDisplacement);
HandlePanningUpdate(aEvent.mPanDisplacement);
// TODO: Handle pan events sent without pan begin / pan end events properly.
if (mPanGestureState) {
ScreenPoint panDistance(fabs(panDisplacement.x), fabs(panDisplacement.y));
ScreenPoint panDistance(fabs(aEvent.mPanDisplacement.x), fabs(aEvent.mPanDisplacement.y));
OverscrollHandoffState handoffState(
*mPanGestureState->GetOverscrollHandoffChain(), panDistance);
CallDispatchScroll(aEvent.mPanStartPoint, aEvent.mPanStartPoint + aEvent.mPanDisplacement,
CallDispatchScroll(aEvent.mLocalPanStartPoint,
aEvent.mLocalPanStartPoint + aEvent.mLocalPanDisplacement,
handoffState);
}
@ -1608,7 +1607,7 @@ nsEventStatus AsyncPanZoomController::OnLongPress(const TapGestureInput& aEvent)
if (controller) {
int32_t modifiers = WidgetModifiersToDOMModifiers(aEvent.modifiers);
CSSPoint geckoScreenPoint;
if (ConvertToGecko(aEvent.mPoint, &geckoScreenPoint)) {
if (ConvertToGecko(aEvent.mLocalPoint, &geckoScreenPoint)) {
uint64_t blockId = GetInputQueue()->InjectNewTouchBlock(this);
controller->HandleLongTap(geckoScreenPoint, modifiers, GetGuid(), blockId);
return nsEventStatus_eConsumeNoDefault;
@ -1623,7 +1622,7 @@ nsEventStatus AsyncPanZoomController::OnLongPressUp(const TapGestureInput& aEven
if (controller) {
int32_t modifiers = WidgetModifiersToDOMModifiers(aEvent.modifiers);
CSSPoint geckoScreenPoint;
if (ConvertToGecko(aEvent.mPoint, &geckoScreenPoint)) {
if (ConvertToGecko(aEvent.mLocalPoint, &geckoScreenPoint)) {
controller->HandleLongTapUp(geckoScreenPoint, modifiers, GetGuid());
return nsEventStatus_eConsumeNoDefault;
}
@ -1631,7 +1630,7 @@ nsEventStatus AsyncPanZoomController::OnLongPressUp(const TapGestureInput& aEven
return nsEventStatus_eIgnore;
}
nsEventStatus AsyncPanZoomController::GenerateSingleTap(const ScreenIntPoint& aPoint, mozilla::Modifiers aModifiers) {
nsEventStatus AsyncPanZoomController::GenerateSingleTap(const ParentLayerPoint& aPoint, mozilla::Modifiers aModifiers) {
nsRefPtr<GeckoContentController> controller = GetGeckoContentController();
if (controller) {
CSSPoint geckoScreenPoint;
@ -1667,14 +1666,14 @@ nsEventStatus AsyncPanZoomController::OnSingleTapUp(const TapGestureInput& aEven
// If mZoomConstraints.mAllowDoubleTapZoom is true we wait for a call to OnSingleTapConfirmed before
// sending event to content
if (!(mZoomConstraints.mAllowDoubleTapZoom && CurrentTouchBlock()->TouchActionAllowsDoubleTapZoom())) {
return GenerateSingleTap(aEvent.mPoint, aEvent.modifiers);
return GenerateSingleTap(aEvent.mLocalPoint, aEvent.modifiers);
}
return nsEventStatus_eIgnore;
}
nsEventStatus AsyncPanZoomController::OnSingleTapConfirmed(const TapGestureInput& aEvent) {
APZC_LOG("%p got a single-tap-confirmed in state %d\n", this, mState);
return GenerateSingleTap(aEvent.mPoint, aEvent.modifiers);
return GenerateSingleTap(aEvent.mLocalPoint, aEvent.modifiers);
}
nsEventStatus AsyncPanZoomController::OnDoubleTap(const TapGestureInput& aEvent) {
@ -1684,7 +1683,7 @@ nsEventStatus AsyncPanZoomController::OnDoubleTap(const TapGestureInput& aEvent)
if (mZoomConstraints.mAllowDoubleTapZoom && CurrentTouchBlock()->TouchActionAllowsDoubleTapZoom()) {
int32_t modifiers = WidgetModifiersToDOMModifiers(aEvent.modifiers);
CSSPoint geckoScreenPoint;
if (ConvertToGecko(aEvent.mPoint, &geckoScreenPoint)) {
if (ConvertToGecko(aEvent.mLocalPoint, &geckoScreenPoint)) {
controller->HandleDoubleTap(geckoScreenPoint, modifiers, GetGuid());
}
}
@ -1699,52 +1698,42 @@ nsEventStatus AsyncPanZoomController::OnCancelTap(const TapGestureInput& aEvent)
return nsEventStatus_eIgnore;
}
// Helper function for To[Global|Local]ScreenCoordinates().
// TODO(botond): Generalize this into a template function in UnitTransforms.h.
static void TransformVector(const Matrix4x4& aTransform,
ScreenPoint* aVector,
const ScreenPoint& aAnchor) {
ScreenPoint start = aAnchor;
ScreenPoint end = aAnchor + *aVector;
start = TransformTo<ScreenPixel>(aTransform, start);
end = TransformTo<ScreenPixel>(aTransform, end);
*aVector = end - start;
}
void AsyncPanZoomController::ToGlobalScreenCoordinates(ScreenPoint* aVector,
const ScreenPoint& aAnchor) const {
ScreenPoint AsyncPanZoomController::ToScreenCoordinates(const ParentLayerPoint& aVector,
const ParentLayerPoint& aAnchor) const {
if (APZCTreeManager* treeManagerLocal = GetApzcTreeManager()) {
Matrix4x4 apzcToScreen = treeManagerLocal->GetScreenToApzcTransform(this).Inverse();
TransformVector(apzcToScreen, aVector, aAnchor);
return TransformVector<ScreenPixel>(apzcToScreen, aVector, aAnchor);
}
return ViewAs<ScreenPixel>(aVector, PixelCastJustification::TransformNotAvailable);
}
void AsyncPanZoomController::ToLocalScreenCoordinates(ScreenPoint* aVector,
const ScreenPoint& aAnchor) const {
ParentLayerPoint AsyncPanZoomController::ToParentLayerCoordinates(const ScreenPoint& aVector,
const ScreenPoint& aAnchor) const {
if (APZCTreeManager* treeManagerLocal = GetApzcTreeManager()) {
Matrix4x4 transform = treeManagerLocal->GetScreenToApzcTransform(this);
TransformVector(transform, aVector, aAnchor);
return TransformVector<ParentLayerPixel>(transform, aVector, aAnchor);
}
return ViewAs<ParentLayerPixel>(aVector, PixelCastJustification::TransformNotAvailable);
}
float AsyncPanZoomController::PanDistance() const {
ScreenPoint panVector;
ScreenPoint panStart;
ScreenCoord AsyncPanZoomController::PanDistance() const {
ParentLayerPoint panVector;
ParentLayerPoint panStart;
{
ReentrantMonitorAutoEnter lock(mMonitor);
panVector = ScreenPoint(mX.PanDistance(), mY.PanDistance());
panVector = ParentLayerPoint(mX.PanDistance(), mY.PanDistance());
panStart = PanStart();
}
ToGlobalScreenCoordinates(&panVector, panStart);
return NS_hypot(panVector.x, panVector.y);
return ToScreenCoordinates(panVector, panStart).Length();
}
ScreenPoint AsyncPanZoomController::PanStart() const {
return ScreenPoint(mX.PanStart(), mY.PanStart());
ParentLayerPoint AsyncPanZoomController::PanStart() const {
return ParentLayerPoint(mX.PanStart(), mY.PanStart());
}
const ScreenPoint AsyncPanZoomController::GetVelocityVector() const {
return ScreenPoint(mX.GetVelocity(), mY.GetVelocity());
const ParentLayerPoint AsyncPanZoomController::GetVelocityVector() const {
return ParentLayerPoint(mX.GetVelocity(), mY.GetVelocity());
}
void AsyncPanZoomController::HandlePanningWithTouchAction(double aAngle) {
@ -1844,7 +1833,7 @@ void AsyncPanZoomController::HandlePanningUpdate(const ScreenPoint& aPanDistance
nsEventStatus AsyncPanZoomController::StartPanning(const MultiTouchInput& aEvent) {
ReentrantMonitorAutoEnter lock(mMonitor);
ScreenPoint point = GetFirstTouchScreenPoint(aEvent);
ParentLayerPoint point = GetFirstTouchPoint(aEvent);
float dx = mX.PanDistance(point.x);
float dy = mY.PanDistance(point.y);
@ -1877,25 +1866,25 @@ nsEventStatus AsyncPanZoomController::StartPanning(const MultiTouchInput& aEvent
}
void AsyncPanZoomController::UpdateWithTouchAtDevicePoint(const MultiTouchInput& aEvent) {
ScreenPoint point = GetFirstTouchScreenPoint(aEvent);
ParentLayerPoint point = GetFirstTouchPoint(aEvent);
mX.UpdateWithTouchAtDevicePoint(point.x, aEvent.mTime);
mY.UpdateWithTouchAtDevicePoint(point.y, aEvent.mTime);
}
bool AsyncPanZoomController::AttemptScroll(const ScreenPoint& aStartPoint,
const ScreenPoint& aEndPoint,
bool AsyncPanZoomController::AttemptScroll(const ParentLayerPoint& aStartPoint,
const ParentLayerPoint& aEndPoint,
OverscrollHandoffState& aOverscrollHandoffState) {
// "start - end" rather than "end - start" because e.g. moving your finger
// down (*positive* direction along y axis) causes the vertical scroll offset
// to *decrease* as the page follows your finger.
ScreenPoint displacement = aStartPoint - aEndPoint;
ParentLayerPoint displacement = aStartPoint - aEndPoint;
ScreenPoint overscroll; // will be used outside monitor block
ParentLayerPoint overscroll; // will be used outside monitor block
{
ReentrantMonitorAutoEnter lock(mMonitor);
ScreenPoint adjustedDisplacement;
ParentLayerPoint adjustedDisplacement;
bool xChanged = mX.AdjustDisplacement(displacement.x, adjustedDisplacement.x, overscroll.x);
bool yChanged = mY.AdjustDisplacement(displacement.y, adjustedDisplacement.y, overscroll.y);
if (xChanged || yChanged) {
@ -1932,7 +1921,7 @@ bool AsyncPanZoomController::AttemptScroll(const ScreenPoint& aStartPoint,
return OverscrollForPanning(overscroll, aOverscrollHandoffState.mPanDistance);
}
bool AsyncPanZoomController::OverscrollForPanning(ScreenPoint aOverscroll,
bool AsyncPanZoomController::OverscrollForPanning(ParentLayerPoint aOverscroll,
const ScreenPoint& aPanDistance) {
// Only allow entering overscroll along an axis if the pan distance along
// that axis is greater than the pan distance along the other axis by a
@ -1949,7 +1938,7 @@ bool AsyncPanZoomController::OverscrollForPanning(ScreenPoint aOverscroll,
return OverscrollBy(aOverscroll);
}
bool AsyncPanZoomController::OverscrollBy(const ScreenPoint& aOverscroll) {
bool AsyncPanZoomController::OverscrollBy(const ParentLayerPoint& aOverscroll) {
if (!gfxPrefs::APZOverscrollEnabled()) {
return false;
}
@ -1986,7 +1975,7 @@ nsRefPtr<const OverscrollHandoffChain> AsyncPanZoomController::BuildOverscrollHa
return result;
}
void AsyncPanZoomController::AcceptFling(const ScreenPoint& aVelocity,
void AsyncPanZoomController::AcceptFling(const ParentLayerPoint& aVelocity,
const nsRefPtr<const OverscrollHandoffChain>& aOverscrollHandoffChain,
bool aHandoff) {
// We may have a pre-existing velocity for whatever reason (for example,
@ -1999,7 +1988,7 @@ void AsyncPanZoomController::AcceptFling(const ScreenPoint& aVelocity,
!aHandoff)); // only apply acceleration if this is an initial fling
}
bool AsyncPanZoomController::AttemptFling(ScreenPoint aVelocity,
bool AsyncPanZoomController::AttemptFling(ParentLayerPoint aVelocity,
const nsRefPtr<const OverscrollHandoffChain>& aOverscrollHandoffChain,
bool aHandoff) {
// If we are pannable, take over the fling ourselves.
@ -2013,7 +2002,7 @@ bool AsyncPanZoomController::AttemptFling(ScreenPoint aVelocity,
return false;
}
void AsyncPanZoomController::HandleFlingOverscroll(const ScreenPoint& aVelocity,
void AsyncPanZoomController::HandleFlingOverscroll(const ParentLayerPoint& aVelocity,
const nsRefPtr<const OverscrollHandoffChain>& aOverscrollHandoffChain) {
APZCTreeManager* treeManagerLocal = GetApzcTreeManager();
if (!(treeManagerLocal && treeManagerLocal->DispatchFling(this,
@ -2028,7 +2017,7 @@ void AsyncPanZoomController::HandleFlingOverscroll(const ScreenPoint& aVelocity,
}
}
void AsyncPanZoomController::HandleSmoothScrollOverscroll(const ScreenPoint& aVelocity) {
void AsyncPanZoomController::HandleSmoothScrollOverscroll(const ParentLayerPoint& aVelocity) {
// We must call BuildOverscrollHandoffChain from this deferred callback
// function in order to avoid a deadlock when acquiring the tree lock.
HandleFlingOverscroll(aVelocity, BuildOverscrollHandoffChain());
@ -2037,7 +2026,7 @@ void AsyncPanZoomController::HandleSmoothScrollOverscroll(const ScreenPoint& aVe
void AsyncPanZoomController::StartSmoothScroll() {
SetState(SMOOTH_SCROLL);
nsPoint initialPosition = CSSPoint::ToAppUnits(mFrameMetrics.GetScrollOffset());
// Cast velocity from ScreenPoints/ms to CSSPoints/ms then convert to
// Cast velocity from ParentLayerPoints/ms to CSSPoints/ms then convert to
// appunits/second
nsPoint initialVelocity = CSSPoint::ToAppUnits(CSSPoint(mX.GetVelocity(),
mY.GetVelocity())) * 1000.0f;
@ -2050,13 +2039,13 @@ void AsyncPanZoomController::StartSmoothScroll() {
gfxPrefs::ScrollBehaviorDampingRatio()));
}
void AsyncPanZoomController::StartOverscrollAnimation(const ScreenPoint& aVelocity) {
void AsyncPanZoomController::StartOverscrollAnimation(const ParentLayerPoint& aVelocity) {
SetState(OVERSCROLL_ANIMATION);
StartAnimation(new OverscrollAnimation(*this, aVelocity));
}
bool AsyncPanZoomController::CallDispatchScroll(const ScreenPoint& aStartPoint,
const ScreenPoint& aEndPoint,
bool AsyncPanZoomController::CallDispatchScroll(const ParentLayerPoint& aStartPoint,
const ParentLayerPoint& aEndPoint,
OverscrollHandoffState& aOverscrollHandoffState) {
// Make a local copy of the tree manager pointer and check if it's not
// null before calling DispatchScroll(). This is necessary because
@ -2068,13 +2057,13 @@ bool AsyncPanZoomController::CallDispatchScroll(const ScreenPoint& aStartPoint,
}
void AsyncPanZoomController::TrackTouch(const MultiTouchInput& aEvent) {
ScreenPoint prevTouchPoint(mX.GetPos(), mY.GetPos());
ScreenPoint touchPoint = GetFirstTouchScreenPoint(aEvent);
ParentLayerPoint prevTouchPoint(mX.GetPos(), mY.GetPos());
ParentLayerPoint touchPoint = GetFirstTouchPoint(aEvent);
ScreenPoint panDistance(mX.PanDistance(touchPoint.x),
mY.PanDistance(touchPoint.y));
const ScreenPoint panStart = PanStart();
ToGlobalScreenCoordinates(&panDistance, panStart);
ScreenPoint panDistance = ToScreenCoordinates(
ParentLayerPoint(mX.PanDistance(touchPoint.x),
mY.PanDistance(touchPoint.y)),
PanStart());
HandlePanningUpdate(panDistance);
UpdateWithTouchAtDevicePoint(aEvent);
@ -2086,8 +2075,8 @@ void AsyncPanZoomController::TrackTouch(const MultiTouchInput& aEvent) {
}
}
ScreenPoint AsyncPanZoomController::GetFirstTouchScreenPoint(const MultiTouchInput& aEvent) {
return ((SingleTouchData&)aEvent.mTouches[0]).mScreenPoint;
ParentLayerPoint AsyncPanZoomController::GetFirstTouchPoint(const MultiTouchInput& aEvent) {
return ((SingleTouchData&)aEvent.mTouches[0]).mLocalScreenPoint;
}
void AsyncPanZoomController::StartAnimation(AsyncPanZoomAnimation* aAnimation)
@ -2200,7 +2189,7 @@ RedistributeDisplayPortExcess(CSSSize& aDisplayPortSize,
/* static */
const ScreenMargin AsyncPanZoomController::CalculatePendingDisplayPort(
const FrameMetrics& aFrameMetrics,
const ScreenPoint& aVelocity,
const ParentLayerPoint& aVelocity,
double aEstimatedPaintDuration)
{
CSSSize compositionSize = aFrameMetrics.CalculateBoundedCompositedSizeInCssPixels();
@ -2284,7 +2273,7 @@ bool AsyncPanZoomController::SnapBackIfOverscrolled() {
ReentrantMonitorAutoEnter lock(mMonitor);
if (IsOverscrolled()) {
APZC_LOG("%p is overscrolled, starting snap-back\n", this);
StartOverscrollAnimation(ScreenPoint(0, 0));
StartOverscrollAnimation(ParentLayerPoint(0, 0));
return true;
}
return false;
@ -2439,7 +2428,7 @@ Matrix4x4 AsyncPanZoomController::GetOverscrollTransform() const {
// Compute the amount of the stretch along each axis. The stretch is
// proportional to the amount by which we are overscrolled along that axis.
ScreenSize compositionSize(mX.GetCompositionLength(), mY.GetCompositionLength());
ParentLayerSize compositionSize(mX.GetCompositionLength(), mY.GetCompositionLength());
float scaleX = 1 + kStretchFactor * fabsf(mX.GetOverscroll()) / mX.GetCompositionLength();
float scaleY = 1 + kStretchFactor * fabsf(mY.GetOverscroll()) / mY.GetCompositionLength();
@ -2457,19 +2446,19 @@ Matrix4x4 AsyncPanZoomController::GetOverscrollTransform() const {
// are overscrolling at the top or on the left, but if we are overscrolling
// at the bottom or on the right, we want the bottom or right edge of the
// content to stay in place instead, so we add a translation to compensate.
ScreenPoint translation;
ParentLayerPoint translation;
bool overscrolledOnRight = (mX.GetOverscroll() > 0 && !mX.IsInUnderscroll())
|| (mX.GetOverscroll() < 0 && mX.IsInUnderscroll());
if (overscrolledOnRight) {
ScreenCoord overscrolledCompositionWidth = scaleX * compositionSize.width;
ScreenCoord extraCompositionWidth = overscrolledCompositionWidth - compositionSize.width;
ParentLayerCoord overscrolledCompositionWidth = scaleX * compositionSize.width;
ParentLayerCoord extraCompositionWidth = overscrolledCompositionWidth - compositionSize.width;
translation.x = -extraCompositionWidth;
}
bool overscrolledAtBottom = (mY.GetOverscroll() > 0 && !mY.IsInUnderscroll())
|| (mY.GetOverscroll() < 0 && mY.IsInUnderscroll());
if (overscrolledAtBottom) {
ScreenCoord overscrolledCompositionHeight = scaleY * compositionSize.height;
ScreenCoord extraCompositionHeight = overscrolledCompositionHeight - compositionSize.height;
ParentLayerCoord overscrolledCompositionHeight = scaleY * compositionSize.height;
ParentLayerCoord extraCompositionHeight = overscrolledCompositionHeight - compositionSize.height;
translation.y = -extraCompositionHeight;
}
@ -2551,7 +2540,7 @@ bool AsyncPanZoomController::AdvanceAnimations(const TimeStamp& aSampleTime)
}
void AsyncPanZoomController::SampleContentTransformForFrame(ViewTransform* aOutTransform,
ScreenPoint& aScrollOffset)
ParentLayerPoint& aScrollOffset)
{
ReentrantMonitorAutoEnter lock(mMonitor);
@ -2588,25 +2577,25 @@ ViewTransform AsyncPanZoomController::GetCurrentAsyncTransform() const {
}
}
ParentLayerToScreenScale scale = mFrameMetrics.mPresShellResolution // non-transient portion
* mFrameMetrics.GetAsyncZoom(); // transient portion
ScreenPoint translation = (currentScrollOffset - lastPaintScrollOffset)
* mFrameMetrics.GetZoom();
LayerToParentLayerScale scale(mFrameMetrics.mPresShellResolution // non-transient portion
* mFrameMetrics.GetAsyncZoom().scale); // transient portion
ParentLayerPoint translation = (currentScrollOffset - lastPaintScrollOffset)
* mFrameMetrics.GetZoom();
return ViewTransform(scale, -translation);
}
Matrix4x4 AsyncPanZoomController::GetNontransientAsyncTransform() const {
ReentrantMonitorAutoEnter lock(mMonitor);
return Matrix4x4::Scaling(mLastContentPaintMetrics.mPresShellResolution.scale,
mLastContentPaintMetrics.mPresShellResolution.scale,
return Matrix4x4::Scaling(mLastContentPaintMetrics.mPresShellResolution,
mLastContentPaintMetrics.mPresShellResolution,
1.0f);
}
Matrix4x4 AsyncPanZoomController::GetTransformToLastDispatchedPaint() const {
ReentrantMonitorAutoEnter lock(mMonitor);
ParentLayerPoint scrollChange =
LayerPoint scrollChange =
(mLastContentPaintMetrics.GetScrollOffset() - mLastDispatchedPaintMetrics.GetScrollOffset())
* mLastContentPaintMetrics.mDevPixelsPerCSSPixel
* mLastContentPaintMetrics.mCumulativeResolution
@ -2647,7 +2636,6 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetri
bool isDefault = mFrameMetrics.IsDefault();
mLastContentPaintMetrics = aLayerMetrics;
UpdateTransformScale();
mFrameMetrics.SetMayHaveTouchListeners(aLayerMetrics.GetMayHaveTouchListeners());
mFrameMetrics.SetMayHaveTouchCaret(aLayerMetrics.GetMayHaveTouchCaret());
@ -2721,8 +2709,8 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetri
// since the repaint request.
float totalResolutionChange = aLayerMetrics.mCumulativeResolution.scale
/ mFrameMetrics.mCumulativeResolution.scale;
float presShellResolutionChange = aLayerMetrics.mPresShellResolution.scale
/ mFrameMetrics.mPresShellResolution.scale;
float presShellResolutionChange = aLayerMetrics.mPresShellResolution
/ mFrameMetrics.mPresShellResolution;
mFrameMetrics.ZoomBy(totalResolutionChange / presShellResolutionChange);
} else {
// Take the new zoom as either device scale or composition width or both
@ -2821,7 +2809,7 @@ void AsyncPanZoomController::ZoomToRect(CSSRect aRect) {
ParentLayerRect compositionBounds = mFrameMetrics.mCompositionBounds;
CSSRect cssPageRect = mFrameMetrics.mScrollableRect;
CSSPoint scrollOffset = mFrameMetrics.GetScrollOffset();
CSSToParentLayerScale currentZoom = mFrameMetrics.GetZoomToParent();
CSSToParentLayerScale currentZoom = mFrameMetrics.GetZoom();
CSSToParentLayerScale targetZoom;
// The minimum zoom to prevent over-zoom-out.
@ -2829,10 +2817,10 @@ void AsyncPanZoomController::ZoomToRect(CSSRect aRect) {
// then the CSS content rect, in layers pixels, will be smaller than the
// composition bounds. If this happens, we can't fill the target composited
// area with this frame.
CSSToParentLayerScale localMinZoom(std::max((mZoomConstraints.mMinZoom * mFrameMetrics.mTransformScale).scale,
CSSToParentLayerScale localMinZoom(std::max(mZoomConstraints.mMinZoom.scale,
std::max(compositionBounds.width / cssPageRect.width,
compositionBounds.height / cssPageRect.height)));
CSSToParentLayerScale localMaxZoom = mZoomConstraints.mMaxZoom * mFrameMetrics.mTransformScale;
CSSToParentLayerScale localMaxZoom = mZoomConstraints.mMaxZoom;
if (!aRect.IsEmpty()) {
// Intersect the zoom-to-rect to the CSS rect to make sure it fits.
@ -2864,7 +2852,7 @@ void AsyncPanZoomController::ZoomToRect(CSSRect aRect) {
targetZoom.scale = clamped(targetZoom.scale, localMinZoom.scale, localMaxZoom.scale);
FrameMetrics endZoomToMetrics = mFrameMetrics;
endZoomToMetrics.SetZoom(targetZoom / mFrameMetrics.mTransformScale);
endZoomToMetrics.SetZoom(targetZoom);
// Adjust the zoomToRect to a sensible position to prevent overscrolling.
CSSSize sizeAfterZoom = endZoomToMetrics.CalculateCompositedSizeInCssPixels();
@ -2883,7 +2871,7 @@ void AsyncPanZoomController::ZoomToRect(CSSRect aRect) {
endZoomToMetrics.SetScrollOffset(aRect.TopLeft());
endZoomToMetrics.SetDisplayPortMargins(
CalculatePendingDisplayPort(endZoomToMetrics,
ScreenPoint(0,0),
ParentLayerPoint(0,0),
0));
endZoomToMetrics.SetUseDisplayPortMargins();
@ -3108,19 +3096,5 @@ void AsyncPanZoomController::ShareCompositorFrameMetrics() {
}
}
ParentLayerPoint AsyncPanZoomController::ToParentLayerCoords(const ScreenPoint& aPoint)
{
// The parent layer pixel space and the screen space for a given layer are the
// same as of bug 1052063. FIXME: Unify these two coordinate systems.
return ParentLayerPoint(aPoint.x, aPoint.y);
}
void AsyncPanZoomController::UpdateTransformScale()
{
// The parent layer pixel space and the screen space for a given layer are the
// same as of bug 1052063. FIXME: Unify these two coordinate systems.
mFrameMetrics.mTransformScale.scale = 1;
}
}
}

View File

@ -90,9 +90,10 @@ public:
* device DPI, before we start panning the screen. This is to prevent us from
* accidentally processing taps as touch moves, and from very short/accidental
* touches moving the screen.
* Note: this distance is in global screen coordinates.
* Note: It's an abuse of the 'Coord' class to use it to represent a 2D
* distance, but it's the closest thing we currently have.
*/
static float GetTouchStartTolerance();
static ScreenCoord GetTouchStartTolerance();
AsyncPanZoomController(uint64_t aLayersId,
APZCTreeManager* aTreeManager,
@ -162,7 +163,7 @@ public:
* out parameter.
*/
void SampleContentTransformForFrame(ViewTransform* aOutTransform,
ScreenPoint& aScrollOffset);
ParentLayerPoint& aScrollOffset);
/**
* Return a visual effect that reflects this apzc's
@ -247,7 +248,7 @@ public:
*/
static const ScreenMargin CalculatePendingDisplayPort(
const FrameMetrics& aFrameMetrics,
const ScreenPoint& aVelocity,
const ParentLayerPoint& aVelocity,
double aEstimatedPaintDuration);
/**
@ -335,25 +336,25 @@ public:
/**
* Convert the vector |aVector|, rooted at the point |aAnchor|, from
* this APZC's local screen coordinates into global screen coordinates.
* this APZC's ParentLayer coordinates into screen coordinates.
* The anchor is necessary because with 3D tranforms, the location of the
* vector can affect the result of the transform.
* To respect the lock ordering, mMonitor must NOT be held when calling
* this function (since this function acquires the tree lock).
*/
void ToGlobalScreenCoordinates(ScreenPoint* aVector,
const ScreenPoint& aAnchor) const;
ScreenPoint ToScreenCoordinates(const ParentLayerPoint& aVector,
const ParentLayerPoint& aAnchor) const;
/**
* Convert the vector |aVector|, rooted at the point |aAnchor|, from
* global screen coordinates into this APZC's local screen coordinates .
* screen coordinates into this APZC's ParentLayer coordinates.
* The anchor is necessary because with 3D tranforms, the location of the
* vector can affect the result of the transform.
* To respect the lock ordering, mMonitor must NOT be held when calling
* this function (since this function acquires the tree lock).
*/
void ToLocalScreenCoordinates(ScreenPoint* aVector,
const ScreenPoint& aAnchor) const;
ParentLayerPoint ToParentLayerCoordinates(const ScreenPoint& aVector,
const ScreenPoint& aAnchor) const;
protected:
// Protected destructor, to discourage deletion outside of Release():
@ -471,31 +472,29 @@ protected:
* the distance between the current position and the initial position of the
* current touch (this only makes sense if a touch is currently happening and
* OnTouchMove() or the equivalent for pan gestures is being invoked).
* Note: This function returns a distance in global screen coordinates,
* not the local screen coordinates of this APZC.
* Note: It's an abuse of the 'Coord' class to use it to represent a 2D
* distance, but it's the closest thing we currently have.
*/
float PanDistance() const;
ScreenCoord PanDistance() const;
/**
* Gets the start point of the current touch.
* Like PanDistance(), this only makes sense if a touch is currently
* happening and OnTouchMove() or the equivalent for pan gestures is
* being invoked.
* Unlikely PanDistance(), this function returns a point in local screen
* coordinates.
*/
ScreenPoint PanStart() const;
ParentLayerPoint PanStart() const;
/**
* Gets a vector of the velocities of each axis.
*/
const ScreenPoint GetVelocityVector() const;
const ParentLayerPoint GetVelocityVector() const;
/**
* Gets the first touch point from a MultiTouchInput. This gets only
* the first one and assumes the rest are either missing or not relevant.
*/
ScreenPoint GetFirstTouchScreenPoint(const MultiTouchInput& aEvent);
ParentLayerPoint GetFirstTouchPoint(const MultiTouchInput& aEvent);
/**
* Sets the panning state basing on the pan direction angle and current touch-action value.
@ -509,7 +508,6 @@ protected:
/**
* Update the panning state and axis locks.
* Note: |aDelta| is expected to be in global screen coordinates.
*/
void HandlePanningUpdate(const ScreenPoint& aDelta);
@ -586,7 +584,7 @@ protected:
* NOTE: This must be converted to CSSPoint relative to the child
* document before sending over IPC.
*/
bool ConvertToGecko(const ScreenPoint& aPoint, CSSPoint* aOut);
bool ConvertToGecko(const ParentLayerPoint& aPoint, CSSPoint* aOut);
enum AxisLockMode {
FREE, /* No locking at all */
@ -596,18 +594,8 @@ protected:
static AxisLockMode GetAxisLockMode();
// Convert a point from local screen coordinates to parent layer coordinates.
// This is a common operation as inputs from the tree manager are in screen
// coordinates but the composition bounds is in parent layer coordinates.
ParentLayerPoint ToParentLayerCoords(const ScreenPoint& aPoint);
// Update mFrameMetrics.mTransformScale. This should be called whenever
// our CSS transform or the non-transient part of our async transform
// changes, as it corresponds to the scale portion of those transforms.
void UpdateTransformScale();
// Helper function for OnSingleTapUp() and OnSingleTapConfirmed().
nsEventStatus GenerateSingleTap(const ScreenIntPoint& aPoint, mozilla::Modifiers aModifiers);
nsEventStatus GenerateSingleTap(const ParentLayerPoint& aPoint, mozilla::Modifiers aModifiers);
// Common processing at the end of a touch block.
void OnTouchEndOrCancel();
@ -824,7 +812,7 @@ public:
* APZC, and determines whether acceleration is applied to the
* fling.
*/
bool AttemptFling(ScreenPoint aVelocity,
bool AttemptFling(ParentLayerPoint aVelocity,
const nsRefPtr<const OverscrollHandoffChain>& aOverscrollHandoffChain,
bool aHandoff);
@ -833,7 +821,7 @@ private:
friend class OverscrollAnimation;
friend class SmoothScrollAnimation;
// The initial velocity of the most recent fling.
ScreenPoint mLastFlingVelocity;
ParentLayerPoint mLastFlingVelocity;
// The time at which the most recent fling started.
TimeStamp mLastFlingTime;
@ -842,18 +830,18 @@ private:
// The overscroll is handled by trying to hand the fling off to an APZC
// later in the handoff chain, or if there are no takers, continuing the
// fling and entering an overscrolled state.
void HandleFlingOverscroll(const ScreenPoint& aVelocity,
void HandleFlingOverscroll(const ParentLayerPoint& aVelocity,
const nsRefPtr<const OverscrollHandoffChain>& aOverscrollHandoffChain);
void HandleSmoothScrollOverscroll(const ScreenPoint& aVelocity);
void HandleSmoothScrollOverscroll(const ParentLayerPoint& aVelocity);
// Helper function used by TakeOverFling() and HandleFlingOverscroll().
void AcceptFling(const ScreenPoint& aVelocity,
void AcceptFling(const ParentLayerPoint& aVelocity,
const nsRefPtr<const OverscrollHandoffChain>& aOverscrollHandoffChain,
bool aHandoff);
// Start an overscroll animation with the given initial velocity.
void StartOverscrollAnimation(const ScreenPoint& aVelocity);
void StartOverscrollAnimation(const ParentLayerPoint& aVelocity);
void StartSmoothScroll();
@ -944,7 +932,7 @@ public:
* state). If this returns false, the caller APZC knows that it should enter
* an overscrolled state itself if it can.
*/
bool AttemptScroll(const ScreenPoint& aStartPoint, const ScreenPoint& aEndPoint,
bool AttemptScroll(const ParentLayerPoint& aStartPoint, const ParentLayerPoint& aEndPoint,
OverscrollHandoffState& aOverscrollHandoffState);
void FlushRepaintForOverscrollHandoff();
@ -982,8 +970,8 @@ private:
* Guards against the case where the APZC is being concurrently destroyed
* (and thus mTreeManager is being nulled out).
*/
bool CallDispatchScroll(const ScreenPoint& aStartPoint,
const ScreenPoint& aEndPoint,
bool CallDispatchScroll(const ParentLayerPoint& aStartPoint,
const ParentLayerPoint& aEndPoint,
OverscrollHandoffState& aOverscrollHandoffState);
/**
@ -991,7 +979,7 @@ private:
* around OverscrollBy() that also implements restrictions on entering
* overscroll based on the pan angle.
*/
bool OverscrollForPanning(ScreenPoint aOverscroll,
bool OverscrollForPanning(ParentLayerPoint aOverscroll,
const ScreenPoint& aPanDistance);
/**
@ -1000,7 +988,7 @@ private:
* and the function returns true.
* Otherwise, nothing happens and the function return false.
*/
bool OverscrollBy(const ScreenPoint& aOverscroll);
bool OverscrollBy(const ParentLayerPoint& aOverscroll);
/* ===================================================================

View File

@ -42,13 +42,19 @@ Axis::Axis(AsyncPanZoomController* aAsyncPanZoomController)
{
}
float Axis::ToLocalVelocity(float aVelocityInchesPerMs) {
ScreenPoint aVelocityPoint = MakePoint(aVelocityInchesPerMs * APZCTreeManager::GetDPI());
mAsyncPanZoomController->ToLocalScreenCoordinates(&aVelocityPoint, mAsyncPanZoomController->PanStart());
return aVelocityPoint.Length();
float Axis::ToLocalVelocity(float aVelocityInchesPerMs) const {
ScreenPoint velocity = MakePoint(aVelocityInchesPerMs * APZCTreeManager::GetDPI());
// Use ToScreenCoordinates() to convert a point rather than a vector by
// treating the point as a vector, and using (0, 0) as the anchor.
ScreenPoint panStart = mAsyncPanZoomController->ToScreenCoordinates(
mAsyncPanZoomController->PanStart(),
ParentLayerPoint());
ParentLayerPoint localVelocity =
mAsyncPanZoomController->ToParentLayerCoordinates(velocity, panStart);
return localVelocity.Length();
}
void Axis::UpdateWithTouchAtDevicePoint(ScreenCoord aPos, uint32_t aTimestampMs) {
void Axis::UpdateWithTouchAtDevicePoint(ParentLayerCoord aPos, uint32_t aTimestampMs) {
// mVelocityQueue is controller-thread only
AsyncPanZoomController::AssertOnControllerThread();
@ -98,16 +104,16 @@ void Axis::UpdateWithTouchAtDevicePoint(ScreenCoord aPos, uint32_t aTimestampMs)
}
}
void Axis::StartTouch(ScreenCoord aPos, uint32_t aTimestampMs) {
void Axis::StartTouch(ParentLayerCoord aPos, uint32_t aTimestampMs) {
mStartPos = aPos;
mPos = aPos;
mPosTimeMs = aTimestampMs;
mAxisLocked = false;
}
bool Axis::AdjustDisplacement(ScreenCoord aDisplacement,
/* ScreenCoord */ float& aDisplacementOut,
/* ScreenCoord */ float& aOverscrollAmountOut)
bool Axis::AdjustDisplacement(ParentLayerCoord aDisplacement,
/* ParentLayerCoord */ float& aDisplacementOut,
/* ParentLayerCoord */ float& aOverscrollAmountOut)
{
if (mAxisLocked) {
aOverscrollAmountOut = 0;
@ -115,10 +121,10 @@ bool Axis::AdjustDisplacement(ScreenCoord aDisplacement,
return false;
}
ScreenCoord displacement = aDisplacement;
ParentLayerCoord displacement = aDisplacement;
// First consume any overscroll in the opposite direction along this axis.
ScreenCoord consumedOverscroll = 0;
ParentLayerCoord consumedOverscroll = 0;
if (mOverscroll > 0 && aDisplacement < 0) {
consumedOverscroll = std::min(mOverscroll, -aDisplacement);
} else if (mOverscroll < 0 && aDisplacement > 0) {
@ -140,7 +146,7 @@ bool Axis::AdjustDisplacement(ScreenCoord aDisplacement,
return fabsf(consumedOverscroll) > EPSILON;
}
ScreenCoord Axis::ApplyResistance(ScreenCoord aRequestedOverscroll) const {
ParentLayerCoord Axis::ApplyResistance(ParentLayerCoord aRequestedOverscroll) const {
// 'resistanceFactor' is a value between 0 and 1, which:
// - tends to 1 as the existing overscroll tends to 0
// - tends to 0 as the existing overscroll tends to the composition length
@ -148,10 +154,10 @@ ScreenCoord Axis::ApplyResistance(ScreenCoord aRequestedOverscroll) const {
// factor; this should prevent overscrolling by more than the composition
// length.
float resistanceFactor = 1 - fabsf(mOverscroll) / GetCompositionLength();
return resistanceFactor < 0 ? ScreenCoord(0) : aRequestedOverscroll * resistanceFactor;
return resistanceFactor < 0 ? ParentLayerCoord(0) : aRequestedOverscroll * resistanceFactor;
}
void Axis::OverscrollBy(ScreenCoord aOverscroll) {
void Axis::OverscrollBy(ParentLayerCoord aOverscroll) {
MOZ_ASSERT(CanScroll());
aOverscroll = ApplyResistance(aOverscroll);
if (aOverscroll > 0) {
@ -178,7 +184,7 @@ void Axis::OverscrollBy(ScreenCoord aOverscroll) {
mOverscroll += aOverscroll;
}
ScreenCoord Axis::GetOverscroll() const {
ParentLayerCoord Axis::GetOverscroll() const {
return mOverscroll;
}
@ -250,15 +256,15 @@ void Axis::ClearOverscroll() {
mOverscroll = 0;
}
ScreenCoord Axis::PanStart() const {
ParentLayerCoord Axis::PanStart() const {
return mStartPos;
}
ScreenCoord Axis::PanDistance() const {
ParentLayerCoord Axis::PanDistance() const {
return fabs(mPos - mStartPos);
}
ScreenCoord Axis::PanDistance(ScreenCoord aPos) const {
ParentLayerCoord Axis::PanDistance(ParentLayerCoord aPos) const {
return fabs(aPos - mStartPos);
}
@ -314,9 +320,9 @@ bool Axis::FlingApplyFrictionOrCancel(const TimeDuration& aDelta,
return true;
}
ScreenCoord Axis::DisplacementWillOverscrollAmount(ScreenCoord aDisplacement) const {
ScreenCoord newOrigin = GetOrigin() + aDisplacement;
ScreenCoord newCompositionEnd = GetCompositionEnd() + aDisplacement;
ParentLayerCoord Axis::DisplacementWillOverscrollAmount(ParentLayerCoord aDisplacement) const {
ParentLayerCoord newOrigin = GetOrigin() + aDisplacement;
ParentLayerCoord newCompositionEnd = GetCompositionEnd() + aDisplacement;
// If the current pan plus a displacement takes the window to the left of or
// above the current page rect.
bool minus = newOrigin < GetPageStart();
@ -338,11 +344,11 @@ ScreenCoord Axis::DisplacementWillOverscrollAmount(ScreenCoord aDisplacement) co
}
CSSCoord Axis::ScaleWillOverscrollAmount(float aScale, CSSCoord aFocus) const {
// Internally, do computations in Screen coordinates *before* the scale is
// applied.
CSSToScreenScale zoom = GetFrameMetrics().GetZoom();
ScreenCoord focus = aFocus * zoom;
ScreenCoord originAfterScale = (GetOrigin() + focus) - (focus / aScale);
// Internally, do computations in ParentLayer coordinates *before* the scale
// is applied.
CSSToParentLayerScale zoom = GetFrameMetrics().GetZoom();
ParentLayerCoord focus = aFocus * zoom;
ParentLayerCoord originAfterScale = (GetOrigin() + focus) - (focus / aScale);
bool both = ScaleWillOverscrollBothSides(aScale);
bool minus = GetPageStart() - originAfterScale > COORDINATE_EPSILON;
@ -370,39 +376,37 @@ void Axis::SetVelocity(float aVelocity) {
mVelocity = aVelocity;
}
ScreenCoord Axis::GetCompositionEnd() const {
ParentLayerCoord Axis::GetCompositionEnd() const {
return GetOrigin() + GetCompositionLength();
}
ScreenCoord Axis::GetPageEnd() const {
ParentLayerCoord Axis::GetPageEnd() const {
return GetPageStart() + GetPageLength();
}
ScreenCoord Axis::GetOrigin() const {
ScreenPoint origin = GetFrameMetrics().GetScrollOffset() * GetFrameMetrics().GetZoom();
ParentLayerCoord Axis::GetOrigin() const {
ParentLayerPoint origin = GetFrameMetrics().GetScrollOffset() * GetFrameMetrics().GetZoom();
return GetPointOffset(origin);
}
ScreenCoord Axis::GetCompositionLength() const {
return GetRectLength(GetFrameMetrics().mCompositionBounds / GetFrameMetrics().mTransformScale);
ParentLayerCoord Axis::GetCompositionLength() const {
return GetRectLength(GetFrameMetrics().mCompositionBounds);
}
ScreenCoord Axis::GetPageStart() const {
ScreenRect pageRect = GetFrameMetrics().GetExpandedScrollableRect() * GetFrameMetrics().GetZoom();
ParentLayerCoord Axis::GetPageStart() const {
ParentLayerRect pageRect = GetFrameMetrics().GetExpandedScrollableRect() * GetFrameMetrics().GetZoom();
return GetRectOffset(pageRect);
}
ScreenCoord Axis::GetPageLength() const {
ScreenRect pageRect = GetFrameMetrics().GetExpandedScrollableRect() * GetFrameMetrics().GetZoom();
ParentLayerCoord Axis::GetPageLength() const {
ParentLayerRect pageRect = GetFrameMetrics().GetExpandedScrollableRect() * GetFrameMetrics().GetZoom();
return GetRectLength(pageRect);
}
bool Axis::ScaleWillOverscrollBothSides(float aScale) const {
const FrameMetrics& metrics = GetFrameMetrics();
ScreenToParentLayerScale scale(metrics.mTransformScale.scale * aScale);
ScreenRect screenCompositionBounds = metrics.mCompositionBounds / scale;
ParentLayerRect screenCompositionBounds = metrics.mCompositionBounds
/ ParentLayerToParentLayerScale(aScale);
return GetRectLength(screenCompositionBounds) - GetPageLength() > COORDINATE_EPSILON;
}
@ -417,17 +421,17 @@ AxisX::AxisX(AsyncPanZoomController* aAsyncPanZoomController)
}
ScreenCoord AxisX::GetPointOffset(const ScreenPoint& aPoint) const
ParentLayerCoord AxisX::GetPointOffset(const ParentLayerPoint& aPoint) const
{
return aPoint.x;
}
ScreenCoord AxisX::GetRectLength(const ScreenRect& aRect) const
ParentLayerCoord AxisX::GetRectLength(const ParentLayerRect& aRect) const
{
return aRect.width;
}
ScreenCoord AxisX::GetRectOffset(const ScreenRect& aRect) const
ParentLayerCoord AxisX::GetRectOffset(const ParentLayerRect& aRect) const
{
return aRect.x;
}
@ -443,17 +447,17 @@ AxisY::AxisY(AsyncPanZoomController* aAsyncPanZoomController)
}
ScreenCoord AxisY::GetPointOffset(const ScreenPoint& aPoint) const
ParentLayerCoord AxisY::GetPointOffset(const ParentLayerPoint& aPoint) const
{
return aPoint.y;
}
ScreenCoord AxisY::GetRectLength(const ScreenRect& aRect) const
ParentLayerCoord AxisY::GetRectLength(const ParentLayerRect& aRect) const
{
return aRect.height;
}
ScreenCoord AxisY::GetRectOffset(const ScreenRect& aRect) const
ParentLayerCoord AxisY::GetRectOffset(const ParentLayerRect& aRect) const
{
return aRect.y;
}

View File

@ -41,13 +41,13 @@ public:
* Notify this Axis that a new touch has been received, including a timestamp
* for when the touch was received. This triggers a recalculation of velocity.
*/
void UpdateWithTouchAtDevicePoint(ScreenCoord aPos, uint32_t aTimestampMs);
void UpdateWithTouchAtDevicePoint(ParentLayerCoord aPos, uint32_t aTimestampMs);
/**
* 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.
*/
void StartTouch(ScreenCoord aPos, uint32_t aTimestampMs);
void StartTouch(ParentLayerCoord aPos, uint32_t aTimestampMs);
/**
* Notify this Axis that a touch has ended gracefully. This may perform
@ -73,18 +73,18 @@ public:
* displacement, and the function returns true iff internal overscroll amounts
* were changed.
*/
bool AdjustDisplacement(ScreenCoord aDisplacement,
/* ScreenCoord */ float& aDisplacementOut,
/* ScreenCoord */ float& aOverscrollAmountOut);
bool AdjustDisplacement(ParentLayerCoord aDisplacement,
/* ParentLayerCoord */ float& aDisplacementOut,
/* ParentLayerCoord */ float& aOverscrollAmountOut);
/**
* Overscrolls this axis by the requested amount in the requested direction.
* The axis must be at the end of its scroll range in this direction.
*/
void OverscrollBy(ScreenCoord aOverscroll);
void OverscrollBy(ParentLayerCoord aOverscroll);
/**
* Return the amount of overscroll on this axis, in Screen pixels.
* Return the amount of overscroll on this axis, in ParentLayer pixels.
*
* If this amount is nonzero, the relevant component of
* mAsyncPanZoomController->mFrameMetrics.mScrollOffset must be at its
@ -94,7 +94,7 @@ public:
* Note that if |mInUnderscroll| is true, the interpretation of this field
* changes slightly (see below).
*/
ScreenCoord GetOverscroll() const;
ParentLayerCoord GetOverscroll() const;
/**
* Return whether the axis is in underscroll.
@ -138,20 +138,20 @@ public:
/**
* Gets the starting position of the touch supplied in StartTouch().
*/
ScreenCoord PanStart() const;
ParentLayerCoord PanStart() const;
/**
* Gets the distance between the starting position of the touch supplied in
* StartTouch() and the current touch from the last
* UpdateWithTouchAtDevicePoint().
*/
ScreenCoord PanDistance() const;
ParentLayerCoord PanDistance() const;
/**
* Gets the distance between the starting position of the touch supplied in
* StartTouch() and the supplied position.
*/
ScreenCoord PanDistance(ScreenCoord aPos) const;
ParentLayerCoord PanDistance(ParentLayerCoord aPos) const;
/**
* Applies friction during a fling, or cancels the fling if the velocity is
@ -198,7 +198,7 @@ public:
* If a displacement will overscroll the axis, this returns the amount and in
* what direction.
*/
ScreenCoord DisplacementWillOverscrollAmount(ScreenCoord aDisplacement) const;
ParentLayerCoord DisplacementWillOverscrollAmount(ParentLayerCoord aDisplacement) const;
/**
* If a scale will overscroll the axis, this returns the amount and in what
@ -209,7 +209,7 @@ public:
* relative.
*
* Note: Unlike most other functions in Axis, this functions operates in
* CSS coordinates so there is no confusion as to whether the Screen
* CSS coordinates so there is no confusion as to whether the ParentLayer
* coordinates it operates in are before or after the scale is applied.
*/
CSSCoord ScaleWillOverscrollAmount(float aScale, CSSCoord aFocus) const;
@ -223,30 +223,30 @@ public:
*/
bool ScaleWillOverscrollBothSides(float aScale) const;
ScreenCoord GetOrigin() const;
ScreenCoord GetCompositionLength() const;
ScreenCoord GetPageStart() const;
ScreenCoord GetPageLength() const;
ScreenCoord GetCompositionEnd() const;
ScreenCoord GetPageEnd() const;
ParentLayerCoord GetOrigin() const;
ParentLayerCoord GetCompositionLength() const;
ParentLayerCoord GetPageStart() const;
ParentLayerCoord GetPageLength() const;
ParentLayerCoord GetCompositionEnd() const;
ParentLayerCoord GetPageEnd() const;
ScreenCoord GetPos() const { return mPos; }
ParentLayerCoord GetPos() const { return mPos; }
virtual ScreenCoord GetPointOffset(const ScreenPoint& aPoint) const = 0;
virtual ScreenCoord GetRectLength(const ScreenRect& aRect) const = 0;
virtual ScreenCoord GetRectOffset(const ScreenRect& aRect) const = 0;
virtual ParentLayerCoord GetPointOffset(const ParentLayerPoint& aPoint) const = 0;
virtual ParentLayerCoord GetRectLength(const ParentLayerRect& aRect) const = 0;
virtual ParentLayerCoord GetRectOffset(const ParentLayerRect& aRect) const = 0;
virtual ScreenPoint MakePoint(ScreenCoord aCoord) const = 0;
protected:
ScreenCoord mPos;
ParentLayerCoord mPos;
uint32_t mPosTimeMs;
ScreenCoord mStartPos;
float mVelocity; // Units: ScreenCoords per millisecond
ParentLayerCoord mStartPos;
float mVelocity; // Units: ParentLayerCoords per millisecond
bool mAxisLocked; // Whether movement on this axis is locked.
AsyncPanZoomController* mAsyncPanZoomController;
ScreenCoord mOverscroll; // See GetOverscroll().
bool mInUnderscroll; // See IsInUnderscroll().
ParentLayerCoord mOverscroll; // See GetOverscroll().
bool mInUnderscroll; // See IsInUnderscroll().
// A queue of (timestamp, velocity) pairs; these are the historical
// velocities at the given timestamps. Timestamps are in milliseconds,
// velocities are in screen pixels per ms. This member can only be
@ -257,27 +257,27 @@ protected:
// Adjust a requested overscroll amount for resistance, yielding a smaller
// actual overscroll amount.
ScreenCoord ApplyResistance(ScreenCoord aOverscroll) const;
ParentLayerCoord ApplyResistance(ParentLayerCoord aOverscroll) const;
// Convert a velocity from global inches/ms into local ScreenCoords per ms
float ToLocalVelocity(float aVelocityInchesPerMs);
// Convert a velocity from global inches/ms into ParentLayerCoords/ms.
float ToLocalVelocity(float aVelocityInchesPerMs) const;
};
class AxisX : public Axis {
public:
explicit AxisX(AsyncPanZoomController* mAsyncPanZoomController);
virtual ScreenCoord GetPointOffset(const ScreenPoint& aPoint) const MOZ_OVERRIDE;
virtual ScreenCoord GetRectLength(const ScreenRect& aRect) const MOZ_OVERRIDE;
virtual ScreenCoord GetRectOffset(const ScreenRect& aRect) const MOZ_OVERRIDE;
virtual ParentLayerCoord GetPointOffset(const ParentLayerPoint& aPoint) const MOZ_OVERRIDE;
virtual ParentLayerCoord GetRectLength(const ParentLayerRect& aRect) const MOZ_OVERRIDE;
virtual ParentLayerCoord GetRectOffset(const ParentLayerRect& aRect) const MOZ_OVERRIDE;
virtual ScreenPoint MakePoint(ScreenCoord aCoord) const MOZ_OVERRIDE;
};
class AxisY : public Axis {
public:
explicit AxisY(AsyncPanZoomController* mAsyncPanZoomController);
virtual ScreenCoord GetPointOffset(const ScreenPoint& aPoint) const MOZ_OVERRIDE;
virtual ScreenCoord GetRectLength(const ScreenRect& aRect) const MOZ_OVERRIDE;
virtual ScreenCoord GetRectOffset(const ScreenRect& aRect) const MOZ_OVERRIDE;
virtual ParentLayerCoord GetPointOffset(const ParentLayerPoint& aPoint) const MOZ_OVERRIDE;
virtual ParentLayerCoord GetRectLength(const ParentLayerRect& aRect) const MOZ_OVERRIDE;
virtual ParentLayerCoord GetRectOffset(const ParentLayerRect& aRect) const MOZ_OVERRIDE;
virtual ScreenPoint MakePoint(ScreenCoord aCoord) const MOZ_OVERRIDE;
};

View File

@ -34,19 +34,30 @@ static const uint32_t MAX_TAP_TIME = 300;
*/
static const float PINCH_START_THRESHOLD = 35.0f;
ScreenPoint GetCurrentFocus(const MultiTouchInput& aEvent)
ParentLayerPoint GetCurrentFocus(const MultiTouchInput& aEvent)
{
const ScreenIntPoint& firstTouch = aEvent.mTouches[0].mScreenPoint,
secondTouch = aEvent.mTouches[1].mScreenPoint;
return ScreenPoint(firstTouch + secondTouch) / 2;
const ParentLayerPoint& firstTouch = aEvent.mTouches[0].mLocalScreenPoint;
const ParentLayerPoint& secondTouch = aEvent.mTouches[1].mLocalScreenPoint;
return (firstTouch + secondTouch) / 2;
}
float GetCurrentSpan(const MultiTouchInput& aEvent)
{
const ScreenIntPoint& firstTouch = aEvent.mTouches[0].mScreenPoint,
secondTouch = aEvent.mTouches[1].mScreenPoint;
ScreenIntPoint delta = secondTouch - firstTouch;
return float(NS_hypot(delta.x, delta.y));
const ParentLayerPoint& firstTouch = aEvent.mTouches[0].mLocalScreenPoint;
const ParentLayerPoint& secondTouch = aEvent.mTouches[1].mLocalScreenPoint;
ParentLayerPoint delta = secondTouch - firstTouch;
return delta.Length();
}
TapGestureInput CreateTapEvent(const MultiTouchInput& aTouch, TapGestureInput::TapGestureType aType)
{
return TapGestureInput(aType,
aTouch.mTime,
aTouch.mTimeStamp,
// Use mLocalScreenPoint as this goes directly to APZC
// without being transformed in APZCTreeManager.
aTouch.mTouches[0].mLocalScreenPoint,
aTouch.modifiers);
}
GestureEventListener::GestureEventListener(AsyncPanZoomController* aAsyncPanZoomController)
@ -127,7 +138,7 @@ nsEventStatus GestureEventListener::HandleInputTouchSingleStart()
switch (mState) {
case GESTURE_NONE:
SetState(GESTURE_FIRST_SINGLE_TOUCH_DOWN);
mTouchStartPosition = mLastTouchInput.mTouches[0].mScreenPoint;
mTouchStartPosition = mLastTouchInput.mTouches[0].mLocalScreenPoint;
CreateLongTapTimeoutTask();
CreateMaxTapTimeoutTask();
@ -200,10 +211,10 @@ nsEventStatus GestureEventListener::HandleInputTouchMultiStart()
bool GestureEventListener::MoveDistanceIsLarge()
{
const ScreenPoint start = mLastTouchInput.mTouches[0].mScreenPoint;
ScreenPoint delta = start - mTouchStartPosition;
mAsyncPanZoomController->ToGlobalScreenCoordinates(&delta, start);
return (delta.Length() > AsyncPanZoomController::GetTouchStartTolerance());
const ParentLayerPoint start = mLastTouchInput.mTouches[0].mLocalScreenPoint;
ParentLayerPoint delta = start - mTouchStartPosition;
ScreenPoint screenDelta = mAsyncPanZoomController->ToScreenCoordinates(delta, start);
return (screenDelta.Length() > AsyncPanZoomController::GetTouchStartTolerance());
}
nsEventStatus GestureEventListener::HandleInputTouchMove()
@ -314,12 +325,8 @@ nsEventStatus GestureEventListener::HandleInputTouchEnd()
case GESTURE_FIRST_SINGLE_TOUCH_DOWN: {
CancelLongTapTimeoutTask();
CancelMaxTapTimeoutTask();
TapGestureInput tapEvent(TapGestureInput::TAPGESTURE_UP,
mLastTouchInput.mTime,
mLastTouchInput.mTimeStamp,
mLastTouchInput.mTouches[0].mScreenPoint,
mLastTouchInput.modifiers);
nsEventStatus tapupStatus = mAsyncPanZoomController->HandleGestureEvent(tapEvent);
nsEventStatus tapupStatus = mAsyncPanZoomController->HandleGestureEvent(
CreateTapEvent(mLastTouchInput, TapGestureInput::TAPGESTURE_UP));
if (tapupStatus == nsEventStatus_eIgnore) {
SetState(GESTURE_FIRST_SINGLE_TOUCH_UP);
CreateMaxTapTimeoutTask();
@ -333,12 +340,8 @@ nsEventStatus GestureEventListener::HandleInputTouchEnd()
case GESTURE_SECOND_SINGLE_TOUCH_DOWN: {
CancelMaxTapTimeoutTask();
SetState(GESTURE_NONE);
TapGestureInput tapEvent(TapGestureInput::TAPGESTURE_DOUBLE,
mLastTouchInput.mTime,
mLastTouchInput.mTimeStamp,
mLastTouchInput.mTouches[0].mScreenPoint,
mLastTouchInput.modifiers);
mAsyncPanZoomController->HandleGestureEvent(tapEvent);
mAsyncPanZoomController->HandleGestureEvent(
CreateTapEvent(mLastTouchInput, TapGestureInput::TAPGESTURE_DOUBLE));
break;
}
@ -350,12 +353,8 @@ nsEventStatus GestureEventListener::HandleInputTouchEnd()
case GESTURE_LONG_TOUCH_DOWN: {
SetState(GESTURE_NONE);
TapGestureInput tapEvent(TapGestureInput::TAPGESTURE_LONG_UP,
mLastTouchInput.mTime,
mLastTouchInput.mTimeStamp,
mLastTouchInput.mTouches[0].mScreenPoint,
mLastTouchInput.modifiers);
mAsyncPanZoomController->HandleGestureEvent(tapEvent);
mAsyncPanZoomController->HandleGestureEvent(
CreateTapEvent(mLastTouchInput, TapGestureInput::TAPGESTURE_LONG_UP));
break;
}
@ -412,12 +411,8 @@ void GestureEventListener::HandleInputTimeoutLongTap()
CancelMaxTapTimeoutTask();
case GESTURE_FIRST_SINGLE_TOUCH_MAX_TAP_DOWN: {
SetState(GESTURE_LONG_TOUCH_DOWN);
TapGestureInput tapEvent(TapGestureInput::TAPGESTURE_LONG,
mLastTouchInput.mTime,
mLastTouchInput.mTimeStamp,
mLastTouchInput.mTouches[0].mScreenPoint,
mLastTouchInput.modifiers);
mAsyncPanZoomController->HandleGestureEvent(tapEvent);
mAsyncPanZoomController->HandleGestureEvent(
CreateTapEvent(mLastTouchInput, TapGestureInput::TAPGESTURE_LONG));
break;
}
default:
@ -447,12 +442,8 @@ void GestureEventListener::HandleInputTimeoutMaxTap()
void GestureEventListener::TriggerSingleTapConfirmedEvent()
{
TapGestureInput tapEvent(TapGestureInput::TAPGESTURE_CONFIRMED,
mLastTapInput.mTime,
mLastTapInput.mTimeStamp,
mLastTapInput.mTouches[0].mScreenPoint,
mLastTapInput.modifiers);
mAsyncPanZoomController->HandleGestureEvent(tapEvent);
mAsyncPanZoomController->HandleGestureEvent(
CreateTapEvent(mLastTapInput, TapGestureInput::TAPGESTURE_CONFIRMED));
}
void GestureEventListener::SetState(GestureState aState)

View File

@ -8,7 +8,7 @@
#define mozilla_layers_GestureEventListener_h
#include "InputData.h" // for MultiTouchInput, etc
#include "Units.h" // for ScreenIntPoint
#include "Units.h"
#include "mozilla/EventForwards.h" // for nsEventStatus
#include "nsAutoPtr.h" // for nsRefPtr
#include "nsISupportsImpl.h"
@ -193,7 +193,7 @@ private:
* or GESTURE_SECOND_SINGLE_TOUCH_DOWN then we're certain the gesture is
* not tap.
*/
ScreenIntPoint mTouchStartPosition;
ParentLayerPoint mTouchStartPosition;
/**
* Task used to timeout a long tap. This gets posted to the UI thread such

View File

@ -143,12 +143,10 @@ APZCCallbackHelper::UpdateRootFrame(nsIDOMWindowUtils* aUtils,
aMetrics.SetScrollOffset(actualScrollOffset);
// The pres shell resolution is updated by the the async zoom since the
// last paint. The ScreenToLayerScale(1.0f) reflects this async zoom being
// turned into a "sync" zoom during the repaint.
ParentLayerToLayerScale presShellResolution = aMetrics.mPresShellResolution
* aMetrics.GetAsyncZoom()
* ScreenToLayerScale(1.0f);
aUtils->SetResolution(presShellResolution.scale, presShellResolution.scale);
// last paint.
float presShellResolution = aMetrics.mPresShellResolution
* aMetrics.GetAsyncZoom().scale;
aUtils->SetResolution(presShellResolution, presShellResolution);
// Finally, we set the displayport.
nsCOMPtr<nsIContent> content = nsLayoutUtils::FindContentFor(aMetrics.GetScrollId());

View File

@ -747,8 +747,8 @@ ClientLayerManager::ProgressiveUpdateCallback(bool aHasPendingNewThebesContent,
aMetrics.mCriticalDisplayPort : aMetrics.mDisplayPort;
LayerRect displayPort = (metricsDisplayPort + aMetrics.GetScrollOffset()) * paintScale;
ScreenPoint scrollOffset;
CSSToScreenScale zoom;
ParentLayerPoint scrollOffset;
CSSToParentLayerScale zoom;
bool ret = AndroidBridge::Bridge()->ProgressiveUpdateCallback(
aHasPendingNewThebesContent, displayPort, paintScale.scale, aDrawingCritical,
scrollOffset, zoom);

View File

@ -75,7 +75,7 @@ GetTransformToAncestorsParentLayer(Layer* aStart, const LayerMetricsWrapper& aAn
// If the layer has a non-transient async transform then we need to apply it here
// because it will get applied by the APZ in the compositor as well
const FrameMetrics& metrics = iter.Metrics();
transform.PostScale(metrics.mPresShellResolution.scale, metrics.mPresShellResolution.scale, 1.f);
transform.PostScale(metrics.mPresShellResolution, metrics.mPresShellResolution, 1.f);
}
return transform;
}
@ -149,16 +149,10 @@ ClientTiledPaintedLayer::BeginPaint()
GetTransformToAncestorsParentLayer(this, displayPortAncestor);
transformDisplayPortToLayer.Invert();
// Note that below we use GetZoomToParent() in a number of places. Because this
// code runs on the client side, the mTransformScale field of the FrameMetrics
// will not have been set. This can result in incorrect values being returned
// by GetZoomToParent() when we have CSS transforms set on some of these layers.
// This code should be audited and updated as part of fixing bug 993525.
// Compute the critical display port that applies to this layer in the
// LayoutDevice space of this layer.
ParentLayerRect criticalDisplayPort =
(displayportMetrics.mCriticalDisplayPort * displayportMetrics.GetZoomToParent())
(displayportMetrics.mCriticalDisplayPort * displayportMetrics.GetZoom())
+ displayportMetrics.mCompositionBounds.TopLeft();
mPaintData.mCriticalDisplayPort = RoundedOut(
ApplyParentLayerToLayerTransform(transformDisplayPortToLayer, criticalDisplayPort));
@ -166,7 +160,7 @@ ClientTiledPaintedLayer::BeginPaint()
// Store the resolution from the displayport ancestor layer. Because this is Gecko-side,
// before any async transforms have occurred, we can use the zoom for this.
mPaintData.mResolution = displayportMetrics.GetZoomToParent();
mPaintData.mResolution = displayportMetrics.GetZoom();
TILING_LOG("TILING %p: Resolution %f\n", this, mPaintData.mPresShellResolution.scale);
// Store the applicable composition bounds in this layer's Layer units.
@ -179,7 +173,7 @@ ClientTiledPaintedLayer::BeginPaint()
TILING_LOG("TILING %p: Composition bounds %s\n", this, Stringify(mPaintData.mCompositionBounds).c_str());
// Calculate the scroll offset since the last transaction
mPaintData.mScrollOffset = displayportMetrics.GetScrollOffset() * displayportMetrics.GetZoomToParent();
mPaintData.mScrollOffset = displayportMetrics.GetScrollOffset() * displayportMetrics.GetZoom();
TILING_LOG("TILING %p: Scroll offset %s\n", this, Stringify(mPaintData.mScrollOffset).c_str());
}

View File

@ -150,10 +150,10 @@ ComputeViewTransform(const FrameMetrics& aContentMetrics, const FrameMetrics& aC
// but with aContentMetrics used in place of mLastContentPaintMetrics, because they
// should be equivalent, modulo race conditions while transactions are inflight.
ParentLayerToScreenScale scale = aCompositorMetrics.mPresShellResolution
* aCompositorMetrics.GetAsyncZoom();
ScreenPoint translation = (aCompositorMetrics.GetScrollOffset() - aContentMetrics.GetScrollOffset())
* aCompositorMetrics.GetZoom();
LayerToParentLayerScale scale(aCompositorMetrics.mPresShellResolution
* aCompositorMetrics.GetAsyncZoom().scale);
ParentLayerPoint translation = (aCompositorMetrics.GetScrollOffset() - aContentMetrics.GetScrollOffset())
* aCompositorMetrics.GetZoom();
return ViewTransform(scale, -translation);
}
@ -1366,8 +1366,8 @@ GetCompositorSideCompositionBounds(const LayerMetricsWrapper& aScrollAncestor,
const ViewTransform& aAPZTransform)
{
Matrix4x4 nonTransientAPZUntransform = Matrix4x4::Scaling(
aScrollAncestor.Metrics().mPresShellResolution.scale,
aScrollAncestor.Metrics().mPresShellResolution.scale,
aScrollAncestor.Metrics().mPresShellResolution,
aScrollAncestor.Metrics().mPresShellResolution,
1.f);
nonTransientAPZUntransform.Invert();

View File

@ -588,7 +588,7 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(Layer *aLayer)
hasAsyncTransform = true;
ViewTransform asyncTransformWithoutOverscroll;
ScreenPoint scrollOffset;
ParentLayerPoint scrollOffset;
controller->SampleContentTransformForFrame(&asyncTransformWithoutOverscroll,
scrollOffset);
Matrix4x4 overscrollTransform = controller->GetOverscrollTransform();
@ -718,7 +718,7 @@ ApplyAsyncTransformToScrollbarForContent(Layer* aScrollbar,
// aScrollbarIsDescendant hunk below we unapply the entire async
// transform, which includes the nontransientasync transform and would
// normally account for the resolution.
scale *= metrics.mPresShellResolution.scale;
scale *= metrics.mPresShellResolution;
}
scrollbarTransform.PostScale(1.f, 1.f / transientTransform._22, 1.f);
scrollbarTransform.PostTranslate(0, -transientTransform._42 * scale, 0);
@ -726,7 +726,7 @@ ApplyAsyncTransformToScrollbarForContent(Layer* aScrollbar,
if (aScrollbar->GetScrollbarDirection() == Layer::HORIZONTAL) {
float scale = metrics.CalculateCompositedSizeInCssPixels().width / metrics.mScrollableRect.width;
if (aScrollbarIsDescendant) {
scale *= metrics.mPresShellResolution.scale;
scale *= metrics.mPresShellResolution;
}
scrollbarTransform.PostScale(1.f / transientTransform._11, 1.f, 1.f);
scrollbarTransform.PostTranslate(-transientTransform._41 * scale, 0, 0);
@ -868,8 +868,8 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer)
// appears to be that metrics.mZoom is poorly initialized in some scenarios. In these scenarios,
// however, we can assume there is no async zooming in progress and so the following statement
// works fine.
CSSToScreenScale userZoom(metrics.mDevPixelsPerCSSPixel * metrics.mCumulativeResolution * LayerToScreenScale(1));
ScreenPoint userScroll = metrics.GetScrollOffset() * userZoom;
CSSToParentLayerScale userZoom(metrics.mDevPixelsPerCSSPixel * metrics.mCumulativeResolution * LayerToParentLayerScale(1));
ParentLayerPoint userScroll = metrics.GetScrollOffset() * userZoom;
SyncViewportInfo(displayPort, geckoZoom, mLayersUpdated,
userScroll, userZoom, fixedLayerMargins,
offset);
@ -884,15 +884,15 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer)
// primary scrollable layer. We compare this to the user zoom and scroll
// offset in the view transform we obtained from Java in order to compute the
// transformation we need to apply.
ScreenPoint geckoScroll(0, 0);
ParentLayerPoint geckoScroll(0, 0);
if (metrics.IsScrollable()) {
geckoScroll = metrics.GetScrollOffset() * userZoom;
}
LayerToScreenScale asyncZoom = userZoom / metrics.LayersPixelsPerCSSPixel();
ParentLayerToScreenScale scale = metrics.mPresShellResolution
* asyncZoom;
ScreenPoint translation = userScroll - geckoScroll;
LayerToParentLayerScale asyncZoom = userZoom / metrics.LayersPixelsPerCSSPixel();
LayerToParentLayerScale scale(metrics.mPresShellResolution
* asyncZoom.scale);
ParentLayerPoint translation = userScroll - geckoScroll;
Matrix4x4 treeTransform = ViewTransform(scale, -translation);
SetShadowTransform(aLayer, oldTransform * treeTransform);
@ -901,14 +901,14 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer)
// Apply resolution scaling to the old transform - the layer tree as it is
// doesn't have the necessary transform to display correctly.
oldTransform.PreScale(metrics.mPresShellResolution.scale, metrics.mPresShellResolution.scale, 1);
oldTransform.PreScale(metrics.mPresShellResolution, metrics.mPresShellResolution, 1);
// Make sure that overscroll and under-zoom are represented in the old
// transform so that fixed position content moves and scales accordingly.
// These calculations will effectively scale and offset fixed position layers
// in screen space when the compensatory transform is performed in
// AlignFixedAndStickyLayers.
ScreenRect contentScreenRect = mContentRect * userZoom;
ParentLayerRect contentScreenRect = mContentRect * userZoom;
Point3D overscrollTranslation;
if (userScroll.x < contentScreenRect.x) {
overscrollTranslation.x = contentScreenRect.x - userScroll.x;
@ -1018,8 +1018,8 @@ void
AsyncCompositionManager::SyncViewportInfo(const LayerIntRect& aDisplayPort,
const CSSToLayerScale& aDisplayResolution,
bool aLayersUpdated,
ScreenPoint& aScrollOffset,
CSSToScreenScale& aScale,
ParentLayerPoint& aScrollOffset,
CSSToParentLayerScale& aScale,
LayerMargin& aFixedLayerMargins,
ScreenPoint& aOffset)
{
@ -1035,7 +1035,7 @@ AsyncCompositionManager::SyncViewportInfo(const LayerIntRect& aDisplayPort,
}
void
AsyncCompositionManager::SyncFrameMetrics(const ScreenPoint& aScrollOffset,
AsyncCompositionManager::SyncFrameMetrics(const ParentLayerPoint& aScrollOffset,
float aZoom,
const CSSRect& aCssPageRect,
bool aLayersUpdated,

View File

@ -28,8 +28,8 @@ class AutoResolveRefLayers;
// Represents (affine) transforms that are calculated from a content view.
struct ViewTransform {
explicit ViewTransform(ParentLayerToScreenScale aScale = ParentLayerToScreenScale(),
ScreenPoint aTranslation = ScreenPoint())
explicit ViewTransform(LayerToParentLayerScale aScale = LayerToParentLayerScale(),
ParentLayerPoint aTranslation = ParentLayerPoint())
: mScale(aScale)
, mTranslation(aTranslation)
{}
@ -55,8 +55,8 @@ struct ViewTransform {
return !(*this == rhs);
}
ParentLayerToScreenScale mScale;
ScreenPoint mTranslation;
LayerToParentLayerScale mScale;
ParentLayerPoint mTranslation;
};
/**
@ -139,11 +139,11 @@ private:
void SyncViewportInfo(const LayerIntRect& aDisplayPort,
const CSSToLayerScale& aDisplayResolution,
bool aLayersUpdated,
ScreenPoint& aScrollOffset,
CSSToScreenScale& aScale,
ParentLayerPoint& aScrollOffset,
CSSToParentLayerScale& aScale,
LayerMargin& aFixedLayerMargins,
ScreenPoint& aOffset);
void SyncFrameMetrics(const ScreenPoint& aScrollOffset,
void SyncFrameMetrics(const ParentLayerPoint& aScrollOffset,
float aZoom,
const CSSRect& aCssPageRect,
bool aLayersUpdated,

View File

@ -188,7 +188,7 @@ public:
bool SampleContentTransformForFrame(const TimeStamp& aSampleTime,
ViewTransform* aOutTransform,
ScreenPoint& aScrollOffset) {
ParentLayerPoint& aScrollOffset) {
bool ret = AdvanceAnimations(aSampleTime);
AsyncPanZoomController::SampleContentTransformForFrame(
aOutTransform, aScrollOffset);
@ -243,12 +243,12 @@ protected:
void MakeApzcZoomable()
{
apzc->UpdateZoomConstraints(ZoomConstraints(true, true, CSSToScreenScale(0.25f), CSSToScreenScale(4.0f)));
apzc->UpdateZoomConstraints(ZoomConstraints(true, true, CSSToParentLayerScale(0.25f), CSSToParentLayerScale(4.0f)));
}
void MakeApzcUnzoomable()
{
apzc->UpdateZoomConstraints(ZoomConstraints(false, false, CSSToScreenScale(1.0f), CSSToScreenScale(1.0f)));
apzc->UpdateZoomConstraints(ZoomConstraints(false, false, CSSToParentLayerScale(1.0f), CSSToParentLayerScale(1.0f)));
}
AsyncPanZoomController::GestureBehavior mGestureBehavior;
@ -277,11 +277,33 @@ public:
* code to dispatch input events.
*/
// Some helper functions for constructing input event objects suitable to be
// passed either to an APZC (which expects an transformed point), or to an APZTM
// (which expects an untransformed point). We handle both cases by setting both
// the transformed and untransformed fields to the same value.
static SingleTouchData
CreateSingleTouchData(int32_t aIdentifier, int aX, int aY)
{
SingleTouchData touch(aIdentifier, ScreenIntPoint(aX, aY), ScreenSize(0, 0), 0, 0);
touch.mLocalScreenPoint = ParentLayerPoint(aX, aY);
return touch;
}
static PinchGestureInput
CreatePinchGestureInput(PinchGestureInput::PinchGestureType aType,
int aFocusX, int aFocusY,
float aCurrentSpan, float aPreviousSpan)
{
PinchGestureInput result(aType, 0, TimeStamp(), ScreenPoint(aFocusX, aFocusY),
aCurrentSpan, aPreviousSpan, 0);
result.mLocalFocusPoint = ParentLayerPoint(aFocusX, aFocusY);
return result;
}
template<class InputReceiver> static nsEventStatus
TouchDown(const nsRefPtr<InputReceiver>& aTarget, int aX, int aY, int aTime, uint64_t* aOutInputBlockId = nullptr)
{
MultiTouchInput mti = MultiTouchInput(MultiTouchInput::MULTITOUCH_START, aTime, TimeStamp(), 0);
mti.mTouches.AppendElement(SingleTouchData(0, ScreenIntPoint(aX, aY), ScreenSize(0, 0), 0, 0));
mti.mTouches.AppendElement(CreateSingleTouchData(0, aX, aY));
return aTarget->ReceiveInputEvent(mti, nullptr, aOutInputBlockId);
}
@ -289,7 +311,7 @@ template<class InputReceiver> static nsEventStatus
TouchMove(const nsRefPtr<InputReceiver>& aTarget, int aX, int aY, int aTime)
{
MultiTouchInput mti = MultiTouchInput(MultiTouchInput::MULTITOUCH_MOVE, aTime, TimeStamp(), 0);
mti.mTouches.AppendElement(SingleTouchData(0, ScreenIntPoint(aX, aY), ScreenSize(0, 0), 0, 0));
mti.mTouches.AppendElement(CreateSingleTouchData(0, aX, aY));
return aTarget->ReceiveInputEvent(mti, nullptr, nullptr);
}
@ -297,7 +319,7 @@ template<class InputReceiver> static nsEventStatus
TouchUp(const nsRefPtr<InputReceiver>& aTarget, int aX, int aY, int aTime)
{
MultiTouchInput mti = MultiTouchInput(MultiTouchInput::MULTITOUCH_END, aTime, TimeStamp(), 0);
mti.mTouches.AppendElement(SingleTouchData(0, ScreenIntPoint(aX, aY), ScreenSize(0, 0), 0, 0));
mti.mTouches.AppendElement(CreateSingleTouchData(0, aX, aY));
return aTarget->ReceiveInputEvent(mti, nullptr, nullptr);
}
@ -435,28 +457,25 @@ PinchWithPinchInput(const nsRefPtr<InputReceiver>& aTarget,
nsEventStatus (*aOutEventStatuses)[3] = nullptr)
{
nsEventStatus actualStatus = aTarget->ReceiveInputEvent(
PinchGestureInput(PinchGestureInput::PINCHGESTURE_START,
0, TimeStamp(), ScreenPoint(aFocusX, aFocusY),
10.0, 10.0, 0),
nullptr);
CreatePinchGestureInput(PinchGestureInput::PINCHGESTURE_START,
aFocusX, aFocusY, 10.0, 10.0),
nullptr);
if (aOutEventStatuses) {
(*aOutEventStatuses)[0] = actualStatus;
}
actualStatus = aTarget->ReceiveInputEvent(
PinchGestureInput(PinchGestureInput::PINCHGESTURE_SCALE,
0, TimeStamp(), ScreenPoint(aFocusX, aFocusY),
10.0 * aScale, 10.0, 0),
nullptr);
CreatePinchGestureInput(PinchGestureInput::PINCHGESTURE_SCALE,
aFocusX, aFocusY, 10.0 * aScale, 10.0),
nullptr);
if (aOutEventStatuses) {
(*aOutEventStatuses)[1] = actualStatus;
}
actualStatus = aTarget->ReceiveInputEvent(
PinchGestureInput(PinchGestureInput::PINCHGESTURE_END,
0, TimeStamp(), ScreenPoint(aFocusX, aFocusY),
// note: negative values here tell APZC
// not to turn the pinch into a pan
-1.0, -1.0, 0),
nullptr);
CreatePinchGestureInput(PinchGestureInput::PINCHGESTURE_END,
// note: negative values here tell APZC
// not to turn the pinch into a pan
aFocusX, aFocusY, -1.0, -1.0),
nullptr);
if (aOutEventStatuses) {
(*aOutEventStatuses)[2] = actualStatus;
}
@ -498,8 +517,8 @@ PinchWithTouchInput(const nsRefPtr<InputReceiver>& aTarget,
}
MultiTouchInput mtiStart = MultiTouchInput(MultiTouchInput::MULTITOUCH_START, 0, TimeStamp(), 0);
mtiStart.mTouches.AppendElement(SingleTouchData(inputId, ScreenIntPoint(aFocusX, aFocusY), ScreenSize(0, 0), 0, 0));
mtiStart.mTouches.AppendElement(SingleTouchData(inputId + 1, ScreenIntPoint(aFocusX, aFocusY), ScreenSize(0, 0), 0, 0));
mtiStart.mTouches.AppendElement(CreateSingleTouchData(inputId, aFocusX, aFocusY));
mtiStart.mTouches.AppendElement(CreateSingleTouchData(inputId + 1, aFocusX, aFocusY));
nsEventStatus status = aTarget->ReceiveInputEvent(mtiStart, aOutInputBlockId);
if (aOutEventStatuses) {
(*aOutEventStatuses)[0] = status;
@ -510,24 +529,24 @@ PinchWithTouchInput(const nsRefPtr<InputReceiver>& aTarget,
}
MultiTouchInput mtiMove1 = MultiTouchInput(MultiTouchInput::MULTITOUCH_MOVE, 0, TimeStamp(), 0);
mtiMove1.mTouches.AppendElement(SingleTouchData(inputId, ScreenIntPoint(aFocusX - pinchLength, aFocusY), ScreenSize(0, 0), 0, 0));
mtiMove1.mTouches.AppendElement(SingleTouchData(inputId + 1, ScreenIntPoint(aFocusX + pinchLength, aFocusY), ScreenSize(0, 0), 0, 0));
mtiMove1.mTouches.AppendElement(CreateSingleTouchData(inputId, aFocusX - pinchLength, aFocusY));
mtiMove1.mTouches.AppendElement(CreateSingleTouchData(inputId + 1, aFocusX + pinchLength, aFocusY));
status = aTarget->ReceiveInputEvent(mtiMove1, nullptr);
if (aOutEventStatuses) {
(*aOutEventStatuses)[1] = status;
}
MultiTouchInput mtiMove2 = MultiTouchInput(MultiTouchInput::MULTITOUCH_MOVE, 0, TimeStamp(), 0);
mtiMove2.mTouches.AppendElement(SingleTouchData(inputId, ScreenIntPoint(aFocusX - pinchLengthScaled, aFocusY), ScreenSize(0, 0), 0, 0));
mtiMove2.mTouches.AppendElement(SingleTouchData(inputId + 1, ScreenIntPoint(aFocusX + pinchLengthScaled, aFocusY), ScreenSize(0, 0), 0, 0));
mtiMove2.mTouches.AppendElement(CreateSingleTouchData(inputId, aFocusX - pinchLengthScaled, aFocusY));
mtiMove2.mTouches.AppendElement(CreateSingleTouchData(inputId + 1, aFocusX + pinchLengthScaled, aFocusY));
status = aTarget->ReceiveInputEvent(mtiMove2, nullptr);
if (aOutEventStatuses) {
(*aOutEventStatuses)[2] = status;
}
MultiTouchInput mtiEnd = MultiTouchInput(MultiTouchInput::MULTITOUCH_END, 0, TimeStamp(), 0);
mtiEnd.mTouches.AppendElement(SingleTouchData(inputId, ScreenIntPoint(aFocusX - pinchLengthScaled, aFocusY), ScreenSize(0, 0), 0, 0));
mtiEnd.mTouches.AppendElement(SingleTouchData(inputId + 1, ScreenIntPoint(aFocusX + pinchLengthScaled, aFocusY), ScreenSize(0, 0), 0, 0));
mtiEnd.mTouches.AppendElement(CreateSingleTouchData(inputId, aFocusX - pinchLengthScaled, aFocusY));
mtiEnd.mTouches.AppendElement(CreateSingleTouchData(inputId + 1, aFocusX + pinchLengthScaled, aFocusY));
status = aTarget->ReceiveInputEvent(mtiEnd, nullptr);
if (aOutEventStatuses) {
(*aOutEventStatuses)[3] = status;
@ -567,7 +586,7 @@ protected:
fm.mCompositionBounds = ParentLayerRect(200, 200, 100, 200);
fm.mScrollableRect = CSSRect(0, 0, 980, 1000);
fm.SetScrollOffset(CSSPoint(300, 300));
fm.SetZoom(CSSToScreenScale(2.0));
fm.SetZoom(CSSToParentLayerScale(2.0));
// the visible area of the document in CSS pixels is x=300 y=300 w=50 h=100
return fm;
}
@ -610,7 +629,7 @@ protected:
// part 2 of the test, move to the top-right corner of the page and pinch and
// make sure we stay in the correct spot
fm.SetZoom(CSSToScreenScale(2.0));
fm.SetZoom(CSSToParentLayerScale(2.0));
fm.SetScrollOffset(CSSPoint(930, 5));
apzc->SetFrameMetrics(fm);
// the visible area of the document in CSS pixels is x=930 y=5 w=50 h=100
@ -709,7 +728,7 @@ TEST_F(APZCBasicTester, Overzoom) {
fm.mCompositionBounds = ParentLayerRect(0, 0, 100, 100);
fm.mScrollableRect = CSSRect(0, 0, 125, 150);
fm.SetScrollOffset(CSSPoint(10, 0));
fm.SetZoom(CSSToScreenScale(1.0));
fm.SetZoom(CSSToParentLayerScale(1.0));
apzc->SetFrameMetrics(fm);
MakeApzcZoomable();
@ -728,11 +747,11 @@ TEST_F(APZCBasicTester, Overzoom) {
}
TEST_F(APZCBasicTester, SimpleTransform) {
ScreenPoint pointOut;
ParentLayerPoint pointOut;
ViewTransform viewTransformOut;
apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
EXPECT_EQ(ScreenPoint(), pointOut);
EXPECT_EQ(ParentLayerPoint(), pointOut);
EXPECT_EQ(ViewTransform(), viewTransformOut);
}
@ -778,8 +797,8 @@ TEST_F(APZCBasicTester, ComplexTransform) {
metrics.SetScrollOffset(CSSPoint(10, 10));
metrics.mScrollableRect = CSSRect(0, 0, 50, 50);
metrics.mCumulativeResolution = LayoutDeviceToLayerScale(2);
metrics.mPresShellResolution = ParentLayerToLayerScale(2);
metrics.SetZoom(CSSToScreenScale(6));
metrics.mPresShellResolution = 2.0f;
metrics.SetZoom(CSSToParentLayerScale(6));
metrics.mDevPixelsPerCSSPixel = CSSToLayoutDeviceScale(3);
metrics.SetScrollId(FrameMetrics::START_SCROLL_ID);
@ -789,7 +808,7 @@ TEST_F(APZCBasicTester, ComplexTransform) {
layers[0]->SetFrameMetrics(metrics);
layers[1]->SetFrameMetrics(childMetrics);
ScreenPoint pointOut;
ParentLayerPoint pointOut;
ViewTransform viewTransformOut;
// Both the parent and child layer should behave exactly the same here, because
@ -799,40 +818,40 @@ TEST_F(APZCBasicTester, ComplexTransform) {
apzc->SetFrameMetrics(metrics);
apzc->NotifyLayersUpdated(metrics, true);
apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
EXPECT_EQ(ViewTransform(ParentLayerToScreenScale(2), ScreenPoint()), viewTransformOut);
EXPECT_EQ(ScreenPoint(60, 60), pointOut);
EXPECT_EQ(ViewTransform(LayerToParentLayerScale(2), ParentLayerPoint()), viewTransformOut);
EXPECT_EQ(ParentLayerPoint(60, 60), pointOut);
childApzc->SetFrameMetrics(childMetrics);
childApzc->NotifyLayersUpdated(childMetrics, true);
childApzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
EXPECT_EQ(ViewTransform(ParentLayerToScreenScale(2), ScreenPoint()), viewTransformOut);
EXPECT_EQ(ScreenPoint(60, 60), pointOut);
EXPECT_EQ(ViewTransform(LayerToParentLayerScale(2), ParentLayerPoint()), viewTransformOut);
EXPECT_EQ(ParentLayerPoint(60, 60), pointOut);
// do an async scroll by 5 pixels and check the transform
metrics.ScrollBy(CSSPoint(5, 0));
apzc->SetFrameMetrics(metrics);
apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
EXPECT_EQ(ViewTransform(ParentLayerToScreenScale(2), ScreenPoint(-30, 0)), viewTransformOut);
EXPECT_EQ(ScreenPoint(90, 60), pointOut);
EXPECT_EQ(ViewTransform(LayerToParentLayerScale(2), ParentLayerPoint(-30, 0)), viewTransformOut);
EXPECT_EQ(ParentLayerPoint(90, 60), pointOut);
childMetrics.ScrollBy(CSSPoint(5, 0));
childApzc->SetFrameMetrics(childMetrics);
childApzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
EXPECT_EQ(ViewTransform(ParentLayerToScreenScale(2), ScreenPoint(-30, 0)), viewTransformOut);
EXPECT_EQ(ScreenPoint(90, 60), pointOut);
EXPECT_EQ(ViewTransform(LayerToParentLayerScale(2), ParentLayerPoint(-30, 0)), viewTransformOut);
EXPECT_EQ(ParentLayerPoint(90, 60), pointOut);
// do an async zoom of 1.5x and check the transform
metrics.ZoomBy(1.5f);
apzc->SetFrameMetrics(metrics);
apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
EXPECT_EQ(ViewTransform(ParentLayerToScreenScale(3), ScreenPoint(-45, 0)), viewTransformOut);
EXPECT_EQ(ScreenPoint(135, 90), pointOut);
EXPECT_EQ(ViewTransform(LayerToParentLayerScale(3), ParentLayerPoint(-45, 0)), viewTransformOut);
EXPECT_EQ(ParentLayerPoint(135, 90), pointOut);
childMetrics.ZoomBy(1.5f);
childApzc->SetFrameMetrics(childMetrics);
childApzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
EXPECT_EQ(ViewTransform(ParentLayerToScreenScale(3), ScreenPoint(-45, 0)), viewTransformOut);
EXPECT_EQ(ScreenPoint(135, 90), pointOut);
EXPECT_EQ(ViewTransform(LayerToParentLayerScale(3), ParentLayerPoint(-45, 0)), viewTransformOut);
EXPECT_EQ(ParentLayerPoint(135, 90), pointOut);
}
class APZCPanningTester : public APZCBasicTester {
@ -850,7 +869,7 @@ protected:
int time = 0;
int touchStart = 50;
int touchEnd = 10;
ScreenPoint pointOut;
ParentLayerPoint pointOut;
ViewTransform viewTransformOut;
nsTArray<uint32_t> allowedTouchBehaviors;
@ -861,10 +880,10 @@ protected:
apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
if (aShouldTriggerScroll) {
EXPECT_EQ(ScreenPoint(0, -(touchEnd-touchStart)), pointOut);
EXPECT_EQ(ParentLayerPoint(0, -(touchEnd-touchStart)), pointOut);
EXPECT_NE(ViewTransform(), viewTransformOut);
} else {
EXPECT_EQ(ScreenPoint(), pointOut);
EXPECT_EQ(ParentLayerPoint(), pointOut);
EXPECT_EQ(ViewTransform(), viewTransformOut);
}
@ -876,7 +895,7 @@ protected:
PanAndCheckStatus(apzc, time, touchEnd, touchStart, aShouldBeConsumed, &allowedTouchBehaviors);
apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
EXPECT_EQ(ScreenPoint(), pointOut);
EXPECT_EQ(ParentLayerPoint(), pointOut);
EXPECT_EQ(ViewTransform(), viewTransformOut);
}
@ -887,7 +906,7 @@ protected:
int time = 0;
int touchStart = 50;
int touchEnd = 10;
ScreenPoint pointOut;
ParentLayerPoint pointOut;
ViewTransform viewTransformOut;
uint64_t blockId = 0;
@ -904,7 +923,7 @@ protected:
EXPECT_LE(1, mcc->RunThroughDelayedTasks());
apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
EXPECT_EQ(ScreenPoint(), pointOut);
EXPECT_EQ(ParentLayerPoint(), pointOut);
EXPECT_EQ(ViewTransform(), viewTransformOut);
apzc->AssertStateIsReset();
@ -961,12 +980,12 @@ TEST_F(APZCBasicTester, Fling) {
int time = 0;
int touchStart = 50;
int touchEnd = 10;
ScreenPoint pointOut;
ParentLayerPoint pointOut;
ViewTransform viewTransformOut;
// Fling down. Each step scroll further down
Pan(apzc, time, touchStart, touchEnd);
ScreenPoint lastPoint;
ParentLayerPoint lastPoint;
for (int i = 1; i < 50; i+=1) {
apzc->SampleContentTransformForFrame(testStartTime+TimeDuration::FromMilliseconds(i), &viewTransformOut, pointOut);
EXPECT_GT(pointOut.y, lastPoint.y);
@ -1054,11 +1073,11 @@ TEST_F(APZCBasicTester, OverScrollPanning) {
// Check that we recover from overscroll via an animation.
const TimeDuration increment = TimeDuration::FromMilliseconds(1);
bool recoveredFromOverscroll = false;
ScreenPoint pointOut;
ParentLayerPoint pointOut;
ViewTransform viewTransformOut;
while (apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut)) {
// The reported scroll offset should be the same throughout.
EXPECT_EQ(ScreenPoint(0, 90), pointOut);
EXPECT_EQ(ParentLayerPoint(0, 90), pointOut);
if (!apzc->IsOverscrolled()) {
recoveredFromOverscroll = true;
@ -1080,7 +1099,7 @@ TEST_F(APZCBasicTester, OverScrollAbort) {
Pan(apzc, time, touchStart, touchEnd);
EXPECT_TRUE(apzc->IsOverscrolled());
ScreenPoint pointOut;
ParentLayerPoint pointOut;
ViewTransform viewTransformOut;
// This sample call will run to the end of the fling animation
@ -1140,7 +1159,7 @@ protected:
int tapCallsExpected = aSlow ? 1 : 0;
// Advance the fling animation by timeDelta milliseconds.
ScreenPoint pointOut;
ParentLayerPoint pointOut;
ViewTransform viewTransformOut;
apzc->SampleContentTransformForFrame(testStartTime + TimeDuration::FromMilliseconds(timeDelta), &viewTransformOut, pointOut);
@ -1151,7 +1170,7 @@ protected:
while (mcc->RunThroughDelayedTasks());
// Verify that we didn't advance any further after the fling was aborted, in either case.
ScreenPoint finalPointOut;
ParentLayerPoint finalPointOut;
apzc->SampleContentTransformForFrame(testStartTime + TimeDuration::FromMilliseconds(timeDelta + 1000), &viewTransformOut, finalPointOut);
EXPECT_EQ(pointOut.x, finalPointOut.x);
EXPECT_EQ(pointOut.y, finalPointOut.y);
@ -1173,7 +1192,7 @@ protected:
while (mcc->RunThroughDelayedTasks());
// Sample the fling a couple of times to ensure it's going.
ScreenPoint point, finalPoint;
ParentLayerPoint point, finalPoint;
ViewTransform viewTransform;
apzc->SampleContentTransformForFrame(testStartTime + TimeDuration::FromMilliseconds(10), &viewTransform, point);
apzc->SampleContentTransformForFrame(testStartTime + TimeDuration::FromMilliseconds(20), &viewTransform, finalPoint);
@ -1385,7 +1404,7 @@ protected:
time += 1000;
MultiTouchInput mti = MultiTouchInput(MultiTouchInput::MULTITOUCH_MOVE, time, TimeStamp(), 0);
mti.mTouches.AppendElement(SingleTouchData(0, ScreenIntPoint(touchX, touchEndY), ScreenSize(0, 0), 0, 0));
mti.mTouches.AppendElement(SingleTouchData(0, ParentLayerPoint(touchX, touchEndY), ScreenSize(0, 0), 0, 0));
status = apzc->ReceiveInputEvent(mti, nullptr);
EXPECT_EQ(nsEventStatus_eConsumeDoDefault, status);
@ -1393,11 +1412,11 @@ protected:
status = TouchUp(apzc, touchX, touchEndY, time);
EXPECT_EQ(nsEventStatus_eConsumeDoDefault, status);
ScreenPoint pointOut;
ParentLayerPoint pointOut;
ViewTransform viewTransformOut;
apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
EXPECT_EQ(ScreenPoint(), pointOut);
EXPECT_EQ(ParentLayerPoint(), pointOut);
EXPECT_EQ(ViewTransform(), viewTransformOut);
apzc->AssertStateIsReset();
@ -1563,13 +1582,13 @@ TEST_F(APZCGestureDetectorTester, TapFollowedByPinch) {
int inputId = 0;
MultiTouchInput mti;
mti = MultiTouchInput(MultiTouchInput::MULTITOUCH_START, time, TimeStamp(), 0);
mti.mTouches.AppendElement(SingleTouchData(inputId, ScreenIntPoint(20, 20), ScreenSize(0, 0), 0, 0));
mti.mTouches.AppendElement(SingleTouchData(inputId + 1, ScreenIntPoint(10, 10), ScreenSize(0, 0), 0, 0));
mti.mTouches.AppendElement(SingleTouchData(inputId, ParentLayerPoint(20, 20), ScreenSize(0, 0), 0, 0));
mti.mTouches.AppendElement(SingleTouchData(inputId + 1, ParentLayerPoint(10, 10), ScreenSize(0, 0), 0, 0));
apzc->ReceiveInputEvent(mti, nullptr);
mti = MultiTouchInput(MultiTouchInput::MULTITOUCH_END, time, TimeStamp(), 0);
mti.mTouches.AppendElement(SingleTouchData(inputId, ScreenIntPoint(20, 20), ScreenSize(0, 0), 0, 0));
mti.mTouches.AppendElement(SingleTouchData(inputId + 1, ScreenIntPoint(10, 10), ScreenSize(0, 0), 0, 0));
mti.mTouches.AppendElement(SingleTouchData(inputId, ParentLayerPoint(20, 20), ScreenSize(0, 0), 0, 0));
mti.mTouches.AppendElement(SingleTouchData(inputId + 1, ParentLayerPoint(10, 10), ScreenSize(0, 0), 0, 0));
apzc->ReceiveInputEvent(mti, nullptr);
while (mcc->RunThroughDelayedTasks());
@ -1588,17 +1607,17 @@ TEST_F(APZCGestureDetectorTester, TapFollowedByMultipleTouches) {
int inputId = 0;
MultiTouchInput mti;
mti = MultiTouchInput(MultiTouchInput::MULTITOUCH_START, time, TimeStamp(), 0);
mti.mTouches.AppendElement(SingleTouchData(inputId, ScreenIntPoint(20, 20), ScreenSize(0, 0), 0, 0));
mti.mTouches.AppendElement(SingleTouchData(inputId, ParentLayerPoint(20, 20), ScreenSize(0, 0), 0, 0));
apzc->ReceiveInputEvent(mti, nullptr);
mti = MultiTouchInput(MultiTouchInput::MULTITOUCH_START, time, TimeStamp(), 0);
mti.mTouches.AppendElement(SingleTouchData(inputId, ScreenIntPoint(20, 20), ScreenSize(0, 0), 0, 0));
mti.mTouches.AppendElement(SingleTouchData(inputId + 1, ScreenIntPoint(10, 10), ScreenSize(0, 0), 0, 0));
mti.mTouches.AppendElement(SingleTouchData(inputId, ParentLayerPoint(20, 20), ScreenSize(0, 0), 0, 0));
mti.mTouches.AppendElement(SingleTouchData(inputId + 1, ParentLayerPoint(10, 10), ScreenSize(0, 0), 0, 0));
apzc->ReceiveInputEvent(mti, nullptr);
mti = MultiTouchInput(MultiTouchInput::MULTITOUCH_END, time, TimeStamp(), 0);
mti.mTouches.AppendElement(SingleTouchData(inputId, ScreenIntPoint(20, 20), ScreenSize(0, 0), 0, 0));
mti.mTouches.AppendElement(SingleTouchData(inputId + 1, ScreenIntPoint(10, 10), ScreenSize(0, 0), 0, 0));
mti.mTouches.AppendElement(SingleTouchData(inputId, ParentLayerPoint(20, 20), ScreenSize(0, 0), 0, 0));
mti.mTouches.AppendElement(SingleTouchData(inputId + 1, ParentLayerPoint(10, 10), ScreenSize(0, 0), 0, 0));
apzc->ReceiveInputEvent(mti, nullptr);
while (mcc->RunThroughDelayedTasks());

View File

@ -21,9 +21,13 @@ namespace mozilla {
MOZ_BEGIN_ENUM_CLASS(PixelCastJustification, uint8_t)
// For the root layer, Screen Pixel = Parent Layer Pixel.
ScreenToParentLayerForRoot,
ScreenIsParentLayerForRoot,
// For the root composition size we want to view it as layer pixels in any layer
ParentLayerToLayerForRootComposition
ParentLayerToLayerForRootComposition,
// The transform that is usually used to convert between two coordinate
// systems is not available (for example, because the object that stores it
// is being destroyed), so fall back to the identity.
TransformNotAvailable
MOZ_END_ENUM_CLASS(PixelCastJustification)
template <class TargetUnits, class SourceUnits>
@ -34,6 +38,16 @@ template <class TargetUnits, class SourceUnits>
gfx::IntSizeTyped<TargetUnits> ViewAs(const gfx::IntSizeTyped<SourceUnits>& aSize, PixelCastJustification) {
return gfx::IntSizeTyped<TargetUnits>(aSize.width, aSize.height);
}
template <class TargetUnits, class SourceUnits>
gfx::PointTyped<TargetUnits> ViewAs(const gfx::PointTyped<SourceUnits>& aPoint, PixelCastJustification) {
return gfx::PointTyped<TargetUnits>(aPoint.x, aPoint.y);
}
template <class NewTargetUnits, class OldTargetUnits, class SourceUnits>
gfx::ScaleFactor<SourceUnits, NewTargetUnits> ViewTargetAs(
const gfx::ScaleFactor<SourceUnits, OldTargetUnits>& aScaleFactor,
PixelCastJustification) {
return gfx::ScaleFactor<SourceUnits, NewTargetUnits>(aScaleFactor.scale);
}
// Convenience functions for casting untyped entities to typed entities.
// Using these functions does not require a justification, but once we convert
@ -91,6 +105,18 @@ static gfx::IntRectTyped<TargetUnits> TransformTo(const gfx::Matrix4x4& aTransfo
return RoundedToInt(ViewAs<TargetUnits>(aTransform.TransformBounds(rect)));
}
// Transform |aVector|, which is anchored at |aAnchor|, by the given transform
// matrix, yielding a point in |TargetUnits|.
// The anchor is necessary because with 3D tranforms, the location of the
// vector can affect the result of the transform.
template <typename TargetUnits, typename SourceUnits>
static gfx::PointTyped<TargetUnits> TransformVector(const gfx::Matrix4x4& aTransform,
const gfx::PointTyped<SourceUnits>& aVector,
const gfx::PointTyped<SourceUnits>& aAnchor) {
gfx::PointTyped<TargetUnits> transformedStart = TransformTo<TargetUnits>(aTransform, aAnchor);
gfx::PointTyped<TargetUnits> transformedEnd = TransformTo<TargetUnits>(aTransform, aAnchor + aVector);
return transformedEnd - transformedStart;
}
}

View File

@ -27,12 +27,25 @@ struct LayoutDevicePixel;
struct LayerPixel;
struct RenderTargetPixel;
struct ScreenPixel;
// The layer coordinates of the parent frame.
// This can be arrived at in three ways:
// - Start with the CSS coordinates of the parent frame, multiply by the
// device scale and the cumulative resolution of the parent frame.
// - Start with the CSS coordinates of current frame, multiply by the device
// scale, the cumulative resolution of the current frame, and the scales
// from the CSS and async transforms of the current frame.
// - Start with global screen coordinates and unapply all CSS and async
// transforms from the root down to and including the parent.
// It's helpful to look at https://wiki.mozilla.org/Platform/GFX/APZ#Coordinate_systems
// to get a picture of how the various coordinate systems relate to each other.
struct ParentLayerPixel {};
template<> struct IsPixel<CSSPixel> : TrueType {};
template<> struct IsPixel<LayoutDevicePixel> : TrueType {};
template<> struct IsPixel<LayerPixel> : TrueType {};
template<> struct IsPixel<RenderTargetPixel> : TrueType {};
template<> struct IsPixel<ScreenPixel> : TrueType {};
template<> struct IsPixel<ParentLayerPixel> : TrueType {};
typedef gfx::CoordTyped<CSSPixel> CSSCoord;
typedef gfx::IntCoordTyped<CSSPixel> CSSIntCoord;
@ -67,8 +80,6 @@ typedef gfx::IntRectTyped<LayerPixel> LayerIntRect;
typedef gfx::MarginTyped<LayerPixel> LayerMargin;
typedef gfx::IntMarginTyped<LayerPixel> LayerIntMargin;
typedef gfx::CoordTyped<ScreenPixel> ScreenCoord;
typedef gfx::IntCoordTyped<ScreenPixel> ScreenIntCoord;
typedef gfx::PointTyped<RenderTargetPixel> RenderTargetPoint;
typedef gfx::IntPointTyped<RenderTargetPixel> RenderTargetIntPoint;
typedef gfx::SizeTyped<RenderTargetPixel> RenderTargetSize;
@ -78,6 +89,8 @@ typedef gfx::IntRectTyped<RenderTargetPixel> RenderTargetIntRect;
typedef gfx::MarginTyped<RenderTargetPixel> RenderTargetMargin;
typedef gfx::IntMarginTyped<RenderTargetPixel> RenderTargetIntMargin;
typedef gfx::CoordTyped<ScreenPixel> ScreenCoord;
typedef gfx::IntCoordTyped<ScreenPixel> ScreenIntCoord;
typedef gfx::PointTyped<ScreenPixel> ScreenPoint;
typedef gfx::IntPointTyped<ScreenPixel> ScreenIntPoint;
typedef gfx::SizeTyped<ScreenPixel> ScreenSize;
@ -87,20 +100,38 @@ typedef gfx::IntRectTyped<ScreenPixel> ScreenIntRect;
typedef gfx::MarginTyped<ScreenPixel> ScreenMargin;
typedef gfx::IntMarginTyped<ScreenPixel> ScreenIntMargin;
typedef gfx::CoordTyped<ParentLayerPixel> ParentLayerCoord;
typedef gfx::IntCoordTyped<ParentLayerPixel> ParentLayerIntCoord;
typedef gfx::PointTyped<ParentLayerPixel> ParentLayerPoint;
typedef gfx::IntPointTyped<ParentLayerPixel> ParentLayerIntPoint;
typedef gfx::SizeTyped<ParentLayerPixel> ParentLayerSize;
typedef gfx::IntSizeTyped<ParentLayerPixel> ParentLayerIntSize;
typedef gfx::RectTyped<ParentLayerPixel> ParentLayerRect;
typedef gfx::IntRectTyped<ParentLayerPixel> ParentLayerIntRect;
typedef gfx::MarginTyped<ParentLayerPixel> ParentLayerMargin;
typedef gfx::IntMarginTyped<ParentLayerPixel> ParentLayerIntMargin;
typedef gfx::ScaleFactor<CSSPixel, LayoutDevicePixel> CSSToLayoutDeviceScale;
typedef gfx::ScaleFactor<CSSPixel, LayerPixel> CSSToLayerScale;
typedef gfx::ScaleFactor<CSSPixel, ScreenPixel> CSSToScreenScale;
typedef gfx::ScaleFactor<CSSPixel, ParentLayerPixel> CSSToParentLayerScale;
typedef gfx::ScaleFactor<LayoutDevicePixel, CSSPixel> LayoutDeviceToCSSScale;
typedef gfx::ScaleFactor<LayoutDevicePixel, LayerPixel> LayoutDeviceToLayerScale;
typedef gfx::ScaleFactor<LayoutDevicePixel, ScreenPixel> LayoutDeviceToScreenScale;
typedef gfx::ScaleFactor<LayoutDevicePixel, ParentLayerPixel> LayoutDeviceToParentLayerScale;
typedef gfx::ScaleFactor<LayerPixel, CSSPixel> LayerToCSSScale;
typedef gfx::ScaleFactor<LayerPixel, LayoutDevicePixel> LayerToLayoutDeviceScale;
typedef gfx::ScaleFactor<LayerPixel, RenderTargetPixel> LayerToRenderTargetScale;
typedef gfx::ScaleFactor<LayerPixel, ScreenPixel> LayerToScreenScale;
typedef gfx::ScaleFactor<LayerPixel, ParentLayerPixel> LayerToParentLayerScale;
typedef gfx::ScaleFactor<RenderTargetPixel, ScreenPixel> RenderTargetToScreenScale;
typedef gfx::ScaleFactor<ScreenPixel, CSSPixel> ScreenToCSSScale;
typedef gfx::ScaleFactor<ScreenPixel, LayoutDevicePixel> ScreenToLayoutDeviceScale;
typedef gfx::ScaleFactor<ScreenPixel, LayerPixel> ScreenToLayerScale;
typedef gfx::ScaleFactor<ScreenPixel, ParentLayerPixel> ScreenToParentLayerScale;
typedef gfx::ScaleFactor<ParentLayerPixel, LayerPixel> ParentLayerToLayerScale;
typedef gfx::ScaleFactor<ParentLayerPixel, ScreenPixel> ParentLayerToScreenScale;
typedef gfx::ScaleFactor<ParentLayerPixel, ParentLayerPixel> ParentLayerToParentLayerScale;
/*
* The pixels that content authors use to specify sizes in.

View File

@ -724,10 +724,9 @@ nsDisplayScrollLayer::ComputeFrameMetrics(nsIFrame* aForFrame,
// Only the root scrollable frame for a given presShell should pick up
// the presShell's resolution. All the other frames are 1.0.
if (aScrollFrame == presShell->GetRootScrollFrame()) {
metrics.mPresShellResolution = ParentLayerToLayerScale(presShell->GetXResolution(),
presShell->GetYResolution());
metrics.mPresShellResolution = presShell->GetXResolution();
} else {
metrics.mPresShellResolution = ParentLayerToLayerScale(1.0f);
metrics.mPresShellResolution = 1.0f;
}
// The cumulative resolution is the resolution at which the scroll frame's
// content is actually rendered. It includes the pres shell resolutions of
@ -747,9 +746,9 @@ nsDisplayScrollLayer::ComputeFrameMetrics(nsIFrame* aForFrame,
// Initially, AsyncPanZoomController should render the content to the screen
// at the painted resolution.
const LayerToScreenScale layerToScreenScale(1.0f);
const LayerToParentLayerScale layerToParentLayerScale(1.0f);
metrics.SetZoom(metrics.mCumulativeResolution * metrics.mDevPixelsPerCSSPixel
* layerToScreenScale);
* layerToParentLayerScale);
if (presShell) {
nsIDocument* document = nullptr;
@ -763,11 +762,6 @@ nsDisplayScrollLayer::ComputeFrameMetrics(nsIFrame* aForFrame,
metrics.SetMayHaveTouchCaret(presShell->MayHaveTouchCaret());
}
LayoutDeviceToParentLayerScale layoutToParentLayerScale =
// The ScreenToParentLayerScale should be mTransformScale which is not calculated yet,
// but we don't yet handle CSS transforms, so we assume it's 1 here.
metrics.mCumulativeResolution * LayerToScreenScale(1.0) * ScreenToParentLayerScale(1.0);
// Calculate the composition bounds as the size of the scroll frame and
// its origin relative to the reference frame.
// If aScrollFrame is null, we are in a document without a root scroll frame,
@ -776,7 +770,8 @@ nsDisplayScrollLayer::ComputeFrameMetrics(nsIFrame* aForFrame,
nsRect compositionBounds(frameForCompositionBoundsCalculation->GetOffsetToCrossDoc(aReferenceFrame),
frameForCompositionBoundsCalculation->GetSize());
ParentLayerRect frameBounds = LayoutDeviceRect::FromAppUnits(compositionBounds, auPerDevPixel)
* layoutToParentLayerScale;
* metrics.mCumulativeResolution
* layerToParentLayerScale;
metrics.mCompositionBounds = frameBounds;
// For the root scroll frame of the root content document, the above calculation

View File

@ -2784,12 +2784,11 @@ CalculateFrameMetricsForDisplayPort(nsIFrame* aScrollFrame,
nsIPresShell* presShell = presContext->PresShell();
CSSToLayoutDeviceScale deviceScale(float(nsPresContext::AppUnitsPerCSSPixel())
/ presContext->AppUnitsPerDevPixel());
ParentLayerToLayerScale resolution;
float resolution = 1.0f;
if (aScrollFrame == presShell->GetRootScrollFrame()) {
// Only the root scrollable frame for a given presShell should pick up
// the presShell's resolution. All the other frames are 1.0.
resolution = ParentLayerToLayerScale(presShell->GetXResolution(),
presShell->GetYResolution());
resolution = presShell->GetXResolution();
}
// Note: unlike in ComputeFrameMetrics(), we don't know the full cumulative
// resolution including FrameMetrics::mExtraResolution, because layout hasn't
@ -2801,10 +2800,11 @@ CalculateFrameMetricsForDisplayPort(nsIFrame* aScrollFrame,
presShell->GetCumulativeResolution().width
* nsLayoutUtils::GetTransformToAncestorScale(aScrollFrame).width);
LayerToParentLayerScale layerToParentLayerScale(1.0f);
metrics.mDevPixelsPerCSSPixel = deviceScale;
metrics.mPresShellResolution = resolution;
metrics.mCumulativeResolution = cumulativeResolution;
metrics.SetZoom(deviceScale * cumulativeResolution * LayerToScreenScale(1));
metrics.SetZoom(deviceScale * cumulativeResolution * layerToParentLayerScale);
// Only the size of the composition bounds is relevant to the
// displayport calculation, not its origin.
@ -2816,9 +2816,7 @@ CalculateFrameMetricsForDisplayPort(nsIFrame* aScrollFrame,
compBoundsScale = LayoutDeviceToParentLayerScale(res.width, res.height);
}
} else {
compBoundsScale = cumulativeResolution
* LayerToScreenScale(1.0f)
* ScreenToParentLayerScale(1.0f);
compBoundsScale = cumulativeResolution * layerToParentLayerScale;
}
metrics.mCompositionBounds
= LayoutDeviceRect::FromAppUnits(nsRect(nsPoint(0, 0), compositionSize),
@ -2869,7 +2867,7 @@ nsLayoutUtils::GetOrMaybeCreateDisplayPort(nsDisplayListBuilder& aBuilder,
if (!haveDisplayPort) {
FrameMetrics metrics = CalculateFrameMetricsForDisplayPort(aScrollFrame, scrollableFrame);
ScreenMargin displayportMargins = APZCTreeManager::CalculatePendingDisplayPort(
metrics, ScreenPoint(0.0f, 0.0f), 0.0);
metrics, ParentLayerPoint(0.0f, 0.0f), 0.0);
nsIPresShell* presShell = aScrollFrame->PresContext()->GetPresShell();
gfx::IntSize alignment = gfxPlatform::GetPlatform()->UseTiling()
? gfx::IntSize(gfxPrefs::LayersTileWidth(), gfxPrefs::LayersTileHeight()) :

View File

@ -108,6 +108,8 @@ protected:
class SingleTouchData
{
public:
// Construct a SingleTouchData from a Screen point.
// mLocalScreenPoint remains (0,0) unless it's set later.
SingleTouchData(int32_t aIdentifier,
ScreenIntPoint aScreenPoint,
ScreenSize aRadius,
@ -121,6 +123,23 @@ public:
{
}
// Construct a SingleTouchData from a ParentLayer point.
// mScreenPoint remains (0,0) unless it's set later.
// Note: if APZ starts using the radius for anything, we should add a local
// version of that too, and have this constructor take it as a ParentLayerSize.
SingleTouchData(int32_t aIdentifier,
ParentLayerPoint aLocalScreenPoint,
ScreenSize aRadius,
float aRotationAngle,
float aForce)
: mIdentifier(aIdentifier),
mLocalScreenPoint(aLocalScreenPoint),
mRadius(aRadius),
mRotationAngle(aRotationAngle),
mForce(aForce)
{
}
SingleTouchData()
{
}
@ -135,6 +154,10 @@ public:
// coordinates on the screen.
ScreenIntPoint mScreenPoint;
// |mScreenPoint| transformed to the local coordinates of the APZC targeted
// by the hit. This is set and used by APZ.
ParentLayerPoint mLocalScreenPoint;
// Radius that the touch covers, i.e. if you're using your thumb it will
// probably be larger than using your pinky, even with the same force.
// Radius can be different along x and y. For example, if you press down with
@ -274,6 +297,11 @@ public:
// Only non-zero if mType is PANGESTURE_PAN or PANGESTURE_MOMENTUMPAN.
ScreenPoint mPanDisplacement;
// Versions of |mPanStartPoint| and |mPanDisplacement| in the local
// coordinates of the APZC receiving the pan. These are set and used by APZ.
ParentLayerPoint mLocalPanStartPoint;
ParentLayerPoint mLocalPanDisplacement;
};
/**
@ -291,6 +319,8 @@ public:
PINCHGESTURE_END
};
// Construct a tap gesture from a Screen point.
// mLocalFocusPoint remains (0,0) unless it's set later.
PinchGestureInput(PinchGestureType aType,
uint32_t aTime,
TimeStamp aTimeStamp,
@ -304,8 +334,23 @@ public:
mCurrentSpan(aCurrentSpan),
mPreviousSpan(aPreviousSpan)
{
}
// Construct a tap gesture from a ParentLayer point.
// mFocusPoint remains (0,0) unless it's set later.
PinchGestureInput(PinchGestureType aType,
uint32_t aTime,
TimeStamp aTimeStamp,
const ParentLayerPoint& aLocalFocusPoint,
float aCurrentSpan,
float aPreviousSpan,
Modifiers aModifiers)
: InputData(PINCHGESTURE_INPUT, aTime, aTimeStamp, aModifiers),
mType(aType),
mLocalFocusPoint(aLocalFocusPoint),
mCurrentSpan(aCurrentSpan),
mPreviousSpan(aPreviousSpan)
{
}
PinchGestureType mType;
@ -317,6 +362,10 @@ public:
// are the coordinates on the screen of this midpoint.
ScreenPoint mFocusPoint;
// |mFocusPoint| transformed to the local coordinates of the APZC targeted
// by the hit. This is set and used by APZ.
ParentLayerPoint mLocalFocusPoint;
// The distance in device pixels (though as a float for increased precision
// and because it is the distance along both the x and y axis) between the
// touches responsible for the pinch gesture.
@ -346,6 +395,8 @@ public:
TAPGESTURE_CANCEL
};
// Construct a tap gesture from a Screen point.
// mLocalPoint remains (0,0) unless it's set later.
TapGestureInput(TapGestureType aType,
uint32_t aTime,
TimeStamp aTimeStamp,
@ -355,12 +406,29 @@ public:
mType(aType),
mPoint(aPoint)
{
}
// Construct a tap gesture from a ParentLayer point.
// mPoint remains (0,0) unless it's set later.
TapGestureInput(TapGestureType aType,
uint32_t aTime,
TimeStamp aTimeStamp,
const ParentLayerPoint& aLocalPoint,
Modifiers aModifiers)
: InputData(TAPGESTURE_INPUT, aTime, aTimeStamp, aModifiers),
mType(aType),
mLocalPoint(aLocalPoint)
{
}
TapGestureType mType;
// The location of the tap in screen pixels.
ScreenIntPoint mPoint;
// The location of the tap in the local coordinates of the APZC receiving it.
// This is set and used by APZ.
ParentLayerPoint mLocalPoint;
};
}

View File

@ -1493,7 +1493,7 @@ AndroidBridge::SetPageRect(const CSSRect& aCssPageRect)
void
AndroidBridge::SyncViewportInfo(const LayerIntRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution,
bool aLayersUpdated, ScreenPoint& aScrollOffset, CSSToScreenScale& aScale,
bool aLayersUpdated, ParentLayerPoint& aScrollOffset, CSSToParentLayerScale& aScale,
LayerMargin& aFixedLayerMargins, ScreenPoint& aOffset)
{
mozilla::widget::android::GeckoLayerClient *client = mLayerClient;
@ -1512,7 +1512,7 @@ AndroidBridge::SyncViewportInfo(const LayerIntRect& aDisplayPort, const CSSToLay
}
ViewTransform* viewTransform = ViewTransform::Wrap(viewTransformJObj);
aScrollOffset = ScreenPoint(viewTransform->getx(), viewTransform->gety());
aScrollOffset = ParentLayerPoint(viewTransform->getx(), viewTransform->gety());
aScale.scale = viewTransform->getscale();
aFixedLayerMargins.top = viewTransform->getfixedLayerMarginTop();
aFixedLayerMargins.right = viewTransform->getfixedLayerMarginRight();
@ -1523,7 +1523,7 @@ AndroidBridge::SyncViewportInfo(const LayerIntRect& aDisplayPort, const CSSToLay
delete viewTransform;
}
void AndroidBridge::SyncFrameMetrics(const ScreenPoint& aScrollOffset, float aZoom, const CSSRect& aCssPageRect,
void AndroidBridge::SyncFrameMetrics(const ParentLayerPoint& aScrollOffset, float aZoom, const CSSRect& aCssPageRect,
bool aLayersUpdated, const CSSRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution,
bool aIsFirstPaint, LayerMargin& aFixedLayerMargins, ScreenPoint& aOffset)
{
@ -1956,7 +1956,7 @@ AndroidBridge::IsContentDocumentDisplayed()
bool
AndroidBridge::ProgressiveUpdateCallback(bool aHasPendingNewThebesContent, const LayerRect& aDisplayPort, float aDisplayResolution,
bool aDrawingCritical, ScreenPoint& aScrollOffset, CSSToScreenScale& aZoom)
bool aDrawingCritical, ParentLayerPoint& aScrollOffset, CSSToParentLayerScale& aZoom)
{
mozilla::widget::android::GeckoLayerClient *client = mLayerClient;
if (!client) {

View File

@ -208,7 +208,7 @@ public:
bool IsContentDocumentDisplayed();
bool ProgressiveUpdateCallback(bool aHasPendingNewThebesContent, const LayerRect& aDisplayPort, float aDisplayResolution, bool aDrawingCritical,
mozilla::ScreenPoint& aScrollOffset, mozilla::CSSToScreenScale& aZoom);
mozilla::ParentLayerPoint& aScrollOffset, mozilla::CSSToParentLayerScale& aZoom);
void SetLayerClient(JNIEnv* env, jobject jobj);
mozilla::widget::android::GeckoLayerClient* GetLayerClient() { return mLayerClient; }
@ -306,9 +306,9 @@ public:
void SetFirstPaintViewport(const LayerIntPoint& aOffset, const CSSToLayerScale& aZoom, const CSSRect& aCssPageRect);
void SetPageRect(const CSSRect& aCssPageRect);
void SyncViewportInfo(const LayerIntRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution,
bool aLayersUpdated, ScreenPoint& aScrollOffset, CSSToScreenScale& aScale,
bool aLayersUpdated, ParentLayerPoint& aScrollOffset, CSSToParentLayerScale& aScale,
LayerMargin& aFixedLayerMargins, ScreenPoint& aOffset);
void SyncFrameMetrics(const ScreenPoint& aScrollOffset, float aZoom, const CSSRect& aCssPageRect,
void SyncFrameMetrics(const ParentLayerPoint& aScrollOffset, float aZoom, const CSSRect& aCssPageRect,
bool aLayersUpdated, const CSSRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution,
bool aIsFirstPaint, LayerMargin& aFixedLayerMargins, ScreenPoint& aOffset);

View File

@ -253,8 +253,8 @@ APZController::GetRootZoomConstraints(ZoomConstraints* aOutConstraints)
// from 1/4 to 4x by default.
aOutConstraints->mAllowZoom = true;
aOutConstraints->mAllowDoubleTapZoom = false;
aOutConstraints->mMinZoom = CSSToScreenScale(0.25f);
aOutConstraints->mMaxZoom = CSSToScreenScale(4.0f);
aOutConstraints->mMinZoom = CSSToParentLayerScale(0.25f);
aOutConstraints->mMaxZoom = CSSToParentLayerScale(4.0f);
return true;
}
return false;