Plumb dst color space in many places, rather than "mode"
[platform/upstream/libSkiaSharp.git] / include / core / 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 "SkFilterQuality.h"
13 #include "SkFlattenable.h"
14 #include "SkImageInfo.h"
15 #include "SkMask.h"
16 #include "SkMatrix.h"
17 #include "SkPaint.h"
18 #include "../gpu/GrColor.h"
19
20 class SkColorFilter;
21 class SkColorSpace;
22 class SkFallbackAlloc;
23 class SkImage;
24 class SkPath;
25 class SkPicture;
26 class SkRasterPipeline;
27 class GrContext;
28 class GrFragmentProcessor;
29
30 /** \class SkShader
31  *
32  *  Shaders specify the source color(s) for what is being drawn. If a paint
33  *  has no shader, then the paint's color is used. If the paint has a
34  *  shader, then the shader's color(s) are use instead, but they are
35  *  modulated by the paint's alpha. This makes it easy to create a shader
36  *  once (e.g. bitmap tiling or gradient) and then change its transparency
37  *  w/o having to modify the original shader... only the paint's alpha needs
38  *  to be modified.
39  */
40 class SK_API SkShader : public SkFlattenable {
41 public:
42     SkShader(const SkMatrix* localMatrix = NULL);
43     virtual ~SkShader();
44
45     /**
46      *  Returns the local matrix.
47      *
48      *  FIXME: This can be incorrect for a Shader with its own local matrix
49      *  that is also wrapped via CreateLocalMatrixShader.
50      */
51     const SkMatrix& getLocalMatrix() const { return fLocalMatrix; }
52
53     enum TileMode {
54         /** replicate the edge color if the shader draws outside of its
55          *  original bounds
56          */
57         kClamp_TileMode,
58
59         /** repeat the shader's image horizontally and vertically */
60         kRepeat_TileMode,
61
62         /** repeat the shader's image horizontally and vertically, alternating
63          *  mirror images so that adjacent images always seam
64          */
65         kMirror_TileMode,
66
67 #if 0
68         /** only draw within the original domain, return 0 everywhere else */
69         kDecal_TileMode,
70 #endif
71     };
72
73     enum {
74         kTileModeCount = kMirror_TileMode + 1
75     };
76
77     // override these in your subclass
78
79     enum Flags {
80         //!< set if all of the colors will be opaque
81         kOpaqueAlpha_Flag = 1 << 0,
82
83         /** set if the spans only vary in X (const in Y).
84             e.g. an Nx1 bitmap that is being tiled in Y, or a linear-gradient
85             that varies from left-to-right. This flag specifies this for
86             shadeSpan().
87          */
88         kConstInY32_Flag = 1 << 1,
89
90         /** hint for the blitter that 4f is the preferred shading mode.
91          */
92         kPrefers4f_Flag  = 1 << 2,
93     };
94
95     /**
96      *  Returns true if the shader is guaranteed to produce only opaque
97      *  colors, subject to the SkPaint using the shader to apply an opaque
98      *  alpha value. Subclasses should override this to allow some
99      *  optimizations.
100      */
101     virtual bool isOpaque() const { return false; }
102
103     /**
104      *  Returns true if the shader is guaranteed to produce only a single color.
105      *  Subclasses can override this to allow loop-hoisting optimization.
106      */
107     virtual bool isConstant() const { return false; }
108
109     /**
110      *  ContextRec acts as a parameter bundle for creating Contexts.
111      */
112     struct ContextRec {
113         enum DstType {
114             kPMColor_DstType, // clients prefer shading into PMColor dest
115             kPM4f_DstType,    // clients prefer shading into PM4f dest
116         };
117
118         ContextRec(const SkPaint& paint, const SkMatrix& matrix, const SkMatrix* localM,
119                    DstType dstType, SkColorSpace* dstColorSpace)
120             : fPaint(&paint)
121             , fMatrix(&matrix)
122             , fLocalMatrix(localM)
123             , fPreferredDstType(dstType)
124             , fDstColorSpace(dstColorSpace) {}
125
126         const SkPaint*  fPaint;            // the current paint associated with the draw
127         const SkMatrix* fMatrix;           // the current matrix in the canvas
128         const SkMatrix* fLocalMatrix;      // optional local matrix
129         const DstType   fPreferredDstType; // the "natural" client dest type
130         SkColorSpace*   fDstColorSpace;    // the color space of the dest surface (if any)
131     };
132
133     class Context : public ::SkNoncopyable {
134     public:
135         Context(const SkShader& shader, const ContextRec&);
136
137         virtual ~Context();
138
139         /**
140          *  Called sometimes before drawing with this shader. Return the type of
141          *  alpha your shader will return. The default implementation returns 0.
142          *  Your subclass should override if it can (even sometimes) report a
143          *  non-zero value, since that will enable various blitters to perform
144          *  faster.
145          */
146         virtual uint32_t getFlags() const { return 0; }
147
148         /**
149          *  Called for each span of the object being drawn. Your subclass should
150          *  set the appropriate colors (with premultiplied alpha) that correspond
151          *  to the specified device coordinates.
152          */
153         virtual void shadeSpan(int x, int y, SkPMColor[], int count) = 0;
154
155         virtual void shadeSpan4f(int x, int y, SkPM4f[], int count);
156
157         struct BlitState;
158         typedef void (*BlitBW)(BlitState*,
159                                int x, int y, const SkPixmap&, int count);
160         typedef void (*BlitAA)(BlitState*,
161                                int x, int y, const SkPixmap&, int count, const SkAlpha[]);
162
163         struct BlitState {
164             // inputs
165             Context*    fCtx;
166             SkBlendMode fMode;
167
168             // outputs
169             enum { N = 2 };
170             void*       fStorage[N];
171             BlitBW      fBlitBW;
172             BlitAA      fBlitAA;
173         };
174
175         // Returns true if one or more of the blitprocs are set in the BlitState
176         bool chooseBlitProcs(const SkImageInfo& info, BlitState* state) {
177             state->fBlitBW = nullptr;
178             state->fBlitAA = nullptr;
179             if (this->onChooseBlitProcs(info, state)) {
180                 SkASSERT(state->fBlitBW || state->fBlitAA);
181                 return true;
182             }
183             return false;
184         }
185
186         /**
187          * The const void* ctx is only const because all the implementations are const.
188          * This can be changed to non-const if a new shade proc needs to change the ctx.
189          */
190         typedef void (*ShadeProc)(const void* ctx, int x, int y, SkPMColor[], int count);
191         virtual ShadeProc asAShadeProc(void** ctx);
192
193         /**
194          *  Similar to shadeSpan, but only returns the alpha-channel for a span.
195          *  The default implementation calls shadeSpan() and then extracts the alpha
196          *  values from the returned colors.
197          */
198         virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count);
199
200         // Notification from blitter::blitMask in case we need to see the non-alpha channels
201         virtual void set3DMask(const SkMask*) {}
202
203     protected:
204         // Reference to shader, so we don't have to dupe information.
205         const SkShader& fShader;
206
207         enum MatrixClass {
208             kLinear_MatrixClass,            // no perspective
209             kFixedStepInX_MatrixClass,      // fast perspective, need to call fixedStepInX() each
210                                             // scanline
211             kPerspective_MatrixClass        // slow perspective, need to mappoints each pixel
212         };
213         static MatrixClass ComputeMatrixClass(const SkMatrix&);
214
215         uint8_t         getPaintAlpha() const { return fPaintAlpha; }
216         const SkMatrix& getTotalInverse() const { return fTotalInverse; }
217         MatrixClass     getInverseClass() const { return (MatrixClass)fTotalInverseClass; }
218         const SkMatrix& getCTM() const { return fCTM; }
219
220         virtual bool onChooseBlitProcs(const SkImageInfo&, BlitState*) { return false; }
221
222     private:
223         SkMatrix    fCTM;
224         SkMatrix    fTotalInverse;
225         uint8_t     fPaintAlpha;
226         uint8_t     fTotalInverseClass;
227
228         typedef SkNoncopyable INHERITED;
229     };
230
231     /**
232      *  Create the actual object that does the shading.
233      *  Size of storage must be >= contextSize.
234      */
235     Context* createContext(const ContextRec&, void* storage) const;
236
237     /**
238      *  Return the size of a Context returned by createContext.
239      */
240     size_t contextSize(const ContextRec&) const;
241
242 #ifdef SK_SUPPORT_LEGACY_SHADER_ISABITMAP
243     /**
244      *  Returns true if this shader is just a bitmap, and if not null, returns the bitmap,
245      *  localMatrix, and tilemodes. If this is not a bitmap, returns false and ignores the
246      *  out-parameters.
247      */
248     bool isABitmap(SkBitmap* outTexture, SkMatrix* outMatrix, TileMode xy[2]) const {
249         return this->onIsABitmap(outTexture, outMatrix, xy);
250     }
251
252     bool isABitmap() const {
253         return this->isABitmap(nullptr, nullptr, nullptr);
254     }
255 #endif
256
257     /**
258      *  Iff this shader is backed by a single SkImage, return its ptr (the caller must ref this
259      *  if they want to keep it longer than the lifetime of the shader). If not, return nullptr.
260      */
261     SkImage* isAImage(SkMatrix* localMatrix, TileMode xy[2]) const {
262         return this->onIsAImage(localMatrix, xy);
263     }
264
265     bool isAImage() const {
266         return this->isAImage(nullptr, nullptr) != nullptr;
267     }
268
269     /**
270      *  If the shader subclass can be represented as a gradient, asAGradient
271      *  returns the matching GradientType enum (or kNone_GradientType if it
272      *  cannot). Also, if info is not null, asAGradient populates info with
273      *  the relevant (see below) parameters for the gradient.  fColorCount
274      *  is both an input and output parameter.  On input, it indicates how
275      *  many entries in fColors and fColorOffsets can be used, if they are
276      *  non-NULL.  After asAGradient has run, fColorCount indicates how
277      *  many color-offset pairs there are in the gradient.  If there is
278      *  insufficient space to store all of the color-offset pairs, fColors
279      *  and fColorOffsets will not be altered.  fColorOffsets specifies
280      *  where on the range of 0 to 1 to transition to the given color.
281      *  The meaning of fPoint and fRadius is dependant on the type of gradient.
282      *
283      *  None:
284      *      info is ignored.
285      *  Color:
286      *      fColorOffsets[0] is meaningless.
287      *  Linear:
288      *      fPoint[0] and fPoint[1] are the end-points of the gradient
289      *  Radial:
290      *      fPoint[0] and fRadius[0] are the center and radius
291      *  Conical:
292      *      fPoint[0] and fRadius[0] are the center and radius of the 1st circle
293      *      fPoint[1] and fRadius[1] are the center and radius of the 2nd circle
294      *  Sweep:
295      *      fPoint[0] is the center of the sweep.
296      */
297
298     enum GradientType {
299         kNone_GradientType,
300         kColor_GradientType,
301         kLinear_GradientType,
302         kRadial_GradientType,
303         kSweep_GradientType,
304         kConical_GradientType,
305         kLast_GradientType = kConical_GradientType
306     };
307
308     struct GradientInfo {
309         int         fColorCount;    //!< In-out parameter, specifies passed size
310                                     //   of fColors/fColorOffsets on input, and
311                                     //   actual number of colors/offsets on
312                                     //   output.
313         SkColor*    fColors;        //!< The colors in the gradient.
314         SkScalar*   fColorOffsets;  //!< The unit offset for color transitions.
315         SkPoint     fPoint[2];      //!< Type specific, see above.
316         SkScalar    fRadius[2];     //!< Type specific, see above.
317         TileMode    fTileMode;      //!< The tile mode used.
318         uint32_t    fGradientFlags; //!< see SkGradientShader::Flags
319     };
320
321     virtual GradientType asAGradient(GradientInfo* info) const;
322
323     /**
324      *  If the shader subclass is composed of two shaders, return true, and if rec is not NULL,
325      *  fill it out with info about the shader.
326      *
327      *  These are bare pointers; the ownership and reference count are unchanged.
328      */
329
330     struct ComposeRec {
331         const SkShader*     fShaderA;
332         const SkShader*     fShaderB;
333         SkBlendMode         fBlendMode;
334     };
335
336     virtual bool asACompose(ComposeRec*) const { return false; }
337
338 #if SK_SUPPORT_GPU
339     struct AsFPArgs {
340         AsFPArgs() {}
341         AsFPArgs(GrContext* context,
342                  const SkMatrix* viewMatrix,
343                  const SkMatrix* localMatrix,
344                  SkFilterQuality filterQuality,
345                  SkColorSpace* dstColorSpace)
346             : fContext(context)
347             , fViewMatrix(viewMatrix)
348             , fLocalMatrix(localMatrix)
349             , fFilterQuality(filterQuality)
350             , fDstColorSpace(dstColorSpace) {}
351
352         GrContext*                    fContext;
353         const SkMatrix*               fViewMatrix;
354         const SkMatrix*               fLocalMatrix;
355         SkFilterQuality               fFilterQuality;
356         SkColorSpace*                 fDstColorSpace;
357     };
358
359     /**
360      *  Returns a GrFragmentProcessor that implements the shader for the GPU backend. NULL is
361      *  returned if there is no GPU implementation.
362      *
363      *  The GPU device does not call SkShader::createContext(), instead we pass the view matrix,
364      *  local matrix, and filter quality directly.
365      *
366      *  The GrContext may be used by the to create textures that are required by the returned
367      *  processor.
368      *
369      *  The returned GrFragmentProcessor should expect an unpremultiplied input color and
370      *  produce a premultiplied output.
371      */
372     virtual sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const;
373 #endif
374
375     /**
376      *  If the shader can represent its "average" luminance in a single color, return true and
377      *  if color is not NULL, return that color. If it cannot, return false and ignore the color
378      *  parameter.
379      *
380      *  Note: if this returns true, the returned color will always be opaque, as only the RGB
381      *  components are used to compute luminance.
382      */
383     bool asLuminanceColor(SkColor*) const;
384
385 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
386     /**
387      *  If the shader is a custom shader which has data the caller might want, call this function
388      *  to get that data.
389      */
390     virtual bool asACustomShader(void** /* customData */) const { return false; }
391 #endif
392
393     //////////////////////////////////////////////////////////////////////////
394     //  Methods to create combinations or variants of shaders
395
396     /**
397      *  Return a shader that will apply the specified localMatrix to this shader.
398      *  The specified matrix will be applied before any matrix associated with this shader.
399      */
400     sk_sp<SkShader> makeWithLocalMatrix(const SkMatrix&) const;
401
402     /**
403      *  Create a new shader that produces the same colors as invoking this shader and then applying
404      *  the colorfilter.
405      */
406     sk_sp<SkShader> makeWithColorFilter(sk_sp<SkColorFilter>) const;
407
408     //////////////////////////////////////////////////////////////////////////
409     //  Factory methods for stock shaders
410
411     /**
412      *  Call this to create a new "empty" shader, that will not draw anything.
413      */
414     static sk_sp<SkShader> MakeEmptyShader();
415
416     /**
417      *  Call this to create a new shader that just draws the specified color. This should always
418      *  draw the same as a paint with this color (and no shader).
419      */
420     static sk_sp<SkShader> MakeColorShader(SkColor);
421
422     /**
423      *  Create a shader that draws the specified color (in the specified colorspace).
424      *
425      *  This works around the limitation that SkPaint::setColor() only takes byte values, and does
426      *  not support specific colorspaces.
427      */
428     static sk_sp<SkShader> MakeColorShader(const SkColor4f&, sk_sp<SkColorSpace>);
429
430     static sk_sp<SkShader> MakeComposeShader(sk_sp<SkShader> dst, sk_sp<SkShader> src, SkBlendMode);
431
432     /** Call this to create a new shader that will draw with the specified bitmap.
433      *
434      *  If the bitmap cannot be used (e.g. has no pixels, or its dimensions
435      *  exceed implementation limits (currently at 64K - 1)) then SkEmptyShader
436      *  may be returned.
437      *
438      *  If the src is kA8_Config then that mask will be colorized using the color on
439      *  the paint.
440      *
441      *  @param src  The bitmap to use inside the shader
442      *  @param tmx  The tiling mode to use when sampling the bitmap in the x-direction.
443      *  @param tmy  The tiling mode to use when sampling the bitmap in the y-direction.
444      *  @return     Returns a new shader object. Note: this function never returns null.
445     */
446     static sk_sp<SkShader> MakeBitmapShader(const SkBitmap& src, TileMode tmx, TileMode tmy,
447                                             const SkMatrix* localMatrix = nullptr);
448
449     // NOTE: You can create an SkImage Shader with SkImage::newShader().
450
451     /** Call this to create a new shader that will draw with the specified picture.
452      *
453      *  @param src  The picture to use inside the shader (if not NULL, its ref count
454      *              is incremented). The SkPicture must not be changed after
455      *              successfully creating a picture shader.
456      *  @param tmx  The tiling mode to use when sampling the bitmap in the x-direction.
457      *  @param tmy  The tiling mode to use when sampling the bitmap in the y-direction.
458      *  @param tile The tile rectangle in picture coordinates: this represents the subset
459      *              (or superset) of the picture used when building a tile. It is not
460      *              affected by localMatrix and does not imply scaling (only translation
461      *              and cropping). If null, the tile rect is considered equal to the picture
462      *              bounds.
463      *  @return     Returns a new shader object. Note: this function never returns null.
464     */
465     static sk_sp<SkShader> MakePictureShader(sk_sp<SkPicture> src, TileMode tmx, TileMode tmy,
466                                              const SkMatrix* localMatrix, const SkRect* tile);
467
468     /**
469      *  If this shader can be represented by another shader + a localMatrix, return that shader and
470      *  the localMatrix. If not, return nullptr and ignore the localMatrix parameter.
471      */
472     virtual sk_sp<SkShader> makeAsALocalMatrixShader(SkMatrix* localMatrix) const;
473
474     SK_TO_STRING_VIRT()
475     SK_DEFINE_FLATTENABLE_TYPE(SkShader)
476     SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
477
478     bool appendStages(SkRasterPipeline*, SkColorSpace*, SkFallbackAlloc*,
479                       const SkMatrix& ctm, const SkPaint&) const;
480
481 protected:
482     void flatten(SkWriteBuffer&) const override;
483
484     bool computeTotalInverse(const ContextRec&, SkMatrix* totalInverse) const;
485
486     /**
487      *  Your subclass must also override contextSize() if it overrides onCreateContext().
488      *  Base class impl returns NULL.
489      */
490     virtual Context* onCreateContext(const ContextRec&, void* storage) const;
491
492     /**
493      *  Override this if your subclass overrides createContext, to return the correct size of
494      *  your subclass' context.
495      */
496     virtual size_t onContextSize(const ContextRec&) const;
497
498     virtual bool onAsLuminanceColor(SkColor*) const {
499         return false;
500     }
501
502 #ifdef SK_SUPPORT_LEGACY_SHADER_ISABITMAP
503     virtual bool onIsABitmap(SkBitmap*, SkMatrix*, TileMode[2]) const {
504         return false;
505     }
506 #endif
507
508     virtual SkImage* onIsAImage(SkMatrix*, TileMode[2]) const {
509         return nullptr;
510     }
511
512     virtual bool onAppendStages(SkRasterPipeline*, SkColorSpace*, SkFallbackAlloc*,
513                                 const SkMatrix&, const SkPaint&) const {
514         return false;
515     }
516
517 private:
518     // This is essentially const, but not officially so it can be modified in
519     // constructors.
520     SkMatrix fLocalMatrix;
521
522     // So the SkLocalMatrixShader can whack fLocalMatrix in its SkReadBuffer constructor.
523     friend class SkLocalMatrixShader;
524     friend class SkBitmapProcLegacyShader;    // for computeTotalInverse()
525
526     typedef SkFlattenable INHERITED;
527 };
528
529 #endif