• 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 <cutils/compiler.h>
26 
27 #include "Extensions.h"
28 #include "ProgramCache.h"
29 #include "TextureCache.h"
30 #include "GradientCache.h"
31 #include "Snapshot.h"
32 
33 namespace android {
34 namespace uirenderer {
35 
36 ///////////////////////////////////////////////////////////////////////////////
37 // Base shader
38 ///////////////////////////////////////////////////////////////////////////////
39 
40 /**
41  * Represents a Skia shader. A shader will modify the GL context and active
42  * program to recreate the original effect.
43  */
44 struct SkiaShader {
45     /**
46      * Type of Skia shader in use.
47      */
48     enum Type {
49         kNone,
50         kBitmap,
51         kLinearGradient,
52         kCircularGradient,
53         kSweepGradient,
54         kCompose
55     };
56 
57     ANDROID_API SkiaShader(Type type, SkShader* key, SkShader::TileMode tileX,
58             SkShader::TileMode tileY, SkMatrix* matrix, bool blend);
59     virtual ~SkiaShader();
60 
61     virtual SkiaShader* copy() = 0;
62     void copyFrom(const SkiaShader& shader);
63 
64     virtual void describe(ProgramDescription& description, const Extensions& extensions);
65     virtual void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
66             GLuint* textureUnit);
67 
getSkShaderSkiaShader68     inline SkShader *getSkShader() {
69         return mKey;
70     }
71 
blendSkiaShader72     inline bool blend() const {
73         return mBlend;
74     }
75 
typeSkiaShader76     Type type() const {
77         return mType;
78     }
79 
setSkiaShader80     virtual void set(TextureCache* textureCache, GradientCache* gradientCache) {
81         mTextureCache = textureCache;
82         mGradientCache = gradientCache;
83     }
84 
updateTransformsSkiaShader85     virtual void updateTransforms(Program* program, const mat4& modelView,
86             const Snapshot& snapshot) {
87     }
88 
getGenerationIdSkiaShader89     uint32_t getGenerationId() {
90         return mGenerationId;
91     }
92 
setMatrixSkiaShader93     void setMatrix(SkMatrix* matrix) {
94         updateLocalMatrix(matrix);
95         mGenerationId++;
96     }
97 
updateLocalMatrixSkiaShader98     void updateLocalMatrix(const SkMatrix* matrix) {
99         if (matrix) {
100             mat4 localMatrix(*matrix);
101             mShaderMatrix.loadInverse(localMatrix);
102         } else {
103             mShaderMatrix.loadIdentity();
104         }
105     }
106 
107     void computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView);
108 
109 protected:
SkiaShaderSkiaShader110     SkiaShader() {
111     }
112 
113     /**
114      * The appropriate texture unit must have been activated prior to invoking
115      * this method.
116      */
117     inline void bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT);
118 
119     Type mType;
120     SkShader* mKey;
121     SkShader::TileMode mTileX;
122     SkShader::TileMode mTileY;
123     bool mBlend;
124 
125     TextureCache* mTextureCache;
126     GradientCache* mGradientCache;
127 
128     mat4 mUnitMatrix;
129     mat4 mShaderMatrix;
130 
131 private:
132     uint32_t mGenerationId;
133 }; // struct SkiaShader
134 
135 
136 ///////////////////////////////////////////////////////////////////////////////
137 // Implementations
138 ///////////////////////////////////////////////////////////////////////////////
139 
140 /**
141  * A shader that draws a bitmap.
142  */
143 struct SkiaBitmapShader: public SkiaShader {
144     ANDROID_API SkiaBitmapShader(SkBitmap* bitmap, SkShader* key, SkShader::TileMode tileX,
145             SkShader::TileMode tileY, SkMatrix* matrix, bool blend);
146     SkiaShader* copy();
147 
148     void describe(ProgramDescription& description, const Extensions& extensions);
149     void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
150             GLuint* textureUnit);
151     void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot);
152 
153 private:
SkiaBitmapShaderSkiaBitmapShader154     SkiaBitmapShader() {
155     }
156 
157     /**
158      * This method does not work for n == 0.
159      */
isPowerOfTwoSkiaBitmapShader160     inline bool isPowerOfTwo(unsigned int n) {
161         return !(n & (n - 1));
162     }
163 
164     SkBitmap* mBitmap;
165     Texture* mTexture;
166     GLenum mWrapS;
167     GLenum mWrapT;
168 }; // struct SkiaBitmapShader
169 
170 /**
171  * A shader that draws a linear gradient.
172  */
173 struct SkiaLinearGradientShader: public SkiaShader {
174     ANDROID_API SkiaLinearGradientShader(float* bounds, uint32_t* colors, float* positions,
175             int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
176     ~SkiaLinearGradientShader();
177     SkiaShader* copy();
178 
179     void describe(ProgramDescription& description, const Extensions& extensions);
180     void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
181             GLuint* textureUnit);
182     void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot);
183 
184 private:
SkiaLinearGradientShaderSkiaLinearGradientShader185     SkiaLinearGradientShader() {
186     }
187 
188     float* mBounds;
189     uint32_t* mColors;
190     float* mPositions;
191     int mCount;
192 }; // struct SkiaLinearGradientShader
193 
194 /**
195  * A shader that draws a sweep gradient.
196  */
197 struct SkiaSweepGradientShader: public SkiaShader {
198     ANDROID_API SkiaSweepGradientShader(float x, float y, uint32_t* colors, float* positions,
199             int count, SkShader* key, SkMatrix* matrix, bool blend);
200     ~SkiaSweepGradientShader();
201     SkiaShader* copy();
202 
203     virtual void describe(ProgramDescription& description, const Extensions& extensions);
204     void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
205             GLuint* textureUnit);
206     void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot);
207 
208 protected:
209     SkiaSweepGradientShader(Type type, float x, float y, uint32_t* colors, float* positions,
210             int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
SkiaSweepGradientShaderSkiaSweepGradientShader211     SkiaSweepGradientShader() {
212     }
213 
214     uint32_t* mColors;
215     float* mPositions;
216     int mCount;
217 }; // struct SkiaSweepGradientShader
218 
219 /**
220  * A shader that draws a circular gradient.
221  */
222 struct SkiaCircularGradientShader: public SkiaSweepGradientShader {
223     ANDROID_API SkiaCircularGradientShader(float x, float y, float radius, uint32_t* colors,
224             float* positions, int count, SkShader* key,SkShader::TileMode tileMode,
225             SkMatrix* matrix, bool blend);
226     SkiaShader* copy();
227 
228     void describe(ProgramDescription& description, const Extensions& extensions);
229 
230 private:
SkiaCircularGradientShaderSkiaCircularGradientShader231     SkiaCircularGradientShader() {
232     }
233 }; // struct SkiaCircularGradientShader
234 
235 /**
236  * A shader that draws two shaders, composited with an xfermode.
237  */
238 struct SkiaComposeShader: public SkiaShader {
239     ANDROID_API SkiaComposeShader(SkiaShader* first, SkiaShader* second, SkXfermode::Mode mode,
240             SkShader* key);
241     ~SkiaComposeShader();
242     SkiaShader* copy();
243 
244     void set(TextureCache* textureCache, GradientCache* gradientCache);
245 
246     void describe(ProgramDescription& description, const Extensions& extensions);
247     void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
248             GLuint* textureUnit);
249 
250 private:
SkiaComposeShaderSkiaComposeShader251     SkiaComposeShader(): mCleanup(false) {
252     }
253 
cleanupSkiaComposeShader254     void cleanup() {
255         mCleanup = true;
256     }
257 
258     SkiaShader* mFirst;
259     SkiaShader* mSecond;
260     SkXfermode::Mode mMode;
261 
262     bool mCleanup;
263 }; // struct SkiaComposeShader
264 
265 }; // namespace uirenderer
266 }; // namespace android
267 
268 #endif // ANDROID_HWUI_SKIA_SHADER_H
269