SkiaShader.h revision 3f085429fd47ebd32ac2463b3eae2a5a6c17be25
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, const 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(const 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 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/** 155 * A shader that draws a bitmap. 156 */ 157struct SkiaBitmapShader: public SkiaShader { 158 ANDROID_API SkiaBitmapShader(SkBitmap* bitmap, SkShader* key, SkShader::TileMode tileX, 159 SkShader::TileMode tileY, SkMatrix* matrix, bool blend); 160 SkiaShader* copy(); 161 162 void describe(ProgramDescription& description, const Extensions& extensions); 163 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, 164 GLuint* textureUnit); 165 166private: 167 SkiaBitmapShader() : mBitmap(NULL), mTexture(NULL) { 168 } 169 170 SkBitmap* mBitmap; 171 Texture* mTexture; 172 GLenum mWrapS; 173 GLenum mWrapT; 174}; // struct SkiaBitmapShader 175 176/** 177 * A shader that draws a linear gradient. 178 */ 179struct SkiaLinearGradientShader: public SkiaShader { 180 ANDROID_API SkiaLinearGradientShader(float* bounds, uint32_t* colors, float* positions, 181 int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend); 182 ~SkiaLinearGradientShader(); 183 SkiaShader* copy(); 184 185 void describe(ProgramDescription& description, const Extensions& extensions); 186 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, 187 GLuint* textureUnit); 188 189private: 190 SkiaLinearGradientShader() { 191 } 192 193 bool mIsSimple; 194 float* mBounds; 195 uint32_t* mColors; 196 float* mPositions; 197 int mCount; 198}; // struct SkiaLinearGradientShader 199 200/** 201 * A shader that draws a sweep gradient. 202 */ 203struct SkiaSweepGradientShader: public SkiaShader { 204 ANDROID_API SkiaSweepGradientShader(float x, float y, uint32_t* colors, float* positions, 205 int count, SkShader* key, SkMatrix* matrix, bool blend); 206 ~SkiaSweepGradientShader(); 207 SkiaShader* copy(); 208 209 virtual void describe(ProgramDescription& description, const Extensions& extensions); 210 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, 211 GLuint* textureUnit); 212 213protected: 214 SkiaSweepGradientShader(Type type, uint32_t* colors, float* positions, 215 int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend); 216 SkiaSweepGradientShader() { 217 } 218 219 bool mIsSimple; 220 uint32_t* mColors; 221 float* mPositions; 222 int mCount; 223}; // struct SkiaSweepGradientShader 224 225/** 226 * A shader that draws a circular gradient. 227 */ 228struct SkiaCircularGradientShader: public SkiaSweepGradientShader { 229 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); 232 SkiaShader* copy(); 233 234 void describe(ProgramDescription& description, const Extensions& extensions); 235 236private: 237 SkiaCircularGradientShader() { 238 } 239}; // struct SkiaCircularGradientShader 240 241/** 242 * A shader that draws two shaders, composited with an xfermode. 243 */ 244struct SkiaComposeShader: public SkiaShader { 245 ANDROID_API SkiaComposeShader(SkiaShader* first, SkiaShader* second, SkXfermode::Mode mode, 246 SkShader* key); 247 ~SkiaComposeShader(); 248 SkiaShader* copy(); 249 250 void setCaches(Caches& caches) { 251 SkiaShader::setCaches(caches); 252 mFirst->setCaches(caches); 253 mSecond->setCaches(caches); 254 } 255 256 void describe(ProgramDescription& description, const Extensions& extensions); 257 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, 258 GLuint* textureUnit); 259 260private: 261 SkiaComposeShader(): mCleanup(false) { 262 } 263 264 void cleanup() { 265 mCleanup = true; 266 } 267 268 SkiaShader* mFirst; 269 SkiaShader* mSecond; 270 SkXfermode::Mode mMode; 271 272 bool mCleanup; 273}; // struct SkiaComposeShader 274 275}; // namespace uirenderer 276}; // namespace android 277 278#endif // ANDROID_HWUI_SKIA_SHADER_H 279