Allow the ImageBuffers used by SVG filters to be accelerated
authorsenorblanco@chromium.org <senorblanco@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 6 Dec 2011 04:16:28 +0000 (04:16 +0000)
committersenorblanco@chromium.org <senorblanco@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 6 Dec 2011 04:16:28 +0000 (04:16 +0000)
https://bugs.webkit.org/show_bug.cgi?id=73842

Reviewed by Kenneth Russell.

Source/WebCore:

Regressions covered by existing SVG tests; new functionality to be
tested by the API exposed on Internals.

* page/Settings.cpp:
(WebCore::Settings::Settings):
* page/Settings.h:
(WebCore::Settings::setAcceleratedFiltersEnabled):
(WebCore::Settings::acceleratedFiltersEnabled):
* platform/graphics/filters/FETile.cpp:
(WebCore::FETile::platformApplySoftware):
* platform/graphics/filters/Filter.h:
(WebCore::Filter::Filter):
(WebCore::Filter::renderingMode):
(WebCore::Filter::setRenderingMode):
* platform/graphics/filters/FilterEffect.cpp:
(WebCore::FilterEffect::asImageBuffer):
(WebCore::FilterEffect::createImageBufferResult):
* platform/graphics/skia/ImageBufferSkia.cpp:
(WebCore::ImageBuffer::platformTransformColorSpace):
* rendering/svg/RenderSVGResourceClipper.cpp:
(WebCore::RenderSVGResourceClipper::applyClippingToContext):
* rendering/svg/RenderSVGResourceFilter.cpp:
(WebCore::RenderSVGResourceFilter::applyResource):
* rendering/svg/RenderSVGResourceMasker.cpp:
(WebCore::RenderSVGResourceMasker::applyResource):
* rendering/svg/RenderSVGResourcePattern.cpp:
(WebCore::RenderSVGResourcePattern::createTileImage):
* rendering/svg/SVGImageBufferTools.cpp:
(WebCore::SVGImageBufferTools::createImageBuffer):
* rendering/svg/SVGImageBufferTools.h:
* testing/Internals.cpp:
(WebCore::Internals::setAcceleratedFiltersEnabled):
* testing/Internals.h:
* testing/Internals.idl:

Source/WebKit/chromium:

* public/WebSettings.h:
* src/WebSettingsImpl.cpp:
(WebKit::WebSettingsImpl::setAcceleratedFiltersEnabled):
* src/WebSettingsImpl.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@102088 268f45cc-cd09-0410-ab3c-d52691b4dbfc

21 files changed:
Source/WebCore/ChangeLog
Source/WebCore/page/Settings.cpp
Source/WebCore/page/Settings.h
Source/WebCore/platform/graphics/filters/FETile.cpp
Source/WebCore/platform/graphics/filters/Filter.h
Source/WebCore/platform/graphics/filters/FilterEffect.cpp
Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp
Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp
Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp
Source/WebCore/rendering/svg/RenderSVGResourceMasker.cpp
Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp
Source/WebCore/rendering/svg/SVGImageBufferTools.cpp
Source/WebCore/rendering/svg/SVGImageBufferTools.h
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/Internals.h
Source/WebCore/testing/Internals.idl
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/public/WebSettings.h
Source/WebKit/chromium/src/WebSettingsImpl.cpp
Source/WebKit/chromium/src/WebSettingsImpl.h

index 138b4cc..2086add 100644 (file)
@@ -1,3 +1,45 @@
+2011-12-05  Stephen White  <senorblanco@chromium.org>
+
+        Allow the ImageBuffers used by SVG filters to be accelerated
+        https://bugs.webkit.org/show_bug.cgi?id=73842
+
+        Reviewed by Kenneth Russell.
+
+        Regressions covered by existing SVG tests; new functionality to be
+        tested by the API exposed on Internals.
+
+        * page/Settings.cpp:
+        (WebCore::Settings::Settings):
+        * page/Settings.h:
+        (WebCore::Settings::setAcceleratedFiltersEnabled):
+        (WebCore::Settings::acceleratedFiltersEnabled):
+        * platform/graphics/filters/FETile.cpp:
+        (WebCore::FETile::platformApplySoftware):
+        * platform/graphics/filters/Filter.h:
+        (WebCore::Filter::Filter):
+        (WebCore::Filter::renderingMode):
+        (WebCore::Filter::setRenderingMode):
+        * platform/graphics/filters/FilterEffect.cpp:
+        (WebCore::FilterEffect::asImageBuffer):
+        (WebCore::FilterEffect::createImageBufferResult):
+        * platform/graphics/skia/ImageBufferSkia.cpp:
+        (WebCore::ImageBuffer::platformTransformColorSpace):
+        * rendering/svg/RenderSVGResourceClipper.cpp:
+        (WebCore::RenderSVGResourceClipper::applyClippingToContext):
+        * rendering/svg/RenderSVGResourceFilter.cpp:
+        (WebCore::RenderSVGResourceFilter::applyResource):
+        * rendering/svg/RenderSVGResourceMasker.cpp:
+        (WebCore::RenderSVGResourceMasker::applyResource):
+        * rendering/svg/RenderSVGResourcePattern.cpp:
+        (WebCore::RenderSVGResourcePattern::createTileImage):
+        * rendering/svg/SVGImageBufferTools.cpp:
+        (WebCore::SVGImageBufferTools::createImageBuffer):
+        * rendering/svg/SVGImageBufferTools.h:
+        * testing/Internals.cpp:
+        (WebCore::Internals::setAcceleratedFiltersEnabled):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
 2011-12-05  Benjamin Poulain  <bpoulain@apple.com>
 
         Upstream htmlSelectMultipleItems needed for <select multiple> by iOS
