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

View File

@ -8,6 +8,7 @@
#include <stdint.h> // for uint32_t, uint64_t #include <stdint.h> // for uint32_t, uint64_t
#include "Units.h" // for CSSRect, CSSPixel, etc #include "Units.h" // for CSSRect, CSSPixel, etc
#include "mozilla/Maybe.h"
#include "mozilla/gfx/BasePoint.h" // for BasePoint #include "mozilla/gfx/BasePoint.h" // for BasePoint
#include "mozilla/gfx/Rect.h" // for RoundedIn #include "mozilla/gfx/Rect.h" // for RoundedIn
#include "mozilla/gfx/ScaleFactor.h" // for ScaleFactor #include "mozilla/gfx/ScaleFactor.h" // for ScaleFactor
@ -98,7 +99,8 @@ public:
mDoSmoothScroll == aOther.mDoSmoothScroll && mDoSmoothScroll == aOther.mDoSmoothScroll &&
mLineScrollAmount == aOther.mLineScrollAmount && mLineScrollAmount == aOther.mLineScrollAmount &&
mPageScrollAmount == aOther.mPageScrollAmount && mPageScrollAmount == aOther.mPageScrollAmount &&
mAllowVerticalScrollWithWheel == aOther.mAllowVerticalScrollWithWheel; mAllowVerticalScrollWithWheel == aOther.mAllowVerticalScrollWithWheel &&
mClipRect == aOther.mClipRect;
} }
bool operator!=(const FrameMetrics& aOther) const bool operator!=(const FrameMetrics& aOther) const
{ {
@ -517,6 +519,21 @@ public:
mAllowVerticalScrollWithWheel = true; 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: private:
// The pres-shell resolution that has been induced on the document containing // 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. // Whether or not the frame can be vertically scrolled with a mouse wheel.
bool mAllowVerticalScrollWithWheel; bool mAllowVerticalScrollWithWheel;
// The clip rect to use when compositing a layer with this FrameMetrics.
Maybe<ParentLayerIntRect> mClipRect;
// WARNING!!!! // WARNING!!!!
// //
// When adding new fields to FrameMetrics, the following places should be // 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) { if (m.GetScrollParentId() != FrameMetrics::NULL_SCROLL_ID) {
AppendToString(aStream, m.GetScrollParentId(), "] [scrollParent="); AppendToString(aStream, m.GetScrollParentId(), "] [scrollParent=");
} }
if (m.HasClipRect()) {
AppendToString(aStream, m.ClipRect(), "] [clip=");
}
AppendToString(aStream, m.GetZoom(), "] [z=", "] }"); AppendToString(aStream, m.GetZoom(), "] [z=", "] }");
} else { } else {
AppendToString(aStream, m.GetDisplayPortMargins(), " [dpm="); AppendToString(aStream, m.GetDisplayPortMargins(), " [dpm=");

View File

@ -2898,6 +2898,7 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetri
mFrameMetrics.SetHasScrollgrab(aLayerMetrics.GetHasScrollgrab()); mFrameMetrics.SetHasScrollgrab(aLayerMetrics.GetHasScrollgrab());
mFrameMetrics.SetLineScrollAmount(aLayerMetrics.GetLineScrollAmount()); mFrameMetrics.SetLineScrollAmount(aLayerMetrics.GetLineScrollAmount());
mFrameMetrics.SetPageScrollAmount(aLayerMetrics.GetPageScrollAmount()); mFrameMetrics.SetPageScrollAmount(aLayerMetrics.GetPageScrollAmount());
mFrameMetrics.SetClipRect(aLayerMetrics.GetClipRect());
if (scrollOffsetUpdated) { if (scrollOffsetUpdated) {
APZC_LOG("%p updating scroll offset from %s to %s\n", this, 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 // Apply the render offset
mLayerManager->GetCompositor()->SetScreenRenderOffset(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; combinedAsyncTransformWithoutOverscroll *= asyncTransformWithoutOverscroll;
combinedAsyncTransform *= (Matrix4x4(asyncTransformWithoutOverscroll) * overscrollTransform); combinedAsyncTransform *= (Matrix4x4(asyncTransformWithoutOverscroll) * overscrollTransform);
if (i > 0 && clipRect) { if (i > 0 && clipRect) {

View File

@ -12,6 +12,7 @@
#include "mozilla/ArrayUtils.h" #include "mozilla/ArrayUtils.h"
#include "mozilla/DebugOnly.h" #include "mozilla/DebugOnly.h"
#include "mozilla/Maybe.h"
#include "mozilla/TimeStamp.h" #include "mozilla/TimeStamp.h"
#ifdef XP_WIN #ifdef XP_WIN
#include "mozilla/TimeStamp_windows.h" #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 */ } /* namespace IPC */
#endif /* __IPC_GLUE_IPCMESSAGEUTILS_H__ */ #endif /* __IPC_GLUE_IPCMESSAGEUTILS_H__ */

View File

@ -4241,8 +4241,6 @@ ContainerState::SetupScrollingMetadata(NewLayerEntry* aEntry)
} }
uint32_t baseLength = metricsArray.Length(); uint32_t baseLength = metricsArray.Length();
ParentLayerIntRect tmpClipRect;
const ParentLayerIntRect* layerClip = aEntry->mLayer->GetClipRect().ptrOr(nullptr);
nsIFrame* fParent; nsIFrame* fParent;
for (const nsIFrame* f = aEntry->mAnimatedGeometryRoot; for (const nsIFrame* f = aEntry->mAnimatedGeometryRoot;
f != mContainerAnimatedGeometryRoot; f != mContainerAnimatedGeometryRoot;
@ -4267,23 +4265,9 @@ ContainerState::SetupScrollingMetadata(NewLayerEntry* aEntry)
continue; continue;
} }
Maybe<nsRect> clipRect;
scrollFrame->ComputeFrameMetrics(aEntry->mLayer, mContainerReferenceFrame, scrollFrame->ComputeFrameMetrics(aEntry->mLayer, mContainerReferenceFrame,
mParameters, &clipRect, &metricsArray); mParameters, &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.
}
} }
aEntry->mLayer->SetClipRect(ToMaybe(layerClip));
// Watch out for FrameMetrics copies in profiles // Watch out for FrameMetrics copies in profiles
aEntry->mLayer->SetFrameMetrics(metricsArray); aEntry->mLayer->SetFrameMetrics(metricsArray);
} }

View File

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

View File

@ -8134,6 +8134,7 @@ nsLayoutUtils::ComputeFrameMetrics(nsIFrame* aForFrame,
Layer* aLayer, Layer* aLayer,
ViewID aScrollParentId, ViewID aScrollParentId,
const nsRect& aViewport, const nsRect& aViewport,
const Maybe<nsRect>& aClipRect,
bool aIsRoot, bool aIsRoot,
const ContainerLayerParameters& aContainerParameters) const ContainerLayerParameters& aContainerParameters)
{ {
@ -8261,6 +8262,13 @@ nsLayoutUtils::ComputeFrameMetrics(nsIFrame* aForFrame,
* metrics.GetCumulativeResolution() * metrics.GetCumulativeResolution()
* layerToParentLayerScale; * 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 // 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 // will yield the size of the viewport frame as the composition bounds, which
// doesn't actually correspond to what is visible when // doesn't actually correspond to what is visible when

View File

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

View File

@ -56,6 +56,7 @@
#include "gfxPlatform.h" #include "gfxPlatform.h"
#include "gfxPrefs.h" #include "gfxPrefs.h"
#include "AsyncScrollBase.h" #include "AsyncScrollBase.h"
#include "UnitTransforms.h"
#include <mozilla/layers/AxisPhysicsModel.h> #include <mozilla/layers/AxisPhysicsModel.h>
#include <mozilla/layers/AxisPhysicsMSDModel.h> #include <mozilla/layers/AxisPhysicsMSDModel.h>
#include <algorithm> #include <algorithm>
@ -3042,7 +3043,6 @@ void
ScrollFrameHelper::ComputeFrameMetrics(Layer* aLayer, ScrollFrameHelper::ComputeFrameMetrics(Layer* aLayer,
nsIFrame* aContainerReferenceFrame, nsIFrame* aContainerReferenceFrame,
const ContainerLayerParameters& aParameters, const ContainerLayerParameters& aParameters,
Maybe<nsRect>* aClipRect,
nsTArray<FrameMetrics>* aOutput) const nsTArray<FrameMetrics>* aOutput) const
{ {
if (!mShouldBuildScrollableLayer || mIsScrollableLayerInRootContainer) { if (!mShouldBuildScrollableLayer || mIsScrollableLayerInRootContainer) {
@ -3065,6 +3065,7 @@ ScrollFrameHelper::ComputeFrameMetrics(Layer* aLayer,
nsPoint toReferenceFrame = mOuter->GetOffsetToCrossDoc(aContainerReferenceFrame); nsPoint toReferenceFrame = mOuter->GetOffsetToCrossDoc(aContainerReferenceFrame);
bool isRoot = mIsRoot && mOuter->PresContext()->IsRootContentDocument(); bool isRoot = mIsRoot && mOuter->PresContext()->IsRootContentDocument();
Maybe<nsRect> parentLayerClip;
if (needsParentLayerClip) { if (needsParentLayerClip) {
nsRect clip = nsRect(mScrollPort.TopLeft() + toReferenceFrame, nsRect clip = nsRect(mScrollPort.TopLeft() + toReferenceFrame,
nsLayoutUtils::CalculateCompositionSizeForFrame(mOuter)); nsLayoutUtils::CalculateCompositionSizeForFrame(mOuter));
@ -3074,9 +3075,31 @@ ScrollFrameHelper::ComputeFrameMetrics(Layer* aLayer,
clip.height = NSToCoordRound(clip.height / res); clip.height = NSToCoordRound(clip.height / res);
} }
// When using containers, the container layer contains the clip. Otherwise parentLayerClip = Some(clip);
// we always include the clip. }
*aClipRect = 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()); MOZ_ASSERT(mScrolledFrame->GetContent());
@ -3086,7 +3109,7 @@ ScrollFrameHelper::ComputeFrameMetrics(Layer* aLayer,
nsLayoutUtils::ComputeFrameMetrics( nsLayoutUtils::ComputeFrameMetrics(
mScrolledFrame, mOuter, mOuter->GetContent(), mScrolledFrame, mOuter, mOuter->GetContent(),
aContainerReferenceFrame, aLayer, mScrollParentID, aContainerReferenceFrame, aLayer, mScrollParentID,
scrollport, isRoot, aParameters); scrollport, parentLayerClip, isRoot, aParameters);
} }
bool bool

View File

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

View File

@ -418,7 +418,6 @@ public:
virtual void ComputeFrameMetrics(mozilla::layers::Layer* aLayer, virtual void ComputeFrameMetrics(mozilla::layers::Layer* aLayer,
nsIFrame* aContainerReferenceFrame, nsIFrame* aContainerReferenceFrame,
const ContainerLayerParameters& aParameters, const ContainerLayerParameters& aParameters,
mozilla::Maybe<nsRect>* aOutClipRect,
nsTArray<FrameMetrics>* aOutput) const = 0; 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-2.html 1059498-1-ref.html
== 1059498-3.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 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 == 1062963-floatmanager-reflow.html 1062963-floatmanager-reflow-ref.html
test-pref(dom.webcomponents.enabled,true) == 1066554-1.html 1066554-1-ref.html test-pref(dom.webcomponents.enabled,true) == 1066554-1.html 1066554-1-ref.html
== 1069716-1.html 1069716-1-ref.html == 1069716-1.html 1069716-1-ref.html