Move the APZ scroll frame clip onto FrameMetrics. (bug 1148582 part 3, r=mstange,tn)

This commit is contained in:
David Anderson 2015-05-26 12:40:24 -07:00
parent 9aa4b5c38b
commit 1266e0674b
14 changed files with 118 additions and 33 deletions

View File

@ -732,6 +732,7 @@ struct ParamTraits<mozilla::layers::FrameMetrics>
WriteParam(aMsg, aParam.GetLineScrollAmount());
WriteParam(aMsg, aParam.GetPageScrollAmount());
WriteParam(aMsg, aParam.AllowVerticalScrollWithWheel());
WriteParam(aMsg, aParam.mClipRect);
WriteParam(aMsg, aParam.GetContentDescription());
}
@ -774,6 +775,7 @@ struct ParamTraits<mozilla::layers::FrameMetrics>
ReadParam(aMsg, aIter, &aResult->mLineScrollAmount) &&
ReadParam(aMsg, aIter, &aResult->mPageScrollAmount) &&
ReadParam(aMsg, aIter, &aResult->mAllowVerticalScrollWithWheel) &&
ReadParam(aMsg, aIter, &aResult->mClipRect) &&
ReadContentDescription(aMsg, aIter, aResult));
}
};

View File

@ -8,6 +8,7 @@
#include <stdint.h> // for uint32_t, uint64_t
#include "Units.h" // for CSSRect, CSSPixel, etc
#include "mozilla/Maybe.h"
#include "mozilla/gfx/BasePoint.h" // for BasePoint
#include "mozilla/gfx/Rect.h" // for RoundedIn
#include "mozilla/gfx/ScaleFactor.h" // for ScaleFactor
@ -98,7 +99,8 @@ public:
mDoSmoothScroll == aOther.mDoSmoothScroll &&
mLineScrollAmount == aOther.mLineScrollAmount &&
mPageScrollAmount == aOther.mPageScrollAmount &&
mAllowVerticalScrollWithWheel == aOther.mAllowVerticalScrollWithWheel;
mAllowVerticalScrollWithWheel == aOther.mAllowVerticalScrollWithWheel &&
mClipRect == aOther.mClipRect;
}
bool operator!=(const FrameMetrics& aOther) const
{
@ -517,6 +519,21 @@ public:
mAllowVerticalScrollWithWheel = true;
}
void SetClipRect(const Maybe<ParentLayerIntRect>& aClipRect)
{
mClipRect = aClipRect;
}
const Maybe<ParentLayerIntRect>& GetClipRect() const
{
return mClipRect;
}
bool HasClipRect() const {
return mClipRect.isSome();
}
const ParentLayerIntRect& ClipRect() const {
return mClipRect.ref();
}
private:
// The pres-shell resolution that has been induced on the document containing
@ -688,6 +705,9 @@ private:
// Whether or not the frame can be vertically scrolled with a mouse wheel.
bool mAllowVerticalScrollWithWheel;
// The clip rect to use when compositing a layer with this FrameMetrics.
Maybe<ParentLayerIntRect> mClipRect;
// WARNING!!!!
//
// When adding new fields to FrameMetrics, the following places should be

View File

