summaryrefslogtreecommitdiffstats
path: root/layout/painting
diff options
context:
space:
mode:
Diffstat (limited to 'layout/painting')
-rw-r--r--layout/painting/crashtests/1862277-1.html6
-rw-r--r--layout/painting/crashtests/1870415-1.html35
-rw-r--r--layout/painting/crashtests/crashtests.list7
-rw-r--r--layout/painting/nsDisplayList.cpp63
-rw-r--r--layout/painting/nsDisplayList.h27
5 files changed, 95 insertions, 43 deletions
diff --git a/layout/painting/crashtests/1862277-1.html b/layout/painting/crashtests/1862277-1.html
index 820bade2fd..f732bb71b6 100644
--- a/layout/painting/crashtests/1862277-1.html
+++ b/layout/painting/crashtests/1862277-1.html
@@ -15,11 +15,7 @@ that is affected by the clip path a couple times. The retained display list won'
container, but the modified display list will have the nsDisplayMask, this will confuse merging when the
same item appears inside two different containers.
-Note that we set widget.windows.window_occlusion_tracking.enabled=false for this test because
-crashtests leave windows open and occlud the crashtest window, which means the refresh driver doesn't
-run, which means the requestAnimationFrame don't run. Bug 1864255 tracks fixing this.
-
-Note that we image.decode-sync.enabled=false for this test because sync decoding triggers extra
+Note that we image.testing.decode-sync.enabled=false for this test because sync decoding triggers extra
invalidation which "fixes" this bug before it gets a chance to appear. Bug 1866411 tracks this.
-->
diff --git a/layout/painting/crashtests/1870415-1.html b/layout/painting/crashtests/1870415-1.html
new file mode 100644
index 0000000000..ef379dad4d
--- /dev/null
+++ b/layout/painting/crashtests/1870415-1.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html class="reftest-wait" >
+
+<style>
+HTML {
+ border: lch(53% 16 none) solid 472288419.0851412mm;
+ background-blend-mode: difference
+}
+* {
+ overflow-y: hidden;
+ position: sticky;
+ content-visibility: auto;
+ background: url(#x) local, scroll repeat-x bottom / contain, left 3% center / contain scroll padding-box, image-set('\E0FAEt\1BA3F\E0379o8' type('c\1D242+\6F0\A8E6**=\D\A\11D5D\1F9D4*\A0\FFF9 2\1F500\6F9\26F1C\2F220 0\D\1FE4C\2064*|\301\62DC\1DD1\101FD 3\643X\E00E6\E0998\2B4C7Y\6F0+*=\23DD6 A>\1615A\101FD\E0C32\1DE4\2F51D\A34A\1D908\1D244\1F9FB*"\135F-=%Z\1D172\1BF1C\C7D\A16B\669\FFFF\A21F\161BF\E0E63\3099\1BBDB\1924\E006C 4\20F9D-\101FD\E3F7\D\3099\2F97E\B>>=5\669\2998A\E0A33\E0450\1D1AC\2FDC2\2FE9E\D\1F973\E0918>\E0493\346\209BC\1D244 c4\1F469\669\E0563\D\Al3\2027\66A') 249dppx, '\E0E1B\E0500\2CC7\E020A+\FDDE\66A 0\A 5\200E\2FD7A/*\1F82 91\2F69F\D\1A7F\FE20(\D-\2F9B0\202A,\3099\FFF9\2FFEA 99G\FE22\11A03 e\16D58]7\1B7D8y\ED25\E08AB\D\A\7F2\235FE\1DBB1\3000\1B71\2029\E08A1vH|=\B751\D\0\66A' type('\23A\2F300\BCC\B48E\1D187 7\E0969\98D3\BBC5\133DF?[\2F36E\1F252\E04CE>>=\2F94D.\660\1D243\E029A 3\27048L\2BF98\2FF8B\7F1\66A\1D168 9\2826\101FD\390\1B07D 29\669\7E5DZ\2029\6F9\6F0\11F0D\27DA2\2F7EB\29A96\E05A5sA\D;\253CB\660\166D6\E0C9C*=\2F046\A682\2044\660o\296A9p\2011{\202D\202F\9\2F8BD C\\#\2A9A7\645') 75dpcm, '\301\4430\301\2F40D\1D943\16DFC 8R\12ED6\1FC45\2426\2FEA8 0<<=\29E7D\2AC8E\D\2028\66A\1D244\1125A\16FE7\D\D\16ED4\66B\1D0BA|=\FB2C\E0C77\BF-\2F93B\23A\A\D^=s\F6D5\E02EB\E008D\36A\0\\\1B885\205F/=\E0FD5\3000#8]n\6F9s\2F9B7\1A7F\B^\1D574!U4\2F645\E0A65\2060B;\FDFA\D>>=\1648A\D3EC\24A09\E05AE\E02FF\A0\E078E{\E0135\2FB3F\1D16E f\1D1AA\4FFB\3A7A\16943\A\D\E032B' 11dppx type('\489\5932\E0A6B\6F9\1F7A0\66A\1F182\205F\D\A\7F3\1DD7\16110\1D11B\1BADC\72E5\12CDB\E034E\25E85\8\669\AD\3000 9')), border-box repeat-x;
+ rotate: 2116778118.5570207grad 32 20208 64
+}
+</style>
+<script>
+window.addEventListener("load", () => {
+ let a = document.createElementNS("http://www.w3.org/1999/xhtml", "form")
+ document.documentElement.appendChild(a)
+ let b = document.createElementNS("http://www.w3.org/1999/xhtml", "p")
+ let c = document.createElementNS("http://www.w3.org/1999/xhtml", "span")
+ let d = document.createElementNS("http://www.w3.org/1999/xhtml", "bdo")
+ d.contentEditable = true
+ d.setAttribute("autofocus", true)
+ c.appendChild(d)
+ b.appendChild(c)
+ a.appendChild(b)
+ setTimeout(finish, 1000);
+});
+function finish() {
+ document.documentElement.className = "";
+}
+</script>
+</html>
diff --git a/layout/painting/crashtests/crashtests.list b/layout/painting/crashtests/crashtests.list
index 954e2de6e2..b51fa60007 100644
--- a/layout/painting/crashtests/crashtests.list
+++ b/layout/painting/crashtests/crashtests.list
@@ -8,7 +8,7 @@ load 1418722-1.html
load 1419917.html
load 1425271-1.html
load 1428906-1.html
-pref(widget.windows.window_occlusion_tracking.enabled,false) load 1430589-1.html # Bug 1819154
+load 1430589-1.html
load 1454105-1.html
load 1455944-1.html
load 1458145.html
@@ -18,7 +18,7 @@ load 1469472.html
load 1477831-1.html
load 1504033.html
load 1514544-1.html
-asserts(0-5) load 1547420-1.html
+asserts(0-10) load 1547420-1.html # bug 1524064
load 1549909.html
load 1551389-1.html
asserts(0-2) load 1555819-1.html
@@ -31,4 +31,5 @@ load 1714584-1.html
load 1763006-1.html
load 1819957-1.html
load 1851726-1.html
-pref(widget.windows.window_occlusion_tracking.enabled,false) pref(image.decode-sync.enabled,false) load 1862277-1.html
+pref(image.testing.decode-sync.enabled,false) load 1862277-1.html
+needs-focus pref(ui.caretBlinkTime,200) pref(image.testing.decode-sync.enabled,false) asserts(0-2) load 1870415-1.html
diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp
index 2c2b7cb04c..0007f86c5e 100644
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -5207,7 +5207,7 @@ bool nsDisplayOwnLayer::CreateWebRenderCommands(
Maybe<wr::WrAnimationProperty> prop;
bool needsProp = aManager->LayerManager()->AsyncPanZoomEnabled() &&
(IsScrollThumbLayer() || IsZoomingLayer() ||
- ShouldGetFixedOrStickyAnimationId() ||
+ ShouldGetFixedAnimationId() ||
(IsRootScrollbarContainer() && HasDynamicToolbar()));
if (needsProp) {
@@ -5234,7 +5234,7 @@ bool nsDisplayOwnLayer::CreateWebRenderCommands(
params.prim_flags |= wr::PrimitiveFlags::IS_SCROLLBAR_CONTAINER;
}
if (IsZoomingLayer() ||
- (ShouldGetFixedOrStickyAnimationId() ||
+ (ShouldGetFixedAnimationId() ||
(IsRootScrollbarContainer() && HasDynamicToolbar()))) {
params.is_2d_scale_translation = true;
params.should_snap = true;
@@ -5250,9 +5250,8 @@ bool nsDisplayOwnLayer::CreateWebRenderCommands(
bool nsDisplayOwnLayer::UpdateScrollData(WebRenderScrollData* aData,
WebRenderLayerScrollData* aLayerData) {
- bool isRelevantToApz =
- (IsScrollThumbLayer() || IsScrollbarContainer() || IsZoomingLayer() ||
- ShouldGetFixedOrStickyAnimationId());
+ bool isRelevantToApz = (IsScrollThumbLayer() || IsScrollbarContainer() ||
+ IsZoomingLayer() || ShouldGetFixedAnimationId());
if (!isRelevantToApz) {
return false;
@@ -5267,16 +5266,11 @@ bool nsDisplayOwnLayer::UpdateScrollData(WebRenderScrollData* aData,
return true;
}
- if (IsFixedPositionLayer() && ShouldGetFixedOrStickyAnimationId()) {
+ if (IsFixedPositionLayer() && ShouldGetFixedAnimationId()) {
aLayerData->SetFixedPositionAnimationId(mWrAnimationId);
return true;
}
- if (IsStickyPositionLayer() && ShouldGetFixedOrStickyAnimationId()) {
- aLayerData->SetStickyPositionAnimationId(mWrAnimationId);
- return true;
- }
-
MOZ_ASSERT(IsScrollbarContainer() || IsScrollThumbLayer());
aLayerData->SetScrollbarData(mScrollbarData);
@@ -5458,7 +5452,7 @@ bool nsDisplayFixedPosition::UpdateScrollData(
return true;
}
-bool nsDisplayFixedPosition::ShouldGetFixedOrStickyAnimationId() {
+bool nsDisplayFixedPosition::ShouldGetFixedAnimationId() {
#if defined(MOZ_WIDGET_ANDROID)
return mFrame->PresContext()->IsRootContentDocumentCrossProcess() &&
nsLayoutUtils::ScrollIdForRootScrollFrame(mFrame->PresContext()) ==
@@ -5522,7 +5516,8 @@ nsDisplayStickyPosition::nsDisplayStickyPosition(
: nsDisplayOwnLayer(aBuilder, aFrame, aList, aActiveScrolledRoot),
mContainerASR(aContainerASR),
mClippedToDisplayPort(aClippedToDisplayPort),
- mShouldFlatten(false) {
+ mShouldFlatten(false),
+ mWrStickyAnimationId(0) {
MOZ_COUNT_CTOR(nsDisplayStickyPosition);
}
@@ -5738,12 +5733,27 @@ bool nsDisplayStickyPosition::CreateWebRenderCommands(
wr::LayoutVector2D applied = {
NSAppUnitsToFloatPixels(appliedOffset.x, auPerDevPixel),
NSAppUnitsToFloatPixels(appliedOffset.y, auPerDevPixel)};
+ bool needsProp = ShouldGetStickyAnimationId();
+ Maybe<wr::WrAnimationProperty> prop;
+ auto spatialKey = wr::SpatialKey(uint64_t(mFrame), GetPerFrameKey(),
+ wr::SpatialKeyKind::Sticky);
+ if (needsProp) {
+ RefPtr<WebRenderAPZAnimationData> animationData =
+ aManager->CommandBuilder()
+ .CreateOrRecycleWebRenderUserData<WebRenderAPZAnimationData>(
+ this);
+ mWrStickyAnimationId = animationData->GetAnimationId();
+
+ prop.emplace();
+ prop->id = mWrStickyAnimationId;
+ prop->key = spatialKey;
+ prop->effect_type = wr::WrAnimationType::Transform;
+ }
wr::WrSpatialId spatialId = aBuilder.DefineStickyFrame(
wr::ToLayoutRect(bounds), topMargin.ptrOr(nullptr),
rightMargin.ptrOr(nullptr), bottomMargin.ptrOr(nullptr),
- leftMargin.ptrOr(nullptr), vBounds, hBounds, applied,
- wr::SpatialKey(uint64_t(mFrame), GetPerFrameKey(),
- wr::SpatialKeyKind::Sticky));
+ leftMargin.ptrOr(nullptr), vBounds, hBounds, applied, spatialKey,
+ prop.ptrOr(nullptr));
saccHelper.emplace(aBuilder, spatialId);
aManager->CommandBuilder().PushOverrideForASR(mContainerASR, spatialId);
@@ -5812,6 +5822,10 @@ bool nsDisplayStickyPosition::UpdateScrollData(
->GetContent());
aLayerData->SetStickyPositionScrollContainerId(scrollId);
}
+
+ if (ShouldGetStickyAnimationId()) {
+ aLayerData->SetStickyPositionAnimationId(mWrStickyAnimationId);
+ }
}
// Return true if either there is a dynamic toolbar affecting this sticky
// item or the OwnLayer base implementation returns true for some other
@@ -5821,21 +5835,8 @@ bool nsDisplayStickyPosition::UpdateScrollData(
return ret;
}
-bool nsDisplayStickyPosition::ShouldGetFixedOrStickyAnimationId() {
-#if defined(MOZ_WIDGET_ANDROID)
- if (HasDynamicToolbar()) { // also implies being in the cross-process RCD
- StickyScrollContainer* stickyScrollContainer = GetStickyScrollContainer();
- if (stickyScrollContainer) {
- ScrollableLayerGuid::ViewID scrollId =
- nsLayoutUtils::FindOrCreateIDFor(stickyScrollContainer->ScrollFrame()
- ->GetScrolledFrame()
- ->GetContent());
- return nsLayoutUtils::ScrollIdForRootScrollFrame(mFrame->PresContext()) ==
- scrollId;
- }
- }
-#endif
- return false;
+bool nsDisplayStickyPosition::ShouldGetStickyAnimationId() const {
+ return HasDynamicToolbar(); // also implies being in the cross-process RCD
}
nsDisplayScrollInfoLayer::nsDisplayScrollInfoLayer(
diff --git a/layout/painting/nsDisplayList.h b/layout/painting/nsDisplayList.h
index acda6ea863..9862415f61 100644
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -5475,7 +5475,7 @@ class nsDisplayOwnLayer : public nsDisplayWrapList {
bool IsFixedPositionLayer() const;
bool IsStickyPositionLayer() const;
bool HasDynamicToolbar() const;
- virtual bool ShouldGetFixedOrStickyAnimationId() { return false; }
+ virtual bool ShouldGetFixedAnimationId() { return false; }
bool CreatesStackingContextHelper() override { return true; }
@@ -5491,6 +5491,16 @@ class nsDisplayOwnLayer : public nsDisplayWrapList {
*/
layers::ScrollbarData mScrollbarData;
bool mForceActive;
+
+ // Used for APZ to animate this layer for purposes such as
+ // pinch-zooming or scrollbar thumb movement. Note that setting this
+ // creates a WebRender ReferenceFrame spatial node, and should only
+ // be used for display items that establish a Gecko reference frame
+ // as well (or leaf items like scrollbar thumb nodes where it does not
+ // matter).
+ // FIXME: This is currently also used for adjusting position:fixed items
+ // for dynamic toolbar movement. This may be a problem as position:fixed
+ // items do not establish Gecko reference frames.
uint64_t mWrAnimationId;
};
@@ -5550,7 +5560,8 @@ class nsDisplayStickyPosition : public nsDisplayOwnLayer {
: nsDisplayOwnLayer(aBuilder, aOther),
mContainerASR(aOther.mContainerASR),
mClippedToDisplayPort(aOther.mClippedToDisplayPort),
- mShouldFlatten(false) {
+ mShouldFlatten(false),
+ mWrStickyAnimationId(0) {
MOZ_COUNT_CTOR(nsDisplayStickyPosition);
}
@@ -5575,7 +5586,6 @@ class nsDisplayStickyPosition : public nsDisplayOwnLayer {
bool UpdateScrollData(layers::WebRenderScrollData* aData,
layers::WebRenderLayerScrollData* aLayerData) override;
- bool ShouldGetFixedOrStickyAnimationId() override;
const ActiveScrolledRoot* GetContainerASR() const { return mContainerASR; }
@@ -5591,6 +5601,8 @@ class nsDisplayStickyPosition : public nsDisplayOwnLayer {
return mShouldFlatten;
}
+ bool ShouldGetStickyAnimationId() const;
+
private:
NS_DISPLAY_ALLOW_CLONING()
@@ -5620,6 +5632,13 @@ class nsDisplayStickyPosition : public nsDisplayOwnLayer {
// True if this item should be flattened away.
bool mShouldFlatten;
+
+ // Used for APZ to animate the sticky element in the compositor
+ // for purposes such as dynamic toolbar movement and (in the future)
+ // overscroll-related adjustment. Unlike nsDisplayOwnLayer::mWrAnimationId,
+ // this does not create a WebRender ReferenceFrame, which is important
+ // because sticky elements do not establish Gecko reference frames either.
+ uint64_t mWrStickyAnimationId;
};
class nsDisplayFixedPosition : public nsDisplayOwnLayer {
@@ -5661,7 +5680,7 @@ class nsDisplayFixedPosition : public nsDisplayOwnLayer {
nsDisplayListBuilder* aDisplayListBuilder) override;
bool UpdateScrollData(layers::WebRenderScrollData* aData,
layers::WebRenderLayerScrollData* aLayerData) override;
- bool ShouldGetFixedOrStickyAnimationId() override;
+ bool ShouldGetFixedAnimationId() override;
void WriteDebugInfo(std::stringstream& aStream) override;
protected: