Bug 883646 - Propagate the ScaleFactor classes far and wide. r=kentuckyfriedtakahe

This commit is contained in:
Kartikaya Gupta 2013-06-21 17:03:56 -04:00
parent d197a8ba0d
commit 1de2b15435
20 changed files with 148 additions and 128 deletions

View File

@ -346,15 +346,19 @@ TabChild::Observe(nsISupports *aSubject,
// Calculate a really simple resolution that we probably won't
// be keeping, as well as putting the scroll offset back to
// the top-left of the page.
mLastMetrics.mZoom = gfxSize(1.0, 1.0);
mLastMetrics.mZoom = ScreenToScreenScale(1.0);
mLastMetrics.mViewport = CSSRect(CSSPoint(), kDefaultViewportSize);
mLastMetrics.mCompositionBounds = ScreenIntRect(ScreenIntPoint(), mInnerSize);
CSSToScreenScale resolution =
AsyncPanZoomController::CalculateResolution(mLastMetrics);
mLastMetrics.mResolution = gfxSize(resolution.scale, resolution.scale);
// We use ScreenToLayerScale(1) below in order to ask gecko to render
// what's currently visible on the screen. This is effectively turning
// the async zoom amount into the gecko zoom amount.
mLastMetrics.mResolution =
resolution / mLastMetrics.mDevPixelsPerCSSPixel * ScreenToLayerScale(1);
mLastMetrics.mScrollOffset = CSSPoint(0, 0);
utils->SetResolution(mLastMetrics.mResolution.width,
mLastMetrics.mResolution.height);
utils->SetResolution(mLastMetrics.mResolution.scale,
mLastMetrics.mResolution.scale);
HandlePossibleViewportChange();
}
@ -597,13 +601,13 @@ TabChild::HandlePossibleViewportChange()
nsresult rv = utils->GetIsFirstPaint(&isFirstPaint);
MOZ_ASSERT(NS_SUCCEEDED(rv));
if (NS_FAILED(rv) || isFirstPaint) {
gfxSize intrinsicScale =
CSSToScreenScale intrinsicScale =
AsyncPanZoomController::CalculateIntrinsicScale(metrics);
// FIXME/bug 799585(?): GetViewportInfo() returns a defaultZoom of
// 0.0 to mean "did not calculate a zoom". In that case, we default
// it to the intrinsic scale.
if (viewportInfo.GetDefaultZoom() < 0.01f) {
viewportInfo.SetDefaultZoom(intrinsicScale.width);
viewportInfo.SetDefaultZoom(intrinsicScale.scale);
}
double defaultZoom = viewportInfo.GetDefaultZoom();
@ -611,8 +615,7 @@ TabChild::HandlePossibleViewportChange()
defaultZoom <= viewportInfo.GetMaxZoom());
// GetViewportInfo() returns a resolution-dependent scale factor.
// Convert that to a resolution-indepedent zoom.
metrics.mZoom = gfxSize(defaultZoom / intrinsicScale.width,
defaultZoom / intrinsicScale.height);
metrics.mZoom = ScreenToScreenScale(defaultZoom / intrinsicScale.scale);
}
metrics.mDisplayPort = AsyncPanZoomController::CalculatePendingDisplayPort(
@ -621,9 +624,8 @@ TabChild::HandlePossibleViewportChange()
// we have no idea how long painting will take.
metrics, gfx::Point(0.0f, 0.0f), gfx::Point(0.0f, 0.0f), 0.0);
CSSToScreenScale resolution = AsyncPanZoomController::CalculateResolution(metrics);
metrics.mResolution = gfxSize(resolution.scale / metrics.mDevPixelsPerCSSPixel,
resolution.scale / metrics.mDevPixelsPerCSSPixel);
utils->SetResolution(metrics.mResolution.width, metrics.mResolution.height);
metrics.mResolution = resolution / metrics.mDevPixelsPerCSSPixel * ScreenToLayerScale(1);
utils->SetResolution(metrics.mResolution.scale, metrics.mResolution.scale);
// Force a repaint with these metrics. This, among other things, sets the
// displayport, so we start with async painting.

View File

@ -290,7 +290,7 @@ public:
void GetDPI(float* aDPI);
void GetDefaultScale(double *aScale);
gfxSize GetZoom() { return mLastMetrics.mZoom; }
ScreenToScreenScale GetZoom() { return mLastMetrics.mZoom; }
ScreenOrientation GetOrientation() { return mOrientation; }

View File

@ -55,10 +55,20 @@ struct ScaleFactor {
return ScaleFactor<other, dst>(scale / aOther.scale);
}
template<class other>
ScaleFactor<src, other> operator/(const ScaleFactor<other, dst>& aOther) const {
return ScaleFactor<src, other>(scale / aOther.scale);
}
template<class other>
ScaleFactor<src, other> operator*(const ScaleFactor<dst, other>& aOther) const {
return ScaleFactor<src, other>(scale * aOther.scale);
}
template<class other>
ScaleFactor<other, dst> operator*(const ScaleFactor<other, src>& aOther) const {
return ScaleFactor<other, dst>(scale * aOther.scale);
}
};
}

View File

