Skia
2DGraphicsLibrary
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 "../private/SkTArray.h"
12 #include "../private/SkTemplates.h"
13 #include "../private/SkMutex.h"
14 #include "SkColorSpace.h"
15 #include "SkFilterQuality.h"
16 #include "SkFlattenable.h"
17 #include "SkMatrix.h"
18 #include "SkRect.h"
19 
20 class GrContext;
22 class SkColorFilter;
23 struct SkIPoint;
24 class SkSpecialImage;
25 class SkImageFilterCache;
26 struct SkImageFilterCacheKey;
27 
35 class SK_API SkImageFilter : public SkFlattenable {
36 public:
37  class Context {
38  public:
39  Context(const SkMatrix& ctm, const SkIRect& clipBounds, SkImageFilterCache* cache)
40  : fCTM(ctm)
41  , fClipBounds(clipBounds)
42  , fCache(cache)
43  {}
44 
45  const SkMatrix& ctm() const { return fCTM; }
46  const SkIRect& clipBounds() const { return fClipBounds; }
47  SkImageFilterCache* cache() const { return fCache; }
48 
49  private:
50  SkMatrix fCTM;
51  SkIRect fClipBounds;
52  SkImageFilterCache* fCache;
53  };
54 
55  class CropRect {
56  public:
57  enum CropEdge {
58  kHasLeft_CropEdge = 0x01,
59  kHasTop_CropEdge = 0x02,
60  kHasWidth_CropEdge = 0x04,
61  kHasHeight_CropEdge = 0x08,
62  kHasAll_CropEdge = 0x0F,
63  };
64  CropRect() {}
65  explicit CropRect(const SkRect& rect, uint32_t flags = kHasAll_CropEdge)
66  : fRect(rect), fFlags(flags) {}
67  uint32_t flags() const { return fFlags; }
68  const SkRect& rect() const { return fRect; }
69 #ifndef SK_IGNORE_TO_STRING
70  void toString(SkString* str) const;
71 #endif
72 
83  void applyTo(const SkIRect& imageBounds, const SkMatrix&, bool embiggen,
84  SkIRect* cropped) const;
85 
86  private:
87  SkRect fRect;
88  uint32_t fFlags;
89  };
90 
91  enum TileUsage {
94  };
95 
112  sk_sp<SkSpecialImage> filterImage(SkSpecialImage* src, const Context&, SkIPoint* offset) const;
113 
114  enum MapDirection {
115  kForward_MapDirection,
116  kReverse_MapDirection
117  };
129  SkIRect filterBounds(const SkIRect& src, const SkMatrix& ctm,
130  MapDirection = kReverse_MapDirection) const;
131 
132 #if SK_SUPPORT_GPU
133  static sk_sp<SkSpecialImage> DrawWithFP(GrContext* context,
135  const SkIRect& bounds,
136  sk_sp<SkColorSpace> colorSpace);
137 #endif
138 
146  bool isColorFilterNode(SkColorFilter** filterPtr) const {
147  return this->onIsColorFilterNode(filterPtr);
148  }
149 
150  // DEPRECATED : use isColorFilterNode() instead
151  bool asColorFilter(SkColorFilter** filterPtr) const {
152  return this->isColorFilterNode(filterPtr);
153  }
154 
155  static sk_sp<SkImageFilter> MakeBlur(SkScalar sigmaX, SkScalar sigmaY,
156  sk_sp<SkImageFilter> input,
157  const CropRect* cropRect = nullptr);
158 
164  bool asAColorFilter(SkColorFilter** filterPtr) const;
165 
170  int countInputs() const { return fInputs.count(); }
171 
176  SkImageFilter* getInput(int i) const {
177  SkASSERT(i < fInputs.count());
178  return fInputs[i].get();
179  }
180 
190  bool cropRectIsSet() const { return fCropRect.flags() != 0x0; }
191 
192  CropRect getCropRect() const { return fCropRect; }
193 
194  // Default impl returns union of all input bounds.
195  virtual SkRect computeFastBounds(const SkRect&) const;
196 
197  // Can this filter DAG compute the resulting bounds of an object-space rectangle?
198  bool canComputeFastBounds() const;
199 
204  sk_sp<SkImageFilter> makeWithLocalMatrix(const SkMatrix&) const;
205 
206 #ifdef SK_SUPPORT_LEGACY_IMAGEFILTER_PTR
207  SkImageFilter* newWithLocalMatrix(const SkMatrix& matrix) const {
208  return this->makeWithLocalMatrix(matrix).release();
209  }
210 #endif
211 
217  bool canHandleComplexCTM() const;
218 
222  static sk_sp<SkImageFilter> MakeMatrixFilter(const SkMatrix& matrix,
223  SkFilterQuality quality,
224  sk_sp<SkImageFilter> input);
225 
226 #ifdef SK_SUPPORT_LEGACY_IMAGEFILTER_PTR
227  static SkImageFilter* CreateMatrixFilter(const SkMatrix& matrix,
228  SkFilterQuality filterQuality,
229  SkImageFilter* input = nullptr) {
230  return MakeMatrixFilter(matrix, filterQuality, sk_ref_sp<SkImageFilter>(input)).release();
231  }
232 #endif
233 
234  SK_TO_STRING_PUREVIRT()
235  SK_DEFINE_FLATTENABLE_TYPE(SkImageFilter)
236  SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
237 
238 protected:
239  class Common {
240  public:
249  bool unflatten(SkReadBuffer&, int expectedInputs);
250 
251  const CropRect& cropRect() const { return fCropRect; }
252  int inputCount() const { return fInputs.count(); }
253  sk_sp<SkImageFilter>* inputs() const { return fInputs.get(); }
254 
255  sk_sp<SkImageFilter> getInput(int index) const { return fInputs[index]; }
256 
257  private:
258  CropRect fCropRect;
259  // most filters accept at most 2 input-filters
260  SkAutoSTArray<2, sk_sp<SkImageFilter>> fInputs;
261 
262  void allocInputs(int count);
263  };
264 
265  SkImageFilter(sk_sp<SkImageFilter>* inputs, int inputCount, const CropRect* cropRect);
266 
267  virtual ~SkImageFilter();
268 
276  explicit SkImageFilter(int inputCount, SkReadBuffer& rb);
277 
278  void flatten(SkWriteBuffer&) const override;
279 
299  virtual sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* src, const Context&,
300  SkIPoint* offset) const = 0;
301 
313  virtual SkIRect onFilterBounds(const SkIRect&, const SkMatrix&, MapDirection) const;
314 
328  virtual SkIRect onFilterNodeBounds(const SkIRect&, const SkMatrix&, MapDirection) const;
329 
330  // Helper function which invokes filter processing on the input at the
331  // specified "index". If the input is null, it returns "src" and leaves
332  // "offset" untouched. If the input is non-null, it
333  // calls filterImage() on that input, and returns the result.
334  sk_sp<SkSpecialImage> filterInput(int index,
335  SkSpecialImage* src,
336  const Context&,
337  SkIPoint* offset) const;
338 
343  virtual bool onIsColorFilterNode(SkColorFilter** /*filterPtr*/) const {
344  return false;
345  }
346 
351  virtual bool onCanHandleComplexCTM() const { return false; }
352 
361  bool applyCropRect(const Context&, const SkIRect& srcBounds, SkIRect* dstBounds) const;
362 
372  sk_sp<SkSpecialImage> applyCropRect(const Context&, SkSpecialImage* src, SkIPoint* srcOffset,
373  SkIRect* bounds) const;
374 
381  Context mapContext(const Context& ctx) const;
382 
383 private:
384  friend class SkGraphics;
385  static void PurgeCache();
386 
387  void init(sk_sp<SkImageFilter>* inputs, int inputCount, const CropRect* cropRect);
388 
389  bool usesSrcInput() const { return fUsesSrcInput; }
390  virtual bool affectsTransparentBlack() const { return false; }
391 
392  SkAutoSTArray<2, sk_sp<SkImageFilter>> fInputs;
393 
394  bool fUsesSrcInput;
395  CropRect fCropRect;
396  uint32_t fUniqueID; // Globally unique
397  mutable SkTArray<SkImageFilterCacheKey> fCacheKeys;
398  mutable SkMutex fMutex;
399  typedef SkFlattenable INHERITED;
400 };
401 
405 #define SK_IMAGEFILTER_UNFLATTEN_COMMON(localVar, expectedCount) \
406  Common localVar; \
407  do { \
408  if (!localVar.unflatten(buffer, expectedCount)) { \
409  return NULL; \
410  } \
411  } while (0)
412 
413 #endif
Definition: SkImageFilter.h:55
Provides custom fragment shader code.
Definition: GrFragmentProcessor.h:24
ColorFilters are optional objects in the drawing pipeline.
Definition: SkColorFilter.h:29
int countInputs() const
Returns the number of inputs this filter will accept (some inputs can be NULL).
Definition: SkImageFilter.h:170
bool isColorFilterNode(SkColorFilter **filterPtr) const
Returns whether this image filter is a color filter and puts the color filter into the "filterPtr" pa...
Definition: SkImageFilter.h:146
The SkMatrix class holds a 3x3 matrix for transforming coordinates.
Definition: SkMatrix.h:26
virtual bool onIsColorFilterNode(SkColorFilter **) const
Return true (and return a ref'd colorfilter) if this node in the DAG is just a colorfilter w/o CropRe...
Definition: SkImageFilter.h:343
SkFlattenable is the base class for objects that need to be flattened into a data stream for either t...
Definition: SkFlattenable.h:70
virtual bool onCanHandleComplexCTM() const
Override this to describe the behavior of your subclass - as a leaf node.
Definition: SkImageFilter.h:351
Base class for image filters.
Definition: SkImageFilter.h:35
Shared pointer class to wrap classes that support a ref()/unref() interface.
Definition: SkRefCnt.h:258
Definition: GrContext.h:48
TileUsage
Definition: SkImageFilter.h:91
the created device will never be drawn tiled
Definition: SkImageFilter.h:93
SkImageFilter * getInput(int i) const
Returns the input filter at a given index, or NULL if no input is connected.
Definition: SkImageFilter.h:176
Definition: SkImageFilter.h:239
Definition: SkWriteBuffer.h:26
the created device may be drawn tiled
Definition: SkImageFilter.h:92
Definition: SkRect.h:390
virtual void flatten(SkWriteBuffer &) const
Override this if your subclass needs to record data that it will need to recreate itself from its Cre...
Definition: SkFlattenable.h:117
bool cropRectIsSet() const
Returns whether any edges of the crop rect have been set.
Definition: SkImageFilter.h:190
Definition: SkImageFilter.h:37
SkIRect holds four 32 bit integer coordinates for a rectangle.
Definition: SkRect.h:20
Definition: SkGraphics.h:17
SkIPoint holds two 32 bit integer coordinates.
Definition: SkPoint.h:40
Light weight class for managing strings.
Definition: SkString.h:121