Bug 1781096 - Fix decoding="sync" when the frame is created after the image attribute. r=tnikkel

The fix is the one line in
nsImageLoadingContent::MaybeForceSyncDecoding, but I added new asserts
that should prevent this from regressing in the future.

Differential Revision: https://phabricator.services.mozilla.com/D154815
This commit is contained in:
Emilio Cobos Álvarez 2022-08-17 10:10:26 +00:00
Родитель a8f97c1373
Коммит 9897cb6fe5
5 изменённых файлов: 36 добавлений и 13 удалений

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

@ -112,18 +112,6 @@ add_task(async function() {
) && // in the toolbar
inRange(r.x1, 11, 13), // very close to the left of the screen
},
{
name: "Initial favicon appearing after first paint",
condition: r => {
let faviconRect = win.gBrowser.tabs[0].iconImage.getBoundingClientRect();
return (
r.w == faviconRect.width &&
r.h == faviconRect.height &&
r.x1 == faviconRect.x &&
r.y1 == faviconRect.y
);
},
},
{
// Note that the length and x values here are a bit weird because on
// some fonts, we appear to detect the two words separately.

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

@ -127,6 +127,11 @@ interface nsIImageLoadingContent : imgINotificationObserver
*/
[noscript, infallible] readonly attribute nsIURI currentURI;
/**
* Gets the sync-decoding hint set by the decoding attribute.
*/
[noscript, infallible] readonly attribute boolean syncDecodingHint;
/**
* loadImageWithChannel allows data from an existing channel to be
* used as the image data for this content node.

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

@ -339,6 +339,11 @@ void nsImageLoadingContent::SetLoadingEnabled(bool aLoadingEnabled) {
}
}
nsresult nsImageLoadingContent::GetSyncDecodingHint(bool* aHint) {
*aHint = mSyncDecodingHint;
return NS_OK;
}
already_AddRefed<Promise> nsImageLoadingContent::QueueDecodeAsync(
ErrorResult& aRv) {
Document* doc = GetOurOwnerDoc();
@ -520,7 +525,8 @@ void nsImageLoadingContent::SetSyncDecodingHint(bool aHint) {
void nsImageLoadingContent::MaybeForceSyncDecoding(
bool aPrepareNextRequest, nsIFrame* aFrame /* = nullptr */) {
nsIFrame* frame = GetOurPrimaryImageFrame();
// GetOurPrimaryImageFrame() might not return the frame during frame init.
nsIFrame* frame = aFrame ? aFrame : GetOurPrimaryImageFrame();
if (!frame) {
return;
}

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

@ -516,6 +516,7 @@ void nsImageFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
// We have a PresContext now, so we need to notify the image content node
// that it can register images.
imageLoader->FrameCreated(this);
AssertSyncDecodingHintIsInSync();
if (nsIDocShell* docShell = PresContext()->GetDocShell()) {
RefPtr<BrowsingContext> bc = docShell->GetBrowsingContext();
mIsInObjectOrEmbed = bc->IsEmbedderTypeObjectOrEmbed() &&
@ -2052,9 +2053,24 @@ static bool OldImageHasDifferentRatio(const nsImageFrame& aFrame,
return oldRatio != currentRatio;
}
#ifdef DEBUG
void nsImageFrame::AssertSyncDecodingHintIsInSync() const {
if (!IsForElement()) {
return;
}
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
MOZ_ASSERT(imageLoader);
// The opposite is not true, we might have some other heuristics which force
// sync-decoding of images.
MOZ_ASSERT_IF(imageLoader->GetSyncDecodingHint(), mForceSyncDecoding);
}
#endif
void nsDisplayImage::Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) {
MOZ_ASSERT(mImage);
auto* frame = static_cast<nsImageFrame*>(mFrame);
frame->AssertSyncDecodingHintIsInSync();
const bool oldImageIsDifferent =
OldImageHasDifferentRatio(*frame, *mImage, mPrevImage);
@ -2118,6 +2134,7 @@ bool nsDisplayImage::CreateWebRenderCommands(
return false;
}
frame->AssertSyncDecodingHintIsInSync();
const bool oldImageIsDifferent =
OldImageHasDifferentRatio(*frame, *mImage, mPrevImage);

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

@ -298,6 +298,13 @@ class nsImageFrame : public nsAtomicContainerFrame, public nsIReflowCallback {
/// Always sync decode our image when painting if @aForce is true.
void SetForceSyncDecoding(bool aForce) { mForceSyncDecoding = aForce; }
void AssertSyncDecodingHintIsInSync() const
#ifndef DEBUG
{}
#else
;
#endif
/**
* Computes the predicted dest rect that we'll draw into, in app units, based
* upon the provided frame content box. (The content box is what