@ -38,8 +38,8 @@ public:
, mScrollOffset(0, 0)
, mScrollId(NULL_SCROLL_ID)
, mScrollableRect(0, 0, 0, 0)
, mResolution(1, 1)
, mZoom(1, 1)
, mResolution(1)
, mZoom(1)
, mDevPixelsPerCSSPixel(1)
, mMayHaveTouchListeners(false)
, mPresShellId(-1)
@ -84,18 +84,14 @@ public:
return mScrollId != NULL_SCROLL_ID;
}
gfxSize LayersPixelsPerCSSPixel() const
CSSToLayerScale LayersPixelsPerCSSPixel() const
{
return mResolution * mDevPixelsPerCSSPixel;
}
gfx::Point GetScrollOffsetInLayerPixels() const
LayerPoint GetScrollOffsetInLayerPixels() const
{
return gfx::Point(
static_cast<gfx::Float>(
mScrollOffset.x * LayersPixelsPerCSSPixel().width),
static_cast<gfx::Float>(
mScrollOffset.y * LayersPixelsPerCSSPixel().height));
return mScrollOffset * LayersPixelsPerCSSPixel();
}
// ---------------------------------------------------------------------------
@ -172,8 +168,8 @@ public:
//
// It is required that the rect:
// { x = mScrollOffset.x, y = mScrollOffset.y,
// width = mCompositionBounds.x / mResolution.width,
// height = mCompositionBounds.y / mResolution.height }
// width = mCompositionBounds.x / mResolution.scale,
// height = mCompositionBounds.y / mResolution.scale }
// Be within |mScrollableRect|.
//
// This is valid for any layer, but is always relative to this frame and
@ -209,7 +205,7 @@ public:
// post-multiplied into the parent's transform. Since this only happens when
// we walk the layer tree, the resulting transform isn't stored here. Thus the
// resolution of parent layers is opaque to this metric.
gfxSize mResolution;
LayoutDeviceToLayerScale mResolution;
// The resolution-independent "user zoom". For example, if a page
// configures the viewport to a zoom value of 2x, then this member
@ -224,13 +220,13 @@ public:
//
// When this is not true, we're probably asynchronously sampling a
// zoom animation for content.
gfxSize mZoom;
ScreenToScreenScale mZoom;
// 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
// resolution.
float mDevPixelsPerCSSPixel;
CSSToLayoutDeviceScale mDevPixelsPerCSSPixel;
// Whether or not this frame may have touch listeners.
bool mMayHaveTouchListeners;

View File

