blob: 7d056640ccf555b48a6bc51ab3f717e4442e9075 [file] [log] [blame]
Brian Osmane8e54582016-11-28 10:06:27 -05001/*
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
Brian Osmane8e54582016-11-28 10:06:27 -050011#include "GrResourceKey.h"
Brian Salomon2bbdcc42017-09-07 12:36:34 -040012#include "GrSamplerState.h"
13#include "SkImageInfo.h"
Brian Osmane8e54582016-11-28 10:06:27 -050014
Brian Salomon2bbdcc42017-09-07 12:36:34 -040015class GrContext;
Brian Osmane8e54582016-11-28 10:06:27 -050016class GrColorSpaceXform;
Brian Salomon2bbdcc42017-09-07 12:36:34 -040017class GrFragmentProcessor;
Brian Osmane8e54582016-11-28 10:06:27 -050018class GrTexture;
Robert Phillipsb66b42f2017-03-14 08:53:02 -040019class GrTextureProxy;
Brian Salomon2bbdcc42017-09-07 12:36:34 -040020class SkColorSpace;
21class SkMatrix;
22struct SkRect;
Brian Osmane8e54582016-11-28 10:06:27 -050023
24/**
25 * Different GPUs and API extensions have different requirements with respect to what texture
26 * sampling parameters may be used with textures of various types. This class facilitates making
Brian Salomon2bbdcc42017-09-07 12:36:34 -040027 * texture compatible with a given GrSamplerState. There are two immediate subclasses defined
Brian Osmane8e54582016-11-28 10:06:27 -050028 * below. One is a base class for sources that are inherently texture-backed (e.g. a texture-backed
29 * SkImage). It supports subsetting the original texture. The other is for use cases where the
30 * source can generate a texture that represents some content (e.g. cpu pixels, SkPicture, ...).
31 */
32class GrTextureProducer : public SkNoncopyable {
33public:
34 struct CopyParams {
Brian Salomon2bbdcc42017-09-07 12:36:34 -040035 GrSamplerState::Filter fFilter;
36 int fWidth;
37 int fHeight;
Brian Osmane8e54582016-11-28 10:06:27 -050038 };
39
40 enum FilterConstraint {
41 kYes_FilterConstraint,
42 kNo_FilterConstraint,
43 };
44
45 /**
46 * Helper for creating a fragment processor to sample the texture with a given filtering mode.
47 * It attempts to avoid making texture copies or using domains whenever possible.
48 *
49 * @param textureMatrix Matrix used to access the texture. It is applied to
50 * the local coords. The post-transformed coords should
51 * be in texel units (rather than normalized) with
52 * respect to this Producer's bounds (width()/height()).
53 * @param constraintRect A rect that represents the area of the texture to be
54 * sampled. It must be contained in the Producer's
55 * bounds as defined by width()/height().
56 * @param filterConstriant Indicates whether filtering is limited to
57 * constraintRect.
58 * @param coordsLimitedToConstraintRect Is it known that textureMatrix*localCoords is bound
59 * by the portion of the texture indicated by
60 * constraintRect (without consideration of filter
61 * width, just the raw coords).
62 * @param filterOrNullForBicubic If non-null indicates the filter mode. If null means
63 * use bicubic filtering.
64 **/
Brian Salomonaff329b2017-08-11 09:40:37 -040065 virtual std::unique_ptr<GrFragmentProcessor> createFragmentProcessor(
66 const SkMatrix& textureMatrix,
67 const SkRect& constraintRect,
68 FilterConstraint filterConstraint,
69 bool coordsLimitedToConstraintRect,
Brian Salomon2bbdcc42017-09-07 12:36:34 -040070 const GrSamplerState::Filter* filterOrNullForBicubic,
Brian Salomonaff329b2017-08-11 09:40:37 -040071 SkColorSpace* dstColorSpace) = 0;
Brian Osmane8e54582016-11-28 10:06:27 -050072
73 virtual ~GrTextureProducer() {}
74
75 int width() const { return fWidth; }
76 int height() const { return fHeight; }
77 bool isAlphaOnly() const { return fIsAlphaOnly; }
78 virtual SkAlphaType alphaType() const = 0;
79
80protected:
Robert Phillips51e7ca32017-03-27 10:14:08 -040081 friend class GrTextureProducer_TestAccess;
82
Brian Osmane8e54582016-11-28 10:06:27 -050083 GrTextureProducer(int width, int height, bool isAlphaOnly)
84 : fWidth(width)
85 , fHeight(height)
86 , fIsAlphaOnly(isAlphaOnly) {}
87
88 /** Helper for creating a key for a copy from an original key. */
89 static void MakeCopyKeyFromOrigKey(const GrUniqueKey& origKey,
90 const CopyParams& copyParams,
91 GrUniqueKey* copyKey) {
92 SkASSERT(!copyKey->isValid());
93 if (origKey.isValid()) {
94 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
95 GrUniqueKey::Builder builder(copyKey, origKey, kDomain, 3);
Brian Salomon2bbdcc42017-09-07 12:36:34 -040096 builder[0] = static_cast<uint32_t>(copyParams.fFilter);
Brian Osmane8e54582016-11-28 10:06:27 -050097 builder[1] = copyParams.fWidth;
98 builder[2] = copyParams.fHeight;
99 }
100 }
101
102 /**
103 * If we need to make a copy in order to be compatible with GrTextureParams producer is asked to
104 * return a key that identifies its original content + the CopyParms parameter. If the producer
105 * does not want to cache the stretched version (e.g. the producer is volatile), this should
106 * simply return without initializing the copyKey. If the texture generated by this producer
Brian Osman61624f02016-12-09 14:51:59 -0500107 * depends on the destination color space, then that information should also be incorporated
108 * in the key.
Brian Osmane8e54582016-11-28 10:06:27 -0500109 */
110 virtual void makeCopyKey(const CopyParams&, GrUniqueKey* copyKey,
Brian Osman61624f02016-12-09 14:51:59 -0500111 SkColorSpace* dstColorSpace) = 0;
Brian Osmane8e54582016-11-28 10:06:27 -0500112
113 /**
114 * If a stretched version of the texture is generated, it may be cached (assuming that
115 * makeCopyKey() returns true). In that case, the maker is notified in case it
116 * wants to note that for when the maker is destroyed.
117 */
118 virtual void didCacheCopy(const GrUniqueKey& copyKey) = 0;
119
120
121 enum DomainMode {
122 kNoDomain_DomainMode,
123 kDomain_DomainMode,
124 kTightCopy_DomainMode
125 };
126
Robert Phillipsb66b42f2017-03-14 08:53:02 -0400127 static sk_sp<GrTextureProxy> CopyOnGpu(GrContext*, sk_sp<GrTextureProxy> inputProxy,
Brian Salomon4df00922017-09-07 16:34:11 +0000128 const SkIRect* subset, const CopyParams& copyParams);
Robert Phillipsb66b42f2017-03-14 08:53:02 -0400129
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400130 static DomainMode DetermineDomainMode(const SkRect& constraintRect,
131 FilterConstraint filterConstraint,
132 bool coordsLimitedToConstraintRect,
133 GrTextureProxy*,
134 const SkIRect* textureContentArea,
135 const GrSamplerState::Filter* filterModeOrNullForBicubic,
136 SkRect* domainRect);
Robert Phillips51e7ca32017-03-27 10:14:08 -0400137
Brian Salomonaff329b2017-08-11 09:40:37 -0400138 static std::unique_ptr<GrFragmentProcessor> CreateFragmentProcessorForDomainAndFilter(
139 sk_sp<GrTextureProxy> proxy,
140 sk_sp<GrColorSpaceXform>,
141 const SkMatrix& textureMatrix,
142 DomainMode,
143 const SkRect& domain,
Brian Salomon2bbdcc42017-09-07 12:36:34 -0400144 const GrSamplerState::Filter* filterOrNullForBicubic);
Robert Phillipsb66b42f2017-03-14 08:53:02 -0400145
Brian Osmane8e54582016-11-28 10:06:27 -0500146private:
147 const int fWidth;
148 const int fHeight;
149 const bool fIsAlphaOnly;
150
151 typedef SkNoncopyable INHERITED;
152};
153
154#endif