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