@ -183,6 +183,9 @@ AppendToString(std::stringstream& aStream, const FrameMetrics& m,
if (m.GetScrollParentId() != FrameMetrics::NULL_SCROLL_ID) {
AppendToString(aStream, m.GetScrollParentId(), "] [scrollParent=");
}
if (m.HasClipRect()) {
AppendToString(aStream, m.ClipRect(), "] [clip=");
}
AppendToString(aStream, m.GetZoom(), "] [z=", "] }");
} else {
AppendToString(aStream, m.GetDisplayPortMargins(), " [dpm=");

View File

@ -2898,6 +2898,7 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetri
mFrameMetrics.SetHasScrollgrab(aLayerMetrics.GetHasScrollgrab());
mFrameMetrics.SetLineScrollAmount(aLayerMetrics.GetLineScrollAmount());
mFrameMetrics.SetPageScrollAmount(aLayerMetrics.GetPageScrollAmount());
mFrameMetrics.SetClipRect(aLayerMetrics.GetClipRect());
if (scrollOffsetUpdated) {
APZC_LOG("%p updating scroll offset from %s to %s\n", this,

View File

@ -623,6 +623,17 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(Layer *aLayer)
// Apply the render offset
mLayerManager->GetCompositor()->SetScreenRenderOffset(offset);
// See the comment below - the first FrameMetrics has the clip computed
// by layout (currently, effectively the composition bounds), which we
// intersect here to include the layer clip.
if (i == 0 && metrics.HasClipRect()) {
if (clipRect) {
clipRect = Some(clipRect.value().Intersect(metrics.ClipRect()));
} else {
clipRect = Some(metrics.ClipRect());
}
}
combinedAsyncTransformWithoutOverscroll *= asyncTransformWithoutOverscroll;
combinedAsyncTransform *= (Matrix4x4(asyncTransformWithoutOverscroll) * overscrollTransform);
if (i > 0 && clipRect) {

View File

@ -12,6 +12,7 @@
#include "mozilla/ArrayUtils.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/Maybe.h"
#include "mozilla/TimeStamp.h"
#ifdef XP_WIN
#include "mozilla/TimeStamp_windows.h"
@ -805,6 +806,40 @@ struct ParamTraits<nsIWidget::TouchPointerState>
{
};
template<class T>
struct ParamTraits< mozilla::Maybe<T> >
{
typedef mozilla::Maybe<T> paramType;
static void Write(Message* msg, const paramType& param)
{
if (param.isSome()) {
WriteParam(msg, true);
WriteParam(msg, param.value());
} else {
WriteParam(msg, false);
}
}
static bool Read(const Message* msg, void** iter, paramType* result)
{
bool isSome;
if (!ReadParam(msg, iter, &isSome)) {
return false;
}
if (isSome) {
T tmp;
if (!ReadParam(msg, iter, &tmp)) {
return false;
}
*result = mozilla::Some(mozilla::Move(tmp));
} else {
*result = mozilla::Nothing();
}
return true;
}
};
} /* namespace IPC */
#endif /* __IPC_GLUE_IPCMESSAGEUTILS_H__ */

View File

@ -4241,8 +4241,6 @@ ContainerState::SetupScrollingMetadata(NewLayerEntry* aEntry)
}
uint32_t baseLength = metricsArray.Length();
ParentLayerIntRect tmpClipRect;
const ParentLayerIntRect* layerClip = aEntry->mLayer->GetClipRect().ptrOr(nullptr);
nsIFrame* fParent;
for (const nsIFrame* f = aEntry->mAnimatedGeometryRoot;
f != mContainerAnimatedGeometryRoot;
@ -4267,23 +4265,9 @@ ContainerState::SetupScrollingMetadata(NewLayerEntry* aEntry)
continue;
}
Maybe<nsRect> clipRect;
scrollFrame->ComputeFrameMetrics(aEntry->mLayer, mContainerReferenceFrame,
mParameters, &clipRect, &metricsArray);
if (clipRect) {
ParentLayerIntRect pixClip = ViewAs<ParentLayerPixel>(ScaleToNearestPixels(*clipRect));
if (layerClip) {
tmpClipRect.IntersectRect(pixClip, *layerClip);
} else {
tmpClipRect = pixClip;
}
layerClip = &tmpClipRect;
// XXX this could cause IPC churn due to cliprects being updated
// twice during layer building --- for non-PaintedLayers that have
// both CSS and scroll clipping.
}
mParameters, &metricsArray);
}
aEntry->mLayer->SetClipRect(ToMaybe(layerClip));
// Watch out for FrameMetrics copies in profiles
aEntry->mLayer->SetFrameMetrics(metricsArray);
}

View File

