diff --git a/gfx/tests/crashtests/1765667.html b/gfx/tests/crashtests/1765667.html
new file mode 100644
index 000000000000..06654644dc4b
--- /dev/null
+++ b/gfx/tests/crashtests/1765667.html
@@ -0,0 +1,4 @@
+
+
diff --git a/gfx/tests/crashtests/crashtests.list b/gfx/tests/crashtests/crashtests.list
index e675466ddb1d..933cc1079284 100644
--- a/gfx/tests/crashtests/crashtests.list
+++ b/gfx/tests/crashtests/crashtests.list
@@ -212,3 +212,4 @@ load 1745775.html
load 1757002.html
load 1758127-1.html
load 1762973-1.html
+pref(layout.css.backdrop-filter.enabled,true) load 1765667.html
diff --git a/gfx/wr/webrender/src/picture.rs b/gfx/wr/webrender/src/picture.rs
index e55789d6858c..bb9c4502daa7 100644
--- a/gfx/wr/webrender/src/picture.rs
+++ b/gfx/wr/webrender/src/picture.rs
@@ -4827,9 +4827,25 @@ impl PicturePrimitive {
}
}
+ // We know that we'll never need to sample > 300 device pixels outside the tile
+ // for blurring, so clamp the content rect here so that we don't try to allocate
+ // a really large surface in the case of a drop-shadow with large offset.
+ let max_content_rect = (tile.local_dirty_rect.cast_unit() * device_pixel_scale)
+ .inflate(
+ MAX_BLUR_RADIUS * BLUR_SAMPLE_SCALE,
+ MAX_BLUR_RADIUS * BLUR_SAMPLE_SCALE,
+ )
+ .round_out()
+ .to_i32();
+
let content_device_rect = (local_content_rect.cast_unit() * device_pixel_scale)
.round_out()
.to_i32();
+
+ let content_device_rect = content_device_rect
+ .intersection(&max_content_rect)
+ .expect("bug: no intersection with tile dirty rect");
+
let content_task_size = content_device_rect.size();
let normalized_content_rect = content_task_size.into();