index 83d849e..55e9c1c 100644 (file)
@@ -170,6 +170,7 @@ Settings::Settings(Page* page)
     , m_allowScriptsToCloseWindows(false)
     , m_canvasUsesAcceleratedDrawing(false)
     , m_acceleratedDrawingEnabled(false)
+    , m_acceleratedFiltersEnabled(false)
     // FIXME: This should really be disabled by default as it makes platforms that don't support the feature download files
     // they can't use by. Leaving enabled for now to not change existing behavior.
     , m_downloadableBinaryFontsEnabled(true)
index 65a84d3..4c12fec 100644 (file)
@@ -301,6 +301,9 @@ namespace WebCore {
         void setAcceleratedDrawingEnabled(bool enabled) { m_acceleratedDrawingEnabled = enabled; }
         bool acceleratedDrawingEnabled() const { return m_acceleratedDrawingEnabled; }
 
+        void setAcceleratedFiltersEnabled(bool enabled) { m_acceleratedFiltersEnabled = enabled; }
+        bool acceleratedFiltersEnabled() const { return m_acceleratedFiltersEnabled; }
+
         void setAcceleratedCompositingEnabled(bool);
         bool acceleratedCompositingEnabled() const { return m_acceleratedCompositingEnabled; }
 
@@ -573,6 +576,7 @@ namespace WebCore {
         bool m_allowScriptsToCloseWindows : 1;
         bool m_canvasUsesAcceleratedDrawing : 1;
         bool m_acceleratedDrawingEnabled : 1;
+        bool m_acceleratedFiltersEnabled : 1;
         bool m_downloadableBinaryFontsEnabled : 1;
         bool m_xssAuditorEnabled : 1;
         bool m_acceleratedCompositingEnabled : 1;
index c80f7c8..a6e1da3 100644 (file)
@@ -67,7 +67,7 @@ void FETile::platformApplySoftware()
     }
 
     OwnPtr<ImageBuffer> tileImage;
-    if (!SVGImageBufferTools::createImageBuffer(tileRect, tileRect, tileImage, ColorSpaceDeviceRGB))
+    if (!SVGImageBufferTools::createImageBuffer(tileRect, tileRect, tileImage, ColorSpaceDeviceRGB, filter()->renderingMode()))
         return;
 
     GraphicsContext* tileImageContext = tileImage->context();
index a43bd20..b0f604d 100644 (file)
@@ -32,6 +32,7 @@ class FilterEffect;
 
 class Filter : public RefCounted<Filter> {
 public:
+    Filter() : m_renderingMode(Unaccelerated) { }
     virtual ~Filter() { }
 
     void setSourceImage(PassOwnPtr<ImageBuffer> sourceImage) { m_sourceImage = sourceImage; }
@@ -40,6 +41,9 @@ public:
     FloatSize filterResolution() const { return m_filterResolution; }
     void setFilterResolution(const FloatSize& filterResolution) { m_filterResolution = filterResolution; }
 
+    RenderingMode renderingMode() const { return m_renderingMode; }
+    void setRenderingMode(RenderingMode renderingMode) { m_renderingMode = renderingMode; }
+
     virtual float applyHorizontalScale(float value) const { return value * m_filterResolution.width(); }
     virtual float applyVerticalScale(float value) const { return value * m_filterResolution.height(); }
     
@@ -51,6 +55,7 @@ public:
 private:
     OwnPtr<ImageBuffer> m_sourceImage;
     FloatSize m_filterResolution;
+    RenderingMode m_renderingMode;
 };
 
 } // namespace WebCore
