1 /*
2  * Copyright 2012 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 GrTextureAccess_DEFINED
9 #define GrTextureAccess_DEFINED
10 
11 #include "GrGpuResourceRef.h"
12 #include "GrTexture.h"
13 #include "SkRefCnt.h"
14 #include "SkShader.h"
15 
16 /**
17  * Represents the filtering and tile modes used to access a texture. It is mostly used with
18  * GrTextureAccess (defined below). Also, some of the texture cache methods require knowledge about
19  * filtering and tiling to perform a cache lookup. If it wasn't for this latter usage this would
20  * be folded into GrTextureAccess. The default is clamp tile modes and no filtering.
21  */
22 class GrTextureParams {
23 public:
GrTextureParams()24     GrTextureParams() {
25         this->reset();
26     }
27 
28     enum FilterMode {
29         kNone_FilterMode,
30         kBilerp_FilterMode,
31         kMipMap_FilterMode
32     };
33 
GrTextureParams(SkShader::TileMode tileXAndY,FilterMode filterMode)34     GrTextureParams(SkShader::TileMode tileXAndY, FilterMode filterMode) {
35         this->reset(tileXAndY, filterMode);
36     }
37 
GrTextureParams(const SkShader::TileMode tileModes[2],FilterMode filterMode)38     GrTextureParams(const SkShader::TileMode tileModes[2], FilterMode filterMode) {
39         this->reset(tileModes, filterMode);
40     }
41 
GrTextureParams(const GrTextureParams & params)42     GrTextureParams(const GrTextureParams& params) {
43         *this = params;
44     }
45 
46     GrTextureParams& operator= (const GrTextureParams& params) {
47         fTileModes[0] = params.fTileModes[0];
48         fTileModes[1] = params.fTileModes[1];
49         fFilterMode = params.fFilterMode;
50         return *this;
51     }
52 
reset()53     void reset() {
54         this->reset(SkShader::kClamp_TileMode, kNone_FilterMode);
55     }
56 
reset(SkShader::TileMode tileXAndY,FilterMode filterMode)57     void reset(SkShader::TileMode tileXAndY, FilterMode filterMode) {
58         fTileModes[0] = fTileModes[1] = tileXAndY;
59         fFilterMode = filterMode;
60     }
61 
reset(const SkShader::TileMode tileModes[2],FilterMode filterMode)62     void reset(const SkShader::TileMode tileModes[2], FilterMode filterMode) {
63         fTileModes[0] = tileModes[0];
64         fTileModes[1] = tileModes[1];
65         fFilterMode = filterMode;
66     }
67 
setClampNoFilter()68     void setClampNoFilter() {
69         fTileModes[0] = fTileModes[1] = SkShader::kClamp_TileMode;
70         fFilterMode = kNone_FilterMode;
71     }
72 
setClamp()73     void setClamp() {
74         fTileModes[0] = fTileModes[1] = SkShader::kClamp_TileMode;
75     }
76 
setFilterMode(FilterMode filterMode)77     void setFilterMode(FilterMode filterMode) { fFilterMode = filterMode; }
78 
setTileModeX(const SkShader::TileMode tm)79     void setTileModeX(const SkShader::TileMode tm) { fTileModes[0] = tm; }
setTileModeY(const SkShader::TileMode tm)80     void setTileModeY(const SkShader::TileMode tm) { fTileModes[1] = tm; }
setTileModeXAndY(const SkShader::TileMode tm)81     void setTileModeXAndY(const SkShader::TileMode tm) { fTileModes[0] = fTileModes[1] = tm; }
82 
getTileModeX()83     SkShader::TileMode getTileModeX() const { return fTileModes[0]; }
84 
getTileModeY()85     SkShader::TileMode getTileModeY() const { return fTileModes[1]; }
86 
isTiled()87     bool isTiled() const {
88         return SkShader::kClamp_TileMode != fTileModes[0] ||
89                SkShader::kClamp_TileMode != fTileModes[1];
90     }
91 
filterMode()92     FilterMode filterMode() const { return fFilterMode; }
93 
94     bool operator== (const GrTextureParams& other) const {
95         return fTileModes[0] == other.fTileModes[0] &&
96                fTileModes[1] == other.fTileModes[1] &&
97                fFilterMode == other.fFilterMode;
98     }
99 
100     bool operator!= (const GrTextureParams& other) const { return !(*this == other); }
101 
102 private:
103 
104     SkShader::TileMode fTileModes[2];
105     FilterMode         fFilterMode;
106 };
107 
108 /** A class representing the swizzle access pattern for a texture. Note that if the texture is
109  *  an alpha-only texture then the alpha channel is substituted for other components. Any mangling
110  *  to handle the r,g,b->a conversions for alpha textures is automatically included in the stage
111  *  key. However, if a GrProcessor uses different swizzles based on its input then it must
112  *  consider that variation in its key-generation.
113  */
114 class GrTextureAccess : public SkNoncopyable {
115 public:
116     SK_DECLARE_INST_COUNT(GrTextureAccess);
117 
118     /**
119      * A default GrTextureAccess must have reset() called on it in a GrProcessor subclass's
120      * constructor if it will be accessible via GrProcessor::textureAccess().
121      */
122     GrTextureAccess();
123 
124     /**
125      * Uses the default swizzle, "rgba".
126      */
127     GrTextureAccess(GrTexture*, const GrTextureParams&);
128     explicit GrTextureAccess(GrTexture*,
129                              GrTextureParams::FilterMode = GrTextureParams::kNone_FilterMode,
130                              SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode);
131 
132     /**
133      * swizzle must be a string between one and four (inclusive) characters containing only 'r',
134      * 'g', 'b',  and/or 'a'.
135      */
136     GrTextureAccess(GrTexture*, const char* swizzle, const GrTextureParams&);
137     GrTextureAccess(GrTexture*,
138                     const char* swizzle,
139                     GrTextureParams::FilterMode = GrTextureParams::kNone_FilterMode,
140                     SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode);
141 
142     void reset(GrTexture*, const GrTextureParams&);
143     void reset(GrTexture*,
144                GrTextureParams::FilterMode = GrTextureParams::kNone_FilterMode,
145                SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode);
146     void reset(GrTexture*, const char* swizzle, const GrTextureParams&);
147     void reset(GrTexture*,
148                const char* swizzle,
149                GrTextureParams::FilterMode = GrTextureParams::kNone_FilterMode,
150                SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode);
151 
152     bool operator== (const GrTextureAccess& other) const {
153 #ifdef SK_DEBUG
154         // below assumes all chars in fSwizzle are initialized even if string is < 4 chars long.
155         SkASSERT(memcmp(fSwizzle, other.fSwizzle, sizeof(fSwizzle)-1) ==
156                  strcmp(fSwizzle, other.fSwizzle));
157 #endif
158         return fParams == other.fParams &&
159                (this->getTexture() == other.getTexture()) &&
160                (0 == memcmp(fSwizzle, other.fSwizzle, sizeof(fSwizzle)-1));
161     }
162 
163     bool operator!= (const GrTextureAccess& other) const { return !(*this == other); }
164 
getTexture()165     GrTexture* getTexture() const { return fTexture.get(); }
166 
167     /**
168      * For internal use by GrProcessor.
169      */
getProgramTexture()170     const GrGpuResourceRef* getProgramTexture() const { return &fTexture; }
171 
172     /**
173      * Returns a string representing the swizzle. The string is is null-terminated.
174      */
getSwizzle()175     const char* getSwizzle() const { return fSwizzle; }
176 
177     /** Returns a mask indicating which components are referenced in the swizzle. The return
178         is a bitfield of GrColorComponentFlags. */
swizzleMask()179     uint32_t swizzleMask() const { return fSwizzleMask; }
180 
getParams()181     const GrTextureParams& getParams() const { return fParams; }
182 
183 private:
184     void setSwizzle(const char*);
185 
186     typedef GrTGpuResourceRef<GrTexture> ProgramTexture;
187 
188     ProgramTexture                  fTexture;
189     GrTextureParams                 fParams;
190     uint32_t                        fSwizzleMask;
191     char                            fSwizzle[5];
192 
193     typedef SkNoncopyable INHERITED;
194 };
195 
196 #endif
197