blob: 0a3d52970331e02da226ad26dcad38160846a53d [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"
bsalomon3aa5fce2015-11-12 09:59:44 -080014#include "SkFunction.h"
bsalomon89fe56b2015-10-29 10:49:28 -070015#include "SkTLazy.h"
bsalomon045802d2015-10-20 07:58:01 -070016
17class GrContext;
bsalomon045802d2015-10-20 07:58:01 -070018class GrTextureParams;
19class GrUniqueKey;
20class SkBitmap;
21
22/**
23 * Different GPUs and API extensions have different requirements with respect to what texture
24 * sampling parameters may be used with textures of various types. This class facilitates making
bsalomon89fe56b2015-10-29 10:49:28 -070025 * texture compatible with a given GrTextureParams. There are two immediate subclasses defined
26 * below. One is a base class for sources that are inherently texture-backed (e.g. a texture-backed
27 * SkImage). It supports subsetting the original texture. The other is for use cases where the
28 * source can generate a texture that represents some content (e.g. cpu pixels, SkPicture, ...).
bsalomon045802d2015-10-20 07:58:01 -070029 */
bsalomon89fe56b2015-10-29 10:49:28 -070030class GrTextureProducer : public SkNoncopyable {
bsalomon045802d2015-10-20 07:58:01 -070031public:
32 struct CopyParams {
33 GrTextureParams::FilterMode fFilter;
34 int fWidth;
35 int fHeight;
36 };
37
bsalomon89fe56b2015-10-29 10:49:28 -070038 virtual ~GrTextureProducer() {}
39
bsalomon3aa5fce2015-11-12 09:59:44 -080040 int width() const { return fWidth; }
41 int height() const { return fHeight; }
42
bsalomon89fe56b2015-10-29 10:49:28 -070043protected:
bsalomon3aa5fce2015-11-12 09:59:44 -080044 GrTextureProducer(int width, int height) : fWidth(width), fHeight(height) {}
45
bsalomon89fe56b2015-10-29 10:49:28 -070046 /** Helper for creating a key for a copy from an original key. */
47 static void MakeCopyKeyFromOrigKey(const GrUniqueKey& origKey,
48 const CopyParams& copyParams,
49 GrUniqueKey* copyKey) {
50 SkASSERT(!copyKey->isValid());
51 if (origKey.isValid()) {
52 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
53 GrUniqueKey::Builder builder(copyKey, origKey, kDomain, 3);
54 builder[0] = copyParams.fFilter;
55 builder[1] = copyParams.fWidth;
56 builder[2] = copyParams.fHeight;
57 }
58 }
59
60 /**
61 * If we need to make a copy in order to be compatible with GrTextureParams producer is asked to
62 * return a key that identifies its original content + the CopyParms parameter. If the producer
63 * does not want to cache the stretched version (e.g. the producer is volatile), this should
64 * simply return without initializing the copyKey.
65 */
66 virtual void makeCopyKey(const CopyParams&, GrUniqueKey* copyKey) = 0;
67
68 /**
69 * If a stretched version of the texture is generated, it may be cached (assuming that
70 * makeCopyKey() returns true). In that case, the maker is notified in case it
71 * wants to note that for when the maker is destroyed.
72 */
73 virtual void didCacheCopy(const GrUniqueKey& copyKey) = 0;
74
bsalomon3aa5fce2015-11-12 09:59:44 -080075private:
76 const int fWidth;
77 const int fHeight;
78
bsalomon89fe56b2015-10-29 10:49:28 -070079 typedef SkNoncopyable INHERITED;
80};
81
bsalomonc75be342015-10-29 12:34:31 -070082/**
83 * Base class for sources that start out as textures. Optionally allows for a content area subrect.
84 * The intent is not to use content area for subrect rendering. Rather, the pixels outside the
85 * content area have undefined values and shouldn't be read *regardless* of filtering mode or
86 * the SkCanvas::SrcRectConstraint used for subrect draws.
87 */
bsalomon89fe56b2015-10-29 10:49:28 -070088class GrTextureAdjuster : public GrTextureProducer {
89public:
90 /** Makes the subset of the texture safe to use with the given texture parameters.
91 outOffset will be the top-left corner of the subset if a copy is not made. Otherwise,
92 the copy will be tight to the contents and outOffset will be (0, 0). If the copy's size
93 does not match subset's dimensions then the contents are scaled to fit the copy.*/
94 GrTexture* refTextureSafeForParams(const GrTextureParams&, SkIPoint* outOffset);
95
bsalomonc55271f2015-11-09 11:55:57 -080096 enum FilterConstraint {
97 kYes_FilterConstraint,
98 kNo_FilterConstraint,
99 };
100
101 /**
102 * Helper for creating a fragment processor to sample the texture with a given filtering mode.
103 * It attempts to avoids making a copy of the texture and avoid using a texture domain unless
104 * necessary.
105 *
bsalomon3aa5fce2015-11-12 09:59:44 -0800106 * @param textureMatrix Matrix to apply to local coordinates to compute
107 * texel coordinates. The post-transformed coordinates
108 * should be in texels (relative to this->width() and
109 * this->height()) and not be normalized.
110 * @param constraintRect Subrect of content area to be rendered. The
111 * constraint rect is relative to the content area.
bsalomonc55271f2015-11-09 11:55:57 -0800112 * @param filterConstriant Indicates whether filtering is limited to
113 * constraintRect.
114 * @param coordsLimitedToConstraintRect Is it known that textureMatrix*localCoords is bound
115 * by the portion of the texture indicated by
116 * constraintRect (without consideration of filter
117 * width, just the raw coords).
118 * @param filterOrNullForBicubic If non-null indicates the filter mode. If null means
119 * use bicubic filtering.
120 **/
121 const GrFragmentProcessor* createFragmentProcessor(
122 const SkMatrix& textureMatrix,
123 const SkRect& constraintRect,
124 FilterConstraint filterConstraint,
125 bool coordsLimitedToConstraintRect,
126 const GrTextureParams::FilterMode* filterOrNullForBicubic);
127
bsalomon89fe56b2015-10-29 10:49:28 -0700128protected:
bsalomonc75be342015-10-29 12:34:31 -0700129 /** The whole texture is content. */
bsalomon3aa5fce2015-11-12 09:59:44 -0800130 explicit GrTextureAdjuster(GrTexture* original)
131 : INHERITED(original->width(), original->height())
132 , fOriginal(original) {}
bsalomon89fe56b2015-10-29 10:49:28 -0700133
bsalomonc75be342015-10-29 12:34:31 -0700134 GrTextureAdjuster(GrTexture* original, const SkIRect& contentArea);
bsalomon89fe56b2015-10-29 10:49:28 -0700135
bsalomon3aa5fce2015-11-12 09:59:44 -0800136 GrTexture* originalTexture() const { return fOriginal; }
137
bsalomonc75be342015-10-29 12:34:31 -0700138 /** Returns the content area or null for the whole original texture */
bsalomonc55271f2015-11-09 11:55:57 -0800139 const SkIRect* contentAreaOrNull() { return fContentArea.getMaybeNull(); }
bsalomon89fe56b2015-10-29 10:49:28 -0700140
141private:
bsalomonc75be342015-10-29 12:34:31 -0700142 SkTLazy<SkIRect> fContentArea;
bsalomon89fe56b2015-10-29 10:49:28 -0700143 GrTexture* fOriginal;
144
145 typedef GrTextureProducer INHERITED;
146};
147
148/**
149 * Base class for sources that start out as something other than a texture (encoded image,
150 * picture, ...).
151 */
152class GrTextureMaker : public GrTextureProducer {
153public:
bsalomon89fe56b2015-10-29 10:49:28 -0700154 /** Returns a texture that is safe for use with the params. If the size of the returned texture
155 does not match width()/height() then the contents of the original must be scaled to fit
156 the texture. */
bsalomon045802d2015-10-20 07:58:01 -0700157 GrTexture* refTextureForParams(GrContext*, const GrTextureParams&);
158
159protected:
bsalomon3aa5fce2015-11-12 09:59:44 -0800160 GrTextureMaker(int width, int height) : INHERITED(width, height) {}
161
bsalomon045802d2015-10-20 07:58:01 -0700162 /**
163 * Return the maker's "original" texture. It is the responsibility of the maker
164 * to make this efficient ... if the texture is being generated, the maker must handle
165 * caching it (if desired).
166 */
167 virtual GrTexture* refOriginalTexture(GrContext*) = 0;
168
169 /**
bsalomon89fe56b2015-10-29 10:49:28 -0700170 * If we need to copy the producer's original texture, the producer is asked to return a key
bsalomon045802d2015-10-20 07:58:01 -0700171 * that identifies its original + the CopyParms parameter. If the maker does not want to cache
bsalomon89fe56b2015-10-29 10:49:28 -0700172 * the stretched version (e.g. the producer is volatile), this should simply return without
bsalomon045802d2015-10-20 07:58:01 -0700173 * initializing the copyKey.
174 */
175 virtual void makeCopyKey(const CopyParams&, GrUniqueKey* copyKey) = 0;
176
177 /**
178 * Return a new (uncached) texture that is the stretch of the maker's original.
179 *
180 * The base-class handles general logic for this, and only needs access to the following
bsalomon100b8f82015-10-28 08:37:44 -0700181 * method:
182 * - refOriginalTexture()
bsalomon045802d2015-10-20 07:58:01 -0700183 *
184 * Subclass may override this if they can handle creating the texture more directly than
185 * by copying.
186 */
187 virtual GrTexture* generateTextureForParams(GrContext*, const CopyParams&);
188
bsalomon045802d2015-10-20 07:58:01 -0700189private:
bsalomon89fe56b2015-10-29 10:49:28 -0700190 typedef GrTextureProducer INHERITED;
bsalomon045802d2015-10-20 07:58:01 -0700191};
192
193#endif