Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2016 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 GrTextureProducer_DEFINED
      9 #define GrTextureProducer_DEFINED
     10 
     11 #include "GrSamplerParams.h"
     12 #include "GrResourceKey.h"
     13 
     14 class GrColorSpaceXform;
     15 class GrTexture;
     16 class GrTextureProxy;
     17 
     18 /**
     19  * Different GPUs and API extensions have different requirements with respect to what texture
     20  * sampling parameters may be used with textures of various types. This class facilitates making
     21  * texture compatible with a given GrSamplerParams. There are two immediate subclasses defined
     22  * below. One is a base class for sources that are inherently texture-backed (e.g. a texture-backed
     23  * SkImage). It supports subsetting the original texture. The other is for use cases where the
     24  * source can generate a texture that represents some content (e.g. cpu pixels, SkPicture, ...).
     25  */
     26 class GrTextureProducer : public SkNoncopyable {
     27 public:
     28     struct CopyParams {
     29         GrSamplerParams::FilterMode fFilter;
     30         int                         fWidth;
     31         int                         fHeight;
     32     };
     33 
     34     enum FilterConstraint {
     35         kYes_FilterConstraint,
     36         kNo_FilterConstraint,
     37     };
     38 
     39     /**
     40      * Helper for creating a fragment processor to sample the texture with a given filtering mode.
     41      * It attempts to avoid making texture copies or using domains whenever possible.
     42      *
     43      * @param textureMatrix                    Matrix used to access the texture. It is applied to
     44      *                                         the local coords. The post-transformed coords should
     45      *                                         be in texel units (rather than normalized) with
     46      *                                         respect to this Producer's bounds (width()/height()).
     47      * @param constraintRect                   A rect that represents the area of the texture to be
     48      *                                         sampled. It must be contained in the Producer's
     49      *                                         bounds as defined by width()/height().
     50      * @param filterConstriant                 Indicates whether filtering is limited to
     51      *                                         constraintRect.
     52      * @param coordsLimitedToConstraintRect    Is it known that textureMatrix*localCoords is bound
     53      *                                         by the portion of the texture indicated by
     54      *                                         constraintRect (without consideration of filter
     55      *                                         width, just the raw coords).
     56      * @param filterOrNullForBicubic           If non-null indicates the filter mode. If null means
     57      *                                         use bicubic filtering.
     58      **/
     59     virtual sk_sp<GrFragmentProcessor> createFragmentProcessor(
     60                                     const SkMatrix& textureMatrix,
     61                                     const SkRect& constraintRect,
     62                                     FilterConstraint filterConstraint,
     63                                     bool coordsLimitedToConstraintRect,
     64                                     const GrSamplerParams::FilterMode* filterOrNullForBicubic,
     65                                     SkColorSpace* dstColorSpace) = 0;
     66 
     67     virtual ~GrTextureProducer() {}
     68 
     69     int width() const { return fWidth; }
     70     int height() const { return fHeight; }
     71     bool isAlphaOnly() const { return fIsAlphaOnly; }
     72     virtual SkAlphaType alphaType() const = 0;
     73 
     74 protected:
     75     friend class GrTextureProducer_TestAccess;
     76 
     77     GrTextureProducer(int width, int height, bool isAlphaOnly)
     78         : fWidth(width)
     79         , fHeight(height)
     80         , fIsAlphaOnly(isAlphaOnly) {}
     81 
     82     /** Helper for creating a key for a copy from an original key. */
     83     static void MakeCopyKeyFromOrigKey(const GrUniqueKey& origKey,
     84                                        const CopyParams& copyParams,
     85                                        GrUniqueKey* copyKey) {
     86         SkASSERT(!copyKey->isValid());
     87         if (origKey.isValid()) {
     88             static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
     89             GrUniqueKey::Builder builder(copyKey, origKey, kDomain, 3);
     90             builder[0] = copyParams.fFilter;
     91             builder[1] = copyParams.fWidth;
     92             builder[2] = copyParams.fHeight;
     93         }
     94     }
     95 
     96     /**
     97     *  If we need to make a copy in order to be compatible with GrTextureParams producer is asked to
     98     *  return a key that identifies its original content + the CopyParms parameter. If the producer
     99     *  does not want to cache the stretched version (e.g. the producer is volatile), this should
    100     *  simply return without initializing the copyKey. If the texture generated by this producer
    101     *  depends on the destination color space, then that information should also be incorporated
    102     *  in the key.
    103     */
    104     virtual void makeCopyKey(const CopyParams&, GrUniqueKey* copyKey,
    105                              SkColorSpace* dstColorSpace) = 0;
    106 
    107     /**
    108     *  If a stretched version of the texture is generated, it may be cached (assuming that
    109     *  makeCopyKey() returns true). In that case, the maker is notified in case it
    110     *  wants to note that for when the maker is destroyed.
    111     */
    112     virtual void didCacheCopy(const GrUniqueKey& copyKey) = 0;
    113 
    114 
    115     enum DomainMode {
    116         kNoDomain_DomainMode,
    117         kDomain_DomainMode,
    118         kTightCopy_DomainMode
    119     };
    120 
    121     static sk_sp<GrTextureProxy> CopyOnGpu(GrContext*, sk_sp<GrTextureProxy> inputProxy,
    122                                            const SkIRect* subset, const CopyParams& copyParams);
    123 
    124     static DomainMode DetermineDomainMode(
    125         const SkRect& constraintRect,
    126         FilterConstraint filterConstraint,
    127         bool coordsLimitedToConstraintRect,
    128         GrTextureProxy*,
    129         const SkIRect* textureContentArea,
    130         const GrSamplerParams::FilterMode* filterModeOrNullForBicubic,
    131         SkRect* domainRect);
    132 
    133     static sk_sp<GrFragmentProcessor> CreateFragmentProcessorForDomainAndFilter(
    134         sk_sp<GrTextureProxy> proxy,
    135         sk_sp<GrColorSpaceXform>,
    136         const SkMatrix& textureMatrix,
    137         DomainMode,
    138         const SkRect& domain,
    139         const GrSamplerParams::FilterMode* filterOrNullForBicubic);
    140 
    141 private:
    142     const int   fWidth;
    143     const int   fHeight;
    144     const bool  fIsAlphaOnly;
    145 
    146     typedef SkNoncopyable INHERITED;
    147 };
    148 
    149 #endif
    150