Skia
2DGraphicsLibrary
 All Classes Namespaces 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;
21 class GrFragmentProcessor;
22 class SkColorFilter;
23 class SkColorSpaceXformer;
24 struct SkIPoint;
25 class SkSpecialImage;
26 class SkImageFilterCache;
27 struct SkImageFilterCacheKey;
28 
36 class SK_API SkImageFilter : public SkFlattenable {
37 public:
38  // Extra information about the output of a filter DAG. For now, this is just the color space
39  // (of the original requesting device). This is used when constructing intermediate rendering
40  // surfaces, so that we ensure we land in a surface that's similar/compatible to the final
41  // consumer of the DAG's output.
43  public:
44  explicit OutputProperties(SkColorSpace* colorSpace) : fColorSpace(colorSpace) {}
45 
46  SkColorSpace* colorSpace() const { return fColorSpace; }
47 
48  private:
49  // This will be a pointer to the device's color space, and our lifetime is bounded by
50  // the device, so we can store a bare pointer.
51  SkColorSpace* fColorSpace;
52  };
53 
54  class Context {
55  public:
56  Context(const SkMatrix& ctm, const SkIRect& clipBounds, SkImageFilterCache* cache,
57  const OutputProperties& outputProperties)
58  : fCTM(ctm)
59  , fClipBounds(clipBounds)
60  , fCache(cache)
61  , fOutputProperties(outputProperties)
62  {}
63 
64  const SkMatrix& ctm() const { return fCTM; }
65  const SkIRect& clipBounds() const { return fClipBounds; }
66  SkImageFilterCache* cache() const { return fCache; }
67  const OutputProperties& outputProperties() const { return fOutputProperties; }
68 
69  private:
70  SkMatrix fCTM;
71  SkIRect fClipBounds;
72  SkImageFilterCache* fCache;
73  OutputProperties fOutputProperties;
74  };
75 
76  class CropRect {
77  public:
78  enum CropEdge {
79  kHasLeft_CropEdge = 0x01,
80  kHasTop_CropEdge = 0x02,
81  kHasWidth_CropEdge = 0x04,
82  kHasHeight_CropEdge = 0x08,
83  kHasAll_CropEdge = 0x0F,
84  };
85  CropRect() {}
86  explicit CropRect(const SkRect& rect, uint32_t flags = kHasAll_CropEdge)
87  : fRect(rect), fFlags(flags) {}
88  uint32_t flags() const { return fFlags; }
89  const SkRect& rect() const { return fRect; }
90 #ifndef SK_IGNORE_TO_STRING
91  void toString(SkString* str) const;
92 #endif
93 
104  void applyTo(const SkIRect& imageBounds, const SkMatrix&, bool embiggen,
105  SkIRect* cropped) const;
106 
107  private:
108  SkRect fRect;
109  uint32_t fFlags;
110  };
111 
112  enum TileUsage {
115  };
116 
133  sk_sp<SkSpecialImage> filterImage(SkSpecialImage* src, const Context&, SkIPoint* offset) const;
134 
135  enum MapDirection {
136  kForward_MapDirection,
137  kReverse_MapDirection
138  };
150  SkIRect filterBounds(const SkIRect& src, const SkMatrix& ctm,
151  MapDirection = kReverse_MapDirection) const;
152 
153 #if SK_SUPPORT_GPU
154  static sk_sp<SkSpecialImage> DrawWithFP(GrContext* context,
156  const SkIRect& bounds,
157  const OutputProperties& outputProperties);
158 #endif
159 
167  bool isColorFilterNode(SkColorFilter** filterPtr) const {
168  return this->onIsColorFilterNode(filterPtr);
169  }
170 
171  // DEPRECATED : use isColorFilterNode() instead
172  bool asColorFilter(SkColorFilter** filterPtr) const {
173  return this->isColorFilterNode(filterPtr);
174  }
175 
181  bool asAColorFilter(SkColorFilter** filterPtr) const;
182 
187  int countInputs() const { return fInputs.count(); }
188 
193  SkImageFilter* getInput(int i) const {
194  SkASSERT(i < fInputs.count());
195  return fInputs[i].get();
196  }
197 
207  bool cropRectIsSet() const { return fCropRect.flags() != 0x0; }
208 
209  CropRect getCropRect() const { return fCropRect; }
210 
211  // Default impl returns union of all input bounds.
212  virtual SkRect computeFastBounds(const SkRect&) const;
213 
214  // Can this filter DAG compute the resulting bounds of an object-space rectangle?
215  bool canComputeFastBounds() const;
216 
221  sk_sp<SkImageFilter> makeWithLocalMatrix(const SkMatrix&) const;
222 
228  bool canHandleComplexCTM() const;
229 
233  static sk_sp<SkImageFilter> MakeMatrixFilter(const SkMatrix& matrix,
234  SkFilterQuality quality,
235  sk_sp<SkImageFilter> input);
236 
237  SK_TO_STRING_PUREVIRT()
238  SK_DEFINE_FLATTENABLE_TYPE(SkImageFilter)
239  SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
240 
241 protected:
242  class Common {
243  public:
252  bool unflatten(SkReadBuffer&, int expectedInputs);
253 
254  const CropRect& cropRect() const { return fCropRect; }
255  int inputCount() const { return fInputs.count(); }
256  sk_sp<SkImageFilter>* inputs() const { return fInputs.get(); }
257 
258  sk_sp<SkImageFilter> getInput(int index) const { return fInputs[index]; }
259 
260  private:
261  CropRect fCropRect;
262  // most filters accept at most 2 input-filters
263  SkAutoSTArray<2, sk_sp<SkImageFilter>> fInputs;
264 
265  void allocInputs(int count);
266  };
267 
268  SkImageFilter(sk_sp<SkImageFilter> const* inputs, int inputCount, const CropRect* cropRect);
269 
270  ~SkImageFilter() override;
271 
279  explicit SkImageFilter(int inputCount, SkReadBuffer& rb);
280 
281  void flatten(SkWriteBuffer&) const override;
282 
283  const CropRect* getCropRectIfSet() const {
284  return this->cropRectIsSet() ? &fCropRect : nullptr;
285  }
286 
306  virtual sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* src, const Context&,
307  SkIPoint* offset) const = 0;
308 
320  virtual SkIRect onFilterBounds(const SkIRect&, const SkMatrix&, MapDirection) const;
321 
335  virtual SkIRect onFilterNodeBounds(const SkIRect&, const SkMatrix&, MapDirection) const;
336 
337  // Helper function which invokes filter processing on the input at the
338  // specified "index". If the input is null, it returns "src" and leaves
339  // "offset" untouched. If the input is non-null, it
340  // calls filterImage() on that input, and returns the result.
341  sk_sp<SkSpecialImage> filterInput(int index,
342  SkSpecialImage* src,
343  const Context&,
344  SkIPoint* offset) const;
345 
350  virtual bool onIsColorFilterNode(SkColorFilter** /*filterPtr*/) const {
351  return false;
352  }
353 
358  virtual bool onCanHandleComplexCTM() const { return false; }
359 
368  bool applyCropRect(const Context&, const SkIRect& srcBounds, SkIRect* dstBounds) const;
369 
379  sk_sp<SkSpecialImage> applyCropRect(const Context&, SkSpecialImage* src, SkIPoint* srcOffset,
380  SkIRect* bounds) const;
381 
388  Context mapContext(const Context& ctx) const;
389 
390 #if SK_SUPPORT_GPU
391 
396  static sk_sp<SkSpecialImage> ImageToColorSpace(SkSpecialImage* src, const OutputProperties&);
397 #endif
398 
402  sk_sp<SkImageFilter> makeColorSpace(SkColorSpaceXformer* xformer) const {
403  return this->onMakeColorSpace(xformer);
404  }
405  virtual sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const = 0;
406 
407 private:
408  // For makeColorSpace().
409  friend class ArithmeticImageFilterImpl;
410  friend class SkAlphaThresholdFilterImpl;
411  friend class SkBlurImageFilterImpl;
412  friend class SkColorFilterImageFilter;
413  friend class SkColorSpaceXformer;
414  friend class SkComposeImageFilter;
415  friend class SkDiffuseLightingImageFilter;
416  friend class SkDisplacementMapEffect;
417  friend class SkDropShadowImageFilter;
418  friend class SkImageSource;
419  friend class SkMagnifierImageFilter;
420  friend class SkMatrixConvolutionImageFilter;
421  friend class SkMatrixImageFilter;
422  friend class SkLocalMatrixImageFilter;
423  friend class SkMergeImageFilter;
424  friend class SkMorphologyImageFilter;
425  friend class SkOffsetImageFilter;
426  friend class SkSpecularLightingImageFilter;
427  friend class SkTileImageFilter;
428  friend class SkXfermodeImageFilter_Base;
429 
430  friend class SkGraphics;
431 
432  static void PurgeCache();
433 
434  void init(sk_sp<SkImageFilter> const* inputs, int inputCount, const CropRect* cropRect);
435 
436  bool usesSrcInput() const { return fUsesSrcInput; }
437  virtual bool affectsTransparentBlack() const { return false; }
438 
439  SkAutoSTArray<2, sk_sp<SkImageFilter>> fInputs;
440 
441  bool fUsesSrcInput;
442  CropRect fCropRect;
443  uint32_t fUniqueID; // Globally unique
444  mutable SkTArray<SkImageFilterCacheKey> fCacheKeys;
445  mutable SkMutex fMutex;
446  typedef SkFlattenable INHERITED;
447 };
448 
452 #define SK_IMAGEFILTER_UNFLATTEN_COMMON(localVar, expectedCount) \
453  Common localVar; \
454  do { \
455  if (!localVar.unflatten(buffer, expectedCount)) { \
456  return NULL; \
457  } \
458  } while (0)
459 
460 #endif
Definition: SkDropShadowImageFilter.h:15
Definition: SkImageFilter.h:76
Definition: SkImageFilter.h:42
Definition: SkColorSpace.h:59
ColorFilters are optional objects in the drawing pipeline.
Definition: SkColorFilter.h:32
int countInputs() const
Returns the number of inputs this filter will accept (some inputs can be NULL).
Definition: SkImageFilter.h:187
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:167
The SkMatrix class holds a 3x3 matrix for transforming coordinates.
Definition: SkMatrix.h:28
Definition: SkMergeImageFilter.h:13
Definition: SkMatrixConvolutionImageFilter.h:24
sk_sp< SkImageFilter > makeColorSpace(SkColorSpaceXformer *xformer) const
Returns an image filter transformed into a new color space via the |xformer|.
Definition: SkImageFilter.h:402
Definition: SkColorFilterImageFilter.h:15
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:350
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:358
Base class for image filters.
Definition: SkImageFilter.h:36
Definition: SkOffsetImageFilter.h:14
Shared pointer class to wrap classes that support a ref()/unref() interface.
Definition: SkRefCnt.h:246
Definition: SkMagnifierImageFilter.h:15
Definition: GrContext.h:47
TileUsage
Definition: SkImageFilter.h:112
Definition: SkTileImageFilter.h:13
the created device will never be drawn tiled
Definition: SkImageFilter.h:114
SkImageFilter * getInput(int i) const
Returns the input filter at a given index, or NULL if no input is connected.
Definition: SkImageFilter.h:193
Definition: SkImageSource.h:14
Definition: SkImageFilter.h:242
Definition: SkWriteBuffer.h:27
the created device may be drawn tiled
Definition: SkImageFilter.h:113
Definition: SkRect.h:404
Definition: SkMorphologyImageFilter.h:16
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:207
Definition: SkComposeImageFilter.h:13
Definition: SkImageFilter.h:54
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
Definition: SkDisplacementMapEffect.h:13