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