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
33namespace WebCore {
34
35class DrawQuadData;
36class PureColorQuadData;
37class TextureQuadData;
38
39enum 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
54struct 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
97struct 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
117class ShaderProgram {
118public:
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
168private:
169    GLuint loadShader(GLenum shaderType, const char* pSource);
170    GLint createProgram(const char* vertexSource, const char* fragmentSource);
171    GLfloat* getTileProjectionMatrix(const DrawQuadData* data);
172    void setBlendingState(bool enableBlending);
173    void drawQuadInternal(ShaderType type, const GLfloat* matrix, int textureId,
174                         float opacity, GLenum textureTarget, GLenum filter,
175                         const Color& pureColor,  const FloatRect& fillPortion,
176                         const FloatSize& repeatScale);
177    Color shaderColor(Color pureColor, float opacity);
178    ShaderType getTextureShaderType(GLenum textureTarget, bool hasRepeatScale);
179    void resetBlending();
180    void setupSurfaceProjectionMatrix();
181#if DEBUG_MATRIX
182    FloatRect debugMatrixTransform(const TransformationMatrix& matrix, const char* matrixName);
183    void debugMatrixInfo(float currentScale,
184                         const TransformationMatrix& clipProjectionMatrix,
185                         const TransformationMatrix& webViewMatrix,
186                         const TransformationMatrix& modifiedDrawMatrix,
187                         const TransformationMatrix* layerMatrix);
188#endif // DEBUG_MATRIX
189
190    bool m_blendingEnabled;
191
192    TransformationMatrix m_surfaceProjectionMatrix;
193    TransformationMatrix m_clipProjectionMatrix;
194    TransformationMatrix m_visibleContentRectProjectionMatrix;
195    GLuint m_textureBuffer[1];
196
197    TransformationMatrix m_contentToInvViewMatrix;
198    TransformationMatrix m_contentToViewMatrix;
199    SkRect m_visibleContentRect;
200    IntRect m_invScreenRect;
201    FloatRect m_clipRect;
202    IntRect m_invViewClip;
203    int m_titleBarHeight;
204    // This is the layout position in screen coordinate and didn't contain the
205    // animation offset.
206    IntRect m_screenRect;
207
208    FloatRect m_contentViewport;
209
210    float m_contrast;
211
212    // The height of the render target, either FBO or screen.
213    int m_targetHeight;
214    bool m_alphaLayer;
215    TransformationMatrix m_webViewMatrix;
216    float m_currentScale;
217
218    // Put all the uniform location (handle) info into an array, and group them
219    // by the shader's type, this can help to clean up the interface.
220    // TODO: use the type and data comparison to skip GL call if possible.
221    ShaderHandles m_handleArray[MaxShaderNumber];
222
223    // If there is any GL error happens such that the Shaders are not initialized
224    // successfully at the first time, then we need to init again when we draw.
225    bool m_needsInit;
226
227    // For transfer queue blitting, we need a special matrix map from (0,1) to
228    // (-1,1)
229    GLfloat m_transferProjMtx[16];
230
231    GLfloat m_tileProjMatrix[16];
232
233    Vector<ShaderResource> m_resources;
234};
235
236} // namespace WebCore
237
238#endif // USE(ACCELERATED_COMPOSITING)
239#endif // ShaderProgram_h
240