Implement SkXfermode image filter. This required changing the signature of SkXfermode::asNewEffectOrCoeffs(), to add an optional background texture.

For the raster path, we do a straightforward 2-pass method: draw background, then composite the foreground over it.

For the GPU path, if the xfermode can be expressed as an effect, we build an effect with the background texture incorporated, then do a single-pass draw fetching both foreground and background textures, and compositing to the result. If the xfermode is expressed as src/dst coefficients, we do a 2-pass draw as in the raster path and use fixed-function blending.

R=bsalomon@google.com, reed@google.com

Review URL: https://codereview.chromium.org/16125008

git-svn-id: http://skia.googlecode.com/svn/trunk/include@9373 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/core/SkXfermode.h b/core/SkXfermode.h
index f960e14..03ca101 100644
--- a/core/SkXfermode.h
+++ b/core/SkXfermode.h
@@ -15,6 +15,7 @@
 
 class GrContext;
 class GrEffectRef;
+class GrTexture;
 class SkString;
 
 /** \class SkXfermode
@@ -197,12 +198,16 @@
         it and own a ref to it. Since the xfermode may or may not assign *effect, the caller should
         set *effect to NULL beforehand. If the function returns true and *effect is NULL then the
         src and dst coeffs will be applied to the draw. When *effect is non-NULL the coeffs are
-        ignored.
+        ignored. background specifies the texture to use as the background for compositing, and
+        should be accessed in the effect's fragment shader. If NULL, the effect should request
+        access to destination color (setWillReadDstColor()), and use that in the fragment shader
+        (builder->dstColor()).
      */
     virtual bool asNewEffectOrCoeff(GrContext*,
                                     GrEffectRef** effect,
                                     Coeff* src,
-                                    Coeff* dst) const;
+                                    Coeff* dst,
+                                    GrTexture* background = NULL) const;
 
     /**
      *  The same as calling xfermode->asNewEffect(...), except that this also checks if the xfermode
@@ -212,7 +217,8 @@
                                    GrContext*,
                                    GrEffectRef** effect,
                                    Coeff* src,
-                                   Coeff* dst);
+                                   Coeff* dst,
+                                   GrTexture* background = NULL);
 
     SkDEVCODE(virtual void toString(SkString* str) const = 0;)
     SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
diff --git a/effects/SkXfermodeImageFilter.h b/effects/SkXfermodeImageFilter.h
new file mode 100644
index 0000000..ec7ce87
--- /dev/null
+++ b/effects/SkXfermodeImageFilter.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkXfermodeImageFilter_DEFINED
+#define SkXfermodeImageFilter_DEFINED
+
+#include "SkImageFilter.h"
+
+class SkBitmap;
+class SkXfermode;
+
+class SK_API SkXfermodeImageFilter : public SkImageFilter {
+    /**
+     * This filter takes an xfermode, and uses it to composite the foreground
+     * over the background.  If foreground or background is NULL, the input
+     * bitmap (src) is used instead.
+      */
+
+public:
+    SkXfermodeImageFilter(SkXfermode* mode, SkImageFilter* background, SkImageFilter* foreground = NULL);
+
+    virtual ~SkXfermodeImageFilter();
+
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkXfermodeImageFilter)
+
+    virtual bool onFilterImage(Proxy* proxy,
+                               const SkBitmap& src,
+                               const SkMatrix& ctm,
+                               SkBitmap* dst,
+                               SkIPoint* offset) SK_OVERRIDE;
+#if SK_SUPPORT_GPU
+    virtual bool canFilterImageGPU() const SK_OVERRIDE { return true; }
+    virtual bool filterImageGPU(Proxy* proxy, const SkBitmap& src, SkBitmap* result) SK_OVERRIDE;
+#endif
+
+protected:
+    explicit SkXfermodeImageFilter(SkFlattenableReadBuffer& buffer);
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
+
+private:
+    SkXfermode* fMode;
+    typedef SkImageFilter INHERITED;
+};
+
+#endif