Home | History | Annotate | Download | only in hwui
      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 
     33 namespace android {
     34 namespace 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  */
     44 struct 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 
     57     ANDROID_API SkiaShader(Type type, SkShader* key, SkShader::TileMode tileX,
     58             SkShader::TileMode tileY, SkMatrix* matrix, bool blend);
     59     virtual ~SkiaShader();
     60 
     61     virtual SkiaShader* copy() = 0;
     62     void copyFrom(const SkiaShader& shader);
     63 
     64     virtual void describe(ProgramDescription& description, const Extensions& extensions);
     65     virtual void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
     66             GLuint* textureUnit);
     67 
     68     inline SkShader* getSkShader() {
     69         return mKey;
     70     }
     71 
     72     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 
     85     uint32_t getGenerationId() {
     86         return mGenerationId;
     87     }
     88 
     89     void setMatrix(SkMatrix* matrix) {
     90         updateLocalMatrix(matrix);
     91         mGenerationId++;
     92     }
     93 
     94     void updateLocalMatrix(const SkMatrix* matrix) {
     95         if (matrix) {
     96             mat4 localMatrix(*matrix);
     97             mShaderMatrix.loadInverse(localMatrix);
     98         } else {
     99             mShaderMatrix.loadIdentity();
    100         }
    101     }
    102 
    103     void computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView);
    104 
    105 protected:
    106     SkiaShader() {
    107     }
    108 
    109     /**
    110      * The appropriate texture unit must have been activated prior to invoking
    111      * this method.
    112      */
    113     inline void bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT);
    114 
    115     Type mType;
    116     SkShader* mKey;
    117     SkShader::TileMode mTileX;
    118     SkShader::TileMode mTileY;
    119     bool mBlend;
    120 
    121     TextureCache* mTextureCache;
    122     GradientCache* mGradientCache;
    123 
    124     mat4 mUnitMatrix;
    125     mat4 mShaderMatrix;
    126 
    127 private:
    128     uint32_t mGenerationId;
    129 }; // struct SkiaShader
    130 
    131 
    132 ///////////////////////////////////////////////////////////////////////////////
    133 // Implementations
    134 ///////////////////////////////////////////////////////////////////////////////
    135 
    136 /**
    137  * A shader that draws a bitmap.
    138  */
    139 struct 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 
    148 private:
    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  */
    161 struct 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 
    171 private:
    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  */
    185 struct 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 
    195 protected:
    196     SkiaSweepGradientShader(Type type, float x, float y, 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  */
    210 struct 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 
    218 private:
    219     SkiaCircularGradientShader() {
    220     }
    221 }; // struct SkiaCircularGradientShader
    222 
    223 /**
    224  * A shader that draws two shaders, composited with an xfermode.
    225  */
    226 struct 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 set(TextureCache* textureCache, GradientCache* gradientCache);
    233 
    234     void describe(ProgramDescription& description, const Extensions& extensions);
    235     void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
    236             GLuint* textureUnit);
    237 
    238 private:
    239     SkiaComposeShader(): mCleanup(false) {
    240     }
    241 
    242     void cleanup() {
    243         mCleanup = true;
    244     }
    245 
    246     SkiaShader* mFirst;
    247     SkiaShader* mSecond;
    248     SkXfermode::Mode mMode;
    249 
    250     bool mCleanup;
    251 }; // struct SkiaComposeShader
    252 
    253 }; // namespace uirenderer
    254 }; // namespace android
    255 
    256 #endif // ANDROID_HWUI_SKIA_SHADER_H
    257