Home | History | Annotate | Download | only in rendering
      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 ShaderProgram_h
     18 #define ShaderProgram_h
     19 
     20 #if USE(ACCELERATED_COMPOSITING)
     21 
     22 #include "Color.h"
     23 #include "FloatRect.h"
     24 #include "IntRect.h"
     25 #include "SkRect.h"
     26 #include "TransformationMatrix.h"
     27 #include "private/hwui/DrawGlInfo.h"
     28 #include <GLES2/gl2.h>
     29 
     30 #define MAX_CONTRAST 5
     31 #define DEBUG_MATRIX 0
     32 
     33 namespace WebCore {
     34 
     35 class DrawQuadData;
     36 class PureColorQuadData;
     37 class TextureQuadData;
     38 
     39 enum ShaderType {
     40     UndefinedShader = -1,
     41     PureColor,
     42     Tex2D,
     43     Tex2DInv,
     44     TexOES,
     45     TexOESInv,
     46     Video,
     47     RepeatTex,
     48     RepeatTexInv,
     49     // When growing this enum list, make sure to insert before the
     50     // MaxShaderNumber and init the m_handleArray accordingly.
     51     MaxShaderNumber
     52 };
     53 
     54 struct ShaderHandles {
     55     ShaderHandles()
     56         : alphaHandle(-1)
     57         , contrastHandle(-1)
     58         , positionHandle(-1)
     59         , programHandle(-1)
     60         , projMtxHandle(-1)
     61         , pureColorHandle(-1)
     62         , texSamplerHandle(-1)
     63         , videoMtxHandle(-1)
     64         , fillPortionHandle(-1)
     65         , scaleHandle(-1)
     66     {
     67     }
     68 
     69     void init(GLint alphaHdl, GLint contrastHdl, GLint posHdl, GLint pgmHdl,
     70               GLint projMtxHdl, GLint colorHdl, GLint texSamplerHdl,
     71               GLint videoMtxHdl, GLint fillPortionHdl, GLint scaleHdl)
     72     {
     73         alphaHandle = alphaHdl;
     74         contrastHandle = contrastHdl;
     75         positionHandle = posHdl;
     76         programHandle = pgmHdl;
     77         projMtxHandle = projMtxHdl;
     78         pureColorHandle = colorHdl;
     79         texSamplerHandle = texSamplerHdl;
     80         videoMtxHandle = videoMtxHdl;
     81         fillPortionHandle = fillPortionHdl;
     82         scaleHandle = scaleHdl;
     83     }
     84 
     85     GLint alphaHandle;
     86     GLint contrastHandle;
     87     GLint positionHandle;
     88     GLint programHandle;
     89     GLint projMtxHandle;
     90     GLint pureColorHandle;
     91     GLint texSamplerHandle;
     92     GLint videoMtxHandle;
     93     GLint fillPortionHandle;
     94     GLint scaleHandle;
     95 };
     96 
     97 struct ShaderResource {
     98     ShaderResource()
     99         : program(-1)
    100         , vertexShader(-1)
    101         , fragmentShader(-1)
    102     {
    103     };
    104 
    105     ShaderResource(GLuint prog, GLuint vertex, GLuint fragment)
    106         : program(prog)
    107         , vertexShader(vertex)
    108         , fragmentShader(fragment)
    109     {
    110     };
    111 
    112     GLuint program;
    113     GLuint vertexShader;
    114     GLuint fragmentShader;
    115 };
    116 
    117 class ShaderProgram {
    118 public:
    119     ShaderProgram();
    120     void initGLResources();
    121     void cleanupGLResources();
    122     // Drawing
    123     void setupDrawing(const IntRect& invScreenRect, const SkRect& visibleContentRect,
    124                       const IntRect& screenRect, int titleBarHeight,
    125                       const IntRect& screenClip, float scale);
    126     float zValue(const TransformationMatrix& drawMatrix, float w, float h);
    127 
    128     // For drawQuad and drawLayerQuad, they can handle 3 cases for now:
    129     // 1) textureTarget == GL_TEXTURE_2D
    130     // Normal texture in GL_TEXTURE_2D target.
    131     // 2) textureTarget == GL_TEXTURE_EXTERNAL_OES
    132     // Surface texture in GL_TEXTURE_EXTERNAL_OES target.
    133     // 3) textureId == 0
    134     // No texture needed, just a pureColor quad.
    135     void drawQuad(const DrawQuadData* data);
    136     void drawVideoLayerQuad(const TransformationMatrix& drawMatrix,
    137                      float* textureMatrix, SkRect& geometry, int textureId);
    138     FloatRect rectInInvViewCoord(const TransformationMatrix& drawMatrix,
    139                                 const IntSize& size);
    140     FloatRect rectInViewCoord(const TransformationMatrix& drawMatrix,
    141                                 const IntSize& size);
    142 
    143     FloatRect rectInViewCoord(const FloatRect& rect);
    144     FloatRect rectInInvViewCoord(const FloatRect& rect);
    145     FloatRect convertInvViewCoordToContentCoord(const FloatRect& rect);
    146     FloatRect convertViewCoordToInvViewCoord(const FloatRect& rect);
    147     FloatRect convertInvViewCoordToViewCoord(const FloatRect& rect);
    148 
    149     void clip(const FloatRect& rect);
    150     IntRect clippedRectWithVisibleContentRect(const IntRect& rect, int margin = 0);
    151     FloatRect contentViewport() { return m_contentViewport; }
    152 
    153     float contrast() { return m_contrast; }
    154     void setContrast(float c)
    155     {
    156         float contrast = c;
    157         if (contrast < 0)
    158             contrast = 0;
    159         if (contrast > MAX_CONTRAST)
    160             contrast = MAX_CONTRAST;
    161         m_contrast = contrast;
    162     }
    163     void setGLDrawInfo(const android::uirenderer::DrawGlInfo* info);
    164     void forceNeedsInit() { m_needsInit = true; }
    165     bool needsInit() { return m_needsInit; }
    166     bool usePointSampling(float tileScale, const TransformationMatrix* layerTransform);
    167 
    168 private:
    169     GLuint loadShader(GLenum shaderType, const char* pSource);
    170     GLint createProgram(const char* vertexSource, const char* fragmentSource);
    171     void initProgram(ShaderType type);
    172     GLfloat* getTileProjectionMatrix(const DrawQuadData* data);
    173     void setBlendingState(bool enableBlending);
    174     void drawQuadInternal(ShaderType type, const GLfloat* matrix, int textureId,
    175                          float opacity, GLenum textureTarget, GLenum filter,
    176                          const Color& pureColor,  const FloatRect& fillPortion,
    177                          const FloatSize& repeatScale);
    178     Color shaderColor(Color pureColor, float opacity);
    179     ShaderType getTextureShaderType(GLenum textureTarget, bool hasRepeatScale);
    180     void resetBlending();
    181     void setupSurfaceProjectionMatrix();
    182 #if DEBUG_MATRIX
    183     FloatRect debugMatrixTransform(const TransformationMatrix& matrix, const char* matrixName);
    184     void debugMatrixInfo(float currentScale,
    185                          const TransformationMatrix& clipProjectionMatrix,
    186                          const TransformationMatrix& webViewMatrix,
    187                          const TransformationMatrix& modifiedDrawMatrix,
    188                          const TransformationMatrix* layerMatrix);
    189 #endif // DEBUG_MATRIX
    190 
    191     bool m_blendingEnabled;
    192 
    193     TransformationMatrix m_surfaceProjectionMatrix;
    194     TransformationMatrix m_clipProjectionMatrix;
    195     TransformationMatrix m_visibleContentRectProjectionMatrix;
    196     GLuint m_textureBuffer[1];
    197 
    198     TransformationMatrix m_contentToInvViewMatrix;
    199     TransformationMatrix m_contentToViewMatrix;
    200     SkRect m_visibleContentRect;
    201     IntRect m_invScreenRect;
    202     FloatRect m_clipRect;
    203     IntRect m_invViewClip;
    204     int m_titleBarHeight;
    205     // This is the layout position in screen coordinate and didn't contain the
    206     // animation offset.
    207     IntRect m_screenRect;
    208 
    209     FloatRect m_contentViewport;
    210 
    211     float m_contrast;
    212 
    213     // The height of the render target, either FBO or screen.
    214     int m_targetHeight;
    215     bool m_alphaLayer;
    216     TransformationMatrix m_webViewMatrix;
    217     float m_currentScale;
    218 
    219     // Put all the uniform location (handle) info into an array, and group them
    220     // by the shader's type, this can help to clean up the interface.
    221     // TODO: use the type and data comparison to skip GL call if possible.
    222     ShaderHandles m_handleArray[MaxShaderNumber];
    223 
    224     // If there is any GL error happens such that the Shaders are not initialized
    225     // successfully at the first time, then we need to init again when we draw.
    226     bool m_needsInit;
    227 
    228     // For transfer queue blitting, we need a special matrix map from (0,1) to
    229     // (-1,1)
    230     GLfloat m_transferProjMtx[16];
    231 
    232     GLfloat m_tileProjMatrix[16];
    233 
    234     Vector<ShaderResource> m_resources;
    235 
    236     ShaderType m_cachedProgramType;
    237     GLfloat m_cachedOpacity;
    238     FloatRect m_cachedFillPortion;
    239     Color m_cachedPureColor;
    240 };
    241 
    242 } // namespace WebCore
    243 
    244 #endif // USE(ACCELERATED_COMPOSITING)
    245 #endif // ShaderProgram_h
    246