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 #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 SkArenaAlloc;
     21 class SkColorFilter;
     22 class SkColorSpace;
     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     ~SkShader() override;
     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      * Make a context using the memory provided by the arena.
    233      *
    234      * @return pointer to context or nullptr if can't be created
    235      */
    236     Context* makeContext(const ContextRec&, SkArenaAlloc*) const;
    237 
    238 #ifdef SK_SUPPORT_LEGACY_SHADER_ISABITMAP
    239     /**
    240      *  Returns true if this shader is just a bitmap, and if not null, returns the bitmap,
    241      *  localMatrix, and tilemodes. If this is not a bitmap, returns false and ignores the
    242      *  out-parameters.
    243      */
    244     bool isABitmap(SkBitmap* outTexture, SkMatrix* outMatrix, TileMode xy[2]) const {
    245         return this->onIsABitmap(outTexture, outMatrix, xy);
    246     }
    247 
    248     bool isABitmap() const {
    249         return this->isABitmap(nullptr, nullptr, nullptr);
    250     }
    251 #endif
    252 
    253     /**
    254      *  Iff this shader is backed by a single SkImage, return its ptr (the caller must ref this
    255      *  if they want to keep it longer than the lifetime of the shader). If not, return nullptr.
    256      */
    257     SkImage* isAImage(SkMatrix* localMatrix, TileMode xy[2]) const {
    258         return this->onIsAImage(localMatrix, xy);
    259     }
    260 
    261     bool isAImage() const {
    262         return this->isAImage(nullptr, nullptr) != nullptr;
    263     }
    264 
    265     /**
    266      *  If the shader subclass can be represented as a gradient, asAGradient
    267      *  returns the matching GradientType enum (or kNone_GradientType if it
    268      *  cannot). Also, if info is not null, asAGradient populates info with
    269      *  the relevant (see below) parameters for the gradient.  fColorCount
    270      *  is both an input and output parameter.  On input, it indicates how
    271      *  many entries in fColors and fColorOffsets can be used, if they are
    272      *  non-NULL.  After asAGradient has run, fColorCount indicates how
    273      *  many color-offset pairs there are in the gradient.  If there is
    274      *  insufficient space to store all of the color-offset pairs, fColors
    275      *  and fColorOffsets will not be altered.  fColorOffsets specifies
    276      *  where on the range of 0 to 1 to transition to the given color.
    277      *  The meaning of fPoint and fRadius is dependant on the type of gradient.
    278      *
    279      *  None:
    280      *      info is ignored.
    281      *  Color:
    282      *      fColorOffsets[0] is meaningless.
    283      *  Linear:
    284      *      fPoint[0] and fPoint[1] are the end-points of the gradient
    285      *  Radial:
    286      *      fPoint[0] and fRadius[0] are the center and radius
    287      *  Conical:
    288      *      fPoint[0] and fRadius[0] are the center and radius of the 1st circle
    289      *      fPoint[1] and fRadius[1] are the center and radius of the 2nd circle
    290      *  Sweep:
    291      *      fPoint[0] is the center of the sweep.
    292      */
    293 
    294     enum GradientType {
    295         kNone_GradientType,
    296         kColor_GradientType,
    297         kLinear_GradientType,
    298         kRadial_GradientType,
    299         kSweep_GradientType,
    300         kConical_GradientType,
    301         kLast_GradientType = kConical_GradientType
    302     };
    303 
    304     struct GradientInfo {
    305         int         fColorCount;    //!< In-out parameter, specifies passed size
    306                                     //   of fColors/fColorOffsets on input, and
    307                                     //   actual number of colors/offsets on
    308                                     //   output.
    309         SkColor*    fColors;        //!< The colors in the gradient.
    310         SkScalar*   fColorOffsets;  //!< The unit offset for color transitions.
    311         SkPoint     fPoint[2];      //!< Type specific, see above.
    312         SkScalar    fRadius[2];     //!< Type specific, see above.
    313         TileMode    fTileMode;      //!< The tile mode used.
    314         uint32_t    fGradientFlags; //!< see SkGradientShader::Flags
    315     };
    316 
    317     virtual GradientType asAGradient(GradientInfo* info) const;
    318 
    319     /**
    320      *  If the shader subclass is composed of two shaders, return true, and if rec is not NULL,
    321      *  fill it out with info about the shader.
    322      *
    323      *  These are bare pointers; the ownership and reference count are unchanged.
    324      */
    325 
    326     struct ComposeRec {
    327         const SkShader*     fShaderA;
    328         const SkShader*     fShaderB;
    329         SkBlendMode         fBlendMode;
    330     };
    331 
    332     virtual bool asACompose(ComposeRec*) const { return false; }
    333 
    334 #if SK_SUPPORT_GPU
    335     struct AsFPArgs {
    336         AsFPArgs() {}
    337         AsFPArgs(GrContext* context,
    338                  const SkMatrix* viewMatrix,
    339                  const SkMatrix* localMatrix,
    340                  SkFilterQuality filterQuality,
    341                  SkColorSpace* dstColorSpace)
    342             : fContext(context)
    343             , fViewMatrix(viewMatrix)
    344             , fLocalMatrix(localMatrix)
    345             , fFilterQuality(filterQuality)
    346             , fDstColorSpace(dstColorSpace) {}
    347 
    348         GrContext*                    fContext;
    349         const SkMatrix*               fViewMatrix;
    350         const SkMatrix*               fLocalMatrix;
    351         SkFilterQuality               fFilterQuality;
    352         SkColorSpace*                 fDstColorSpace;
    353     };
    354 
    355     /**
    356      *  Returns a GrFragmentProcessor that implements the shader for the GPU backend. NULL is
    357      *  returned if there is no GPU implementation.
    358      *
    359      *  The GPU device does not call SkShader::createContext(), instead we pass the view matrix,
    360      *  local matrix, and filter quality directly.
    361      *
    362      *  The GrContext may be used by the to create textures that are required by the returned
    363      *  processor.
    364      *
    365      *  The returned GrFragmentProcessor should expect an unpremultiplied input color and
    366      *  produce a premultiplied output.
    367      */
    368     virtual sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const;
    369 #endif
    370 
    371     /**
    372      *  If the shader can represent its "average" luminance in a single color, return true and
    373      *  if color is not NULL, return that color. If it cannot, return false and ignore the color
    374      *  parameter.
    375      *
    376      *  Note: if this returns true, the returned color will always be opaque, as only the RGB
    377      *  components are used to compute luminance.
    378      */
    379     bool asLuminanceColor(SkColor*) const;
    380 
    381     //////////////////////////////////////////////////////////////////////////
    382     //  Methods to create combinations or variants of shaders
    383 
    384     /**
    385      *  Return a shader that will apply the specified localMatrix to this shader.
    386      *  The specified matrix will be applied before any matrix associated with this shader.
    387      */
    388     sk_sp<SkShader> makeWithLocalMatrix(const SkMatrix&) const;
    389 
    390     /**
    391      *  Create a new shader that produces the same colors as invoking this shader and then applying
    392      *  the colorfilter.
    393      */
    394     sk_sp<SkShader> makeWithColorFilter(sk_sp<SkColorFilter>) const;
    395 
    396     //////////////////////////////////////////////////////////////////////////
    397     //  Factory methods for stock shaders
    398 
    399     /**
    400      *  Call this to create a new "empty" shader, that will not draw anything.
    401      */
    402     static sk_sp<SkShader> MakeEmptyShader();
    403 
    404     /**
    405      *  Call this to create a new shader that just draws the specified color. This should always
    406      *  draw the same as a paint with this color (and no shader).
    407      */
    408     static sk_sp<SkShader> MakeColorShader(SkColor);
    409 
    410     /**
    411      *  Create a shader that draws the specified color (in the specified colorspace).
    412      *
    413      *  This works around the limitation that SkPaint::setColor() only takes byte values, and does
    414      *  not support specific colorspaces.
    415      */
    416     static sk_sp<SkShader> MakeColorShader(const SkColor4f&, sk_sp<SkColorSpace>);
    417 
    418     static sk_sp<SkShader> MakeComposeShader(sk_sp<SkShader> dst, sk_sp<SkShader> src, SkBlendMode);
    419 
    420     /** Call this to create a new shader that will draw with the specified bitmap.
    421      *
    422      *  If the bitmap cannot be used (e.g. has no pixels, or its dimensions
    423      *  exceed implementation limits (currently at 64K - 1)) then SkEmptyShader
    424      *  may be returned.
    425      *
    426      *  If the src is kA8_Config then that mask will be colorized using the color on
    427      *  the paint.
    428      *
    429      *  @param src  The bitmap to use inside the 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      *  @return     Returns a new shader object. Note: this function never returns null.
    433     */
    434     static sk_sp<SkShader> MakeBitmapShader(const SkBitmap& src, TileMode tmx, TileMode tmy,
    435                                             const SkMatrix* localMatrix = nullptr);
    436 
    437     // NOTE: You can create an SkImage Shader with SkImage::newShader().
    438 
    439     /** Call this to create a new shader that will draw with the specified picture.
    440      *
    441      *  @param src  The picture to use inside the shader (if not NULL, its ref count
    442      *              is incremented). The SkPicture must not be changed after
    443      *              successfully creating a picture shader.
    444      *  @param tmx  The tiling mode to use when sampling the bitmap in the x-direction.
    445      *  @param tmy  The tiling mode to use when sampling the bitmap in the y-direction.
    446      *  @param tile The tile rectangle in picture coordinates: this represents the subset
    447      *              (or superset) of the picture used when building a tile. It is not
    448      *              affected by localMatrix and does not imply scaling (only translation
    449      *              and cropping). If null, the tile rect is considered equal to the picture
    450      *              bounds.
    451      *  @return     Returns a new shader object. Note: this function never returns null.
    452     */
    453     static sk_sp<SkShader> MakePictureShader(sk_sp<SkPicture> src, TileMode tmx, TileMode tmy,
    454                                              const SkMatrix* localMatrix, const SkRect* tile);
    455 
    456     /**
    457      *  If this shader can be represented by another shader + a localMatrix, return that shader and
    458      *  the localMatrix. If not, return nullptr and ignore the localMatrix parameter.
    459      */
    460     virtual sk_sp<SkShader> makeAsALocalMatrixShader(SkMatrix* localMatrix) const;
    461 
    462     SK_TO_STRING_VIRT()
    463     SK_DEFINE_FLATTENABLE_TYPE(SkShader)
    464     SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
    465 
    466     bool appendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*,
    467                       const SkMatrix& ctm, const SkPaint&) const;
    468 
    469 protected:
    470     void flatten(SkWriteBuffer&) const override;
    471 
    472     bool computeTotalInverse(const ContextRec&, SkMatrix* totalInverse) const;
    473 
    474     /**
    475      * Specialize creating a SkShader context using the supplied allocator.
    476      * @return pointer to context owned by the arena allocator.
    477      */
    478     virtual Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const {
    479         return nullptr;
    480     }
    481 
    482     virtual bool onAsLuminanceColor(SkColor*) const {
    483         return false;
    484     }
    485 
    486 #ifdef SK_SUPPORT_LEGACY_SHADER_ISABITMAP
    487     virtual bool onIsABitmap(SkBitmap*, SkMatrix*, TileMode[2]) const {
    488         return false;
    489     }
    490 #endif
    491 
    492     virtual SkImage* onIsAImage(SkMatrix*, TileMode[2]) const {
    493         return nullptr;
    494     }
    495 
    496     virtual bool onAppendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*,
    497                                 const SkMatrix&, const SkPaint&,
    498                                 const SkMatrix* /*local matrix*/) const;
    499 
    500 private:
    501     // This is essentially const, but not officially so it can be modified in
    502     // constructors.
    503     SkMatrix fLocalMatrix;
    504 
    505     // So the SkLocalMatrixShader can whack fLocalMatrix in its SkReadBuffer constructor.
    506     friend class SkLocalMatrixShader;
    507     friend class SkBitmapProcLegacyShader;    // for computeTotalInverse()
    508 
    509     typedef SkFlattenable INHERITED;
    510 };
    511 
    512 #endif
    513