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