blob: 2de9a93bd1369b2edc8bd9d973640b53d9440a29 [file] [log] [blame]
Romain Guy06f96e22010-07-30 19:18:16 -07001/*
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
Romain Guy5b3b3522010-10-27 18:57:51 -070017#ifndef ANDROID_HWUI_SKIA_SHADER_H
18#define ANDROID_HWUI_SKIA_SHADER_H
Romain Guy06f96e22010-07-30 19:18:16 -070019
20#include <SkShader.h>
21#include <SkXfermode.h>
22
23#include <GLES2/gl2.h>
24
Romain Guy79537452011-10-12 13:48:51 -070025#include <cutils/compiler.h>
26
Romain Guy06f96e22010-07-30 19:18:16 -070027#include "Extensions.h"
28#include "ProgramCache.h"
29#include "TextureCache.h"
30#include "GradientCache.h"
31#include "Snapshot.h"
32
33namespace android {
34namespace 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 */
44struct 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
Romain Guy79537452011-10-12 13:48:51 -070057 ANDROID_API SkiaShader(Type type, SkShader* key, SkShader::TileMode tileX,
58 SkShader::TileMode tileY, SkMatrix* matrix, bool blend);
Romain Guy06f96e22010-07-30 19:18:16 -070059 virtual ~SkiaShader();
60
Romain Guy24c00212011-01-14 15:31:00 -080061 virtual SkiaShader* copy() = 0;
62 void copyFrom(const SkiaShader& shader);
63
Romain Guy06f96e22010-07-30 19:18:16 -070064 virtual void describe(ProgramDescription& description, const Extensions& extensions);
65 virtual void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
66 GLuint* textureUnit);
67
Chet Haase5c13d892010-10-08 08:37:55 -070068 inline SkShader *getSkShader() {
69 return mKey;
70 }
71
Romain Guy06f96e22010-07-30 19:18:16 -070072 inline bool blend() const {
73 return mBlend;
74 }
75
76 Type type() const {
77 return mType;
78 }
79
80 virtual void set(TextureCache* textureCache, GradientCache* gradientCache) {
81 mTextureCache = textureCache;
82 mGradientCache = gradientCache;
83 }
84
Romain Guy759ea802010-09-16 20:49:46 -070085 virtual void updateTransforms(Program* program, const mat4& modelView,
86 const Snapshot& snapshot) {
87 }
88
Romain Guy24c00212011-01-14 15:31:00 -080089 uint32_t getGenerationId() {
90 return mGenerationId;
91 }
92
Romain Guy14830942010-10-07 15:07:45 -070093 void setMatrix(SkMatrix* matrix) {
94 updateLocalMatrix(matrix);
Romain Guy24c00212011-01-14 15:31:00 -080095 mGenerationId++;
Romain Guy06f96e22010-07-30 19:18:16 -070096 }
97
Romain Guy14830942010-10-07 15:07:45 -070098 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
Romain Guy06f96e22010-07-30 19:18:16 -0700109protected:
Romain Guy24c00212011-01-14 15:31:00 -0800110 SkiaShader() {
111 }
112
Romain Guy01d06572010-11-11 12:06:27 -0800113 /**
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);
Romain Guy06f96e22010-07-30 19:18:16 -0700118
119 Type mType;
120 SkShader* mKey;
121 SkShader::TileMode mTileX;
122 SkShader::TileMode mTileY;
Romain Guy06f96e22010-07-30 19:18:16 -0700123 bool mBlend;
124
125 TextureCache* mTextureCache;
126 GradientCache* mGradientCache;
Romain Guy14830942010-10-07 15:07:45 -0700127
128 mat4 mUnitMatrix;
129 mat4 mShaderMatrix;
Romain Guy24c00212011-01-14 15:31:00 -0800130
131private:
132 uint32_t mGenerationId;
Romain Guy06f96e22010-07-30 19:18:16 -0700133}; // struct SkiaShader
134
135
136///////////////////////////////////////////////////////////////////////////////
137// Implementations
138///////////////////////////////////////////////////////////////////////////////
139
140/**
141 * A shader that draws a bitmap.
142 */
143struct SkiaBitmapShader: public SkiaShader {
Romain Guy79537452011-10-12 13:48:51 -0700144 ANDROID_API SkiaBitmapShader(SkBitmap* bitmap, SkShader* key, SkShader::TileMode tileX,
Romain Guy06f96e22010-07-30 19:18:16 -0700145 SkShader::TileMode tileY, SkMatrix* matrix, bool blend);
Romain Guy24c00212011-01-14 15:31:00 -0800146 SkiaShader* copy();
Romain Guy06f96e22010-07-30 19:18:16 -0700147
148 void describe(ProgramDescription& description, const Extensions& extensions);
149 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
150 GLuint* textureUnit);
Romain Guy759ea802010-09-16 20:49:46 -0700151 void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot);
Romain Guy06f96e22010-07-30 19:18:16 -0700152
153private:
Romain Guy24c00212011-01-14 15:31:00 -0800154 SkiaBitmapShader() {
155 }
156
Romain Guy06f96e22010-07-30 19:18:16 -0700157 /**
158 * This method does not work for n == 0.
159 */
160 inline bool isPowerOfTwo(unsigned int n) {
161 return !(n & (n - 1));
162 }
163
164 SkBitmap* mBitmap;
Romain Guy8164c2d2010-10-25 18:03:28 -0700165 Texture* mTexture;
Romain Guy29d89972010-09-22 16:10:57 -0700166 GLenum mWrapS;
167 GLenum mWrapT;
Romain Guy06f96e22010-07-30 19:18:16 -0700168}; // struct SkiaBitmapShader
169
170/**
171 * A shader that draws a linear gradient.
172 */
173struct SkiaLinearGradientShader: public SkiaShader {
Romain Guy79537452011-10-12 13:48:51 -0700174 ANDROID_API SkiaLinearGradientShader(float* bounds, uint32_t* colors, float* positions,
175 int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
Romain Guy06f96e22010-07-30 19:18:16 -0700176 ~SkiaLinearGradientShader();
Romain Guy24c00212011-01-14 15:31:00 -0800177 SkiaShader* copy();
Romain Guy06f96e22010-07-30 19:18:16 -0700178
179 void describe(ProgramDescription& description, const Extensions& extensions);
180 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
181 GLuint* textureUnit);
Romain Guy759ea802010-09-16 20:49:46 -0700182 void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot);
Romain Guy06f96e22010-07-30 19:18:16 -0700183
184private:
Romain Guy24c00212011-01-14 15:31:00 -0800185 SkiaLinearGradientShader() {
186 }
187
Romain Guy06f96e22010-07-30 19:18:16 -0700188 float* mBounds;
189 uint32_t* mColors;
190 float* mPositions;
191 int mCount;
192}; // struct SkiaLinearGradientShader
193
194/**
Romain Guyee916f12010-09-20 17:53:08 -0700195 * A shader that draws a sweep gradient.
196 */
197struct SkiaSweepGradientShader: public SkiaShader {
Romain Guy79537452011-10-12 13:48:51 -0700198 ANDROID_API SkiaSweepGradientShader(float x, float y, uint32_t* colors, float* positions,
199 int count, SkShader* key, SkMatrix* matrix, bool blend);
Romain Guyee916f12010-09-20 17:53:08 -0700200 ~SkiaSweepGradientShader();
Romain Guy24c00212011-01-14 15:31:00 -0800201 SkiaShader* copy();
Romain Guyee916f12010-09-20 17:53:08 -0700202
Romain Guyddb80be2010-09-20 19:04:33 -0700203 virtual void describe(ProgramDescription& description, const Extensions& extensions);
Romain Guy14830942010-10-07 15:07:45 -0700204 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
Romain Guyee916f12010-09-20 17:53:08 -0700205 GLuint* textureUnit);
206 void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot);
207
Romain Guyddb80be2010-09-20 19:04:33 -0700208protected:
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);
Romain Guy24c00212011-01-14 15:31:00 -0800211 SkiaSweepGradientShader() {
212 }
Romain Guyddb80be2010-09-20 19:04:33 -0700213
Romain Guyee916f12010-09-20 17:53:08 -0700214 uint32_t* mColors;
215 float* mPositions;
216 int mCount;
217}; // struct SkiaSweepGradientShader
218
219/**
Romain Guyddb80be2010-09-20 19:04:33 -0700220 * A shader that draws a circular gradient.
221 */
222struct SkiaCircularGradientShader: public SkiaSweepGradientShader {
Romain Guy79537452011-10-12 13:48:51 -0700223 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);
Romain Guy24c00212011-01-14 15:31:00 -0800226 SkiaShader* copy();
Romain Guyddb80be2010-09-20 19:04:33 -0700227
228 void describe(ProgramDescription& description, const Extensions& extensions);
Romain Guy24c00212011-01-14 15:31:00 -0800229
230private:
231 SkiaCircularGradientShader() {
232 }
Romain Guyddb80be2010-09-20 19:04:33 -0700233}; // struct SkiaCircularGradientShader
234
235/**
Romain Guy06f96e22010-07-30 19:18:16 -0700236 * A shader that draws two shaders, composited with an xfermode.
237 */
238struct SkiaComposeShader: public SkiaShader {
Romain Guy79537452011-10-12 13:48:51 -0700239 ANDROID_API SkiaComposeShader(SkiaShader* first, SkiaShader* second, SkXfermode::Mode mode,
240 SkShader* key);
Romain Guy43ccf462011-01-14 18:51:01 -0800241 ~SkiaComposeShader();
Romain Guy24c00212011-01-14 15:31:00 -0800242 SkiaShader* copy();
Romain Guy06f96e22010-07-30 19:18:16 -0700243
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
250private:
Romain Guy43ccf462011-01-14 18:51:01 -0800251 SkiaComposeShader(): mCleanup(false) {
252 }
253
254 void cleanup() {
255 mCleanup = true;
Romain Guy24c00212011-01-14 15:31:00 -0800256 }
257
Romain Guy06f96e22010-07-30 19:18:16 -0700258 SkiaShader* mFirst;
259 SkiaShader* mSecond;
260 SkXfermode::Mode mMode;
Romain Guy43ccf462011-01-14 18:51:01 -0800261
262 bool mCleanup;
Romain Guy06f96e22010-07-30 19:18:16 -0700263}; // struct SkiaComposeShader
264
265}; // namespace uirenderer
266}; // namespace android
267
Romain Guy5b3b3522010-10-27 18:57:51 -0700268#endif // ANDROID_HWUI_SKIA_SHADER_H