@ -408,8 +408,8 @@ ClientLayerManager::ProgressiveUpdateCallback(bool aHasPendingNewThebesContent,
// This is derived from the code in
// gfx/layers/ipc/CompositorParent.cpp::TransformShadowTree.
const gfx3DMatrix& rootTransform = GetRoot()->GetTransform();
CSSToLayerScale paintScale(metrics.mDevPixelsPerCSSPixel / rootTransform.GetXScale(),
metrics.mDevPixelsPerCSSPixel / rootTransform.GetYScale());
CSSToLayerScale paintScale = metrics.mDevPixelsPerCSSPixel
/ LayerToLayoutDeviceScale(rootTransform.GetXScale(), rootTransform.GetYScale());
const CSSRect& metricsDisplayPort =
(aDrawingCritical && !metrics.mCriticalDisplayPort.IsEmpty()) ?
metrics.mCriticalDisplayPort : metrics.mDisplayPort;

View File

@ -75,8 +75,8 @@ ClientTiledThebesLayer::BeginPaint()
mPaintData.mResolution.SizeTo(1, 1);
for (ContainerLayer* parent = GetParent(); parent; parent = parent->GetParent()) {
const FrameMetrics& metrics = parent->GetFrameMetrics();
mPaintData.mResolution.width *= metrics.mResolution.width;
mPaintData.mResolution.height *= metrics.mResolution.height;
mPaintData.mResolution.width *= metrics.mResolution.scale;
mPaintData.mResolution.height *= metrics.mResolution.scale;
}
// Calculate the scroll offset since the last transaction, and the

View File

@ -351,7 +351,8 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFram
const gfx3DMatrix& rootTransform = mLayerManager->GetRoot()->GetTransform();
const FrameMetrics& metrics = container->GetFrameMetrics();
float paintScale = metrics.mDevPixelsPerCSSPixel / rootTransform.GetXScale();
CSSToLayerScale paintScale = metrics.mDevPixelsPerCSSPixel
/ LayerToLayoutDeviceScale(rootTransform.GetXScale(), rootTransform.GetYScale());
CSSRect displayPort(metrics.mCriticalDisplayPort.IsEmpty() ?
metrics.mDisplayPort : metrics.mCriticalDisplayPort);
gfx::Margin fixedLayerMargins(0, 0, 0, 0);
@ -405,15 +406,15 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer, const gfx3DMatr
gfx3DMatrix treeTransform;
CSSToLayerScale geckoZoom(metrics.mDevPixelsPerCSSPixel / aRootTransform.GetXScale(),
metrics.mDevPixelsPerCSSPixel / aRootTransform.GetYScale());
CSSToLayerScale geckoZoom = metrics.mDevPixelsPerCSSPixel /
LayerToLayoutDeviceScale(aRootTransform.GetXScale(), aRootTransform.GetYScale());
LayerIntPoint scrollOffsetLayerPixels = RoundedToInt(metrics.mScrollOffset * geckoZoom);
if (mIsFirstPaint) {
mContentRect = metrics.mScrollableRect;
SetFirstPaintViewport(scrollOffsetLayerPixels,
geckoZoom.scale,
geckoZoom,
mContentRect);
mIsFirstPaint = false;
} else if (!metrics.mScrollableRect.IsEqualEdges(mContentRect)) {
@ -435,8 +436,8 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer, const gfx3DMatr
ScreenPoint offset(0, 0);
ScreenPoint userScroll(0, 0);
CSSToScreenScale userZoom;
SyncViewportInfo(displayPort, geckoZoom.scale, mLayersUpdated,
userScroll, userZoom.scale, userZoom.scale, fixedLayerMargins,
SyncViewportInfo(displayPort, geckoZoom, mLayersUpdated,
userScroll, userZoom, fixedLayerMargins,
offset);
mLayersUpdated = false;
@ -544,7 +545,7 @@ AsyncCompositionManager::TransformShadowTree(TimeStamp aCurrentFrame)
void
AsyncCompositionManager::SetFirstPaintViewport(const LayerIntPoint& aOffset,
float aZoom,
const CSSToLayerScale& aZoom,
const CSSRect& aCssPageRect)
{
#ifdef MOZ_WIDGET_ANDROID
@ -562,10 +563,10 @@ AsyncCompositionManager::SetPageRect(const CSSRect& aCssPageRect)
void
AsyncCompositionManager::SyncViewportInfo(const LayerIntRect& aDisplayPort,
float aDisplayResolution,
const CSSToLayerScale& aDisplayResolution,
bool aLayersUpdated,
ScreenPoint& aScrollOffset,
float& aScaleX, float& aScaleY,
CSSToScreenScale& aScale,
gfx::Margin& aFixedLayerMargins,
ScreenPoint& aOffset)
{
@ -574,7 +575,7 @@ AsyncCompositionManager::SyncViewportInfo(const LayerIntRect& aDisplayPort,
aDisplayResolution,
aLayersUpdated,
aScrollOffset,
aScaleX, aScaleY,
aScale,
aFixedLayerMargins,
aOffset);
#endif
@ -586,7 +587,7 @@ AsyncCompositionManager::SyncFrameMetrics(const ScreenPoint& aScrollOffset,
const CSSRect& aCssPageRect,
bool aLayersUpdated,
const CSSRect& aDisplayPort,
float aDisplayResolution,
const CSSToLayerScale& aDisplayResolution,
bool aIsFirstPaint,
gfx::Margin& aFixedLayerMargins,
ScreenPoint& aOffset)

View File

@ -115,14 +115,14 @@ private:
bool* aWantNextFrame);
void SetFirstPaintViewport(const LayerIntPoint& aOffset,
float aZoom,
const CSSToLayerScale& aZoom,
const CSSRect& aCssPageRect);
void SetPageRect(const CSSRect& aCssPageRect);
void SyncViewportInfo(const LayerIntRect& aDisplayPort,
float aDisplayResolution,
const CSSToLayerScale& aDisplayResolution,
bool aLayersUpdated,
ScreenPoint& aScrollOffset,
float& aScaleX, float& aScaleY,
CSSToScreenScale& aScale,
gfx::Margin& aFixedLayerMargins,
ScreenPoint& aOffset);
void SyncFrameMetrics(const ScreenPoint& aScrollOffset,
@ -130,7 +130,7 @@ private:
const CSSRect& aCssPageRect,
bool aLayersUpdated,
const CSSRect& aDisplayPort,
float aDisplayResolution,
const CSSToLayerScale& aDisplayResolution,
bool aIsFirstPaint,
gfx::Margin& aFixedLayerMargins,
ScreenPoint& aOffset);

View File

@ -165,8 +165,8 @@ ThebesLayerComposite::GetEffectiveResolution()
gfxSize resolution(1, 1);
for (ContainerLayer* parent = GetParent(); parent; parent = parent->GetParent()) {
const FrameMetrics& metrics = parent->GetFrameMetrics();
resolution.width *= metrics.mResolution.width;
resolution.height *= metrics.mResolution.height;
resolution.width *= metrics.mResolution.scale;
resolution.height *= metrics.mResolution.scale;
}
return resolution;
@ -199,8 +199,8 @@ ThebesLayerComposite::GetDisplayPort()
metrics.mDisplayPort.height);
displayPort.ScaleRoundOut(parentResolution.width, parentResolution.height);
}
parentResolution.width /= metrics.mResolution.width;
parentResolution.height /= metrics.mResolution.height;
parentResolution.width /= metrics.mResolution.scale;
parentResolution.height /= metrics.mResolution.scale;
}
if (parent->UseIntermediateSurface()) {
transform.PreMultiply(parent->GetTransform());
@ -252,9 +252,10 @@ ThebesLayerComposite::GetCompositionBounds()
// Get the content document bounds, in screen-space.
const FrameMetrics& metrics = scrollableLayer->GetFrameMetrics();
const LayerIntRect content = RoundedToInt(metrics.mScrollableRect / scale);
// !!! WTF. this code is just wrong. See bug 881451.
gfx::Point scrollOffset =
gfx::Point((metrics.mScrollOffset.x * metrics.LayersPixelsPerCSSPixel().width) / scale.scale,
(metrics.mScrollOffset.y * metrics.LayersPixelsPerCSSPixel().height) / scale.scale);
gfx::Point((metrics.mScrollOffset.x * metrics.LayersPixelsPerCSSPixel().scale) / scale.scale,
(metrics.mScrollOffset.y * metrics.LayersPixelsPerCSSPixel().scale) / scale.scale);
const nsIntPoint contentOrigin(
content.x - NS_lround(scrollOffset.x),
content.y - NS_lround(scrollOffset.y));

View File

@ -391,7 +391,7 @@ nsEventStatus AsyncPanZoomController::OnTouchStart(const MultiTouchInput& aEvent
{
MonitorAutoLock monitor(mMonitor);
// Bring the resolution back in sync with the zoom.
SetZoomAndResolution(mFrameMetrics.mZoom.width);
SetZoomAndResolution(mFrameMetrics.mZoom);
RequestContentRepaint();
ScheduleComposite();
}
@ -545,7 +545,7 @@ nsEventStatus AsyncPanZoomController::OnScale(const PinchGestureInput& aEvent) {
MonitorAutoLock monitor(mMonitor);
CSSToScreenScale resolution = CalculateResolution(mFrameMetrics);
gfxFloat userZoom = mFrameMetrics.mZoom.width;
gfxFloat userZoom = mFrameMetrics.mZoom.scale;
ScreenPoint focusPoint = aEvent.mFocusPoint;
CSSPoint focusChange = (mLastZoomFocus - focusPoint) / resolution;
@ -564,8 +564,8 @@ nsEventStatus AsyncPanZoomController::OnScale(const PinchGestureInput& aEvent) {
// either axis such that we don't overscroll the boundaries when zooming.
gfx::Point neededDisplacement;
float maxZoom = mMaxZoom / CalculateIntrinsicScale(mFrameMetrics).width;
float minZoom = mMinZoom / CalculateIntrinsicScale(mFrameMetrics).width;
float maxZoom = mMaxZoom / CalculateIntrinsicScale(mFrameMetrics).scale;
float minZoom = mMinZoom / CalculateIntrinsicScale(mFrameMetrics).scale;
bool doScale = (spanRatio > 1.0 && userZoom < maxZoom) ||
(spanRatio < 1.0 && userZoom > minZoom);
@ -785,7 +785,7 @@ bool AsyncPanZoomController::DoFling(const TimeDuration& aDelta) {
if (!shouldContinueFlingX && !shouldContinueFlingY) {
// Bring the resolution back in sync with the zoom, in case we scaled down
// the zoom while accelerating.
SetZoomAndResolution(mFrameMetrics.mZoom.width);
SetZoomAndResolution(mFrameMetrics.mZoom);
SendAsyncScrollEvent();
RequestContentRepaint();
mState = NOTHING;
@ -825,10 +825,10 @@ void AsyncPanZoomController::ScrollBy(const CSSPoint& aOffset) {
void AsyncPanZoomController::ScaleWithFocus(float aZoom,
const ScreenPoint& aFocus) {
float zoomFactor = aZoom / mFrameMetrics.mZoom.width;
float zoomFactor = aZoom / mFrameMetrics.mZoom.scale;
CSSToScreenScale resolution = CalculateResolution(mFrameMetrics);
SetZoomAndResolution(aZoom);
SetZoomAndResolution(ScreenToScreenScale(aZoom));
// If the new scale is very small, we risk multiplying in huge rounding
// errors, so don't bother adjusting the scroll offset.
@ -958,21 +958,17 @@ const CSSRect AsyncPanZoomController::CalculatePendingDisplayPort(
return scrollableRect.ClampRect(shiftedDisplayPort) - scrollOffset;
}
/*static*/ gfxSize
/*static*/ CSSToScreenScale
AsyncPanZoomController::CalculateIntrinsicScale(const FrameMetrics& aMetrics)
{
gfxFloat intrinsicScale = (gfxFloat(aMetrics.mCompositionBounds.width) /
gfxFloat(aMetrics.mViewport.width));
return gfxSize(intrinsicScale, intrinsicScale);
return CSSToScreenScale(gfxFloat(aMetrics.mCompositionBounds.width) /
gfxFloat(aMetrics.mViewport.width));
}
/*static*/ CSSToScreenScale
AsyncPanZoomController::CalculateResolution(const FrameMetrics& aMetrics)
{
gfxSize intrinsicScale = CalculateIntrinsicScale(aMetrics);
gfxSize userZoom = aMetrics.mZoom;
return CSSToScreenScale(intrinsicScale.width * userZoom.width,
intrinsicScale.height * userZoom.height);
return CalculateIntrinsicScale(aMetrics) * aMetrics.mZoom;
}
/*static*/ CSSRect
@ -1031,7 +1027,7 @@ void AsyncPanZoomController::RequestContentRepaint() {
mFrameMetrics.mScrollOffset.x) < EPSILON &&
fabsf(mLastPaintRequestMetrics.mScrollOffset.y -
mFrameMetrics.mScrollOffset.y) < EPSILON &&
mFrameMetrics.mResolution.width == mLastPaintRequestMetrics.mResolution.width) {
mFrameMetrics.mResolution == mLastPaintRequestMetrics.mResolution) {
return;
}
@ -1039,14 +1035,13 @@ void AsyncPanZoomController::RequestContentRepaint() {
// Cache the zoom since we're temporarily changing it for
// acceleration-scaled painting.
gfxFloat actualZoom = mFrameMetrics.mZoom.width;
ScreenToScreenScale actualZoom = mFrameMetrics.mZoom;
// Calculate the factor of acceleration based on the faster of the two axes.
float accelerationFactor =
clamped(std::max(mX.GetAccelerationFactor(), mY.GetAccelerationFactor()),
MIN_ZOOM / 2.0f, MAX_ZOOM);
// Scale down the resolution a bit based on acceleration.
mFrameMetrics.mZoom.width = mFrameMetrics.mZoom.height =
actualZoom / accelerationFactor;
mFrameMetrics.mZoom.scale /= accelerationFactor;
// This message is compressed, so fire whether or not we already have a paint
// queued up. We need to know whether or not a paint was requested anyways,
@ -1061,7 +1056,7 @@ void AsyncPanZoomController::RequestContentRepaint() {
mWaitingForContentToPaint = true;
// Set the zoom back to what it was for the purpose of logic control.
mFrameMetrics.mZoom = gfxSize(actualZoom, actualZoom);
mFrameMetrics.mZoom = actualZoom;
}
void
@ -1107,11 +1102,10 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa
// will affect the final computed resolution.
double sampledPosition = gComputedTimingFunction->GetValue(animPosition);
gfxFloat startZoom = mStartZoomToMetrics.mZoom.width;
gfxFloat endZoom = mEndZoomToMetrics.mZoom.width;
gfxFloat sampledZoom = (endZoom * sampledPosition +
startZoom * (1 - sampledPosition));
mFrameMetrics.mZoom = gfxSize(sampledZoom, sampledZoom);
ScreenToScreenScale startZoom = mStartZoomToMetrics.mZoom;
ScreenToScreenScale endZoom = mEndZoomToMetrics.mZoom;
mFrameMetrics.mZoom = ScreenToScreenScale(endZoom.scale * sampledPosition +
startZoom.scale * (1 - sampledPosition));
mFrameMetrics.mScrollOffset = CSSPoint::FromUnknownPoint(gfx::Point(
mEndZoomToMetrics.mScrollOffset.x * sampledPosition +
@ -1124,7 +1118,7 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa
if (aSampleTime - mAnimationStartTime >= ZOOM_TO_DURATION) {
// Bring the resolution in sync with the zoom.
SetZoomAndResolution(mFrameMetrics.mZoom.width);
SetZoomAndResolution(mFrameMetrics.mZoom);
mState = NOTHING;
SendAsyncScrollEvent();
RequestContentRepaint();
@ -1143,8 +1137,7 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa
localScale = CalculateResolution(mFrameMetrics);
if (frame.IsScrollable()) {
metricsScrollOffset = LayerPoint::FromUnknownPoint(
frame.GetScrollOffsetInLayerPixels());
metricsScrollOffset = frame.GetScrollOffsetInLayerPixels();
}
scrollOffset = mFrameMetrics.mScrollOffset;
@ -1180,10 +1173,10 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa
// Scales on the root layer, on what's currently painted.
const gfx3DMatrix& currentTransform = aLayer->GetTransform();
LayerToCSSScale rootScale(currentTransform.GetXScale() / frame.mDevPixelsPerCSSPixel,
currentTransform.GetYScale() / frame.mDevPixelsPerCSSPixel);
CSSToLayerScale rootScale = frame.mDevPixelsPerCSSPixel
/ LayerToLayoutDeviceScale(currentTransform.GetXScale(), currentTransform.GetYScale());
LayerPoint translation = (scrollOffset / rootScale) - metricsScrollOffset;
LayerPoint translation = (scrollOffset * rootScale) - metricsScrollOffset;
*aNewTransform = ViewTransform(-translation, localScale);
aScrollOffset = scrollOffset * localScale;
@ -1274,7 +1267,7 @@ void AsyncPanZoomController::UpdateCompositionBounds(const ScreenIntRect& aCompo
// has gone out of view, the buffer will be cleared elsewhere anyways.
if (aCompositionBounds.width && aCompositionBounds.height &&
oldCompositionBounds.width && oldCompositionBounds.height) {
SetZoomAndResolution(mFrameMetrics.mZoom.width);
SetZoomAndResolution(mFrameMetrics.mZoom);
// Repaint on a rotation so that our new resolution gets properly updated.
RequestContentRepaint();
@ -1303,9 +1296,9 @@ void AsyncPanZoomController::ZoomToRect(const gfxRect& aRect) {
ScreenIntRect compositionBounds = mFrameMetrics.mCompositionBounds;
CSSRect cssPageRect = mFrameMetrics.mScrollableRect;
CSSPoint scrollOffset = mFrameMetrics.mScrollOffset;
gfxSize currentZoom = mFrameMetrics.mZoom;
float currentZoom = mFrameMetrics.mZoom.scale;
float targetZoom;
float intrinsicScale = CalculateIntrinsicScale(mFrameMetrics).width;
float intrinsicScale = CalculateIntrinsicScale(mFrameMetrics).scale;
// The minimum zoom to prevent over-zoom-out.
// If the zoom factor is lower than this (i.e. we are zoomed more into the page),
@ -1331,8 +1324,8 @@ void AsyncPanZoomController::ZoomToRect(const gfxRect& aRect) {
// 3. currentZoom is equal to localMinZoom and user still double-tapping it
// Treat these three cases as a request to zoom out as much as possible.
if (zoomToRect.IsEmpty() ||
(currentZoom.width == localMaxZoom && targetZoom >= localMaxZoom) ||
(currentZoom.width == localMinZoom && targetZoom <= localMinZoom)) {
(currentZoom == localMaxZoom && targetZoom >= localMaxZoom) ||
(currentZoom == localMinZoom && targetZoom <= localMinZoom)) {
CSSRect compositedRect = CalculateCompositedRectInCssPixels(mFrameMetrics);
float y = scrollOffset.y;
float newHeight =
@ -1351,7 +1344,7 @@ void AsyncPanZoomController::ZoomToRect(const gfxRect& aRect) {
}
targetZoom = clamped(targetZoom, localMinZoom, localMaxZoom);
mEndZoomToMetrics.mZoom = gfxSize(targetZoom, targetZoom);
mEndZoomToMetrics.mZoom = ScreenToScreenScale(targetZoom);
// Adjust the zoomToRect to a sensible position to prevent overscrolling.
FrameMetrics metricsAfterZoom = mFrameMetrics;
@ -1434,12 +1427,14 @@ void AsyncPanZoomController::TimeoutTouchListeners() {
ContentReceivedTouch(false);
}
void AsyncPanZoomController::SetZoomAndResolution(float aZoom) {
void AsyncPanZoomController::SetZoomAndResolution(const ScreenToScreenScale& aZoom) {
mMonitor.AssertCurrentThreadOwns();
mFrameMetrics.mZoom = gfxSize(aZoom, aZoom);
mFrameMetrics.mZoom = aZoom;
CSSToScreenScale resolution = CalculateResolution(mFrameMetrics);
mFrameMetrics.mResolution = gfxSize(resolution.scale / mFrameMetrics.mDevPixelsPerCSSPixel,
resolution.scale / mFrameMetrics.mDevPixelsPerCSSPixel);
// We use ScreenToLayerScale(1) below in order to ask gecko to render
// what's currently visible on the screen. This is effectively turning
// the async zoom amount into the gecko zoom amount.
mFrameMetrics.mResolution = resolution / mFrameMetrics.mDevPixelsPerCSSPixel * ScreenToLayerScale(1);
}
void AsyncPanZoomController::UpdateZoomConstraints(bool aAllowZoom,

View File

@ -227,7 +227,7 @@ public:
* Return the scale factor needed to fit the viewport in |aMetrics|
* into its composition bounds.
*/
static gfxSize CalculateIntrinsicScale(const FrameMetrics& aMetrics);
static CSSToScreenScale CalculateIntrinsicScale(const FrameMetrics& aMetrics);
/**
* Return the resolution that content should be rendered at given
@ -456,7 +456,7 @@ protected:
*
* *** The monitor must be held while calling this.
*/
void SetZoomAndResolution(float aScale);
void SetZoomAndResolution(const ScreenToScreenScale& aZoom);
/**
* Timeout function for mozbrowserasyncscroll event. Because we throttle

View File

@ -318,7 +318,7 @@ bool Axis::ScaleWillOverscrollBothSides(float aScale) {
CSSRect cssContentRect = metrics.mScrollableRect;
CSSToScreenScale scale(metrics.mZoom.width * aScale);
CSSToScreenScale scale(metrics.mZoom.scale * aScale);
CSSIntRect cssCompositionBounds = RoundedIn(metrics.mCompositionBounds / scale);
return GetRectLength(cssContentRect) < GetRectLength(CSSRect(cssCompositionBounds));

View File

@ -788,6 +788,22 @@ struct ParamTraits<nsIntSize>
}
};
template<class T, class U>
struct ParamTraits< mozilla::gfx::ScaleFactor<T, U> >
{
typedef mozilla::gfx::ScaleFactor<T, U> paramType;
static void Write(Message* msg, const paramType& param)
{
WriteParam(msg, param.scale);
}
static bool Read(const Message* msg, void** iter, paramType* result)
{
return (ReadParam(msg, iter, &result->scale));
}
};
template<class T>
struct ParamTraits< mozilla::gfx::PointTyped<T> >
{

View File

@ -57,6 +57,7 @@ typedef gfx::ScaleFactor<LayoutDevicePixel, LayerPixel> LayoutDeviceToLayerScale
typedef gfx::ScaleFactor<LayerPixel, LayoutDevicePixel> LayerToLayoutDeviceScale;
typedef gfx::ScaleFactor<LayerPixel, ScreenPixel> LayerToScreenScale;
typedef gfx::ScaleFactor<ScreenPixel, LayerPixel> ScreenToLayerScale;
typedef gfx::ScaleFactor<ScreenPixel, ScreenPixel> ScreenToScreenScale;
/*
* The pixels that content authors use to specify sizes in.

View File

@ -631,9 +631,10 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
bool aMayHaveTouchListeners) {
nsPresContext* presContext = aForFrame->PresContext();
int32_t auPerDevPixel = presContext->AppUnitsPerDevPixel();
LayoutDeviceToLayerScale resolution(aContainerParameters.mXScale, aContainerParameters.mYScale);
nsIntRect visible = aVisibleRect.ScaleToNearestPixels(
aContainerParameters.mXScale, aContainerParameters.mYScale, auPerDevPixel);
resolution.scale, resolution.scale, auPerDevPixel);
aRoot->SetVisibleRegion(nsIntRegion(visible));
FrameMetrics metrics;
@ -668,10 +669,10 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
if (TabChild *tc = GetTabChildFrom(presShell)) {
metrics.mZoom = tc->GetZoom();
}
metrics.mResolution = gfxSize(presShell->GetXResolution(), presShell->GetYResolution());
metrics.mResolution = resolution;
metrics.mDevPixelsPerCSSPixel =
(float)nsPresContext::AppUnitsPerCSSPixel() / auPerDevPixel;
metrics.mDevPixelsPerCSSPixel = CSSToLayoutDeviceScale(
(float)nsPresContext::AppUnitsPerCSSPixel() / auPerDevPixel);
metrics.mMayHaveTouchListeners = aMayHaveTouchListeners;

View File

@ -167,10 +167,7 @@ ComputeShadowTreeTransform(nsIFrame* aContainerFrame,
nscoord auPerDevPixel = aContainerFrame->PresContext()->AppUnitsPerDevPixel();
nsIntPoint scrollOffset =
aConfig.mScrollOffset.ToNearestPixels(auPerDevPixel);
// metricsScrollOffset is in layer coordinates.
gfx::Point metricsScrollOffset = aMetrics->GetScrollOffsetInLayerPixels();
nsIntPoint roundedMetricsScrollOffset =
nsIntPoint(NS_lround(metricsScrollOffset.x), NS_lround(metricsScrollOffset.y));
LayerIntPoint metricsScrollOffset = RoundedToInt(aMetrics->GetScrollOffsetInLayerPixels());
if (aRootFrameLoader->AsyncScrollEnabled() && !aMetrics->mDisplayPort.IsEmpty()) {
// Only use asynchronous scrolling if it is enabled and there is a
@ -178,8 +175,8 @@ ComputeShadowTreeTransform(nsIFrame* aContainerFrame,
// synchronously scrolled for identifying a scroll area before it is
// being actively scrolled.
nsIntPoint scrollCompensation(
(scrollOffset.x / aTempScaleX - roundedMetricsScrollOffset.x),
(scrollOffset.y / aTempScaleY - roundedMetricsScrollOffset.y));
(scrollOffset.x / aTempScaleX - metricsScrollOffset.x),
(scrollOffset.y / aTempScaleY - metricsScrollOffset.y));
return ViewTransform(-scrollCompensation, aConfig.mXScale, aConfig.mYScale);
} else {
@ -371,7 +368,7 @@ BuildViewMap(ViewMap& oldContentViews, ViewMap& newContentViews,
if (metrics.IsScrollable()) {
nscoord auPerDevPixel = aFrameLoader->GetPrimaryFrameOfOwningContent()
->PresContext()->AppUnitsPerDevPixel();
nscoord auPerCSSPixel = auPerDevPixel * metrics.mDevPixelsPerCSSPixel;
nscoord auPerCSSPixel = auPerDevPixel * metrics.mDevPixelsPerCSSPixel.scale;
nsContentView* view = FindViewForId(oldContentViews, scrollId);
if (view) {
// View already exists. Be sure to propagate scales for any values

View File

@ -2114,7 +2114,7 @@ AndroidBridge::IsTablet()
}
void
AndroidBridge::SetFirstPaintViewport(const LayerIntPoint& aOffset, float aZoom, const CSSRect& aCssPageRect)
AndroidBridge::SetFirstPaintViewport(const LayerIntPoint& aOffset, const CSSToLayerScale& aZoom, const CSSRect& aCssPageRect)
{
AndroidGeckoLayerClient *client = mLayerClient;
if (!client)
@ -2134,8 +2134,8 @@ AndroidBridge::SetPageRect(const CSSRect& aCssPageRect)
}
void
AndroidBridge::SyncViewportInfo(const LayerIntRect& aDisplayPort, float aDisplayResolution, bool aLayersUpdated,
ScreenPoint& aScrollOffset, float& aScaleX, float& aScaleY,
AndroidBridge::SyncViewportInfo(const LayerIntRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution,
bool aLayersUpdated, ScreenPoint& aScrollOffset, CSSToScreenScale& aScale,
gfx::Margin& aFixedLayerMargins, ScreenPoint& aOffset)
{
AndroidGeckoLayerClient *client = mLayerClient;
@ -2143,12 +2143,12 @@ AndroidBridge::SyncViewportInfo(const LayerIntRect& aDisplayPort, float aDisplay
return;
client->SyncViewportInfo(aDisplayPort, aDisplayResolution, aLayersUpdated,
aScrollOffset, aScaleX, aScaleY, aFixedLayerMargins,
aScrollOffset, aScale, aFixedLayerMargins,
aOffset);
}
void AndroidBridge::SyncFrameMetrics(const ScreenPoint& aScrollOffset, float aZoom, const CSSRect& aCssPageRect,
bool aLayersUpdated, const CSSRect& aDisplayPort, float aDisplayResolution,
bool aLayersUpdated, const CSSRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution,
bool aIsFirstPaint, gfx::Margin& aFixedLayerMargins, ScreenPoint& aOffset)
{
AndroidGeckoLayerClient *client = mLayerClient;

View File

@ -371,13 +371,13 @@ public:
void EnableNetworkNotifications();
void DisableNetworkNotifications();
void SetFirstPaintViewport(const LayerIntPoint& aOffset, float aZoom, const CSSRect& aCssPageRect);
void SetFirstPaintViewport(const LayerIntPoint& aOffset, const CSSToLayerScale& aZoom, const CSSRect& aCssPageRect);
void SetPageRect(const CSSRect& aCssPageRect);
void SyncViewportInfo(const LayerIntRect& aDisplayPort, float aDisplayResolution, bool aLayersUpdated,
ScreenPoint& aScrollOffset, float& aScaleX, float& aScaleY,
void SyncViewportInfo(const LayerIntRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution,
bool aLayersUpdated, ScreenPoint& aScrollOffset, CSSToScreenScale& aScale,
gfx::Margin& aFixedLayerMargins, ScreenPoint& aOffset);
void SyncFrameMetrics(const ScreenPoint& aScrollOffset, float aZoom, const CSSRect& aCssPageRect,
bool aLayersUpdated, const CSSRect& aDisplayPort, float aDisplayResolution,
bool aLayersUpdated, const CSSRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution,
bool aIsFirstPaint, gfx::Margin& aFixedLayerMargins, ScreenPoint& aOffset);
void AddPluginView(jobject view, const gfxRect& rect, bool isFullScreen);

View File

@ -905,7 +905,7 @@ AndroidProgressiveUpdateData::Init(jobject jobj)
}
void
AndroidGeckoLayerClient::SetFirstPaintViewport(const LayerIntPoint& aOffset, float aZoom, const CSSRect& aCssPageRect)
AndroidGeckoLayerClient::SetFirstPaintViewport(const LayerIntPoint& aOffset, const CSSToLayerScale& aZoom, const CSSRect& aCssPageRect)
{
NS_ASSERTION(!isNull(), "SetFirstPaintViewport called on null layer client!");
JNIEnv *env = GetJNIForThread(); // this is called on the compositor thread
@ -913,7 +913,7 @@ AndroidGeckoLayerClient::SetFirstPaintViewport(const LayerIntPoint& aOffset, flo
return;
AutoLocalJNIFrame jniFrame(env, 0);
return env->CallVoidMethod(wrapped_obj, jSetFirstPaintViewport, (float)aOffset.x, (float)aOffset.y, aZoom,
return env->CallVoidMethod(wrapped_obj, jSetFirstPaintViewport, (float)aOffset.x, (float)aOffset.y, aZoom.scale,
aCssPageRect.x, aCssPageRect.y, aCssPageRect.XMost(), aCssPageRect.YMost());
}
@ -931,8 +931,8 @@ AndroidGeckoLayerClient::SetPageRect(const CSSRect& aCssPageRect)
}
void
AndroidGeckoLayerClient::SyncViewportInfo(const LayerIntRect& aDisplayPort, float aDisplayResolution, bool aLayersUpdated,
ScreenPoint& aScrollOffset, float& aScaleX, float& aScaleY,
AndroidGeckoLayerClient::SyncViewportInfo(const LayerIntRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution,
bool aLayersUpdated, ScreenPoint& aScrollOffset, CSSToScreenScale& aScale,
gfx::Margin& aFixedLayerMargins, ScreenPoint& aOffset)
{
NS_ASSERTION(!isNull(), "SyncViewportInfo called on null layer client!");
@ -945,7 +945,7 @@ AndroidGeckoLayerClient::SyncViewportInfo(const LayerIntRect& aDisplayPort, floa
jobject viewTransformJObj = env->CallObjectMethod(wrapped_obj, jSyncViewportInfoMethod,
aDisplayPort.x, aDisplayPort.y,
aDisplayPort.width, aDisplayPort.height,
aDisplayResolution, aLayersUpdated);
aDisplayResolution.scale, aLayersUpdated);
if (jniFrame.CheckForException())
return;
@ -955,7 +955,7 @@ AndroidGeckoLayerClient::SyncViewportInfo(const LayerIntRect& aDisplayPort, floa
viewTransform.Init(viewTransformJObj);
aScrollOffset = ScreenPoint(viewTransform.GetX(env), viewTransform.GetY(env));
aScaleX = aScaleY = viewTransform.GetScale(env);
aScale.scale = viewTransform.GetScale(env);
viewTransform.GetFixedLayerMargins(env, aFixedLayerMargins);
aOffset.x = viewTransform.GetOffsetX(env);
@ -964,7 +964,7 @@ AndroidGeckoLayerClient::SyncViewportInfo(const LayerIntRect& aDisplayPort, floa
void
AndroidGeckoLayerClient::SyncFrameMetrics(const ScreenPoint& aScrollOffset, float aZoom, const CSSRect& aCssPageRect,
bool aLayersUpdated, const CSSRect& aDisplayPort, float aDisplayResolution,
bool aLayersUpdated, const CSSRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution,
bool aIsFirstPaint, gfx::Margin& aFixedLayerMargins, ScreenPoint& aOffset)
{
NS_ASSERTION(!isNull(), "SyncFrameMetrics called on null layer client!");
@ -975,14 +975,14 @@ AndroidGeckoLayerClient::SyncFrameMetrics(const ScreenPoint& aScrollOffset, floa
AutoLocalJNIFrame jniFrame(env);
// convert the displayport rect from scroll-relative CSS pixels to document-relative device pixels
LayerRect dpUnrounded = aDisplayPort * CSSToLayerScale(aDisplayResolution);
LayerRect dpUnrounded = aDisplayPort * aDisplayResolution;
dpUnrounded += LayerPoint::FromUnknownPoint(aScrollOffset.ToUnknownPoint());
LayerIntRect dp = gfx::RoundedToInt(dpUnrounded);
jobject viewTransformJObj = env->CallObjectMethod(wrapped_obj, jSyncFrameMetricsMethod,
aScrollOffset.x, aScrollOffset.y, aZoom,
aCssPageRect.x, aCssPageRect.y, aCssPageRect.XMost(), aCssPageRect.YMost(),
aLayersUpdated, dp.x, dp.y, dp.width, dp.height, aDisplayResolution,
aLayersUpdated, dp.x, dp.y, dp.width, dp.height, aDisplayResolution.scale,
aIsFirstPaint);
if (jniFrame.CheckForException())

View File

@ -269,13 +269,13 @@ public:
AndroidGeckoLayerClient() {}
AndroidGeckoLayerClient(jobject jobj) { Init(jobj); }
void SetFirstPaintViewport(const LayerIntPoint& aOffset, float aZoom, const CSSRect& aCssPageRect);
void SetFirstPaintViewport(const LayerIntPoint& aOffset, const CSSToLayerScale& aZoom, const CSSRect& aCssPageRect);
void SetPageRect(const CSSRect& aCssPageRect);
void SyncViewportInfo(const LayerIntRect& aDisplayPort, float aDisplayResolution, bool aLayersUpdated,
ScreenPoint& aScrollOffset, float& aScaleX, float& aScaleY,
void SyncViewportInfo(const LayerIntRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution,
bool aLayersUpdated, ScreenPoint& aScrollOffset, CSSToScreenScale& aScale,
gfx::Margin& aFixedLayerMargins, ScreenPoint& aOffset);
void SyncFrameMetrics(const ScreenPoint& aScrollOffset, float aZoom, const CSSRect& aCssPageRect,
bool aLayersUpdated, const CSSRect& aDisplayPort, float aDisplayResolution,
bool aLayersUpdated, const CSSRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution,
bool aIsFirstPaint, gfx::Margin& aFixedLayerMargins, ScreenPoint& aOffset);
bool ProgressiveUpdateCallback(bool aHasPendingNewThebesContent, const LayerRect& aDisplayPort, float aDisplayResolution, bool aDrawingCritical, gfx::Rect& aViewport, float& aScaleX, float& aScaleY);
bool CreateFrame(AutoLocalJNIFrame *jniFrame, AndroidLayerRendererFrame& aFrame);