Skip to content

Commit

Permalink
Apply patch. rdar://problem/108930635
Browse files Browse the repository at this point in the history
Identifier: 263769.50@safari-7616.1.14.10-branch
  • Loading branch information
Dan Robson committed May 24, 2023
1 parent c8446e4 commit 645d9c0
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<body>
<p>This test ensures if an image with decoding="async" is decoded after the first paint, it will not flicker.</p>
<img src="resources/green-400x400.png">
</body>
22 changes: 22 additions & 0 deletions LayoutTests/fast/images/decode-decoding-change-image-src.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<body>
<p>This test ensures if an image with decoding="async" is decoded after the first paint, it will not flicker.</p>
<img id="image" decoding="async" src="">
<script>
if (window.internals && window.testRunner) {
internals.clearMemoryCache();
testRunner.waitUntilDone();
}

function setImageSrc() {
var image = document.getElementById("image");
image.onload = (() => {
// Force layout and display so the image frame starts decoding.
document.body.offsetHeight;
if (window.testRunner)
testRunner.notifyDone();
});
image.src = "resources/green-400x400.png";
}
requestAnimationFrame(setImageSrc);
</script>
</body>
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
function loadImage(image, src) {
return new Promise((resolve) => {
image.onload = (() => {
// Move the image to a new separate layer.
var box = document.createElement("div");
box.style.willChange = "transform";
box.appendChild(image);
document.body.appendChild(box);

if (window.internals && window.testRunner) {
// Force layout and display so the image gets drawn.
document.body.offsetHeight;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
function loadImage(image, src) {
return new Promise((resolve) => {
image.onload = (() => {
// Move the image to a new separate layer.
var box = document.createElement("div");
box.style.willChange = "transform";
box.appendChild(image);
document.body.appendChild(box);

if (window.internals && window.testRunner) {
// Force layout and display so the image gets drawn.
document.body.offsetHeight;
Expand Down
41 changes: 27 additions & 14 deletions Source/WebCore/rendering/RenderBoxModelObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,32 +309,45 @@ DecodingMode RenderBoxModelObject::decodingModeForImageDraw(const Image& image,
}

// Large image case.
// Some document types force synchronous decoding.
#if PLATFORM(IOS_FAMILY)
if (IOSApplication::isIBooksStorytime())
return DecodingMode::Synchronous;
#endif
if (document().isImageDocument())
return DecodingMode::Synchronous;

// A PaintBehavior may force synchronous decoding.
if (paintInfo.paintBehavior.contains(PaintBehavior::Snapshotting))
return DecodingMode::Synchronous;

// <img decoding="sync"> forces synchronous decoding.
if (is<HTMLImageElement>(element())) {
auto decodingMode = downcast<HTMLImageElement>(*element()).decodingMode();
if (decodingMode == DecodingMode::Asynchronous)
return DecodingMode::Asynchronous;
if (decodingMode == DecodingMode::Synchronous)
if (downcast<HTMLImageElement>(*element()).decodingMode() == DecodingMode::Synchronous)
return DecodingMode::Synchronous;
}

// Layout tests may force asynchronous decoding.
if (bitmapImage.isLargeImageAsyncDecodingEnabledForTesting())
return DecodingMode::Asynchronous;
if (document().isImageDocument())
return DecodingMode::Synchronous;
if (!settings().largeImageAsyncDecodingEnabled())
return DecodingMode::Synchronous;
if (!bitmapImage.canUseAsyncDecodingForLargeImages())
return DecodingMode::Synchronous;
if (paintInfo.paintBehavior.contains(PaintBehavior::TileFirstPaint))
return DecodingMode::Asynchronous;
// FIXME: isVisibleInViewport() is not cheap. Find a way to make this condition faster.
if (!isVisibleInViewport())

// Not first paint, so we have to avoid flickering anyway.
if (!paintInfo.paintBehavior.contains(PaintBehavior::TileFirstPaint)) {
// FIXME: isVisibleInViewport() is not cheap. Find a way to make this condition faster.
if (isVisibleInViewport())
return DecodingMode::Synchronous;
}

// <img decoding="async"> forces asynchronous decoding.
if (is<HTMLImageElement>(element())) {
if (downcast<HTMLImageElement>(*element()).decodingMode() == DecodingMode::Asynchronous)
return DecodingMode::Asynchronous;
}

// Resepect the web preferences key: largeImageAsyncDecodingEnabled.
if (settings().largeImageAsyncDecodingEnabled() && bitmapImage.canUseAsyncDecodingForLargeImages())
return DecodingMode::Asynchronous;

return DecodingMode::Synchronous;
}

Expand Down

0 comments on commit 645d9c0

Please sign in to comment.