• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ANDROID_HWUI_SKIA_SHADER_H
18 #define ANDROID_HWUI_SKIA_SHADER_H
19 
20 #include <SkShader.h>
21 #include <SkXfermode.h>
22 
23 #include <GLES2/gl2.h>
24 
25 #include "Extensions.h"
26 #include "ProgramCache.h"
27 #include "TextureCache.h"
28 #include "GradientCache.h"
29 #include "Snapshot.h"
30 
31 namespace android {
32 namespace uirenderer {
33 
34 ///////////////////////////////////////////////////////////////////////////////
35 // Base shader
36 ///////////////////////////////////////////////////////////////////////////////
37 
38 /**
39  * Represents a Skia shader. A shader will modify the GL context and active
40  * program to recreate the original effect.
41  */
42 struct SkiaShader {
43     /**
44      * Type of Skia shader in use.
45      */
46     enum Type {
47         kNone,
48         kBitmap,
49         kLinearGradient,
50         kCircularGradient,
51         kSweepGradient,
52         kCompose
53     };
54 
55     SkiaShader(Type type, SkShader* key, SkShader::TileMode tileX, SkShader::TileMode tileY,
56             SkMatrix* matrix, bool blend);
57     virtual ~SkiaShader();
58 
59     virtual SkiaShader* copy() = 0;
60     void copyFrom(const SkiaShader& shader);
61 
62     virtual void describe(ProgramDescription& description, const Extensions& extensions);
63     virtual void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
64             GLuint* textureUnit);
65 
getSkShaderSkiaShader66     inline SkShader *getSkShader() {
67         return mKey;
68     }
69 
blendSkiaShader70     inline bool blend() const {
71         return mBlend;
72     }
73 
typeSkiaShader74     Type type() const {
75         return mType;
76     }
77 
setSkiaShader78     virtual void set(TextureCache* textureCache, GradientCache* gradientCache) {
79         mTextureCache = textureCache;
80         mGradientCache = gradientCache;
81     }
82 
updateTransformsSkiaShader83     virtual void updateTransforms(Program* program, const mat4& modelView,
84             const Snapshot& snapshot) {
85     }
86 
getGenerationIdSkiaShader87     uint32_t getGenerationId() {
88         return mGenerationId;
89     }
90 
setMatrixSkiaShader91     void setMatrix(SkMatrix* matrix) {
92         updateLocalMatrix(matrix);
93         mGenerationId++;
94     }
95 
updateLocalMatrixSkiaShader96     void updateLocalMatrix(const SkMatrix* matrix) {
97         if (matrix) {
98             mat4 localMatrix(*matrix);
99             mShaderMatrix.loadInverse(localMatrix);
100         } else {
101             mShaderMatrix.loadIdentity();
102         }
103     }
104 
105     void computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView);
106 
107 protected:
SkiaShaderSkiaShader108     SkiaShader() {
109     }
110 
111     /**
112      * The appropriate texture unit must have been activated prior to invoking
113      * this method.
114      */
115     inline void bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT);
116 
117     Type mType;
118     SkShader* mKey;
119     SkShader::TileMode mTileX;
120     SkShader::TileMode mTileY;
121     bool mBlend;
122 
123     TextureCache* mTextureCache;
124     GradientCache* mGradientCache;
125 
126     mat4 mUnitMatrix;
127     mat4 mShaderMatrix;
128 
129 private:
130     uint32_t mGenerationId;
131 }; // struct SkiaShader
132 
133 
134 ///////////////////////////////////////////////////////////////////////////////
135 // Implementations
136 ///////////////////////////////////////////////////////////////////////////////
137 
138 /**
139  * A shader that draws a bitmap.
140  */
141 struct SkiaBitmapShader: public SkiaShader {
142     SkiaBitmapShader(SkBitmap* bitmap, SkShader* key, SkShader::TileMode tileX,
143             SkShader::TileMode tileY, SkMatrix* matrix, bool blend);
144     SkiaShader* copy();
145 
146     void describe(ProgramDescription& description, const Extensions& extensions);
147     void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
148             GLuint* textureUnit);
149     void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot);
150 
151 private:
SkiaBitmapShaderSkiaBitmapShader152     SkiaBitmapShader() {
153     }
154 
155     /**
156      * This method does not work for n == 0.
157      */
isPowerOfTwoSkiaBitmapShader158     inline bool isPowerOfTwo(unsigned int n) {
159         return !(n & (n - 1));
160     }
161 
162     SkBitmap* mBitmap;
163     Texture* mTexture;
164     GLenum mWrapS;
165     GLenum mWrapT;
166 }; // struct SkiaBitmapShader
167 
168 /**
169  * A shader that draws a linear gradient.
170  */
171 struct SkiaLinearGradientShader: public SkiaShader {
172     SkiaLinearGradientShader(float* bounds, uint32_t* colors, float* positions, int count,
173             SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
174     ~SkiaLinearGradientShader();
175     SkiaShader* copy();
176 
177     void describe(ProgramDescription& description, const Extensions& extensions);
178     void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
179             GLuint* textureUnit);
180     void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot);
181 
182 private:
SkiaLinearGradientShaderSkiaLinearGradientShader183     SkiaLinearGradientShader() {
184     }
185 
186     float* mBounds;
187     uint32_t* mColors;
188     float* mPositions;
189     int mCount;
190 }; // struct SkiaLinearGradientShader
191 
192 /**
193  * A shader that draws a sweep gradient.
194  */
195 struct SkiaSweepGradientShader: public SkiaShader {
196     SkiaSweepGradientShader(float x, float y, uint32_t* colors, float* positions, int count,
197             SkShader* key, SkMatrix* matrix, bool blend);
198     ~SkiaSweepGradientShader();
199     SkiaShader* copy();
200 
201     virtual void describe(ProgramDescription& description, const Extensions& extensions);
202     void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
203             GLuint* textureUnit);
204     void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot);
205 
206 protected:
207     SkiaSweepGradientShader(Type type, float x, float y, uint32_t* colors, float* positions,
208             int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
SkiaSweepGradientShaderSkiaSweepGradientShader209     SkiaSweepGradientShader() {
210     }
211 
212     uint32_t* mColors;
213     float* mPositions;
214     int mCount;
215 }; // struct SkiaSweepGradientShader
216 
217 /**
218  * A shader that draws a circular gradient.
219  */
220 struct SkiaCircularGradientShader: public SkiaSweepGradientShader {
221     SkiaCircularGradientShader(float x, float y, float radius, uint32_t* colors, float* positions,
222             int count, SkShader* key,SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
223     SkiaShader* copy();
224 
225     void describe(ProgramDescription& description, const Extensions& extensions);
226 
227 private:
SkiaCircularGradientShaderSkiaCircularGradientShader228     SkiaCircularGradientShader() {
229     }
230 }; // struct SkiaCircularGradientShader
231 
232 /**
233  * A shader that draws two shaders, composited with an xfermode.
234  */
235 struct SkiaComposeShader: public SkiaShader {
236     SkiaComposeShader(SkiaShader* first, SkiaShader* second, SkXfermode::Mode mode, SkShader* key);
237     ~SkiaComposeShader();
238     SkiaShader* copy();
239 
240     void set(TextureCache* textureCache, GradientCache* gradientCache);
241 
242     void describe(ProgramDescription& description, const Extensions& extensions);
243     void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
244             GLuint* textureUnit);
245 
246 private:
SkiaComposeShaderSkiaComposeShader247     SkiaComposeShader(): mCleanup(false) {
248     }
249 
cleanupSkiaComposeShader250     void cleanup() {
251         mCleanup = true;
252     }
253 
254     SkiaShader* mFirst;
255     SkiaShader* mSecond;
256     SkXfermode::Mode mMode;
257 
258     bool mCleanup;
259 }; // struct SkiaComposeShader
260 
261 }; // namespace uirenderer
262 }; // namespace android
263 
264 #endif // ANDROID_HWUI_SKIA_SHADER_H
265