123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- /*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
- #ifndef GrTextureProducer_DEFINED
- #define GrTextureProducer_DEFINED
- #include "include/core/SkImageInfo.h"
- #include "include/gpu/GrSamplerState.h"
- #include "include/private/GrResourceKey.h"
- #include "include/private/SkNoncopyable.h"
- #include "src/gpu/GrColorSpaceInfo.h"
- class GrFragmentProcessor;
- class GrRecordingContext;
- class GrTexture;
- class GrTextureProxy;
- class SkColorSpace;
- class SkMatrix;
- struct SkRect;
- /**
- * Different GPUs and API extensions have different requirements with respect to what texture
- * sampling parameters may be used with textures of various types. This class facilitates making
- * texture compatible with a given GrSamplerState. There are two immediate subclasses defined
- * below. One is a base class for sources that are inherently texture-backed (e.g. a texture-backed
- * SkImage). It supports subsetting the original texture. The other is for use cases where the
- * source can generate a texture that represents some content (e.g. cpu pixels, SkPicture, ...).
- */
- class GrTextureProducer : public SkNoncopyable {
- public:
- struct CopyParams {
- GrSamplerState::Filter fFilter;
- int fWidth;
- int fHeight;
- };
- enum FilterConstraint {
- kYes_FilterConstraint,
- kNo_FilterConstraint,
- };
- /**
- * Helper for creating a fragment processor to sample the texture with a given filtering mode.
- * It attempts to avoid making texture copies or using domains whenever possible.
- *
- * @param textureMatrix Matrix used to access the texture. It is applied to
- * the local coords. The post-transformed coords should
- * be in texel units (rather than normalized) with
- * respect to this Producer's bounds (width()/height()).
- * @param constraintRect A rect that represents the area of the texture to be
- * sampled. It must be contained in the Producer's
- * bounds as defined by width()/height().
- * @param filterConstriant Indicates whether filtering is limited to
- * constraintRect.
- * @param coordsLimitedToConstraintRect Is it known that textureMatrix*localCoords is bound
- * by the portion of the texture indicated by
- * constraintRect (without consideration of filter
- * width, just the raw coords).
- * @param filterOrNullForBicubic If non-null indicates the filter mode. If null means
- * use bicubic filtering.
- **/
- virtual std::unique_ptr<GrFragmentProcessor> createFragmentProcessor(
- const SkMatrix& textureMatrix,
- const SkRect& constraintRect,
- FilterConstraint filterConstraint,
- bool coordsLimitedToConstraintRect,
- const GrSamplerState::Filter* filterOrNullForBicubic) = 0;
- /**
- * Returns a texture that is safe for use with the params.
- *
- * If the size of the returned texture does not match width()/height() then the contents of the
- * original may have been scaled to fit the texture or the original may have been copied into
- * a subrect of the copy. 'scaleAdjust' must be applied to the normalized texture coordinates
- * in order to correct for the latter case.
- *
- * If the GrSamplerState is known to clamp and use kNearest or kBilerp filter mode then the
- * proxy will always be unscaled and nullptr can be passed for scaleAdjust. There is a weird
- * contract that if scaleAdjust is not null it must be initialized to {1, 1} before calling
- * this method. (TODO: Fix this and make this function always initialize scaleAdjust).
- */
- sk_sp<GrTextureProxy> refTextureProxyForParams(const GrSamplerState&,
- SkScalar scaleAdjust[2]);
- sk_sp<GrTextureProxy> refTextureProxyForParams(
- const GrSamplerState::Filter* filterOrNullForBicubic, SkScalar scaleAdjust[2]);
- /**
- * Returns a texture. If willNeedMips is true then the returned texture is guaranteed to have
- * allocated mip map levels. This can be a performance win if future draws with the texture
- * require mip maps.
- */
- // TODO: Once we remove support for npot textures, we should add a flag for must support repeat
- // wrap mode. To support that flag now would require us to support scaleAdjust array like in
- // refTextureProxyForParams, however the current public API that uses this call does not expose
- // that array.
- sk_sp<GrTextureProxy> refTextureProxy(GrMipMapped willNeedMips);
- virtual ~GrTextureProducer() {}
- int width() const { return fWidth; }
- int height() const { return fHeight; }
- GrColorType colorType() const { return fColorSpaceInfo.colorType(); }
- SkAlphaType alphaType() const { return fColorSpaceInfo.alphaType(); }
- SkColorSpace* colorSpace() const { return fColorSpaceInfo.colorSpace(); }
- bool isAlphaOnly() const { return GrColorTypeIsAlphaOnly(fColorSpaceInfo.colorType()); }
- bool domainNeedsDecal() const { return fDomainNeedsDecal; }
- // If the "texture" samples multiple images that have different resolutions (e.g. YUV420)
- virtual bool hasMixedResolutions() const { return false; }
- protected:
- friend class GrTextureProducer_TestAccess;
- GrTextureProducer(GrRecordingContext* context, int width, int height,
- const GrColorSpaceInfo& csInfo, bool domainNeedsDecal)
- : fContext(context)
- , fWidth(width)
- , fHeight(height)
- , fColorSpaceInfo(csInfo)
- , fDomainNeedsDecal(domainNeedsDecal) {}
- /** Helper for creating a key for a copy from an original key. */
- static void MakeCopyKeyFromOrigKey(const GrUniqueKey& origKey,
- const CopyParams& copyParams,
- GrUniqueKey* copyKey) {
- SkASSERT(!copyKey->isValid());
- if (origKey.isValid()) {
- static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
- GrUniqueKey::Builder builder(copyKey, origKey, kDomain, 3);
- builder[0] = static_cast<uint32_t>(copyParams.fFilter);
- builder[1] = copyParams.fWidth;
- builder[2] = copyParams.fHeight;
- }
- }
- /**
- * If we need to make a copy in order to be compatible with GrTextureParams producer is asked to
- * return a key that identifies its original content + the CopyParms parameter. If the producer
- * does not want to cache the stretched version (e.g. the producer is volatile), this should
- * simply return without initializing the copyKey. If the texture generated by this producer
- * depends on the destination color space, then that information should also be incorporated
- * in the key.
- */
- virtual void makeCopyKey(const CopyParams&, GrUniqueKey* copyKey) = 0;
- /**
- * If a stretched version of the texture is generated, it may be cached (assuming that
- * makeCopyKey() returns true). In that case, the maker is notified in case it
- * wants to note that for when the maker is destroyed.
- */
- virtual void didCacheCopy(const GrUniqueKey& copyKey, uint32_t contextUniqueID) = 0;
- enum DomainMode {
- kNoDomain_DomainMode,
- kDomain_DomainMode,
- kTightCopy_DomainMode
- };
- // This can draw to accomplish the copy, thus the recording context is needed
- static sk_sp<GrTextureProxy> CopyOnGpu(GrRecordingContext*,
- sk_sp<GrTextureProxy> inputProxy,
- GrColorType,
- const CopyParams& copyParams,
- bool dstWillRequireMipMaps);
- static DomainMode DetermineDomainMode(const SkRect& constraintRect,
- FilterConstraint filterConstraint,
- bool coordsLimitedToConstraintRect,
- GrTextureProxy*,
- const GrSamplerState::Filter* filterModeOrNullForBicubic,
- SkRect* domainRect);
- std::unique_ptr<GrFragmentProcessor> createFragmentProcessorForDomainAndFilter(
- sk_sp<GrTextureProxy> proxy,
- const SkMatrix& textureMatrix,
- DomainMode,
- const SkRect& domain,
- const GrSamplerState::Filter* filterOrNullForBicubic);
- GrRecordingContext* context() const { return fContext; }
- private:
- virtual sk_sp<GrTextureProxy> onRefTextureProxyForParams(const GrSamplerState&,
- bool willBeMipped,
- SkScalar scaleAdjust[2]) = 0;
- GrRecordingContext* fContext;
- const int fWidth;
- const int fHeight;
- const GrColorSpaceInfo fColorSpaceInfo;
- // If true, any domain effect uses kDecal instead of kClamp, and sampler filter uses
- // kClampToBorder instead of kClamp.
- const bool fDomainNeedsDecal;
- typedef SkNoncopyable INHERITED;
- };
- #endif
|