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
9#ifndef SkShader_DEFINED
10#define SkShader_DEFINED
11
12#include "SkBitmap.h"
13#include "SkFlattenable.h"
14#include "SkMask.h"
15#include "SkMatrix.h"
16#include "SkPaint.h"
17#include "../gpu/GrColor.h"
18
19class SkPath;
20class SkPicture;
21class SkXfermode;
22class GrContext;
23class GrEffectRef;
24
25/** \class SkShader
26 *
27 *  Shaders specify the source color(s) for what is being drawn. If a paint
28 *  has no shader, then the paint's color is used. If the paint has a
29 *  shader, then the shader's color(s) are use instead, but they are
30 *  modulated by the paint's alpha. This makes it easy to create a shader
31 *  once (e.g. bitmap tiling or gradient) and then change its transparency
32 *  w/o having to modify the original shader... only the paint's alpha needs
33 *  to be modified.
34 */
35class SK_API SkShader : public SkFlattenable {
36public:
37    SK_DECLARE_INST_COUNT(SkShader)
38
39    SkShader(const SkMatrix* localMatrix = NULL);
40    virtual ~SkShader();
41
42    /**
43     *  Returns the local matrix.
44     */
45    const SkMatrix& getLocalMatrix() const { return fLocalMatrix; }
46
47    /**
48     *  Returns true if the local matrix is not an identity matrix.
49     */
50    bool hasLocalMatrix() const { return !fLocalMatrix.isIdentity(); }
51
52#ifdef SK_SUPPORT_LEGACY_SHADER_LOCALMATRIX
53    /**
54     *  Set the shader's local matrix.
55     *  @param localM   The shader's new local matrix.
56     */
57    void setLocalMatrix(const SkMatrix& localM) { fLocalMatrix = localM; }
58
59    /**
60     *  Reset the shader's local matrix to identity.
61     */
62    void resetLocalMatrix() { fLocalMatrix.reset(); }
63#endif
64
65    enum TileMode {
66        /** replicate the edge color if the shader draws outside of its
67         *  original bounds
68         */
69        kClamp_TileMode,
70
71        /** repeat the shader's image horizontally and vertically */
72        kRepeat_TileMode,
73
74        /** repeat the shader's image horizontally and vertically, alternating
75         *  mirror images so that adjacent images always seam
76         */
77        kMirror_TileMode,
78
79#if 0
80        /** only draw within the original domain, return 0 everywhere else */
81        kDecal_TileMode,
82#endif
83
84        kTileModeCount
85    };
86
87    // override these in your subclass
88
89    enum Flags {
90        //!< set if all of the colors will be opaque
91        kOpaqueAlpha_Flag  = 0x01,
92
93        //! set if this shader's shadeSpan16() method can be called
94        kHasSpan16_Flag = 0x02,
95
96        /** Set this bit if the shader's native data type is instrinsically 16
97            bit, meaning that calling the 32bit shadeSpan() entry point will
98            mean the the impl has to up-sample 16bit data into 32bit. Used as a
99            a means of clearing a dither request if the it will have no effect
100        */
101        kIntrinsicly16_Flag = 0x04,
102
103        /** set if the spans only vary in X (const in Y).
104            e.g. an Nx1 bitmap that is being tiled in Y, or a linear-gradient
105            that varies from left-to-right. This flag specifies this for
106            shadeSpan().
107         */
108        kConstInY32_Flag = 0x08,
109
110        /** same as kConstInY32_Flag, but is set if this is true for shadeSpan16
111            which may not always be the case, since shadeSpan16 may be
112            predithered, which would mean it was not const in Y, even though
113            the 32bit shadeSpan() would be const.
114         */
115        kConstInY16_Flag = 0x10
116    };
117
118    /**
119     *  Returns true if the shader is guaranteed to produce only opaque
120     *  colors, subject to the SkPaint using the shader to apply an opaque
121     *  alpha value. Subclasses should override this to allow some
122     *  optimizations.
123     */
124    virtual bool isOpaque() const { return false; }
125
126    /**
127     *  ContextRec acts as a parameter bundle for creating Contexts.
128     */
129    struct ContextRec {
130        ContextRec() : fDevice(NULL), fPaint(NULL), fMatrix(NULL), fLocalMatrix(NULL) {}
131        ContextRec(const SkBitmap& device, const SkPaint& paint, const SkMatrix& matrix)
132            : fDevice(&device)
133            , fPaint(&paint)
134            , fMatrix(&matrix)
135            , fLocalMatrix(NULL) {}
136
137        const SkBitmap* fDevice;        // the bitmap we are drawing into
138        const SkPaint*  fPaint;         // the current paint associated with the draw
139        const SkMatrix* fMatrix;        // the current matrix in the canvas
140        const SkMatrix* fLocalMatrix;   // optional local matrix
141    };
142
143    class Context : public ::SkNoncopyable {
144    public:
145        Context(const SkShader& shader, const ContextRec&);
146
147        virtual ~Context();
148
149        /**
150         *  Called sometimes before drawing with this shader. Return the type of
151         *  alpha your shader will return. The default implementation returns 0.
152         *  Your subclass should override if it can (even sometimes) report a
153         *  non-zero value, since that will enable various blitters to perform
154         *  faster.
155         */
156        virtual uint32_t getFlags() const { return 0; }
157
158        /**
159         *  Return the alpha associated with the data returned by shadeSpan16(). If
160         *  kHasSpan16_Flag is not set, this value is meaningless.
161         */
162        virtual uint8_t getSpan16Alpha() const { return fPaintAlpha; }
163
164        /**
165         *  Called for each span of the object being drawn. Your subclass should
166         *  set the appropriate colors (with premultiplied alpha) that correspond
167         *  to the specified device coordinates.
168         */
169        virtual void shadeSpan(int x, int y, SkPMColor[], int count) = 0;
170
171        typedef void (*ShadeProc)(void* ctx, int x, int y, SkPMColor[], int count);
172        virtual ShadeProc asAShadeProc(void** ctx);
173
174        /**
175         *  Called only for 16bit devices when getFlags() returns
176         *  kOpaqueAlphaFlag | kHasSpan16_Flag
177         */
178        virtual void shadeSpan16(int x, int y, uint16_t[], int count);
179
180        /**
181         *  Similar to shadeSpan, but only returns the alpha-channel for a span.
182         *  The default implementation calls shadeSpan() and then extracts the alpha
183         *  values from the returned colors.
184         */
185        virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count);
186
187        /**
188         *  Helper function that returns true if this shader's shadeSpan16() method
189         *  can be called.
190         */
191        bool canCallShadeSpan16() {
192            return SkShader::CanCallShadeSpan16(this->getFlags());
193        }
194
195        // Notification from blitter::blitMask in case we need to see the non-alpha channels
196        virtual void set3DMask(const SkMask*) {}
197
198    protected:
199        // Reference to shader, so we don't have to dupe information.
200        const SkShader& fShader;
201
202        enum MatrixClass {
203            kLinear_MatrixClass,            // no perspective
204            kFixedStepInX_MatrixClass,      // fast perspective, need to call fixedStepInX() each
205                                            // scanline
206            kPerspective_MatrixClass        // slow perspective, need to mappoints each pixel
207        };
208        static MatrixClass ComputeMatrixClass(const SkMatrix&);
209
210        uint8_t         getPaintAlpha() const { return fPaintAlpha; }
211        const SkMatrix& getTotalInverse() const { return fTotalInverse; }
212        MatrixClass     getInverseClass() const { return (MatrixClass)fTotalInverseClass; }
213        const SkMatrix& getCTM() const { return fCTM; }
214    private:
215        SkMatrix    fCTM;
216        SkMatrix    fTotalInverse;
217        uint8_t     fPaintAlpha;
218        uint8_t     fTotalInverseClass;
219
220        typedef SkNoncopyable INHERITED;
221    };
222
223    /**
224     *  Create the actual object that does the shading.
225     *  Size of storage must be >= contextSize.
226     */
227    Context* createContext(const ContextRec&, void* storage) const;
228
229    /**
230     *  Return the size of a Context returned by createContext.
231     *
232     *  Override this if your subclass overrides createContext, to return the correct size of
233     *  your subclass' context.
234     */
235    virtual size_t contextSize() const;
236
237    /**
238     *  Helper to check the flags to know if it is legal to call shadeSpan16()
239     */
240    static bool CanCallShadeSpan16(uint32_t flags) {
241        return (flags & kHasSpan16_Flag) != 0;
242    }
243
244    /**
245     Gives method bitmap should be read to implement a shader.
246     Also determines number and interpretation of "extra" parameters returned
247     by asABitmap
248     */
249    enum BitmapType {
250        kNone_BitmapType,   //<! Shader is not represented as a bitmap
251        kDefault_BitmapType,//<! Access bitmap using local coords transformed
252                            //   by matrix. No extras
253        kRadial_BitmapType, //<! Access bitmap by transforming local coordinates
254                            //   by the matrix and taking the distance of result
255                            //   from  (0,0) as bitmap column. Bitmap is 1 pixel
256                            //   tall. No extras
257        kSweep_BitmapType,  //<! Access bitmap by transforming local coordinates
258                            //   by the matrix and taking the angle of result
259                            //   to (0,0) as bitmap x coord, where angle = 0 is
260                            //   bitmap left edge of bitmap = 2pi is the
261                            //   right edge. Bitmap is 1 pixel tall. No extras
262        kTwoPointRadial_BitmapType,
263                            //<! Matrix transforms to space where (0,0) is
264                            //   the center of the starting circle.  The second
265                            //   circle will be centered (x, 0) where x  may be
266                            //   0. The post-matrix space is normalized such
267                            //   that 1 is the second radius - first radius.
268                            //   Three extra parameters are returned:
269                            //      0: x-offset of second circle center
270                            //         to first.
271                            //      1: radius of first circle in post-matrix
272                            //         space
273                            //      2: the second radius minus the first radius
274                            //         in pre-transformed space.
275        kTwoPointConical_BitmapType,
276                            //<! Matrix transforms to space where (0,0) is
277                            //   the center of the starting circle.  The second
278                            //   circle will be centered (x, 0) where x  may be
279                            //   0.
280                            //   Three extra parameters are returned:
281                            //      0: x-offset of second circle center
282                            //         to first.
283                            //      1: radius of first circle
284                            //      2: the second radius minus the first radius
285        kLinear_BitmapType, //<! Access bitmap using local coords transformed
286                            //   by matrix. No extras
287
288       kLast_BitmapType = kLinear_BitmapType
289    };
290    /** Optional methods for shaders that can pretend to be a bitmap/texture
291        to play along with opengl. Default just returns kNone_BitmapType and
292        ignores the out parameters.
293
294        @param outTexture if non-NULL will be the bitmap representing the shader
295                          after return.
296        @param outMatrix  if non-NULL will be the matrix to apply to vertices
297                          to access the bitmap after return.
298        @param xy         if non-NULL will be the tile modes that should be
299                          used to access the bitmap after return.
300        @param twoPointRadialParams Two extra return values needed for two point
301                                    radial bitmaps. The first is the x-offset of
302                                    the second point and the second is the radius
303                                    about the first point.
304    */
305    virtual BitmapType asABitmap(SkBitmap* outTexture, SkMatrix* outMatrix,
306                         TileMode xy[2]) const;
307
308    /**
309     *  If the shader subclass can be represented as a gradient, asAGradient
310     *  returns the matching GradientType enum (or kNone_GradientType if it
311     *  cannot). Also, if info is not null, asAGradient populates info with
312     *  the relevant (see below) parameters for the gradient.  fColorCount
313     *  is both an input and output parameter.  On input, it indicates how
314     *  many entries in fColors and fColorOffsets can be used, if they are
315     *  non-NULL.  After asAGradient has run, fColorCount indicates how
316     *  many color-offset pairs there are in the gradient.  If there is
317     *  insufficient space to store all of the color-offset pairs, fColors
318     *  and fColorOffsets will not be altered.  fColorOffsets specifies
319     *  where on the range of 0 to 1 to transition to the given color.
320     *  The meaning of fPoint and fRadius is dependant on the type of gradient.
321     *
322     *  None:
323     *      info is ignored.
324     *  Color:
325     *      fColorOffsets[0] is meaningless.
326     *  Linear:
327     *      fPoint[0] and fPoint[1] are the end-points of the gradient
328     *  Radial:
329     *      fPoint[0] and fRadius[0] are the center and radius
330     *  Radial2:
331     *      fPoint[0] and fRadius[0] are the center and radius of the 1st circle
332     *      fPoint[1] and fRadius[1] are the center and radius of the 2nd circle
333     *  Sweep:
334     *      fPoint[0] is the center of the sweep.
335     */
336
337    enum GradientType {
338        kNone_GradientType,
339        kColor_GradientType,
340        kLinear_GradientType,
341        kRadial_GradientType,
342        kRadial2_GradientType,
343        kSweep_GradientType,
344        kConical_GradientType,
345        kLast_GradientType = kConical_GradientType
346    };
347
348    struct GradientInfo {
349        int         fColorCount;    //!< In-out parameter, specifies passed size
350                                    //   of fColors/fColorOffsets on input, and
351                                    //   actual number of colors/offsets on
352                                    //   output.
353        SkColor*    fColors;        //!< The colors in the gradient.
354        SkScalar*   fColorOffsets;  //!< The unit offset for color transitions.
355        SkPoint     fPoint[2];      //!< Type specific, see above.
356        SkScalar    fRadius[2];     //!< Type specific, see above.
357        TileMode    fTileMode;      //!< The tile mode used.
358        uint32_t    fGradientFlags; //!< see SkGradientShader::Flags
359    };
360
361    virtual GradientType asAGradient(GradientInfo* info) const;
362
363    /**
364     *  If the shader subclass is composed of two shaders, return true, and if rec is not NULL,
365     *  fill it out with info about the shader.
366     *
367     *  These are bare pointers; the ownership and reference count are unchanged.
368     */
369
370    struct ComposeRec {
371        const SkShader*     fShaderA;
372        const SkShader*     fShaderB;
373        const SkXfermode*   fMode;
374    };
375
376    virtual bool asACompose(ComposeRec* rec) const { return false; }
377
378
379    /**
380     *  Returns true if the shader subclass succeeds in setting the grEffect and the grColor output
381     *  parameters to a value, returns false if it fails or if there is not an implementation of
382     *  this method in the shader subclass.
383     *  The incoming color to the effect has r=g=b=a all extracted from the SkPaint's alpha.
384     *  The output color should be the computed SkShader premul color modulated by the incoming
385     *  color. The GrContext may be used by the effect to create textures. The GPU device does not
386     *  call createContext. Instead we pass the SkPaint here in case the shader needs paint info.
387     */
388    virtual bool asNewEffect(GrContext* context, const SkPaint& paint,
389                             const SkMatrix* localMatrixOrNull, GrColor* grColor,
390                             GrEffectRef** grEffect) const;
391
392#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
393    /**
394     *  If the shader is a custom shader which has data the caller might want, call this function
395     *  to get that data.
396     */
397    virtual bool asACustomShader(void** customData) const { return false; }
398
399    uint32_t getGenerationID() const { return fGenerationID; }
400    void setGenerationID(uint32_t generationID) { fGenerationID = generationID; }
401#endif
402
403    //////////////////////////////////////////////////////////////////////////
404    //  Factory methods for stock shaders
405
406    /**
407     *  Call this to create a new "empty" shader, that will not draw anything.
408     */
409    static SkShader* CreateEmptyShader();
410
411    /** Call this to create a new shader that will draw with the specified bitmap.
412     *
413     *  If the bitmap cannot be used (e.g. has no pixels, or its dimensions
414     *  exceed implementation limits (currently at 64K - 1)) then SkEmptyShader
415     *  may be returned.
416     *
417     *  If the src is kA8_Config then that mask will be colorized using the color on
418     *  the paint.
419     *
420     *  @param src  The bitmap to use inside the shader
421     *  @param tmx  The tiling mode to use when sampling the bitmap in the x-direction.
422     *  @param tmy  The tiling mode to use when sampling the bitmap in the y-direction.
423     *  @return     Returns a new shader object. Note: this function never returns null.
424    */
425    static SkShader* CreateBitmapShader(const SkBitmap& src,
426                                        TileMode tmx, TileMode tmy,
427                                        const SkMatrix* localMatrix = NULL);
428
429    /** Call this to create a new shader that will draw with the specified picture.
430     *
431     *  @param src  The picture to use inside the shader (if not NULL, its ref count
432     *              is incremented). The SkPicture must not be changed after
433     *              successfully creating a picture shader.
434     *              FIXME: src cannot be const due to SkCanvas::drawPicture
435     *  @param tmx  The tiling mode to use when sampling the bitmap in the x-direction.
436     *  @param tmy  The tiling mode to use when sampling the bitmap in the y-direction.
437     *  @return     Returns a new shader object. Note: this function never returns null.
438    */
439    static SkShader* CreatePictureShader(SkPicture* src, TileMode tmx, TileMode tmy,
440                                         const SkMatrix* localMatrix = NULL);
441
442    /**
443     *  Return a shader that will apply the specified localMatrix to the proxy shader.
444     *  The specified matrix will be applied before any matrix associated with the proxy.
445     *
446     *  Note: ownership of the proxy is not transferred (though a ref is taken).
447     */
448    static SkShader* CreateLocalMatrixShader(SkShader* proxy, const SkMatrix& localMatrix);
449
450    /**
451     *  If this shader can be represented by another shader + a localMatrix, return that shader
452     *  and, if not NULL, the localMatrix. If not, return NULL and ignore the localMatrix parameter.
453     *
454     *  Note: the returned shader (if not NULL) will have been ref'd, and it is the responsibility
455     *  of the caller to balance that with unref() when they are done.
456     */
457    virtual SkShader* refAsALocalMatrixShader(SkMatrix* localMatrix) const;
458
459    SK_TO_STRING_VIRT()
460    SK_DEFINE_FLATTENABLE_TYPE(SkShader)
461
462protected:
463    SkShader(SkReadBuffer& );
464    virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
465
466    bool computeTotalInverse(const ContextRec&, SkMatrix* totalInverse) const;
467
468    /**
469     *  Your subclass must also override contextSize() if it overrides onCreateContext().
470     *  Base class impl returns NULL.
471     */
472    virtual Context* onCreateContext(const ContextRec&, void* storage) const;
473
474private:
475    SkMatrix fLocalMatrix;
476
477    typedef SkFlattenable INHERITED;
478
479#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
480    uint32_t fGenerationID;
481#endif
482};
483
484#endif
485