Bug 1280013 - Incorporate the APZ callback transforms when using the root composition bounds to clip the displayport base. r=botond,tnikkel

MozReview-Commit-ID: 1HOGQnCjIMt
This commit is contained in:
Kartikaya Gupta 2016-06-29 08:50:20 -04:00
parent 6a6c1034f1
commit 47b3b7b426
4 changed files with 52 additions and 26 deletions

View File

@ -400,8 +400,8 @@ APZCCallbackHelper::ApplyCallbackTransform(const CSSPoint& aInput,
// that's not on the Root Document (RD). That is, on platforms where
// RCD == RD, it's 1, and on platforms where RCD != RD, it's the RCD
// resolution. 'input' has this resolution applied, but the scroll
// deltas retrieved below do not, so we need to apply them to the
// deltas before adding the deltas to 'input'. (Technically, deltas
// delta retrieved below do not, so we need to apply them to the
// delta before adding the delta to 'input'. (Technically, deltas
// from scroll frames outside the RCD would already have this
// resolution applied, but we don't have such scroll frames in
// practice.)
@ -409,30 +409,10 @@ APZCCallbackHelper::ApplyCallbackTransform(const CSSPoint& aInput,
if (nsIPresShell* shell = GetRootContentDocumentPresShellForContent(content)) {
nonRootResolution = shell->GetCumulativeNonRootScaleResolution();
}
// Now apply the callback-transform.
// XXX: Walk up the frame tree from the frame of this content element
// to the root of the frame tree, and apply any apzCallbackTransform
// found on the way. This is only approximately correct, as it does
// not take into account CSS transforms, nor differences in structure between
// the frame tree (which determines the transforms we're applying)
// and the layer tree (which determines the transforms we *want* to
// apply).
nsIFrame* frame = content->GetPrimaryFrame();
nsCOMPtr<nsIContent> lastContent;
while (frame) {
if (content && (content != lastContent)) {
void* property = content->GetProperty(nsGkAtoms::apzCallbackTransform);
if (property) {
CSSPoint delta = (*static_cast<CSSPoint*>(property));
delta = delta * nonRootResolution;
input += delta;
}
}
frame = frame->GetParent();
lastContent = content;
content = frame ? frame->GetContent() : nullptr;
}
return input;
// Now apply the callback-transform. This is only approximately correct,
// see the comment on GetCumulativeApzCallbackTransform for details.
CSSPoint transform = nsLayoutUtils::GetCumulativeApzCallbackTransform(content->GetPrimaryFrame());
return input + transform * nonRootResolution;
}
LayoutDeviceIntPoint

View File

@ -9330,3 +9330,26 @@ nsLayoutUtils::IsTransformed(nsIFrame* aForFrame, nsIFrame* aTopFrame)
return false;
}
/*static*/ CSSPoint
nsLayoutUtils::GetCumulativeApzCallbackTransform(nsIFrame* aFrame)
{
CSSPoint delta;
if (!aFrame) {
return delta;
}
nsIFrame* frame = aFrame;
nsCOMPtr<nsIContent> content = frame->GetContent();
nsCOMPtr<nsIContent> lastContent;
while (frame) {
if (content && (content != lastContent)) {
void* property = content->GetProperty(nsGkAtoms::apzCallbackTransform);
if (property) {
delta += *static_cast<CSSPoint*>(property);
}
}
frame = GetCrossDocParentFrame(frame);
lastContent = content;
content = frame ? frame->GetContent() : nullptr;
}
return delta;
}

View File

@ -2836,6 +2836,16 @@ public:
*/
static bool IsTransformed(nsIFrame* aForFrame, nsIFrame* aTopFrame = nullptr);
/**
* Walk up from aFrame to the cross-doc root, accumulating all the APZ callback
* transforms on the content elements encountered along the way. Return the
* accumulated value.
* XXX: Note that this does not take into account CSS transforms, nor
* differences in structure between the frame tree and the layer tree (which
* is probably what we *want* to be computing).
*/
static CSSPoint GetCumulativeApzCallbackTransform(nsIFrame* aFrame);
private:
static uint32_t sFontSizeInflationEmPerLine;
static uint32_t sFontSizeInflationMinTwips;

View File

@ -3534,7 +3534,20 @@ ScrollFrameHelper::DecideScrollableLayer(nsDisplayListBuilder* aBuilder,
rootCompBounds = rootCompBounds.RemoveResolution(rootPresShell->GetResolution());
}
// We want to convert the root composition bounds from the coordinate
// space of |rootFrame| to the coordinate space of |mOuter|. We do
// that with the TransformRect call below. However, since we care
// about the root composition bounds relative to what the user is
// actually seeing, we also need to incorporate the APZ callback
// transforms into this. Most of the time those transforms are
// negligible, but in some cases (e.g. when a zoom is applied on
// an overflow:hidden document) it is not (see bug 1280013).
// XXX: Eventually we may want to create a modified version of
// TransformRect that includes the APZ callback transforms
// directly.
nsLayoutUtils::TransformRect(rootFrame, mOuter, rootCompBounds);
rootCompBounds += CSSPoint::ToAppUnits(
nsLayoutUtils::GetCumulativeApzCallbackTransform(mOuter));
displayportBase = displayportBase.Intersect(rootCompBounds);
}