WebKit Bugzilla
Attachment 348778 Details for
Bug 189248
: Simplify RenderLayer filter code
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-189248-20180903105742.patch (text/plain), 60.66 KB, created by
Simon Fraser (smfr)
on 2018-09-03 10:57:44 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Simon Fraser (smfr)
Created:
2018-09-03 10:57:44 PDT
Size:
60.66 KB
patch
obsolete
>Subversion Revision: 235579 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 1afa94a06acd22fe194a0d5d68a3ca8ecbf9133d..a0b730fd55cdefad4f8991f30396b67ba1b98726 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,55 @@ >+2018-09-03 Simon Fraser <simon.fraser@apple.com> >+ >+ Simplify RenderLayer filter code >+ https://bugs.webkit.org/show_bug.cgi?id=189248 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Painting filters in RenderLayer involved the confusingly named RenderLayer::FilterInfo, >+ and FilterEffectRenderer/FilterEffectRendererHelper. Reduce confusion by just collapsing >+ these together into RenderLayerFilters. RenderLayerFilters stores a reference to the >+ CSSFilter, and knows how to set it up, and vend a GraphicsContext* for painting the content >+ to be filtered. >+ >+ It's also simpler to just give RenderLayer a member variable for RenderLayerFilters, rather >+ than using a side hash (we can recoup the space in other ways layer). >+ >+ * Sources.txt: >+ * WebCore.xcodeproj/project.pbxproj: >+ * css/CSSFilterImageValue.cpp: >+ * rendering/CSSFilter.h: >+ * rendering/FilterEffectRenderer.cpp: Removed. >+ * rendering/FilterEffectRenderer.h: Removed. >+ * rendering/RenderLayer.cpp: >+ (WebCore::RenderLayer::RenderLayer): >+ (WebCore::RenderLayer::~RenderLayer): >+ (WebCore::RenderLayer::paintsWithFilters const): >+ (WebCore::RenderLayer::requiresFullLayerImageForFilters const): >+ (WebCore::RenderLayer::setFilterBackendNeedsRepaintingInRect): >+ (WebCore::RenderLayer::filtersForPainting const): >+ (WebCore::RenderLayer::setupFilters): >+ (WebCore::RenderLayer::applyFilters): >+ (WebCore::RenderLayer::paintLayerContents): >+ (WebCore::RenderLayer::calculateClipRects const): >+ (WebCore::RenderLayer::filter const): Deleted. >+ (WebCore::RenderLayer::filterPainter const): Deleted. >+ (WebCore::RenderLayer::hasFilterThatIsPainting const): Deleted. >+ * rendering/RenderLayer.h: >+ * rendering/RenderLayerFilterInfo.cpp: Removed. >+ * rendering/RenderLayerFilters.cpp: Added. >+ (WebCore::RenderLayerFilters::RenderLayerFilters): >+ (WebCore::RenderLayerFilters::~RenderLayerFilters): >+ (WebCore::RenderLayerFilters::setFilter): >+ (WebCore::RenderLayerFilters::hasFilterThatMovesPixels const): >+ (WebCore::RenderLayerFilters::hasFilterThatShouldBeRestrictedBySecurityOrigin const): >+ (WebCore::RenderLayerFilters::notifyFinished): >+ (WebCore::RenderLayerFilters::updateReferenceFilterClients): >+ (WebCore::RenderLayerFilters::removeReferenceFilterClients): >+ (WebCore::RenderLayerFilters::buildFilter): >+ (WebCore::RenderLayerFilters::beginFilterEffect): >+ (WebCore::RenderLayerFilters::applyFilterEffect): >+ * rendering/RenderLayerFilters.h: Renamed from Source/WebCore/rendering/RenderLayerFilterInfo.h. >+ > 2018-09-01 Simon Fraser <simon.fraser@apple.com> > > Rename FilterEffectRenderer to CSSFilter >diff --git a/Source/WebCore/Sources.txt b/Source/WebCore/Sources.txt >index 0dcaa831e7fd763632efaa51026a4ed60f21cb07..d9d93df2d3570880f6643842c782dcef87127cc5 100644 >--- a/Source/WebCore/Sources.txt >+++ b/Source/WebCore/Sources.txt >@@ -1841,7 +1841,6 @@ rendering/CSSFilter.cpp > rendering/ClipRect.cpp > rendering/CounterNode.cpp > rendering/EllipsisBox.cpp >-rendering/FilterEffectRenderer.cpp > rendering/FlexibleBoxAlgorithm.cpp > rendering/FixedTableLayout.cpp > rendering/FloatingObjects.cpp >@@ -1896,7 +1895,7 @@ rendering/RenderInline.cpp > rendering/RenderLayer.cpp > rendering/RenderLayerBacking.cpp > rendering/RenderLayerCompositor.cpp >-rendering/RenderLayerFilterInfo.cpp >+rendering/RenderLayerFilters.cpp > rendering/RenderLayerModelObject.cpp > rendering/RenderLineBoxList.cpp > rendering/RenderLineBreak.cpp >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index 1ae6827adcc00ca0fb041436490999c054cdb613..adf48dcbf49a81b06b2838bf1bdaef40ce39d104 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -886,7 +886,6 @@ > 31288E750E3005D6003619AE /* CSSKeyframesRule.h in Headers */ = {isa = PBXBuildFile; fileRef = 31288E710E3005D6003619AE /* CSSKeyframesRule.h */; }; > 3128CA6B147331630074C72A /* NotificationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 3128CA6A147331630074C72A /* NotificationController.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 312C0C41146DC6CC0016C911 /* Notification.h in Headers */ = {isa = PBXBuildFile; fileRef = 333F704F0FB49CA2008E12A6 /* Notification.h */; settings = {ATTRIBUTES = (Private, ); }; }; >- 31313F661443B35F006E2A90 /* FilterEffectRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = 31313F641443B35E006E2A90 /* FilterEffectRenderer.h */; }; > 313171561FB079E5008D91FC /* CanvasBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 313171541FB079D1008D91FC /* CanvasBase.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 313591061E7DDC7300F30630 /* RTCIceConnectionState.h in Headers */ = {isa = PBXBuildFile; fileRef = 313591001E7DDC6000F30630 /* RTCIceConnectionState.h */; }; > 313591071E7DDC7300F30630 /* RTCIceGatheringState.h in Headers */ = {isa = PBXBuildFile; fileRef = 313591011E7DDC6000F30630 /* RTCIceGatheringState.h */; }; >@@ -1350,7 +1349,6 @@ > 504AACCE1834455900E3D9BC /* InspectorNodeFinder.h in Headers */ = {isa = PBXBuildFile; fileRef = 504AACCC1834455900E3D9BC /* InspectorNodeFinder.h */; }; > 5081E3E03CFF80C16EF8B48B /* CachedResourceRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 5081E3E13D0280C16EF8B48B /* CachedResourceRequest.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 508CCA4F13CF106B003151F3 /* RenderFragmentedFlow.h in Headers */ = {isa = PBXBuildFile; fileRef = 508CCA4D13CF106B003151F3 /* RenderFragmentedFlow.h */; }; >- 50D10D9A1545F5760096D288 /* RenderLayerFilterInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 50D10D981545F5760096D288 /* RenderLayerFilterInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 510184690B08602A004A825F /* CachedPage.h in Headers */ = {isa = PBXBuildFile; fileRef = 510184670B08602A004A825F /* CachedPage.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 510192D218B6B9AB007FC7A1 /* ImageControlsRootElementMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 510192D018B6B9AB007FC7A1 /* ImageControlsRootElementMac.h */; }; > 510192D618B6B9B7007FC7A1 /* ImageControlsRootElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 510192D418B6B9B7007FC7A1 /* ImageControlsRootElement.h */; }; >@@ -5611,6 +5609,8 @@ > 0F4966A91DB40C4300A274BB /* JSDOMPointReadOnly.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMPointReadOnly.h; sourceTree = "<group>"; }; > 0F53FB81213B1BB800C40D34 /* CSSFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSFilter.cpp; sourceTree = "<group>"; }; > 0F53FB83213B1BB800C40D34 /* CSSFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSFilter.h; sourceTree = "<group>"; }; >+ 0F53FB89213B768400C40D34 /* RenderLayerFilters.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RenderLayerFilters.h; sourceTree = "<group>"; }; >+ 0F53FB8B213B768400C40D34 /* RenderLayerFilters.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = RenderLayerFilters.cpp; sourceTree = "<group>"; }; > 0F54DCE31881051D003EEDBB /* TextAutoSizing.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextAutoSizing.cpp; sourceTree = "<group>"; }; > 0F54DCE41881051D003EEDBB /* TextAutoSizing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextAutoSizing.h; sourceTree = "<group>"; }; > 0F54DD051881D5F5003EEDBB /* Touch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Touch.h; sourceTree = "<group>"; }; >@@ -6749,8 +6749,6 @@ > 31288E710E3005D6003619AE /* CSSKeyframesRule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSKeyframesRule.h; sourceTree = "<group>"; }; > 3128CA67147331520074C72A /* NotificationController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NotificationController.cpp; sourceTree = "<group>"; }; > 3128CA6A147331630074C72A /* NotificationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NotificationController.h; sourceTree = "<group>"; }; >- 31313F631443B35E006E2A90 /* FilterEffectRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FilterEffectRenderer.cpp; sourceTree = "<group>"; }; >- 31313F641443B35E006E2A90 /* FilterEffectRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FilterEffectRenderer.h; sourceTree = "<group>"; }; > 313171541FB079D1008D91FC /* CanvasBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CanvasBase.h; sourceTree = "<group>"; }; > 313171571FB0969E008D91FC /* CanvasBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CanvasBase.cpp; sourceTree = "<group>"; }; > 313591001E7DDC6000F30630 /* RTCIceConnectionState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCIceConnectionState.h; sourceTree = "<group>"; }; >@@ -7799,8 +7797,6 @@ > 5081E3E13D0280C16EF8B48B /* CachedResourceRequest.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CachedResourceRequest.h; sourceTree = "<group>"; }; > 508CCA4D13CF106B003151F3 /* RenderFragmentedFlow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderFragmentedFlow.h; sourceTree = "<group>"; }; > 508CCA4E13CF106B003151F3 /* RenderFragmentedFlow.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderFragmentedFlow.cpp; sourceTree = "<group>"; }; >- 50D10D971545F5760096D288 /* RenderLayerFilterInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderLayerFilterInfo.cpp; sourceTree = "<group>"; }; >- 50D10D981545F5760096D288 /* RenderLayerFilterInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderLayerFilterInfo.h; sourceTree = "<group>"; }; > 510184670B08602A004A825F /* CachedPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedPage.h; sourceTree = "<group>"; }; > 510184680B08602A004A825F /* CachedPage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CachedPage.cpp; sourceTree = "<group>"; }; > 510192CF18B6B9AB007FC7A1 /* ImageControlsRootElementMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageControlsRootElementMac.cpp; sourceTree = "<group>"; }; >@@ -25743,8 +25739,6 @@ > 0F53FB83213B1BB800C40D34 /* CSSFilter.h */, > A8CFF6CA0A1561CD000A4234 /* EllipsisBox.cpp */, > A8CFF6BD0A156118000A4234 /* EllipsisBox.h */, >- 31313F631443B35E006E2A90 /* FilterEffectRenderer.cpp */, >- 31313F641443B35E006E2A90 /* FilterEffectRenderer.h */, > A8CFF0480A154F09000A4234 /* FixedTableLayout.cpp */, > A8CFF04A0A154F09000A4234 /* FixedTableLayout.h */, > 94DD79721E54E3A20058FB80 /* FlexibleBoxAlgorithm.cpp */, >@@ -25865,8 +25859,8 @@ > 0F580CFB0F12DE9B0051D689 /* RenderLayerBacking.h */, > 0F580CFA0F12DE9B0051D689 /* RenderLayerCompositor.cpp */, > 0F580CF90F12DE9B0051D689 /* RenderLayerCompositor.h */, >- 50D10D971545F5760096D288 /* RenderLayerFilterInfo.cpp */, >- 50D10D981545F5760096D288 /* RenderLayerFilterInfo.h */, >+ 0F53FB8B213B768400C40D34 /* RenderLayerFilters.cpp */, >+ 0F53FB89213B768400C40D34 /* RenderLayerFilters.h */, > 3C244FE5A375AC633F88BE6F /* RenderLayerModelObject.cpp */, > 3C244FE4A375AC633F88BE6F /* RenderLayerModelObject.h */, > BC33FB1A0F30EE85002CDD7C /* RenderLineBoxList.cpp */, >@@ -27861,7 +27855,6 @@ > 712BE4831FE865DD002031CC /* FillMode.h in Headers */, > 845E72F80FD261EE00A87D79 /* Filter.h in Headers */, > 08C9251A0FCC7C4A00480DEC /* FilterEffect.h in Headers */, >- 31313F661443B35F006E2A90 /* FilterEffectRenderer.h in Headers */, > 49ECEB6E1499790D00CDD3A4 /* FilterOperation.h in Headers */, > 49ECEB701499790D00CDD3A4 /* FilterOperations.h in Headers */, > 372C00D9129619F8005C9575 /* FindOptions.h in Headers */, >@@ -29797,7 +29790,6 @@ > BCEA487A097D93020094C9E4 /* RenderLayer.h in Headers */, > 0F580CFF0F12DE9B0051D689 /* RenderLayerBacking.h in Headers */, > 0F580CFD0F12DE9B0051D689 /* RenderLayerCompositor.h in Headers */, >- 50D10D9A1545F5760096D288 /* RenderLayerFilterInfo.h in Headers */, > 3C244FEAA375AC633F88BE6F /* RenderLayerModelObject.h in Headers */, > 0BE030A20F3112FB003C1A46 /* RenderLineBoxList.h in Headers */, > BCEA4864097D93020094C9E4 /* RenderLineBreak.h in Headers */, >diff --git a/Source/WebCore/css/CSSFilterImageValue.cpp b/Source/WebCore/css/CSSFilterImageValue.cpp >index 6f253d13b331339221e152bbfb688f4b9cd841ae..73482825b03985138e28c007c68921b280f905db 100644 >--- a/Source/WebCore/css/CSSFilterImageValue.cpp >+++ b/Source/WebCore/css/CSSFilterImageValue.cpp >@@ -30,7 +30,6 @@ > #include "CSSFilter.h" > #include "CachedImage.h" > #include "CachedResourceLoader.h" >-#include "FilterEffectRenderer.h" > #include "GraphicsContext.h" > #include "ImageBuffer.h" > #include "RenderElement.h" >diff --git a/Source/WebCore/rendering/CSSFilter.h b/Source/WebCore/rendering/CSSFilter.h >index c2a238780b103b7cb9b17800688ff098c943cc56..493729f9491b911529f2e241a4b9206e22bc67f2 100644 >--- a/Source/WebCore/rendering/CSSFilter.h >+++ b/Source/WebCore/rendering/CSSFilter.h >@@ -43,9 +43,8 @@ enum class FilterConsumer { FilterProperty, FilterFunction }; > > class CSSFilter final : public Filter { > WTF_MAKE_FAST_ALLOCATED; >+ friend class RenderLayerFilters; > public: >- friend class FilterEffectRendererHelper; >- > static Ref<CSSFilter> create(); > > void setSourceImageRect(const FloatRect&); >diff --git a/Source/WebCore/rendering/FilterEffectRenderer.cpp b/Source/WebCore/rendering/FilterEffectRenderer.cpp >deleted file mode 100644 >index d3b5d2598466889eb16005f03aad808cd25f0112..0000000000000000000000000000000000000000 >--- a/Source/WebCore/rendering/FilterEffectRenderer.cpp >+++ /dev/null >@@ -1,145 +0,0 @@ >-/* >- * Copyright (C) 2011-2017 Apple Inc. All rights reserved. >- * Copyright (C) 2013 Google Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#include "config.h" >-#include "FilterEffectRenderer.h" >- >-#include "CSSFilter.h" >-#include "CachedSVGDocument.h" >-#include "CachedSVGDocumentReference.h" >-#include "ElementIterator.h" >-#include "FEColorMatrix.h" >-#include "FEComponentTransfer.h" >-#include "FEDropShadow.h" >-#include "FEGaussianBlur.h" >-#include "FEMerge.h" >-#include "Logging.h" >-#include "RenderLayer.h" >-#include "SVGElement.h" >-#include "SVGFilterBuilder.h" >-#include "SVGFilterPrimitiveStandardAttributes.h" >-#include "SourceGraphic.h" >-#include <algorithm> >-#include <wtf/MathExtras.h> >- >-#if USE(DIRECT2D) >-#include <d2d1.h> >-#endif >- >-namespace WebCore { >- >-bool FilterEffectRendererHelper::prepareFilterEffect(RenderLayer& layer, const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect, const LayoutRect& layerRepaintRect) >-{ >- ASSERT(m_haveFilterEffect); >- ASSERT(layer.filter()); >- >- auto& filter = *layer.filter(); >- auto filterSourceRect = filter.computeSourceImageRectForDirtyRect(filterBoxRect, dirtyRect); >- >- if (filterSourceRect.isEmpty()) { >- // The dirty rect is not in view, just bail out. >- m_haveFilterEffect = false; >- return false; >- } >- >- bool hasUpdatedBackingStore = filter.updateBackingStoreRect(filterSourceRect); >- >- m_renderLayer = &layer; >- if (!filter.hasFilterThatMovesPixels()) >- m_repaintRect = dirtyRect; >- else { >- if (hasUpdatedBackingStore) >- m_repaintRect = filterSourceRect; >- else { >- m_repaintRect = dirtyRect; >- m_repaintRect.unite(layerRepaintRect); >- m_repaintRect.intersect(filterSourceRect); >- } >- } >- m_paintOffset = filterSourceRect.location(); >- >- return true; >-} >- >-GraphicsContext* FilterEffectRendererHelper::filterContext() const >-{ >- if (!m_haveFilterEffect) >- return nullptr; >- return m_renderLayer->filter()->inputContext(); >-} >- >-bool FilterEffectRendererHelper::beginFilterEffect() >-{ >- ASSERT(m_renderLayer); >- ASSERT(m_renderLayer->filter()); >- >- auto& filter = *m_renderLayer->filter(); >- filter.allocateBackingStoreIfNeeded(m_targetContext); >- // Paint into the context that represents the SourceGraphic of the filter. >- auto* sourceGraphicsContext = filter.inputContext(); >- if (!sourceGraphicsContext || filter.filterRegion().isEmpty() || ImageBuffer::sizeNeedsClamping(filter.filterRegion().size())) { >- // Disable the filters and continue. >- m_haveFilterEffect = false; >- return false; >- } >- >- // Translate the context so that the contents of the layer is captured in the offscreen memory buffer. >- sourceGraphicsContext->save(); >- sourceGraphicsContext->translate(-m_paintOffset); >- sourceGraphicsContext->clearRect(m_repaintRect); >- sourceGraphicsContext->clip(m_repaintRect); >- >- m_startedFilterEffect = true; >- return true; >-} >- >-void FilterEffectRendererHelper::applyFilterEffect(GraphicsContext& destinationContext) >-{ >- ASSERT(m_haveFilterEffect); >- ASSERT(m_renderLayer); >- ASSERT(m_renderLayer->filter()); >- ASSERT(m_renderLayer->filter()->inputContext()); >- >- LOG_WITH_STREAM(Filters, stream << "\nFilterEffectRendererHelper " << this << " applyFilterEffect"); >- >- auto& filter = *m_renderLayer->filter(); >- filter.inputContext()->restore(); >- >- filter.apply(); >- >- // Get the filtered output and draw it in place. >- LayoutRect destRect = filter.outputRect(); >- destRect.move(m_paintOffset.x(), m_paintOffset.y()); >- >- if (auto* outputBuffer = filter.output()) >- destinationContext.drawImageBuffer(*outputBuffer, snapRectToDevicePixels(destRect, m_renderLayer->renderer().document().deviceScaleFactor())); >- >- filter.clearIntermediateResults(); >- >- LOG_WITH_STREAM(Filters, stream << "FilterEffectRendererHelper " << this << " applyFilterEffect done\n"); >-} >- >-} // namespace WebCore >diff --git a/Source/WebCore/rendering/FilterEffectRenderer.h b/Source/WebCore/rendering/FilterEffectRenderer.h >deleted file mode 100644 >index 3fb1a3427f2b90bd71e3b877e3f8121925ff7d7a..0000000000000000000000000000000000000000 >--- a/Source/WebCore/rendering/FilterEffectRenderer.h >+++ /dev/null >@@ -1,65 +0,0 @@ >-/* >- * Copyright (C) 2011-2017 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#pragma once >- >-#include "LayoutRect.h" >- >-namespace WebCore { >- >-class Document; >-class GraphicsContext; >-class RenderLayer; >- >-class FilterEffectRendererHelper { >- WTF_MAKE_FAST_ALLOCATED; >-public: >- FilterEffectRendererHelper(bool haveFilterEffect, GraphicsContext& targetContext) >- : m_targetContext(targetContext) >- , m_haveFilterEffect(haveFilterEffect) >- { >- } >- >- bool haveFilterEffect() const { return m_haveFilterEffect; } >- bool hasStartedFilterEffect() const { return m_startedFilterEffect; } >- >- bool prepareFilterEffect(RenderLayer&, const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect, const LayoutRect& layerRepaintRect); >- bool beginFilterEffect(); >- void applyFilterEffect(GraphicsContext& destinationContext); >- >- GraphicsContext* filterContext() const; >- >- const LayoutRect& repaintRect() const { return m_repaintRect; } >- >-private: >- RenderLayer* m_renderLayer { nullptr }; // FIXME: this is mainly used to get the CSSFilter. FilterEffectRendererHelper should be weaned off it. >- LayoutPoint m_paintOffset; >- LayoutRect m_repaintRect; >- const GraphicsContext& m_targetContext; >- bool m_haveFilterEffect { false }; >- bool m_startedFilterEffect { false }; >-}; >- >-} // namespace WebCore >diff --git a/Source/WebCore/rendering/RenderLayer.cpp b/Source/WebCore/rendering/RenderLayer.cpp >index 8a074b42066f21e059eb19a2386415a1788b8357..d390c139b3d58c8b4ebd8026215961c7471ff5f8 100644 >--- a/Source/WebCore/rendering/RenderLayer.cpp >+++ b/Source/WebCore/rendering/RenderLayer.cpp >@@ -59,7 +59,6 @@ > #include "EventHandler.h" > #include "FEColorMatrix.h" > #include "FEMerge.h" >-#include "FilterEffectRenderer.h" > #include "FloatConversion.h" > #include "FloatPoint3D.h" > #include "FloatRect.h" >@@ -96,7 +95,7 @@ > #include "RenderIterator.h" > #include "RenderLayerBacking.h" > #include "RenderLayerCompositor.h" >-#include "RenderLayerFilterInfo.h" >+#include "RenderLayerFilters.h" > #include "RenderMarquee.h" > #include "RenderMultiColumnFlow.h" > #include "RenderReplica.h" >@@ -312,7 +311,6 @@ RenderLayer::RenderLayer(RenderLayerModelObject& rendererLayerModelObject) > #if !ASSERT_DISABLED > , m_layerListMutationAllowed(true) > #endif >- , m_hasFilterInfo(false) > #if ENABLE(CSS_COMPOSITING) > , m_blendMode(static_cast<unsigned>(BlendMode::Normal)) > , m_hasNotIsolatedCompositedBlendingDescendants(false) >@@ -370,7 +368,7 @@ RenderLayer::~RenderLayer() > clearScrollCorner(); > clearResizer(); > >- FilterInfo::remove(*this); >+ clearLayerFilters(); > > // Child layers will be deleted by their corresponding render objects, so > // we don't need to delete them ourselves. >@@ -452,24 +450,15 @@ bool RenderLayer::paintsWithFilters() const > if (!isComposited()) > return true; > >- if (!m_backing || !m_backing->canCompositeFilters()) >- return true; >- >- return false; >+ return !m_backing->canCompositeFilters(); > } > > bool RenderLayer::requiresFullLayerImageForFilters() const > { > if (!paintsWithFilters()) > return false; >- auto* cssFilter = filter(); >- return cssFilter && cssFilter->hasFilterThatMovesPixels(); >-} > >-CSSFilter* RenderLayer::filter() const >-{ >- auto* filterInfo = FilterInfo::getIfExists(*this); >- return filterInfo ? filterInfo->filter() : nullptr; >+ return m_filters && m_filters->hasFilterThatMovesPixels(); > } > > void RenderLayer::updateLayerPositionsAfterLayout(const RenderLayer* rootLayer, OptionSet<UpdateLayerPositionsFlag> flags) >@@ -1608,16 +1597,19 @@ RenderLayer* RenderLayer::enclosingFilterRepaintLayer() const > return nullptr; > } > >+// FIXME: This neeeds a better name. > void RenderLayer::setFilterBackendNeedsRepaintingInRect(const LayoutRect& rect) > { >+ ASSERT(requiresFullLayerImageForFilters()); >+ ASSERT(m_filters); >+ > if (rect.isEmpty()) > return; > > LayoutRect rectForRepaint = rect; > renderer().style().filterOutsets().expandRect(rectForRepaint); > >- FilterInfo& filterInfo = FilterInfo::get(*this); >- filterInfo.expandDirtySourceRect(rectForRepaint); >+ m_filters->expandDirtySourceRect(rectForRepaint); > > RenderLayer* parentLayer = enclosingFilterRepaintLayer(); > ASSERT(parentLayer); >@@ -4196,43 +4188,30 @@ bool RenderLayer::setupClipPath(GraphicsContext& context, const LayerPaintingInf > return false; > } > >-std::pair<RenderLayer::FilterInfo*, std::unique_ptr<FilterEffectRendererHelper>> RenderLayer::filterPainter(GraphicsContext& context, OptionSet<PaintLayerFlag> paintFlags) const >+RenderLayerFilters* RenderLayer::filtersForPainting(GraphicsContext& context, OptionSet<PaintLayerFlag> paintFlags) const > { > if (context.paintingDisabled()) >- return { }; >+ return nullptr; > > if (paintFlags & PaintLayerPaintingOverlayScrollbars) >- return { }; >+ return nullptr; > > if (!paintsWithFilters()) >- return { }; >- >- auto* info = FilterInfo::getIfExists(*this); >- if (!info || !info->filter()) >- return { }; >- >- auto helper = std::make_unique<FilterEffectRendererHelper>(true, context); >- if (!helper->haveFilterEffect()) >- return { }; >+ return nullptr; > >- return { info, WTFMove(helper) }; >-} >+ if (m_filters && m_filters->filter()) >+ return m_filters.get(); > >-bool RenderLayer::hasFilterThatIsPainting(GraphicsContext& context, OptionSet<PaintLayerFlag> paintFlags) const >-{ >- return !!filterPainter(context, paintFlags).first; >+ return nullptr; > } > >-std::unique_ptr<FilterEffectRendererHelper> RenderLayer::setupFilters(GraphicsContext& context, LayerPaintingInfo& paintingInfo, OptionSet<PaintLayerFlag> paintFlags, const LayoutSize& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed) >+GraphicsContext* RenderLayer::setupFilters(GraphicsContext& destinationContext, LayerPaintingInfo& paintingInfo, OptionSet<PaintLayerFlag> paintFlags, const LayoutSize& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed) > { >- auto painter = filterPainter(context, paintFlags); >- if (!painter.first) >+ auto* paintingFilters = filtersForPainting(destinationContext, paintFlags); >+ if (!paintingFilters) > return nullptr; > >- auto& filterInfo = *painter.first; >- auto& filterPainter = *painter.second; >- >- LayoutRect filterRepaintRect = filterInfo.dirtySourceRect(); >+ LayoutRect filterRepaintRect = paintingFilters->dirtySourceRect(); > filterRepaintRect.move(offsetFromRoot); > > if (!rootRelativeBoundsComputed) { >@@ -4240,35 +4219,28 @@ std::unique_ptr<FilterEffectRendererHelper> RenderLayer::setupFilters(GraphicsCo > rootRelativeBoundsComputed = true; > } > >- if (!filterPainter.prepareFilterEffect(*this, enclosingIntRect(rootRelativeBounds), enclosingIntRect(paintingInfo.paintDirtyRect), enclosingIntRect(filterRepaintRect))) >- return nullptr; >- >- // Now we know for sure that the source image will be updated, so we can revert our tracking repaint rect back to zero. >- filterInfo.resetDirtySourceRect(); >- >- if (!filterPainter.beginFilterEffect()) >+ GraphicsContext* filterContext = paintingFilters->beginFilterEffect(destinationContext, enclosingIntRect(rootRelativeBounds), enclosingIntRect(paintingInfo.paintDirtyRect), enclosingIntRect(filterRepaintRect)); >+ if (!filterContext) > return nullptr; > >- paintingInfo.paintDirtyRect = filterPainter.repaintRect(); >+ paintingInfo.paintDirtyRect = paintingFilters->repaintRect(); > > // If the filter needs the full source image, we need to avoid using the clip rectangles. > // Otherwise, if for example this layer has overflow:hidden, a drop shadow will not compute correctly. > // Note that we will still apply the clipping on the final rendering of the filter. >- paintingInfo.clipToDirtyRect = !filterInfo.filter()->hasFilterThatMovesPixels(); >+ paintingInfo.clipToDirtyRect = !paintingFilters->hasFilterThatMovesPixels(); > >- paintingInfo.requireSecurityOriginAccessForWidgets = filterInfo.filter()->hasFilterThatShouldBeRestrictedBySecurityOrigin(); >+ paintingInfo.requireSecurityOriginAccessForWidgets = paintingFilters->hasFilterThatShouldBeRestrictedBySecurityOrigin(); > >- return WTFMove(painter.second); >+ return filterContext; > } > >-void RenderLayer::applyFilters(FilterEffectRendererHelper* filterPainter, GraphicsContext& originalContext, const LayerPaintingInfo& paintingInfo, const LayerFragments& layerFragments) >+void RenderLayer::applyFilters(GraphicsContext& originalContext, const LayerPaintingInfo& paintingInfo, const LayerFragments& layerFragments) > { >- ASSERT(filterPainter->hasStartedFilterEffect()); >- > // FIXME: Handle more than one fragment. > ClipRect backgroundRect = layerFragments.isEmpty() ? ClipRect() : layerFragments[0].backgroundRect; > clipToRect(originalContext, paintingInfo, backgroundRect); >- filterPainter->applyFilterEffect(originalContext); >+ m_filters->applyFilterEffect(originalContext); > restoreClip(originalContext, paintingInfo, backgroundRect); > } > >@@ -4318,7 +4290,7 @@ void RenderLayer::paintLayerContents(GraphicsContext& context, const LayerPainti > > // Apply clip-path to context. > LayoutSize columnAwareOffsetFromRoot = offsetFromRoot; >- if (renderer().enclosingFragmentedFlow() && (renderer().hasClipPath() || hasFilterThatIsPainting(context, paintFlags))) >+ if (renderer().enclosingFragmentedFlow() && (renderer().hasClipPath() || filtersForPainting(context, paintFlags))) > columnAwareOffsetFromRoot = toLayoutSize(convertToLayerCoords(paintingInfo.rootLayer, LayoutPoint(), AdjustForColumns)); > > bool hasClipPath = false; >@@ -4335,9 +4307,7 @@ void RenderLayer::paintLayerContents(GraphicsContext& context, const LayerPainti > > { // Scope for filter-related state changes. > LayerPaintingInfo localPaintingInfo(paintingInfo); >- std::unique_ptr<FilterEffectRendererHelper> filterPainter = setupFilters(context, localPaintingInfo, paintFlags, columnAwareOffsetFromRoot, rootRelativeBounds, rootRelativeBoundsComputed); >- >- GraphicsContext* filterContext = filterPainter ? filterPainter->filterContext() : nullptr; >+ GraphicsContext* filterContext = setupFilters(context, localPaintingInfo, paintFlags, columnAwareOffsetFromRoot, rootRelativeBounds, rootRelativeBoundsComputed); > if (filterContext && haveTransparency) { > // If we have a filter and transparency, we have to eagerly start a transparency layer here, rather than risk a child layer lazily starts one with the wrong context. > beginTransparencyLayers(context, localPaintingInfo, paintingInfo.paintDirtyRect); >@@ -4431,8 +4401,7 @@ void RenderLayer::paintLayerContents(GraphicsContext& context, const LayerPainti > (isPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip, offsetFromRoot); > updatePaintingInfoForFragments(layerFragments, paintingInfo, localPaintFlags, shouldPaintContent, offsetFromRoot); > >- applyFilters(filterPainter.get(), context, paintingInfo, layerFragments); >- filterPainter = nullptr; >+ applyFilters(context, paintingInfo, layerFragments); > } > } > >@@ -5966,7 +5935,7 @@ RenderLayerBacking* RenderLayer::ensureBacking() > m_backing = std::make_unique<RenderLayerBacking>(*this); > compositor().layerBecameComposited(*this); > >- updateOrRemoveFilterEffectRenderer(); >+ updateFilterPaintingStrategy(); > } > return m_backing.get(); > } >@@ -5978,7 +5947,7 @@ void RenderLayer::clearBacking(bool layerBeingDestroyed) > m_backing = nullptr; > > if (!layerBeingDestroyed) >- updateOrRemoveFilterEffectRenderer(); >+ updateFilterPaintingStrategy(); > } > > bool RenderLayer::hasCompositedMask() const >@@ -6688,13 +6657,13 @@ void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle* oldStyle > #if ENABLE(CSS_COMPOSITING) > updateBlendMode(); > #endif >- updateOrRemoveFilterClients(); >+ updateFiltersAfterStyleChange(); > > updateNeedsCompositedScrolling(); > > compositor().layerStyleChanged(diff, *this, oldStyle); > >- updateOrRemoveFilterEffectRenderer(); >+ updateFilterPaintingStrategy(); > > #if PLATFORM(IOS) && ENABLE(TOUCH_EVENTS) > if (diff == StyleDifference::RecompositeLayer || diff >= StyleDifference::LayoutPositionedMovementOnly) >@@ -6860,30 +6829,45 @@ RenderStyle RenderLayer::createReflectionStyle() > return newStyle; > } > >-void RenderLayer::updateOrRemoveFilterClients() >+void RenderLayer::ensureLayerFilters() >+{ >+ if (m_filters) >+ return; >+ >+ m_filters = std::make_unique<RenderLayerFilters>(*this); >+} >+ >+void RenderLayer::clearLayerFilters() >+{ >+ m_filters = nullptr; >+} >+ >+void RenderLayer::updateFiltersAfterStyleChange() > { > if (!hasFilter()) { >- FilterInfo::remove(*this); >+ clearLayerFilters(); > return; > } >+ > // Add the filter as a client to this renderer, unless we are a RenderLayer accommodating > // an SVG. In that case it takes care of its own resource management for filters. >- if (renderer().style().filter().hasReferenceFilter() && !renderer().isSVGRoot()) >- FilterInfo::get(*this).updateReferenceFilterClients(renderer().style().filter()); >- else if (FilterInfo* filterInfo = FilterInfo::getIfExists(*this)) >- filterInfo->removeReferenceFilterClients(); >+ if (renderer().style().filter().hasReferenceFilter() && !renderer().isSVGRoot()) { >+ ensureLayerFilters(); >+ m_filters->updateReferenceFilterClients(renderer().style().filter()); >+ } else if (m_filters) >+ m_filters->removeReferenceFilterClients(); > } > >-void RenderLayer::updateOrRemoveFilterEffectRenderer() >+void RenderLayer::updateFilterPaintingStrategy() > { >- // FilterEffectRenderer is only used to render the filters in software mode, >- // so we always need to run updateOrRemoveFilterEffectRenderer after the composited >+ // RenderLayerFilters is only used to render the filters in software mode, >+ // so we always need to run updateFilterPaintingStrategy() after the composited > // mode might have changed for this layer. > if (!paintsWithFilters()) { > // Don't delete the whole filter info here, because we might use it > // for loading SVG reference filter files. >- if (FilterInfo* filterInfo = FilterInfo::getIfExists(*this)) >- filterInfo->setFilter(nullptr); >+ if (m_filters) >+ m_filters->setFilter(nullptr); > > // Early-return only if we *don't* have reference filters. > // For reference filters, we still want the FilterEffect graph built >@@ -6892,24 +6876,8 @@ void RenderLayer::updateOrRemoveFilterEffectRenderer() > return; > } > >- FilterInfo& filterInfo = FilterInfo::get(*this); >- if (!filterInfo.filter()) { >- auto cssFilter = CSSFilter::create(); >- cssFilter->setFilterScale(page().deviceScaleFactor()); >- cssFilter->setRenderingMode(renderer().settings().acceleratedFiltersEnabled() ? Accelerated : Unaccelerated); >- filterInfo.setFilter(WTFMove(cssFilter)); >- >- // We can optimize away code paths in other places if we know that there are no software filters. >- renderer().view().setHasSoftwareFilters(true); >- } else if (filterInfo.filter()->filterScale() != page().deviceScaleFactor()) { >- filterInfo.filter()->setFilterScale(page().deviceScaleFactor()); >- filterInfo.filter()->clearIntermediateResults(); >- } >- >- // If the filter fails to build, remove it from the layer. It will still attempt to >- // go through regular processing (e.g. compositing), but never apply anything. >- if (!filterInfo.filter()->build(renderer(), renderer().style().filter(), FilterConsumer::FilterProperty)) >- filterInfo.setFilter(nullptr); >+ ensureLayerFilters(); >+ m_filters->buildFilter(renderer(), page().deviceScaleFactor(), renderer().settings().acceleratedFiltersEnabled() ? Accelerated : Unaccelerated); > } > > void RenderLayer::filterNeedsRepaint() >diff --git a/Source/WebCore/rendering/RenderLayer.h b/Source/WebCore/rendering/RenderLayer.h >index 820ab45f88bd256466d6c4af2eb612448e989e2b..eb683ccce2e85a1ce3bd276dd3ba18efd26962b1 100644 >--- a/Source/WebCore/rendering/RenderLayer.h >+++ b/Source/WebCore/rendering/RenderLayer.h >@@ -63,8 +63,6 @@ namespace WebCore { > class CSSFilter; > class ClipRects; > class ClipRectsCache; >-class FilterEffectRendererHelper; >-class FilterOperations; > class HitTestRequest; > class HitTestResult; > class HitTestingTransformState; >@@ -72,6 +70,7 @@ class RenderFragmentedFlow; > class RenderGeometryMap; > class RenderLayerBacking; > class RenderLayerCompositor; >+class RenderLayerFilters; > class RenderMarquee; > class RenderReplica; > class RenderScrollbarPart; >@@ -125,6 +124,7 @@ class RenderLayer final : public ScrollableArea { > WTF_MAKE_FAST_ALLOCATED; > public: > friend class RenderReplica; >+ friend class RenderLayerFilters; > > explicit RenderLayer(RenderLayerModelObject&); > virtual ~RenderLayer(); >@@ -645,7 +645,7 @@ public: > bool hasNotIsolatedBlendingDescendantsStatusDirty() const { return false; } > #endif > >- bool isComposited() const { return m_backing != 0; } >+ bool isComposited() const { return m_backing != nullptr; } > bool hasCompositingDescendant() const { return m_hasCompositingDescendant; } > bool hasCompositedMask() const; > RenderLayerBacking* backing() const { return m_backing.get(); } >@@ -679,7 +679,6 @@ public: > > bool paintsWithFilters() const; > bool requiresFullLayerImageForFilters() const; >- CSSFilter* filter() const; > > #if !ASSERT_DISABLED > bool layerListMutationAllowed() const { return m_layerListMutationAllowed; } >@@ -823,11 +822,12 @@ private: > > bool setupClipPath(GraphicsContext&, const LayerPaintingInfo&, const LayoutSize& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed); > >- class FilterInfo; >- std::pair<FilterInfo*, std::unique_ptr<FilterEffectRendererHelper>> filterPainter(GraphicsContext&, OptionSet<PaintLayerFlag>) const; >- bool hasFilterThatIsPainting(GraphicsContext&, OptionSet<PaintLayerFlag>) const; >- std::unique_ptr<FilterEffectRendererHelper> setupFilters(GraphicsContext&, LayerPaintingInfo&, OptionSet<PaintLayerFlag>, const LayoutSize& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed); >- void applyFilters(FilterEffectRendererHelper*, GraphicsContext& originalContext, const LayerPaintingInfo&, const LayerFragments&); >+ void ensureLayerFilters(); >+ void clearLayerFilters(); >+ >+ RenderLayerFilters* filtersForPainting(GraphicsContext&, OptionSet<PaintLayerFlag>) const; >+ GraphicsContext* setupFilters(GraphicsContext& destinationContext, LayerPaintingInfo&, OptionSet<PaintLayerFlag>, const LayoutSize& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed); >+ void applyFilters(GraphicsContext& originalContext, const LayerPaintingInfo&, const LayerFragments&); > > void paintLayer(GraphicsContext&, const LayerPaintingInfo&, OptionSet<PaintLayerFlag>); > void paintLayerContentsAndReflection(GraphicsContext&, const LayerPaintingInfo&, OptionSet<PaintLayerFlag>); >@@ -955,8 +955,8 @@ private: > bool paintingInsideReflection() const { return m_paintingInsideReflection; } > void setPaintingInsideReflection(bool b) { m_paintingInsideReflection = b; } > >- void updateOrRemoveFilterClients(); >- void updateOrRemoveFilterEffectRenderer(); >+ void updateFiltersAfterStyleChange(); >+ void updateFilterPaintingStrategy(); > > #if ENABLE(CSS_COMPOSITING) > void updateAncestorChainHasBlendingDescendants(); >@@ -1092,8 +1092,6 @@ private: > bool m_layerListMutationAllowed : 1; > #endif > >- bool m_hasFilterInfo : 1; >- > #if ENABLE(CSS_COMPOSITING) > unsigned m_blendMode : 5; > bool m_hasNotIsolatedCompositedBlendingDescendants : 1; >@@ -1163,6 +1161,7 @@ private: > > IntRect m_blockSelectionGapsBounds; > >+ std::unique_ptr<RenderLayerFilters> m_filters; > std::unique_ptr<RenderLayerBacking> m_backing; > > PaintFrequencyTracker m_paintFrequencyTracker; >diff --git a/Source/WebCore/rendering/RenderLayerFilterInfo.cpp b/Source/WebCore/rendering/RenderLayerFilterInfo.cpp >deleted file mode 100644 >index ba16580fce6379063b0e41bea1399ac0dedadc8e..0000000000000000000000000000000000000000 >--- a/Source/WebCore/rendering/RenderLayerFilterInfo.cpp >+++ /dev/null >@@ -1,137 +0,0 @@ >-/* >- * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. >- * Copyright (C) 2013 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * >- * 1. Redistributions of source code must retain the above >- * copyright notice, this list of conditions and the following >- * disclaimer. >- * 2. Redistributions in binary form must reproduce the above >- * copyright notice, this list of conditions and the following >- * disclaimer in the documentation and/or other materials >- * provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE >- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, >- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY >- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR >- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF >- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF >- * SUCH DAMAGE. >- */ >- >-#include "config.h" >-#include "RenderLayerFilterInfo.h" >- >-#include "CachedSVGDocument.h" >-#include "CachedSVGDocumentReference.h" >-#include "FilterEffectRenderer.h" >-#include "RenderSVGResourceFilter.h" >-#include <wtf/NeverDestroyed.h> >- >-namespace WebCore { >- >-HashMap<const RenderLayer*, std::unique_ptr<RenderLayer::FilterInfo>>& RenderLayer::FilterInfo::map() >-{ >- static NeverDestroyed<HashMap<const RenderLayer*, std::unique_ptr<FilterInfo>>> map; >- return map; >-} >- >-RenderLayer::FilterInfo* RenderLayer::FilterInfo::getIfExists(const RenderLayer& layer) >-{ >- ASSERT(layer.m_hasFilterInfo == map().contains(&layer)); >- >- return layer.m_hasFilterInfo ? map().get(&layer) : nullptr; >-} >- >-RenderLayer::FilterInfo& RenderLayer::FilterInfo::get(RenderLayer& layer) >-{ >- ASSERT(layer.m_hasFilterInfo == map().contains(&layer)); >- >- auto& info = map().add(&layer, nullptr).iterator->value; >- if (!info) { >- info = std::make_unique<FilterInfo>(layer); >- layer.m_hasFilterInfo = true; >- } >- return *info; >-} >- >-void RenderLayer::FilterInfo::remove(RenderLayer& layer) >-{ >- ASSERT(layer.m_hasFilterInfo == map().contains(&layer)); >- if (!layer.m_hasFilterInfo) >- return; >- >- map().remove(&layer); >- layer.m_hasFilterInfo = false; >-} >- >-RenderLayer::FilterInfo::FilterInfo(RenderLayer& layer) >- : m_layer(layer) >-{ >-} >- >-RenderLayer::FilterInfo::~FilterInfo() >-{ >- removeReferenceFilterClients(); >-} >- >-void RenderLayer::FilterInfo::setFilter(RefPtr<CSSFilter>&& filter) >-{ >- m_filter = filter; >-} >- >-void RenderLayer::FilterInfo::notifyFinished(CachedResource&) >-{ >- m_layer.filterNeedsRepaint(); >-} >- >-void RenderLayer::FilterInfo::updateReferenceFilterClients(const FilterOperations& operations) >-{ >- removeReferenceFilterClients(); >- for (auto& operation : operations.operations()) { >- if (!is<ReferenceFilterOperation>(*operation)) >- continue; >- auto& referenceOperation = downcast<ReferenceFilterOperation>(*operation); >- auto* documentReference = referenceOperation.cachedSVGDocumentReference(); >- if (auto* cachedSVGDocument = documentReference ? documentReference->document() : nullptr) { >- // Reference is external; wait for notifyFinished(). >- cachedSVGDocument->addClient(*this); >- m_externalSVGReferences.append(cachedSVGDocument); >- } else { >- // Reference is internal; add layer as a client so we can trigger filter repaint on SVG attribute change. >- auto* filterElement = m_layer.renderer().document().getElementById(referenceOperation.fragment()); >- if (!filterElement) >- continue; >- auto* renderer = filterElement->renderer(); >- if (!is<RenderSVGResourceFilter>(renderer)) >- continue; >- downcast<RenderSVGResourceFilter>(*renderer).addClientRenderLayer(&m_layer); >- m_internalSVGReferences.append(filterElement); >- } >- } >-} >- >-void RenderLayer::FilterInfo::removeReferenceFilterClients() >-{ >- for (auto& resourceHandle : m_externalSVGReferences) >- resourceHandle->removeClient(*this); >- >- m_externalSVGReferences.clear(); >- >- for (auto& filterElement : m_internalSVGReferences) { >- if (auto* renderer = filterElement->renderer()) >- downcast<RenderSVGResourceContainer>(*renderer).removeClientRenderLayer(&m_layer); >- } >- m_internalSVGReferences.clear(); >-} >- >-} // namespace WebCore >diff --git a/Source/WebCore/rendering/RenderLayerFilterInfo.h b/Source/WebCore/rendering/RenderLayerFilterInfo.h >deleted file mode 100644 >index 4782c4173821025405cff7ca39e002a8351257e4..0000000000000000000000000000000000000000 >--- a/Source/WebCore/rendering/RenderLayerFilterInfo.h >+++ /dev/null >@@ -1,78 +0,0 @@ >-/* >- * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. >- * Copyright (C) 2013 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * >- * 1. Redistributions of source code must retain the above >- * copyright notice, this list of conditions and the following >- * disclaimer. >- * 2. Redistributions in binary form must reproduce the above >- * copyright notice, this list of conditions and the following >- * disclaimer in the documentation and/or other materials >- * provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE >- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, >- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY >- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR >- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF >- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF >- * SUCH DAMAGE. >- */ >- >-#pragma once >- >-#include "CachedResourceHandle.h" >-#include "CachedSVGDocumentClient.h" >-#include "RenderLayer.h" >- >-namespace WebCore { >- >-class CachedSVGDocument; >-class Element; >- >-class RenderLayer::FilterInfo final : private CachedSVGDocumentClient { >-#if !COMPILER(MSVC) >- WTF_MAKE_FAST_ALLOCATED; >-#endif >-public: >- static FilterInfo& get(RenderLayer&); >- static FilterInfo* getIfExists(const RenderLayer&); >- static void remove(RenderLayer&); >- >- explicit FilterInfo(RenderLayer&); >- virtual ~FilterInfo(); >- >- const LayoutRect& dirtySourceRect() const { return m_dirtySourceRect; } >- void expandDirtySourceRect(const LayoutRect& rect) { m_dirtySourceRect.unite(rect); } >- void resetDirtySourceRect() { m_dirtySourceRect = LayoutRect(); } >- >- CSSFilter* filter() const { return m_filter.get(); } >- void setFilter(RefPtr<CSSFilter>&&); >- >- void updateReferenceFilterClients(const FilterOperations&); >- void removeReferenceFilterClients(); >- >-private: >- void notifyFinished(CachedResource&) final; >- >- static HashMap<const RenderLayer*, std::unique_ptr<FilterInfo>>& map(); >- >- RenderLayer& m_layer; >- >- RefPtr<CSSFilter> m_filter; >- LayoutRect m_dirtySourceRect; >- >- Vector<RefPtr<Element>> m_internalSVGReferences; >- Vector<CachedResourceHandle<CachedSVGDocument>> m_externalSVGReferences; >-}; >- >-} // namespace WebCore >diff --git a/Source/WebCore/rendering/RenderLayerFilters.cpp b/Source/WebCore/rendering/RenderLayerFilters.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..77d99c9a8aedc93b38f1ff417fe444eaabfbaa12 >--- /dev/null >+++ b/Source/WebCore/rendering/RenderLayerFilters.cpp >@@ -0,0 +1,195 @@ >+/* >+ * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * >+ * 1. Redistributions of source code must retain the above >+ * copyright notice, this list of conditions and the following >+ * disclaimer. >+ * 2. Redistributions in binary form must reproduce the above >+ * copyright notice, this list of conditions and the following >+ * disclaimer in the documentation and/or other materials >+ * provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE >+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, >+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY >+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR >+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF >+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF >+ * SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "RenderLayerFilters.h" >+ >+#include "CachedSVGDocument.h" >+#include "CachedSVGDocumentReference.h" >+#include "RenderSVGResourceFilter.h" >+#include <wtf/NeverDestroyed.h> >+ >+namespace WebCore { >+ >+RenderLayerFilters::RenderLayerFilters(RenderLayer& layer) >+ : m_layer(layer) >+{ >+ WTFLogAlways("RenderLayerFilters %p ctor", this); >+} >+ >+RenderLayerFilters::~RenderLayerFilters() >+{ >+ WTFLogAlways("RenderLayerFilters %p dtor", this); >+ removeReferenceFilterClients(); >+} >+ >+void RenderLayerFilters::setFilter(RefPtr<CSSFilter>&& filter) >+{ >+ m_filter = WTFMove(filter); >+} >+ >+bool RenderLayerFilters::hasFilterThatMovesPixels() const >+{ >+ return m_filter && m_filter->hasFilterThatMovesPixels(); >+} >+ >+bool RenderLayerFilters::hasFilterThatShouldBeRestrictedBySecurityOrigin() const >+{ >+ return m_filter && m_filter->hasFilterThatShouldBeRestrictedBySecurityOrigin(); >+} >+ >+void RenderLayerFilters::notifyFinished(CachedResource&) >+{ >+ m_layer.filterNeedsRepaint(); >+} >+ >+void RenderLayerFilters::updateReferenceFilterClients(const FilterOperations& operations) >+{ >+ removeReferenceFilterClients(); >+ >+ for (auto& operation : operations.operations()) { >+ if (!is<ReferenceFilterOperation>(*operation)) >+ continue; >+ >+ auto& referenceOperation = downcast<ReferenceFilterOperation>(*operation); >+ auto* documentReference = referenceOperation.cachedSVGDocumentReference(); >+ if (auto* cachedSVGDocument = documentReference ? documentReference->document() : nullptr) { >+ // Reference is external; wait for notifyFinished(). >+ cachedSVGDocument->addClient(*this); >+ m_externalSVGReferences.append(cachedSVGDocument); >+ } else { >+ // Reference is internal; add layer as a client so we can trigger filter repaint on SVG attribute change. >+ auto* filterElement = m_layer.renderer().document().getElementById(referenceOperation.fragment()); >+ if (!filterElement) >+ continue; >+ auto* renderer = filterElement->renderer(); >+ if (!is<RenderSVGResourceFilter>(renderer)) >+ continue; >+ downcast<RenderSVGResourceFilter>(*renderer).addClientRenderLayer(&m_layer); >+ m_internalSVGReferences.append(filterElement); >+ } >+ } >+} >+ >+void RenderLayerFilters::removeReferenceFilterClients() >+{ >+ for (auto& resourceHandle : m_externalSVGReferences) >+ resourceHandle->removeClient(*this); >+ >+ m_externalSVGReferences.clear(); >+ >+ for (auto& filterElement : m_internalSVGReferences) { >+ if (auto* renderer = filterElement->renderer()) >+ downcast<RenderSVGResourceContainer>(*renderer).removeClientRenderLayer(&m_layer); >+ } >+ m_internalSVGReferences.clear(); >+} >+ >+void RenderLayerFilters::buildFilter(RenderElement& renderer, float scaleFactor, RenderingMode renderingMode) >+{ >+ if (!m_filter) { >+ m_filter = CSSFilter::create(); >+ m_filter->setFilterScale(scaleFactor); >+ m_filter->setRenderingMode(renderingMode); >+ } else if (m_filter->filterScale() != scaleFactor) { >+ m_filter->setFilterScale(scaleFactor); >+ m_filter->clearIntermediateResults(); >+ } >+ >+ // If the filter fails to build, remove it from the layer. It will still attempt to >+ // go through regular processing (e.g. compositing), but never apply anything. >+ // FIXME: this rebuilds the entire effects chain even if the filter style didn't change. >+ if (!m_filter->build(renderer, renderer.style().filter(), FilterConsumer::FilterProperty)) >+ m_filter = nullptr; >+} >+ >+GraphicsContext* RenderLayerFilters::beginFilterEffect(GraphicsContext& destinationContext, const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect, const LayoutRect& layerRepaintRect) >+{ >+ if (!m_filter) >+ return nullptr; >+ >+ auto& filter = *m_filter; >+ auto filterSourceRect = filter.computeSourceImageRectForDirtyRect(filterBoxRect, dirtyRect); >+ if (filterSourceRect.isEmpty()) >+ return nullptr; >+ >+ bool hasUpdatedBackingStore = filter.updateBackingStoreRect(filterSourceRect); >+ if (!filter.hasFilterThatMovesPixels()) >+ m_repaintRect = dirtyRect; >+ else { >+ if (hasUpdatedBackingStore) >+ m_repaintRect = filterSourceRect; >+ else { >+ m_repaintRect = dirtyRect; >+ m_repaintRect.unite(layerRepaintRect); >+ m_repaintRect.intersect(filterSourceRect); >+ } >+ } >+ m_paintOffset = filterSourceRect.location(); >+ resetDirtySourceRect(); >+ >+ filter.allocateBackingStoreIfNeeded(destinationContext); >+ auto* sourceGraphicsContext = filter.inputContext(); >+ if (!sourceGraphicsContext || filter.filterRegion().isEmpty() || ImageBuffer::sizeNeedsClamping(filter.filterRegion().size())) >+ return nullptr; >+ >+ // Translate the context so that the contents of the layer is captured in the offscreen memory buffer. >+ sourceGraphicsContext->save(); >+ sourceGraphicsContext->translate(-m_paintOffset); >+ sourceGraphicsContext->clearRect(m_repaintRect); >+ sourceGraphicsContext->clip(m_repaintRect); >+ >+ return sourceGraphicsContext; >+} >+ >+void RenderLayerFilters::applyFilterEffect(GraphicsContext& destinationContext) >+{ >+ ASSERT(m_filter->inputContext()); >+ >+ LOG_WITH_STREAM(Filters, stream << "\nRenderLayerFilters " << this << " applyFilterEffect"); >+ >+ auto& filter = *m_filter; >+ filter.inputContext()->restore(); >+ >+ filter.apply(); >+ >+ // Get the filtered output and draw it in place. >+ LayoutRect destRect = filter.outputRect(); >+ destRect.move(m_paintOffset.x(), m_paintOffset.y()); >+ >+ if (auto* outputBuffer = filter.output()) >+ destinationContext.drawImageBuffer(*outputBuffer, snapRectToDevicePixels(destRect, m_layer.renderer().document().deviceScaleFactor())); >+ >+ filter.clearIntermediateResults(); >+ >+ LOG_WITH_STREAM(Filters, stream << "RenderLayerFilters " << this << " applyFilterEffect done\n"); >+} >+ >+} // namespace WebCore >diff --git a/Source/WebCore/rendering/RenderLayerFilters.h b/Source/WebCore/rendering/RenderLayerFilters.h >new file mode 100644 >index 0000000000000000000000000000000000000000..d344cbda01d0daa9566717e1d5a6cdbfdc0e995e >--- /dev/null >+++ b/Source/WebCore/rendering/RenderLayerFilters.h >@@ -0,0 +1,86 @@ >+/* >+ * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * >+ * 1. Redistributions of source code must retain the above >+ * copyright notice, this list of conditions and the following >+ * disclaimer. >+ * 2. Redistributions in binary form must reproduce the above >+ * copyright notice, this list of conditions and the following >+ * disclaimer in the documentation and/or other materials >+ * provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE >+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, >+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY >+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR >+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF >+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF >+ * SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#include "CachedResourceHandle.h" >+#include "CachedSVGDocumentClient.h" >+#include "RenderLayer.h" >+ >+namespace WebCore { >+ >+class CachedSVGDocument; >+class Element; >+class FilterOperations; >+ >+class RenderLayerFilters final : private CachedSVGDocumentClient { >+ WTF_MAKE_FAST_ALLOCATED; >+public: >+ explicit RenderLayerFilters(RenderLayer&); >+ virtual ~RenderLayerFilters(); >+ >+ const LayoutRect& dirtySourceRect() const { return m_dirtySourceRect; } >+ void expandDirtySourceRect(const LayoutRect& rect) { m_dirtySourceRect.unite(rect); } >+ >+ CSSFilter* filter() const { return m_filter.get(); } >+ void setFilter(RefPtr<CSSFilter>&&); >+ >+ bool hasFilterThatMovesPixels() const; >+ bool hasFilterThatShouldBeRestrictedBySecurityOrigin() const; >+ >+ void updateReferenceFilterClients(const FilterOperations&); >+ void removeReferenceFilterClients(); >+ >+ void buildFilter(RenderElement&, float scaleFactor, RenderingMode); >+ >+ // Per render >+ LayoutRect repaintRect() const { return m_repaintRect; } >+ >+ GraphicsContext* beginFilterEffect(GraphicsContext& destinationContext, const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect, const LayoutRect& layerRepaintRect); >+ void applyFilterEffect(GraphicsContext& destinationContext); >+ >+private: >+ void notifyFinished(CachedResource&) final; >+ void resetDirtySourceRect() { m_dirtySourceRect = LayoutRect(); } >+ >+ RenderLayer& m_layer; >+ >+ Vector<RefPtr<Element>> m_internalSVGReferences; >+ Vector<CachedResourceHandle<CachedSVGDocument>> m_externalSVGReferences; >+ >+ RefPtr<CSSFilter> m_filter; >+ LayoutRect m_dirtySourceRect; >+ >+ // Data used per paint >+ LayoutPoint m_paintOffset; >+ LayoutRect m_repaintRect; >+}; >+ >+} // namespace WebCore
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 189248
: 348778