summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h
blob: b233f2bd117e79001ea259d15341b3134033f053 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ShaderProgram_h
#define ShaderProgram_h

#if USE(ACCELERATED_COMPOSITING)

#include "Color.h"
#include "FloatRect.h"
#include "IntRect.h"
#include "SkRect.h"
#include "TransformationMatrix.h"
#include <GLES2/gl2.h>

#define MAX_CONTRAST 5

namespace WebCore {

class DrawQuadData;
class PureColorQuadData;
class TextureQuadData;

enum ShaderType {
    UndefinedShader = -1,
    PureColor,
    Tex2D,
    Tex2DInv,
    TexOES,
    TexOESInv,
    Video,
    // When growing this enum list, make sure to insert before the
    // MaxShaderNumber and init the m_handleArray accordingly.
    MaxShaderNumber
};

struct ShaderHandles {
    ShaderHandles()
        : alphaHandle(-1)
        , contrastHandle(-1)
        , positionHandle(-1)
        , programHandle(-1)
        , projMtxHandle(-1)
        , pureColorHandle(-1)
        , texSamplerHandle(-1)
        , videoMtxHandle(-1)
    {
    }

    void init(GLint alphaHdl, GLint contrastHdl, GLint posHdl, GLint pgmHdl,
              GLint projMtxHdl, GLint colorHdl, GLint texSamplerHdl,
              GLint videoMtxHdl)
    {
        alphaHandle = alphaHdl;
        contrastHandle = contrastHdl;
        positionHandle = posHdl;
        programHandle = pgmHdl;
        projMtxHandle = projMtxHdl;
        pureColorHandle = colorHdl;
        texSamplerHandle = texSamplerHdl;
        videoMtxHandle = videoMtxHdl;
    }

    GLint alphaHandle;
    GLint contrastHandle;
    GLint positionHandle;
    GLint programHandle;
    GLint projMtxHandle;
    GLint pureColorHandle;
    GLint texSamplerHandle;
    GLint videoMtxHandle;
};

struct ShaderResource {
    ShaderResource()
        : program(-1)
        , vertexShader(-1)
        , fragmentShader(-1)
    {
    };

    ShaderResource(GLuint prog, GLuint vertex, GLuint fragment)
        : program(prog)
        , vertexShader(vertex)
        , fragmentShader(fragment)
    {
    };

    GLuint program;
    GLuint vertexShader;
    GLuint fragmentShader;
};

class ShaderProgram {
public:
    ShaderProgram();
    void initGLResources();
    void cleanupGLResources();
    // Drawing
    void setupDrawing(const IntRect& viewRect, const SkRect& visibleRect,
                      const IntRect& webViewRect, int titleBarHeight,
                      const IntRect& screenClip, float scale);
    float zValue(const TransformationMatrix& drawMatrix, float w, float h);

    // For drawQuad and drawLayerQuad, they can handle 3 cases for now:
    // 1) textureTarget == GL_TEXTURE_2D
    // Normal texture in GL_TEXTURE_2D target.
    // 2) textureTarget == GL_TEXTURE_EXTERNAL_OES
    // Surface texture in GL_TEXTURE_EXTERNAL_OES target.
    // 3) textureId == 0
    // No texture needed, just a pureColor quad.
    void drawQuad(const DrawQuadData* data);
    void drawVideoLayerQuad(const TransformationMatrix& drawMatrix,
                     float* textureMatrix, SkRect& geometry, int textureId);
    FloatRect rectInScreenCoord(const TransformationMatrix& drawMatrix,
                                const IntSize& size);
    FloatRect rectInInvScreenCoord(const TransformationMatrix& drawMatrix,
                                const IntSize& size);

    FloatRect rectInInvScreenCoord(const FloatRect& rect);
    FloatRect rectInScreenCoord(const FloatRect& rect);
    FloatRect convertScreenCoordToDocumentCoord(const FloatRect& rect);
    FloatRect convertInvScreenCoordToScreenCoord(const FloatRect& rect);
    FloatRect convertScreenCoordToInvScreenCoord(const FloatRect& rect);

