mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 13:51:41 +00:00
Bug 784908: Part 1: Change names of FrameMetrics variables to be more descriptive, add documentation, change some coordinate spaces. r=roc
This commit is contained in:
parent
dda6595530
commit
4b01b719b1
@ -206,38 +206,38 @@ const ContentPanning = {
|
||||
let metrics = data.json;
|
||||
let displayPort = metrics.displayPort;
|
||||
|
||||
let screenWidth = metrics.screenSize.width;
|
||||
let screenHeight = metrics.screenSize.height;
|
||||
let compositionWidth = metrics.compositionBounds.width;
|
||||
let compositionHeight = metrics.compositionBounds.height;
|
||||
|
||||
let x = metrics.x;
|
||||
let y = metrics.y;
|
||||
|
||||
this._zoom = metrics.zoom;
|
||||
this._viewport = new Rect(x, y,
|
||||
screenWidth / metrics.zoom,
|
||||
screenHeight / metrics.zoom);
|
||||
compositionWidth / metrics.zoom,
|
||||
compositionHeight / metrics.zoom);
|
||||
this._cssPageRect = new Rect(metrics.cssPageRect.x,
|
||||
metrics.cssPageRect.y,
|
||||
metrics.cssPageRect.width,
|
||||
metrics.cssPageRect.height);
|
||||
|
||||
let cwu = content.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
if (this._screenWidth != screenWidth || this._screenHeight != screenHeight) {
|
||||
cwu.setCSSViewport(screenWidth, screenHeight);
|
||||
this._screenWidth = screenWidth;
|
||||
this._screenHeight = screenHeight;
|
||||
if (this._compositionWidth != compositionWidth || this._compositionHeight != compositionHeight) {
|
||||
cwu.setCSSViewport(compositionWidth, compositionHeight);
|
||||
this._compositionWidth = compositionWidth;
|
||||
this._compositionHeight = compositionHeight;
|
||||
}
|
||||
|
||||
// Set scroll position
|
||||
cwu.setScrollPositionClampingScrollPortSize(
|
||||
screenWidth / metrics.zoom, screenHeight / metrics.zoom);
|
||||
compositionWidth / metrics.zoom, compositionHeight / metrics.zoom);
|
||||
content.scrollTo(x, y);
|
||||
cwu.setResolution(displayPort.resolution, displayPort.resolution);
|
||||
|
||||
let element = null;
|
||||
if (content.document && (element = content.document.documentElement)) {
|
||||
cwu.setDisplayPortForElement(displayPort.left,
|
||||
displayPort.top,
|
||||
cwu.setDisplayPortForElement(displayPort.x,
|
||||
displayPort.y,
|
||||
displayPort.width,
|
||||
displayPort.height,
|
||||
element);
|
||||
@ -272,7 +272,7 @@ const ContentPanning = {
|
||||
|
||||
let cssPageRect = this._cssPageRect;
|
||||
let viewport = this._viewport;
|
||||
let bRect = new Rect(Math.max(cssPageRect.left, rect.x - margin),
|
||||
let bRect = new Rect(Math.max(cssPageRect.x, rect.x - margin),
|
||||
rect.y,
|
||||
rect.w + 2 * margin,
|
||||
rect.h);
|
||||
|
@ -843,27 +843,29 @@ TabChild::RecvUpdateFrame(const FrameMetrics& aFrameMetrics)
|
||||
}
|
||||
|
||||
nsCString data;
|
||||
data += nsPrintfCString("{ \"x\" : %d", NS_lround(aFrameMetrics.mViewportScrollOffset.x));
|
||||
data += nsPrintfCString(", \"y\" : %d", NS_lround(aFrameMetrics.mViewportScrollOffset.y));
|
||||
data += nsPrintfCString("{ \"x\" : %d", NS_lround(aFrameMetrics.mScrollOffset.x));
|
||||
data += nsPrintfCString(", \"y\" : %d", NS_lround(aFrameMetrics.mScrollOffset.y));
|
||||
// We don't treat the x and y scales any differently for this
|
||||
// semi-platform-specific code.
|
||||
data += nsPrintfCString(", \"zoom\" : %f", aFrameMetrics.mResolution.width);
|
||||
data += nsPrintfCString(", \"displayPort\" : ");
|
||||
data += nsPrintfCString("{ \"left\" : %d", aFrameMetrics.mDisplayPort.X());
|
||||
data += nsPrintfCString(", \"top\" : %d", aFrameMetrics.mDisplayPort.Y());
|
||||
data += nsPrintfCString(", \"width\" : %d", aFrameMetrics.mDisplayPort.Width());
|
||||
data += nsPrintfCString(", \"height\" : %d", aFrameMetrics.mDisplayPort.Height());
|
||||
data += nsPrintfCString("{ \"x\" : %f", aFrameMetrics.mDisplayPort.x);
|
||||
data += nsPrintfCString(", \"y\" : %f", aFrameMetrics.mDisplayPort.y);
|
||||
data += nsPrintfCString(", \"width\" : %f", aFrameMetrics.mDisplayPort.width);
|
||||
data += nsPrintfCString(", \"height\" : %f", aFrameMetrics.mDisplayPort.height);
|
||||
data += nsPrintfCString(", \"resolution\" : %f", aFrameMetrics.mResolution.width);
|
||||
data += nsPrintfCString(" }");
|
||||
data += nsPrintfCString(", \"screenSize\" : ");
|
||||
data += nsPrintfCString("{ \"width\" : %d", aFrameMetrics.mViewport.width);
|
||||
data += nsPrintfCString(", \"height\" : %d", aFrameMetrics.mViewport.height);
|
||||
data += nsPrintfCString(", \"compositionBounds\" : ");
|
||||
data += nsPrintfCString("{ \"x\" : %d", aFrameMetrics.mCompositionBounds.x);
|
||||
data += nsPrintfCString(", \"y\" : %d", aFrameMetrics.mCompositionBounds.y);
|
||||
data += nsPrintfCString(", \"width\" : %d", aFrameMetrics.mCompositionBounds.width);
|
||||
data += nsPrintfCString(", \"height\" : %d", aFrameMetrics.mCompositionBounds.height);
|
||||
data += nsPrintfCString(" }");
|
||||
data += nsPrintfCString(", \"cssPageRect\" : ");
|
||||
data += nsPrintfCString("{ \"x\" : %f", aFrameMetrics.mCSSContentRect.x);
|
||||
data += nsPrintfCString(", \"y\" : %f", aFrameMetrics.mCSSContentRect.y);
|
||||
data += nsPrintfCString(", \"width\" : %f", aFrameMetrics.mCSSContentRect.width);
|
||||
data += nsPrintfCString(", \"height\" : %f", aFrameMetrics.mCSSContentRect.height);
|
||||
data += nsPrintfCString("{ \"x\" : %f", aFrameMetrics.mScrollableRect.x);
|
||||
data += nsPrintfCString(", \"y\" : %f", aFrameMetrics.mScrollableRect.y);
|
||||
data += nsPrintfCString(", \"width\" : %f", aFrameMetrics.mScrollableRect.width);
|
||||
data += nsPrintfCString(", \"height\" : %f", aFrameMetrics.mScrollableRect.height);
|
||||
data += nsPrintfCString(" }");
|
||||
data += nsPrintfCString(" }");
|
||||
|
||||
|
@ -403,6 +403,21 @@ struct BaseRect {
|
||||
width = right - x;
|
||||
height = bottom - y;
|
||||
}
|
||||
// Scale 'this' by 1/aScale, converting coordinates to integers so that the result is
|
||||
// the largest integer-coordinate rectangle contained by the unrounded result.
|
||||
void ScaleInverseRoundIn(double aScale) { ScaleInverseRoundIn(aScale, aScale); }
|
||||
// Scale 'this' by 1/aXScale and 1/aYScale, converting coordinates to integers so
|
||||
// that the result is the largest integer-coordinate rectangle contained by the
|
||||
// unrounded result.
|
||||
void ScaleInverseRoundIn(double aXScale, double aYScale)
|
||||
{
|
||||
T right = static_cast<T>(floor(double(XMost()) / aXScale));
|
||||
T bottom = static_cast<T>(floor(double(YMost()) / aYScale));
|
||||
x = static_cast<T>(ceil(double(x) / aXScale));
|
||||
y = static_cast<T>(ceil(double(y) / aYScale));
|
||||
width = gfx_max<T>(0, right - x);
|
||||
height = gfx_max<T>(0, bottom - y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clamp aPoint to this rectangle. It is allowed to end up on any
|
||||
|
@ -30,12 +30,15 @@ public:
|
||||
// will begin at.
|
||||
|
||||
FrameMetrics()
|
||||
: mViewport(0, 0, 0, 0)
|
||||
: mCompositionBounds(0, 0, 0, 0)
|
||||
, mContentRect(0, 0, 0, 0)
|
||||
, mViewportScrollOffset(0, 0)
|
||||
, mDisplayPort(0, 0, 0, 0)
|
||||
, mViewport(0, 0, 0, 0)
|
||||
, mScrollOffset(0, 0)
|
||||
, mScrollId(NULL_SCROLL_ID)
|
||||
, mCSSContentRect(0, 0, 0, 0)
|
||||
, mScrollableRect(0, 0, 0, 0)
|
||||
, mResolution(1, 1)
|
||||
, mDevPixelsPerCSSPixel(1)
|
||||
, mMayHaveTouchListeners(false)
|
||||
{}
|
||||
|
||||
@ -44,7 +47,7 @@ public:
|
||||
bool operator==(const FrameMetrics& aOther) const
|
||||
{
|
||||
return (mViewport.IsEqualEdges(aOther.mViewport) &&
|
||||
mViewportScrollOffset == aOther.mViewportScrollOffset &&
|
||||
mScrollOffset == aOther.mScrollOffset &&
|
||||
mDisplayPort.IsEqualEdges(aOther.mDisplayPort) &&
|
||||
mScrollId == aOther.mScrollId);
|
||||
}
|
||||
@ -68,21 +71,129 @@ public:
|
||||
return mScrollId != NULL_SCROLL_ID;
|
||||
}
|
||||
|
||||
// These are all in layer coordinate space.
|
||||
nsIntRect mViewport;
|
||||
gfxSize LayersPixelsPerCSSPixel() const
|
||||
{
|
||||
return mResolution * mDevPixelsPerCSSPixel;
|
||||
}
|
||||
|
||||
gfx::Point GetScrollOffsetInLayerPixels() const
|
||||
{
|
||||
return gfx::Point(mScrollOffset.x * LayersPixelsPerCSSPixel().width,
|
||||
mScrollOffset.y * LayersPixelsPerCSSPixel().height);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// The following metrics are all in widget space/device pixels.
|
||||
//
|
||||
|
||||
// This is the area within the widget that we're compositing to, which means
|
||||
// that it is the visible region of this frame. It is not relative to
|
||||
// anything.
|
||||
// So { 0, 0, [compositeArea.width], [compositeArea.height] }.
|
||||
//
|
||||
// This is useful because, on mobile, the viewport and composition dimensions
|
||||
// are not always the same. In this case, we calculate the displayport using
|
||||
// an area bigger than the region we're compositing to. If we used the
|
||||
// viewport dimensions to calculate the displayport, we'd run into situations
|
||||
// where we're prerendering the wrong regions and the content may be clipped,
|
||||
// or too much of it prerendered. If the displayport is the same as the
|
||||
// viewport, there is no need for this and we can just use the viewport
|
||||
// instead.
|
||||
//
|
||||
// This is only valid on the root layer. Nested iframes do not need this
|
||||
// metric as they do not have a displayport set. See bug 775452.
|
||||
nsIntRect mCompositionBounds;
|
||||
|
||||
// |mScrollableRect|, stored in device pixels. DECPRECATED, DO NOT USE.
|
||||
//
|
||||
// This is valid on any layer where |mScrollableRect| is, though it may be
|
||||
// more lazily maintained than |mScrollableRect|. That is, when
|
||||
// |mScrollableRect| is updated, this may lag. For this reason, it's better to
|
||||
// use |mScrollableRect| for any control logic.
|
||||
//
|
||||
// FIXME/bug 785929: Is this really necessary? Can it not be calculated from
|
||||
// |mScrollableRect| whenever it's needed?
|
||||
nsIntRect mContentRect;
|
||||
gfx::Point mViewportScrollOffset;
|
||||
nsIntRect mDisplayPort;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// The following metrics are all in CSS pixels. They are not in any uniform
|
||||
// space, so each is explained separately.
|
||||
//
|
||||
|
||||
// The area of a frame's contents that has been painted, relative to the
|
||||
// viewport. It is in the same coordinate space as |mViewport|. For example,
|
||||
// if it is at 0,0, then it's at the same place at the viewport, which is at
|
||||
// the top-left in the layer, and at the same place as the scroll offset of
|
||||
// the document.
|
||||
//
|
||||
// Note that this is structured in such a way that it doesn't depend on the
|
||||
// method layout uses to scroll content.
|
||||
//
|
||||
// May be larger or smaller than |mScrollableRect|.
|
||||
//
|
||||
// To pre-render a margin of 100 CSS pixels around the window,
|
||||
// { x = -100, y = - 100,
|
||||
// width = window.innerWidth + 100, height = window.innerHeight + 100 }
|
||||
//
|
||||
// This is only valid on the root layer. Nested iframes do not have a
|
||||
// displayport set on them. See bug 775452.
|
||||
gfx::Rect mDisplayPort;
|
||||
|
||||
// The CSS viewport, which is the dimensions we're using to constrain the
|
||||
// <html> element of this frame, relative to the top-left of the layer. Note
|
||||
// that its offset is structured in such a way that it doesn't depend on the
|
||||
// method layout uses to scroll content.
|
||||
//
|
||||
// This is mainly useful on the root layer, however nested iframes can have
|
||||
// their own viewport, which will just be the size of the window of the
|
||||
// iframe. For layers that don't correspond to a document, this metric is
|
||||
// meaningless and invalid.
|
||||
gfx::Rect mViewport;
|
||||
|
||||
// The position of the top-left of the CSS viewport, relative to the document
|
||||
// (or the document relative to the viewport, if that helps understand it).
|
||||
//
|
||||
// Thus it is relative to the document. It is in the same coordinate space as
|
||||
// |mScrollableRect|, but a different coordinate space than |mViewport| and
|
||||
// |mDisplayPort|.
|
||||
//
|
||||
// It is required that the rect:
|
||||
// { x = mScrollOffset.x, y = mScrollOffset.y,
|
||||
// width = mCompositionBounds.x / mResolution.width,
|
||||
// height = mCompositionBounds.y / mResolution.height }
|
||||
// Be within |mScrollableRect|.
|
||||
//
|
||||
// This is valid for any layer, but is always relative to this frame and
|
||||
// not any parents, regardless of parent transforms.
|
||||
gfx::Point mScrollOffset;
|
||||
|
||||
// A unique ID assigned to each scrollable frame (unless this is
|
||||
// ROOT_SCROLL_ID, in which case it is not unique).
|
||||
ViewID mScrollId;
|
||||
|
||||
// Consumers often want to know the origin/size before scaling to pixels
|
||||
// so we record this as well.
|
||||
gfx::Rect mCSSContentRect;
|
||||
// The scrollable bounds of a frame. This is determined by reflow.
|
||||
// For the top-level |window|,
|
||||
// { x = window.scrollX, y = window.scrollY, // could be 0, 0
|
||||
// width = window.innerWidth, height = window.innerHeight }
|
||||
//
|
||||
// This is relative to the document. It is in the same coordinate space as
|
||||
// |mScrollOffset|, but a different coordinate space than |mViewport| and
|
||||
// |mDisplayPort|. Note also that this coordinate system is understood by
|
||||
// window.scrollTo().
|
||||
//
|
||||
// This is valid on any layer unless it has no content.
|
||||
gfx::Rect mScrollableRect;
|
||||
|
||||
// This represents the resolution at which the associated layer
|
||||
// will been rendered.
|
||||
gfxSize mResolution;
|
||||
|
||||
// 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;
|
||||
|
||||
// Whether or not this frame may have touch listeners.
|
||||
bool mMayHaveTouchListeners;
|
||||
};
|
||||
|
@ -143,6 +143,17 @@ AppendToString(nsACString& s, const nsIntRect& r,
|
||||
return s += sfx;
|
||||
}
|
||||
|
||||
nsACString&
|
||||
AppendToString(nsACString& s, const Rect& r,
|
||||
const char* pfx="", const char* sfx="")
|
||||
{
|
||||
s += pfx;
|
||||
s.AppendPrintf(
|
||||
"(x=%f, y=%f, w=%f, h=%f)",
|
||||
r.x, r.y, r.width, r.height);
|
||||
return s += sfx;
|
||||
}
|
||||
|
||||
nsACString&
|
||||
AppendToString(nsACString& s, const nsIntRegion& r,
|
||||
const char* pfx="", const char* sfx="")
|
||||
@ -173,7 +184,7 @@ AppendToString(nsACString& s, const FrameMetrics& m,
|
||||
{
|
||||
s += pfx;
|
||||
AppendToString(s, m.mViewport, "{ viewport=");
|
||||
AppendToString(s, m.mViewportScrollOffset, " viewportScroll=");
|
||||
AppendToString(s, m.mScrollOffset, " viewportScroll=");
|
||||
AppendToString(s, m.mDisplayPort, " displayport=");
|
||||
AppendToString(s, m.mScrollId, " scrollId=", " }");
|
||||
return s += sfx;
|
||||
|
@ -253,7 +253,7 @@ BasicTiledThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
Layer* primaryScrollable = BasicManager()->GetPrimaryScrollableLayer();
|
||||
if (primaryScrollable) {
|
||||
const FrameMetrics& metrics = primaryScrollable->AsContainerLayer()->GetFrameMetrics();
|
||||
scrollOffset = metrics.mViewportScrollOffset;
|
||||
scrollOffset = metrics.mScrollOffset;
|
||||
}
|
||||
int32_t scrollDiffX = scrollOffset.x - mLastScrollOffset.x;
|
||||
int32_t scrollDiffY = scrollOffset.y - mLastScrollOffset.y;
|
||||
|
@ -138,10 +138,10 @@ AsyncPanZoomController::ReceiveInputEvent(const nsInputEvent& aEvent,
|
||||
{
|
||||
MonitorAutoLock monitor(mMonitor);
|
||||
currentZoom = mFrameMetrics.mResolution.width;
|
||||
currentScrollOffset = gfx::Point(mFrameMetrics.mViewportScrollOffset.x,
|
||||
mFrameMetrics.mViewportScrollOffset.y);
|
||||
lastScrollOffset = gfx::Point(mLastContentPaintMetrics.mViewportScrollOffset.x,
|
||||
mLastContentPaintMetrics.mViewportScrollOffset.y);
|
||||
currentScrollOffset = gfx::Point(mFrameMetrics.mScrollOffset.x,
|
||||
mFrameMetrics.mScrollOffset.y);
|
||||
lastScrollOffset = gfx::Point(mLastContentPaintMetrics.mScrollOffset.x,
|
||||
mLastContentPaintMetrics.mScrollOffset.y);
|
||||
}
|
||||
|
||||
nsEventStatus status;
|
||||
@ -669,10 +669,10 @@ void AsyncPanZoomController::SetCompositorParent(CompositorParent* aCompositorPa
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::ScrollBy(const gfx::Point& aOffset) {
|
||||
gfx::Point newOffset(mFrameMetrics.mViewportScrollOffset.x + aOffset.x,
|
||||
mFrameMetrics.mViewportScrollOffset.y + aOffset.y);
|
||||
gfx::Point newOffset(mFrameMetrics.mScrollOffset.x + aOffset.x,
|
||||
mFrameMetrics.mScrollOffset.y + aOffset.y);
|
||||
FrameMetrics metrics(mFrameMetrics);
|
||||
metrics.mViewportScrollOffset = newOffset;
|
||||
metrics.mScrollOffset = newOffset;
|
||||
mFrameMetrics = metrics;
|
||||
}
|
||||
|
||||
@ -682,12 +682,12 @@ void AsyncPanZoomController::SetPageRect(const gfx::Rect& aCSSPageRect) {
|
||||
float scale = mFrameMetrics.mResolution.width;
|
||||
|
||||
// The page rect is the css page rect scaled by the current zoom.
|
||||
pageSize.ScaleRoundOut(1 / scale);
|
||||
pageSize.ScaleInverseRoundOut(scale);
|
||||
|
||||
// Round the page rect so we don't get any truncation, then get the nsIntRect
|
||||
// from this.
|
||||
metrics.mContentRect = nsIntRect(pageSize.x, pageSize.y, pageSize.width, pageSize.height);
|
||||
metrics.mCSSContentRect = aCSSPageRect;
|
||||
metrics.mScrollableRect = aCSSPageRect;
|
||||
|
||||
mFrameMetrics = metrics;
|
||||
}
|
||||
@ -703,19 +703,19 @@ void AsyncPanZoomController::ScaleWithFocus(float aScale, const nsIntPoint& aFoc
|
||||
|
||||
// Force a recalculation of the page rect based on the new zoom and the
|
||||
// current CSS page rect (which is unchanged since it's not affected by zoom).
|
||||
SetPageRect(mFrameMetrics.mCSSContentRect);
|
||||
SetPageRect(mFrameMetrics.mScrollableRect);
|
||||
|
||||
gfx::Point scrollOffset = metrics.mViewportScrollOffset;
|
||||
gfx::Point scrollOffset = metrics.mScrollOffset;
|
||||
|
||||
scrollOffset.x += float(aFocus.x) * (scaleFactor - 1.0f) / oldScale;
|
||||
scrollOffset.y += float(aFocus.y) * (scaleFactor - 1.0f) / oldScale;
|
||||
|
||||
metrics.mViewportScrollOffset = scrollOffset;
|
||||
metrics.mScrollOffset = scrollOffset;
|
||||
|
||||
mFrameMetrics = metrics;
|
||||
}
|
||||
|
||||
bool AsyncPanZoomController::EnlargeDisplayPortAlongAxis(float aViewport,
|
||||
bool AsyncPanZoomController::EnlargeDisplayPortAlongAxis(float aCompositionBounds,
|
||||
float aVelocity,
|
||||
float* aDisplayPortOffset,
|
||||
float* aDisplayPortLength)
|
||||
@ -724,77 +724,50 @@ bool AsyncPanZoomController::EnlargeDisplayPortAlongAxis(float aViewport,
|
||||
const float MAX_SKATE_SIZE_MULTIPLIER = 4.0f;
|
||||
|
||||
if (fabsf(aVelocity) > MIN_SKATE_SPEED) {
|
||||
*aDisplayPortLength = aViewport * clamped(fabsf(aVelocity),
|
||||
*aDisplayPortLength = aCompositionBounds * clamped(fabsf(aVelocity),
|
||||
MIN_SKATE_SIZE_MULTIPLIER, MAX_SKATE_SIZE_MULTIPLIER);
|
||||
*aDisplayPortOffset = aVelocity > 0 ? 0 : aViewport - *aDisplayPortLength;
|
||||
*aDisplayPortOffset = aVelocity > 0 ? 0 : aCompositionBounds - *aDisplayPortLength;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const nsIntRect AsyncPanZoomController::CalculatePendingDisplayPort() {
|
||||
const gfx::Rect AsyncPanZoomController::CalculatePendingDisplayPort() {
|
||||
float scale = mFrameMetrics.mResolution.width;
|
||||
nsIntRect viewport = mFrameMetrics.mViewport;
|
||||
viewport.ScaleRoundIn(1 / scale);
|
||||
nsIntRect compositionBounds = mFrameMetrics.mCompositionBounds;
|
||||
compositionBounds.ScaleInverseRoundIn(scale);
|
||||
|
||||
gfx::Point scrollOffset = mFrameMetrics.mViewportScrollOffset;
|
||||
gfx::Point scrollOffset = mFrameMetrics.mScrollOffset;
|
||||
gfx::Point velocity = GetVelocityVector();
|
||||
|
||||
// The displayport is relative to the current scroll offset. Here's a little
|
||||
// diagram to make it easier to see:
|
||||
//
|
||||
// - - - -
|
||||
// | |
|
||||
// *************
|
||||
// * | | *
|
||||
// - -*- @------ -*- -
|
||||
// | * |=====| * |
|
||||
// * |=====| *
|
||||
// | * |=====| * |
|
||||
// - -*- ------- -*- -
|
||||
// * | | *
|
||||
// *************
|
||||
// | |
|
||||
// - - - -
|
||||
//
|
||||
// The full --- area with === inside it is the actual viewport rect, the *** area
|
||||
// is the displayport, and the - - - area is an imaginary additional page on all 4
|
||||
// borders of the actual page. Notice that the displayport intersects half-way with
|
||||
// each of the imaginary extra pages. The @ symbol at the top left of the
|
||||
// viewport marks the current scroll offset. From the @ symbol to the far left
|
||||
// and far top, it is clear that this distance is 1/4 of the displayport's
|
||||
// height/width dimension.
|
||||
const float STATIONARY_SIZE_MULTIPLIER = 2.0f;
|
||||
gfx::Rect displayPort(0, 0,
|
||||
viewport.width * STATIONARY_SIZE_MULTIPLIER,
|
||||
viewport.height * STATIONARY_SIZE_MULTIPLIER);
|
||||
compositionBounds.width * STATIONARY_SIZE_MULTIPLIER,
|
||||
compositionBounds.height * STATIONARY_SIZE_MULTIPLIER);
|
||||
|
||||
// If there's motion along an axis of movement, and it's above a threshold,
|
||||
// then we want to paint a larger area in the direction of that motion so that
|
||||
// it's less likely to checkerboard.
|
||||
bool enlargedX = EnlargeDisplayPortAlongAxis(
|
||||
viewport.width, velocity.x, &displayPort.x, &displayPort.width);
|
||||
compositionBounds.width, velocity.x, &displayPort.x, &displayPort.width);
|
||||
bool enlargedY = EnlargeDisplayPortAlongAxis(
|
||||
viewport.height, velocity.y, &displayPort.y, &displayPort.height);
|
||||
compositionBounds.height, velocity.y, &displayPort.y, &displayPort.height);
|
||||
|
||||
if (!enlargedX && !enlargedY) {
|
||||
displayPort.x = -displayPort.width / 4;
|
||||
displayPort.y = -displayPort.height / 4;
|
||||
} else if (!enlargedX) {
|
||||
displayPort.width = viewport.width;
|
||||
displayPort.width = compositionBounds.width;
|
||||
} else if (!enlargedY) {
|
||||
displayPort.height = viewport.height;
|
||||
displayPort.height = compositionBounds.height;
|
||||
}
|
||||
|
||||
gfx::Rect shiftedDisplayPort = displayPort;
|
||||
shiftedDisplayPort.MoveBy(scrollOffset.x, scrollOffset.y);
|
||||
displayPort = shiftedDisplayPort.Intersect(mFrameMetrics.mCSSContentRect);
|
||||
displayPort = shiftedDisplayPort.Intersect(mFrameMetrics.mScrollableRect);
|
||||
displayPort.MoveBy(-scrollOffset.x, -scrollOffset.y);
|
||||
|
||||
// Round the displayport so we don't get any truncation, then get the nsIntRect
|
||||
// from this.
|
||||
displayPort.Round();
|
||||
return nsIntRect(displayPort.x, displayPort.y, displayPort.width, displayPort.height);
|
||||
return displayPort;
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::SetDPI(int aDPI) {
|
||||
@ -814,22 +787,13 @@ void AsyncPanZoomController::ScheduleComposite() {
|
||||
void AsyncPanZoomController::RequestContentRepaint() {
|
||||
mFrameMetrics.mDisplayPort = CalculatePendingDisplayPort();
|
||||
|
||||
gfx::Point oldScrollOffset = mLastPaintRequestMetrics.mViewportScrollOffset,
|
||||
newScrollOffset = mFrameMetrics.mViewportScrollOffset;
|
||||
gfx::Point oldScrollOffset = mLastPaintRequestMetrics.mScrollOffset,
|
||||
newScrollOffset = mFrameMetrics.mScrollOffset;
|
||||
|
||||
// If we're trying to paint what we already think is painted, discard this
|
||||
// request since it's a pointless paint.
|
||||
nsRect oldDisplayPort = nsRect(
|
||||
mLastPaintRequestMetrics.mDisplayPort.x,
|
||||
mLastPaintRequestMetrics.mDisplayPort.y,
|
||||
mLastPaintRequestMetrics.mDisplayPort.width,
|
||||
mLastPaintRequestMetrics.mDisplayPort.height);
|
||||
|
||||
gfx::Rect newDisplayPort = gfx::Rect(
|
||||
mFrameMetrics.mDisplayPort.x,
|
||||
mFrameMetrics.mDisplayPort.y,
|
||||
mFrameMetrics.mDisplayPort.width,
|
||||
mFrameMetrics.mDisplayPort.height);
|
||||
gfx::Rect oldDisplayPort = mLastPaintRequestMetrics.mDisplayPort;
|
||||
gfx::Rect newDisplayPort = mFrameMetrics.mDisplayPort;
|
||||
|
||||
oldDisplayPort.MoveBy(oldScrollOffset.x, oldScrollOffset.y);
|
||||
newDisplayPort.MoveBy(newScrollOffset.x, newScrollOffset.y);
|
||||
@ -892,11 +856,11 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa
|
||||
mEndZoomToMetrics.mResolution.width * sampledPosition +
|
||||
mStartZoomToMetrics.mResolution.width * (1 - sampledPosition);
|
||||
|
||||
mFrameMetrics.mViewportScrollOffset = gfx::Point(
|
||||
mEndZoomToMetrics.mViewportScrollOffset.x * sampledPosition +
|
||||
mStartZoomToMetrics.mViewportScrollOffset.x * (1 - sampledPosition),
|
||||
mEndZoomToMetrics.mViewportScrollOffset.y * sampledPosition +
|
||||
mStartZoomToMetrics.mViewportScrollOffset.y * (1 - sampledPosition)
|
||||
mFrameMetrics.mScrollOffset = gfx::Point(
|
||||
mEndZoomToMetrics.mScrollOffset.x * sampledPosition +
|
||||
mStartZoomToMetrics.mScrollOffset.x * (1 - sampledPosition),
|
||||
mEndZoomToMetrics.mScrollOffset.y * sampledPosition +
|
||||
mStartZoomToMetrics.mScrollOffset.y * (1 - sampledPosition)
|
||||
);
|
||||
|
||||
requestAnimationFrame = true;
|
||||
@ -920,10 +884,10 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa
|
||||
localScaleY = mFrameMetrics.mResolution.height;
|
||||
|
||||
if (frame.IsScrollable()) {
|
||||
metricsScrollOffset = frame.mViewportScrollOffset;
|
||||
metricsScrollOffset = frame.GetScrollOffsetInLayerPixels();
|
||||
}
|
||||
|
||||
scrollOffset = mFrameMetrics.mViewportScrollOffset;
|
||||
scrollOffset = mFrameMetrics.mScrollOffset;
|
||||
}
|
||||
|
||||
nsIntPoint scrollCompensation(
|
||||
@ -974,8 +938,8 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aViewportFr
|
||||
case WAITING_LISTENERS:
|
||||
// FIXME/bug 784908: Scroll offset is stored in layer pixels in the rest
|
||||
// of the layers code, but we want it in CSS pixels.
|
||||
mFrameMetrics.mViewportScrollOffset =
|
||||
aViewportFrame.mViewportScrollOffset / aViewportFrame.mResolution.width;
|
||||
mFrameMetrics.mScrollOffset =
|
||||
aViewportFrame.mScrollOffset / aViewportFrame.mResolution.width;
|
||||
break;
|
||||
// Don't clobber if we're in other states.
|
||||
default:
|
||||
@ -988,10 +952,15 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aViewportFr
|
||||
|
||||
mX.CancelTouch();
|
||||
mY.CancelTouch();
|
||||
|
||||
// The composition bounds are not stored within the layers code, so we have
|
||||
// to reset them back to what they were every time we overwrite them.
|
||||
nsIntRect compositionBounds = mFrameMetrics.mCompositionBounds;
|
||||
mFrameMetrics = aViewportFrame;
|
||||
mFrameMetrics.mCompositionBounds = compositionBounds;
|
||||
mFrameMetrics.mResolution.width = 1 / mFrameMetrics.mResolution.width;
|
||||
mFrameMetrics.mResolution.height = 1 / mFrameMetrics.mResolution.height;
|
||||
SetPageRect(mFrameMetrics.mCSSContentRect);
|
||||
SetPageRect(mFrameMetrics.mScrollableRect);
|
||||
|
||||
// Bug 776413/fixme: Request a repaint as soon as a page is loaded so that
|
||||
// we get a larger displayport. This is very bad because we're wasting a
|
||||
@ -999,9 +968,9 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aViewportFr
|
||||
RequestContentRepaint();
|
||||
|
||||
mState = NOTHING;
|
||||
} else if (!mFrameMetrics.mCSSContentRect.IsEqualEdges(aViewportFrame.mCSSContentRect)) {
|
||||
mFrameMetrics.mCSSContentRect = aViewportFrame.mCSSContentRect;
|
||||
SetPageRect(mFrameMetrics.mCSSContentRect);
|
||||
} else if (!mFrameMetrics.mScrollableRect.IsEqualEdges(aViewportFrame.mScrollableRect)) {
|
||||
mFrameMetrics.mScrollableRect = aViewportFrame.mScrollableRect;
|
||||
SetPageRect(mFrameMetrics.mScrollableRect);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1010,10 +979,10 @@ const FrameMetrics& AsyncPanZoomController::GetFrameMetrics() {
|
||||
return mFrameMetrics;
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::UpdateViewportSize(int aWidth, int aHeight) {
|
||||
void AsyncPanZoomController::UpdateCompositionBounds(const nsIntRect& aCompositionBounds) {
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
FrameMetrics metrics = GetFrameMetrics();
|
||||
metrics.mViewport = nsIntRect(0, 0, aWidth, aHeight);
|
||||
metrics.mCompositionBounds = aCompositionBounds;
|
||||
mFrameMetrics = metrics;
|
||||
}
|
||||
|
||||
@ -1032,27 +1001,29 @@ void AsyncPanZoomController::ZoomToRect(const gfxRect& aRect) {
|
||||
{
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
|
||||
nsIntRect viewport = mFrameMetrics.mViewport;
|
||||
gfx::Rect cssPageRect = mFrameMetrics.mCSSContentRect;
|
||||
gfx::Point scrollOffset = mFrameMetrics.mViewportScrollOffset;
|
||||
nsIntRect compositionBounds = mFrameMetrics.mCompositionBounds;
|
||||
gfx::Rect cssPageRect = mFrameMetrics.mScrollableRect;
|
||||
gfx::Point scrollOffset = mFrameMetrics.mScrollOffset;
|
||||
|
||||
// If the rect is empty, treat it as a request to zoom out to the full page
|
||||
// size.
|
||||
if (zoomToRect.IsEmpty()) {
|
||||
nsIntRect cssViewport = viewport;
|
||||
cssViewport.ScaleRoundIn(1 / mFrameMetrics.mResolution.width);
|
||||
cssViewport.MoveBy(nsIntPoint(NS_lround(scrollOffset.x), NS_lround(scrollOffset.y)));
|
||||
// composition bounds in CSS coordinates
|
||||
nsIntRect cssCompositionBounds = compositionBounds;
|
||||
cssCompositionBounds.ScaleInverseRoundIn(mFrameMetrics.mResolution.width);
|
||||
cssCompositionBounds.MoveBy(scrollOffset.x, scrollOffset.y);
|
||||
|
||||
float y = mFrameMetrics.mViewportScrollOffset.y;
|
||||
float newHeight = cssViewport.height * cssPageRect.width / cssViewport.width;
|
||||
float dh = cssViewport.height - newHeight;
|
||||
float y = mFrameMetrics.mScrollOffset.y;
|
||||
float newHeight =
|
||||
cssCompositionBounds.height * cssPageRect.width / cssCompositionBounds.width;
|
||||
float dh = cssCompositionBounds.height - newHeight;
|
||||
|
||||
zoomToRect = gfx::Rect(0.0f,
|
||||
y + dh/2,
|
||||
cssPageRect.width,
|
||||
y + dh/2 + newHeight);
|
||||
} else {
|
||||
float targetRatio = float(viewport.width) / float(viewport.height);
|
||||
float targetRatio = float(compositionBounds.width) / float(compositionBounds.height);
|
||||
float rectRatio = zoomToRect.width / zoomToRect.height;
|
||||
|
||||
if (fabsf(targetRatio - rectRatio) < EPSILON) {
|
||||
@ -1073,24 +1044,24 @@ void AsyncPanZoomController::ZoomToRect(const gfxRect& aRect) {
|
||||
}
|
||||
|
||||
mEndZoomToMetrics.mResolution.width = mEndZoomToMetrics.mResolution.height =
|
||||
NS_MIN(viewport.width / zoomToRect.width, viewport.height / zoomToRect.height);
|
||||
NS_MIN(compositionBounds.width / zoomToRect.width, compositionBounds.height / zoomToRect.height);
|
||||
|
||||
mEndZoomToMetrics.mResolution.width = mEndZoomToMetrics.mResolution.height =
|
||||
clamped(mEndZoomToMetrics.mResolution.width, MIN_ZOOM, MAX_ZOOM);
|
||||
|
||||
// Recalculate the zoom to rect using the new dimensions.
|
||||
zoomToRect.width = viewport.width / mEndZoomToMetrics.mResolution.width;
|
||||
zoomToRect.height = viewport.height / mEndZoomToMetrics.mResolution.height;
|
||||
zoomToRect.width = compositionBounds.width / mEndZoomToMetrics.mResolution.width;
|
||||
zoomToRect.height = compositionBounds.height / mEndZoomToMetrics.mResolution.height;
|
||||
|
||||
// Clamp the zoom to rect to the CSS rect to make sure it fits.
|
||||
zoomToRect = zoomToRect.Intersect(cssPageRect);
|
||||
|
||||
// Do one final recalculation to get the resolution.
|
||||
mEndZoomToMetrics.mResolution.width = mEndZoomToMetrics.mResolution.height =
|
||||
NS_MAX(viewport.width / zoomToRect.width, viewport.height / zoomToRect.height);
|
||||
NS_MAX(compositionBounds.width / zoomToRect.width, compositionBounds.height / zoomToRect.height);
|
||||
|
||||
mStartZoomToMetrics = mFrameMetrics;
|
||||
mEndZoomToMetrics.mViewportScrollOffset =
|
||||
mEndZoomToMetrics.mScrollOffset =
|
||||
gfx::Point(zoomToRect.x, zoomToRect.y);
|
||||
|
||||
mAnimationStartTime = TimeStamp::Now();
|
||||
|
@ -97,17 +97,13 @@ public:
|
||||
nsInputEvent* aOutEvent);
|
||||
|
||||
/**
|
||||
* Updates the viewport size, i.e. the dimensions of the frame (not
|
||||
* necessarily the screen) content will actually be rendered onto in device
|
||||
* pixels for example, a subframe will not take the entire screen, but we
|
||||
* still want to know how big it is in device pixels. Ideally we want to be
|
||||
* using CSS pixels everywhere inside here, but in this case we need to know
|
||||
* how large of a displayport to set so we use these dimensions plus some
|
||||
* extra.
|
||||
*
|
||||
* XXX: Use nsIntRect instead.
|
||||
* Updates the composition bounds, i.e. the dimensions of the final size of
|
||||
* the frame this is tied to during composition onto, in device pixels. In
|
||||
* general, this will just be:
|
||||
* { x = 0, y = 0, width = surface.width, height = surface.height }, however
|
||||
* there is no hard requirement for this.
|
||||
*/
|
||||
void UpdateViewportSize(int aWidth, int aHeight);
|
||||
void UpdateCompositionBounds(const nsIntRect& aCompositionBounds);
|
||||
|
||||
/**
|
||||
* We have found a scrollable subframe, so disable our machinery until we hit
|
||||
@ -350,7 +346,7 @@ protected:
|
||||
* a larger area than the screen so that when you scroll down, you don't
|
||||
* checkerboard immediately.
|
||||
*/
|
||||
const nsIntRect CalculatePendingDisplayPort();
|
||||
const gfx::Rect CalculatePendingDisplayPort();
|
||||
|
||||
/**
|
||||
* Attempts to enlarge the displayport along a single axis. Returns whether or
|
||||
@ -360,7 +356,7 @@ protected:
|
||||
* |aDisplayPortLength|. If enlarged, these will be updated with the new
|
||||
* metrics.
|
||||
*/
|
||||
bool EnlargeDisplayPortAlongAxis(float aViewport, float aVelocity,
|
||||
bool EnlargeDisplayPortAlongAxis(float aCompositionBounds, float aVelocity,
|
||||
float* aDisplayPortOffset, float* aDisplayPortLength);
|
||||
|
||||
/**
|
||||
|
@ -140,12 +140,12 @@ bool Axis::FlingApplyFrictionOrCancel(const TimeDuration& aDelta) {
|
||||
}
|
||||
|
||||
Axis::Overscroll Axis::GetOverscroll() {
|
||||
// If the current pan takes the viewport to the left of or above the current
|
||||
// If the current pan takes the window to the left of or above the current
|
||||
// page rect.
|
||||
bool minus = GetOrigin() < GetPageStart();
|
||||
// If the current pan takes the viewport to the right of or below the current
|
||||
// If the current pan takes the window to the right of or below the current
|
||||
// page rect.
|
||||
bool plus = GetViewportEnd() > GetPageEnd();
|
||||
bool plus = GetCompositionEnd() > GetPageEnd();
|
||||
if (minus && plus) {
|
||||
return OVERSCROLL_BOTH;
|
||||
}
|
||||
@ -161,19 +161,20 @@ Axis::Overscroll Axis::GetOverscroll() {
|
||||
float Axis::GetExcess() {
|
||||
switch (GetOverscroll()) {
|
||||
case OVERSCROLL_MINUS: return GetOrigin() - GetPageStart();
|
||||
case OVERSCROLL_PLUS: return GetViewportEnd() - GetPageEnd();
|
||||
case OVERSCROLL_BOTH: return (GetViewportEnd() - GetPageEnd()) + (GetPageStart() - GetOrigin());
|
||||
case OVERSCROLL_PLUS: return GetCompositionEnd() - GetPageEnd();
|
||||
case OVERSCROLL_BOTH: return (GetCompositionEnd() - GetPageEnd()) +
|
||||
(GetPageStart() - GetOrigin());
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Axis::Overscroll Axis::DisplacementWillOverscroll(int32_t aDisplacement) {
|
||||
// If the current pan plus a displacement takes the viewport to the left of or
|
||||
// If the current pan plus a displacement takes the window to the left of or
|
||||
// above the current page rect.
|
||||
bool minus = GetOrigin() + aDisplacement < GetPageStart();
|
||||
// If the current pan plus a displacement takes the viewport to the right of or
|
||||
// If the current pan plus a displacement takes the window to the right of or
|
||||
// below the current page rect.
|
||||
bool plus = GetViewportEnd() + aDisplacement > GetPageEnd();
|
||||
bool plus = GetCompositionEnd() + aDisplacement > GetPageEnd();
|
||||
if (minus && plus) {
|
||||
return OVERSCROLL_BOTH;
|
||||
}
|
||||
@ -189,7 +190,7 @@ Axis::Overscroll Axis::DisplacementWillOverscroll(int32_t aDisplacement) {
|
||||
float Axis::DisplacementWillOverscrollAmount(int32_t aDisplacement) {
|
||||
switch (DisplacementWillOverscroll(aDisplacement)) {
|
||||
case OVERSCROLL_MINUS: return (GetOrigin() + aDisplacement) - GetPageStart();
|
||||
case OVERSCROLL_PLUS: return (GetViewportEnd() + aDisplacement) - GetPageEnd();
|
||||
case OVERSCROLL_PLUS: return (GetCompositionEnd() + aDisplacement) - GetPageEnd();
|
||||
// Don't handle overscrolled in both directions; a displacement can't cause
|
||||
// this, it must have already been zoomed out too far.
|
||||
default: return 0;
|
||||
@ -201,7 +202,7 @@ Axis::Overscroll Axis::ScaleWillOverscroll(float aScale, int32_t aFocus) {
|
||||
|
||||
bool both = ScaleWillOverscrollBothSides(aScale);
|
||||
bool minus = originAfterScale < GetPageStart() * aScale;
|
||||
bool plus = (originAfterScale + GetViewportLength()) > GetPageEnd() * aScale;
|
||||
bool plus = (originAfterScale + GetCompositionLength()) > GetPageEnd() * aScale;
|
||||
|
||||
if ((minus && plus) || both) {
|
||||
return OVERSCROLL_BOTH;
|
||||
@ -219,7 +220,8 @@ float Axis::ScaleWillOverscrollAmount(float aScale, int32_t aFocus) {
|
||||
float originAfterScale = (GetOrigin() + aFocus) * aScale - aFocus;
|
||||
switch (ScaleWillOverscroll(aScale, aFocus)) {
|
||||
case OVERSCROLL_MINUS: return originAfterScale - GetPageStart() * aScale;
|
||||
case OVERSCROLL_PLUS: return (originAfterScale + GetViewportLength()) - GetPageEnd() * aScale;
|
||||
case OVERSCROLL_PLUS: return (originAfterScale + GetCompositionLength()) -
|
||||
NS_lround(GetPageEnd() * aScale);
|
||||
// Don't handle OVERSCROLL_BOTH. Client code is expected to deal with it.
|
||||
default: return 0;
|
||||
}
|
||||
@ -229,8 +231,8 @@ float Axis::GetVelocity() {
|
||||
return mVelocity;
|
||||
}
|
||||
|
||||
float Axis::GetViewportEnd() {
|
||||
return GetOrigin() + GetViewportLength();
|
||||
float Axis::GetCompositionEnd() {
|
||||
return GetOrigin() + GetCompositionLength();
|
||||
}
|
||||
|
||||
float Axis::GetPageEnd() {
|
||||
@ -238,40 +240,44 @@ float Axis::GetPageEnd() {
|
||||
}
|
||||
|
||||
float Axis::GetOrigin() {
|
||||
gfx::Point origin = mAsyncPanZoomController->GetFrameMetrics().mViewportScrollOffset;
|
||||
gfx::Point origin = mAsyncPanZoomController->GetFrameMetrics().mScrollOffset;
|
||||
return GetPointOffset(origin);
|
||||
}
|
||||
|
||||
float Axis::GetViewportLength() {
|
||||
nsIntRect viewport = mAsyncPanZoomController->GetFrameMetrics().mViewport;
|
||||
gfx::Rect scaledViewport = gfx::Rect(viewport.x, viewport.y, viewport.width, viewport.height);
|
||||
scaledViewport.ScaleRoundIn(1 / mAsyncPanZoomController->GetFrameMetrics().mResolution.width);
|
||||
return GetRectLength(scaledViewport);
|
||||
float Axis::GetCompositionLength() {
|
||||
nsIntRect compositionBounds =
|
||||
mAsyncPanZoomController->GetFrameMetrics().mCompositionBounds;
|
||||
gfx::Rect scaledCompositionBounds =
|
||||
gfx::Rect(compositionBounds.x, compositionBounds.y,
|
||||
compositionBounds.width, compositionBounds.height);
|
||||
scaledCompositionBounds.ScaleInverseRoundIn(
|
||||
mAsyncPanZoomController->GetFrameMetrics().mResolution.width);
|
||||
return GetRectLength(scaledCompositionBounds);
|
||||
}
|
||||
|
||||
float Axis::GetPageStart() {
|
||||
gfx::Rect pageRect = mAsyncPanZoomController->GetFrameMetrics().mCSSContentRect;
|
||||
gfx::Rect pageRect = mAsyncPanZoomController->GetFrameMetrics().mScrollableRect;
|
||||
return GetRectOffset(pageRect);
|
||||
}
|
||||
|
||||
float Axis::GetPageLength() {
|
||||
gfx::Rect pageRect = mAsyncPanZoomController->GetFrameMetrics().mCSSContentRect;
|
||||
gfx::Rect pageRect = mAsyncPanZoomController->GetFrameMetrics().mScrollableRect;
|
||||
return GetRectLength(pageRect);
|
||||
}
|
||||
|
||||
bool Axis::ScaleWillOverscrollBothSides(float aScale) {
|
||||
const FrameMetrics& metrics = mAsyncPanZoomController->GetFrameMetrics();
|
||||
|
||||
gfx::Rect cssContentRect = metrics.mCSSContentRect;
|
||||
gfx::Rect cssContentRect = metrics.mScrollableRect;
|
||||
|
||||
float currentScale = metrics.mResolution.width;
|
||||
gfx::Rect viewport = gfx::Rect(metrics.mViewport.x,
|
||||
metrics.mViewport.y,
|
||||
metrics.mViewport.width,
|
||||
metrics.mViewport.height);
|
||||
viewport.ScaleRoundIn(1 / (currentScale * aScale));
|
||||
nsIntRect compositionBounds = metrics.mCompositionBounds;
|
||||
gfx::Rect scaledCompositionBounds =
|
||||
gfx::Rect(compositionBounds.x, compositionBounds.y,
|
||||
compositionBounds.width, compositionBounds.height);
|
||||
scaledCompositionBounds.ScaleInverseRoundIn(currentScale * aScale);
|
||||
|
||||
return GetRectLength(cssContentRect) < GetRectLength(viewport);
|
||||
return GetRectLength(cssContentRect) < GetRectLength(scaledCompositionBounds);
|
||||
}
|
||||
|
||||
AxisX::AxisX(AsyncPanZoomController* aAsyncPanZoomController)
|
||||
|
@ -165,10 +165,10 @@ public:
|
||||
bool ScaleWillOverscrollBothSides(float aScale);
|
||||
|
||||
float GetOrigin();
|
||||
float GetViewportLength();
|
||||
float GetCompositionLength();
|
||||
float GetPageStart();
|
||||
float GetPageLength();
|
||||
float GetViewportEnd();
|
||||
float GetCompositionEnd();
|
||||
float GetPageEnd();
|
||||
|
||||
virtual float GetPointOffset(const gfx::Point& aPoint) = 0;
|
||||
|
@ -467,8 +467,8 @@ private:
|
||||
}
|
||||
const FrameMetrics& fm = c->GetFrameMetrics();
|
||||
gfx3DMatrix m(aContainer->GetTransform());
|
||||
m.Translate(gfxPoint3D(-fm.mViewportScrollOffset.x,
|
||||
-fm.mViewportScrollOffset.y, 0));
|
||||
m.Translate(gfxPoint3D(-fm.GetScrollOffsetInLayerPixels().x,
|
||||
-fm.GetScrollOffsetInLayerPixels().y, 0));
|
||||
|
||||
// The transform already takes the resolution scale into account. Since we
|
||||
// will apply the resolution scale again when computing the effective
|
||||
@ -787,30 +787,43 @@ CompositorParent::TransformShadowTree(TimeStamp aCurrentFrame)
|
||||
|
||||
float rootScaleX = rootTransform.GetXScale(),
|
||||
rootScaleY = rootTransform.GetYScale();
|
||||
// The ratio of layers pixels to device pixels. The Java
|
||||
// compositor wants to see values in units of device pixels, so we
|
||||
// map our FrameMetrics values to that space. This is not exposed
|
||||
// as a FrameMetrics helper because it's a deprecated conversion.
|
||||
float devPixelRatioX = 1 / rootScaleX, devPixelRatioY = 1 / rootScaleY;
|
||||
|
||||
gfx::Point scrollOffsetLayersPixels(metrics.GetScrollOffsetInLayerPixels());
|
||||
nsIntPoint scrollOffsetDevPixels(
|
||||
NS_lround(scrollOffsetLayersPixels.x * devPixelRatioX),
|
||||
NS_lround(scrollOffsetLayersPixels.y * devPixelRatioY));
|
||||
|
||||
if (mIsFirstPaint) {
|
||||
mContentRect = metrics.mContentRect;
|
||||
const gfx::Point& scrollOffset = metrics.mViewportScrollOffset;
|
||||
SetFirstPaintViewport(nsIntPoint(NS_lround(scrollOffset.x),
|
||||
NS_lround(scrollOffset.y)),
|
||||
SetFirstPaintViewport(scrollOffsetDevPixels,
|
||||
1/rootScaleX,
|
||||
mContentRect,
|
||||
metrics.mCSSContentRect);
|
||||
metrics.mScrollableRect);
|
||||
mIsFirstPaint = false;
|
||||
} else if (!metrics.mContentRect.IsEqualEdges(mContentRect)) {
|
||||
mContentRect = metrics.mContentRect;
|
||||
SetPageRect(metrics.mCSSContentRect);
|
||||
SetPageRect(metrics.mScrollableRect);
|
||||
}
|
||||
|
||||
// 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
|
||||
nsIntRect displayPort = metrics.mDisplayPort;
|
||||
gfx::Point scrollOffset = metrics.mViewportScrollOffset;
|
||||
displayPort.x += NS_lround(scrollOffset.x);
|
||||
displayPort.y += NS_lround(scrollOffset.y);
|
||||
gfx::Rect displayPortLayersPixels(metrics.mDisplayPort);
|
||||
nsIntRect displayPortDevPixels(
|
||||
NS_lround(displayPortLayersPixels.x * devPixelRatioX),
|
||||
NS_lround(displayPortLayersPixels.y * devPixelRatioY),
|
||||
NS_lround(displayPortLayersPixels.width * devPixelRatioX),
|
||||
NS_lround(displayPortLayersPixels.height * devPixelRatioY));
|
||||
|
||||
SyncViewportInfo(displayPort, 1/rootScaleX, mLayersUpdated,
|
||||
displayPortDevPixels.x += scrollOffsetDevPixels.x;
|
||||
displayPortDevPixels.y += scrollOffsetDevPixels.y;
|
||||
|
||||
SyncViewportInfo(displayPortDevPixels, 1/rootScaleX, mLayersUpdated,
|
||||
mScrollOffset, mXScale, mYScale);
|
||||
mLayersUpdated = false;
|
||||
|
||||
@ -825,8 +838,7 @@ CompositorParent::TransformShadowTree(TimeStamp aCurrentFrame)
|
||||
|
||||
nsIntPoint metricsScrollOffset(0, 0);
|
||||
if (metrics.IsScrollable()) {
|
||||
metricsScrollOffset =
|
||||
nsIntPoint(NS_lround(scrollOffset.x), NS_lround(scrollOffset.y));
|
||||
metricsScrollOffset = scrollOffsetDevPixels;
|
||||
}
|
||||
|
||||
nsIntPoint scrollCompensation(
|
||||
|
@ -37,7 +37,9 @@ ReusableTileStoreOGL::InvalidateTiles(TiledThebesLayerOGL* aLayer,
|
||||
// This will be incorrect when the transform involves rotation, but
|
||||
// it'd be quite hard to retain invalid tiles correctly in this
|
||||
// situation anyway.
|
||||
renderBounds = parent->GetEffectiveTransform().TransformBounds(gfxRect(metrics.mDisplayPort));
|
||||
renderBounds = parent->GetEffectiveTransform().TransformBounds(
|
||||
gfxRect(metrics.mDisplayPort.x, metrics.mDisplayPort.y,
|
||||
metrics.mDisplayPort.width, metrics.mDisplayPort.height));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -217,10 +219,14 @@ ReusableTileStoreOGL::DrawTiles(TiledThebesLayerOGL* aLayer,
|
||||
scrollableLayer = parent;
|
||||
if (!parentMetrics.mDisplayPort.IsEmpty() && scrollableLayer) {
|
||||
displayPort = parent->GetEffectiveTransform().
|
||||
TransformBounds(gfxRect(parentMetrics.mDisplayPort));
|
||||
TransformBounds(gfxRect(
|
||||
parentMetrics.mDisplayPort.x, parentMetrics.mDisplayPort.y,
|
||||
parentMetrics.mDisplayPort.width, parentMetrics.mDisplayPort.height));
|
||||
const FrameMetrics& metrics = scrollableLayer->GetFrameMetrics();
|
||||
const nsIntSize& contentSize = metrics.mContentRect.Size();
|
||||
const gfx::Point& scrollOffset = metrics.mViewportScrollOffset;
|
||||
gfx::Point scrollOffset =
|
||||
gfx::Point(metrics.mScrollOffset.x * metrics.LayersPixelsPerCSSPixel().width,
|
||||
metrics.mScrollOffset.y * metrics.LayersPixelsPerCSSPixel().height);
|
||||
const nsIntPoint& contentOrigin = metrics.mContentRect.TopLeft() -
|
||||
nsIntPoint(NS_lround(scrollOffset.x), NS_lround(scrollOffset.y));
|
||||
gfxRect contentRect = gfxRect(contentOrigin.x, contentOrigin.y,
|
||||
|
@ -960,25 +960,29 @@ struct ParamTraits<mozilla::layers::FrameMetrics>
|
||||
|
||||
static void Write(Message* aMsg, const paramType& aParam)
|
||||
{
|
||||
WriteParam(aMsg, aParam.mCSSContentRect);
|
||||
WriteParam(aMsg, aParam.mScrollableRect);
|
||||
WriteParam(aMsg, aParam.mViewport);
|
||||
WriteParam(aMsg, aParam.mContentRect);
|
||||
WriteParam(aMsg, aParam.mViewportScrollOffset);
|
||||
WriteParam(aMsg, aParam.mScrollOffset);
|
||||
WriteParam(aMsg, aParam.mDisplayPort);
|
||||
WriteParam(aMsg, aParam.mCompositionBounds);
|
||||
WriteParam(aMsg, aParam.mScrollId);
|
||||
WriteParam(aMsg, aParam.mResolution);
|
||||
WriteParam(aMsg, aParam.mDevPixelsPerCSSPixel);
|
||||
WriteParam(aMsg, aParam.mMayHaveTouchListeners);
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||
{
|
||||
return (ReadParam(aMsg, aIter, &aResult->mCSSContentRect) &&
|
||||
return (ReadParam(aMsg, aIter, &aResult->mScrollableRect) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mViewport) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mContentRect) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mViewportScrollOffset) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mScrollOffset) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mDisplayPort) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mCompositionBounds) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mScrollId) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mResolution) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mDevPixelsPerCSSPixel) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mMayHaveTouchListeners));
|
||||
}
|
||||
};
|
||||
|
@ -575,6 +575,7 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
|
||||
bool aMayHaveTouchListeners) {
|
||||
nsPresContext* presContext = aForFrame->PresContext();
|
||||
int32_t auPerDevPixel = presContext->AppUnitsPerDevPixel();
|
||||
float auPerCSSPixel = nsPresContext::AppUnitsPerCSSPixel();
|
||||
|
||||
nsIntRect visible = aVisibleRect.ScaleToNearestPixels(
|
||||
aContainerParameters.mXScale, aContainerParameters.mYScale, auPerDevPixel);
|
||||
@ -582,12 +583,18 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
|
||||
|
||||
FrameMetrics metrics;
|
||||
|
||||
metrics.mViewport = aViewport.ScaleToNearestPixels(
|
||||
aContainerParameters.mXScale, aContainerParameters.mYScale, auPerDevPixel);
|
||||
metrics.mViewport = mozilla::gfx::Rect(
|
||||
NSAppUnitsToDoublePixels(aViewport.x, auPerDevPixel),
|
||||
NSAppUnitsToDoublePixels(aViewport.y, auPerDevPixel),
|
||||
NSAppUnitsToDoublePixels(aViewport.width, auPerDevPixel),
|
||||
NSAppUnitsToDoublePixels(aViewport.height, auPerDevPixel));
|
||||
|
||||
if (aDisplayPort) {
|
||||
metrics.mDisplayPort = aDisplayPort->ScaleToNearestPixels(
|
||||
aContainerParameters.mXScale, aContainerParameters.mYScale, auPerDevPixel);
|
||||
metrics.mDisplayPort = mozilla::gfx::Rect(
|
||||
NSAppUnitsToDoublePixels(aDisplayPort->x, auPerDevPixel),
|
||||
NSAppUnitsToDoublePixels(aDisplayPort->y, auPerDevPixel),
|
||||
NSAppUnitsToDoublePixels(aDisplayPort->width, auPerDevPixel),
|
||||
NSAppUnitsToDoublePixels(aDisplayPort->height, auPerDevPixel));
|
||||
}
|
||||
|
||||
nsIScrollableFrame* scrollableFrame = nullptr;
|
||||
@ -598,7 +605,7 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
|
||||
nsRect contentBounds = scrollableFrame->GetScrollRange();
|
||||
contentBounds.width += scrollableFrame->GetScrollPortRect().width;
|
||||
contentBounds.height += scrollableFrame->GetScrollPortRect().height;
|
||||
metrics.mCSSContentRect =
|
||||
metrics.mScrollableRect =
|
||||
mozilla::gfx::Rect(nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.x),
|
||||
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.y),
|
||||
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.width),
|
||||
@ -606,13 +613,13 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
|
||||
metrics.mContentRect = contentBounds.ScaleToNearestPixels(
|
||||
aContainerParameters.mXScale, aContainerParameters.mYScale, auPerDevPixel);
|
||||
nsPoint scrollPosition = scrollableFrame->GetScrollPosition();
|
||||
metrics.mViewportScrollOffset = mozilla::gfx::Point(
|
||||
NSAppUnitsToDoublePixels(scrollPosition.x, auPerDevPixel) * aContainerParameters.mXScale,
|
||||
NSAppUnitsToDoublePixels(scrollPosition.y, auPerDevPixel) * aContainerParameters.mYScale);
|
||||
metrics.mScrollOffset = mozilla::gfx::Point(
|
||||
NSAppUnitsToDoublePixels(scrollPosition.x, auPerCSSPixel),
|
||||
NSAppUnitsToDoublePixels(scrollPosition.y, auPerCSSPixel));
|
||||
}
|
||||
else {
|
||||
nsRect contentBounds = aForFrame->GetRect();
|
||||
metrics.mCSSContentRect =
|
||||
metrics.mScrollableRect =
|
||||
mozilla::gfx::Rect(nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.x),
|
||||
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.y),
|
||||
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.width),
|
||||
@ -626,6 +633,8 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
|
||||
nsIPresShell* presShell = presContext->GetPresShell();
|
||||
metrics.mResolution = gfxSize(presShell->GetXResolution(), presShell->GetYResolution());
|
||||
|
||||
metrics.mDevPixelsPerCSSPixel = auPerCSSPixel / auPerDevPixel;
|
||||
|
||||
metrics.mMayHaveTouchListeners = aMayHaveTouchListeners;
|
||||
|
||||
aRoot->SetFrameMetrics(metrics);
|
||||
@ -1070,8 +1079,10 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
|
||||
}
|
||||
}
|
||||
|
||||
nsRect viewport(aBuilder->ToReferenceFrame(aForFrame), aForFrame->GetSize());
|
||||
|
||||
RecordFrameMetrics(aForFrame, rootScrollFrame,
|
||||
root, mVisibleRect, mVisibleRect,
|
||||
root, mVisibleRect, viewport,
|
||||
(usingDisplayport ? &displayport : nullptr), id,
|
||||
containerParameters, mayHaveTouchListeners);
|
||||
if (usingDisplayport &&
|
||||
|
@ -158,7 +158,7 @@ ComputeShadowTreeTransform(nsIFrame* aContainerFrame,
|
||||
nsIntPoint scrollOffset =
|
||||
aConfig.mScrollOffset.ToNearestPixels(auPerDevPixel);
|
||||
// metricsScrollOffset is in layer coordinates.
|
||||
gfx::Point metricsScrollOffset = aMetrics->mViewportScrollOffset;
|
||||
gfx::Point metricsScrollOffset = aMetrics->GetScrollOffsetInLayerPixels();
|
||||
nsIntPoint roundedMetricsScrollOffset =
|
||||
nsIntPoint(NS_lround(metricsScrollOffset.x), NS_lround(metricsScrollOffset.y));
|
||||
|
||||
@ -217,7 +217,9 @@ BuildListForLayer(Layer* aLayer,
|
||||
nsRect bounds;
|
||||
{
|
||||
nscoord auPerDevPixel = aSubdocFrame->PresContext()->AppUnitsPerDevPixel();
|
||||
bounds = metrics->mViewport.ToAppUnits(auPerDevPixel);
|
||||
gfx::Rect viewport = metrics->mViewport;
|
||||
bounds = nsIntRect(viewport.x, viewport.y,
|
||||
viewport.width, viewport.height).ToAppUnits(auPerDevPixel);
|
||||
ApplyTransform(bounds, tmpTransform, auPerDevPixel);
|
||||
|
||||
}
|
||||
@ -362,6 +364,7 @@ BuildViewMap(ViewMap& oldContentViews, ViewMap& newContentViews,
|
||||
if (metrics.IsScrollable()) {
|
||||
nscoord auPerDevPixel = aFrameLoader->GetPrimaryFrameOfOwningContent()
|
||||
->PresContext()->AppUnitsPerDevPixel();
|
||||
nscoord auPerCSSPixel = auPerDevPixel * metrics.mDevPixelsPerCSSPixel;
|
||||
nsContentView* view = FindViewForId(oldContentViews, scrollId);
|
||||
if (view) {
|
||||
// View already exists. Be sure to propagate scales for any values
|
||||
@ -392,8 +395,8 @@ BuildViewMap(ViewMap& oldContentViews, ViewMap& newContentViews,
|
||||
// The default scale is 1, so no need to propagate scale down.
|
||||
ViewConfig config;
|
||||
config.mScrollOffset = nsPoint(
|
||||
NSIntPixelsToAppUnits(metrics.mViewportScrollOffset.x, auPerDevPixel) * aXScale,
|
||||
NSIntPixelsToAppUnits(metrics.mViewportScrollOffset.y, auPerDevPixel) * aYScale);
|
||||
NSIntPixelsToAppUnits(metrics.mScrollOffset.x, auPerCSSPixel) * aXScale,
|
||||
NSIntPixelsToAppUnits(metrics.mScrollOffset.y, auPerCSSPixel) * aYScale);
|
||||
view = new nsContentView(aFrameLoader, scrollId, config);
|
||||
view->mParentScaleX = aAccConfigXScale;
|
||||
view->mParentScaleY = aAccConfigYScale;
|
||||
@ -728,7 +731,8 @@ void
|
||||
RenderFrameParent::NotifyDimensionsChanged(int width, int height)
|
||||
{
|
||||
if (mPanZoomController) {
|
||||
mPanZoomController->UpdateViewportSize(width, height);
|
||||
mPanZoomController->UpdateCompositionBounds(
|
||||
nsIntRect(0, 0, width, height));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user