1 /* 2 * Copyright 2015 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 GrTextureMaker_DEFINED 9 #define GrTextureMaker_DEFINED 10 11 #include "GrTextureParams.h" 12 #include "GrResourceKey.h" 13 #include "GrTexture.h" 14 #include "SkTLazy.h" 15 16 class GrContext; 17 class GrTextureParams; 18 class GrUniqueKey; 19 class SkBitmap; 20 21 /** 22 * Different GPUs and API extensions have different requirements with respect to what texture 23 * sampling parameters may be used with textures of various types. This class facilitates making 24 * texture compatible with a given GrTextureParams. There are two immediate subclasses defined 25 * below. One is a base class for sources that are inherently texture-backed (e.g. a texture-backed 26 * SkImage). It supports subsetting the original texture. The other is for use cases where the 27 * source can generate a texture that represents some content (e.g. cpu pixels, SkPicture, ...). 28 */ 29 class GrTextureProducer : public SkNoncopyable { 30 public: 31 struct CopyParams { 32 GrTextureParams::FilterMode fFilter; 33 int fWidth; 34 int fHeight; 35 }; 36 37 enum FilterConstraint { 38 kYes_FilterConstraint, 39 kNo_FilterConstraint, 40 }; 41 42 /** 43 * Helper for creating a fragment processor to sample the texture with a given filtering mode. 44 * It attempts to avoid making texture copies or using domains whenever possible. 45 * 46 * @param textureMatrix Matrix used to access the texture. It is applied to 47 * the local coords. The post-transformed coords should 48 * be in texel units (rather than normalized) with 49 * respect to this Producer's bounds (width()/height()). 50 * @param constraintRect A rect that represents the area of the texture to be 51 * sampled. It must be contained in the Producer's bounds 52 * as defined by width()/height(). 53 * @param filterConstriant Indicates whether filtering is limited to 54 * constraintRect. 55 * @param coordsLimitedToConstraintRect Is it known that textureMatrix*localCoords is bound 56 * by the portion of the texture indicated by 57 * constraintRect (without consideration of filter 58 * width, just the raw coords). 59 * @param filterOrNullForBicubic If non-null indicates the filter mode. If null means 60 * use bicubic filtering. 61 **/ 62 virtual const GrFragmentProcessor* createFragmentProcessor( 63 const SkMatrix& textureMatrix, 64 const SkRect& constraintRect, 65 FilterConstraint filterConstraint, 66 bool coordsLimitedToConstraintRect, 67 const GrTextureParams::FilterMode* filterOrNullForBicubic) = 0; 68 69 virtual ~GrTextureProducer() {} 70 71 int width() const { return fWidth; } 72 int height() const { return fHeight; } 73 bool isAlphaOnly() const { return fIsAlphaOnly; } 74 75 protected: 76 GrTextureProducer(int width, int height, bool isAlphaOnly) 77 : fWidth(width) 78 , fHeight(height) 79 , fIsAlphaOnly(isAlphaOnly) {} 80 81 /** Helper for creating a key for a copy from an original key. */ 82 static void MakeCopyKeyFromOrigKey(const GrUniqueKey& origKey, 83 const CopyParams& copyParams, 84 GrUniqueKey* copyKey) { 85 SkASSERT(!copyKey->isValid()); 86 if (origKey.isValid()) { 87 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); 88 GrUniqueKey::Builder builder(copyKey, origKey, kDomain, 3); 89 builder[0] = copyParams.fFilter; 90 builder[1] = copyParams.fWidth; 91 builder[2] = copyParams.fHeight; 92 } 93 } 94 95 /** 96 * If we need to make a copy in order to be compatible with GrTextureParams producer is asked to 97 * return a key that identifies its original content + the CopyParms parameter. If the producer 98 * does not want to cache the stretched version (e.g. the producer is volatile), this should 99 * simply return without initializing the copyKey. 100 */ 101 virtual void makeCopyKey(const CopyParams&, GrUniqueKey* copyKey) = 0; 102 103 /** 104 * If a stretched version of the texture is generated, it may be cached (assuming that 105 * makeCopyKey() returns true). In that case, the maker is notified in case it 106 * wants to note that for when the maker is destroyed. 107 */ 108 virtual void didCacheCopy(const GrUniqueKey& copyKey) = 0; 109 110 private: 111 const int fWidth; 112 const int fHeight; 113 const bool fIsAlphaOnly; 114 115 typedef SkNoncopyable INHERITED; 116 }; 117 118 /** 119 * Base class for sources that start out as textures. Optionally allows for a content area subrect. 120 * The intent is not to use content area for subrect rendering. Rather, the pixels outside the 121 * content area have undefined values and shouldn't be read *regardless* of filtering mode or 122 * the SkCanvas::SrcRectConstraint used for subrect draws. 123 */ 124 class GrTextureAdjuster : public GrTextureProducer { 125 public: 126 /** Makes the subset of the texture safe to use with the given texture parameters. 127 outOffset will be the top-left corner of the subset if a copy is not made. Otherwise, 128 the copy will be tight to the contents and outOffset will be (0, 0). If the copy's size 129 does not match subset's dimensions then the contents are scaled to fit the copy.*/ 130 GrTexture* refTextureSafeForParams(const GrTextureParams&, SkIPoint* outOffset); 131 132 const GrFragmentProcessor* createFragmentProcessor( 133 const SkMatrix& textureMatrix, 134 const SkRect& constraintRect, 135 FilterConstraint, 136 bool coordsLimitedToConstraintRect, 137 const GrTextureParams::FilterMode* filterOrNullForBicubic) override; 138 139 protected: 140 /** The whole texture is content. */ 141 explicit GrTextureAdjuster(GrTexture* original, bool isAlphaOnly) 142 : INHERITED(original->width(), original->height(), isAlphaOnly) 143 , fOriginal(original) {} 144 145 GrTextureAdjuster(GrTexture* original, const SkIRect& contentArea, bool isAlphaOnly); 146 147 GrTexture* originalTexture() const { return fOriginal; } 148 149 /** Returns the content area or null for the whole original texture */ 150 const SkIRect* contentAreaOrNull() { return fContentArea.getMaybeNull(); } 151 152 private: 153 SkTLazy<SkIRect> fContentArea; 154 GrTexture* fOriginal; 155 156 GrTexture* refCopy(const CopyParams ©Params); 157 158 typedef GrTextureProducer INHERITED; 159 }; 160 161 /** 162 * Base class for sources that start out as something other than a texture (encoded image, 163 * picture, ...). 164 */ 165 class GrTextureMaker : public GrTextureProducer { 166 public: 167 /** Returns a texture that is safe for use with the params. If the size of the returned texture 168 does not match width()/height() then the contents of the original must be scaled to fit 169 the texture. */ 170 GrTexture* refTextureForParams(const GrTextureParams&); 171 172 const GrFragmentProcessor* createFragmentProcessor( 173 const SkMatrix& textureMatrix, 174 const SkRect& constraintRect, 175 FilterConstraint filterConstraint, 176 bool coordsLimitedToConstraintRect, 177 const GrTextureParams::FilterMode* filterOrNullForBicubic) override; 178 179 protected: 180 GrTextureMaker(GrContext* context, int width, int height, bool isAlphaOnly) 181 : INHERITED(width, height, isAlphaOnly) 182 , fContext(context) {} 183 184 /** 185 * Return the maker's "original" texture. It is the responsibility of the maker to handle any 186 * caching of the original if desired. 187 */ 188 virtual GrTexture* refOriginalTexture() = 0; 189 190 /** 191 * Return a new (uncached) texture that is the stretch of the maker's original. 192 * 193 * The base-class handles general logic for this, and only needs access to the following 194 * method: 195 * - refOriginalTexture() 196 * 197 * Subclass may override this if they can handle creating the texture more directly than 198 * by copying. 199 */ 200 virtual GrTexture* generateTextureForParams(const CopyParams&); 201 202 GrContext* context() const { return fContext; } 203 204 private: 205 GrContext* fContext; 206 207 typedef GrTextureProducer INHERITED; 208 }; 209 210 #endif 211