@ -1543,7 +1543,7 @@ already_AddRefed<LayerManager> nsDisplayList::PaintRoot(nsDisplayListBuilder* aB
presShell->GetRootScrollFrame(),
content,
aBuilder->FindReferenceFrameFor(frame),
root, FrameMetrics::NULL_SCROLL_ID, viewport,
root, FrameMetrics::NULL_SCROLL_ID, viewport, Nothing(),
isRoot, containerParameters));
}
@ -4175,7 +4175,7 @@ nsDisplaySubDocument::ComputeFrameMetrics(Layer* aLayer,
return MakeUnique<FrameMetrics>(
nsLayoutUtils::ComputeFrameMetrics(
mFrame, rootScrollFrame, rootScrollFrame->GetContent(), ReferenceFrame(),
aLayer, mScrollParentId, viewport,
aLayer, mScrollParentId, viewport, Nothing(),
isRootContentDocument, params));
}
@ -4447,7 +4447,7 @@ nsDisplayScrollInfoLayer::ComputeFrameMetrics(Layer* aLayer,
nsLayoutUtils::ComputeFrameMetrics(
mScrolledFrame, mScrollFrame, mScrollFrame->GetContent(),
ReferenceFrame(), aLayer,
mScrollParentId, viewport, false, params)));
mScrollParentId, viewport, Nothing(), false, params)));
}

View File

