Changeset 99539 in webkit
- Timestamp:
- Nov 8, 2011 1:32:52 AM (12 years ago)
- Location:
- trunk
- Files:
-
- 8 added
- 28 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r99538 r99539 1 2011-11-08 Nikolas Zimmermann <nzimmermann@rim.com> 2 3 Switch SVGImage cache to store ImageBuffers instead of whole SVGImages, including a DOM/Render tree 4 https://bugs.webkit.org/show_bug.cgi?id=71368 5 6 Reviewed by Antti Koivisto. 7 8 Add some layout tests covering repainting of embedded SVG documents triggered by SMIL animations. 9 10 * platform/chromium/test_expectations.txt: Fix test expectations, as described in bug 71226. 11 * platform/mac/svg/as-image/animated-svg-as-image-no-fixed-intrinsic-size-expected.png: Added. 12 * platform/mac/svg/as-image/animated-svg-as-image-no-fixed-intrinsic-size-expected.txt: Added. 13 * platform/mac/svg/as-image/animated-svg-as-image-same-image-expected.png: Added. 14 * platform/mac/svg/as-image/animated-svg-as-image-same-image-expected.txt: Added. 15 * svg/as-image/animated-svg-as-image-no-fixed-intrinsic-size.html: Added. 16 * svg/as-image/animated-svg-as-image-same-image.html: Added. 17 * svg/as-image/resources/animated-rect-same-image.svg: Copied from LayoutTests/svg/as-image/resources/animated-rect-fixed-size.svg. 18 * svg/zoom/page/zoom-coords-viewattr-01-b.svg: Add comment, why scrollbars shouldn't appear anymore here. 19 1 20 2011-11-08 Philippe Normand <pnormand@igalia.com> 2 21 -
trunk/LayoutTests/platform/chromium/test_expectations.txt
r99529 r99539 1487 1487 BUGCR23471 LEOPARD : fast/text/stroking.html = IMAGE 1488 1488 1489 // Failing on the bots but not locally; need investigation1490 BUGCR23560 MAC : svg/as-image/animated-svg-as-image.html = PASS IMAGE1491 1492 1489 // ----------------------------------------------------------------- 1493 1490 // END MAC PORT TESTS … … 3850 3847 BUGWK71215 SNOWLEOPARD DEBUG : animations/change-keyframes.html = TEXT 3851 3848 3852 BUGWK71226 : svg/as-background-image/animated-svg-as-background.html = IMAGE 3853 BUGWK71226 : svg/zoom/page/zoom-coords-viewattr-01-b.svg = IMAGE+TEXT 3854 BUGWK71226 MAC : svg/zoom/page/zoom-img-preserveAspectRatio-support-1.html = IMAGE+TEXT 3855 BUGWK71226 WIN LINUX : svg/zoom/page/zoom-img-preserveAspectRatio-support-1.html = PASS IMAGE+TEXT 3856 BUGWK71226 : fast/backgrounds/size/contain-and-cover-zoomed.html = IMAGE+TEXT 3857 BUGWK71226 : fast/backgrounds/animated-svg-as-mask.html = IMAGE+TEXT IMAGE 3849 BUGWK71673 MAC : svg/zoom/page/zoom-img-preserveAspectRatio-support-1.html = IMAGE+TEXT 3850 BUGWK71673 WIN LINUX : svg/zoom/page/zoom-img-preserveAspectRatio-support-1.html = PASS IMAGE+TEXT 3858 3851 3859 3852 BUGWK71278 SLOW WIN RELEASE : fast/events/dispatch-message-string-data.html = PASS -
trunk/LayoutTests/svg/zoom/page/zoom-coords-viewattr-01-b.svg
r54844 r99539 123 123 124 124 <defs> 125 <!-- Note that the zooming won't have any visible effect except for stroke size changes, as width/height is 100% --> 125 126 <script>var zoomCount = 2;</script> 126 127 <script xlink:href="../resources/testPageZoom.js"/> -
trunk/Source/WebCore/CMakeLists.txt
r99523 r99539 1807 1807 svg/animation/SVGSMILElement.cpp 1808 1808 svg/graphics/SVGImage.cpp 1809 svg/graphics/SVGImageCache.cpp 1809 1810 svg/graphics/filters/SVGFEImage.cpp 1810 1811 svg/graphics/filters/SVGFilter.cpp -
trunk/Source/WebCore/ChangeLog
r99533 r99539 1 2011-11-08 Nikolas Zimmermann <nzimmermann@rim.com> 2 3 Switch SVGImage cache to store ImageBuffers instead of whole SVGImages, including a DOM/Render tree 4 https://bugs.webkit.org/show_bug.cgi?id=71368 5 6 Reviewed by Antti Koivisto. 7 8 Fix regressions/races introduced by r98852. SVGImage repainting didn't work under certain circumstances. 9 The problem was hard to reproduce on Mac ports, but easily visible on Chromium, when opening two files 10 that shared the same animated SVG image. The problem of sharing a single ImageObserver across multiple 11 instances of the same SVGImage, leads to nasty problems, that are timing dependant. changedInRect() calls 12 that should only by received in one document, are received in the other as well, due the shared nature 13 of CachedImage. To avoid these problems alltogether, a new approach is needed, that was initially suggested 14 by Antti. 15 16 Avoid creating multiple SVGImages and caching them for different sizes/zoom levels. Introduce SVGImageCache 17 which holds rendered versions of the SVGImage at certain sizes/zoom levels. It holds (ImageBuffer, Image) pairs 18 for each renderer, associated with a size and zoom level. 19 20 This is a major change to the cache as introduced some weeks ago. Instead of holding multiple SVGImages, each containing 21 a whole DOM/render tree, we now create bitmap images rendered at the requested sizes/zoom levels and cache them. 22 23 Revert ImageBySizeCache changes that were needed to make it usable wih SVGImage. Its now used only in CSSImageGeneratorValue and 24 thus the extra information that CSSImageGeneratorValue doesn't need can be removed again (desired/actual size differentations, and the zoom level). 25 26 Tests: svg/as-image/animated-svg-as-image-no-fixed-intrinsic-size.html 27 svg/as-image/animated-svg-as-image-same-image.html 28 29 * CMakeLists.txt: Add svg/graphics/SVGImageCache.* to build. 30 * GNUmakefile.list.am: Ditto. 31 * Target.pri: Ditto. 32 * WebCore.gypi: Ditto. 33 * WebCore.vcproj/WebCore.vcproj: Ditto. 34 * WebCore.vcproj/copyForwardingHeaders.cmd: Copy headers from svg/graphics, as SVGImageCache is needed by CachedImage in SVG enabled builds. 35 * WebCore.xcodeproj/project.pbxproj: Add svg/graphics/SVGImageCache.* to build. 36 * css/CSSImageGeneratorValue.cpp: Remove zoom parameter from addClient/getImage, no need to pass 1 default values anymore. 37 (WebCore::CSSImageGeneratorValue::addClient): 38 (WebCore::CSSImageGeneratorValue::getImage): 39 * loader/cache/CachedImage.cpp: Stop using ImageBySizeCache, and switch to the new SVGImageCache. 40 (WebCore::CachedImage::removeClientForRenderer): 41 (WebCore::CachedImage::lookupOrCreateImageForRenderer): 42 (WebCore::CachedImage::setContainerSizeForRenderer): 43 (WebCore::CachedImage::imageSizeForRenderer): 44 (WebCore::CachedImage::clear): 45 (WebCore::CachedImage::createImage): 46 (WebCore::CachedImage::destroyDecodedData): 47 (WebCore::CachedImage::decodedSizeChanged): 48 (WebCore::CachedImage::didDraw): 49 (WebCore::CachedImage::shouldPauseAnimation): 50 (WebCore::CachedImage::animationAdvanced): 51 (WebCore::CachedImage::changedInRect): 52 * loader/cache/CachedImage.h: 53 * page/DragController.cpp: Stop using imageForRenderer(), as it may return cached BitmapImages, that don't carry a filename extension anymore, which is required here. 54 (WebCore::getImage): 55 * rendering/ImageBySizeCache.cpp: Revert changes to ImageBySizeCache, which were needed to make it usable for SVGImages. CSSImageGenerator doesn't need it. 56 (WebCore::ImageBySizeCache::addClient): 57 (WebCore::ImageBySizeCache::removeClient): 58 (WebCore::ImageBySizeCache::getImage): 59 * rendering/ImageBySizeCache.h: Ditto. 60 (WebCore::SizeAndCount::SizeAndCount): 61 * rendering/RenderImage.cpp: Stop using imageForRenderer(), use cachedImage()->image(), which is guaranteed to be a SVGImage for svg images, and not a cached bitmap copy. 62 (WebCore::RenderImage::embeddedContentBox): 63 * rendering/RenderReplaced.cpp: Simplify logic to figure out the intrinsic size - the special logic for the old SVGImage cache can go away now. 64 (WebCore::RenderReplaced::computeIntrinsicLogicalWidth): 65 (WebCore::RenderReplaced::computeIntrinsicLogicalHeight): 66 * rendering/style/StyleCachedImage.cpp: Call removeClientForRenderer(), which takes care of clearing SVGImageCache entries as well. 67 (WebCore::StyleCachedImage::removeClient): This change is needed, as we don't want to make removeClient() virtual in CachedResource. 68 * rendering/svg/RenderSVGRoot.cpp: Rename isEmbeddedThroughImageElement to isEmbeddedThroughSVGImage, as this is what it actually checks. 69 (WebCore::RenderSVGRoot::isEmbeddedThroughSVGImage): 70 * rendering/svg/RenderSVGRoot.h: 71 * svg/SVGSVGElement.cpp: Fix bug that's visible now with the SVGImageCache, which was already there before, but hard to trigger. 72 (WebCore::SVGSVGElement::currentViewBoxRect): The viewBox depends on who's asking for it: the host document or the embedded document? Take that into account. 73 * svg/SVGSVGElement.h: 74 * svg/graphics/SVGImage.cpp: Cleanup some code. Add new logic that draws a SVGImage into an ImageBuffer at a desired size & zoom. 75 (WebCore::SVGImage::setContainerSize): 76 (WebCore::SVGImage::size): 77 (WebCore::SVGImage::drawSVGToImageBuffer): 78 * svg/graphics/SVGImage.h: 79 * svg/graphics/SVGImageCache.cpp: Added. SVGImageCache caches Image/ImageBuffer pairs for each _renderer_ and size/zoom level. The ImageBySizeCache only cared about size. 80 (WebCore::SVGImageCache::SVGImageCache): 81 (WebCore::SVGImageCache::~SVGImageCache): 82 (WebCore::SVGImageCache::removeRendererFromCache): 83 (WebCore::SVGImageCache::setRequestedSizeAndZoom): 84 (WebCore::SVGImageCache::getRequestedSizeAndZoom): 85 (WebCore::SVGImageCache::imageContentChanged): 86 (WebCore::SVGImageCache::redrawTimerFired): 87 (WebCore::SVGImageCache::lookupOrCreateBitmapImageForRenderer): 88 * svg/graphics/SVGImageCache.h: Added. 89 (WebCore::SVGImageCache::create): 90 (WebCore::SVGImageCache::CachedSizeAndZoom::CachedSizeAndZoom): 91 (WebCore::SVGImageCache::CachedImageData::CachedImageData): 92 1 93 2011-11-07 Yury Semikhatsky <yurys@chromium.org> 2 94 -
trunk/Source/WebCore/GNUmakefile.list.am
r99468 r99539 3537 3537 Source/WebCore/svg/graphics/filters/SVGFilter.cpp \ 3538 3538 Source/WebCore/svg/graphics/filters/SVGFilter.h \ 3539 Source/WebCore/svg/graphics/SVGImageCache.cpp \ 3540 Source/WebCore/svg/graphics/SVGImageCache.h \ 3539 3541 Source/WebCore/svg/graphics/SVGImage.cpp \ 3540 3542 Source/WebCore/svg/graphics/SVGImage.h \ -
trunk/Source/WebCore/Target.pri
r99488 r99539 2484 2484 svg/graphics/filters/SVGFilter.h \ 2485 2485 svg/graphics/SVGImage.h \ 2486 svg/graphics/SVGImageCache.h \ 2486 2487 svg/properties/SVGAttributeToPropertyMap.h \ 2487 2488 svg/properties/SVGAnimatedEnumerationPropertyTearOff.h \ … … 3317 3318 svg/graphics/filters/SVGFilterBuilder.cpp \ 3318 3319 svg/graphics/SVGImage.cpp \ 3320 svg/graphics/SVGImageCache.cpp \ 3319 3321 svg/properties/SVGAttributeToPropertyMap.cpp \ 3320 3322 svg/properties/SVGPathSegListPropertyTearOff.cpp -
trunk/Source/WebCore/WebCore.gypi
r99488 r99539 6207 6207 'svg/animation/SMILTimeContainer.h', 6208 6208 'svg/animation/SVGSMILElement.cpp', 6209 'svg/graphics/SVGImageCache.cpp', 6210 'svg/graphics/SVGImageCache.h', 6209 6211 'svg/graphics/SVGImage.cpp', 6210 6212 'svg/graphics/SVGImage.h', -
trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj
r99468 r99539 67102 67102 > 67103 67103 <File 67104 RelativePath="..\svg\graphics\SVGImageCache.cpp" 67105 > 67106 </File> 67107 <File 67108 RelativePath="..\svg\graphics\SVGImageCache.h" 67109 > 67110 </File> 67111 <File 67104 67112 RelativePath="..\svg\graphics\SVGImage.cpp" 67105 67113 > -
trunk/Source/WebCore/WebCore.vcproj/copyForwardingHeaders.cmd
r94452 r99539 71 71 xcopy /y /d "%ProjectDir%..\xml\*.h" "%CONFIGURATIONBUILDDIR%\include\WebCore" 72 72 xcopy /y /d "%ProjectDir%..\svg\animation\*.h" "%CONFIGURATIONBUILDDIR%\include\WebCore" 73 xcopy /y /d "%ProjectDir%..\svg\graphics\*.h" "%CONFIGURATIONBUILDDIR%\include\WebCore" 73 74 xcopy /y /d "%ProjectDir%..\svg\properties\*.h" "%CONFIGURATIONBUILDDIR%\include\WebCore" 74 75 xcopy /y /d "%ProjectDir%..\svg\*.h" "%CONFIGURATIONBUILDDIR%\include\WebCore" -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r99490 r99539 195 195 08F2F0091213E61700DCEC48 /* RenderImageResource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08F2F0071213E61700DCEC48 /* RenderImageResource.cpp */; }; 196 196 08F2F00A1213E61700DCEC48 /* RenderImageResource.h in Headers */ = {isa = PBXBuildFile; fileRef = 08F2F0081213E61700DCEC48 /* RenderImageResource.h */; settings = {ATTRIBUTES = (Private, ); }; }; 197 08F859D41463F9CD0067D933 /* SVGImageCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08F859D21463F9CD0067D933 /* SVGImageCache.cpp */; }; 198 08F859D51463F9CD0067D933 /* SVGImageCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 08F859D31463F9CD0067D933 /* SVGImageCache.h */; settings = {ATTRIBUTES = (Private, ); }; }; 197 199 08FB17C113BC7E9100040086 /* SVGAttributeToPropertyMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08FB17C013BC7E9100040086 /* SVGAttributeToPropertyMap.cpp */; }; 198 200 08FB3F8413BC754C0099FC18 /* SVGAttributeToPropertyMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 08FB3F8313BC754C0099FC18 /* SVGAttributeToPropertyMap.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 7225 7227 08F2F0071213E61700DCEC48 /* RenderImageResource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderImageResource.cpp; sourceTree = "<group>"; }; 7226 7228 08F2F0081213E61700DCEC48 /* RenderImageResource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderImageResource.h; sourceTree = "<group>"; }; 7229 08F859D21463F9CD0067D933 /* SVGImageCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGImageCache.cpp; sourceTree = "<group>"; }; 7230 08F859D31463F9CD0067D933 /* SVGImageCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGImageCache.h; sourceTree = "<group>"; }; 7227 7231 08FB17C013BC7E9100040086 /* SVGAttributeToPropertyMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGAttributeToPropertyMap.cpp; sourceTree = "<group>"; }; 7228 7232 08FB3F8313BC754C0099FC18 /* SVGAttributeToPropertyMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGAttributeToPropertyMap.h; sourceTree = "<group>"; }; … … 19005 19009 B255990B0D00D8B900BB825C /* SVGImage.cpp */, 19006 19010 B255990C0D00D8B900BB825C /* SVGImage.h */, 19011 08F859D21463F9CD0067D933 /* SVGImageCache.cpp */, 19012 08F859D31463F9CD0067D933 /* SVGImageCache.h */, 19007 19013 ); 19008 19014 path = graphics; … … 24625 24631 07846385145B1B8E00A58DF1 /* JSTrackCustom.h in Headers */, 24626 24632 2D8FEBDD143E3EF70072502B /* CSSCrossfadeValue.h in Headers */, 24633 08F859D51463F9CD0067D933 /* SVGImageCache.h in Headers */, 24627 24634 3169379C14609C6C00C01362 /* DragSession.h in Headers */, 24628 24635 CAE9F910146441F000C245B0 /* CSSAspectRatioValue.h in Headers */, … … 27481 27488 07689D6E145B52CC001CD132 /* JSTrackEventCustom.cpp in Sources */, 27482 27489 2D8FEBDC143E3EF70072502B /* CSSCrossfadeValue.cpp in Sources */, 27490 08F859D41463F9CD0067D933 /* SVGImageCache.cpp in Sources */, 27483 27491 CAE9F90F146441F000C245B0 /* CSSAspectRatioValue.cpp in Sources */, 27484 27492 CDEA763014608A53008B31F1 /* PlatformClockCA.cpp in Sources */, -
trunk/Source/WebCore/css/CSSImageGeneratorValue.cpp
r99468 r99539 49 49 { 50 50 ref(); 51 m_imageCache.addClient(renderer, size , 1);51 m_imageCache.addClient(renderer, size); 52 52 } 53 53 … … 62 62 // If renderer is the only client, make sure we don't delete this, if the size changes (as this will result in addClient/removeClient calls). 63 63 RefPtr<CSSImageGeneratorValue> protect(this); 64 return m_imageCache.getImage(renderer, size , 1);64 return m_imageCache.getImage(renderer, size); 65 65 } 66 66 -
trunk/Source/WebCore/loader/cache/CachedImage.cpp
r98852 r99539 91 91 } 92 92 93 void CachedImage::removeClientForRenderer(RenderObject* renderer) 94 { 95 #if ENABLE(SVG) 96 if (m_svgImageCache) 97 m_svgImageCache->removeRendererFromCache(renderer); 98 #endif 99 removeClient(renderer); 100 } 101 93 102 void CachedImage::didAddClient(CachedResourceClient* c) 94 103 { … … 133 142 134 143 #if ENABLE(SVG) 135 inline Image* CachedImage::lookup ImageForSize(const IntSize& size) const144 inline Image* CachedImage::lookupOrCreateImageForRenderer(const RenderObject* renderer) 136 145 { 137 146 if (!m_image) … … 139 148 if (!m_image->isSVGImage()) 140 149 return m_image.get(); 141 if (Image* image = m_svgImageCache.imageForSize(size)) 142 return image; 143 return m_image.get(); 144 } 145 146 inline Image* CachedImage::lookupOrCreateImageForRenderer(const RenderObject* renderer) 147 { 148 if (!m_image) 149 return 0; 150 if (!m_image->isSVGImage()) 150 Image* useImage = m_svgImageCache->lookupOrCreateBitmapImageForRenderer(renderer); 151 if (useImage == Image::nullImage()) 151 152 return m_image.get(); 152 153 // Request requested size/zoom for this renderer from the cache. 154 IntSize size; 155 float zoom = 1; 156 m_svgImageCache.getRequestedSizeAndZoom(renderer, size, zoom); 157 if (size.isEmpty()) 158 return m_image.get(); 159 160 if (Image* image = m_svgImageCache.getImage(renderer, size, zoom)) 161 return image; 162 163 // Create and cache new image at requested size. 164 RefPtr<Image> newImage = SVGImage::createWithDataAndSize(this, m_data.get(), size, zoom); 165 Image* newImagePtr = newImage.get(); 166 m_svgImageCache.addClient(renderer, size, zoom); 167 m_svgImageCache.putImage(size, newImage.release()); 168 return newImagePtr; 169 } 170 153 return useImage; 154 } 171 155 #else 172 inline Image* CachedImage::lookupImageForSize(const IntSize&) const173 {174 return m_image.get();175 }176 177 156 inline Image* CachedImage::lookupOrCreateImageForRenderer(const RenderObject*) 178 157 { … … 224 203 return; 225 204 } 226 m_svgImageCache .addClient(renderer, containerSize, containerZoom);205 m_svgImageCache->setRequestedSizeAndZoom(renderer, SVGImageCache::SizeAndZoom(containerSize, containerZoom)); 227 206 #else 228 207 UNUSED_PARAM(renderer); … … 264 243 if (m_image->isSVGImage()) { 265 244 // SVGImages already includes the zooming in its intrinsic size. 266 IntSize size; 267 float zoom = 1; 268 m_svgImageCache.getRequestedSizeAndZoom(renderer, size, zoom); 269 if (!size.isEmpty()) 270 return size; 271 return m_image->size(); 245 SVGImageCache::SizeAndZoom sizeAndZoom = m_svgImageCache->requestedSizeAndZoom(renderer); 246 if (sizeAndZoom.size.isEmpty()) 247 return m_image->size(); 248 if (sizeAndZoom.zoom == 1) 249 return sizeAndZoom.size; 250 if (multiplier == 1) { 251 // Consumer wants unscaled coordinates. 252 sizeAndZoom.size.setWidth(sizeAndZoom.size.width() / sizeAndZoom.zoom); 253 sizeAndZoom.size.setHeight(sizeAndZoom.size.height() / sizeAndZoom.zoom); 254 return sizeAndZoom.size; 255 } 256 return sizeAndZoom.size; 272 257 } 273 258 #endif … … 313 298 { 314 299 destroyDecodedData(); 300 #if ENABLE(SVG) 315 301 m_svgImageCache.clear(); 302 #endif 316 303 m_image = 0; 317 304 setEncodedSize(0); … … 331 318 #if ENABLE(SVG) 332 319 if (m_response.mimeType() == "image/svg+xml") { 333 m_image = SVGImage::create(this); 320 RefPtr<SVGImage> svgImage = SVGImage::create(this); 321 m_svgImageCache = SVGImageCache::create(svgImage.get()); 322 m_image = svgImage.release(); 334 323 return; 335 324 } … … 411 400 if (!MemoryCache::shouldMakeResourcePurgeableOnEviction()) 412 401 makePurgeable(true); 413 } else if (m_image && !errorOccurred() && !m_image->isSVGImage())402 } else if (m_image && !errorOccurred()) 414 403 m_image->destroyDecodedData(); 415 404 } … … 417 406 void CachedImage::decodedSizeChanged(const Image* image, int delta) 418 407 { 419 if (!image) 420 return; 421 Image* useImage = lookupImageForSize(image->size()); 422 if (image != useImage) 408 if (!image || image != m_image) 423 409 return; 424 410 … … 428 414 void CachedImage::didDraw(const Image* image) 429 415 { 430 if (!image) 431 return; 432 Image* useImage = lookupImageForSize(image->size()); 433 if (image != useImage) 416 if (!image || image != m_image) 434 417 return; 435 418 … … 443 426 bool CachedImage::shouldPauseAnimation(const Image* image) 444 427 { 445 if (!image) 446 return false; 447 Image* useImage = lookupImageForSize(image->size()); 448 if (image != useImage) 428 if (!image || image != m_image) 449 429 return false; 450 430 … … 460 440 void CachedImage::animationAdvanced(const Image* image) 461 441 { 462 if (!image) 463 return; 464 Image* useImage = lookupImageForSize(image->size()); 465 if (image != useImage) 442 if (!image || image != m_image) 466 443 return; 467 444 notifyObservers(); … … 470 447 void CachedImage::changedInRect(const Image* image, const IntRect& rect) 471 448 { 472 if (!image) 473 return; 474 Image* useImage = lookupImageForSize(image->size()); 475 if (image != useImage) 476 return; 449 if (!image || image != m_image) 450 return; 451 #if ENABLE(SVG) 452 // We have to update the cached ImageBuffers if the underlying content changed. 453 if (image->isSVGImage()) { 454 m_svgImageCache->imageContentChanged(); 455 return; 456 } 457 #endif 477 458 notifyObservers(&rect); 478 459 } 479 460 480 } // namespace WebCore461 } // namespace WebCore -
trunk/Source/WebCore/loader/cache/CachedImage.h
r98852 r99539 26 26 #include "CachedResource.h" 27 27 #include "CachedResourceClient.h" 28 #include " ImageBySizeCache.h"28 #include "SVGImageCache.h" 29 29 #include "ImageObserver.h" 30 30 #include "IntRect.h" … … 68 68 void computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio); 69 69 70 void removeClientForRenderer(RenderObject*); 70 71 virtual void didAddClient(CachedResourceClient*); 71 72 … … 95 96 96 97 private: 97 Image* lookupImageForSize(const IntSize&) const;98 98 Image* lookupOrCreateImageForRenderer(const RenderObject*); 99 99 … … 107 107 108 108 RefPtr<Image> m_image; 109 mutable ImageBySizeCache m_svgImageCache; 109 #if ENABLE(SVG) 110 OwnPtr<SVGImageCache> m_svgImageCache; 111 #endif 110 112 Timer<CachedImage> m_decodedDataDeletionTimer; 111 113 bool m_shouldPaintBrokenImage; -
trunk/Source/WebCore/page/DragController.cpp
r99369 r99539 654 654 ASSERT(element); 655 655 CachedImage* cachedImage = getCachedImage(element); 656 // Don't use cachedImage->imageForRenderer() here as that may return BitmapImages for cached SVG Images. 657 // Users of getImage() want access to the SVGImage, in order to figure out the filename extensions, 658 // which would be empty when asking the cached BitmapImages. 656 659 return (cachedImage && !cachedImage->errorOccurred()) ? 657 cachedImage->image ForRenderer(element->renderer()) : 0;660 cachedImage->image() : 0; 658 661 } 659 662 -
trunk/Source/WebCore/rendering/ImageBySizeCache.cpp
r98852 r99539 24 24 #include "Image.h" 25 25 #include "IntSize.h" 26 #include "IntSizeHash.h"27 26 #include "RenderObject.h" 28 27 … … 33 32 } 34 33 35 void ImageBySizeCache::addClient(const RenderObject* renderer, const IntSize& size , float zoom)34 void ImageBySizeCache::addClient(const RenderObject* renderer, const IntSize& size) 36 35 { 37 36 ASSERT(renderer); … … 41 40 RenderObjectSizeCountMap::iterator it = m_clients.find(renderer); 42 41 if (it == m_clients.end()) 43 m_clients.add(renderer, Size ZoomAndCount(size, zoom, 1));42 m_clients.add(renderer, SizeAndCount(size, 1)); 44 43 else { 45 SizeZoomAndCount& sizeCount = it->second; 46 sizeCount.requestedSize = size; 47 sizeCount.requestedZoom = zoom; 44 SizeAndCount& sizeCount = it->second; 48 45 ++sizeCount.count; 49 46 } … … 56 53 ASSERT(it != m_clients.end()); 57 54 58 SizeZoomAndCount& sizeCount = it->second; 59 IntSize size = sizeCount.actualSize; 55 IntSize removedImageSize; 56 SizeAndCount& sizeCount = it->second; 57 IntSize size = sizeCount.size; 60 58 if (!size.isEmpty()) { 61 59 m_sizes.remove(size); … … 68 66 } 69 67 70 Image* ImageBySizeCache::getImage(const RenderObject* renderer, const IntSize& size , float zoom)68 Image* ImageBySizeCache::getImage(const RenderObject* renderer, const IntSize& size) 71 69 { 72 70 RenderObjectSizeCountMap::iterator it = m_clients.find(renderer); 73 71 if (it != m_clients.end()) { 74 Size ZoomAndCount& sizeCount = it->second;75 IntSize oldSize = sizeCount. actualSize;72 SizeAndCount& sizeCount = it->second; 73 IntSize oldSize = sizeCount.size; 76 74 if (oldSize != size) { 77 75 removeClient(renderer); 78 addClient(renderer, size , zoom);76 addClient(renderer, size); 79 77 } 80 78 } … … 88 86 } 89 87 90 void ImageBySizeCache::getRequestedSizeAndZoom(const RenderObject* renderer, IntSize& size, float& zoom)91 {92 RenderObjectSizeCountMap::iterator it = m_clients.find(renderer);93 if (it == m_clients.end())94 return;95 SizeZoomAndCount& sizeCount = it->second;96 size = sizeCount.requestedSize;97 zoom = sizeCount.requestedZoom;98 }99 100 88 void ImageBySizeCache::putImage(const IntSize& size, PassRefPtr<Image> image) 101 89 { … … 103 91 } 104 92 105 void ImageBySizeCache::clear()106 {107 m_sizes.clear();108 m_clients.clear();109 m_images.clear();110 }111 112 Image* ImageBySizeCache::imageForSize(const IntSize& size) const113 {114 if (size.isEmpty())115 return 0;116 HashMap<IntSize, RefPtr<Image> >::const_iterator it = m_images.find(size);117 if (it == m_images.end())118 return 0;119 return it->second.get();120 }121 122 Image* ImageBySizeCache::imageForRenderer(const RenderObject* renderer) const123 {124 if (!renderer)125 return 0;126 RenderObjectSizeCountMap::const_iterator it = m_clients.find(renderer);127 if (it == m_clients.end())128 return 0;129 return imageForSize(it->second.actualSize);130 }131 132 93 } // namespace WebCore -
trunk/Source/WebCore/rendering/ImageBySizeCache.h
r98852 r99539 32 32 class RenderObject; 33 33 34 struct SizeZoomAndCount { 35 SizeZoomAndCount(IntSize newSize = IntSize(), float newZoom = 0, int newCount = 0) 36 : actualSize(newSize) 37 , requestedSize(newSize) 38 , actualZoom(newZoom) 39 , requestedZoom(newZoom) 34 struct SizeAndCount { 35 SizeAndCount(IntSize newSize = IntSize(), int newCount = 0) 36 : size(newSize) 40 37 , count(newCount) 41 38 { 42 39 } 43 40 44 IntSize actualSize; 45 IntSize requestedSize; 46 float actualZoom; 47 float requestedZoom; 41 IntSize size; 48 42 int count; 49 43 }; 50 44 51 typedef HashMap<const RenderObject*, Size ZoomAndCount> RenderObjectSizeCountMap;45 typedef HashMap<const RenderObject*, SizeAndCount> RenderObjectSizeCountMap; 52 46 53 47 class ImageBySizeCache { … … 55 49 ImageBySizeCache(); 56 50 57 void addClient(const RenderObject*, const IntSize& , float zoom);51 void addClient(const RenderObject*, const IntSize&); 58 52 void removeClient(const RenderObject*); 59 53 60 Image* getImage(const RenderObject*, const IntSize&, float zoom); 61 void getRequestedSizeAndZoom(const RenderObject*, IntSize&, float& zoom); 62 54 Image* getImage(const RenderObject*, const IntSize&); 63 55 void putImage(const IntSize&, PassRefPtr<Image>); 64 56 65 void clear();66 67 Image* imageForSize(const IntSize&) const;68 Image* imageForRenderer(const RenderObject*) const;69 57 const RenderObjectSizeCountMap& clients() const { return m_clients; } 70 58 -
trunk/Source/WebCore/rendering/RenderImage.cpp
r99303 r99539 546 546 547 547 #if ENABLE(SVG) 548 RefPtr<Image> image = m_imageResource->image();549 if ( image && image->isSVGImage())550 return static_ pointer_cast<SVGImage>(image)->embeddedContentBox();548 CachedImage* cachedImage = m_imageResource->cachedImage(); 549 if (cachedImage && cachedImage->image() && cachedImage->image()->isSVGImage()) 550 return static_cast<SVGImage*>(cachedImage->image())->embeddedContentBox(); 551 551 #endif 552 552 -
trunk/Source/WebCore/rendering/RenderReplaced.cpp
r98852 r99539 201 201 int RenderReplaced::computeIntrinsicLogicalWidth(RenderBox* contentRenderer, bool includeMaxWidth) const 202 202 { 203 if (m_hasIntrinsicSize) { 204 if (!contentRenderer || !contentRenderer->style()->logicalWidth().isFixed()) 205 return computeReplacedLogicalWidthRespectingMinMaxWidth(calcAspectRatioLogicalWidth(), includeMaxWidth); 206 } 203 if (m_hasIntrinsicSize) 204 return computeReplacedLogicalWidthRespectingMinMaxWidth(calcAspectRatioLogicalWidth(), includeMaxWidth); 207 205 ASSERT(contentRenderer); 208 206 ASSERT(contentRenderer->style()); … … 212 210 int RenderReplaced::computeIntrinsicLogicalHeight(RenderBox* contentRenderer) const 213 211 { 214 if (m_hasIntrinsicSize) { 215 if (!contentRenderer || !contentRenderer->style()->logicalHeight().isFixed()) 216 return computeReplacedLogicalHeightRespectingMinMaxHeight(calcAspectRatioLogicalHeight()); 217 } 212 if (m_hasIntrinsicSize) 213 return computeReplacedLogicalHeightRespectingMinMaxHeight(calcAspectRatioLogicalHeight()); 218 214 ASSERT(contentRenderer); 219 215 ASSERT(contentRenderer->style()); -
trunk/Source/WebCore/rendering/style/StyleCachedImage.cpp
r98852 r99539 87 87 void StyleCachedImage::removeClient(RenderObject* renderer) 88 88 { 89 m_image->removeClient (renderer);89 m_image->removeClientForRenderer(renderer); 90 90 } 91 91 -
trunk/Source/WebCore/rendering/svg/RenderSVGRoot.cpp
r98852 r99539 118 118 } 119 119 120 bool RenderSVGRoot::isEmbeddedThrough ImageElement() const120 bool RenderSVGRoot::isEmbeddedThroughSVGImage() const 121 121 { 122 122 if (!node()) -
trunk/Source/WebCore/rendering/svg/RenderSVGRoot.h
r98852 r99539 40 40 virtual ~RenderSVGRoot(); 41 41 42 bool isEmbeddedThrough ImageElement() const;42 bool isEmbeddedThroughSVGImage() const; 43 43 44 44 virtual void computeIntrinsicRatioInformation(FloatSize& intrinsicRatio, bool& isPercentageIntrinsicSize) const; -
trunk/Source/WebCore/svg/SVGSVGElement.cpp
r98852 r99539 552 552 } 553 553 554 FloatRect SVGSVGElement::currentViewBoxRect() const 555 { 554 FloatRect SVGSVGElement::currentViewBoxRect(CalculateViewBoxMode mode) const 555 { 556 // FIXME: The interaction of 'currentView' and embedding SVGs in other documents, is untested and unspecified. 556 557 if (useCurrentView()) { 557 558 if (SVGViewSpec* view = currentView()) // what if we should use it but it is not set? … … 560 561 } 561 562 562 // Synthesize a viewBox if we're embedded through a <img> element, if none is present. 563 bool isEmbeddedThroughSVGImage = renderer() && renderer()->isSVGRoot() ? toRenderSVGRoot(renderer())->isEmbeddedThroughSVGImage() : false; 564 bool hasFixedSize = width().unitType() != LengthTypePercentage && height().unitType() != LengthTypePercentage; 565 563 566 FloatRect useViewBox = viewBox(); 564 if (useViewBox.isEmpty() && width().unitType() != LengthTypePercentage && height().unitType() != LengthTypePercentage) { 565 if (RenderObject* renderer = this->renderer()) { 566 if (renderer->isSVGRoot() && toRenderSVGRoot(renderer)->isEmbeddedThroughImageElement()) 567 useViewBox = FloatRect(0, 0, width().value(this), height().value(this)); 568 } 569 } 567 if (useViewBox.isEmpty()) { 568 // If no viewBox is specified but non-relative width/height values, then we 569 // should always synthesize a viewBox if we're embedded through a SVGImage. 570 if (hasFixedSize && isEmbeddedThroughSVGImage) 571 return FloatRect(0, 0, width().value(this), height().value(this)); 572 return FloatRect(); 573 } 574 575 // If a viewBox is specified and non-relative width/height values, then the host document only 576 // uses the width/height values to figure out the intrinsic size when embedding us, whereas the 577 // embedded document sees specified viewBox only. 578 if (hasFixedSize && mode == CalculateViewBoxInHostDocument) 579 return FloatRect(0, 0, width().value(this), height().value(this)); 570 580 571 581 return useViewBox; -
trunk/Source/WebCore/svg/SVGSVGElement.h
r98852 r99539 73 73 74 74 SVGViewSpec* currentView() const; 75 FloatRect currentViewBoxRect() const;76 75 76 enum CalculateViewBoxMode { 77 CalculateViewBoxInHostDocument, 78 CalculateViewBoxInCurrentDocument 79 }; 80 81 FloatRect currentViewBoxRect(CalculateViewBoxMode = CalculateViewBoxInCurrentDocument) const; 77 82 float currentScale() const; 78 83 void setCurrentScale(float scale); -
trunk/Source/WebCore/svg/graphics/SVGImage.cpp
r99303 r99539 103 103 } 104 104 105 PassRefPtr<SVGImage> SVGImage::createWithDataAndSize(ImageObserver* observer, SharedBuffer* data, const IntSize& size, float zoom) 106 { 107 ASSERT(!size.isEmpty()); 108 109 RefPtr<SVGImage> image = adoptRef(new SVGImage(0)); 110 image->setData(data, true); 111 image->setContainerSize(size); 112 image->setContainerZoom(zoom); 113 image->setImageObserver(observer); 114 return image.release(); 115 } 116 117 void SVGImage::setContainerZoom(float containerZoom) 118 { 119 if (!m_page) 120 return; 121 Frame* frame = m_page->mainFrame(); 122 frame->setPageZoomFactor(containerZoom); 123 } 124 125 void SVGImage::setContainerSize(const IntSize& containerSize) 126 { 127 ASSERT(!containerSize.isEmpty()); 128 ASSERT(!imageObserver()); 129 130 if (!m_page) 131 return; 132 Frame* frame = m_page->mainFrame(); 133 SVGSVGElement* rootElement = static_cast<SVGDocument*>(frame->document())->rootElement(); 134 if (!rootElement) 135 return; 136 137 RenderSVGRoot* renderer = toRenderSVGRoot(rootElement->renderer()); 138 if (!renderer) 139 return; 140 renderer->setContainerSize(containerSize); 141 frame->view()->resize(size()); 105 void SVGImage::setContainerSize(const IntSize&) 106 { 107 ASSERT_NOT_REACHED(); 142 108 } 143 109 … … 175 141 // Assure that a container size is always given for a non-identity zoom level. 176 142 ASSERT(renderer->style()->effectiveZoom() == 1); 177 IntSize size = enclosingIntRect(rootElement->currentViewBoxRect( )).size();143 IntSize size = enclosingIntRect(rootElement->currentViewBoxRect(SVGSVGElement::CalculateViewBoxInHostDocument)).size(); 178 144 if (!size.isEmpty()) 179 145 return size; … … 181 147 // As last resort, use CSS default intrinsic size. 182 148 return IntSize(300, 150); 149 } 150 151 void SVGImage::drawSVGToImageBuffer(ImageBuffer* buffer, const IntSize& size, float zoom, ShouldClearBuffer shouldClear) 152 { 153 // FIXME: This doesn't work correctly with animations. If an image contains animations, that say run for 2 seconds, 154 // and we currently have one <img> that displays us. If we open another document referencing the same SVGImage it 155 // will display the document at a time where animations already ran - even though it has its own ImageBuffer. 156 // We currently don't implement SVGSVGElement::setCurrentTime, and can NOT go back in time, once animations started. 157 // There's no way to fix this besides avoiding style/attribute mutations from SVGAnimationElement. 158 ASSERT(buffer); 159 ASSERT(!size.isEmpty()); 160 161 Frame* frame = m_page->mainFrame(); 162 SVGSVGElement* rootElement = static_cast<SVGDocument*>(frame->document())->rootElement(); 163 if (!rootElement) 164 return; 165 RenderSVGRoot* renderer = toRenderSVGRoot(rootElement->renderer()); 166 if (!renderer) 167 return; 168 169 // Draw image at requested size. 170 ImageObserver* observer = imageObserver(); 171 ASSERT(observer); 172 173 // Temporarily reset image observer, we don't want to receive any changeInRect() calls due this relayout. 174 setImageObserver(0); 175 renderer->setContainerSize(size); 176 frame->view()->resize(this->size()); 177 if (zoom != 1) 178 frame->setPageZoomFactor(zoom); 179 180 // Eventually clear image buffer. 181 IntRect rect(IntPoint(), size); 182 if (shouldClear == ClearImageBuffer) 183 buffer->context()->clearRect(rect); 184 185 // Draw SVG on top of ImageBuffer. 186 draw(buffer->context(), rect, rect, ColorSpaceDeviceRGB, CompositeSourceOver); 187 188 // Reset container size & zoom to initial state. Otherwhise the size() of this 189 // image would return whatever last size was set by drawSVGToImageBuffer(). 190 if (zoom != 1) 191 frame->setPageZoomFactor(1); 192 193 renderer->setContainerSize(IntSize()); 194 frame->view()->resize(this->size()); 195 if (frame->view()->needsLayout()) 196 frame->view()->layout(); 197 198 setImageObserver(observer); 183 199 } 184 200 -
trunk/Source/WebCore/svg/graphics/SVGImage.h
r98852 r99539 35 35 namespace WebCore { 36 36 37 class ImageBuffer; 37 38 class Page; 38 39 class RenderBox; … … 46 47 } 47 48 48 static PassRefPtr<SVGImage> createWithDataAndSize(ImageObserver*, SharedBuffer*, const IntSize&, float zoom); 49 enum ShouldClearBuffer { 50 ClearImageBuffer, 51 DontClearImageBuffer 52 }; 49 53 50 void setContainerZoom(float);54 void drawSVGToImageBuffer(ImageBuffer*, const IntSize&, float zoom, ShouldClearBuffer); 51 55 RenderBox* embeddedContentBox() const; 52 56 53 57 virtual bool isSVGImage() const { return true; } 58 virtual IntSize size() const; 54 59 55 60 private: … … 61 66 virtual bool usesContainerSize() const; 62 67 virtual void computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio); 63 64 virtual IntSize size() const;65 68 66 69 virtual bool dataChanged(bool allDataReceived); -
trunk/Source/WebKit/CMakeLists.txt
r95310 r99539 31 31 "${WEBCORE_DIR}/storage" 32 32 "${WEBCORE_DIR}/svg" 33 "${WEBCORE_DIR}/svg/graphics" 33 34 "${WEBCORE_DIR}/svg/properties" 34 35 "${JAVASCRIPTCORE_DIR}" -
trunk/Source/WebKit/ChangeLog
r99274 r99539 1 2011-11-08 Nikolas Zimmermann <nzimmermann@rim.com> 2 3 Switch SVGImage cache to store ImageBuffers instead of whole SVGImages, including a DOM/Render tree 4 https://bugs.webkit.org/show_bug.cgi?id=71368 5 6 Reviewed by Antti Koivisto. 7 8 * CMakeLists.txt: Add svg/graphics include, for SVGImageCache.h. 9 1 10 2011-11-04 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> 2 11
Note: See TracChangeset
for help on using the changeset viewer.