Bug 1577859 - Stop handling scrollbar layers that are descendants of the scrolled content. r=tnikkel

With containerless scrolling, scrollbar layers and their target scrolled layers
will be in sibling subtrees.

Depends on D45596

Differential Revision: https://phabricator.services.mozilla.com/D45918

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Botond Ballo 2019-09-15 21:50:10 +00:00
Родитель 7b88fb63f8
Коммит f94ae56498
7 изменённых файлов: 19 добавлений и 91 удалений

Просмотреть файл

@ -83,7 +83,6 @@ class APZSampler {
LayerToParentLayerMatrix4x4 ComputeTransformForScrollThumb(
const LayerToParentLayerMatrix4x4& aCurrentTransform,
const LayerMetricsWrapper& aContent, const ScrollbarData& aThumbData,
bool aScrollbarIsDescendant,
AsyncTransformComponentMatrix* aOutClipTransform);
CSSRect GetCurrentAsyncLayoutViewport(const LayerMetricsWrapper& aLayer);

Просмотреть файл

@ -601,8 +601,7 @@ APZCTreeManager::UpdateHitTestingTreeImpl(const ScrollNode& aRoot,
HitTestingTreeNode* target = it->second;
mScrollThumbInfo.emplace_back(
*(thumb->GetScrollbarAnimationId()), thumb->GetTransform(),
thumb->GetScrollbarData(), targetGuid, target->GetTransform(),
target->IsAncestorOf(thumb));
thumb->GetScrollbarData(), targetGuid, target->GetTransform());
}
}
@ -721,7 +720,7 @@ void APZCTreeManager::SampleForWebRender(wr::TransactionWrapper& aTxn,
return ComputeTransformForScrollThumb(
info.mThumbTransform * AsyncTransformMatrix(),
info.mTargetTransform.ToUnknownMatrix(), scrollTargetApzc,
aMetrics, info.mThumbData, info.mTargetIsAncestor, nullptr);
aMetrics, info.mThumbData, nullptr);
});
transforms.AppendElement(
wr::ToWrTransformProperty(info.mThumbAnimationId, transform));
@ -3239,8 +3238,7 @@ LayerToParentLayerMatrix4x4 APZCTreeManager::ComputeTransformForNode(
return ComputeTransformForScrollThumb(
aNode->GetTransform() * AsyncTransformMatrix(),
scrollTargetNode->GetTransform().ToUnknownMatrix(),
scrollTargetApzc, aMetrics, aNode->GetScrollbarData(),
scrollTargetNode->IsAncestorOf(aNode), nullptr);
scrollTargetApzc, aMetrics, aNode->GetScrollbarData(), nullptr);
});
}
}
@ -3349,7 +3347,6 @@ LayerToParentLayerMatrix4x4 APZCTreeManager::ComputeTransformForScrollThumb(
const LayerToParentLayerMatrix4x4& aCurrentTransform,
const Matrix4x4& aScrollableContentTransform, AsyncPanZoomController* aApzc,
const FrameMetrics& aMetrics, const ScrollbarData& aScrollbarData,
bool aScrollbarIsDescendant,
AsyncTransformComponentMatrix* aOutClipTransform) {
// We only apply the transform if the scroll-target layer has non-container
// children (i.e. when it has some possibly-visible content). This is to
@ -3440,41 +3437,7 @@ LayerToParentLayerMatrix4x4 APZCTreeManager::ComputeTransformForScrollThumb(
scrollbarTransform.PostTranslate(xTranslation, 0, 0);
}
LayerToParentLayerMatrix4x4 transform =
aCurrentTransform * scrollbarTransform;
AsyncTransformComponentMatrix compensation;
// If the scrollbar layer is a child of the content it is a scrollbar for,
// then we need to adjust for any async transform (including an overscroll
// transform) on the content. This needs to be cancelled out because layout
// positions and sizes the scrollbar on the assumption that there is no async
// transform, and without this adjustment the scrollbar will end up in the
// wrong place.
//
// Note that since the async transform is applied on top of the content's
// regular transform, we need to make sure to unapply the async transform in
// the same coordinate space. This requires applying the content transform
// and then unapplying it after unapplying the async transform.
if (aScrollbarIsDescendant) {
AsyncTransformComponentMatrix overscroll =
aApzc->GetOverscrollTransform(AsyncPanZoomController::eForCompositing);
Matrix4x4 asyncUntransform =
(asyncTransform * overscroll).Inverse().ToUnknownMatrix();
const Matrix4x4& contentTransform = aScrollableContentTransform;
Matrix4x4 contentUntransform = contentTransform.Inverse();
compensation *= ViewAs<AsyncTransformComponentMatrix>(
contentTransform * asyncUntransform * contentUntransform);
// Pass the total compensation out to the caller so that it can use it
// to transform clip transforms as needed.
if (aOutClipTransform) {
*aOutClipTransform = compensation;
}
}
transform = transform * compensation;
return transform;
return aCurrentTransform * scrollbarTransform;
}
APZSampler* APZCTreeManager::GetSampler() const {

Просмотреть файл

@ -525,8 +525,6 @@ class APZCTreeManager : public IAPZCTreeManager, public APZInputBridge {
* NOT reflect async scrolling, i.e. they should be the layer tree's
* copy of the metrics, or APZC's last-content-paint metrics.
* @param aScrollbarData The scrollbar data for the the scroll thumb layer.
* @param aScrollbarIsDescendant True iff. the scroll thumb layer is a
* descendant of the layer bearing the scroll frame's metrics.
* @param aOutClipTransform If not null, and |aScrollbarIsDescendant| is true,
* this will be populated with a transform that should be applied to the
* clip rects of all layers between the scroll thumb layer and the ancestor
@ -538,7 +536,7 @@ class APZCTreeManager : public IAPZCTreeManager, public APZInputBridge {
const LayerToParentLayerMatrix4x4& aCurrentTransform,
const gfx::Matrix4x4& aScrollableContentTransform,
AsyncPanZoomController* aApzc, const FrameMetrics& aMetrics,
const ScrollbarData& aScrollbarData, bool aScrollbarIsDescendant,
const ScrollbarData& aScrollbarData,
AsyncTransformComponentMatrix* aOutClipTransform);
/**
@ -848,20 +846,17 @@ class APZCTreeManager : public IAPZCTreeManager, public APZInputBridge {
ScrollbarData mThumbData;
ScrollableLayerGuid mTargetGuid;
CSSTransformMatrix mTargetTransform;
bool mTargetIsAncestor;
ScrollThumbInfo(const uint64_t& aThumbAnimationId,
const CSSTransformMatrix& aThumbTransform,
const ScrollbarData& aThumbData,
const ScrollableLayerGuid& aTargetGuid,
const CSSTransformMatrix& aTargetTransform,
bool aTargetIsAncestor)
const CSSTransformMatrix& aTargetTransform)
: mThumbAnimationId(aThumbAnimationId),
mThumbTransform(aThumbTransform),
mThumbData(aThumbData),
mTargetGuid(aTargetGuid),
mTargetTransform(aTargetTransform),
mTargetIsAncestor(aTargetIsAncestor) {
mTargetTransform(aTargetTransform) {
MOZ_ASSERT(mTargetGuid.mScrollId == mThumbData.mTargetViewId);
}
};

Просмотреть файл

@ -121,15 +121,13 @@ bool APZSampler::SampleAnimations(const LayerMetricsWrapper& aLayer,
LayerToParentLayerMatrix4x4 APZSampler::ComputeTransformForScrollThumb(
const LayerToParentLayerMatrix4x4& aCurrentTransform,
const LayerMetricsWrapper& aContent, const ScrollbarData& aThumbData,
bool aScrollbarIsDescendant,
AsyncTransformComponentMatrix* aOutClipTransform) {
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
AssertOnSamplerThread();
return mApz->ComputeTransformForScrollThumb(
aCurrentTransform, aContent.GetTransform(), aContent.GetApzc(),
aContent.Metrics(), aThumbData, aScrollbarIsDescendant,
aOutClipTransform);
aContent.Metrics(), aThumbData, aOutClipTransform);
}
CSSRect APZSampler::GetCurrentAsyncLayoutViewport(

Просмотреть файл

@ -180,15 +180,6 @@ HitTestingTreeNode* HitTestingTreeNode::GetPrevSibling() const {
HitTestingTreeNode* HitTestingTreeNode::GetParent() const { return mParent; }
bool HitTestingTreeNode::IsAncestorOf(const HitTestingTreeNode* aOther) const {
for (const HitTestingTreeNode* cur = aOther; cur; cur = cur->GetParent()) {
if (cur == this) {
return true;
}
}
return false;
}
AsyncPanZoomController* HitTestingTreeNode::GetApzc() const { return mApzc; }
AsyncPanZoomController* HitTestingTreeNode::GetNearestContainingApzc() const {

Просмотреть файл

@ -90,8 +90,6 @@ class HitTestingTreeNode {
HitTestingTreeNode* GetPrevSibling() const;
HitTestingTreeNode* GetParent() const;
bool IsAncestorOf(const HitTestingTreeNode* aOther) const;
/* APZC related methods */
AsyncPanZoomController* GetApzc() const;

Просмотреть файл

@ -1305,37 +1305,23 @@ static bool LayerIsScrollbarTarget(const LayerMetricsWrapper& aTarget,
static void ApplyAsyncTransformToScrollbarForContent(
const RefPtr<APZSampler>& aSampler, Layer* aScrollbar,
const LayerMetricsWrapper& aContent, bool aScrollbarIsDescendant) {
const LayerMetricsWrapper& aContent) {
AsyncTransformComponentMatrix clipTransform;
MOZ_ASSERT(aSampler);
LayerToParentLayerMatrix4x4 transform =
aSampler->ComputeTransformForScrollThumb(
aScrollbar->GetLocalTransformTyped(), aContent,
aScrollbar->GetScrollbarData(), aScrollbarIsDescendant,
&clipTransform);
if (aScrollbarIsDescendant) {
// We also need to make a corresponding change on the clip rect of all the
// layers on the ancestor chain from the scrollbar layer up to but not
// including the layer with the async transform. Otherwise the scrollbar
// shifts but gets clipped and so appears to flicker.
for (Layer* ancestor = aScrollbar; ancestor != aContent.GetLayer();
ancestor = ancestor->GetParent()) {
TransformClipRect(ancestor, clipTransform);
}
}
aScrollbar->GetScrollbarData(), &clipTransform);
SetShadowTransform(aScrollbar, transform);
}
static LayerMetricsWrapper FindScrolledLayerForScrollbar(Layer* aScrollbar,
bool* aOutIsAncestor) {
// First check if the scrolled layer is an ancestor of the scrollbar layer.
static LayerMetricsWrapper FindScrolledLayerForScrollbar(Layer* aScrollbar) {
// Find the root of the layer subtree containing the scrollbar target.
LayerMetricsWrapper root(aScrollbar->Manager()->GetRoot());
LayerMetricsWrapper prevAncestor(aScrollbar);
LayerMetricsWrapper scrolledLayer;
for (LayerMetricsWrapper ancestor(aScrollbar); ancestor;
ancestor = ancestor.GetParent()) {
// Don't walk into remote layer trees; the scrollbar will always be in
@ -1346,13 +1332,12 @@ static LayerMetricsWrapper FindScrolledLayerForScrollbar(Layer* aScrollbar,
}
prevAncestor = ancestor;
if (LayerIsScrollbarTarget(ancestor, aScrollbar)) {
*aOutIsAncestor = true;
return ancestor;
}
// With containerless scrolling, the scrollbar target should never be
// an ancestor.
MOZ_ASSERT(!LayerIsScrollbarTarget(ancestor, aScrollbar));
}
// Search the entire layer space of the scrollbar.
// Search the layer subtree.
ForEachNode<ForwardIterator>(root, [&root, &scrolledLayer, &aScrollbar](
LayerMetricsWrapper aLayerMetrics) {
// Do not recurse into RefLayers, since our initial aSubtreeRoot is the
@ -1371,18 +1356,17 @@ static LayerMetricsWrapper FindScrolledLayerForScrollbar(Layer* aScrollbar,
void AsyncCompositionManager::ApplyAsyncTransformToScrollbar(Layer* aLayer) {
// If this layer corresponds to a scrollbar, then there should be a layer that
// is a previous sibling or a parent that has a matching ViewID on its
// is a previous sibling that has a matching ViewID on its
// FrameMetrics. That is the content that this scrollbar is for. We pick up
// the transient async transform from that layer and use it to update the
// scrollbar position. Note that it is possible that the content layer is no
// longer there; in this case we don't need to do anything because there can't
// be an async transform on the content.
bool isAncestor = false;
const LayerMetricsWrapper& scrollTarget =
FindScrolledLayerForScrollbar(aLayer, &isAncestor);
FindScrolledLayerForScrollbar(aLayer);
if (scrollTarget) {
ApplyAsyncTransformToScrollbarForContent(mCompositorBridge->GetAPZSampler(),
aLayer, scrollTarget, isAncestor);
aLayer, scrollTarget);
}
}