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