Bug 924102 - Implement DrawTarget filter APIs with FilterNodeSoftware for Cairo, CG, D2D, D2D1 and Dual. r=Bas
authorMarkus Stange <mstange@themasta.com>
Wed, 27 Nov 2013 12:22:56 +0100
changeset 172429 272bb40f463fc836525d10f0785035851481964b
parent 172428 8d737d52c4cbe38b7e577b8050f1f0caffcd8214
child 172430 9fe4a520bf31befaeee4e26381e2638ceb76f7c4
push id3224
push userlsblakk@mozilla.com
push dateTue, 04 Feb 2014 01:06:49 +0000
treeherdermozilla-beta@60c04d0987f1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersBas
bugs924102
milestone28.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 924102 - Implement DrawTarget filter APIs with FilterNodeSoftware for Cairo, CG, D2D, D2D1 and Dual. r=Bas
gfx/2d/DrawTargetCG.cpp
gfx/2d/DrawTargetCG.h
gfx/2d/DrawTargetCairo.cpp
gfx/2d/DrawTargetCairo.h
gfx/2d/DrawTargetD2D.cpp
gfx/2d/DrawTargetD2D.h
gfx/2d/DrawTargetD2D1.cpp
gfx/2d/DrawTargetD2D1.h
gfx/2d/DrawTargetDual.h
--- a/gfx/2d/DrawTargetCG.cpp
+++ b/gfx/2d/DrawTargetCG.cpp
@@ -6,16 +6,17 @@
 #include "DrawTargetCG.h"
 #include "SourceSurfaceCG.h"
 #include "Rect.h"
 #include "ScaledFontMac.h"
 #include "Tools.h"
 #include <vector>
 #include <algorithm>
 #include "MacIOSurface.h"
+#include "FilterNodeSoftware.h"
 
 using namespace std;
 
 //CG_EXTERN void CGContextSetCompositeOperation (CGContextRef, PrivateCGCompositeMode);
 
 // A private API that Cairo has been using for a long time
 CG_EXTERN void CGContextSetCTM(CGContextRef, CGAffineTransform);
 
@@ -315,16 +316,32 @@ DrawTargetCG::DrawSurface(SourceSurface 
 
   fixer.Fix(mCg);
 
   CGContextRestoreGState(mCg);
 
   CGImageRelease(subimage);
 }
 
+TemporaryRef<FilterNode>
+DrawTargetCG::CreateFilter(FilterType aType)
+{
+  return FilterNodeSoftware::Create(aType);
+}
+
+void
+DrawTargetCG::DrawFilter(FilterNode *aNode,
+                         const Rect &aSourceRect,
+                         const Point &aDestPoint,
+                         const DrawOptions &aOptions)
+{
+  FilterNodeSoftware* filter = static_cast<FilterNodeSoftware*>(aNode);
+  filter->Draw(this, aSourceRect, aDestPoint, aOptions);
+}
+
 static CGColorRef ColorToCGColor(CGColorSpaceRef aColorSpace, const Color& aColor)
 {
   CGFloat components[4] = {aColor.r, aColor.g, aColor.b, aColor.a};
   return CGColorCreate(aColorSpace, components);
 }
 
 class GradientStopsCG : public GradientStops
 {
--- a/gfx/2d/DrawTargetCG.h
+++ b/gfx/2d/DrawTargetCG.h
@@ -102,16 +102,20 @@ public:
   virtual BackendType GetType() const;
   virtual TemporaryRef<SourceSurface> Snapshot();
 
   virtual void DrawSurface(SourceSurface *aSurface,
                            const Rect &aDest,
                            const Rect &aSource,
                            const DrawSurfaceOptions &aSurfOptions = DrawSurfaceOptions(),
                            const DrawOptions &aOptions = DrawOptions());
+  virtual void DrawFilter(FilterNode *aNode,
+                          const Rect &aSourceRect,
+                          const Point &aDestPoint,
+                          const DrawOptions &aOptions = DrawOptions());
   virtual void MaskSurface(const Pattern &aSource,
                            SourceSurface *aMask,
                            Point aOffset,
                            const DrawOptions &aOptions = DrawOptions());
 
   virtual void FillRect(const Rect &aRect,
                         const Pattern &aPattern,
                         const DrawOptions &aOptions = DrawOptions());
@@ -139,16 +143,17 @@ public:
   virtual void PushClip(const Path *);
   virtual void PushClipRect(const Rect &aRect);
   virtual void PopClip();
   virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromNativeSurface(const NativeSurface&) const { return nullptr;}
   virtual TemporaryRef<DrawTarget> CreateSimilarDrawTarget(const IntSize &, SurfaceFormat) const;
   virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule) const;
   virtual TemporaryRef<GradientStops> CreateGradientStops(GradientStop *, uint32_t,
                                                           ExtendMode aExtendMode = EXTEND_CLAMP) const;
