Bug 1451168 - Ensure the transforms from ancestor stacking contexts are combined properly. r=jrmuizel

When passing the transforms from nsDisplayTransform items down to the
descendant display items, we need to make sure they are combined properly
so that the "ancestor transform" on the APZ side is correctly computed.

MozReview-Commit-ID: Di1FBLYGef5

--HG--
extra : rebase_source : 736e7cd375681f84ca2db8e6b98bf1a7525431d4
This commit is contained in:
Kartikaya Gupta 2018-05-01 16:31:23 -04:00
Родитель d52775986b
Коммит 8cc14c6513
3 изменённых файлов: 40 добавлений и 12 удалений

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

@ -42,7 +42,7 @@ WebRenderLayerScrollData::Initialize(WebRenderScrollData& aOwner,
nsDisplayItem* aItem,
int32_t aDescendantCount,
const ActiveScrolledRoot* aStopAtAsr,
const Maybe<gfx::Matrix4x4>& aTransform)
const Maybe<gfx::Matrix4x4>& aAncestorTransform)
{
MOZ_ASSERT(aDescendantCount >= 0); // Ensure value is valid
MOZ_ASSERT(mDescendantCount == -1); // Don't allow re-setting an already set value
@ -50,11 +50,6 @@ WebRenderLayerScrollData::Initialize(WebRenderScrollData& aOwner,
MOZ_ASSERT(aItem);
aItem->UpdateScrollData(&aOwner, this);
if (aTransform) {
// mTransform might have been set by the UpdateScrollData call above, so
// we should combine rather than clobber
mTransform = *aTransform * mTransform;
}
for (const ActiveScrolledRoot* asr = aItem->GetActiveScrolledRoot();
asr && asr != aStopAtAsr;
asr = asr->mParent) {
@ -71,6 +66,24 @@ WebRenderLayerScrollData::Initialize(WebRenderScrollData& aOwner,
mScrollIds.AppendElement(aOwner.AddMetadata(metadata.ref()));
}
}
// aAncestorTransform, if present, is the transform from an ancestor
// nsDisplayTransform that was stored on the stacking context in order to
// propagate it downwards in the tree. (i.e. |aItem| is a strict descendant of
// the nsDisplayTranform which produced aAncestorTransform). We store this
// separately from mTransform because in the case where we have multiple
// scroll metadata on this layer item, the mAncestorTransform is associated
// with the "topmost" scroll metadata, and the mTransform is associated with
// the "bottommost" scroll metadata. The code in
// WebRenderScrollDataWrapper::GetTransform() is responsible for combining
// these transforms and exposing them appropriately. Also, we don't save the
// ancestor transform for thumb layers, because those are a special case in
// APZ; we need to keep the ancestor transform for the scrollable content that
// the thumb scrolls, but not for the thumb itself, as it will result in
// incorrect visual positioning of the thumb.
if (aAncestorTransform && mScrollbarData.mScrollbarLayerType != ScrollbarLayerType::Thumb) {
mAncestorTransform = *aAncestorTransform;
}
}
int32_t
@ -114,6 +127,7 @@ WebRenderLayerScrollData::Dump(const WebRenderScrollData& aOwner) const
for (size_t i : mScrollIds) {
printf_stderr(" metadata: %s\n", Stringify(aOwner.GetScrollMetadata(i)).c_str());
}
printf_stderr(" ancestor transform: %s\n", Stringify(mAncestorTransform).c_str());
printf_stderr(" transform: %s perspective: %d visible: %s\n",
Stringify(mTransform).c_str(), mTransformIsPerspective,
Stringify(mVisibleRegion).c_str());
@ -122,8 +136,8 @@ WebRenderLayerScrollData::Dump(const WebRenderScrollData& aOwner) const
if (mReferentId) {
printf_stderr(" ref layers id: 0x%" PRIx64 "\n", uint64_t(*mReferentId));
}
//printf_stderr(" scroll thumb: %s animation: %" PRIu64 "\n",
// Stringify(mScrollThumbData).c_str(), mScrollbarAnimationId);
printf_stderr(" scrollbar type: %d animation: %" PRIx64 "\n",
(int)mScrollbarData.mScrollbarLayerType, mScrollbarAnimationId);
printf_stderr(" fixed pos container: %" PRIu64 "\n",
mFixedPosScrollContainerId);
}

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

@ -48,7 +48,7 @@ public:
nsDisplayItem* aItem,
int32_t aDescendantCount,
const ActiveScrolledRoot* aStopAtAsr,
const Maybe<gfx::Matrix4x4>& aTransform);
const Maybe<gfx::Matrix4x4>& aAncestorTransform);
int32_t GetDescendantCount() const;
size_t GetScrollMetadataCount() const;
@ -62,6 +62,7 @@ public:
const ScrollMetadata& GetScrollMetadata(const WebRenderScrollData& aOwner,
size_t aIndex) const;
gfx::Matrix4x4 GetAncestorTransform() const { return mAncestorTransform; }
void SetTransform(const gfx::Matrix4x4& aTransform) { mTransform = aTransform; }
gfx::Matrix4x4 GetTransform() const { return mTransform; }
CSSTransformMatrix GetTransformTyped() const;
@ -105,6 +106,7 @@ private:
// Various data that we collect from the Layer in Initialize(), serialize
// over IPC, and use on the parent side in APZ.
gfx::Matrix4x4 mAncestorTransform;
gfx::Matrix4x4 mTransform;
bool mTransformIsPerspective;
EventRegions mEventRegions;
@ -216,6 +218,7 @@ struct ParamTraits<mozilla::layers::WebRenderLayerScrollData>
{
WriteParam(aMsg, aParam.mDescendantCount);
WriteParam(aMsg, aParam.mScrollIds);
WriteParam(aMsg, aParam.mAncestorTransform);
WriteParam(aMsg, aParam.mTransform);
WriteParam(aMsg, aParam.mTransformIsPerspective);
WriteParam(aMsg, aParam.mEventRegions);
@ -232,6 +235,7 @@ struct ParamTraits<mozilla::layers::WebRenderLayerScrollData>
{
return ReadParam(aMsg, aIter, &aResult->mDescendantCount)
&& ReadParam(aMsg, aIter, &aResult->mScrollIds)
&& ReadParam(aMsg, aIter, &aResult->mAncestorTransform)
&& ReadParam(aMsg, aIter, &aResult->mTransform)
&& ReadParam(aMsg, aIter, &aResult->mTransformIsPerspective)
&& ReadParam(aMsg, aIter, &aResult->mEventRegions)

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

@ -222,10 +222,20 @@ public:
{
MOZ_ASSERT(IsValid());
if (AtBottomLayer()) {
return mLayer->GetTransform();
// See WebRenderLayerScrollData::Initialize for more context. The ancestor
// transform is associated with the "topmost" layer, and the transform is
// associated with the "bottommost" layer. If there is only one
// scrollmetadata on the layer, then it is both "topmost" and "bottommost"
// and we combine the two transforms.
gfx::Matrix4x4 transform;
if (AtTopLayer()) {
transform = mLayer->GetAncestorTransform();
}
return gfx::Matrix4x4();
if (AtBottomLayer()) {
transform = transform * mLayer->GetTransform();
}
return transform;
}
CSSTransformMatrix GetTransformTyped() const