Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2015 Google Inc.
      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 GrTextureMaker_DEFINED
      9 #define GrTextureMaker_DEFINED
     10 
     11 #include "GrTextureParams.h"
     12 #include "GrResourceKey.h"
     13 #include "GrTexture.h"
     14 #include "SkTLazy.h"
     15 
     16 class GrContext;
     17 class GrTextureParams;
     18 class GrUniqueKey;
     19 class SkBitmap;
     20 
     21 /**
     22  * Different GPUs and API extensions have different requirements with respect to what texture
     23  * sampling parameters may be used with textures of various types. This class facilitates making
     24  * texture compatible with a given GrTextureParams. There are two immediate subclasses defined
     25  * below. One is a base class for sources that are inherently texture-backed (e.g. a texture-backed
     26  * SkImage). It supports subsetting the original texture. The other is for use cases where the
     27  * source can generate a texture that represents some content (e.g. cpu pixels, SkPicture, ...).
     28  */
     29 class GrTextureProducer : public SkNoncopyable {
     30 public:
     31     struct CopyParams {
     32         GrTextureParams::FilterMode fFilter;
     33         int                         fWidth;
     34         int                         fHeight;
     35     };
     36 
     37     enum FilterConstraint {
     38         kYes_FilterConstraint,
     39         kNo_FilterConstraint,
     40     };
     41 
     42     /**
     43      * Helper for creating a fragment processor to sample the texture with a given filtering mode.
     44      * It attempts to avoid making texture copies or using domains whenever possible.
     45      *
     46      * @param textureMatrix                    Matrix used to access the texture. It is applied to
     47      *                                         the local coords. The post-transformed coords should
     48      *                                         be in texel units (rather than normalized) with
     49      *                                         respect to this Producer's bounds (width()/height()).
     50      * @param constraintRect                   A rect that represents the area of the texture to be
     51      *                                         sampled. It must be contained in the Producer's bounds
     52      *                                         as defined by width()/height().
     53      * @param filterConstriant                 Indicates whether filtering is limited to
     54      *                                         constraintRect.
     55      * @param coordsLimitedToConstraintRect    Is it known that textureMatrix*localCoords is bound
     56      *                                         by the portion of the texture indicated by
     57      *                                         constraintRect (without consideration of filter
     58      *                                         width, just the raw coords).
     59      * @param filterOrNullForBicubic           If non-null indicates the filter mode. If null means
     60      *                                         use bicubic filtering.
     61      **/
     62     virtual const GrFragmentProcessor* createFragmentProcessor(
     63                                     const SkMatrix& textureMatrix,
     64                                     const SkRect& constraintRect,
     65                                     FilterConstraint filterConstraint,
     66                                     bool coordsLimitedToConstraintRect,
     67                                     const GrTextureParams::FilterMode* filterOrNullForBicubic) = 0;
     68 
     69     virtual ~GrTextureProducer() {}
     70 
     71     int width() const { return fWidth; }
     72     int height() const { return fHeight; }
     73     bool isAlphaOnly() const { return fIsAlphaOnly; }
     74 
     75 protected:
     76     GrTextureProducer(int width, int height, bool isAlphaOnly)
     77         : fWidth(width)
     78         , fHeight(height)
     79         , fIsAlphaOnly(isAlphaOnly) {}
     80 
     81     /** Helper for creating a key for a copy from an original key. */
     82     static void MakeCopyKeyFromOrigKey(const GrUniqueKey& origKey,
     83                                        const CopyParams& copyParams,
     84                                        GrUniqueKey* copyKey) {
     85         SkASSERT(!copyKey->isValid());
     86         if (origKey.isValid()) {
     87             static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
     88             GrUniqueKey::Builder builder(copyKey, origKey, kDomain, 3);
     89             builder[0] = copyParams.fFilter;
     90             builder[1] = copyParams.fWidth;
     91             builder[2] = copyParams.fHeight;
     92         }
     93     }
     94 
     95     /**
     96     *  If we need to make a copy in order to be compatible with GrTextureParams producer is asked to
     97     *  return a key that identifies its original content + the CopyParms parameter. If the producer
     98     *  does not want to cache the stretched version (e.g. the producer is volatile), this should
     99     *  simply return without initializing the copyKey.
    100     */
    101     virtual void makeCopyKey(const CopyParams&, GrUniqueKey* copyKey) = 0;
    102 
    103     /**
    104     *  If a stretched version of the texture is generated, it may be cached (assuming that
    105     *  makeCopyKey() returns true). In that case, the maker is notified in case it
    106     *  wants to note that for when the maker is destroyed.
    107     */
    108     virtual void didCacheCopy(const GrUniqueKey& copyKey) = 0;
    109 
    110 private:
    111     const int   fWidth;
    112     const int   fHeight;
    113     const bool  fIsAlphaOnly;
    114 
    115     typedef SkNoncopyable INHERITED;
    116 };
    117 
    118 /**
    119  * Base class for sources that start out as textures. Optionally allows for a content area subrect.
    120  * The intent is not to use content area for subrect rendering. Rather, the pixels outside the
    121  * content area have undefined values and shouldn't be read *regardless* of filtering mode or
    122  * the SkCanvas::SrcRectConstraint used for subrect draws.
    123  */
    124 class GrTextureAdjuster : public GrTextureProducer {
    125 public:
    126     /** Makes the subset of the texture safe to use with the given texture parameters.
    127         outOffset will be the top-left corner of the subset if a copy is not made. Otherwise,
    128         the copy will be tight to the contents and outOffset will be (0, 0). If the copy's size
    129         does not match subset's dimensions then the contents are scaled to fit the copy.*/
    130     GrTexture* refTextureSafeForParams(const GrTextureParams&, SkIPoint* outOffset);
    131 
    132     const GrFragmentProcessor* createFragmentProcessor(
    133                                 const SkMatrix& textureMatrix,
    134                                 const SkRect& constraintRect,
    135                                 FilterConstraint,
    136                                 bool coordsLimitedToConstraintRect,
    137                                 const GrTextureParams::FilterMode* filterOrNullForBicubic) override;
    138 
    139 protected:
    140     /** The whole texture is content. */
    141     explicit GrTextureAdjuster(GrTexture* original, bool isAlphaOnly)
    142         : INHERITED(original->width(), original->height(), isAlphaOnly)
    143         , fOriginal(original) {}
    144 
    145     GrTextureAdjuster(GrTexture* original, const SkIRect& contentArea, bool isAlphaOnly);
    146 
    147     GrTexture* originalTexture() const { return fOriginal; }
    148 
    149     /** Returns the content area or null for the whole original texture */
    150     const SkIRect* contentAreaOrNull() { return fContentArea.getMaybeNull(); }
    151 
    152 private:
    153     SkTLazy<SkIRect>    fContentArea;
    154     GrTexture*          fOriginal;
    155 
    156     GrTexture* refCopy(const CopyParams &copyParams);
    157 
    158     typedef GrTextureProducer INHERITED;
    159 };
    160 
    161 /**
    162  * Base class for sources that start out as something other than a texture (encoded image,
    163  * picture, ...).
    164  */
    165 class GrTextureMaker : public GrTextureProducer {
    166 public:
    167     /** Returns a texture that is safe for use with the params. If the size of the returned texture
    168         does not match width()/height() then the contents of the original must be scaled to fit
    169         the texture. */
    170     GrTexture* refTextureForParams(const GrTextureParams&);
    171 
    172     const GrFragmentProcessor* createFragmentProcessor(
    173                                 const SkMatrix& textureMatrix,
    174                                 const SkRect& constraintRect,
    175                                 FilterConstraint filterConstraint,
    176                                 bool coordsLimitedToConstraintRect,
    177                                 const GrTextureParams::FilterMode* filterOrNullForBicubic) override;
    178 
    179 protected:
    180     GrTextureMaker(GrContext* context, int width, int height, bool isAlphaOnly)
    181         : INHERITED(width, height, isAlphaOnly)
    182         , fContext(context) {}
    183 
    184     /**
    185      *  Return the maker's "original" texture. It is the responsibility of the maker to handle any
    186      *  caching of the original if desired.
    187      */
    188     virtual GrTexture* refOriginalTexture() = 0;
    189 
    190     /**
    191      *  Return a new (uncached) texture that is the stretch of the maker's original.
    192      *
    193      *  The base-class handles general logic for this, and only needs access to the following
    194      *  method:
    195      *  - refOriginalTexture()
    196      *
    197      *  Subclass may override this if they can handle creating the texture more directly than
    198      *  by copying.
    199      */
    200     virtual GrTexture* generateTextureForParams(const CopyParams&);
    201 
    202     GrContext* context() const { return fContext; }
    203 
    204 private:
    205     GrContext*  fContext;
    206 
    207     typedef GrTextureProducer INHERITED;
    208 };
    209 
    210 #endif
    211