blob: 2284cb4c052089663f5f1b1d5047c4690c6e350d [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
11#include "GrSamplerParams.h"
12#include "GrResourceKey.h"
13
14class GrColorSpaceXform;
15class GrTexture;
16
17/**
18 * Different GPUs and API extensions have different requirements with respect to what texture
19 * sampling parameters may be used with textures of various types. This class facilitates making
20 * texture compatible with a given GrSamplerParams. There are two immediate subclasses defined
21 * below. One is a base class for sources that are inherently texture-backed (e.g. a texture-backed
22 * SkImage). It supports subsetting the original texture. The other is for use cases where the
23 * source can generate a texture that represents some content (e.g. cpu pixels, SkPicture, ...).
24 */
25class GrTextureProducer : public SkNoncopyable {
26public:
27 struct CopyParams {
28 GrSamplerParams::FilterMode fFilter;
29 int fWidth;
30 int fHeight;
31 };
32
33 enum FilterConstraint {
34 kYes_FilterConstraint,
35 kNo_FilterConstraint,
36 };
37
38 /**
39 * Helper for creating a fragment processor to sample the texture with a given filtering mode.
40 * It attempts to avoid making texture copies or using domains whenever possible.
41 *
42 * @param textureMatrix Matrix used to access the texture. It is applied to
43 * the local coords. The post-transformed coords should
44 * be in texel units (rather than normalized) with
45 * respect to this Producer's bounds (width()/height()).
46 * @param constraintRect A rect that represents the area of the texture to be
47 * sampled. It must be contained in the Producer's
48 * bounds as defined by width()/height().
49 * @param filterConstriant Indicates whether filtering is limited to
50 * constraintRect.
51 * @param coordsLimitedToConstraintRect Is it known that textureMatrix*localCoords is bound
52 * by the portion of the texture indicated by
53 * constraintRect (without consideration of filter
54 * width, just the raw coords).
55 * @param filterOrNullForBicubic If non-null indicates the filter mode. If null means
56 * use bicubic filtering.
57 **/
58 virtual sk_sp<GrFragmentProcessor> createFragmentProcessor(
59 const SkMatrix& textureMatrix,
60 const SkRect& constraintRect,
61 FilterConstraint filterConstraint,
62 bool coordsLimitedToConstraintRect,
63 const GrSamplerParams::FilterMode* filterOrNullForBicubic,
Brian Osman61624f02016-12-09 14:51:59 -050064 SkColorSpace* dstColorSpace) = 0;
Brian Osmane8e54582016-11-28 10:06:27 -050065
66 virtual ~GrTextureProducer() {}
67
68 int width() const { return fWidth; }
69 int height() const { return fHeight; }
70 bool isAlphaOnly() const { return fIsAlphaOnly; }
71 virtual SkAlphaType alphaType() const = 0;
72
73protected:
74 GrTextureProducer(int width, int height, bool isAlphaOnly)
75 : fWidth(width)
76 , fHeight(height)
77 , fIsAlphaOnly(isAlphaOnly) {}
78
79 /** Helper for creating a key for a copy from an original key. */
80 static void MakeCopyKeyFromOrigKey(const GrUniqueKey& origKey,
81 const CopyParams& copyParams,
82 GrUniqueKey* copyKey) {
83 SkASSERT(!copyKey->isValid());
84 if (origKey.isValid()) {
85 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
86 GrUniqueKey::Builder builder(copyKey, origKey, kDomain, 3);
87 builder[0] = copyParams.fFilter;
88 builder[1] = copyParams.fWidth;
89 builder[2] = copyParams.fHeight;
90 }
91 }
92
93 /**
94 * If we need to make a copy in order to be compatible with GrTextureParams producer is asked to
95 * return a key that identifies its original content + the CopyParms parameter. If the producer
96 * does not want to cache the stretched version (e.g. the producer is volatile), this should
97 * simply return without initializing the copyKey. If the texture generated by this producer
Brian Osman61624f02016-12-09 14:51:59 -050098 * depends on the destination color space, then that information should also be incorporated
99 * in the key.
Brian Osmane8e54582016-11-28 10:06:27 -0500100 */
101 virtual void makeCopyKey(const CopyParams&, GrUniqueKey* copyKey,
Brian Osman61624f02016-12-09 14:51:59 -0500102 SkColorSpace* dstColorSpace) = 0;
Brian Osmane8e54582016-11-28 10:06:27 -0500103
104 /**
105 * If a stretched version of the texture is generated, it may be cached (assuming that
106 * makeCopyKey() returns true). In that case, the maker is notified in case it
107 * wants to note that for when the maker is destroyed.
108 */
109 virtual void didCacheCopy(const GrUniqueKey& copyKey) = 0;
110
111
112 enum DomainMode {
113 kNoDomain_DomainMode,
114 kDomain_DomainMode,
115 kTightCopy_DomainMode
116 };
117
118 static GrTexture* CopyOnGpu(GrTexture* inputTexture, const SkIRect* subset,
119 const CopyParams& copyParams);
120
121 static DomainMode DetermineDomainMode(
122 const SkRect& constraintRect,
123 FilterConstraint filterConstraint,
124 bool coordsLimitedToConstraintRect,
125 int texW, int texH,
126 const SkIRect* textureContentArea,
127 const GrSamplerParams::FilterMode* filterModeOrNullForBicubic,
128 SkRect* domainRect);
129
130 static sk_sp<GrFragmentProcessor> CreateFragmentProcessorForDomainAndFilter(
131 GrTexture* texture,
132 sk_sp<GrColorSpaceXform> colorSpaceXform,
133 const SkMatrix& textureMatrix,
134 DomainMode domainMode,
135 const SkRect& domain,
136 const GrSamplerParams::FilterMode* filterOrNullForBicubic);
137
138private:
139 const int fWidth;
140 const int fHeight;
141 const bool fIsAlphaOnly;
142
143 typedef SkNoncopyable INHERITED;
144};
145
146#endif