GrTextureProducer.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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. #ifndef GrTextureProducer_DEFINED
  8. #define GrTextureProducer_DEFINED
  9. #include "include/core/SkImageInfo.h"
  10. #include "include/gpu/GrSamplerState.h"
  11. #include "include/private/GrResourceKey.h"
  12. #include "include/private/SkNoncopyable.h"
  13. #include "src/gpu/GrColorSpaceInfo.h"
  14. class GrFragmentProcessor;
  15. class GrRecordingContext;
  16. class GrTexture;
  17. class GrTextureProxy;
  18. class SkColorSpace;
  19. class SkMatrix;
  20. struct SkRect;
  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 GrSamplerState. 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. GrSamplerState::Filter fFilter;
  33. int fWidth;
  34. int fHeight;
  35. };
  36. enum FilterConstraint {
  37. kYes_FilterConstraint,
  38. kNo_FilterConstraint,
  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 std::unique_ptr<GrFragmentProcessor> createFragmentProcessor(
  61. const SkMatrix& textureMatrix,
  62. const SkRect& constraintRect,
  63. FilterConstraint filterConstraint,
  64. bool coordsLimitedToConstraintRect,
  65. const GrSamplerState::Filter* filterOrNullForBicubic) = 0;
  66. /**
  67. * Returns a texture that is safe for use with the params.
  68. *
  69. * If the size of the returned texture does not match width()/height() then the contents of the
  70. * original may have been scaled to fit the texture or the original may have been copied into
  71. * a subrect of the copy. 'scaleAdjust' must be applied to the normalized texture coordinates
  72. * in order to correct for the latter case.
  73. *
  74. * If the GrSamplerState is known to clamp and use kNearest or kBilerp filter mode then the
  75. * proxy will always be unscaled and nullptr can be passed for scaleAdjust. There is a weird
  76. * contract that if scaleAdjust is not null it must be initialized to {1, 1} before calling
  77. * this method. (TODO: Fix this and make this function always initialize scaleAdjust).
  78. */
  79. sk_sp<GrTextureProxy> refTextureProxyForParams(const GrSamplerState&,
  80. SkScalar scaleAdjust[2]);
  81. sk_sp<GrTextureProxy> refTextureProxyForParams(
  82. const GrSamplerState::Filter* filterOrNullForBicubic, SkScalar scaleAdjust[2]);
  83. /**
  84. * Returns a texture. If willNeedMips is true then the returned texture is guaranteed to have
  85. * allocated mip map levels. This can be a performance win if future draws with the texture
  86. * require mip maps.
  87. */
  88. // TODO: Once we remove support for npot textures, we should add a flag for must support repeat
  89. // wrap mode. To support that flag now would require us to support scaleAdjust array like in
  90. // refTextureProxyForParams, however the current public API that uses this call does not expose
  91. // that array.
  92. sk_sp<GrTextureProxy> refTextureProxy(GrMipMapped willNeedMips);
  93. virtual ~GrTextureProducer() {}
  94. int width() const { return fWidth; }
  95. int height() const { return fHeight; }
  96. GrColorType colorType() const { return fColorSpaceInfo.colorType(); }
  97. SkAlphaType alphaType() const { return fColorSpaceInfo.alphaType(); }
  98. SkColorSpace* colorSpace() const { return fColorSpaceInfo.colorSpace(); }
  99. bool isAlphaOnly() const { return GrColorTypeIsAlphaOnly(fColorSpaceInfo.colorType()); }
  100. bool domainNeedsDecal() const { return fDomainNeedsDecal; }
  101. // If the "texture" samples multiple images that have different resolutions (e.g. YUV420)
  102. virtual bool hasMixedResolutions() const { return false; }
  103. protected:
  104. friend class GrTextureProducer_TestAccess;
  105. GrTextureProducer(GrRecordingContext* context, int width, int height,
  106. const GrColorSpaceInfo& csInfo, bool domainNeedsDecal)
  107. : fContext(context)
  108. , fWidth(width)
  109. , fHeight(height)
  110. , fColorSpaceInfo(csInfo)
  111. , fDomainNeedsDecal(domainNeedsDecal) {}
  112. /** Helper for creating a key for a copy from an original key. */
  113. static void MakeCopyKeyFromOrigKey(const GrUniqueKey& origKey,
  114. const CopyParams& copyParams,
  115. GrUniqueKey* copyKey) {
  116. SkASSERT(!copyKey->isValid());
  117. if (origKey.isValid()) {
  118. static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
  119. GrUniqueKey::Builder builder(copyKey, origKey, kDomain, 3);
  120. builder[0] = static_cast<uint32_t>(copyParams.fFilter);
  121. builder[1] = copyParams.fWidth;
  122. builder[2] = copyParams.fHeight;
  123. }
  124. }
  125. /**
  126. * If we need to make a copy in order to be compatible with GrTextureParams producer is asked to
  127. * return a key that identifies its original content + the CopyParms parameter. If the producer
  128. * does not want to cache the stretched version (e.g. the producer is volatile), this should
  129. * simply return without initializing the copyKey. If the texture generated by this producer
  130. * depends on the destination color space, then that information should also be incorporated
  131. * in the key.
  132. */
  133. virtual void makeCopyKey(const CopyParams&, GrUniqueKey* copyKey) = 0;
  134. /**
  135. * If a stretched version of the texture is generated, it may be cached (assuming that
  136. * makeCopyKey() returns true). In that case, the maker is notified in case it
  137. * wants to note that for when the maker is destroyed.
  138. */
  139. virtual void didCacheCopy(const GrUniqueKey& copyKey, uint32_t contextUniqueID) = 0;
  140. enum DomainMode {
  141. kNoDomain_DomainMode,
  142. kDomain_DomainMode,
  143. kTightCopy_DomainMode
  144. };
  145. // This can draw to accomplish the copy, thus the recording context is needed
  146. static sk_sp<GrTextureProxy> CopyOnGpu(GrRecordingContext*,
  147. sk_sp<GrTextureProxy> inputProxy,
  148. GrColorType,
  149. const CopyParams& copyParams,
  150. bool dstWillRequireMipMaps);
  151. static DomainMode DetermineDomainMode(const SkRect& constraintRect,
  152. FilterConstraint filterConstraint,
  153. bool coordsLimitedToConstraintRect,
  154. GrTextureProxy*,
  155. const GrSamplerState::Filter* filterModeOrNullForBicubic,
  156. SkRect* domainRect);
  157. std::unique_ptr<GrFragmentProcessor> createFragmentProcessorForDomainAndFilter(
  158. sk_sp<GrTextureProxy> proxy,
  159. const SkMatrix& textureMatrix,
  160. DomainMode,
  161. const SkRect& domain,
  162. const GrSamplerState::Filter* filterOrNullForBicubic);
  163. GrRecordingContext* context() const { return fContext; }
  164. private:
  165. virtual sk_sp<GrTextureProxy> onRefTextureProxyForParams(const GrSamplerState&,
  166. bool willBeMipped,
  167. SkScalar scaleAdjust[2]) = 0;
  168. GrRecordingContext* fContext;
  169. const int fWidth;
  170. const int fHeight;
  171. const GrColorSpaceInfo fColorSpaceInfo;
  172. // If true, any domain effect uses kDecal instead of kClamp, and sampler filter uses
  173. // kClampToBorder instead of kClamp.
  174. const bool fDomainNeedsDecal;
  175. typedef SkNoncopyable INHERITED;
  176. };
  177. #endif