blob: 4377ae5af3ad11c92e104916a0398d0745a6e47a [file] [log] [blame]
bsalomon045802d2015-10-20 07:58:01 -07001/*
2 * Copyright 2015 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 GrTextureMaker_DEFINED
9#define GrTextureMaker_DEFINED
10
11#include "GrTextureParams.h"
12#include "GrResourceKey.h"
bsalomonc55271f2015-11-09 11:55:57 -080013#include "GrTexture.h"
bsalomon89fe56b2015-10-29 10:49:28 -070014#include "SkTLazy.h"
bsalomon045802d2015-10-20 07:58:01 -070015
16class GrContext;
bsalomon045802d2015-10-20 07:58:01 -070017class GrTextureParams;
18class GrUniqueKey;
19class SkBitmap;
20
21/**
22 * Different GPUs and API extensions have different requirements with respect to what texture
23 * sampling parameters may be used with textures of various types. This class facilitates making
bsalomon89fe56b2015-10-29 10:49:28 -070024 * texture compatible with a given GrTextureParams. There are two immediate subclasses defined
25 * below. One is a base class for sources that are inherently texture-backed (e.g. a texture-backed
26 * SkImage). It supports subsetting the original texture. The other is for use cases where the
27 * source can generate a texture that represents some content (e.g. cpu pixels, SkPicture, ...).
bsalomon045802d2015-10-20 07:58:01 -070028 */
bsalomon89fe56b2015-10-29 10:49:28 -070029class GrTextureProducer : public SkNoncopyable {
bsalomon045802d2015-10-20 07:58:01 -070030public:
31 struct CopyParams {
32 GrTextureParams::FilterMode fFilter;
33 int fWidth;
34 int fHeight;
35 };
36
bsalomonb1b01992015-11-18 10:56:08 -080037 enum FilterConstraint {
38 kYes_FilterConstraint,
39 kNo_FilterConstraint,
40 };
41
42 /**
43 * Helper for creating a fragment processor to sample the texture with a given filtering mode.
44 * It attempts to avoid making texture copies or using domains whenever possible.
45 *
46 * @param textureMatrix Matrix used to access the texture. It is applied to
47 * the local coords. The post-transformed coords should
48 * be in texel units (rather than normalized) with
49 * respect to this Producer's bounds (width()/height()).
50 * @param constraintRect A rect that represents the area of the texture to be
51 * sampled. It must be contained in the Producer's bounds
52 * as defined by width()/height().
53 * @param filterConstriant Indicates whether filtering is limited to
54 * constraintRect.
55 * @param coordsLimitedToConstraintRect Is it known that textureMatrix*localCoords is bound
56 * by the portion of the texture indicated by
57 * constraintRect (without consideration of filter
58 * width, just the raw coords).
59 * @param filterOrNullForBicubic If non-null indicates the filter mode. If null means
60 * use bicubic filtering.
61 **/
bungeman06ca8ec2016-06-09 08:01:03 -070062 virtual sk_sp<GrFragmentProcessor> createFragmentProcessor(
bsalomonb1b01992015-11-18 10:56:08 -080063 const SkMatrix& textureMatrix,
64 const SkRect& constraintRect,
65 FilterConstraint filterConstraint,
66 bool coordsLimitedToConstraintRect,
brianosman982eb7f2016-06-06 13:10:58 -070067 const GrTextureParams::FilterMode* filterOrNullForBicubic,
brianosman500bb3e2016-07-22 10:33:07 -070068 SkColorSpace* dstColorSpace,
brianosman982eb7f2016-06-06 13:10:58 -070069 SkSourceGammaTreatment) = 0;
bsalomonb1b01992015-11-18 10:56:08 -080070
bsalomon89fe56b2015-10-29 10:49:28 -070071 virtual ~GrTextureProducer() {}
72
bsalomon3aa5fce2015-11-12 09:59:44 -080073 int width() const { return fWidth; }
74 int height() const { return fHeight; }
bsalomonf1ecd212015-12-09 17:06:02 -080075 bool isAlphaOnly() const { return fIsAlphaOnly; }
brianosmandddbe382016-07-20 13:55:39 -070076 virtual SkColorSpace* getColorSpace() = 0;
bsalomon3aa5fce2015-11-12 09:59:44 -080077
bsalomon89fe56b2015-10-29 10:49:28 -070078protected:
bsalomonf1ecd212015-12-09 17:06:02 -080079 GrTextureProducer(int width, int height, bool isAlphaOnly)
80 : fWidth(width)
81 , fHeight(height)
82 , fIsAlphaOnly(isAlphaOnly) {}
bsalomon3aa5fce2015-11-12 09:59:44 -080083
bsalomon89fe56b2015-10-29 10:49:28 -070084 /** Helper for creating a key for a copy from an original key. */
85 static void MakeCopyKeyFromOrigKey(const GrUniqueKey& origKey,
86 const CopyParams& copyParams,
87 GrUniqueKey* copyKey) {
88 SkASSERT(!copyKey->isValid());
89 if (origKey.isValid()) {
90 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
91 GrUniqueKey::Builder builder(copyKey, origKey, kDomain, 3);
92 builder[0] = copyParams.fFilter;
93 builder[1] = copyParams.fWidth;
94 builder[2] = copyParams.fHeight;
95 }
96 }
97
98 /**
99 * If we need to make a copy in order to be compatible with GrTextureParams producer is asked to
100 * return a key that identifies its original content + the CopyParms parameter. If the producer
101 * does not want to cache the stretched version (e.g. the producer is volatile), this should
102 * simply return without initializing the copyKey.
103 */
104 virtual void makeCopyKey(const CopyParams&, GrUniqueKey* copyKey) = 0;
105
106 /**
107 * If a stretched version of the texture is generated, it may be cached (assuming that
108 * makeCopyKey() returns true). In that case, the maker is notified in case it
109 * wants to note that for when the maker is destroyed.
110 */
111 virtual void didCacheCopy(const GrUniqueKey& copyKey) = 0;
112
bsalomon3aa5fce2015-11-12 09:59:44 -0800113private:
bsalomonf1ecd212015-12-09 17:06:02 -0800114 const int fWidth;
115 const int fHeight;
116 const bool fIsAlphaOnly;
bsalomon3aa5fce2015-11-12 09:59:44 -0800117
bsalomon89fe56b2015-10-29 10:49:28 -0700118 typedef SkNoncopyable INHERITED;
119};
120
bsalomonc75be342015-10-29 12:34:31 -0700121/**
122 * Base class for sources that start out as textures. Optionally allows for a content area subrect.
123 * The intent is not to use content area for subrect rendering. Rather, the pixels outside the
124 * content area have undefined values and shouldn't be read *regardless* of filtering mode or
125 * the SkCanvas::SrcRectConstraint used for subrect draws.
126 */
bsalomon89fe56b2015-10-29 10:49:28 -0700127class GrTextureAdjuster : public GrTextureProducer {
128public:
129 /** Makes the subset of the texture safe to use with the given texture parameters.
130 outOffset will be the top-left corner of the subset if a copy is not made. Otherwise,
131 the copy will be tight to the contents and outOffset will be (0, 0). If the copy's size
132 does not match subset's dimensions then the contents are scaled to fit the copy.*/
brianosman982eb7f2016-06-06 13:10:58 -0700133 GrTexture* refTextureSafeForParams(const GrTextureParams&, SkSourceGammaTreatment,
134 SkIPoint* outOffset);
bsalomon89fe56b2015-10-29 10:49:28 -0700135
bungeman06ca8ec2016-06-09 08:01:03 -0700136 sk_sp<GrFragmentProcessor> createFragmentProcessor(
bsalomonb1b01992015-11-18 10:56:08 -0800137 const SkMatrix& textureMatrix,
138 const SkRect& constraintRect,
139 FilterConstraint,
140 bool coordsLimitedToConstraintRect,
brianosman982eb7f2016-06-06 13:10:58 -0700141 const GrTextureParams::FilterMode* filterOrNullForBicubic,
brianosman500bb3e2016-07-22 10:33:07 -0700142 SkColorSpace* dstColorSpace,
brianosman982eb7f2016-06-06 13:10:58 -0700143 SkSourceGammaTreatment) override;
bsalomonc55271f2015-11-09 11:55:57 -0800144
bsalomon89fe56b2015-10-29 10:49:28 -0700145protected:
bsalomonc75be342015-10-29 12:34:31 -0700146 /** The whole texture is content. */
bsalomonf1ecd212015-12-09 17:06:02 -0800147 explicit GrTextureAdjuster(GrTexture* original, bool isAlphaOnly)
148 : INHERITED(original->width(), original->height(), isAlphaOnly)
bsalomon3aa5fce2015-11-12 09:59:44 -0800149 , fOriginal(original) {}
bsalomon89fe56b2015-10-29 10:49:28 -0700150
bsalomonf1ecd212015-12-09 17:06:02 -0800151 GrTextureAdjuster(GrTexture* original, const SkIRect& contentArea, bool isAlphaOnly);
bsalomon89fe56b2015-10-29 10:49:28 -0700152
bsalomon3aa5fce2015-11-12 09:59:44 -0800153 GrTexture* originalTexture() const { return fOriginal; }
154
bsalomonc75be342015-10-29 12:34:31 -0700155 /** Returns the content area or null for the whole original texture */
bsalomonc55271f2015-11-09 11:55:57 -0800156 const SkIRect* contentAreaOrNull() { return fContentArea.getMaybeNull(); }
bsalomon89fe56b2015-10-29 10:49:28 -0700157
158private:
bsalomonc75be342015-10-29 12:34:31 -0700159 SkTLazy<SkIRect> fContentArea;
bsalomon89fe56b2015-10-29 10:49:28 -0700160 GrTexture* fOriginal;
161
bsalomone179a912016-01-20 06:18:10 -0800162 GrTexture* refCopy(const CopyParams &copyParams);
163
bsalomon89fe56b2015-10-29 10:49:28 -0700164 typedef GrTextureProducer INHERITED;
165};
166
mtklein64593522015-11-12 10:41:05 -0800167/**
bsalomon89fe56b2015-10-29 10:49:28 -0700168 * Base class for sources that start out as something other than a texture (encoded image,
169 * picture, ...).
170 */
171class GrTextureMaker : public GrTextureProducer {
172public:
bsalomon89fe56b2015-10-29 10:49:28 -0700173 /** Returns a texture that is safe for use with the params. If the size of the returned texture
174 does not match width()/height() then the contents of the original must be scaled to fit
175 the texture. */
brianosman982eb7f2016-06-06 13:10:58 -0700176 GrTexture* refTextureForParams(const GrTextureParams&, SkSourceGammaTreatment);
bsalomonb1b01992015-11-18 10:56:08 -0800177
bungeman06ca8ec2016-06-09 08:01:03 -0700178 sk_sp<GrFragmentProcessor> createFragmentProcessor(
bsalomonb1b01992015-11-18 10:56:08 -0800179 const SkMatrix& textureMatrix,
180 const SkRect& constraintRect,
181 FilterConstraint filterConstraint,
182 bool coordsLimitedToConstraintRect,
brianosman982eb7f2016-06-06 13:10:58 -0700183 const GrTextureParams::FilterMode* filterOrNullForBicubic,
brianosman500bb3e2016-07-22 10:33:07 -0700184 SkColorSpace* dstColorSpace,
brianosman982eb7f2016-06-06 13:10:58 -0700185 SkSourceGammaTreatment) override;
bsalomon045802d2015-10-20 07:58:01 -0700186
187protected:
bsalomonf1ecd212015-12-09 17:06:02 -0800188 GrTextureMaker(GrContext* context, int width, int height, bool isAlphaOnly)
189 : INHERITED(width, height, isAlphaOnly)
bsalomonb1b01992015-11-18 10:56:08 -0800190 , fContext(context) {}
bsalomon3aa5fce2015-11-12 09:59:44 -0800191
bsalomon045802d2015-10-20 07:58:01 -0700192 /**
bsalomonb1b01992015-11-18 10:56:08 -0800193 * Return the maker's "original" texture. It is the responsibility of the maker to handle any
194 * caching of the original if desired.
bsalomon045802d2015-10-20 07:58:01 -0700195 */
brianosman982eb7f2016-06-06 13:10:58 -0700196 virtual GrTexture* refOriginalTexture(bool willBeMipped, SkSourceGammaTreatment) = 0;
bsalomon045802d2015-10-20 07:58:01 -0700197
198 /**
199 * Return a new (uncached) texture that is the stretch of the maker's original.
200 *
201 * The base-class handles general logic for this, and only needs access to the following
bsalomon100b8f82015-10-28 08:37:44 -0700202 * method:
203 * - refOriginalTexture()
bsalomon045802d2015-10-20 07:58:01 -0700204 *
205 * Subclass may override this if they can handle creating the texture more directly than
206 * by copying.
207 */
brianosman982eb7f2016-06-06 13:10:58 -0700208 virtual GrTexture* generateTextureForParams(const CopyParams&, bool willBeMipped,
209 SkSourceGammaTreatment);
bsalomonb1b01992015-11-18 10:56:08 -0800210
211 GrContext* context() const { return fContext; }
bsalomon045802d2015-10-20 07:58:01 -0700212
bsalomon045802d2015-10-20 07:58:01 -0700213private:
bsalomonb1b01992015-11-18 10:56:08 -0800214 GrContext* fContext;
215
bsalomon89fe56b2015-10-29 10:49:28 -0700216 typedef GrTextureProducer INHERITED;
bsalomon045802d2015-10-20 07:58:01 -0700217};
218
219#endif