index f927107..dc5302c 100644 (file)
@@ -118,7 +118,7 @@ ImageBuffer* FilterEffect::asImageBuffer()
         return 0;
     if (m_imageBufferResult)
         return m_imageBufferResult.get();
-    m_imageBufferResult = ImageBuffer::create(m_absolutePaintRect.size(), ColorSpaceLinearRGB);
+    m_imageBufferResult = ImageBuffer::create(m_absolutePaintRect.size(), ColorSpaceLinearRGB, m_filter->renderingMode());
     IntRect destinationRect(IntPoint(), m_absolutePaintRect.size());
     if (m_premultipliedImageResult)
         m_imageBufferResult->putPremultipliedImageData(m_premultipliedImageResult.get(), destinationRect.size(), destinationRect, IntPoint());
@@ -255,7 +255,7 @@ ImageBuffer* FilterEffect::createImageBufferResult()
     ASSERT(!hasResult());
     if (m_absolutePaintRect.isEmpty())
         return 0;
-    m_imageBufferResult = ImageBuffer::create(m_absolutePaintRect.size(), ColorSpaceLinearRGB);
+    m_imageBufferResult = ImageBuffer::create(m_absolutePaintRect.size(), ColorSpaceLinearRGB, m_filter->renderingMode());
     if (!m_imageBufferResult)
         return 0;
     ASSERT(m_imageBufferResult->context());
