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