+  virtual TemporaryRef<FilterNode> CreateFilter(FilterType aType);
 
   virtual void *GetNativeSurface(NativeSurfaceType);
 
   virtual IntSize GetSize() { return mSize; }
 
 
   /* This is for creating good compatible surfaces */
   virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
--- a/gfx/2d/DrawTargetCairo.cpp
+++ b/gfx/2d/DrawTargetCairo.cpp
@@ -5,16 +5,17 @@
 
 #include "DrawTargetCairo.h"
 
 #include "SourceSurfaceCairo.h"
 #include "PathCairo.h"
 #include "HelpersCairo.h"
 #include "ScaledFontBase.h"
 #include "BorrowedContext.h"
+#include "FilterNodeSoftware.h"
 
 #include "cairo.h"
 #include "cairo-tee.h"
 #include <string.h>
 
 #include "Blur.h"
 #include "Logging.h"
 #include "Tools.h"
@@ -552,16 +553,26 @@ DrawTargetCairo::DrawSurface(SourceSurfa
   cairo_set_operator(mContext, GfxOpToCairoOp(aOptions.mCompositionOp));
 
   cairo_paint_with_alpha(mContext, aOptions.mAlpha);
 
   cairo_pattern_destroy(pat);
 }
 
 void
+DrawTargetCairo::DrawFilter(FilterNode *aNode,
+                            const Rect &aSourceRect,
+                            const Point &aDestPoint,
+                            const DrawOptions &aOptions)
+{
+  FilterNodeSoftware* filter = static_cast<FilterNodeSoftware*>(aNode);
+  filter->Draw(this, aSourceRect, aDestPoint, aOptions);
+}
+
+void
 DrawTargetCairo::DrawSurfaceWithShadow(SourceSurface *aSurface,
                                        const Point &aDest,
                                        const Color &aColor,
                                        const Point &aOffset,
                                        Float aSigma,
                                        CompositionOp aOperator)
 {
   if (aSurface->GetType() != SURFACE_CAIRO) {
@@ -1012,16 +1023,22 @@ TemporaryRef<GradientStops>
 DrawTargetCairo::CreateGradientStops(GradientStop *aStops, uint32_t aNumStops,
                                      ExtendMode aExtendMode) const
 {
   RefPtr<GradientStopsCairo> stops = new GradientStopsCairo(aStops, aNumStops,
                                                             aExtendMode);
   return stops;
 }
 
+TemporaryRef<FilterNode>
+DrawTargetCairo::CreateFilter(FilterType aType)
+{
+  return FilterNodeSoftware::Create(aType);
+}
+
 /**
  * Copies pixel data from aData into aSurface; aData must have the dimensions
  * given in aSize, with a stride of aStride bytes and aPixelWidth bytes per pixel
  */
 static void
 CopyDataToCairoSurface(cairo_surface_t* aSurface,
                        unsigned char *aData,
                        const IntSize &aSize,
--- a/gfx/2d/DrawTargetCairo.h
+++ b/gfx/2d/DrawTargetCairo.h
@@ -67,16 +67,20 @@ public:
   virtual void ReleaseBits(uint8_t* aData);
 
   virtual void Flush();
   virtual void DrawSurface(SourceSurface *aSurface,
                            const Rect &aDest,
                            const Rect &aSource,
                            const DrawSurfaceOptions &aSurfOptions = DrawSurfaceOptions(),
                            const DrawOptions &aOptions = DrawOptions());
+  virtual void DrawFilter(FilterNode *aNode,
+                          const Rect &aSourceRect,
+                          const Point &aDestPoint,
+                          const DrawOptions &aOptions = DrawOptions());
   virtual void DrawSurfaceWithShadow(SourceSurface *aSurface,
                                      const Point &aDest,
                                      const Color &aColor,
                                      const Point &aOffset,
                                      Float aSigma,
                                      CompositionOp aOperator);
 
   virtual void ClearRect(const Rect &aRect);
@@ -141,16 +145,18 @@ public:
     CreateShadowDrawTarget(const IntSize &aSize, SurfaceFormat aFormat,
                            float aSigma) const;
 
   virtual TemporaryRef<GradientStops>
     CreateGradientStops(GradientStop *aStops,
                         uint32_t aNumStops,
                         ExtendMode aExtendMode = EXTEND_CLAMP) const;
 
+  virtual TemporaryRef<FilterNode> CreateFilter(FilterType aType);
+
   virtual void *GetNativeSurface(NativeSurfaceType aType);
 
   bool Init(cairo_surface_t* aSurface, const IntSize& aSize);
   bool Init(const IntSize& aSize, SurfaceFormat aFormat);
   bool Init(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat);
 
   virtual void SetTransform(const Matrix& aTransform);
 
--- a/gfx/2d/DrawTargetD2D.cpp
+++ b/gfx/2d/DrawTargetD2D.cpp
@@ -10,16 +10,17 @@
 #include "PathD2D.h"
 #include "GradientStopsD2D.h"
 #include "ScaledFontDWrite.h"
 #include "ImageScaling.h"
 #include "Logging.h"
 #include "Tools.h"
 #include <algorithm>
 #include "mozilla/Constants.h"
+#include "FilterNodeSoftware.h"
 
 #include <dwrite.h>
 
 typedef HRESULT (WINAPI*D2D1CreateFactoryFunc)(
     D2D1_FACTORY_TYPE factoryType,
     REFIID iid,
     CONST D2D1_FACTORY_OPTIONS *pFactoryOptions,
     void **factory
@@ -340,16 +341,31 @@ DrawTargetD2D::DrawSurface(SourceSurface
   }
  
   rt->DrawBitmap(bitmap, D2DRect(aDest), aOptions.mAlpha, D2DFilter(aSurfOptions.mFilter), D2DRect(srcRect));
 
   FinalizeRTForOperation(aOptions.mCompositionOp, ColorPattern(Color()), aDest);
 }
 
 void
+DrawTargetD2D::DrawFilter(FilterNode *aNode,
+                          const Rect &aSourceRect,
+                          const Point &aDestPoint,
+                          const DrawOptions &aOptions)
+{
+  if (aNode->GetBackendType() != FILTER_BACKEND_SOFTWARE) {
+    gfxWarning() << "Invalid filter backend passed to DrawTargetD2D!";
+    return;
+  }
+
+  FilterNodeSoftware* filter = static_cast<FilterNodeSoftware*>(aNode);
+  filter->Draw(this, aSourceRect, aDestPoint, aOptions);
+}
+
+void
 DrawTargetD2D::MaskSurface(const Pattern &aSource,
                            SourceSurface *aMask,
                            Point aOffset,
                            const DrawOptions &aOptions)
 {
   RefPtr<ID2D1Bitmap> bitmap;
 
   ID2D1RenderTarget *rt = GetRTForOperation(aOptions.mCompositionOp, ColorPattern(Color()));
@@ -1208,16 +1224,22 @@ DrawTargetD2D::CreateGradientStops(Gradi
   if (FAILED(hr)) {
     gfxWarning() << "Failed to create GradientStopCollection. Code: " << hr;
     return nullptr;
   }
 
   return new GradientStopsD2D(stopCollection);
 }
 
+TemporaryRef<FilterNode>
+DrawTargetD2D::CreateFilter(FilterType aType)
+{
+  return FilterNodeSoftware::Create(aType);
+}
+
 void*
 DrawTargetD2D::GetNativeSurface(NativeSurfaceType aType)
 {
   if (aType != NATIVE_SURFACE_D3D10_TEXTURE) {
     return nullptr;
   }
 
   return mTexture;
--- a/gfx/2d/DrawTargetD2D.h
+++ b/gfx/2d/DrawTargetD2D.h
@@ -51,16 +51,20 @@ public:
   virtual IntSize GetSize() { return mSize; }
 
   virtual void Flush();
   virtual void DrawSurface(SourceSurface *aSurface,
                            const Rect &aDest,
                            const Rect &aSource,
                            const DrawSurfaceOptions &aSurfOptions = DrawSurfaceOptions(),
                            const DrawOptions &aOptions = DrawOptions());
+  virtual void DrawFilter(FilterNode *aNode,
+                          const Rect &aSourceRect,
+                          const Point &aDestPoint,
+                          const DrawOptions &aOptions = DrawOptions());
   virtual void DrawSurfaceWithShadow(SourceSurface *aSurface,
                                      const Point &aDest,
                                      const Color &aColor,
                                      const Point &aOffset,
                                      Float aSigma,
                                      CompositionOp aOperator);
   virtual void ClearRect(const Rect &aRect);
   virtual void MaskSurface(const Pattern &aSource,
@@ -118,16 +122,18 @@ public:
 
   virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule aFillRule = FILL_WINDING) const;
 
   virtual TemporaryRef<GradientStops>
     CreateGradientStops(GradientStop *aStops,
                         uint32_t aNumStops,
                         ExtendMode aExtendMode = EXTEND_CLAMP) const;
 
+  virtual TemporaryRef<FilterNode> CreateFilter(FilterType aType);
+
   virtual void *GetNativeSurface(NativeSurfaceType aType);
 
   bool Init(const IntSize &aSize, SurfaceFormat aFormat);
   bool Init(ID3D10Texture2D *aTexture, SurfaceFormat aFormat);
   bool InitD3D10Data();
   uint32_t GetByteSize() const;
   TemporaryRef<ID2D1Layer> GetCachedLayer();
   void PopCachedLayer(ID2D1RenderTarget *aRT);
--- a/gfx/2d/DrawTargetD2D1.cpp
+++ b/gfx/2d/DrawTargetD2D1.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "DrawTargetD2D1.h"
 #include "DrawTargetD2D.h"
+#include "FilterNodeSoftware.h"
 #include "GradientStopsD2D.h"
 #include "SourceSurfaceD2D1.h"
 #include "SourceSurfaceD2D.h"
 #include "RadialGradientEffectD2D1.h"
 
 #include "HelpersD2D.h"
 #include "Tools.h"
 
@@ -101,16 +102,31 @@ DrawTargetD2D1::DrawSurface(SourceSurfac
                         D2D1::BrushProperties(aOptions.mAlpha, D2DMatrix(transform)),
                         byRef(brush));
   mDC->FillRectangle(D2DRect(aDest), brush);
 
   FinalizeDrawing(aOptions.mCompositionOp, ColorPattern(Color()));
 }
 
 void
+DrawTargetD2D1::DrawFilter(FilterNode *aNode,
+                           const Rect &aSourceRect,
+                           const Point &aDestPoint,
+                           const DrawOptions &aOptions)
+{
+  if (aNode->GetBackendType() != FILTER_BACKEND_SOFTWARE) {
+    gfxWarning() << "Invalid filter backend passed to DrawTargetD2D!";
+    return;
+  }
+
+  FilterNodeSoftware* filter = static_cast<FilterNodeSoftware*>(aNode);
+  filter->Draw(this, aSourceRect, aDestPoint, aOptions);
+}
+
+void
 DrawTargetD2D1::DrawSurfaceWithShadow(SourceSurface *aSurface,
                                       const Point &aDest,
                                       const Color &aColor,
                                       const Point &aOffset,
                                       Float aSigma,
                                       CompositionOp aOperator)
 {
   MarkChanged();
@@ -566,16 +582,22 @@ DrawTargetD2D1::CreateGradientStops(Grad
   if (FAILED(hr)) {
     gfxWarning() << *this << ": Failed to create GradientStopCollection. Code: " << hr;
     return nullptr;
   }
 
   return new GradientStopsD2D(stopCollection);
 }
 
+TemporaryRef<FilterNode>
+DrawTargetD2D1::CreateFilter(FilterType aType)
+{
+  return FilterNodeSoftware::Create(aType);
+}
+
 bool
 DrawTargetD2D1::Init(const IntSize &aSize, SurfaceFormat aFormat)
 {
   HRESULT hr;
   
   hr = Factory::GetD2D1Device()->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS, byRef(mDC));
 
   if (FAILED(hr)) {
--- a/gfx/2d/DrawTargetD2D1.h
+++ b/gfx/2d/DrawTargetD2D1.h
@@ -43,16 +43,20 @@ public:
   virtual IntSize GetSize() { return mSize; }
 
   virtual void Flush();
   virtual void DrawSurface(SourceSurface *aSurface,
                            const Rect &aDest,
                            const Rect &aSource,
                            const DrawSurfaceOptions &aSurfOptions,
                            const DrawOptions &aOptions);
+  virtual void DrawFilter(FilterNode *aNode,
+                          const Rect &aSourceRect,
+                          const Point &aDestPoint,
+                          const DrawOptions &aOptions = DrawOptions());
   virtual void DrawSurfaceWithShadow(SourceSurface *aSurface,
                                      const Point &aDest,
                                      const Color &aColor,
                                      const Point &aOffset,
                                      Float aSigma,
                                      CompositionOp aOperator);
   virtual void ClearRect(const Rect &aRect);
   virtual void MaskSurface(const Pattern &aSource,
@@ -109,16 +113,18 @@ public:
 
   virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule aFillRule = FILL_WINDING) const;
 
   virtual TemporaryRef<GradientStops>
     CreateGradientStops(GradientStop *aStops,
                         uint32_t aNumStops,
                         ExtendMode aExtendMode = EXTEND_CLAMP) const;
 
+  virtual TemporaryRef<FilterNode> CreateFilter(FilterType aType);
+
   virtual void *GetNativeSurface(NativeSurfaceType aType) { return nullptr; }
 
   bool Init(const IntSize &aSize, SurfaceFormat aFormat);
   uint32_t GetByteSize() const;
 
   static ID2D1Factory1 *factory();
   static void CleanupD2D();
   static IDWriteFactory *GetDWriteFactory();
--- a/gfx/2d/DrawTargetDual.h
+++ b/gfx/2d/DrawTargetDual.h
@@ -7,16 +7,17 @@
 #define MOZILLA_GFX_DRAWTARGETDUAL_H_
      
 #include <vector>
 #include <sstream>
 
 #include "SourceSurfaceDual.h"
      
 #include "2D.h"
+#include "Filters.h"
      
 namespace mozilla {
 namespace gfx {
      
 #define FORWARD_FUNCTION(funcName) \
   virtual void funcName() { mA->funcName(); mB->funcName(); }
 #define FORWARD_FUNCTION1(funcName, var1Type, var1Name) \
   virtual void funcName(var1Type var1Name) { mA->funcName(var1Name); mB->funcName(var1Name); }
@@ -55,16 +56,25 @@ public:
     mTransform = aTransform;
     mA->SetTransform(aTransform);
     mB->SetTransform(aTransform);
   }
 
   virtual void DrawSurface(SourceSurface *aSurface, const Rect &aDest, const Rect & aSource,
                            const DrawSurfaceOptions &aSurfOptions, const DrawOptions &aOptions);
 
+  virtual void DrawFilter(FilterNode *aNode,
+                          const Rect &aSourceRect,
+                          const Point &aDestPoint,
+                          const DrawOptions &aOptions = DrawOptions())
+  {
+    mA->DrawFilter(aNode, aSourceRect, aDestPoint, aOptions);
+    mB->DrawFilter(aNode, aSourceRect, aDestPoint, aOptions);
+  }
+
   virtual void MaskSurface(const Pattern &aSource,
                            SourceSurface *aMask,
                            Point aOffset,
                            const DrawOptions &aOptions = DrawOptions());
 
   virtual void DrawSurfaceWithShadow(SourceSurface *aSurface, const Point &aDest,
                                      const Color &aColor, const Point &aOffset,
                                      Float aSigma, CompositionOp aOp);
@@ -121,17 +131,22 @@ public:
      
   virtual TemporaryRef<GradientStops>
     CreateGradientStops(GradientStop *aStops,
                         uint32_t aNumStops,
                         ExtendMode aExtendMode = EXTEND_CLAMP) const
   {
     return mA->CreateGradientStops(aStops, aNumStops, aExtendMode);
   }
-     
+
+  virtual TemporaryRef<FilterNode> CreateFilter(FilterType aType)
+  {
+    return mA->CreateFilter(aType);
+  }
+
   virtual void *GetNativeSurface(NativeSurfaceType aType)
   {
     return nullptr;
   }
 
   virtual bool IsDualDrawTarget()
   {
     return true;