mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1247854 - Apply the correct scroll clips to the nsDisplayTransform and nsDisplayPerspective of a scrolled perspective item. r=mattwoodrow a=ritu
I've decided to fix this in a very explicit way. The only "magic" part that's left is how we decide that the AGR of the perspective item is outside the scrolled frame (and I'm not sure myself how that works). I didn't want to change what scroll clips we set on what items, because the scroll clip really belongs on the perspective item, because that's the item that needs to be clipped, and it should also be the item that should be scrolled if it weren't for the fact that APZ wouldn't know that it should apply the perspective transform before the APZ transform. MozReview-Commit-ID: BBw8VPohQI4
This commit is contained in:
parent
d34ce692fb
commit
f0caad65e4
@ -1060,6 +1060,7 @@ public:
|
||||
mContainerLayer(aContainerLayer),
|
||||
mContainerBounds(aContainerBounds),
|
||||
mContainerScrollClip(aContainerScrollClip),
|
||||
mScrollClipForPerspectiveChild(aParameters.mScrollClipForPerspectiveChild),
|
||||
mParameters(aParameters),
|
||||
mPaintedLayerDataTree(*this, aBackgroundColor),
|
||||
mFlattenToSingleLayer(aFlattenToSingleLayer)
|
||||
@ -1365,6 +1366,7 @@ protected:
|
||||
ContainerLayer* mContainerLayer;
|
||||
nsRect mContainerBounds;
|
||||
const DisplayItemScrollClip* mContainerScrollClip;
|
||||
const DisplayItemScrollClip* mScrollClipForPerspectiveChild;
|
||||
DebugOnly<nsRect> mAccumulatedChildBounds;
|
||||
ContainerLayerParameters mParameters;
|
||||
/**
|
||||
@ -3939,6 +3941,22 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mScrollClipForPerspectiveChild) {
|
||||
// We are the single transform child item of an nsDisplayPerspective.
|
||||
// Our parent forwarded a scroll clip to us. Pick it up.
|
||||
// We do this after any clipping has been applied, because this
|
||||
// forwarded scroll clip is only used for scrolling (in the form of
|
||||
// APZ frame metrics), not for clipping - the clip still belongs on
|
||||
// the perspective item.
|
||||
MOZ_ASSERT(itemType == nsDisplayItem::TYPE_TRANSFORM);
|
||||
MOZ_ASSERT(!itemScrollClip);
|
||||
MOZ_ASSERT(!agrScrollClip);
|
||||
MOZ_ASSERT(DisplayItemScrollClip::IsAncestor(mContainerScrollClip,
|
||||
mScrollClipForPerspectiveChild));
|
||||
itemScrollClip = mScrollClipForPerspectiveChild;
|
||||
agrScrollClip = mScrollClipForPerspectiveChild;
|
||||
}
|
||||
|
||||
// 3D-transformed layers don't necessarily draw in the order in which
|
||||
// they're added to their parent container layer.
|
||||
bool mayDrawOutOfOrder = itemType == nsDisplayItem::TYPE_TRANSFORM &&
|
||||
@ -3992,6 +4010,21 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
|
||||
|
||||
mParameters.mBackgroundColor = uniformColor;
|
||||
mParameters.mScrollClip = agrScrollClip;
|
||||
mParameters.mScrollClipForPerspectiveChild = nullptr;
|
||||
|
||||
if (itemType == nsDisplayItem::TYPE_PERSPECTIVE) {
|
||||
// Perspective items have a single child item, an nsDisplayTransform.
|
||||
// If the perspective item is scrolled, but the perspective-inducing
|
||||
// frame is outside the scroll frame (indicated by this items AGR
|
||||
// being outside that scroll frame), we have to take special care to
|
||||
// make APZ scrolling work properly. APZ needs us to put the scroll
|
||||
// frame's FrameMetrics on our child transform ContainerLayer instead.
|
||||
// Our agrScrollClip is the scroll clip that's applicable to our
|
||||
// perspective frame, so it won't be the scroll clip for the scrolled
|
||||
// frame in the case that we care about, and we'll forward that scroll
|
||||
// clip to our child.
|
||||
mParameters.mScrollClipForPerspectiveChild = itemScrollClip;
|
||||
}
|
||||
|
||||
// Just use its layer.
|
||||
// Set layerContentsVisibleRect.width/height to -1 to indicate we
|
||||
|
@ -56,6 +56,7 @@ struct ContainerLayerParameters {
|
||||
, mLayerContentsVisibleRect(nullptr)
|
||||
, mBackgroundColor(NS_RGBA(0,0,0,0))
|
||||
, mScrollClip(nullptr)
|
||||
, mScrollClipForPerspectiveChild(nullptr)
|
||||
, mInTransformedSubtree(false)
|
||||
, mInActiveTransformedSubtree(false)
|
||||
, mDisableSubpixelAntialiasingInDescendants(false)
|
||||
@ -68,6 +69,7 @@ struct ContainerLayerParameters {
|
||||
, mLayerContentsVisibleRect(nullptr)
|
||||
, mBackgroundColor(NS_RGBA(0,0,0,0))
|
||||
, mScrollClip(nullptr)
|
||||
, mScrollClipForPerspectiveChild(nullptr)
|
||||
, mInTransformedSubtree(false)
|
||||
, mInActiveTransformedSubtree(false)
|
||||
, mDisableSubpixelAntialiasingInDescendants(false)
|
||||
@ -83,6 +85,7 @@ struct ContainerLayerParameters {
|
||||
, mOffset(aOffset)
|
||||
, mBackgroundColor(aParent.mBackgroundColor)
|
||||
, mScrollClip(aParent.mScrollClip)
|
||||
, mScrollClipForPerspectiveChild(aParent.mScrollClipForPerspectiveChild)
|
||||
, mInTransformedSubtree(aParent.mInTransformedSubtree)
|
||||
, mInActiveTransformedSubtree(aParent.mInActiveTransformedSubtree)
|
||||
, mDisableSubpixelAntialiasingInDescendants(aParent.mDisableSubpixelAntialiasingInDescendants)
|
||||
@ -113,6 +116,10 @@ struct ContainerLayerParameters {
|
||||
|
||||
nscolor mBackgroundColor;
|
||||
const DisplayItemScrollClip* mScrollClip;
|
||||
|
||||
// usually nullptr, except when building children of an nsDisplayPerspective
|
||||
const DisplayItemScrollClip* mScrollClipForPerspectiveChild;
|
||||
|
||||
bool mInTransformedSubtree;
|
||||
bool mInActiveTransformedSubtree;
|
||||
bool mDisableSubpixelAntialiasingInDescendants;
|
||||
|
@ -0,0 +1,34 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<meta charset="utf-8">
|
||||
<title>Perspective scrolling</title>
|
||||
|
||||
<style>
|
||||
|
||||
html {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
body {
|
||||
height: 100%;
|
||||
perspective: 1px;
|
||||
overflow: auto;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div {
|
||||
height: 4000px;
|
||||
margin: 200px 100px;
|
||||
border: 10px solid black;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div></div>
|
||||
|
||||
<script>
|
||||
|
||||
document.body.scrollTop = 100;
|
||||
|
||||
</script>
|
33
layout/reftests/async-scrolling/perspective-scrolling-1.html
Normal file
33
layout/reftests/async-scrolling/perspective-scrolling-1.html
Normal file
@ -0,0 +1,33 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" reftest-async-scroll>
|
||||
<meta charset="utf-8">
|
||||
<title>Perspective scrolling</title>
|
||||
|
||||
<style>
|
||||
|
||||
html {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
body {
|
||||
height: 100%;
|
||||
perspective: 1px;
|
||||
overflow: auto;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div {
|
||||
transform-style: preserve-3d;
|
||||
height: 4000px;
|
||||
margin: 200px 100px;
|
||||
border: 10px solid black;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<body reftest-displayport-x="0" reftest-displayport-y="0"
|
||||
reftest-displayport-w="800" reftest-displayport-h="2000"
|
||||
reftest-async-scroll-x="0" reftest-async-scroll-y="100">
|
||||
|
||||
<div></div>
|
@ -0,0 +1,28 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<meta charset="utf-8">
|
||||
<title>Perspective in unscrolled state</title>
|
||||
|
||||
<style>
|
||||
|
||||
html {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
body {
|
||||
height: 100%;
|
||||
perspective: 1px;
|
||||
overflow: auto;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div {
|
||||
height: 4000px;
|
||||
margin: 200px 100px 200px;
|
||||
border: 10px solid black;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div></div>
|
35
layout/reftests/async-scrolling/perspective-scrolling-2.html
Normal file
35
layout/reftests/async-scrolling/perspective-scrolling-2.html
Normal file
@ -0,0 +1,35 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" reftest-async-scroll>
|
||||
<meta charset="utf-8">
|
||||
<title>Perspective in unscrolled state</title>
|
||||
|
||||
<style>
|
||||
|
||||
html {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
perspective: 1px;
|
||||
perspective-origin: top left;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
div {
|
||||
transform: translateZ(-1px) scale(2);
|
||||
transform-origin: -100px -200px;
|
||||
margin: 200px 100px;
|
||||
height: 4000px;
|
||||
border: 10px solid black;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<body reftest-displayport-x="0" reftest-displayport-y="0"
|
||||
reftest-displayport-w="800" reftest-displayport-h="2000"
|
||||
reftest-async-scroll-x="0" reftest-async-scroll-y="0"> <!-- no async scrolling -->
|
||||
|
||||
<div></div>
|
@ -0,0 +1,34 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<meta charset="utf-8">
|
||||
<title>Perspective in scrolled state</title>
|
||||
|
||||
<style>
|
||||
|
||||
html {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
body {
|
||||
height: 100%;
|
||||
perspective: 1px;
|
||||
overflow: auto;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div {
|
||||
height: 4000px;
|
||||
margin: 300px 100px 100px;
|
||||
border: 10px solid black;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div></div>
|
||||
|
||||
<script>
|
||||
|
||||
document.body.scrollTop = 200;
|
||||
|
||||
</script>
|
35
layout/reftests/async-scrolling/perspective-scrolling-3.html
Normal file
35
layout/reftests/async-scrolling/perspective-scrolling-3.html
Normal file
@ -0,0 +1,35 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" reftest-async-scroll>
|
||||
<meta charset="utf-8">
|
||||
<title>Perspective in scrolled state</title>
|
||||
|
||||
<style>
|
||||
|
||||
html {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
perspective: 1px;
|
||||
perspective-origin: top left;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
div {
|
||||
transform: translateZ(-1px) scale(2);
|
||||
transform-origin: -100px -200px;
|
||||
margin: 200px 100px;
|
||||
height: 4000px;
|
||||
border: 10px solid black;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<body reftest-displayport-x="0" reftest-displayport-y="0"
|
||||
reftest-displayport-w="800" reftest-displayport-h="2000"
|
||||
reftest-async-scroll-x="0" reftest-async-scroll-y="200">
|
||||
|
||||
<div></div>
|
@ -36,6 +36,9 @@ fuzzy-if(Android,6,4) == offscreen-clipped-blendmode-1.html offscreen-clipped-bl
|
||||
fuzzy-if(Android,6,4) == offscreen-clipped-blendmode-2.html offscreen-clipped-blendmode-ref.html
|
||||
fuzzy-if(Android,6,4) skip == offscreen-clipped-blendmode-3.html offscreen-clipped-blendmode-ref.html # bug 1251588 - wrong AGR on mix-blend-mode item
|
||||
fuzzy-if(Android,6,4) == offscreen-clipped-blendmode-4.html offscreen-clipped-blendmode-ref.html
|
||||
fuzzy-if(Android,7,4) == perspective-scrolling-1.html perspective-scrolling-1-ref.html
|
||||
fuzzy-if(Android,7,4) == perspective-scrolling-2.html perspective-scrolling-2-ref.html
|
||||
fuzzy-if(Android,7,4) == perspective-scrolling-3.html perspective-scrolling-3-ref.html
|
||||
|
||||
# for the following tests, we want to disable the low-precision buffer
|
||||
# as it will expand the displayport beyond what the test specifies in
|
||||
|
Loading…
Reference in New Issue
Block a user