Skia
2DGraphicsLibrary
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SkShader.h
1 /*
2  * Copyright 2006 The Android Open Source Project
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 SkShader_DEFINED
9 #define SkShader_DEFINED
10 
11 #include "SkBitmap.h"
12 #include "SkFlattenable.h"
13 #include "SkImageInfo.h"
14 #include "SkMask.h"
15 #include "SkMatrix.h"
16 #include "SkPaint.h"
17 #include "../gpu/GrColor.h"
18 
19 class SkColorFilter;
20 class SkColorSpace;
21 class SkImage;
22 class SkPath;
23 class SkPicture;
24 class SkXfermode;
25 class GrContext;
27 
38 class SK_API SkShader : public SkFlattenable {
39 public:
40  SkShader(const SkMatrix* localMatrix = NULL);
41  virtual ~SkShader();
42 
49  const SkMatrix& getLocalMatrix() const { return fLocalMatrix; }
50 
51  enum TileMode {
56 
59 
64 
65 #if 0
66 
67  kDecal_TileMode,
68 #endif
69  };
70 
71  enum {
72  kTileModeCount = kMirror_TileMode + 1
73  };
74 
75  // override these in your subclass
76 
77  enum Flags {
79  kOpaqueAlpha_Flag = 1 << 0,
80 
86  kConstInY32_Flag = 1 << 1,
87 
90  kPrefers4f_Flag = 1 << 2,
91  };
92 
99  virtual bool isOpaque() const { return false; }
100 
104  struct ContextRec {
105  enum DstType {
106  kPMColor_DstType, // clients prefer shading into PMColor dest
107  kPM4f_DstType, // clients prefer shading into PM4f dest
108  };
109 
110  ContextRec(const SkPaint& paint, const SkMatrix& matrix, const SkMatrix* localM,
111  DstType dstType)
112  : fPaint(&paint)
113  , fMatrix(&matrix)
114  , fLocalMatrix(localM)
115  , fPreferredDstType(dstType) {}
116 
117  const SkPaint* fPaint; // the current paint associated with the draw
118  const SkMatrix* fMatrix; // the current matrix in the canvas
119  const SkMatrix* fLocalMatrix; // optional local matrix
120  const DstType fPreferredDstType; // the "natural" client dest type
121  };
122 
123  class Context : public ::SkNoncopyable {
124  public:
125  Context(const SkShader& shader, const ContextRec&);
126 
127  virtual ~Context();
128 
136  virtual uint32_t getFlags() const { return 0; }
137 
143  virtual void shadeSpan(int x, int y, SkPMColor[], int count) = 0;
144 
145  virtual void shadeSpan4f(int x, int y, SkPM4f[], int count);
146 
147  struct BlitState;
148  typedef void (*BlitBW)(BlitState*,
149  int x, int y, const SkPixmap&, int count);
150  typedef void (*BlitAA)(BlitState*,
151  int x, int y, const SkPixmap&, int count, const SkAlpha[]);
152 
153  struct BlitState {
154  // inputs
155  Context* fCtx;
156  SkXfermode* fXfer;
157 
158  // outputs
159  enum { N = 2 };
160  void* fStorage[N];
161  BlitBW fBlitBW;
162  BlitAA fBlitAA;
163  };
164 
165  // Returns true if one or more of the blitprocs are set in the BlitState
166  bool chooseBlitProcs(const SkImageInfo& info, BlitState* state) {
167  state->fBlitBW = nullptr;
168  state->fBlitAA = nullptr;
169  if (this->onChooseBlitProcs(info, state)) {
170  SkASSERT(state->fBlitBW || state->fBlitAA);
171  return true;
172  }
173  return false;
174  }
175 
180  typedef void (*ShadeProc)(const void* ctx, int x, int y, SkPMColor[], int count);
181  virtual ShadeProc asAShadeProc(void** ctx);
182 
188  virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count);
189 
190  // Notification from blitter::blitMask in case we need to see the non-alpha channels
191  virtual void set3DMask(const SkMask*) {}
192 
193  protected:
194  // Reference to shader, so we don't have to dupe information.
195  const SkShader& fShader;
196 
197  enum MatrixClass {
198  kLinear_MatrixClass, // no perspective
199  kFixedStepInX_MatrixClass, // fast perspective, need to call fixedStepInX() each
200  // scanline
201  kPerspective_MatrixClass // slow perspective, need to mappoints each pixel
202  };
203  static MatrixClass ComputeMatrixClass(const SkMatrix&);
204 
205  uint8_t getPaintAlpha() const { return fPaintAlpha; }
206  const SkMatrix& getTotalInverse() const { return fTotalInverse; }
207  MatrixClass getInverseClass() const { return (MatrixClass)fTotalInverseClass; }
208  const SkMatrix& getCTM() const { return fCTM; }
209 
210  virtual bool onChooseBlitProcs(const SkImageInfo&, BlitState*) { return false; }
211 
212  private:
213  SkMatrix fCTM;
214  SkMatrix fTotalInverse;
215  uint8_t fPaintAlpha;
216  uint8_t fTotalInverseClass;
217 
218  typedef SkNoncopyable INHERITED;
219  };
220 
225  Context* createContext(const ContextRec&, void* storage) const;
226 
230  size_t contextSize(const ContextRec&) const;
231 
237  bool isABitmap(SkBitmap* outTexture, SkMatrix* outMatrix, TileMode xy[2]) const {
238  return this->onIsABitmap(outTexture, outMatrix, xy);
239  }
240 
241  bool isABitmap() const {
242  return this->isABitmap(nullptr, nullptr, nullptr);
243  }
244 
249  SkImage* isAImage(SkMatrix* localMatrix, TileMode xy[2]) const {
250  return this->onIsAImage(localMatrix, xy);
251  }
252 
253  bool isAImage() const {
254  return this->isAImage(nullptr, nullptr) != nullptr;
255  }
256 
287  kNone_GradientType,
288  kColor_GradientType,
289  kLinear_GradientType,
290  kRadial_GradientType,
291  kSweep_GradientType,
292  kConical_GradientType,
293  kLast_GradientType = kConical_GradientType
294  };
295 
296  struct GradientInfo {
298  // of fColors/fColorOffsets on input, and
299  // actual number of colors/offsets on
300  // output.
302  SkScalar* fColorOffsets;
303  SkPoint fPoint[2];
304  SkScalar fRadius[2];
306  uint32_t fGradientFlags;
307  };
308 
309  virtual GradientType asAGradient(GradientInfo* info) const;
310 
318  struct ComposeRec {
319  const SkShader* fShaderA;
320  const SkShader* fShaderB;
321  const SkXfermode* fMode;
322  };
323 
324  virtual bool asACompose(ComposeRec*) const { return false; }
325 
326 #if SK_SUPPORT_GPU
327  struct AsFPArgs {
328  AsFPArgs(GrContext* context,
329  const SkMatrix* viewMatrix,
330  const SkMatrix* localMatrix,
331  SkFilterQuality filterQuality,
332  SkColorSpace* dstColorSpace,
333  SkSourceGammaTreatment gammaTreatment)
334  : fContext(context)
335  , fViewMatrix(viewMatrix)
336  , fLocalMatrix(localMatrix)
337  , fFilterQuality(filterQuality)
338  , fDstColorSpace(dstColorSpace)
339  , fGammaTreatment(gammaTreatment) {}
340 
341  GrContext* fContext;
342  const SkMatrix* fViewMatrix;
343  const SkMatrix* fLocalMatrix;
344  SkFilterQuality fFilterQuality;
345  SkColorSpace* fDstColorSpace;
346  SkSourceGammaTreatment fGammaTreatment;
347  };
348 
362  virtual sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const;
363 #endif
364 
373  bool asLuminanceColor(SkColor*) const;
374 
375 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
376 
380  virtual bool asACustomShader(void** /* customData */) const { return false; }
381 #endif
382 
384  // Methods to create combinations or variants of shaders
385 
390  sk_sp<SkShader> makeWithLocalMatrix(const SkMatrix&) const;
391 
396  sk_sp<SkShader> makeWithColorFilter(sk_sp<SkColorFilter>) const;
397 
399  // Factory methods for stock shaders
400 
404  static sk_sp<SkShader> MakeEmptyShader();
405 
410  static sk_sp<SkShader> MakeColorShader(SkColor);
411 
418  static sk_sp<SkShader> MakeColorShader(const SkColor4f&, sk_sp<SkColorSpace>);
419 
420  static sk_sp<SkShader> MakeComposeShader(sk_sp<SkShader> dst, sk_sp<SkShader> src,
422 
423 #ifdef SK_SUPPORT_LEGACY_CREATESHADER_PTR
424  static SkShader* CreateEmptyShader() { return MakeEmptyShader().release(); }
425  static SkShader* CreateColorShader(SkColor c) { return MakeColorShader(c).release(); }
426  static SkShader* CreateBitmapShader(const SkBitmap& src, TileMode tmx, TileMode tmy,
427  const SkMatrix* localMatrix = nullptr) {
428  return MakeBitmapShader(src, tmx, tmy, localMatrix).release();
429  }
430  static SkShader* CreateComposeShader(SkShader* dst, SkShader* src, SkXfermode::Mode mode);
431  static SkShader* CreateComposeShader(SkShader* dst, SkShader* src, SkXfermode* xfer);
432  static SkShader* CreatePictureShader(const SkPicture* src, TileMode tmx, TileMode tmy,
433  const SkMatrix* localMatrix, const SkRect* tile);
434 
435  SkShader* newWithLocalMatrix(const SkMatrix& matrix) const {
436  return this->makeWithLocalMatrix(matrix).release();
437  }
438  SkShader* newWithColorFilter(SkColorFilter* filter) const;
439 #endif
440 
448  static sk_sp<SkShader> MakeComposeShader(sk_sp<SkShader> dst, sk_sp<SkShader> src,
449  sk_sp<SkXfermode> xfer);
450 #ifdef SK_SUPPORT_LEGACY_XFERMODE_PTR
451  static sk_sp<SkShader> MakeComposeShader(sk_sp<SkShader> dst, sk_sp<SkShader> src,
452  SkXfermode* xfer);
453 #endif
454 
469  static sk_sp<SkShader> MakeBitmapShader(const SkBitmap& src, TileMode tmx, TileMode tmy,
470  const SkMatrix* localMatrix = nullptr);
471 
472  // NOTE: You can create an SkImage Shader with SkImage::newShader().
473 
488  static sk_sp<SkShader> MakePictureShader(sk_sp<SkPicture> src, TileMode tmx, TileMode tmy,
489  const SkMatrix* localMatrix, const SkRect* tile);
490 
498  virtual SkShader* refAsALocalMatrixShader(SkMatrix* localMatrix) const;
499 
500  SK_TO_STRING_VIRT()
501  SK_DEFINE_FLATTENABLE_TYPE(SkShader)
502  SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
503 
504 protected:
505  void flatten(SkWriteBuffer&) const override;
506 
507  bool computeTotalInverse(const ContextRec&, SkMatrix* totalInverse) const;
508 
513  virtual Context* onCreateContext(const ContextRec&, void* storage) const;
514 
519  virtual size_t onContextSize(const ContextRec&) const;
520 
521  virtual bool onAsLuminanceColor(SkColor*) const {
522  return false;
523  }
524 
525  virtual bool onIsABitmap(SkBitmap*, SkMatrix*, TileMode[2]) const {
526  return false;
527  }
528 
529  virtual SkImage* onIsAImage(SkMatrix*, TileMode[2]) const {
530  return nullptr;
531  }
532 
533 private:
534  // This is essentially const, but not officially so it can be modified in
535  // constructors.
536  SkMatrix fLocalMatrix;
537 
538  // So the SkLocalMatrixShader can whack fLocalMatrix in its SkReadBuffer constructor.
539  friend class SkLocalMatrixShader;
540  friend class SkBitmapProcLegacyShader; // for computeTotalInverse()
541 
542  typedef SkFlattenable INHERITED;
543 };
544 
545 #endif
Flags
Definition: SkShader.h:77
If the shader subclass is composed of two shaders, return true, and if rec is not NULL...
Definition: SkShader.h:318
TileMode fTileMode
The tile mode used.
Definition: SkShader.h:305
Provides custom fragment shader code.
Definition: GrFragmentProcessor.h:24
Definition: SkColorSpace.h:16
The SkPath class encapsulates compound (multiple contour) geometric paths consisting of straight line...
Definition: SkPath.h:27
Describe an image's dimensions and pixel type.
Definition: SkImageInfo.h:181
SkImage * isAImage(SkMatrix *localMatrix, TileMode xy[2]) const
Iff this shader is backed by a single SkImage, return its ptr (the caller must ref this if they want ...
Definition: SkShader.h:249
Mode
List of predefined xfermodes.
Definition: SkXfermode.h:71
Definition: SkShader.h:327
Shaders specify the source color(s) for what is being drawn.
Definition: SkShader.h:38
ColorFilters are optional objects in the drawing pipeline.
Definition: SkColorFilter.h:29
Pairs SkImageInfo with actual pixels and rowbytes.
Definition: SkPixmap.h:23
Definition: SkPoint.h:156
SkColor * fColors
The colors in the gradient.
Definition: SkShader.h:301
The SkMatrix class holds a 3x3 matrix for transforming coordinates.
Definition: SkMatrix.h:26
const SkMatrix & getLocalMatrix() const
Returns the local matrix.
Definition: SkShader.h:49
virtual bool isOpaque() const
Returns true if the shader is guaranteed to produce only opaque colors, subject to the SkPaint using ...
Definition: SkShader.h:99
uint8_t SkAlpha
8-bit type for an alpha value.
Definition: SkColor.h:22
uint32_t fGradientFlags
see SkGradientShader::Flags
Definition: SkShader.h:306
The SkPaint class holds the style and color information about how to draw geometries, text and bitmaps.
Definition: SkPaint.h:46
Definition: SkColor.h:169
An SkPicture records drawing commands made to a canvas to be played back at a later time...
Definition: SkPicture.h:38
SkMask is used to describe alpha bitmaps, either 1bit, 8bit, or the 3-channel 3D format.
Definition: SkMask.h:19
SkXfermode is the base class for objects that are called to implement custom "transfer-modes" in the ...
Definition: SkXfermode.h:34
SkFlattenable is the base class for objects that need to be flattened into a data stream for either t...
Definition: SkFlattenable.h:70
The SkBitmap class specifies a raster bitmap.
Definition: SkBitmap.h:41
Shared pointer class to wrap classes that support a ref()/unref() interface.
Definition: SkRefCnt.h:258
Definition: GrContext.h:48
virtual uint32_t getFlags() const
Called sometimes before drawing with this shader.
Definition: SkShader.h:136
uint32_t SkPMColor
32 bit ARGB color value, premultiplied.
Definition: SkColor.h:147
SkScalar * fColorOffsets
The unit offset for color transitions.
Definition: SkShader.h:302
uint32_t SkColor
32 bit ARGB color value, not premultiplied.
Definition: SkColor.h:28
Definition: SkShader.h:123
int fColorCount
In-out parameter, specifies passed size.
Definition: SkShader.h:297
GradientType
If the shader subclass can be represented as a gradient, asAGradient returns the matching GradientTyp...
Definition: SkShader.h:286
Definition: SkWriteBuffer.h:26
Definition: SkRect.h:390
TileMode
Definition: SkShader.h:51
replicate the edge color if the shader draws outside of its original bounds
Definition: SkShader.h:55
ContextRec acts as a parameter bundle for creating Contexts.
Definition: SkShader.h:104
Definition: SkShader.h:296
Definition: SkShader.h:153
repeat the shader's image horizontally and vertically
Definition: SkShader.h:58
SkImage is an abstraction for drawing a rectagle of pixels, though the particular type of image could...
Definition: SkImage.h:45
repeat the shader's image horizontally and vertically, alternating mirror images so that adjacent ima...
Definition: SkShader.h:63
bool isABitmap(SkBitmap *outTexture, SkMatrix *outMatrix, TileMode xy[2]) const
Returns true if this shader is just a bitmap, and if not null, returns the bitmap, localMatrix, and tilemodes.
Definition: SkShader.h:237