blob: 601576186fe6810ad031831df53dec9a69ca6cf3 [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
Romain Guy8aa195d2013-06-04 18:00:09 -070036class Caches;
37
Romain Guy06f96e22010-07-30 19:18:16 -070038///////////////////////////////////////////////////////////////////////////////
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 */
Chris Craik564acf72014-01-02 16:46:18 -080046class SkiaShader {
47public:
Romain Guy06f96e22010-07-30 19:18:16 -070048 /**
49 * Type of Skia shader in use.
50 */
51 enum Type {
52 kNone,
53 kBitmap,
54 kLinearGradient,
55 kCircularGradient,
56 kSweepGradient,
57 kCompose
58 };
59
Romain Guy79537452011-10-12 13:48:51 -070060 ANDROID_API SkiaShader(Type type, SkShader* key, SkShader::TileMode tileX,
61 SkShader::TileMode tileY, SkMatrix* matrix, bool blend);
Romain Guy06f96e22010-07-30 19:18:16 -070062 virtual ~SkiaShader();
63
Romain Guy24c00212011-01-14 15:31:00 -080064 virtual SkiaShader* copy() = 0;
65 void copyFrom(const SkiaShader& shader);
66
Romain Guy06f96e22010-07-30 19:18:16 -070067 virtual void describe(ProgramDescription& description, const Extensions& extensions);
68 virtual void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
69 GLuint* textureUnit);
70
Romain Guydcfc8362013-01-03 13:08:57 -080071 inline SkShader* getSkShader() {
Chet Haase5c13d892010-10-08 08:37:55 -070072 return mKey;
73 }
74
Romain Guy06f96e22010-07-30 19:18:16 -070075 inline bool blend() const {
76 return mBlend;
77 }
78
79 Type type() const {
80 return mType;
81 }
82
Romain Guy8aa195d2013-06-04 18:00:09 -070083 virtual void setCaches(Caches& caches) {
84 mCaches = &caches;
Romain Guy06f96e22010-07-30 19:18:16 -070085 }
86
Romain Guy24c00212011-01-14 15:31:00 -080087 uint32_t getGenerationId() {
88 return mGenerationId;
89 }
90
Romain Guy14830942010-10-07 15:07:45 -070091 void setMatrix(SkMatrix* matrix) {
92 updateLocalMatrix(matrix);
Romain Guy24c00212011-01-14 15:31:00 -080093 mGenerationId++;
Romain Guy06f96e22010-07-30 19:18:16 -070094 }
95
Romain Guy14830942010-10-07 15:07:45 -070096 void updateLocalMatrix(const SkMatrix* matrix) {
97 if (matrix) {
98 mat4 localMatrix(*matrix);
99 mShaderMatrix.loadInverse(localMatrix);
100 } else {
101 mShaderMatrix.loadIdentity();
102 }
103 }
104
105 void computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView);
106
Romain Guy06f96e22010-07-30 19:18:16 -0700107protected:
Romain Guy8aa195d2013-06-04 18:00:09 -0700108 SkiaShader();
Romain Guy24c00212011-01-14 15:31:00 -0800109
Romain Guy01d06572010-11-11 12:06:27 -0800110 /**
111 * The appropriate texture unit must have been activated prior to invoking
112 * this method.
113 */
114 inline void bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT);
Romain Guy06f96e22010-07-30 19:18:16 -0700115
116 Type mType;
117 SkShader* mKey;
118 SkShader::TileMode mTileX;
119 SkShader::TileMode mTileY;
Romain Guy06f96e22010-07-30 19:18:16 -0700120 bool mBlend;
121
Romain Guy8aa195d2013-06-04 18:00:09 -0700122 Caches* mCaches;
Romain Guy14830942010-10-07 15:07:45 -0700123
124 mat4 mUnitMatrix;
125 mat4 mShaderMatrix;
Romain Guy24c00212011-01-14 15:31:00 -0800126
127private:
128 uint32_t mGenerationId;
Romain Guy06f96e22010-07-30 19:18:16 -0700129}; // struct SkiaShader
130
131
132///////////////////////////////////////////////////////////////////////////////
133// Implementations
134///////////////////////////////////////////////////////////////////////////////
135
136/**
137 * A shader that draws a bitmap.
138 */
139struct SkiaBitmapShader: public SkiaShader {
Romain Guy79537452011-10-12 13:48:51 -0700140 ANDROID_API SkiaBitmapShader(SkBitmap* bitmap, SkShader* key, SkShader::TileMode tileX,
Romain Guy06f96e22010-07-30 19:18:16 -0700141 SkShader::TileMode tileY, SkMatrix* matrix, bool blend);
Romain Guy24c00212011-01-14 15:31:00 -0800142 SkiaShader* copy();
Romain Guy06f96e22010-07-30 19:18:16 -0700143
144 void describe(ProgramDescription& description, const Extensions& extensions);
145 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
146 GLuint* textureUnit);
147
148private:
lina.x.pi92028732014-01-09 18:17:03 +0800149 SkiaBitmapShader() : mBitmap(NULL), mTexture(NULL) {
Romain Guy24c00212011-01-14 15:31:00 -0800150 }
151
Romain Guy06f96e22010-07-30 19:18:16 -0700152 SkBitmap* mBitmap;
Romain Guy8164c2d2010-10-25 18:03:28 -0700153 Texture* mTexture;
Romain Guy29d89972010-09-22 16:10:57 -0700154 GLenum mWrapS;
155 GLenum mWrapT;
Romain Guy06f96e22010-07-30 19:18:16 -0700156}; // struct SkiaBitmapShader
157
158/**
159 * A shader that draws a linear gradient.
160 */
161struct SkiaLinearGradientShader: public SkiaShader {
Romain Guy79537452011-10-12 13:48:51 -0700162 ANDROID_API SkiaLinearGradientShader(float* bounds, uint32_t* colors, float* positions,
163 int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
Romain Guy06f96e22010-07-30 19:18:16 -0700164 ~SkiaLinearGradientShader();
Romain Guy24c00212011-01-14 15:31:00 -0800165 SkiaShader* copy();
Romain Guy06f96e22010-07-30 19:18:16 -0700166
167 void describe(ProgramDescription& description, const Extensions& extensions);
168 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
169 GLuint* textureUnit);
170
171private:
Romain Guy24c00212011-01-14 15:31:00 -0800172 SkiaLinearGradientShader() {
173 }
174
Romain Guy42e1e0d2012-07-30 14:47:51 -0700175 bool mIsSimple;
Romain Guy06f96e22010-07-30 19:18:16 -0700176 float* mBounds;
177 uint32_t* mColors;
178 float* mPositions;
179 int mCount;
180}; // struct SkiaLinearGradientShader
181
182/**
Romain Guyee916f12010-09-20 17:53:08 -0700183 * A shader that draws a sweep gradient.
184 */
185struct SkiaSweepGradientShader: public SkiaShader {
Romain Guy79537452011-10-12 13:48:51 -0700186 ANDROID_API SkiaSweepGradientShader(float x, float y, uint32_t* colors, float* positions,
187 int count, SkShader* key, SkMatrix* matrix, bool blend);
Romain Guyee916f12010-09-20 17:53:08 -0700188 ~SkiaSweepGradientShader();
Romain Guy24c00212011-01-14 15:31:00 -0800189 SkiaShader* copy();
Romain Guyee916f12010-09-20 17:53:08 -0700190
Romain Guyddb80be2010-09-20 19:04:33 -0700191 virtual void describe(ProgramDescription& description, const Extensions& extensions);
Romain Guy14830942010-10-07 15:07:45 -0700192 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
Romain Guyee916f12010-09-20 17:53:08 -0700193 GLuint* textureUnit);
Romain Guyee916f12010-09-20 17:53:08 -0700194
Romain Guyddb80be2010-09-20 19:04:33 -0700195protected:
Chris Craike63f7c622013-10-17 10:30:55 -0700196 SkiaSweepGradientShader(Type type, uint32_t* colors, float* positions,
Romain Guyddb80be2010-09-20 19:04:33 -0700197 int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
Romain Guy24c00212011-01-14 15:31:00 -0800198 SkiaSweepGradientShader() {
199 }
Romain Guyddb80be2010-09-20 19:04:33 -0700200
Romain Guy42e1e0d2012-07-30 14:47:51 -0700201 bool mIsSimple;
Romain Guyee916f12010-09-20 17:53:08 -0700202 uint32_t* mColors;
203 float* mPositions;
204 int mCount;
205}; // struct SkiaSweepGradientShader
206
207/**
Romain Guyddb80be2010-09-20 19:04:33 -0700208 * A shader that draws a circular gradient.
209 */
210struct SkiaCircularGradientShader: public SkiaSweepGradientShader {
Romain Guy79537452011-10-12 13:48:51 -0700211 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);
Romain Guy24c00212011-01-14 15:31:00 -0800214 SkiaShader* copy();
Romain Guyddb80be2010-09-20 19:04:33 -0700215
216 void describe(ProgramDescription& description, const Extensions& extensions);
Romain Guy24c00212011-01-14 15:31:00 -0800217
218private:
219 SkiaCircularGradientShader() {
220 }
Romain Guyddb80be2010-09-20 19:04:33 -0700221}; // struct SkiaCircularGradientShader
222
223/**
Romain Guy06f96e22010-07-30 19:18:16 -0700224 * A shader that draws two shaders, composited with an xfermode.
225 */
226struct SkiaComposeShader: public SkiaShader {
Romain Guy79537452011-10-12 13:48:51 -0700227 ANDROID_API SkiaComposeShader(SkiaShader* first, SkiaShader* second, SkXfermode::Mode mode,
228 SkShader* key);
Romain Guy43ccf462011-01-14 18:51:01 -0800229 ~SkiaComposeShader();
Romain Guy24c00212011-01-14 15:31:00 -0800230 SkiaShader* copy();
Romain Guy06f96e22010-07-30 19:18:16 -0700231
Romain Guy8aa195d2013-06-04 18:00:09 -0700232 void setCaches(Caches& caches) {
233 SkiaShader::setCaches(caches);
234 mFirst->setCaches(caches);
235 mSecond->setCaches(caches);
236 }
Romain Guy06f96e22010-07-30 19:18:16 -0700237
238 void describe(ProgramDescription& description, const Extensions& extensions);
239 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
240 GLuint* textureUnit);
241
242private:
Romain Guy43ccf462011-01-14 18:51:01 -0800243 SkiaComposeShader(): mCleanup(false) {
244 }
245
246 void cleanup() {
247 mCleanup = true;
Romain Guy24c00212011-01-14 15:31:00 -0800248 }
249
Romain Guy06f96e22010-07-30 19:18:16 -0700250 SkiaShader* mFirst;
251 SkiaShader* mSecond;
252 SkXfermode::Mode mMode;
Romain Guy43ccf462011-01-14 18:51:01 -0800253
254 bool mCleanup;
Romain Guy06f96e22010-07-30 19:18:16 -0700255}; // struct SkiaComposeShader
256
257}; // namespace uirenderer
258}; // namespace android
259
Romain Guy5b3b3522010-10-27 18:57:51 -0700260#endif // ANDROID_HWUI_SKIA_SHADER_H