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