SkiaShader.h revision 564acf7c9bff822f608cda0d5df0a64a9f9aaefd
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
33namespace android {
34namespace uirenderer {
35
36class 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 */
46class SkiaShader {
47public:
48    /**
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
60    ANDROID_API SkiaShader(Type type, SkShader* key, SkShader::TileMode tileX,
61            SkShader::TileMode tileY, SkMatrix* matrix, bool blend);
62    virtual ~SkiaShader();
63
64    virtual SkiaShader* copy() = 0;
65    void copyFrom(const SkiaShader& shader);
66
67    virtual void describe(ProgramDescription& description, const Extensions& extensions);
68    virtual void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
69            GLuint* textureUnit);
70
71    inline SkShader* getSkShader() {
72        return mKey;
73    }
74
75    inline bool blend() const {
76        return mBlend;
77    }
78
79    Type type() const {
80        return mType;
81    }
82
83    virtual void setCaches(Caches& caches) {
84        mCaches = &caches;
85    }
86
87    uint32_t getGenerationId() {
88        return mGenerationId;
89    }
90
91    void setMatrix(SkMatrix* matrix) {
92        updateLocalMatrix(matrix);
93        mGenerationId++;
94    }
95
96    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
107protected:
108    SkiaShader();
109
110    /**
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);
115
116    Type mType;
117    SkShader* mKey;
118    SkShader::TileMode mTileX;
119    SkShader::TileMode mTileY;
120    bool mBlend;
121
122    Caches* mCaches;
123
124    mat4 mUnitMatrix;
125    mat4 mShaderMatrix;
126
127private:
128    uint32_t mGenerationId;
129}; // struct SkiaShader
130
131
132///////////////////////////////////////////////////////////////////////////////
133// Implementations
134///////////////////////////////////////////////////////////////////////////////
135
136/**
137 * A shader that draws a bitmap.
138 */
139struct SkiaBitmapShader: public SkiaShader {
140    ANDROID_API SkiaBitmapShader(SkBitmap* bitmap, SkShader* key, SkShader::TileMode tileX,
141            SkShader::TileMode tileY, SkMatrix* matrix, bool blend);
142    SkiaShader* copy();
143
144    void describe(ProgramDescription& description, const Extensions& extensions);
145    void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
146            GLuint* textureUnit);
147
148private:
149    SkiaBitmapShader() {
150    }
151
152    SkBitmap* mBitmap;
153    Texture* mTexture;
154    GLenum mWrapS;
155    GLenum mWrapT;
156}; // struct SkiaBitmapShader
157
158/**
159 * A shader that draws a linear gradient.
160 */
161struct SkiaLinearGradientShader: public SkiaShader {
162    ANDROID_API SkiaLinearGradientShader(float* bounds, uint32_t* colors, float* positions,
163            int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
164    ~SkiaLinearGradientShader();
165    SkiaShader* copy();
166
167    void describe(ProgramDescription& description, const Extensions& extensions);
168    void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
169            GLuint* textureUnit);
170
171private:
172    SkiaLinearGradientShader() {
173    }
174
175    bool mIsSimple;
176    float* mBounds;
177    uint32_t* mColors;
178    float* mPositions;
179    int mCount;
180}; // struct SkiaLinearGradientShader
181
182/**
183 * A shader that draws a sweep gradient.
184 */
185struct SkiaSweepGradientShader: public SkiaShader {
186    ANDROID_API SkiaSweepGradientShader(float x, float y, uint32_t* colors, float* positions,
187            int count, SkShader* key, SkMatrix* matrix, bool blend);
188    ~SkiaSweepGradientShader();
189    SkiaShader* copy();
190
191    virtual void describe(ProgramDescription& description, const Extensions& extensions);
192    void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
193            GLuint* textureUnit);
194
195protected:
196    SkiaSweepGradientShader(Type type, uint32_t* colors, float* positions,
197            int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
198    SkiaSweepGradientShader() {
199    }
200
201    bool mIsSimple;
202    uint32_t* mColors;
203    float* mPositions;
204    int mCount;
205}; // struct SkiaSweepGradientShader
206
207/**
208 * A shader that draws a circular gradient.
209 */
210struct SkiaCircularGradientShader: public SkiaSweepGradientShader {
211    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);
214    SkiaShader* copy();
215
216    void describe(ProgramDescription& description, const Extensions& extensions);
217
218private:
219    SkiaCircularGradientShader() {
220    }
221}; // struct SkiaCircularGradientShader
222
223/**
224 * A shader that draws two shaders, composited with an xfermode.
225 */
226struct SkiaComposeShader: public SkiaShader {
227    ANDROID_API SkiaComposeShader(SkiaShader* first, SkiaShader* second, SkXfermode::Mode mode,
228            SkShader* key);
229    ~SkiaComposeShader();
230    SkiaShader* copy();
231
232    void setCaches(Caches& caches) {
233        SkiaShader::setCaches(caches);
234        mFirst->setCaches(caches);
235        mSecond->setCaches(caches);
236    }
237
238    void describe(ProgramDescription& description, const Extensions& extensions);
239    void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
240            GLuint* textureUnit);
241
242private:
243    SkiaComposeShader(): mCleanup(false) {
244    }
245
246    void cleanup() {
247        mCleanup = true;
248    }
249
250    SkiaShader* mFirst;
251    SkiaShader* mSecond;
252    SkXfermode::Mode mMode;
253
254    bool mCleanup;
255}; // struct SkiaComposeShader
256
257}; // namespace uirenderer
258}; // namespace android
259
260#endif // ANDROID_HWUI_SKIA_SHADER_H
261