Bug 880676 - Replace a couple of Rect scaling functions with strongly typed operators. r=BenWa

This commit is contained in:
Kartikaya Gupta 2013-06-14 16:11:31 -04:00
parent fbe003e9c9
commit cf832e1e8c
5 changed files with 58 additions and 71 deletions

View File

@ -395,16 +395,15 @@ ClientLayerManager::ProgressiveUpdateCallback(bool aHasPendingNewThebesContent,
// This is derived from the code in
// gfx/layers/ipc/CompositorParent.cpp::TransformShadowTree.
const gfx3DMatrix& rootTransform = GetRoot()->GetTransform();
float devPixelRatioX = 1 / rootTransform.GetXScale();
float devPixelRatioY = 1 / rootTransform.GetYScale();
CSSToLayerScale paintScale = LayerToCSSScale(rootTransform.GetXScale(),
rootTransform.GetYScale()).Inverse();
const CSSRect& metricsDisplayPort =
(aDrawingCritical && !metrics.mCriticalDisplayPort.IsEmpty()) ?
metrics.mCriticalDisplayPort : metrics.mDisplayPort;
LayerRect displayPort = LayerRect::FromCSSRect(metricsDisplayPort + metrics.mScrollOffset,
devPixelRatioX, devPixelRatioY);
LayerRect displayPort = (metricsDisplayPort + metrics.mScrollOffset) * paintScale;
return AndroidBridge::Bridge()->ProgressiveUpdateCallback(
aHasPendingNewThebesContent, displayPort, devPixelRatioX, aDrawingCritical,
aHasPendingNewThebesContent, displayPort, paintScale.scale, aDrawingCritical,
aViewport, aScaleX, aScaleY);
}
#endif

View File

