Bug 1731138 - Invalidate WebRender mask data from css::ImageLoader. r=tnikkel

Otherwise we don't properly repaint animated images.

Differential Revision: https://phabricator.services.mozilla.com/D126093
This commit is contained in:
Emilio Cobos Álvarez 2021-09-21 11:18:58 +00:00
parent 032eecdec3
commit 79c6ddf304
6 changed files with 64 additions and 31 deletions

View File

@ -2409,39 +2409,16 @@ WebRenderCommandBuilder::GenerateFallbackData(
return fallbackData.forget();
}
class WebRenderMaskData : public WebRenderUserData {
public:
explicit WebRenderMaskData(RenderRootStateManager* aManager,
nsDisplayItem* aItem)
: WebRenderUserData(aManager, aItem),
mMaskStyle(nsStyleImageLayers::LayerType::Mask),
mShouldHandleOpacity(false) {
MOZ_COUNT_CTOR(WebRenderMaskData);
}
virtual ~WebRenderMaskData() {
MOZ_COUNT_DTOR(WebRenderMaskData);
ClearImageKey();
void WebRenderMaskData::ClearImageKey() {
if (mBlobKey) {
mManager->AddBlobImageKeyForDiscard(mBlobKey.value());
}
mBlobKey.reset();
}
void ClearImageKey() {
if (mBlobKey) {
mManager->AddBlobImageKeyForDiscard(mBlobKey.value());
}
mBlobKey.reset();
}
UserDataType GetType() override { return UserDataType::eMask; }
static UserDataType Type() { return UserDataType::eMask; }
Maybe<wr::BlobImageKey> mBlobKey;
std::vector<RefPtr<gfx::ScaledFont>> mFonts;
std::vector<RefPtr<gfx::SourceSurface>> mExternalSurfaces;
LayerIntRect mItemRect;
nsPoint mMaskOffset;
nsStyleImageLayers mMaskStyle;
gfx::Size mScale;
bool mShouldHandleOpacity;
};
void WebRenderMaskData::Invalidate() {
mMaskStyle = nsStyleImageLayers(nsStyleImageLayers::LayerType::Mask);
}
Maybe<wr::ImageMask> WebRenderCommandBuilder::BuildWrMaskImage(
nsDisplayMasksAndClipPaths* aMaskItem, wr::DisplayListBuilder& aBuilder,

View File

@ -345,6 +345,36 @@ class WebRenderRemoteData : public WebRenderUserData {
RefPtr<dom::RemoteBrowser> mRemoteBrowser;
};
class WebRenderMaskData : public WebRenderUserData {
public:
explicit WebRenderMaskData(RenderRootStateManager* aManager,
nsDisplayItem* aItem)
: WebRenderUserData(aManager, aItem),
mMaskStyle(nsStyleImageLayers::LayerType::Mask),
mShouldHandleOpacity(false) {
MOZ_COUNT_CTOR(WebRenderMaskData);
}
virtual ~WebRenderMaskData() {
MOZ_COUNT_DTOR(WebRenderMaskData);
ClearImageKey();
}
void ClearImageKey();
void Invalidate();
UserDataType GetType() override { return UserDataType::eMask; }
static UserDataType Type() { return UserDataType::eMask; }
Maybe<wr::BlobImageKey> mBlobKey;
std::vector<RefPtr<gfx::ScaledFont>> mFonts;
std::vector<RefPtr<gfx::SourceSurface>> mExternalSurfaces;
LayerIntRect mItemRect;
nsPoint mMaskOffset;
nsStyleImageLayers mMaskStyle;
gfx::Size mScale;
bool mShouldHandleOpacity;
};
extern void DestroyWebRenderUserDataTable(WebRenderUserDataTable* aTable);
struct WebRenderUserDataProperty {

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@ -4,6 +4,7 @@ support-files =
animated1.gif
animated1.svg
animated2.gif
animatedMask.gif
animated-gif.gif
animated-gif2.gif
animated-gif_trailing-garbage.gif

View File

@ -188,6 +188,27 @@ const kTests = [
return doc.querySelector("div");
},
},
// bug 1731138: Animated mask
{
html: `
<!doctype html>
<style>
div {
width: 100px;
height: 100px;
background-color: lime;
mask-clip: border-box;
mask-size: 100% 100%;
mask-image: url(animatedMask.gif);
}
</style>
<div></div>
`,
element(doc) {
return doc.querySelector("div");
},
},
];
onload = async function() {

View File

@ -536,6 +536,10 @@ static void InvalidateImages(nsIFrame* aFrame, imgIRequest* aRequest,
// XXX: handle Blob data
invalidateFrame = true;
break;
case layers::WebRenderUserData::UserDataType::eMask:
static_cast<layers::WebRenderMaskData*>(data.get())->Invalidate();
invalidateFrame = true;
break;
case layers::WebRenderUserData::UserDataType::eImage:
if (static_cast<layers::WebRenderImageData*>(data.get())
->UsingSharedSurface(aRequest->GetProducerId())) {