index c91ae83..2845099 100644 (file)
@@ -178,6 +178,10 @@ void ImageBuffer::drawPattern(GraphicsContext* context, const FloatRect& srcRect
 
 void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable)
 {
+    // FIXME: Disable color space conversions on accelerated canvases (for now).
+    if (m_data.m_platformContext.isAccelerated()) 
+        return;
+
     const SkBitmap& bitmap = *context()->platformContext()->bitmap();
     if (bitmap.isNull())
         return;
index 5d500f0..3b2e6f9 100644 (file)
@@ -179,7 +179,7 @@ bool RenderSVGResourceClipper::applyClippingToContext(RenderObject* object, cons
     FloatRect clampedAbsoluteTargetRect = SVGImageBufferTools::clampedAbsoluteTargetRect(absoluteTargetRect);
 
     if (shouldCreateClipData && !clampedAbsoluteTargetRect.isEmpty()) {
-        if (!SVGImageBufferTools::createImageBuffer(absoluteTargetRect, clampedAbsoluteTargetRect, clipperData->clipMaskImage, ColorSpaceDeviceRGB))
+        if (!SVGImageBufferTools::createImageBuffer(absoluteTargetRect, clampedAbsoluteTargetRect, clipperData->clipMaskImage, ColorSpaceDeviceRGB, Unaccelerated))
             return false;
 
         GraphicsContext* maskContext = clipperData->clipMaskImage->context();
index 14ddf81..d72b960 100644 (file)
 #include "ImageBuffer.h"
 #include "ImageData.h"
 #include "IntRect.h"
+#include "Page.h"
 #include "RenderSVGResource.h"
 #include "RenderSVGResourceFilterPrimitive.h"
+#include "Settings.h"
 #include "SVGElement.h"
 #include "SVGFilter.h"
 #include "SVGFilterElement.h"
@@ -229,13 +231,17 @@ bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*,
     absoluteDrawingRegion.scale(scale.width(), scale.height());
 
     OwnPtr<ImageBuffer> sourceGraphic;
-    if (!SVGImageBufferTools::createImageBuffer(absoluteDrawingRegion, absoluteDrawingRegion, sourceGraphic, ColorSpaceLinearRGB)) {
+    RenderingMode renderingMode = object->document()->page()->settings()->acceleratedFiltersEnabled() ? Accelerated : Unaccelerated;
+    if (!SVGImageBufferTools::createImageBuffer(absoluteDrawingRegion, absoluteDrawingRegion, sourceGraphic, ColorSpaceLinearRGB, renderingMode)) {
         ASSERT(!m_filter.contains(object));
         filterData->savedContext = context;
         m_filter.set(object, filterData.leakPtr());
         return false;
     }
     
+    // Set the rendering mode from the page's settings.
+    filterData->filter->setRenderingMode(renderingMode);
+
     GraphicsContext* sourceGraphicContext = sourceGraphic->context();
     ASSERT(sourceGraphicContext);
   
index 437b186..b5373e4 100644 (file)
@@ -92,7 +92,7 @@ static inline bool createMaskAndSwapContextForTextGradient(GraphicsContext*& con
         return false;
 
     OwnPtr<ImageBuffer> maskImage;
-    if (!SVGImageBufferTools::createImageBuffer(absoluteTargetRect, clampedAbsoluteTargetRect, maskImage, ColorSpaceDeviceRGB))
+    if (!SVGImageBufferTools::createImageBuffer(absoluteTargetRect, clampedAbsoluteTargetRect, maskImage, ColorSpaceDeviceRGB, Unaccelerated))
         return false;
 
     GraphicsContext* maskImageContext = maskImage->context();
index eb6db3d..82adc6a 100644 (file)
@@ -106,7 +106,7 @@ bool RenderSVGResourceMasker::applyResource(RenderObject* object, RenderStyle*,
         const SVGRenderStyle* svgStyle = style()->svgStyle();
         ASSERT(svgStyle);
         ColorSpace colorSpace = svgStyle->colorInterpolation() == CI_LINEARRGB ? ColorSpaceLinearRGB : ColorSpaceDeviceRGB;
-        if (!SVGImageBufferTools::createImageBuffer(absoluteTargetRect, clampedAbsoluteTargetRect, maskerData->maskImage, colorSpace))
+        if (!SVGImageBufferTools::createImageBuffer(absoluteTargetRect, clampedAbsoluteTargetRect, maskerData->maskImage, colorSpace, Unaccelerated))
             return false;
 
         GraphicsContext* maskImageContext = maskerData->maskImage->context();
index 4d09e11..e235081 100644 (file)
@@ -252,7 +252,7 @@ PassOwnPtr<ImageBuffer> RenderSVGResourcePattern::createTileImage(const PatternA
 
     OwnPtr<ImageBuffer> tileImage;
 
-    if (!SVGImageBufferTools::createImageBuffer(absoluteTileBoundaries, clampedAbsoluteTileBoundaries, tileImage, ColorSpaceDeviceRGB))
+    if (!SVGImageBufferTools::createImageBuffer(absoluteTileBoundaries, clampedAbsoluteTileBoundaries, tileImage, ColorSpaceDeviceRGB, Unaccelerated))
         return nullptr;
 
     GraphicsContext* tileImageContext = tileImage->context();
index c3d7e08..fe31f2f 100644 (file)
@@ -52,7 +52,7 @@ void SVGImageBufferTools::calculateTransformationToOutermostSVGCoordinateSystem(
     }
 }
 
-bool SVGImageBufferTools::createImageBuffer(const FloatRect& absoluteTargetRect, const FloatRect& clampedAbsoluteTargetRect, OwnPtr<ImageBuffer>& imageBuffer, ColorSpace colorSpace)
+bool SVGImageBufferTools::createImageBuffer(const FloatRect& absoluteTargetRect, const FloatRect& clampedAbsoluteTargetRect, OwnPtr<ImageBuffer>& imageBuffer, ColorSpace colorSpace, RenderingMode renderingMode)
 {
     IntSize imageSize(roundedImageBufferSize(clampedAbsoluteTargetRect.size()));
     IntSize unclampedImageSize(SVGImageBufferTools::roundedImageBufferSize(absoluteTargetRect.size()));
@@ -61,7 +61,7 @@ bool SVGImageBufferTools::createImageBuffer(const FloatRect& absoluteTargetRect,
     if (imageSize.isEmpty())
         return false;
 
-    OwnPtr<ImageBuffer> image = ImageBuffer::create(imageSize, colorSpace);
+    OwnPtr<ImageBuffer> image = ImageBuffer::create(imageSize, colorSpace, renderingMode);
     if (!image)
         return false;
 
index 91c4753..7698d2c 100644 (file)
@@ -35,7 +35,7 @@ class RenderObject;
 class SVGImageBufferTools {
     WTF_MAKE_NONCOPYABLE(SVGImageBufferTools);
 public:
-    static bool createImageBuffer(const FloatRect& absoluteTargetRect, const FloatRect& clampedAbsoluteTargetRect, OwnPtr<ImageBuffer>&, ColorSpace);
+    static bool createImageBuffer(const FloatRect& absoluteTargetRect, const FloatRect& clampedAbsoluteTargetRect, OwnPtr<ImageBuffer>&, ColorSpace, RenderingMode);
     static void renderSubtreeToImageBuffer(ImageBuffer*, RenderObject*, const AffineTransform&);
     static void clipToImageBuffer(GraphicsContext*, const AffineTransform& absoluteTransform, const FloatRect& clampedAbsoluteTargetRect, OwnPtr<ImageBuffer>&);
 
index 9f5136f..ae97243 100644 (file)
@@ -314,6 +314,16 @@ void Internals::setAcceleratedDrawingEnabled(Document* document, bool enabled, E
     document->settings()->setAcceleratedDrawingEnabled(enabled);
 }
 
+void Internals::setAcceleratedFiltersEnabled(Document* document, bool enabled, ExceptionCode& ec)
+{
+    if (!document || !document->settings()) {
+        ec = INVALID_ACCESS_ERR;
+        return;
+    }
+
+    document->settings()->setAcceleratedFiltersEnabled(enabled);
+}
+
 void Internals::setEnableScrollAnimator(Document* document, bool enabled, ExceptionCode& ec)
 {
     if (!document || !document->settings()) {
index 28efb4e..a68fe94 100644 (file)
@@ -79,6 +79,7 @@ public:
     void setEnableCompositingForFixedPosition(Document*, bool enabled, ExceptionCode&);
     void setEnableCompositingForScrollableFrames(Document*, bool enabled, ExceptionCode&);
     void setAcceleratedDrawingEnabled(Document*, bool enabled, ExceptionCode&);
+    void setAcceleratedFiltersEnabled(Document*, bool enabled, ExceptionCode&);
 
     void setEnableScrollAnimator(Document*, bool enabled, ExceptionCode&);
     void setZoomAnimatorTransform(Document*, float scale, float tx, float ty, ExceptionCode&);
index f66bb56..889cda2 100644 (file)
@@ -52,6 +52,7 @@ module window {
         void setEnableCompositingForFixedPosition(in Document document, in boolean enabled) raises(DOMException);
         void setEnableCompositingForScrollableFrames(in Document document, in boolean enabled) raises(DOMException);
         void setAcceleratedDrawingEnabled(in Document document, in boolean enabled) raises(DOMException);
+        void setAcceleratedFiltersEnabled(in Document document, in boolean enabled) raises(DOMException);
         void setEnableScrollAnimator(in Document document, in boolean enabled) raises(DOMException);
         void setZoomAnimatorTransform(in Document document, in float scale, in float tx, in float ty) raises(DOMException);
         float getPageScaleFactor(in Document document) raises(DOMException);
index d06a8b3..c09599c 100644 (file)
@@ -1,3 +1,15 @@
+2011-12-05  Stephen White  <senorblanco@chromium.org>
+
+        Allow the ImageBuffers used by SVG filters to be accelerated
+        https://bugs.webkit.org/show_bug.cgi?id=73842
+
+        Reviewed by Kenneth Russell.
+
+        * public/WebSettings.h:
+        * src/WebSettingsImpl.cpp:
+        (WebKit::WebSettingsImpl::setAcceleratedFiltersEnabled):
+        * src/WebSettingsImpl.h:
+
 2011-12-05  Adam Barth  <abarth@webkit.org>
 
         [Chromium] Chromium fails to compile due to missing WebContentLayerClient.h
index dd77499..d28aba1 100644 (file)
@@ -117,6 +117,7 @@ public:
     virtual void setLegacyAccelerated2dCanvasEnabled(bool) = 0;
     virtual void setMinimumAccelerated2dCanvasSize(int) = 0;
     virtual void setAcceleratedDrawingEnabled(bool) = 0;
+    virtual void setAcceleratedFiltersEnabled(bool) = 0;
     virtual void setMemoryInfoEnabled(bool) = 0;
     virtual void setHyperlinkAuditingEnabled(bool) = 0;
     virtual void setAsynchronousSpellCheckingEnabled(bool) = 0;
index 84ec843..20f2345 100644 (file)
@@ -358,6 +358,11 @@ void WebSettingsImpl::setAcceleratedDrawingEnabled(bool enabled)
     m_settings->setAcceleratedDrawingEnabled(enabled);
 }
 
+void WebSettingsImpl::setAcceleratedFiltersEnabled(bool enabled)
+{
+    m_settings->setAcceleratedFiltersEnabled(enabled);
+}
+
 void WebSettingsImpl::setAccelerated2dCanvasEnabled(bool enabled)
 {
     m_settings->setAccelerated2dCanvasEnabled(enabled);
index 1a09394..2c23cc2 100644 (file)
@@ -109,6 +109,7 @@ public:
     virtual void setLegacyAccelerated2dCanvasEnabled(bool);
     virtual void setMinimumAccelerated2dCanvasSize(int);
     virtual void setAcceleratedDrawingEnabled(bool);
+    virtual void setAcceleratedFiltersEnabled(bool);
     virtual void setMemoryInfoEnabled(bool);
     virtual void setHyperlinkAuditingEnabled(bool);
     virtual void setAsynchronousSpellCheckingEnabled(bool);