@ -8134,6 +8134,7 @@ nsLayoutUtils::ComputeFrameMetrics(nsIFrame* aForFrame,
Layer* aLayer,
ViewID aScrollParentId,
const nsRect& aViewport,
const Maybe<nsRect>& aClipRect,
bool aIsRoot,
const ContainerLayerParameters& aContainerParameters)
{
@ -8261,6 +8262,13 @@ nsLayoutUtils::ComputeFrameMetrics(nsIFrame* aForFrame,
* metrics.GetCumulativeResolution()
* layerToParentLayerScale;
if (aClipRect) {
ParentLayerRect rect = LayoutDeviceRect::FromAppUnits(*aClipRect, auPerDevPixel)
* metrics.GetCumulativeResolution()
* layerToParentLayerScale;
metrics.SetClipRect(Some(RoundedToInt(rect)));
}
// For the root scroll frame of the root content document (RCD-RSF), the above calculation
// will yield the size of the viewport frame as the composition bounds, which
// doesn't actually correspond to what is visible when

View File

@ -8,6 +8,7 @@
#include "mozilla/MemoryReporting.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/Maybe.h"
#include "nsBoundingMetrics.h"
#include "nsChangeHint.h"
#include "nsAutoPtr.h"
@ -2628,6 +2629,7 @@ public:
Layer* aLayer,
ViewID aScrollParentId,
const nsRect& aViewport,
const mozilla::Maybe<nsRect>& aClipRect,
bool aIsRoot,
const ContainerLayerParameters& aContainerParameters);

View File

@ -56,6 +56,7 @@
#include "gfxPlatform.h"
#include "gfxPrefs.h"
#include "AsyncScrollBase.h"
#include "UnitTransforms.h"
#include <mozilla/layers/AxisPhysicsModel.h>
#include <mozilla/layers/AxisPhysicsMSDModel.h>
#include <algorithm>
@ -3042,7 +3043,6 @@ void
ScrollFrameHelper::ComputeFrameMetrics(Layer* aLayer,
nsIFrame* aContainerReferenceFrame,
const ContainerLayerParameters& aParameters,
Maybe<nsRect>* aClipRect,
nsTArray<FrameMetrics>* aOutput) const
{
if (!mShouldBuildScrollableLayer || mIsScrollableLayerInRootContainer) {
@ -3065,6 +3065,7 @@ ScrollFrameHelper::ComputeFrameMetrics(Layer* aLayer,
nsPoint toReferenceFrame = mOuter->GetOffsetToCrossDoc(aContainerReferenceFrame);
bool isRoot = mIsRoot && mOuter->PresContext()->IsRootContentDocument();
Maybe<nsRect> parentLayerClip;
if (needsParentLayerClip) {
nsRect clip = nsRect(mScrollPort.TopLeft() + toReferenceFrame,
nsLayoutUtils::CalculateCompositionSizeForFrame(mOuter));
@ -3074,9 +3075,31 @@ ScrollFrameHelper::ComputeFrameMetrics(Layer* aLayer,
clip.height = NSToCoordRound(clip.height / res);
}
// When using containers, the container layer contains the clip. Otherwise
// we always include the clip.
*aClipRect = Some(clip);
parentLayerClip = Some(clip);
}
if (!gfxPrefs::AsyncPanZoomEnabled()) {
if (parentLayerClip) {
// If APZ is not enabled, we still need the displayport to be clipped
// in the compositor.
ParentLayerIntRect displayportClip =
ViewAs<ParentLayerPixel>(
parentLayerClip->ScaleToNearestPixels(
aParameters.mXScale,
aParameters.mYScale,
mScrolledFrame->PresContext()->AppUnitsPerDevPixel()));
ParentLayerIntRect layerClip;
if (const ParentLayerIntRect* origClip = aLayer->GetClipRect().ptrOr(nullptr)) {
layerClip = displayportClip.Intersect(*origClip);
} else {
layerClip = displayportClip;
}
aLayer->SetClipRect(Some(layerClip));
}
// Return early, since if we don't use APZ we don't need FrameMetrics.
return;
}
MOZ_ASSERT(mScrolledFrame->GetContent());
@ -3086,7 +3109,7 @@ ScrollFrameHelper::ComputeFrameMetrics(Layer* aLayer,
nsLayoutUtils::ComputeFrameMetrics(
mScrolledFrame, mOuter, mOuter->GetContent(),
aContainerReferenceFrame, aLayer, mScrollParentID,
scrollport, isRoot, aParameters);
scrollport, parentLayerClip, isRoot, aParameters);
}
bool

View File

@ -378,7 +378,6 @@ public:
bool WantAsyncScroll() const;
void ComputeFrameMetrics(Layer* aLayer, nsIFrame* aContainerReferenceFrame,
const ContainerLayerParameters& aParameters,
mozilla::Maybe<nsRect>* aClipRect,
nsTArray<FrameMetrics>* aOutput) const;
// nsIScrollbarMediator
@ -833,10 +832,9 @@ public:
}
virtual void ComputeFrameMetrics(Layer* aLayer, nsIFrame* aContainerReferenceFrame,
const ContainerLayerParameters& aParameters,
mozilla::Maybe<nsRect>* aClipRect,
nsTArray<FrameMetrics>* aOutput) const override {
mHelper.ComputeFrameMetrics(aLayer, aContainerReferenceFrame,
aParameters, aClipRect, aOutput);
aParameters, aOutput);
}
virtual bool IsIgnoringViewportClipping() const override {
return mHelper.IsIgnoringViewportClipping();
@ -1226,10 +1224,9 @@ public:
}
virtual void ComputeFrameMetrics(Layer* aLayer, nsIFrame* aContainerReferenceFrame,
const ContainerLayerParameters& aParameters,
mozilla::Maybe<nsRect>* aClipRect,
nsTArray<FrameMetrics>* aOutput) const override {
mHelper.ComputeFrameMetrics(aLayer, aContainerReferenceFrame,
aParameters, aClipRect, aOutput);
aParameters, aOutput);
}
virtual bool IsIgnoringViewportClipping() const override {
return mHelper.IsIgnoringViewportClipping();

View File

@ -418,7 +418,6 @@ public:
virtual void ComputeFrameMetrics(mozilla::layers::Layer* aLayer,
nsIFrame* aContainerReferenceFrame,
const ContainerLayerParameters& aParameters,
mozilla::Maybe<nsRect>* aOutClipRect,
nsTArray<FrameMetrics>* aOutput) const = 0;
/**

View File

@ -1847,7 +1847,7 @@ test-pref(layout.css.grid.enabled,true) == 1053035-1-grid.html 1053035-1-ref.htm
== 1059498-2.html 1059498-1-ref.html
== 1059498-3.html 1059498-1-ref.html
skip-if(Mulet) == 1062108-1.html 1062108-1-ref.html # Bug 1139893: font rounding failure, tracked in bug 1141535
fails-if(Android) fuzzy-if(Mulet,1,5) == 1062792-1.html 1062792-1-ref.html
fuzzy-if(Mulet,1,5) == 1062792-1.html 1062792-1-ref.html
== 1062963-floatmanager-reflow.html 1062963-floatmanager-reflow-ref.html
test-pref(dom.webcomponents.enabled,true) == 1066554-1.html 1066554-1-ref.html
== 1069716-1.html 1069716-1-ref.html