Changeset 259830 in webkit
- Timestamp:
- Apr 9, 2020, 2:45:57 PM (6 years ago)
- Location:
- trunk
- Files:
-
- 6 added
- 18 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/svg/animations/css-animation-background-svg-expected.html (added)
-
LayoutTests/svg/animations/css-animation-background-svg.html (added)
-
LayoutTests/svg/animations/css-animation-embedded-svg-expected.html (added)
-
LayoutTests/svg/animations/css-animation-embedded-svg.html (added)
-
LayoutTests/svg/animations/css-animation-hover-svg-expected.html (added)
-
LayoutTests/svg/animations/css-animation-hover-svg.html (added)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/animation/DocumentTimeline.cpp (modified) (2 diffs)
-
Source/WebCore/html/ImageBitmap.cpp (modified) (1 diff)
-
Source/WebCore/loader/cache/CachedImage.cpp (modified) (3 diffs)
-
Source/WebCore/loader/cache/CachedImage.h (modified) (3 diffs)
-
Source/WebCore/loader/cache/CachedImageClient.h (modified) (1 diff)
-
Source/WebCore/loader/cache/CachedResourceLoader.cpp (modified) (3 diffs)
-
Source/WebCore/loader/cache/CachedResourceLoader.h (modified) (3 diffs)
-
Source/WebCore/page/ChromeClient.h (modified) (1 diff)
-
Source/WebCore/page/Page.cpp (modified) (4 diffs)
-
Source/WebCore/page/Page.h (modified) (1 diff)
-
Source/WebCore/platform/graphics/ImageObserver.h (modified) (1 diff)
-
Source/WebCore/rendering/RenderElement.cpp (modified) (2 diffs)
-
Source/WebCore/rendering/RenderElement.h (modified) (2 diffs)
-
Source/WebCore/rendering/RenderImage.cpp (modified) (1 diff)
-
Source/WebCore/svg/graphics/SVGImage.h (modified) (1 diff)
-
Source/WebCore/svg/graphics/SVGImageClients.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r259829 r259830 1 2020-04-09 Said Abou-Hallawa <sabouhallawa@apple.com> 2 3 REGRESSION: CSS animations inside an embedded SVG image do not animate 4 https://bugs.webkit.org/show_bug.cgi?id=209370 5 6 Reviewed by Simon Fraser. 7 8 * svg/animations/css-animation-background-svg-expected.html: Added. 9 * svg/animations/css-animation-background-svg.html: Added. 10 * svg/animations/css-animation-embedded-svg-expected.html: Added. 11 * svg/animations/css-animation-embedded-svg.html: Added. 12 * svg/animations/css-animation-hover-svg-expected.html: Added. 13 * svg/animations/css-animation-hover-svg.html: Added. 14 1 15 2020-04-09 Keith Miller <keith_miller@apple.com> 2 16 -
trunk/Source/WebCore/ChangeLog
r259829 r259830 1 2020-04-09 Said Abou-Hallawa <sabouhallawa@apple.com> 2 3 REGRESSION: CSS animations inside an embedded SVG image do not animate 4 https://bugs.webkit.org/show_bug.cgi?id=209370 5 6 Reviewed by Simon Fraser. 7 8 If WebAnimation is enabled and the SVGImage includes CSS animations, the 9 DocumentTimeline is added to the SVGDocument of the embedded SVGImage. 10 Because the SVGImage has its own Page the RenderingUpdate is scheduled 11 and the updateRendering steps run in this Page. 12 13 The Page of the SVGImage is inactive such that scheduling RenderingUpdate 14 fails; therefore the updateRendering steps never run and the CSS animation 15 never advances. 16 17 The fix is: 18 19 1) Scheduling the RenderingUpdate: This has to happen in the Page which 20 contains the renderer of the SVGImage. Because DocumentTimeline is 21 added to SVGDocument, this scheduling will go through these hubs: 22 - DocumentTimeline 23 - Page 24 - ChromeClient -> SVGImageChromeClient 25 - SVGImage 26 - ImageObserver -> CachedImageObserver 27 - CachedImage 28 - CachedImageClient -> RenderElement 29 - Page 30 31 2) Running the updateRendering steps: Each document in the Page will 32 enumerate its cached SVGImages. The updateRendering of the Page of 33 each SVGImage will be called. 34 35 To make enumerating the cached SVGImages of a Document faster, the URL 36 of the cached SVGImage will be added to the cachedSVGImagesURLs of 37 CachedResourceLoader when notifyFinished() is called for associated 38 CachedImage. 39 40 Tests: svg/animations/css-animation-background-svg.html 41 svg/animations/css-animation-embedded-svg.html 42 svg/animations/css-animation-hover-svg.html 43 44 * animation/DocumentTimeline.cpp: 45 (WebCore::DocumentTimeline::scheduleAnimationResolution): 46 (WebCore::DocumentTimeline::updateAnimationsAndSendEvents): 47 * html/ImageBitmap.cpp: 48 * loader/cache/CachedImage.cpp: 49 (WebCore::CachedImage::hasSVGImage const): 50 (WebCore::CachedImage::CachedImageObserver::scheduleTimedRenderingUpdate): 51 (WebCore::CachedImage::scheduleTimedRenderingUpdate): 52 * loader/cache/CachedImage.h: 53 * loader/cache/CachedImageClient.h: 54 (WebCore::CachedImageClient::scheduleTimedRenderingUpdate): 55 * loader/cache/CachedResourceLoader.cpp: 56 (WebCore::isSVGImageCachedResource): 57 (WebCore::cachedResourceSVGImage): 58 (WebCore::CachedResourceLoader::notifyFinished): 59 (WebCore:: const): 60 * loader/cache/CachedResourceLoader.h: 61 * page/ChromeClient.h: 62 (WebCore::ChromeClient::scheduleTimedRenderingUpdate): 63 * page/Page.cpp: 64 (WebCore::Page::scheduleTimedRenderingUpdate): 65 (WebCore::Page::updateRendering): 66 * page/Page.h: 67 * platform/graphics/ImageObserver.h: 68 * rendering/RenderElement.cpp: 69 (WebCore::RenderElement::notifyFinished): 70 (WebCore::RenderElement::scheduleTimedRenderingUpdate): 71 * rendering/RenderElement.h: 72 * rendering/RenderImage.cpp: 73 (WebCore::RenderImage::notifyFinished): 74 * svg/graphics/SVGImage.h: 75 * svg/graphics/SVGImageClients.h: 76 1 77 2020-04-09 Keith Miller <keith_miller@apple.com> 2 78 -
trunk/Source/WebCore/animation/DocumentTimeline.cpp
r258834 r259830 340 340 return; 341 341 342 m_document->page()-> renderingUpdateScheduler().scheduleTimedRenderingUpdate();342 m_document->page()->scheduleTimedRenderingUpdate(); 343 343 m_animationResolutionScheduled = true; 344 344 } … … 365 365 void DocumentTimeline::updateAnimationsAndSendEvents() 366 366 { 367 368 367 // Updating animations and sending events may invalidate the timing of some animations, so we must set the m_animationResolutionScheduled 369 368 // flag to false prior to running that procedure to allow animation with timing model updates to schedule updates. -
trunk/Source/WebCore/html/ImageBitmap.cpp
r254893 r259830 529 529 void imageFrameAvailable(const Image&, ImageAnimatingState, const IntRect* = nullptr, DecodingStatus = DecodingStatus::Invalid) override { } 530 530 void changedInRect(const Image&, const IntRect* = nullptr) override { } 531 void scheduleTimedRenderingUpdate(const Image&) override { } 531 532 532 533 private: -
trunk/Source/WebCore/loader/cache/CachedImage.cpp
r256482 r259830 269 269 } 270 270 271 bool CachedImage::hasSVGImage() const 272 { 273 return m_image && m_image->isSVGImage(); 274 } 275 271 276 void CachedImage::setContainerContextForClient(const CachedImageClient& client, const LayoutSize& containerSize, float containerZoom, const URL& imageURL) 272 277 { … … 433 438 for (auto cachedImage : m_cachedImages) 434 439 cachedImage->changedInRect(image, rect); 440 } 441 442 void CachedImage::CachedImageObserver::scheduleTimedRenderingUpdate(const Image& image) 443 { 444 for (auto cachedImage : m_cachedImages) 445 cachedImage->scheduleTimedRenderingUpdate(image); 435 446 } 436 447 … … 685 696 } 686 697 698 void CachedImage::scheduleTimedRenderingUpdate(const Image& image) 699 { 700 if (&image != m_image) 701 return; 702 703 CachedResourceClientWalker<CachedImageClient> walker(m_clients); 704 while (auto* client = walker.next()) 705 client->scheduleTimedRenderingUpdate(); 706 } 707 687 708 bool CachedImage::currentFrameKnownToBeOpaque(const RenderElement* renderer) 688 709 { -
trunk/Source/WebCore/loader/cache/CachedImage.h
r256786 r259830 57 57 WEBCORE_EXPORT Image* imageForRenderer(const RenderObject*); // Returns the nullImage() if the image is not available yet. 58 58 bool hasImage() const { return m_image.get(); } 59 bool hasSVGImage() const; 59 60 bool currentFrameKnownToBeOpaque(const RenderElement*); 60 61 … … 153 154 void imageFrameAvailable(const Image&, ImageAnimatingState, const IntRect* changeRect = nullptr, DecodingStatus = DecodingStatus::Invalid) final; 154 155 void changedInRect(const Image&, const IntRect*) final; 156 void scheduleTimedRenderingUpdate(const Image&) final; 155 157 156 158 HashSet<CachedImage*> m_cachedImages; … … 163 165 void imageFrameAvailable(const Image&, ImageAnimatingState, const IntRect* changeRect = nullptr, DecodingStatus = DecodingStatus::Invalid); 164 166 void changedInRect(const Image&, const IntRect*); 167 void scheduleTimedRenderingUpdate(const Image&); 165 168 166 169 void updateBufferInternal(SharedBuffer&); -
trunk/Source/WebCore/loader/cache/CachedImageClient.h
r223728 r259830 49 49 50 50 virtual void didRemoveCachedImageClient(CachedImage&) { } 51 52 virtual void scheduleTimedRenderingUpdate() { } 51 53 }; 52 54 -
trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp
r259308 r259830 70 70 #include "RuntimeApplicationChecks.h" 71 71 #include "RuntimeEnabledFeatures.h" 72 #include "SVGImage.h" 72 73 #include "ScriptController.h" 73 74 #include "SecurityOrigin.h" … … 787 788 ASSERT_NOT_REACHED(); 788 789 return FetchOptions::Destination::EmptyString; 790 } 791 792 static inline bool isSVGImageCachedResource(const CachedResource* resource) 793 { 794 if (!resource || !is<CachedImage>(*resource)) 795 return false; 796 return downcast<CachedImage>(*resource).hasSVGImage(); 797 } 798 799 static inline SVGImage* cachedResourceSVGImage(CachedResource* resource) 800 { 801 if (!isSVGImageCachedResource(resource)) 802 return nullptr; 803 return downcast<SVGImage>(downcast<CachedImage>(*resource).image()); 789 804 } 790 805 … … 1402 1417 } 1403 1418 1419 void CachedResourceLoader::notifyFinished(const CachedResource& resource) 1420 { 1421 if (isSVGImageCachedResource(&resource)) 1422 m_cachedSVGImagesURLs.add(resource.url()); 1423 } 1424 1425 Vector<Ref<SVGImage>> CachedResourceLoader::allCachedSVGImages() const 1426 { 1427 Vector<Ref<SVGImage>> allCachedSVGImages; 1428 1429 for (auto& cachedSVGImageURL : m_cachedSVGImagesURLs) { 1430 auto* resource = cachedResource(cachedSVGImageURL); 1431 if (auto* image = cachedResourceSVGImage(resource)) 1432 allCachedSVGImages.append(*image); 1433 } 1434 1435 return allCachedSVGImages; 1436 } 1437 1404 1438 ResourceErrorOr<CachedResourceHandle<CachedResource>> CachedResourceLoader::preload(CachedResource::Type type, CachedResourceRequest&& request) 1405 1439 { -
trunk/Source/WebCore/loader/cache/CachedResourceLoader.h
r259116 r259830 58 58 class ImageLoader; 59 59 class Page; 60 class SVGImage; 60 61 class Settings; 61 62 … … 117 118 const DocumentResourceMap& allCachedResources() const { return m_documentResources; } 118 119 120 void notifyFinished(const CachedResource&); 121 Vector<Ref<SVGImage>> allCachedSVGImages() const; 122 119 123 bool autoLoadImages() const { return m_autoLoadImages; } 120 124 void setAutoLoadImages(bool); … … 194 198 195 199 HashSet<String> m_validatedURLs; 200 HashSet<String> m_cachedSVGImagesURLs; 196 201 mutable DocumentResourceMap m_documentResources; 197 202 WeakPtr<Document> m_document; -
trunk/Source/WebCore/page/ChromeClient.h
r259330 r259830 317 317 // to do an eager layout before the drawing. 318 318 virtual void scheduleRenderingUpdate() = 0; 319 virtual bool scheduleTimedRenderingUpdate() { return false; } 319 320 virtual bool needsImmediateRenderingUpdate() const { return false; } 320 321 // Returns whether or not the client can render the composited layer, -
trunk/Source/WebCore/page/Page.cpp
r259820 r259830 30 30 #include "CSSAnimationController.h" 31 31 #include "CacheStorageProvider.h" 32 #include "CachedResourceLoader.h" 32 33 #include "Chrome.h" 33 34 #include "ChromeClient.h" … … 105 106 #include "RuntimeEnabledFeatures.h" 106 107 #include "SVGDocumentExtensions.h" 108 #include "SVGImage.h" 107 109 #include "ScriptController.h" 108 110 #include "ScriptDisallowedScope.h" … … 1299 1301 } 1300 1302 1303 void Page::scheduleTimedRenderingUpdate() 1304 { 1305 if (chrome().client().scheduleTimedRenderingUpdate()) 1306 return; 1307 renderingUpdateScheduler().scheduleTimedRenderingUpdate(); 1308 } 1309 1301 1310 // https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering 1302 1311 void Page::updateRendering() … … 1350 1359 }); 1351 1360 #endif 1361 1362 forEachDocument([] (Document& document) { 1363 for (auto& image : document.cachedResourceLoader().allCachedSVGImages()) { 1364 if (auto* page = image->internalPage()) 1365 page->updateRendering(); 1366 } 1367 }); 1352 1368 1353 1369 layoutIfNeeded(); -
trunk/Source/WebCore/page/Page.h
r259820 r259830 479 479 480 480 WEBCORE_EXPORT void scheduleRenderingUpdate(); 481 void scheduleTimedRenderingUpdate(); 481 482 482 483 WEBCORE_EXPORT void suspendScriptedAnimations(); -
trunk/Source/WebCore/platform/graphics/ImageObserver.h
r239636 r259830 51 51 virtual void imageFrameAvailable(const Image&, ImageAnimatingState, const IntRect* changeRect = nullptr, DecodingStatus = DecodingStatus::Invalid) = 0; 52 52 virtual void changedInRect(const Image&, const IntRect* changeRect = nullptr) = 0; 53 virtual void scheduleTimedRenderingUpdate(const Image&) = 0; 53 54 }; 54 55 -
trunk/Source/WebCore/rendering/RenderElement.cpp
r259762 r259830 27 27 28 28 #include "AXObjectCache.h" 29 #include "CachedResourceLoader.h" 29 30 #if PLATFORM(IOS_FAMILY) 30 31 #include "ContentChangeObserver.h" … … 1325 1326 } 1326 1327 1328 void RenderElement::notifyFinished(CachedResource& resource) 1329 { 1330 document().cachedResourceLoader().notifyFinished(resource); 1331 } 1332 1327 1333 void RenderElement::didRemoveCachedImageClient(CachedImage& cachedImage) 1328 1334 { 1329 1335 if (hasPausedImageAnimations()) 1330 1336 view().removeRendererWithPausedImageAnimations(*this, cachedImage); 1337 } 1338 1339 void RenderElement::scheduleTimedRenderingUpdate() 1340 { 1341 if (auto* page = document().page()) 1342 page->scheduleTimedRenderingUpdate(); 1331 1343 } 1332 1344 -
trunk/Source/WebCore/rendering/RenderElement.h
r259703 r259830 264 264 void willBeRemovedFromTree() override; 265 265 void willBeDestroyed() override; 266 void notifyFinished(CachedResource&) override; 266 267 267 268 void setRenderInlineAlwaysCreatesLineBoxes(bool b) { m_renderInlineAlwaysCreatesLineBoxes = b; } … … 321 322 VisibleInViewportState imageFrameAvailable(CachedImage&, ImageAnimatingState, const IntRect* changeRect) final; 322 323 void didRemoveCachedImageClient(CachedImage&) final; 324 void scheduleTimedRenderingUpdate() final; 323 325 324 326 bool getLeadingCorner(FloatPoint& output, bool& insideFixed) const; -
trunk/Source/WebCore/rendering/RenderImage.cpp
r257917 r259830 419 419 if (is<HTMLImageElement>(element())) 420 420 page().didFinishLoadingImageForElement(downcast<HTMLImageElement>(*element())); 421 422 RenderReplaced::notifyFinished(newImage); 421 423 } 422 424 -
trunk/Source/WebCore/svg/graphics/SVGImage.h
r249364 r259830 69 69 NativeImagePtr nativeImage(const GraphicsContext* = nullptr) final; 70 70 #endif 71 72 Page* internalPage() { return m_page.get(); } 71 73 72 74 private: -
trunk/Source/WebCore/svg/graphics/SVGImageClients.h
r216901 r259830 63 63 imageObserver->imageFrameAvailable(*m_image, m_image->isAnimating() ? ImageAnimatingState::Yes : ImageAnimatingState::No, &r); 64 64 } 65 65 66 bool scheduleTimedRenderingUpdate() final 67 { 68 if (m_image && m_image->imageObserver()) 69 m_image->imageObserver()->scheduleTimedRenderingUpdate(*m_image); 70 return true; 71 } 72 66 73 SVGImage* m_image; 67 74 };
Note:
See TracChangeset
for help on using the changeset viewer.