From 79c6ddf304ca2e56f3ddceb127cdbb40c54b8e28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Tue, 21 Sep 2021 11:18:58 +0000 Subject: [PATCH] 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 --- gfx/layers/wr/WebRenderCommandBuilder.cpp | 39 ++++-------------- gfx/layers/wr/WebRenderUserData.h | 30 ++++++++++++++ image/test/mochitest/animatedMask.gif | Bin 0 -> 4568 bytes image/test/mochitest/mochitest.ini | 1 + .../mochitest/test_animated_css_image.html | 21 ++++++++++ layout/style/ImageLoader.cpp | 4 ++ 6 files changed, 64 insertions(+), 31 deletions(-) create mode 100644 image/test/mochitest/animatedMask.gif diff --git a/gfx/layers/wr/WebRenderCommandBuilder.cpp b/gfx/layers/wr/WebRenderCommandBuilder.cpp index 0701fdd5e1dd..97acd7b2980f 100644 --- a/gfx/layers/wr/WebRenderCommandBuilder.cpp +++ b/gfx/layers/wr/WebRenderCommandBuilder.cpp @@ -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 mBlobKey; - std::vector> mFonts; - std::vector> mExternalSurfaces; - LayerIntRect mItemRect; - nsPoint mMaskOffset; - nsStyleImageLayers mMaskStyle; - gfx::Size mScale; - bool mShouldHandleOpacity; -}; +void WebRenderMaskData::Invalidate() { + mMaskStyle = nsStyleImageLayers(nsStyleImageLayers::LayerType::Mask); +} Maybe WebRenderCommandBuilder::BuildWrMaskImage( nsDisplayMasksAndClipPaths* aMaskItem, wr::DisplayListBuilder& aBuilder, diff --git a/gfx/layers/wr/WebRenderUserData.h b/gfx/layers/wr/WebRenderUserData.h index 46c215004350..59556272dda8 100644 --- a/gfx/layers/wr/WebRenderUserData.h +++ b/gfx/layers/wr/WebRenderUserData.h @@ -345,6 +345,36 @@ class WebRenderRemoteData : public WebRenderUserData { RefPtr 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 mBlobKey; + std::vector> mFonts; + std::vector> mExternalSurfaces; + LayerIntRect mItemRect; + nsPoint mMaskOffset; + nsStyleImageLayers mMaskStyle; + gfx::Size mScale; + bool mShouldHandleOpacity; +}; + extern void DestroyWebRenderUserDataTable(WebRenderUserDataTable* aTable); struct WebRenderUserDataProperty { diff --git a/image/test/mochitest/animatedMask.gif b/image/test/mochitest/animatedMask.gif new file mode 100644 index 0000000000000000000000000000000000000000..72a1c51ddc287ae44af76448fe72d5b494d881ec GIT binary patch literal 4568 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 V+t>Zkx%=wxT9pEHh)M$N{|h_-KjQ!Z literal 0 HcmV?d00001 diff --git a/image/test/mochitest/mochitest.ini b/image/test/mochitest/mochitest.ini index d50d93898d31..3c8be35ccc66 100644 --- a/image/test/mochitest/mochitest.ini +++ b/image/test/mochitest/mochitest.ini @@ -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 diff --git a/image/test/mochitest/test_animated_css_image.html b/image/test/mochitest/test_animated_css_image.html index ead07c567ad1..ca4a47915fb9 100644 --- a/image/test/mochitest/test_animated_css_image.html +++ b/image/test/mochitest/test_animated_css_image.html @@ -188,6 +188,27 @@ const kTests = [ return doc.querySelector("div"); }, }, + + // bug 1731138: Animated mask + { + html: ` + + +
+ `, + element(doc) { + return doc.querySelector("div"); + }, + }, ]; onload = async function() { diff --git a/layout/style/ImageLoader.cpp b/layout/style/ImageLoader.cpp index f999ac2cfa1b..34cc2b8cbebf 100644 --- a/layout/style/ImageLoader.cpp +++ b/layout/style/ImageLoader.cpp @@ -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(data.get())->Invalidate(); + invalidateFrame = true; + break; case layers::WebRenderUserData::UserDataType::eImage: if (static_cast(data.get()) ->UsingSharedSurface(aRequest->GetProducerId())) {