blob: a710b8602f8fbeba7c9c312fd1710c80e08e7c6b [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 SkBitmap* mBitmap;
Romain Guy8164c2d2010-10-25 18:03:28 -0700158 Texture* mTexture;
Romain Guy29d89972010-09-22 16:10:57 -0700159 GLenum mWrapS;
160 GLenum mWrapT;
Romain Guy06f96e22010-07-30 19:18:16 -0700161}; // struct SkiaBitmapShader
162
163/**
164 * A shader that draws a linear gradient.
165 */
166struct SkiaLinearGradientShader: public SkiaShader {
Romain Guy79537452011-10-12 13:48:51 -0700167 ANDROID_API SkiaLinearGradientShader(float* bounds, uint32_t* colors, float* positions,
168 int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
Romain Guy06f96e22010-07-30 19:18:16 -0700169 ~SkiaLinearGradientShader();
Romain Guy24c00212011-01-14 15:31:00 -0800170 SkiaShader* copy();
Romain Guy06f96e22010-07-30 19:18:16 -0700171
172 void describe(ProgramDescription& description, const Extensions& extensions);
173 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
174 GLuint* textureUnit);
Romain Guy759ea802010-09-16 20:49:46 -0700175 void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot);
Romain Guy06f96e22010-07-30 19:18:16 -0700176
177private:
Romain Guy24c00212011-01-14 15:31:00 -0800178 SkiaLinearGradientShader() {
179 }
180
Romain Guy42e1e0d2012-07-30 14:47:51 -0700181 bool mIsSimple;
Romain Guy06f96e22010-07-30 19:18:16 -0700182 float* mBounds;
183 uint32_t* mColors;
184 float* mPositions;
185 int mCount;
186}; // struct SkiaLinearGradientShader
187
188/**
Romain Guyee916f12010-09-20 17:53:08 -0700189 * A shader that draws a sweep gradient.
190 */
191struct SkiaSweepGradientShader: public SkiaShader {
Romain Guy79537452011-10-12 13:48:51 -0700192 ANDROID_API SkiaSweepGradientShader(float x, float y, uint32_t* colors, float* positions,
193 int count, SkShader* key, SkMatrix* matrix, bool blend);
Romain Guyee916f12010-09-20 17:53:08 -0700194 ~SkiaSweepGradientShader();
Romain Guy24c00212011-01-14 15:31:00 -0800195 SkiaShader* copy();
Romain Guyee916f12010-09-20 17:53:08 -0700196
Romain Guyddb80be2010-09-20 19:04:33 -0700197 virtual void describe(ProgramDescription& description, const Extensions& extensions);
Romain Guy14830942010-10-07 15:07:45 -0700198 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
Romain Guyee916f12010-09-20 17:53:08 -0700199 GLuint* textureUnit);
200 void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot);
201
Romain Guyddb80be2010-09-20 19:04:33 -0700202protected:
203 SkiaSweepGradientShader(Type type, float x, float y, uint32_t* colors, float* positions,
204 int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
Romain Guy24c00212011-01-14 15:31:00 -0800205 SkiaSweepGradientShader() {
206 }
Romain Guyddb80be2010-09-20 19:04:33 -0700207
Romain Guy42e1e0d2012-07-30 14:47:51 -0700208 bool mIsSimple;
Romain Guyee916f12010-09-20 17:53:08 -0700209 uint32_t* mColors;
210 float* mPositions;
211 int mCount;
212}; // struct SkiaSweepGradientShader
213
214/**
Romain Guyddb80be2010-09-20 19:04:33 -0700215 * A shader that draws a circular gradient.
216 */
217struct SkiaCircularGradientShader: public SkiaSweepGradientShader {
Romain Guy79537452011-10-12 13:48:51 -0700218 ANDROID_API SkiaCircularGradientShader(float x, float y, float radius, uint32_t* colors,
219 float* positions, int count, SkShader* key,SkShader::TileMode tileMode,
220 SkMatrix* matrix, bool blend);
Romain Guy24c00212011-01-14 15:31:00 -0800221 SkiaShader* copy();
Romain Guyddb80be2010-09-20 19:04:33 -0700222
223 void describe(ProgramDescription& description, const Extensions& extensions);
Romain Guy24c00212011-01-14 15:31:00 -0800224
225private:
226 SkiaCircularGradientShader() {
227 }
Romain Guyddb80be2010-09-20 19:04:33 -0700228}; // struct SkiaCircularGradientShader
229
230/**
Romain Guy06f96e22010-07-30 19:18:16 -0700231 * A shader that draws two shaders, composited with an xfermode.
232 */
233struct SkiaComposeShader: public SkiaShader {
Romain Guy79537452011-10-12 13:48:51 -0700234 ANDROID_API SkiaComposeShader(SkiaShader* first, SkiaShader* second, SkXfermode::Mode mode,
235 SkShader* key);
Romain Guy43ccf462011-01-14 18:51:01 -0800236 ~SkiaComposeShader();
Romain Guy24c00212011-01-14 15:31:00 -0800237 SkiaShader* copy();
Romain Guy06f96e22010-07-30 19:18:16 -0700238
239 void set(TextureCache* textureCache, GradientCache* gradientCache);
240
241 void describe(ProgramDescription& description, const Extensions& extensions);
242 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
243 GLuint* textureUnit);
244
245private:
Romain Guy43ccf462011-01-14 18:51:01 -0800246 SkiaComposeShader(): mCleanup(false) {
247 }
248
249 void cleanup() {
250 mCleanup = true;
Romain Guy24c00212011-01-14 15:31:00 -0800251 }
252
Romain Guy06f96e22010-07-30 19:18:16 -0700253 SkiaShader* mFirst;
254 SkiaShader* mSecond;
255 SkXfermode::Mode mMode;
Romain Guy43ccf462011-01-14 18:51:01 -0800256
257 bool mCleanup;
Romain Guy06f96e22010-07-30 19:18:16 -0700258}; // struct SkiaComposeShader
259
260}; // namespace uirenderer
261}; // namespace android
262
Romain Guy5b3b3522010-10-27 18:57:51 -0700263#endif // ANDROID_HWUI_SKIA_SHADER_H