• 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 class Caches;
37 
38 ///////////////////////////////////////////////////////////////////////////////
39 // Base shader
40 ///////////////////////////////////////////////////////////////////////////////
41 
42 /**
43  * Represents a Skia shader. A shader will modify the GL context and active
44  * program to recreate the original effect.
45  */
46 struct SkiaShader {
47     /**
48      * Type of Skia shader in use.
49      */
50     enum Type {
51         kNone,
52         kBitmap,
53         kLinearGradient,
54         kCircularGradient,
55         kSweepGradient,
56         kCompose
57     };
58 
59     ANDROID_API SkiaShader(Type type, SkShader* key, SkShader::TileMode tileX,
60             SkShader::TileMode tileY, SkMatrix* matrix, bool blend);
61     virtual ~SkiaShader();
62 
63     virtual SkiaShader* copy() = 0;
64     void copyFrom(const SkiaShader& shader);
65 
66     virtual void describe(ProgramDescription& description, const Extensions& extensions);
67     virtual void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
68             GLuint* textureUnit);
69 
getSkShaderSkiaShader70     inline SkShader* getSkShader() {
71         return mKey;
72     }
73 
blendSkiaShader74     inline bool blend() const {
75         return mBlend;
76     }
77 
typeSkiaShader78     Type type() const {
79         return mType;
80     }
81 
setCachesSkiaShader82     virtual void setCaches(Caches& caches) {
83         mCaches = &caches;
84     }
85 
getGenerationIdSkiaShader86     uint32_t getGenerationId() {
87         return mGenerationId;
88     }
89 
setMatrixSkiaShader90     void setMatrix(SkMatrix* matrix) {
91         updateLocalMatrix(matrix);
92         mGenerationId++;
93     }
94 
updateLocalMatrixSkiaShader95     void updateLocalMatrix(const SkMatrix* matrix) {
96         if (matrix) {
97             mat4 localMatrix(*matrix);
98             mShaderMatrix.loadInverse(localMatrix);
99         } else {
100             mShaderMatrix.loadIdentity();
101         }
102     }
103 
104     void computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView);
105 
106 protected:
107     SkiaShader();
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     Caches* mCaches;
122 
123     mat4 mUnitMatrix;
124     mat4 mShaderMatrix;
125 
126 private:
127     uint32_t mGenerationId;
128 }; // struct SkiaShader
129 
130 
131 ///////////////////////////////////////////////////////////////////////////////
132 // Implementations
133 ///////////////////////////////////////////////////////////////////////////////
134 
135 /**
136  * A shader that draws a bitmap.
137  */
138 struct SkiaBitmapShader: public SkiaShader {
139     ANDROID_API SkiaBitmapShader(SkBitmap* bitmap, SkShader* key, SkShader::TileMode tileX,
140             SkShader::TileMode tileY, SkMatrix* matrix, bool blend);
141     SkiaShader* copy();
142 
143     void describe(ProgramDescription& description, const Extensions& extensions);
144     void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
145             GLuint* textureUnit);
146 
147 private:
SkiaBitmapShaderSkiaBitmapShader148     SkiaBitmapShader() {
149     }
150 
151     SkBitmap* mBitmap;
152     Texture* mTexture;
153     GLenum mWrapS;
154     GLenum mWrapT;
155 }; // struct SkiaBitmapShader
156 
157 /**
158  * A shader that draws a linear gradient.
159  */
160 struct SkiaLinearGradientShader: public SkiaShader {
161     ANDROID_API SkiaLinearGradientShader(float* bounds, uint32_t* colors, float* positions,
162             int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
163     ~SkiaLinearGradientShader();
164     SkiaShader* copy();
165 
166     void describe(ProgramDescription& description, const Extensions& extensions);
167     void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
168             GLuint* textureUnit);
169 
170 private:
SkiaLinearGradientShaderSkiaLinearGradientShader171     SkiaLinearGradientShader() {
172     }
173 
174     bool mIsSimple;
175     float* mBounds;
176     uint32_t* mColors;
177     float* mPositions;
178     int mCount;
179 }; // struct SkiaLinearGradientShader
180 
181 /**
182  * A shader that draws a sweep gradient.
183  */
184 struct SkiaSweepGradientShader: public SkiaShader {
185     ANDROID_API SkiaSweepGradientShader(float x, float y, uint32_t* colors, float* positions,
186             int count, SkShader* key, SkMatrix* matrix, bool blend);
187     ~SkiaSweepGradientShader();
188     SkiaShader* copy();
189 
190     virtual void describe(ProgramDescription& description, const Extensions& extensions);
191     void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
192             GLuint* textureUnit);
193 
194 protected:
195     SkiaSweepGradientShader(Type type, float x, float y, uint32_t* colors, float* positions,
196             int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
SkiaSweepGradientShaderSkiaSweepGradientShader197     SkiaSweepGradientShader() {
198     }
199 
200     bool mIsSimple;
201     uint32_t* mColors;
202     float* mPositions;
203     int mCount;
204 }; // struct SkiaSweepGradientShader
205 
206 /**
207  * A shader that draws a circular gradient.
208  */
209 struct SkiaCircularGradientShader: public SkiaSweepGradientShader {
210     ANDROID_API SkiaCircularGradientShader(float x, float y, float radius, uint32_t* colors,
211             float* positions, int count, SkShader* key,SkShader::TileMode tileMode,
212             SkMatrix* matrix, bool blend);
213     SkiaShader* copy();
214 
215     void describe(ProgramDescription& description, const Extensions& extensions);
216 
217 private:
SkiaCircularGradientShaderSkiaCircularGradientShader218     SkiaCircularGradientShader() {
219     }
220 }; // struct SkiaCircularGradientShader
221 
222 /**
223  * A shader that draws two shaders, composited with an xfermode.
224  */
225 struct SkiaComposeShader: public SkiaShader {
226     ANDROID_API SkiaComposeShader(SkiaShader* first, SkiaShader* second, SkXfermode::Mode mode,
227             SkShader* key);
228     ~SkiaComposeShader();
229     SkiaShader* copy();
230 
setCachesSkiaComposeShader231     void setCaches(Caches& caches) {
232         SkiaShader::setCaches(caches);
233         mFirst->setCaches(caches);
234         mSecond->setCaches(caches);
235     }
236 
237     void describe(ProgramDescription& description, const Extensions& extensions);
238     void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
239             GLuint* textureUnit);
240 
241 private:
SkiaComposeShaderSkiaComposeShader242     SkiaComposeShader(): mCleanup(false) {
243     }
244 
cleanupSkiaComposeShader245     void cleanup() {
246         mCleanup = true;
247     }
248 
249     SkiaShader* mFirst;
250     SkiaShader* mSecond;
251     SkXfermode::Mode mMode;
252 
253     bool mCleanup;
254 }; // struct SkiaComposeShader
255 
256 }; // namespace uirenderer
257 }; // namespace android
258 
259 #endif // ANDROID_HWUI_SKIA_SHADER_H
260