• 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 
getGenerationIdSkiaShader85     uint32_t getGenerationId() {
86         return mGenerationId;
87     }
88 
setMatrixSkiaShader89     void setMatrix(SkMatrix* matrix) {
90         updateLocalMatrix(matrix);
91         mGenerationId++;
92     }
93 
updateLocalMatrixSkiaShader94     void updateLocalMatrix(const SkMatrix* matrix) {
95         if (matrix) {
96             mat4 localMatrix(*matrix);
97             mShaderMatrix.loadInverse(localMatrix);
98         } else {
99             mShaderMatrix.loadIdentity();
100         }
101     }
102 
103     void computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView);
104 
105 protected:
SkiaShaderSkiaShader106     SkiaShader() {
107     }
108 
109     /**
110      * The appropriate texture unit must have been activated prior to invoking
111      * this method.
112      */
113     inline void bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT);
114 
115     Type mType;
116     SkShader* mKey;
117     SkShader::TileMode mTileX;
118     SkShader::TileMode mTileY;
119     bool mBlend;
120 
121     TextureCache* mTextureCache;
122     GradientCache* mGradientCache;
123 
124     mat4 mUnitMatrix;
125     mat4 mShaderMatrix;
126 
127 private:
128     uint32_t mGenerationId;
129 }; // struct SkiaShader
130 
131 
132 ///////////////////////////////////////////////////////////////////////////////
133 // Implementations
134 ///////////////////////////////////////////////////////////////////////////////
135 
136 /**
137  * A shader that draws a bitmap.
138  */
139 struct SkiaBitmapShader: public SkiaShader {
140     ANDROID_API SkiaBitmapShader(SkBitmap* bitmap, SkShader* key, SkShader::TileMode tileX,
141             SkShader::TileMode tileY, SkMatrix* matrix, bool blend);
142     SkiaShader* copy();
143 
144     void describe(ProgramDescription& description, const Extensions& extensions);
145     void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
146             GLuint* textureUnit);
147 
148 private:
SkiaBitmapShaderSkiaBitmapShader149     SkiaBitmapShader() {
150     }
151 
152     SkBitmap* mBitmap;
153     Texture* mTexture;
154     GLenum mWrapS;
155     GLenum mWrapT;
156 }; // struct SkiaBitmapShader
157 
158 /**
159  * A shader that draws a linear gradient.
160  */
161 struct SkiaLinearGradientShader: public SkiaShader {
162     ANDROID_API SkiaLinearGradientShader(float* bounds, uint32_t* colors, float* positions,
163             int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
164     ~SkiaLinearGradientShader();
165     SkiaShader* copy();
166 
167     void describe(ProgramDescription& description, const Extensions& extensions);
168     void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
169             GLuint* textureUnit);
170 
171 private:
SkiaLinearGradientShaderSkiaLinearGradientShader172     SkiaLinearGradientShader() {
173     }
174 
175     bool mIsSimple;
176     float* mBounds;
177     uint32_t* mColors;
178     float* mPositions;
179     int mCount;
180 }; // struct SkiaLinearGradientShader
181 
182 /**
183  * A shader that draws a sweep gradient.
184  */
185 struct SkiaSweepGradientShader: public SkiaShader {
186     ANDROID_API SkiaSweepGradientShader(float x, float y, uint32_t* colors, float* positions,
187             int count, SkShader* key, SkMatrix* matrix, bool blend);
188     ~SkiaSweepGradientShader();
189     SkiaShader* copy();
190 
191     virtual void describe(ProgramDescription& description, const Extensions& extensions);
192     void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
193             GLuint* textureUnit);
194 
195 protected:
196     SkiaSweepGradientShader(Type type, float x, float y, uint32_t* colors, float* positions,
197             int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
SkiaSweepGradientShaderSkiaSweepGradientShader198     SkiaSweepGradientShader() {
199     }
200 
201     bool mIsSimple;
202     uint32_t* mColors;
203     float* mPositions;
204     int mCount;
205 }; // struct SkiaSweepGradientShader
206 
207 /**
208  * A shader that draws a circular gradient.
209  */
210 struct SkiaCircularGradientShader: public SkiaSweepGradientShader {
211     ANDROID_API SkiaCircularGradientShader(float x, float y, float radius, uint32_t* colors,
212             float* positions, int count, SkShader* key,SkShader::TileMode tileMode,
213             SkMatrix* matrix, bool blend);
214     SkiaShader* copy();
215 
216     void describe(ProgramDescription& description, const Extensions& extensions);
217 
218 private:
SkiaCircularGradientShaderSkiaCircularGradientShader219     SkiaCircularGradientShader() {
220     }
221 }; // struct SkiaCircularGradientShader
222 
223 /**
224  * A shader that draws two shaders, composited with an xfermode.
225  */
226 struct SkiaComposeShader: public SkiaShader {
227     ANDROID_API SkiaComposeShader(SkiaShader* first, SkiaShader* second, SkXfermode::Mode mode,
228             SkShader* key);
229     ~SkiaComposeShader();
230     SkiaShader* copy();
231 
232     void set(TextureCache* textureCache, GradientCache* gradientCache);
233 
234     void describe(ProgramDescription& description, const Extensions& extensions);
235     void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
236             GLuint* textureUnit);
237 
238 private:
SkiaComposeShaderSkiaComposeShader239     SkiaComposeShader(): mCleanup(false) {
240     }
241 
cleanupSkiaComposeShader242     void cleanup() {
243         mCleanup = true;
244     }
245 
246     SkiaShader* mFirst;
247     SkiaShader* mSecond;
248     SkXfermode::Mode mMode;
249 
250     bool mCleanup;
251 }; // struct SkiaComposeShader
252 
253 }; // namespace uirenderer
254 }; // namespace android
255 
256 #endif // ANDROID_HWUI_SKIA_SHADER_H
257