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 ~GrTextureProducer()67 virtual ~GrTextureProducer() {} 68 width()69 int width() const { return fWidth; } height()70 int height() const { return fHeight; } isAlphaOnly()71 bool isAlphaOnly() const { return fIsAlphaOnly; } 72 virtual SkAlphaType alphaType() const = 0; 73 74 protected: 75 friend class GrTextureProducer_TestAccess; 76 GrTextureProducer(int width,int height,bool isAlphaOnly)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. */ MakeCopyKeyFromOrigKey(const GrUniqueKey & origKey,const CopyParams & copyParams,GrUniqueKey * copyKey)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