Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / include / core / SkImageFilter.h
1 /*
2  * Copyright 2011 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7
8 #ifndef SkImageFilter_DEFINED
9 #define SkImageFilter_DEFINED
10
11 #include "SkFlattenable.h"
12 #include "SkMatrix.h"
13 #include "SkRect.h"
14 #include "SkTemplates.h"
15
16 class SkBitmap;
17 class SkColorFilter;
18 class SkBaseDevice;
19 struct SkIPoint;
20 class GrEffect;
21 class GrTexture;
22
23 /**
24  *  Base class for image filters. If one is installed in the paint, then
25  *  all drawing occurs as usual, but it is as if the drawing happened into an
26  *  offscreen (before the xfermode is applied). This offscreen bitmap will
27  *  then be handed to the imagefilter, who in turn creates a new bitmap which
28  *  is what will finally be drawn to the device (using the original xfermode).
29  */
30 class SK_API SkImageFilter : public SkFlattenable {
31 public:
32     SK_DECLARE_INST_COUNT(SkImageFilter)
33
34     class CropRect {
35     public:
36         enum CropEdge {
37             kHasLeft_CropEdge   = 0x01,
38             kHasTop_CropEdge    = 0x02,
39             kHasRight_CropEdge  = 0x04,
40             kHasBottom_CropEdge = 0x08,
41             kHasAll_CropEdge    = 0x0F,
42         };
43         CropRect() {}
44         explicit CropRect(const SkRect& rect, uint32_t flags = kHasAll_CropEdge) : fRect(rect), fFlags(flags) {}
45         uint32_t flags() const { return fFlags; }
46         const SkRect& rect() const { return fRect; }
47     private:
48         SkRect fRect;
49         uint32_t fFlags;
50     };
51
52     // This cache maps from (filter's unique ID + CTM + clipBounds + src bitmap generation ID) to
53     // (result, offset).
54     class Cache : public SkRefCnt {
55     public:
56         struct Key;
57         virtual ~Cache() {}
58         static Cache* Create(size_t maxBytes);
59         static Cache* Get();
60         virtual bool get(const Key& key, SkBitmap* result, SkIPoint* offset) const = 0;
61         virtual void set(const Key& key, const SkBitmap& result, const SkIPoint& offset) = 0;
62     };
63
64     class Context {
65     public:
66         Context(const SkMatrix& ctm, const SkIRect& clipBounds, Cache* cache) :
67             fCTM(ctm), fClipBounds(clipBounds), fCache(cache) {
68         }
69         const SkMatrix& ctm() const { return fCTM; }
70         const SkIRect& clipBounds() const { return fClipBounds; }
71         Cache* cache() const { return fCache; }
72     private:
73         SkMatrix fCTM;
74         SkIRect  fClipBounds;
75         Cache* fCache;
76     };
77
78     class Proxy {
79     public:
80         virtual ~Proxy() {};
81
82         virtual SkBaseDevice* createDevice(int width, int height) = 0;
83         // returns true if the proxy can handle this filter natively
84         virtual bool canHandleImageFilter(const SkImageFilter*) = 0;
85         // returns true if the proxy handled the filter itself. if this returns
86         // false then the filter's code will be called.
87         virtual bool filterImage(const SkImageFilter*, const SkBitmap& src,
88                                  const Context&,
89                                  SkBitmap* result, SkIPoint* offset) = 0;
90     };
91
92     /**
93      *  Request a new (result) image to be created from the src image.
94      *  If the src has no pixels (isNull()) then the request just wants to
95      *  receive the config and width/height of the result.
96      *
97      *  The matrix is the current matrix on the canvas.
98      *
99      *  Offset is the amount to translate the resulting image relative to the
100      *  src when it is drawn. This is an out-param.
101      *
102      *  If the result image cannot be created, return false, in which case both
103      *  the result and offset parameters will be ignored by the caller.
104      */
105     bool filterImage(Proxy*, const SkBitmap& src, const Context&,
106                      SkBitmap* result, SkIPoint* offset) const;
107
108     /**
109      *  Given the src bounds of an image, this returns the bounds of the result
110      *  image after the filter has been applied.
111      */
112     bool filterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst) const;
113
114     /**
115      *  Returns true if the filter can be processed on the GPU.  This is most
116      *  often used for multi-pass effects, where intermediate results must be
117      *  rendered to textures.  For single-pass effects, use asNewEffect().
118      *  The default implementation returns asNewEffect(NULL, NULL, SkMatrix::I(),
119      *  SkIRect()).
120      */
121     virtual bool canFilterImageGPU() const;
122
123     /**
124      *  Process this image filter on the GPU.  This is most often used for
125      *  multi-pass effects, where intermediate results must be rendered to
126      *  textures.  For single-pass effects, use asNewEffect().  src is the
127      *  source image for processing, as a texture-backed bitmap.  result is
128      *  the destination bitmap, which should contain a texture-backed pixelref
129      *  on success.  offset is the amount to translate the resulting image
130      *  relative to the src when it is drawn. The default implementation does
131      *  single-pass processing using asNewEffect().
132      */
133     virtual bool filterImageGPU(Proxy*, const SkBitmap& src, const Context&,
134                                 SkBitmap* result, SkIPoint* offset) const;
135
136     /**
137      *  Returns whether this image filter is a color filter and puts the color filter into the
138      *  "filterPtr" parameter if it can. Does nothing otherwise.
139      *  If this returns false, then the filterPtr is unchanged.
140      *  If this returns true, then if filterPtr is not null, it must be set to a ref'd colorfitler
141      *  (i.e. it may not be set to NULL).
142      */
143     virtual bool asColorFilter(SkColorFilter** filterPtr) const;
144
145     /**
146      *  Returns the number of inputs this filter will accept (some inputs can
147      *  be NULL).
148      */
149     int countInputs() const { return fInputCount; }
150
151     /**
152      *  Returns the input filter at a given index, or NULL if no input is
153      *  connected.  The indices used are filter-specific.
154      */
155     SkImageFilter* getInput(int i) const {
156         SkASSERT(i < fInputCount);
157         return fInputs[i];
158     }
159
160     /**
161      *  Returns whether any edges of the crop rect have been set. The crop
162      *  rect is set at construction time, and determines which pixels from the
163      *  input image will be processed. The size of the crop rect should be
164      *  used as the size of the destination image. The origin of this rect
165      *  should be used to offset access to the input images, and should also
166      *  be added to the "offset" parameter in onFilterImage and
167      *  filterImageGPU(). (The latter ensures that the resulting buffer is
168      *  drawn in the correct location.)
169      */
170     bool cropRectIsSet() const { return fCropRect.flags() != 0x0; }
171
172     // Default impl returns union of all input bounds.
173     virtual void computeFastBounds(const SkRect&, SkRect*) const;
174
175 #if SK_SUPPORT_GPU
176     /**
177      * Wrap the given texture in a texture-backed SkBitmap.
178      */
179     static void WrapTexture(GrTexture* texture, int width, int height, SkBitmap* result);
180
181     /**
182      * Recursively evaluate this filter on the GPU. If the filter has no GPU
183      * implementation, it will be processed in software and uploaded to the GPU.
184      */
185     bool getInputResultGPU(SkImageFilter::Proxy* proxy, const SkBitmap& src, const Context&,
186                            SkBitmap* result, SkIPoint* offset) const;
187 #endif
188
189     /**
190      *  Set an external cache to be used for all image filter processing. This
191      *  will replace the default intra-frame cache.
192      */
193     static void SetExternalCache(Cache* cache);
194
195     /**
196      *  Returns the currently-set external cache, or NULL if none is set.
197      */
198     static Cache* GetExternalCache();
199
200     SK_DEFINE_FLATTENABLE_TYPE(SkImageFilter)
201
202 protected:
203     class Common {
204     public:
205         Common() {}
206         ~Common();
207
208         bool unflatten(SkReadBuffer&, int expectedInputs = -1);
209
210         CropRect        cropRect() const { return fCropRect; }
211         int             inputCount() const { return fInputs.count(); }
212         SkImageFilter** inputs() const { return fInputs.get(); }
213         uint32_t        uniqueID() const { return fUniqueID; }
214
215         // If the caller wants a copy of the inputs, call this and it will transfer ownership
216         // of the unflattened input filters to the caller. This is just a short-cut for copying
217         // the inputs, calling ref() on each, and then waiting for Common's destructor to call
218         // unref() on each.
219         void detachInputs(SkImageFilter** inputs);
220
221     private:
222         CropRect fCropRect;
223         // most filters accept at most 2 input-filters
224         SkAutoSTArray<2, SkImageFilter*> fInputs;
225         uint32_t fUniqueID;
226
227         void allocInputs(int count);
228     };
229
230     SkImageFilter(int inputCount, SkImageFilter** inputs, const CropRect* cropRect = NULL);
231
232     virtual ~SkImageFilter();
233
234     /**
235      *  Constructs a new SkImageFilter read from an SkReadBuffer object.
236      *
237      *  @param inputCount    The exact number of inputs expected for this SkImageFilter object.
238      *                       -1 can be used if the filter accepts any number of inputs.
239      *  @param rb            SkReadBuffer object from which the SkImageFilter is read.
240      */
241     explicit SkImageFilter(int inputCount, SkReadBuffer& rb);
242
243     virtual void flatten(SkWriteBuffer& wb) const SK_OVERRIDE;
244
245     /**
246      *  This is the virtual which should be overridden by the derived class
247      *  to perform image filtering.
248      *
249      *  src is the original primitive bitmap. If the filter has a connected
250      *  input, it should recurse on that input and use that in place of src.
251      *
252      *  The matrix is the current matrix on the canvas.
253      *
254      *  Offset is the amount to translate the resulting image relative to the
255      *  src when it is drawn. This is an out-param.
256      *
257      *  If the result image cannot be created, this should false, in which
258      *  case both the result and offset parameters will be ignored by the
259      *  caller.
260      */
261     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
262                                SkBitmap* result, SkIPoint* offset) const;
263     // Given the bounds of the destination rect to be filled in device
264     // coordinates (first parameter), and the CTM, compute (conservatively)
265     // which rect of the source image would be required (third parameter).
266     // Used for clipping and temp-buffer allocations, so the result need not
267     // be exact, but should never be smaller than the real answer. The default
268     // implementation recursively unions all input bounds, or returns false if
269     // no inputs.
270     virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*) const;
271
272     /** Computes source bounds as the src bitmap bounds offset by srcOffset.
273      *  Apply the transformed crop rect to the bounds if any of the
274      *  corresponding edge flags are set. Intersects the result against the
275      *  context's clipBounds, and returns the result in "bounds". If there is
276      *  no intersection, returns false and leaves "bounds" unchanged.
277      */
278     bool applyCropRect(const Context&, const SkBitmap& src, const SkIPoint& srcOffset,
279                        SkIRect* bounds) const;
280
281     /** Same as the above call, except that if the resulting crop rect is not
282      *  entirely contained by the source bitmap's bounds, it creates a new
283      *  bitmap in "result" and pads the edges with transparent black. In that
284      *  case, the srcOffset is modified to be the same as the bounds, since no
285      *  further adjustment is needed by the caller. This version should only
286      *  be used by filters which are not capable of processing a smaller
287      *  source bitmap into a larger destination.
288      */
289     bool applyCropRect(const Context&, Proxy* proxy, const SkBitmap& src, SkIPoint* srcOffset,
290                        SkIRect* bounds, SkBitmap* result) const;
291
292     /**
293      *  Returns true if the filter can be expressed a single-pass
294      *  GrEffect, used to process this filter on the GPU, or false if
295      *  not.
296      *
297      *  If effect is non-NULL, a new GrEffect instance is stored
298      *  in it.  The caller assumes ownership of the stage, and it is up to the
299      *  caller to unref it.
300      *
301      *  The effect can assume its vertexCoords space maps 1-to-1 with texels
302      *  in the texture.  "matrix" is a transformation to apply to filter
303      *  parameters before they are used in the effect. Note that this function
304      *  will be called with (NULL, NULL, SkMatrix::I()) to query for support,
305      *  so returning "true" indicates support for all possible matrices.
306      */
307     virtual bool asNewEffect(GrEffect** effect,
308                              GrTexture*,
309                              const SkMatrix& matrix,
310                              const SkIRect& bounds) const;
311
312 private:
313     bool usesSrcInput() const { return fUsesSrcInput; }
314
315     typedef SkFlattenable INHERITED;
316     int fInputCount;
317     SkImageFilter** fInputs;
318     bool fUsesSrcInput;
319     CropRect fCropRect;
320     uint32_t fUniqueID; // Globally unique
321 };
322
323 #endif