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 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  */
     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     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 
    462 protected:
    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 
    474 private:
    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