1894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com/*
2894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com * Copyright 2011 Google Inc.
3894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com *
4894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com * Use of this source code is governed by a BSD-style license that can be
5894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com * found in the LICENSE file.
6894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com */
7894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com
8894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com#ifndef SkImageFilter_DEFINED
9894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com#define SkImageFilter_DEFINED
10894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com
11894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com#include "SkFlattenable.h"
124cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org#include "SkMatrix.h"
13194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org#include "SkRect.h"
14894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com
1515356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.comclass SkBitmap;
168d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.orgclass SkColorFilter;
171f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comclass SkBaseDevice;
18c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.comstruct SkIPoint;
190ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.comclass GrEffectRef;
20d0c1a06cb98dd4a009dfa79e37ba6ca23a8c180btomhudson@google.comclass GrTexture;
2115356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com
2215356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com/**
2315356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com *  Base class for image filters. If one is installed in the paint, then
2415356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com *  all drawing occurs as usual, but it is as if the drawing happened into an
2515356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com *  offscreen (before the xfermode is applied). This offscreen bitmap will
2615356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com *  then be handed to the imagefilter, who in turn creates a new bitmap which
2715356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com *  is what will finally be drawn to the device (using the original xfermode).
2815356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com */
2954e01b2ab985e7a7d38109812069d056d128bfa1senorblanco@chromium.orgclass SK_API SkImageFilter : public SkFlattenable {
30894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.compublic:
310456e0b7b85060e9b9597ce414c4c2b19aff4f58robertphillips@google.com    SK_DECLARE_INST_COUNT(SkImageFilter)
320456e0b7b85060e9b9597ce414c4c2b19aff4f58robertphillips@google.com
333f1f2a3a59c43e5bce67ab98e55df45bc7c933a3senorblanco@chromium.org    class CropRect {
343f1f2a3a59c43e5bce67ab98e55df45bc7c933a3senorblanco@chromium.org    public:
35b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org        enum CropEdge {
36b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org            kHasLeft_CropEdge   = 0x01,
37b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org            kHasTop_CropEdge    = 0x02,
38b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org            kHasRight_CropEdge  = 0x04,
39b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org            kHasBottom_CropEdge = 0x08,
40b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org            kHasAll_CropEdge    = 0x0F,
41b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org        };
42b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org        CropRect() {}
43b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org        explicit CropRect(const SkRect& rect, uint32_t flags = kHasAll_CropEdge) : fRect(rect), fFlags(flags) {}
443f1f2a3a59c43e5bce67ab98e55df45bc7c933a3senorblanco@chromium.org        uint32_t flags() const { return fFlags; }
453f1f2a3a59c43e5bce67ab98e55df45bc7c933a3senorblanco@chromium.org        const SkRect& rect() const { return fRect; }
463f1f2a3a59c43e5bce67ab98e55df45bc7c933a3senorblanco@chromium.org    private:
473f1f2a3a59c43e5bce67ab98e55df45bc7c933a3senorblanco@chromium.org        SkRect fRect;
483f1f2a3a59c43e5bce67ab98e55df45bc7c933a3senorblanco@chromium.org        uint32_t fFlags;
49b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org    };
50b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org
51a49c0a540cc3b841174ed84a44ebe6f2d1eb0061senorblanco@chromium.org    class SK_API Cache : public SkRefCnt {
52f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org    public:
53f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org        // By default, we cache only image filters with 2 or more children.
54f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org        static Cache* Create(int minChildren = 2);
55f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org        virtual ~Cache() {}
56f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org        virtual bool get(const SkImageFilter* key, SkBitmap* result, SkIPoint* offset) = 0;
57f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org        virtual void set(const SkImageFilter* key,
58f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org                         const SkBitmap& result, const SkIPoint& offset) = 0;
591a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org        virtual void remove(const SkImageFilter* key) = 0;
60f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org    };
61f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org
624cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org    class Context {
634cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org    public:
64f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org        Context(const SkMatrix& ctm, const SkIRect& clipBounds, Cache* cache) :
65f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org            fCTM(ctm), fClipBounds(clipBounds), fCache(cache) {
664cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org        }
674cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org        const SkMatrix& ctm() const { return fCTM; }
684cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org        const SkIRect& clipBounds() const { return fClipBounds; }
69f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org        Cache* cache() const { return fCache; }
704cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org    private:
714cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org        SkMatrix fCTM;
724cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org        SkIRect  fClipBounds;
73f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org        Cache*   fCache;
744cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org    };
754cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org
7676dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com    class Proxy {
7776dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com    public:
788926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com        virtual ~Proxy() {};
798926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com
801f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com        virtual SkBaseDevice* createDevice(int width, int height) = 0;
818926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com        // returns true if the proxy can handle this filter natively
82ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org        virtual bool canHandleImageFilter(const SkImageFilter*) = 0;
8376dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com        // returns true if the proxy handled the filter itself. if this returns
8476dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com        // false then the filter's code will be called.
85ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org        virtual bool filterImage(const SkImageFilter*, const SkBitmap& src,
864cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org                                 const Context&,
8776dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com                                 SkBitmap* result, SkIPoint* offset) = 0;
8876dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com    };
89894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com
90894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com    /**
91894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com     *  Request a new (result) image to be created from the src image.
92894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com     *  If the src has no pixels (isNull()) then the request just wants to
93894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com     *  receive the config and width/height of the result.
94894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com     *
95894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com     *  The matrix is the current matrix on the canvas.
96894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com     *
97894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com     *  Offset is the amount to translate the resulting image relative to the
986776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org     *  src when it is drawn. This is an out-param.
99894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com     *
100894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com     *  If the result image cannot be created, return false, in which case both
101894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com     *  the result and offset parameters will be ignored by the caller.
102894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com     */
1034cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org    bool filterImage(Proxy*, const SkBitmap& src, const Context&,
104ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org                     SkBitmap* result, SkIPoint* offset) const;
10515356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com
10615356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com    /**
10732d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com     *  Given the src bounds of an image, this returns the bounds of the result
10832d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com     *  image after the filter has been applied.
10932d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com     */
110c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org    bool filterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst) const;
11132d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com
11232d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com    /**
113302cffba86a188373c99833d83392f33e6014542senorblanco@chromium.org     *  Returns true if the filter can be processed on the GPU.  This is most
114302cffba86a188373c99833d83392f33e6014542senorblanco@chromium.org     *  often used for multi-pass effects, where intermediate results must be
1158ea78d83dc4e8243c16eedf8100a3987c54123fabsalomon@google.com     *  rendered to textures.  For single-pass effects, use asNewEffect().
1167938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org     *  The default implementation returns asNewEffect(NULL, NULL, SkMatrix::I(),
1177938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org     *  SkIRect()).
11805054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org     */
119302cffba86a188373c99833d83392f33e6014542senorblanco@chromium.org    virtual bool canFilterImageGPU() const;
12005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org
12105054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org    /**
1223284017a60ea4fc3dc5b95838ba0c301ee1e4e8dskia.committer@gmail.com     *  Process this image filter on the GPU.  This is most often used for
123d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org     *  multi-pass effects, where intermediate results must be rendered to
124d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org     *  textures.  For single-pass effects, use asNewEffect().  src is the
125d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org     *  source image for processing, as a texture-backed bitmap.  result is
126d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org     *  the destination bitmap, which should contain a texture-backed pixelref
127de2e4e8a6422c7d8b5847f038f5c6360b187f7a2skia.committer@gmail.com     *  on success.  offset is the amount to translate the resulting image
1287b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org     *  relative to the src when it is drawn. The default implementation does
1297b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org     *  single-pass processing using asNewEffect().
13005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org     */
1314cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org    virtual bool filterImageGPU(Proxy*, const SkBitmap& src, const Context&,
132ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org                                SkBitmap* result, SkIPoint* offset) const;
13305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org
1348d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org    /**
135a1c511b8704c6c266b90860a4c68f30ca7514f9bsugoi@google.com     *  Returns whether this image filter is a color filter and puts the color filter into the
1364b6d432f1e4ea0a6556dfff1b4d19b69ca005c27sugoi@google.com     *  "filterPtr" parameter if it can. Does nothing otherwise.
1374b6d432f1e4ea0a6556dfff1b4d19b69ca005c27sugoi@google.com     *  If this returns false, then the filterPtr is unchanged.
1384b6d432f1e4ea0a6556dfff1b4d19b69ca005c27sugoi@google.com     *  If this returns true, then if filterPtr is not null, it must be set to a ref'd colorfitler
1394b6d432f1e4ea0a6556dfff1b4d19b69ca005c27sugoi@google.com     *  (i.e. it may not be set to NULL).
1408d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org     */
1414b6d432f1e4ea0a6556dfff1b4d19b69ca005c27sugoi@google.com    virtual bool asColorFilter(SkColorFilter** filterPtr) const;
1428d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org
1438d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org    /**
1448d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org     *  Returns the number of inputs this filter will accept (some inputs can
1458d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org     *  be NULL).
1468d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org     */
1478d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org    int countInputs() const { return fInputCount; }
1488d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org
1498d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org    /**
1508d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org     *  Returns the input filter at a given index, or NULL if no input is
1518d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org     *  connected.  The indices used are filter-specific.
1528d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org     */
1538d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org    SkImageFilter* getInput(int i) const {
1548d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org        SkASSERT(i < fInputCount);
1558d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org        return fInputs[i];
1568d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org    }
1578d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org
158194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org    /**
1593f1f2a3a59c43e5bce67ab98e55df45bc7c933a3senorblanco@chromium.org     *  Returns whether any edges of the crop rect have been set. The crop
1603f1f2a3a59c43e5bce67ab98e55df45bc7c933a3senorblanco@chromium.org     *  rect is set at construction time, and determines which pixels from the
1613f1f2a3a59c43e5bce67ab98e55df45bc7c933a3senorblanco@chromium.org     *  input image will be processed. The size of the crop rect should be
1623f1f2a3a59c43e5bce67ab98e55df45bc7c933a3senorblanco@chromium.org     *  used as the size of the destination image. The origin of this rect
1633f1f2a3a59c43e5bce67ab98e55df45bc7c933a3senorblanco@chromium.org     *  should be used to offset access to the input images, and should also
1643f1f2a3a59c43e5bce67ab98e55df45bc7c933a3senorblanco@chromium.org     *  be added to the "offset" parameter in onFilterImage and
1653f1f2a3a59c43e5bce67ab98e55df45bc7c933a3senorblanco@chromium.org     *  filterImageGPU(). (The latter ensures that the resulting buffer is
1663f1f2a3a59c43e5bce67ab98e55df45bc7c933a3senorblanco@chromium.org     *  drawn in the correct location.)
167194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org     */
1683f1f2a3a59c43e5bce67ab98e55df45bc7c933a3senorblanco@chromium.org    bool cropRectIsSet() const { return fCropRect.flags() != 0x0; }
169194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org
170336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org    // Default impl returns union of all input bounds.
171336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org    virtual void computeFastBounds(const SkRect&, SkRect*) const;
172336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org
1736aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org#ifdef SK_SUPPORT_GPU
1746aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org    /**
1756aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org     * Wrap the given texture in a texture-backed SkBitmap.
1766aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org     */
1776aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org    static void WrapTexture(GrTexture* texture, int width, int height, SkBitmap* result);
1786aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org
1796aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org    /**
1806aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org     * Recursively evaluate this filter on the GPU. If the filter has no GPU
1816aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org     * implementation, it will be processed in software and uploaded to the GPU.
1826aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org     */
1834cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org    bool getInputResultGPU(SkImageFilter::Proxy* proxy, const SkBitmap& src, const Context&,
1846aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org                           SkBitmap* result, SkIPoint* offset) const;
1856aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org#endif
1866aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org
1871a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org    /**
1881a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org     *  Set an external cache to be used for all image filter processing. This
1891a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org     *  will replace the default intra-frame cache.
1901a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org     */
1911a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org    static void SetExternalCache(Cache* cache);
1921a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org
1931a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org    /**
1941a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org     *  Returns the currently-set external cache, or NULL if none is set.
1951a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org     */
1961a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org    static Cache* GetExternalCache();
1971a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org
198c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org    SK_DEFINE_FLATTENABLE_TYPE(SkImageFilter)
199c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org
200894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.comprotected:
201b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org    SkImageFilter(int inputCount, SkImageFilter** inputs, const CropRect* cropRect = NULL);
2029f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org
203c2e8cef4792b478547973d312b26fff4aab7c729senorblanco@chromium.org    // Convenience constructor for 1-input filters.
204b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org    explicit SkImageFilter(SkImageFilter* input, const CropRect* cropRect = NULL);
205c2e8cef4792b478547973d312b26fff4aab7c729senorblanco@chromium.org
206c2e8cef4792b478547973d312b26fff4aab7c729senorblanco@chromium.org    // Convenience constructor for 2-input filters.
207b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org    SkImageFilter(SkImageFilter* input1, SkImageFilter* input2, const CropRect* cropRect = NULL);
2089f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org
2099f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org    virtual ~SkImageFilter();
2109f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org
211c84728d72a47415929464c5cf062300d86a91246commit-bot@chromium.org    /**
2128b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org     *  Constructs a new SkImageFilter read from an SkReadBuffer object.
213c84728d72a47415929464c5cf062300d86a91246commit-bot@chromium.org     *
214c84728d72a47415929464c5cf062300d86a91246commit-bot@chromium.org     *  @param inputCount    The exact number of inputs expected for this SkImageFilter object.
215c84728d72a47415929464c5cf062300d86a91246commit-bot@chromium.org     *                       -1 can be used if the filter accepts any number of inputs.
2168b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org     *  @param rb            SkReadBuffer object from which the SkImageFilter is read.
217c84728d72a47415929464c5cf062300d86a91246commit-bot@chromium.org     */
2188b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org    explicit SkImageFilter(int inputCount, SkReadBuffer& rb);
2199f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org
2208b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org    virtual void flatten(SkWriteBuffer& wb) const SK_OVERRIDE;
22132d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com
2226776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org    /**
2236776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org     *  This is the virtual which should be overridden by the derived class
2246776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org     *  to perform image filtering.
2256776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org     *
2266776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org     *  src is the original primitive bitmap. If the filter has a connected
2276776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org     *  input, it should recurse on that input and use that in place of src.
2286776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org     *
2296776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org     *  The matrix is the current matrix on the canvas.
2306776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org     *
2316776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org     *  Offset is the amount to translate the resulting image relative to the
2326776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org     *  src when it is drawn. This is an out-param.
2336776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org     *
2346776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org     *  If the result image cannot be created, this should false, in which
2356776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org     *  case both the result and offset parameters will be ignored by the
2366776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org     *  caller.
2376776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org     */
2384cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org    virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
239ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org                               SkBitmap* result, SkIPoint* offset) const;
240c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org    // Given the bounds of the destination rect to be filled in device
241c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org    // coordinates (first parameter), and the CTM, compute (conservatively)
242c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org    // which rect of the source image would be required (third parameter).
243c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org    // Used for clipping and temp-buffer allocations, so the result need not
244c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org    // be exact, but should never be smaller than the real answer. The default
245c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org    // implementation recursively unions all input bounds, or returns false if
246c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org    // no inputs.
247c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org    virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*) const;
248894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com
249118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org    /** Computes source bounds as the src bitmap bounds offset by srcOffset.
250118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org     *  Apply the transformed crop rect to the bounds if any of the
251118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org     *  corresponding edge flags are set. Intersects the result against the
252118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org     *  context's clipBounds, and returns the result in "bounds". If there is
253118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org     *  no intersection, returns false and leaves "bounds" unchanged.
254118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org     */
255118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org    bool applyCropRect(const Context&, const SkBitmap& src, const SkIPoint& srcOffset,
256118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org                       SkIRect* bounds) const;
257118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org
258118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org    /** Same as the above call, except that if the resulting crop rect is not
259118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org     *  entirely contained by the source bitmap's bounds, it creates a new
260118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org     *  bitmap in "result" and pads the edges with transparent black. In that
261118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org     *  case, the srcOffset is modified to be the same as the bounds, since no
262118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org     *  further adjustment is needed by the caller. This version should only
263118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org     *  be used by filters which are not capable of processing a smaller
264118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org     *  source bitmap into a larger destination.
265118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org     */
266118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org    bool applyCropRect(const Context&, Proxy* proxy, const SkBitmap& src, SkIPoint* srcOffset,
267118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org                       SkIRect* bounds, SkBitmap* result) const;
268194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org
2691aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org    /**
2701aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org     *  Returns true if the filter can be expressed a single-pass
2711aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org     *  GrEffect, used to process this filter on the GPU, or false if
2721aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org     *  not.
2731aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org     *
2741aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org     *  If effect is non-NULL, a new GrEffect instance is stored
2751aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org     *  in it.  The caller assumes ownership of the stage, and it is up to the
2761aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org     *  caller to unref it.
2771aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org     *
2781aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org     *  The effect can assume its vertexCoords space maps 1-to-1 with texels
2791aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org     *  in the texture.  "matrix" is a transformation to apply to filter
2801aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org     *  parameters before they are used in the effect. Note that this function
2811aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org     *  will be called with (NULL, NULL, SkMatrix::I()) to query for support,
2821aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org     *  so returning "true" indicates support for all possible matrices.
2831aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org     */
2847938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org    virtual bool asNewEffect(GrEffectRef** effect,
2857938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org                             GrTexture*,
2867938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org                             const SkMatrix& matrix,
2877938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org                             const SkIRect& bounds) const;
2881aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org
289894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.comprivate:
29054e01b2ab985e7a7d38109812069d056d128bfa1senorblanco@chromium.org    typedef SkFlattenable INHERITED;
2918d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org    int fInputCount;
2929f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org    SkImageFilter** fInputs;
293b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org    CropRect fCropRect;
294894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com};
295894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com
296894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com#endif
297