Line data Source code
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 :
8 : #ifndef GrTextureProducer_DEFINED
9 : #define GrTextureProducer_DEFINED
10 :
11 : #include "GrSamplerParams.h"
12 : #include "GrResourceKey.h"
13 :
14 : class GrColorSpaceXform;
15 : class GrResourceProvider;
16 : class GrTexture;
17 : class GrTextureProxy;
18 :
19 : /**
20 : * Different GPUs and API extensions have different requirements with respect to what texture
21 : * sampling parameters may be used with textures of various types. This class facilitates making
22 : * texture compatible with a given GrSamplerParams. There are two immediate subclasses defined
23 : * below. One is a base class for sources that are inherently texture-backed (e.g. a texture-backed
24 : * SkImage). It supports subsetting the original texture. The other is for use cases where the
25 : * source can generate a texture that represents some content (e.g. cpu pixels, SkPicture, ...).
26 : */
27 : class GrTextureProducer : public SkNoncopyable {
28 : public:
29 : struct CopyParams {
30 : GrSamplerParams::FilterMode fFilter;
31 : int fWidth;
32 : int fHeight;
33 : };
34 :
35 : enum FilterConstraint {
36 : kYes_FilterConstraint,
37 : kNo_FilterConstraint,
38 : };
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 sk_sp<GrFragmentProcessor> createFragmentProcessor(
61 : const SkMatrix& textureMatrix,
62 : const SkRect& constraintRect,
63 : FilterConstraint filterConstraint,
64 : bool coordsLimitedToConstraintRect,
65 : const GrSamplerParams::FilterMode* filterOrNullForBicubic,
66 : SkColorSpace* dstColorSpace) = 0;
67 :
68 0 : virtual ~GrTextureProducer() {}
69 :
70 0 : int width() const { return fWidth; }
71 0 : int height() const { return fHeight; }
72 0 : bool isAlphaOnly() const { return fIsAlphaOnly; }
73 : virtual SkAlphaType alphaType() const = 0;
74 :
75 : protected:
76 : friend class GrTextureProducer_TestAccess;
77 :
78 0 : GrTextureProducer(int width, int height, bool isAlphaOnly)
79 0 : : fWidth(width)
80 : , fHeight(height)
81 0 : , fIsAlphaOnly(isAlphaOnly) {}
82 :
83 : /** Helper for creating a key for a copy from an original key. */
84 0 : static void MakeCopyKeyFromOrigKey(const GrUniqueKey& origKey,
85 : const CopyParams& copyParams,
86 : GrUniqueKey* copyKey) {
87 0 : SkASSERT(!copyKey->isValid());
88 0 : if (origKey.isValid()) {
89 0 : static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
90 0 : GrUniqueKey::Builder builder(copyKey, origKey, kDomain, 3);
91 0 : builder[0] = copyParams.fFilter;
92 0 : builder[1] = copyParams.fWidth;
93 0 : builder[2] = copyParams.fHeight;
94 : }
95 0 : }
96 :
97 : /**
98 : * If we need to make a copy in order to be compatible with GrTextureParams producer is asked to
99 : * return a key that identifies its original content + the CopyParms parameter. If the producer
100 : * does not want to cache the stretched version (e.g. the producer is volatile), this should
101 : * simply return without initializing the copyKey. If the texture generated by this producer
102 : * depends on the destination color space, then that information should also be incorporated
103 : * in the key.
104 : */
105 : virtual void makeCopyKey(const CopyParams&, GrUniqueKey* copyKey,
106 : SkColorSpace* dstColorSpace) = 0;
107 :
108 : /**
109 : * If a stretched version of the texture is generated, it may be cached (assuming that
110 : * makeCopyKey() returns true). In that case, the maker is notified in case it
111 : * wants to note that for when the maker is destroyed.
112 : */
113 : virtual void didCacheCopy(const GrUniqueKey& copyKey) = 0;
114 :
115 :
116 : enum DomainMode {
117 : kNoDomain_DomainMode,
118 : kDomain_DomainMode,
119 : kTightCopy_DomainMode
120 : };
121 :
122 : static sk_sp<GrTextureProxy> CopyOnGpu(GrContext*, sk_sp<GrTextureProxy> inputProxy,
123 : const SkIRect* subset, const CopyParams& copyParams);
124 :
125 : static DomainMode DetermineDomainMode(
126 : const SkRect& constraintRect,
127 : FilterConstraint filterConstraint,
128 : bool coordsLimitedToConstraintRect,
129 : GrTextureProxy*,
130 : const SkIRect* textureContentArea,
131 : const GrSamplerParams::FilterMode* filterModeOrNullForBicubic,
132 : SkRect* domainRect);
133 :
134 : static sk_sp<GrFragmentProcessor> CreateFragmentProcessorForDomainAndFilter(
135 : GrResourceProvider*,
136 : sk_sp<GrTextureProxy> proxy,
137 : sk_sp<GrColorSpaceXform>,
138 : const SkMatrix& textureMatrix,
139 : DomainMode,
140 : const SkRect& domain,
141 : const GrSamplerParams::FilterMode* filterOrNullForBicubic);
142 :
143 : private:
144 : const int fWidth;
145 : const int fHeight;
146 : const bool fIsAlphaOnly;
147 :
148 : typedef SkNoncopyable INHERITED;
149 : };
150 :
151 : #endif
|