    void clip(const FloatRect& rect);
    IntRect clippedRectWithViewport(const IntRect& rect, int margin = 0);
    FloatRect documentViewport() { return m_documentViewport; }

    float contrast() { return m_contrast; }
    void setContrast(float c)
    {
        float contrast = c;
        if (contrast < 0)
            contrast = 0;
        if (contrast > MAX_CONTRAST)
            contrast = MAX_CONTRAST;
        m_contrast = contrast;
    }
    void setWebViewMatrix(const float* matrix, bool alphaLayer);

    // This delta is the delta from the layout pos and the current animation pos.
    // Basically, in terms of layout, the webview is still in the original layout
    // pos, as without animation. Such that the viewport and visible rect etc are
    // still in that pos, too, except the clipping info.
    // Our rendering approach is after applying all the matrix, webView is
    // rendered as if it was at the original layout pos, but then offset the
    // glViewport to match the animation.
    void calculateAnimationDelta();
    int getAnimationDeltaX() { return m_animationDelta.x(); }
    int getAnimationDeltaY() { return m_animationDelta.y(); }
    bool needsInit() { return m_needsInit; }

private:
    GLuint loadShader(GLenum shaderType, const char* pSource);
    GLint createProgram(const char* vertexSource, const char* fragmentSource);
    GLfloat* getProjectionMatrix(const DrawQuadData* data);
    void setBlendingState(bool enableBlending);
    void drawQuadInternal(ShaderType type, const GLfloat* matrix, int textureId,
                         float opacity, GLenum textureTarget, GLenum filter,
                         const Color& pureColor);
    Color shaderColor(Color pureColor, float opacity);
    ShaderType getTextureShaderType(GLenum textureTarget);
    void resetBlending();

    bool m_blendingEnabled;

    TransformationMatrix m_projectionMatrix;
    GLuint m_textureBuffer[1];

    TransformationMatrix m_documentToScreenMatrix;
    TransformationMatrix m_documentToInvScreenMatrix;
    SkRect m_viewport;
    IntRect m_viewRect;
    FloatRect m_clipRect;
    IntRect m_screenClip;
    int m_titleBarHeight;
    IntRect m_webViewRect;

    FloatRect m_documentViewport;

    float m_contrast;

    bool m_alphaLayer;
    TransformationMatrix m_webViewMatrix;
    float m_currentScale;

    // After the webViewTranform, we need to reposition the rect to match our viewport.
    // Basically, the webViewTransformMatrix should apply on the screen resolution.
    // So we start by doing the scale and translate to get each tile into screen coordinates.
    // After applying the webViewTransformMatrix, b/c the way it currently set up
    // for scroll and titlebar, we need to offset both of them.
    // Finally, map everything back to (-1, 1) by using the m_projectionMatrix.
    // TODO: Given that m_webViewMatrix contains most of the tranformation
    // information, we should be able to get rid of some parameter we got from
    // Java side and simplify our code.
    TransformationMatrix m_repositionMatrix;
    IntPoint m_animationDelta;

    // Put all the uniform location (handle) info into an array, and group them
    // by the shader's type, this can help to clean up the interface.
    // TODO: use the type and data comparison to skip GL call if possible.
    ShaderHandles m_handleArray[MaxShaderNumber];

    // If there is any GL error happens such that the Shaders are not initialized
    // successfully at the first time, then we need to init again when we draw.
    bool m_needsInit;

    // For transfer queue blitting, we need a special matrix map from (0,1) to
    // (-1,1)
    GLfloat m_transferProjMtx[16];

    GLfloat m_tileProjMatrix[16];

    Vector<ShaderResource> m_resources;
};

} // namespace WebCore

#endif // USE(ACCELERATED_COMPOSITING)
#endif // ShaderProgram_h