@ -404,16 +404,15 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer, const gfx3DMatr
gfx3DMatrix treeTransform;
float layerPixelRatioX = 1 / aRootTransform.GetXScale(),
layerPixelRatioY = 1 / aRootTransform.GetYScale();
CSSToLayerScale geckoZoom = LayerToCSSScale(aRootTransform.GetXScale(),
aRootTransform.GetYScale()).Inverse();
LayerIntPoint scrollOffsetLayerPixels = LayerIntPoint::FromCSSPointRounded(
metrics.mScrollOffset, layerPixelRatioX, layerPixelRatioY);
LayerIntPoint scrollOffsetLayerPixels = RoundedToInt(metrics.mScrollOffset * geckoZoom);
if (mIsFirstPaint) {
mContentRect = metrics.mScrollableRect;
SetFirstPaintViewport(scrollOffsetLayerPixels,
layerPixelRatioX,
geckoZoom.scale,
mContentRect);
mIsFirstPaint = false;
} else if (!metrics.mScrollableRect.IsEqualEdges(mContentRect)) {
@ -424,20 +423,19 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer, const gfx3DMatr
// We synchronise the viewport information with Java after sending the above
// notifications, so that Java can take these into account in its response.
// Calculate the absolute display port to send to Java
LayerIntRect displayPort =
LayerIntRect::FromCSSRectRounded(metrics.mCriticalDisplayPort.IsEmpty()
? metrics.mDisplayPort
: metrics.mCriticalDisplayPort,
layerPixelRatioX, layerPixelRatioY);
LayerIntRect displayPort = RoundedToInt(
(metrics.mCriticalDisplayPort.IsEmpty()
? metrics.mDisplayPort
: metrics.mCriticalDisplayPort
) * geckoZoom);
displayPort += scrollOffsetLayerPixels;
gfx::Margin fixedLayerMargins(0, 0, 0, 0);
ScreenPoint offset(0, 0);
ScreenPoint scrollOffset(0, 0);
float scaleX = 1.0,
scaleY = 1.0;
SyncViewportInfo(displayPort, layerPixelRatioX, mLayersUpdated,
scrollOffset, scaleX, scaleY, fixedLayerMargins,
ScreenPoint userScroll(0, 0);
CSSToScreenScale userZoom;
SyncViewportInfo(displayPort, geckoZoom.scale, mLayersUpdated,
userScroll, userZoom.scale, userZoom.scale, fixedLayerMargins,
offset);
mLayersUpdated = false;
@ -447,50 +445,44 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer, const gfx3DMatr
// Handle transformations for asynchronous panning and zooming. We determine the
// zoom used by Gecko from the transformation set on the root layer, and we
// determine the scroll offset used by Gecko from the frame metrics of the
// primary scrollable layer. We compare this to the desired zoom and scroll
// 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.
float tempScaleDiffX = aRootTransform.GetXScale() * scaleX;
float tempScaleDiffY = aRootTransform.GetYScale() * scaleY;
LayerToScreenScale zoomAdjust = userZoom / geckoZoom;
LayerIntPoint metricsScrollOffset(0, 0);
LayerIntPoint geckoScroll(0, 0);
if (metrics.IsScrollable()) {
metricsScrollOffset = scrollOffsetLayerPixels;
geckoScroll = scrollOffsetLayerPixels;
}
LayerPoint scrollCompensation(
(scrollOffset.x / tempScaleDiffX - metricsScrollOffset.x),
(scrollOffset.y / tempScaleDiffY - metricsScrollOffset.y));
treeTransform = gfx3DMatrix(ViewTransform(-scrollCompensation,
CSSToScreenScale(scaleX, scaleY)));
LayerPoint translation = (userScroll / zoomAdjust) - geckoScroll;
treeTransform = gfx3DMatrix(ViewTransform(-translation, userZoom));
// Translate fixed position layers so that they stay in the correct position
// when scrollOffset and metricsScrollOffset differ.
// when userScroll and geckoScroll differ.
gfxPoint fixedOffset;
gfxSize scaleDiff;
LayerRect content = LayerRect::FromCSSRect(mContentRect,
1 / aRootTransform.GetXScale(),
1 / aRootTransform.GetYScale());
LayerRect content = mContentRect * geckoZoom;
// If the contents can fit entirely within the widget area on a particular
// dimension, we need to translate and scale so that the fixed layers remain
// within the page boundaries.
if (mContentRect.width * scaleX < metrics.mCompositionBounds.width) {
fixedOffset.x = -metricsScrollOffset.x;
if (mContentRect.width * userZoom.scale < metrics.mCompositionBounds.width) {
fixedOffset.x = -geckoScroll.x;
scaleDiff.width = std::min(1.0f, metrics.mCompositionBounds.width / content.width);
} else {
fixedOffset.x = clamped(scrollOffset.x / tempScaleDiffX, content.x,
content.XMost() - metrics.mCompositionBounds.width / tempScaleDiffX) - metricsScrollOffset.x;
scaleDiff.width = tempScaleDiffX;
fixedOffset.x = clamped(userScroll.x / zoomAdjust.scale, content.x,
content.XMost() - metrics.mCompositionBounds.width / zoomAdjust.scale) - geckoScroll.x;
scaleDiff.width = zoomAdjust.scale;
}
if (mContentRect.height * scaleY < metrics.mCompositionBounds.height) {
fixedOffset.y = -metricsScrollOffset.y;
if (mContentRect.height * userZoom.scale < metrics.mCompositionBounds.height) {
fixedOffset.y = -geckoScroll.y;
scaleDiff.height = std::min(1.0f, metrics.mCompositionBounds.height / content.height);
} else {
fixedOffset.y = clamped(scrollOffset.y / tempScaleDiffY, content.y,
content.YMost() - metrics.mCompositionBounds.height / tempScaleDiffY) - metricsScrollOffset.y;
scaleDiff.height = tempScaleDiffY;
fixedOffset.y = clamped(userScroll.y / zoomAdjust.scale, content.y,
content.YMost() - metrics.mCompositionBounds.height / zoomAdjust.scale) - geckoScroll.y;
scaleDiff.height = zoomAdjust.scale;
}
// The transform already takes the resolution scale into account. Since we

View File

@ -246,17 +246,15 @@ ThebesLayerComposite::GetCompositionBounds()
// the content resolution.
Layer* rootLayer = Manager()->GetRoot();
const gfx3DMatrix& rootTransform = rootLayer->GetTransform();
float scaleX = rootTransform.GetXScale();
float scaleY = rootTransform.GetYScale();
LayerToCSSScale scale(rootTransform.GetXScale(),
rootTransform.GetYScale());
// Get the content document bounds, in screen-space.
const FrameMetrics& metrics = scrollableLayer->GetFrameMetrics();
const LayerIntRect content = LayerIntRect::FromCSSRectRounded(metrics.mScrollableRect,
1 / scaleX,
1 / scaleY);
const LayerIntRect content = RoundedToInt(metrics.mScrollableRect / scale);
gfx::Point scrollOffset =
gfx::Point((metrics.mScrollOffset.x * metrics.LayersPixelsPerCSSPixel().width) / scaleX,
(metrics.mScrollOffset.y * metrics.LayersPixelsPerCSSPixel().height) / scaleY);
gfx::Point((metrics.mScrollOffset.x * metrics.LayersPixelsPerCSSPixel().width) / scale.scale,
(metrics.mScrollOffset.y * metrics.LayersPixelsPerCSSPixel().height) / scale.scale);
const nsIntPoint contentOrigin(
content.x - NS_lround(scrollOffset.x),
content.y - NS_lround(scrollOffset.y));

View File

@ -106,24 +106,6 @@ struct CSSPixel {
* 3) the "widget scale" (nsIWidget::GetDefaultScale)
*/
struct LayerPixel {
// Conversions from CSS units
static LayerIntPoint FromCSSPointRounded(const CSSPoint& aPoint, float aResolutionX, float aResolutionY) {
return LayerIntPoint(NS_lround(aPoint.x * aResolutionX),
NS_lround(aPoint.y * aResolutionY));
}
static LayerRect FromCSSRect(const CSSRect& aRect, float aResolutionX, float aResolutionY) {
return LayerRect(aRect.x * aResolutionX,
aRect.y * aResolutionY,
aRect.width * aResolutionX,
aRect.height * aResolutionY);
}
static LayerIntRect FromCSSRectRounded(const CSSRect& aRect, float aResolutionX, float aResolutionY) {
return gfx::RoundedToInt(FromCSSRect(aRect, aResolutionX, aResolutionY));
}
};
/*
@ -146,7 +128,7 @@ struct ScreenPixel {
}
};
// Operators to apply ScaleFactors directly to Points
// Operators to apply ScaleFactors directly to Points and Rects
template<class src, class dst>
gfx::PointTyped<dst> operator*(const gfx::PointTyped<src>& aPoint, const gfx::ScaleFactor<src, dst>& aScale) {
@ -160,6 +142,22 @@ gfx::PointTyped<dst> operator/(const gfx::PointTyped<src>& aPoint, const gfx::Sc
aPoint.y / aScale.scale);
}
template<class src, class dst>
gfx::RectTyped<dst> operator*(const gfx::RectTyped<src>& aRect, const gfx::ScaleFactor<src, dst>& aScale) {
return gfx::RectTyped<dst>(aRect.x * aScale.scale,
aRect.y * aScale.scale,
aRect.width * aScale.scale,
aRect.height * aScale.scale);
}
template<class src, class dst>
gfx::RectTyped<dst> operator/(const gfx::RectTyped<src>& aRect, const gfx::ScaleFactor<dst, src>& aScale) {
return gfx::RectTyped<dst>(aRect.x / aScale.scale,
aRect.y / aScale.scale,
aRect.width / aScale.scale,
aRect.height / aScale.scale);
}
};
#endif

View File

@ -937,7 +937,7 @@ 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 = LayerRect::FromCSSRect(aDisplayPort, aDisplayResolution, aDisplayResolution);
LayerRect dpUnrounded = aDisplayPort * CSSToLayerScale(aDisplayResolution);
dpUnrounded += LayerPoint::FromUnknownPoint(aScrollOffset.ToUnknownPoint());
LayerIntRect dp = gfx::RoundedToInt(dpUnrounded);