blob: 9f3025720d5ca5fd2e28074b876777c75d13f491 [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,
Chris Craik3f0854292014-04-15 16:18:08 -070061 SkShader::TileMode tileY, const 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
Chris Craik3f0854292014-04-15 16:18:08 -070091 void setMatrix(const SkMatrix* matrix) {
Romain Guy14830942010-10-07 15:07:45 -070092 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/**
Chris Craik3f0854292014-04-15 16:18:08 -0700137 * A shader that draws a layer.
138 */
139struct SkiaLayerShader: public SkiaShader {
140 SkiaLayerShader(Layer* layer, const SkMatrix* matrix);
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
147private:
148 SkiaLayerShader() {
149 }
150
151 Layer* mLayer;
152}; // struct SkiaLayerShader
153
154/**
Romain Guy06f96e22010-07-30 19:18:16 -0700155 * A shader that draws a bitmap.
156 */
157struct SkiaBitmapShader: public SkiaShader {
Romain Guy79537452011-10-12 13:48:51 -0700158 ANDROID_API SkiaBitmapShader(SkBitmap* bitmap, SkShader* key, SkShader::TileMode tileX,
Romain Guy06f96e22010-07-30 19:18:16 -0700159 SkShader::TileMode tileY, SkMatrix* matrix, bool blend);
Romain Guy24c00212011-01-14 15:31:00 -0800160 SkiaShader* copy();
Romain Guy06f96e22010-07-30 19:18:16 -0700161
162 void describe(ProgramDescription& description, const Extensions& extensions);
163 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
164 GLuint* textureUnit);
165
166private:
lina.x.pi92028732014-01-09 18:17:03 +0800167 SkiaBitmapShader() : mBitmap(NULL), mTexture(NULL) {
Romain Guy24c00212011-01-14 15:31:00 -0800168 }
169
Romain Guy06f96e22010-07-30 19:18:16 -0700170 SkBitmap* mBitmap;
Romain Guy8164c2d2010-10-25 18:03:28 -0700171 Texture* mTexture;
Romain Guy29d89972010-09-22 16:10:57 -0700172 GLenum mWrapS;
173 GLenum mWrapT;
Romain Guy06f96e22010-07-30 19:18:16 -0700174}; // struct SkiaBitmapShader
175
176/**
177 * A shader that draws a linear gradient.
178 */
179struct SkiaLinearGradientShader: public SkiaShader {
Romain Guy79537452011-10-12 13:48:51 -0700180 ANDROID_API SkiaLinearGradientShader(float* bounds, uint32_t* colors, float* positions,
181 int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
Romain Guy06f96e22010-07-30 19:18:16 -0700182 ~SkiaLinearGradientShader();
Romain Guy24c00212011-01-14 15:31:00 -0800183 SkiaShader* copy();
Romain Guy06f96e22010-07-30 19:18:16 -0700184
185 void describe(ProgramDescription& description, const Extensions& extensions);
186 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
187 GLuint* textureUnit);
188
189private:
Romain Guy24c00212011-01-14 15:31:00 -0800190 SkiaLinearGradientShader() {
191 }
192
Romain Guy42e1e0d2012-07-30 14:47:51 -0700193 bool mIsSimple;
Romain Guy06f96e22010-07-30 19:18:16 -0700194 float* mBounds;
195 uint32_t* mColors;
196 float* mPositions;
197 int mCount;
198}; // struct SkiaLinearGradientShader
199
200/**
Romain Guyee916f12010-09-20 17:53:08 -0700201 * A shader that draws a sweep gradient.
202 */
203struct SkiaSweepGradientShader: public SkiaShader {
Romain Guy79537452011-10-12 13:48:51 -0700204 ANDROID_API SkiaSweepGradientShader(float x, float y, uint32_t* colors, float* positions,
205 int count, SkShader* key, SkMatrix* matrix, bool blend);
Romain Guyee916f12010-09-20 17:53:08 -0700206 ~SkiaSweepGradientShader();
Romain Guy24c00212011-01-14 15:31:00 -0800207 SkiaShader* copy();
Romain Guyee916f12010-09-20 17:53:08 -0700208
Romain Guyddb80be2010-09-20 19:04:33 -0700209 virtual void describe(ProgramDescription& description, const Extensions& extensions);
Romain Guy14830942010-10-07 15:07:45 -0700210 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
Romain Guyee916f12010-09-20 17:53:08 -0700211 GLuint* textureUnit);
Romain Guyee916f12010-09-20 17:53:08 -0700212
Romain Guyddb80be2010-09-20 19:04:33 -0700213protected:
Chris Craike63f7c622013-10-17 10:30:55 -0700214 SkiaSweepGradientShader(Type type, uint32_t* colors, float* positions,
Romain Guyddb80be2010-09-20 19:04:33 -0700215 int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
Romain Guy24c00212011-01-14 15:31:00 -0800216 SkiaSweepGradientShader() {
217 }
Romain Guyddb80be2010-09-20 19:04:33 -0700218
Romain Guy42e1e0d2012-07-30 14:47:51 -0700219 bool mIsSimple;
Romain Guyee916f12010-09-20 17:53:08 -0700220 uint32_t* mColors;
221 float* mPositions;
222 int mCount;
223}; // struct SkiaSweepGradientShader
224
225/**
Romain Guyddb80be2010-09-20 19:04:33 -0700226 * A shader that draws a circular gradient.
227 */
228struct SkiaCircularGradientShader: public SkiaSweepGradientShader {
Romain Guy79537452011-10-12 13:48:51 -0700229 ANDROID_API SkiaCircularGradientShader(float x, float y, float radius, uint32_t* colors,
230 float* positions, int count, SkShader* key,SkShader::TileMode tileMode,
231 SkMatrix* matrix, bool blend);
Romain Guy24c00212011-01-14 15:31:00 -0800232 SkiaShader* copy();
Romain Guyddb80be2010-09-20 19:04:33 -0700233
234 void describe(ProgramDescription& description, const Extensions& extensions);
Romain Guy24c00212011-01-14 15:31:00 -0800235
236private:
237 SkiaCircularGradientShader() {
238 }
Romain Guyddb80be2010-09-20 19:04:33 -0700239}; // struct SkiaCircularGradientShader
240
241/**
Romain Guy06f96e22010-07-30 19:18:16 -0700242 * A shader that draws two shaders, composited with an xfermode.
243 */
244struct SkiaComposeShader: public SkiaShader {
Romain Guy79537452011-10-12 13:48:51 -0700245 ANDROID_API SkiaComposeShader(SkiaShader* first, SkiaShader* second, SkXfermode::Mode mode,
246 SkShader* key);
Romain Guy43ccf462011-01-14 18:51:01 -0800247 ~SkiaComposeShader();
Romain Guy24c00212011-01-14 15:31:00 -0800248 SkiaShader* copy();
Romain Guy06f96e22010-07-30 19:18:16 -0700249
Romain Guy8aa195d2013-06-04 18:00:09 -0700250 void setCaches(Caches& caches) {
251 SkiaShader::setCaches(caches);
252 mFirst->setCaches(caches);
253 mSecond->setCaches(caches);
254 }
Romain Guy06f96e22010-07-30 19:18:16 -0700255
256 void describe(ProgramDescription& description, const Extensions& extensions);
257 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
258 GLuint* textureUnit);
259
260private:
Romain Guy43ccf462011-01-14 18:51:01 -0800261 SkiaComposeShader(): mCleanup(false) {
262 }
263
264 void cleanup() {
265 mCleanup = true;
Romain Guy24c00212011-01-14 15:31:00 -0800266 }
267
Romain Guy06f96e22010-07-30 19:18:16 -0700268 SkiaShader* mFirst;
269 SkiaShader* mSecond;
270 SkXfermode::Mode mMode;
Romain Guy43ccf462011-01-14 18:51:01 -0800271
272 bool mCleanup;
Romain Guy06f96e22010-07-30 19:18:16 -0700273}; // struct SkiaComposeShader
274
275}; // namespace uirenderer
276}; // namespace android
277
Romain Guy5b3b3522010-10-27 18:57:51 -0700278#endif // ANDROID_HWUI_SKIA_SHADER_H