summaryrefslogtreecommitdiffstats
path: root/gfx/skia/skia/src/gpu/GrTextureProducer.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--gfx/skia/skia/src/gpu/GrTextureProducer.h203
1 files changed, 203 insertions, 0 deletions
diff --git a/gfx/skia/skia/src/gpu/GrTextureProducer.h b/gfx/skia/skia/src/gpu/GrTextureProducer.h
new file mode 100644
index 0000000000..d124bf7328
--- /dev/null
+++ b/gfx/skia/skia/src/gpu/GrTextureProducer.h
@@ -0,0 +1,203 @@
+/*
+ * 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/private/GrResourceKey.h"
+#include "include/private/SkNoncopyable.h"
+#include "src/gpu/GrColorInfo.h"
+#include "src/gpu/GrSamplerState.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; }
+ const GrColorInfo& colorInfo() const { return fColorInfo; }
+ GrColorType colorType() const { return fColorInfo.colorType(); }
+ SkAlphaType alphaType() const { return fColorInfo.alphaType(); }
+ SkColorSpace* colorSpace() const { return fColorInfo.colorSpace(); }
+ bool isAlphaOnly() const { return GrColorTypeIsAlphaOnly(fColorInfo.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 GrColorInfo& colorInfo, bool domainNeedsDecal)
+ : fContext(context)
+ , fWidth(width)
+ , fHeight(height)
+ , fColorInfo(colorInfo)
+ , 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 GrColorInfo fColorInfo;
+ // 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