/*
 * Copyright 2010, The Android Open Source Project
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#define LOG_TAG "ShaderProgram"
#define LOG_NDEBUG 1

#include "config.h"
#include "ShaderProgram.h"

#if USE(ACCELERATED_COMPOSITING)

#include "AndroidLog.h"
#include "DrawQuadData.h"
#include "FloatPoint3D.h"
#include "GLUtils.h"
#include "TilesManager.h"

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

#define EPSILON 0.00001f

namespace WebCore {

// fillPortion.xy = starting UV coordinates.
// fillPortion.zw = UV coordinates width and height.
static const char gVertexShader[] =
    "attribute vec4 vPosition;\n"
    "uniform mat4 projectionMatrix;\n"
    "uniform vec4 fillPortion;\n"
    "varying vec2 v_texCoord;\n"
    "void main() {\n"
    "  gl_Position = projectionMatrix * vPosition;\n"
    "  v_texCoord = vPosition.xy * fillPortion.zw + fillPortion.xy;\n"
    "}\n";

static const char gRepeatTexFragmentShader[] =
    "precision mediump float;\n"
    "varying vec2 v_texCoord; \n"
    "uniform float alpha; \n"
    "uniform sampler2D s_texture; \n"
    "uniform vec2 repeatScale;\n"
    "void main() {\n"
    "  vec2 repeatedTexCoord; "
    "  repeatedTexCoord.x = v_texCoord.x - floor(v_texCoord.x); "
    "  repeatedTexCoord.y = v_texCoord.y - floor(v_texCoord.y); "
    "  repeatedTexCoord.x = repeatedTexCoord.x * repeatScale.x; "
    "  repeatedTexCoord.y = repeatedTexCoord.y * repeatScale.y; "
    "  gl_FragColor = texture2D(s_texture, repeatedTexCoord); \n"
    "  gl_FragColor *= alpha; "
    "}\n";

static const char gRepeatTexFragmentShaderInverted[] =
    "precision mediump float;\n"
    "varying vec2 v_texCoord; \n"
    "uniform float alpha; \n"
    "uniform float contrast; \n"
    "uniform sampler2D s_texture; \n"
    "uniform vec2 repeatScale;\n"
    "void main() {\n"
    "  vec2 repeatedTexCoord; "
    "  repeatedTexCoord.x = v_texCoord.x - floor(v_texCoord.x); "
    "  repeatedTexCoord.y = v_texCoord.y - floor(v_texCoord.y); "
    "  repeatedTexCoord.x = repeatedTexCoord.x * repeatScale.x; "
    "  repeatedTexCoord.y = repeatedTexCoord.y * repeatScale.y; "
    "  vec4 pixel = texture2D(s_texture, repeatedTexCoord); \n"
    "  float a = pixel.a; \n"
    "  float color = a - (0.2989 * pixel.r + 0.5866 * pixel.g + 0.1145 * pixel.b);\n"
    "  color = ((color - a/2.0) * contrast) + a/2.0; \n"
    "  pixel.rgb = vec3(color, color, color); \n "
    "  gl_FragColor = pixel; \n"
    "  gl_FragColor *= alpha; "
    "}\n";

static const char gFragmentShader[] =
    "precision mediump float;\n"
    "varying vec2 v_texCoord; \n"
    "uniform float alpha; \n"
    "uniform sampler2D s_texture; \n"
    "void main() {\n"
    "  gl_FragColor = texture2D(s_texture, v_texCoord); \n"
    "  gl_FragColor *= alpha; "
    "}\n";

// We could pass the pureColor into either Vertex or Frag Shader.
// The reason we passed the color into the Vertex Shader is that some driver
// might create redundant copy when uniforms in fragment shader changed.
static const char gPureColorVertexShader[] =
    "attribute vec4 vPosition;\n"
    "uniform mat4 projectionMatrix;\n"
    "uniform vec4 inputColor;\n"
    "varying vec4 v_color;\n"
    "void main() {\n"
    "  gl_Position = projectionMatrix * vPosition;\n"
    "  v_color = inputColor;\n"
    "}\n";

static const char gPureColorFragmentShader[] =
    "precision mediump float;\n"
    "varying vec4 v_color;\n"
    "void main() {\n"
    "  gl_FragColor = v_color;\n"
    "}\n";

static const char gFragmentShaderInverted[] =
    "precision mediump float;\n"
    "varying vec2 v_texCoord; \n"
    "uniform float alpha; \n"
    "uniform float contrast; \n"
    "uniform sampler2D s_texture; \n"
    "void main() {\n"
    "  vec4 pixel = texture2D(s_texture, v_texCoord); \n"
    "  float a = pixel.a; \n"
    "  float color = a - (0.2989 * pixel.r + 0.5866 * pixel.g + 0.1145 * pixel.b);\n"
    "  color = ((color - a/2.0) * contrast) + a/2.0; \n"
    "  pixel.rgb = vec3(color, color, color); \n "
    "  gl_FragColor = pixel; \n"
    "  gl_FragColor *= alpha; \n"
    "}\n";

static const char gVideoVertexShader[] =
    "attribute vec4 vPosition;\n"
    "uniform mat4 textureMatrix;\n"
    "uniform mat4 projectionMatrix;\n"
    "varying vec2 v_texCoord;\n"
    "void main() {\n"
    "  gl_Position = projectionMatrix * vPosition;\n"
    "  v_texCoord = vec2(textureMatrix * vec4(vPosition.x, 1.0 - vPosition.y, 0.0, 1.0));\n"
    "}\n";

static const char gVideoFragmentShader[] =
    "#extension GL_OES_EGL_image_external : require\n"
    "precision mediump float;\n"
    "uniform samplerExternalOES s_yuvTexture;\n"
    "varying vec2 v_texCoord;\n"
    "void main() {\n"
    "  gl_FragColor = texture2D(s_yuvTexture, v_texCoord);\n"
    "}\n";

static const char gSurfaceTextureOESFragmentShader[] =
    "#extension GL_OES_EGL_image_external : require\n"
    "precision mediump float;\n"
    "varying vec2 v_texCoord; \n"
    "uniform float alpha; \n"
    "uniform samplerExternalOES s_texture; \n"
    "void main() {\n"
    "  gl_FragColor = texture2D(s_texture, v_texCoord); \n"
    "  gl_FragColor *= alpha; "
    "}\n";

static const char gSurfaceTextureOESFragmentShaderInverted[] =
    "#extension GL_OES_EGL_image_external : require\n"
    "precision mediump float;\n"
    "varying vec2 v_texCoord; \n"
    "uniform float alpha; \n"
    "uniform float contrast; \n"
    "uniform samplerExternalOES s_texture; \n"
    "void main() {\n"
    "  vec4 pixel = texture2D(s_texture, v_texCoord); \n"
    "  float a = pixel.a; \n"
    "  float color = a - (0.2989 * pixel.r + 0.5866 * pixel.g + 0.1145 * pixel.b);\n"
    "  color = ((color - a/2.0) * contrast) + a/2.0; \n"
    "  pixel.rgb = vec3(color, color, color); \n "
    "  gl_FragColor = pixel; \n"
    "  gl_FragColor *= alpha; \n"
    "}\n";

GLuint ShaderProgram::loadShader(GLenum shaderType, const char* pSource)
{
    GLuint shader = glCreateShader(shaderType);
    if (shader) {
        glShaderSource(shader, 1, &pSource, 0);
        glCompileShader(shader);
        GLint compiled = 0;
        glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
        if (!compiled) {
            GLint infoLen = 0;
            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
            if (infoLen) {
                char* buf = (char*) malloc(infoLen);
                if (buf) {
                glGetShaderInfoLog(shader, infoLen, 0, buf);
                ALOGE("could not compile shader %d:\n%s\n", shaderType, buf);
                free(buf);
            }
            glDeleteShader(shader);
            shader = 0;
            }
        }
    }
    return shader;
}

GLint ShaderProgram::createProgram(const char* pVertexSource, const char* pFragmentSource)
{
    GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
    if (!vertexShader) {
        ALOGE("couldn't load the vertex shader!");
        return -1;
    }

    GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
    if (!pixelShader) {
        ALOGE("couldn't load the pixel shader!");
        return -1;
    }

    GLuint program = glCreateProgram();
    if (program) {
        glAttachShader(program, vertexShader);
        GLUtils::checkGlError("glAttachShader vertex");
        glAttachShader(program, pixelShader);
        GLUtils::checkGlError("glAttachShader pixel");
        glLinkProgram(program);
        GLint linkStatus = GL_FALSE;
        glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
        if (linkStatus != GL_TRUE) {
            GLint bufLength = 0;
            glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
            if (bufLength) {
                char* buf = (char*) malloc(bufLength);
                if (buf) {
                    glGetProgramInfoLog(program, bufLength, 0, buf);
                    ALOGE("could not link program:\n%s\n", buf);
                    free(buf);
                }
            }
            glDeleteProgram(program);
            program = -1;
        }
    }

    ShaderResource newResource(program, vertexShader, pixelShader);
    m_resources.append(newResource);
    return program;
}

void ShaderProgram::initProgram(ShaderType type)
{
    // initialize shader's static texSampler and position values
    glUseProgram(m_handleArray[type].programHandle);

    if (m_handleArray[type].texSamplerHandle != -1)
        glUniform1i(m_handleArray[type].texSamplerHandle, 0);
    glEnableVertexAttribArray(m_handleArray[type].positionHandle);
}

ShaderProgram::ShaderProgram()
    : m_blendingEnabled(false)
    , m_contrast(1)
    , m_alphaLayer(false)
    , m_currentScale(1.0f)
    , m_needsInit(true)
{
    // initialize the matrix to calculate z values correctly, since it can be
    // used for that before setupDrawing is called.
    GLUtils::setOrthographicMatrix(m_visibleContentRectProjectionMatrix,
                                   0,0,1,1,
                                   -1000, 1000);
}

void ShaderProgram::cleanupGLResources()
{
    for (unsigned int i = 0; i < m_resources.size(); i++) {
        glDetachShader(m_resources[i].program, m_resources[i].vertexShader);
        glDetachShader(m_resources[i].program, m_resources[i].fragmentShader);
        glDeleteShader(m_resources[i].vertexShader);
        glDeleteShader(m_resources[i].fragmentShader);
        glDeleteProgram(m_resources[i].program);
    }
    glDeleteBuffers(1, m_textureBuffer);

    m_resources.clear();
    m_needsInit = true;
    GLUtils::checkGlError("cleanupGLResources");

    return;
}

void ShaderProgram::initGLResources()
{
    // To detect whether or not resources for ShaderProgram allocated
    // successfully, we clean up pre-existing errors here and will check for
    // new errors at the end of this function.
    GLUtils::checkGlError("before initGLResources");

    GLint tex2DProgram = createProgram(gVertexShader, gFragmentShader);
    GLint pureColorProgram = createProgram(gPureColorVertexShader, gPureColorFragmentShader);
    GLint tex2DInvProgram = createProgram(gVertexShader, gFragmentShaderInverted);
    GLint videoProgram = createProgram(gVideoVertexShader, gVideoFragmentShader);
    GLint texOESProgram =
        createProgram(gVertexShader, gSurfaceTextureOESFragmentShader);
    GLint texOESInvProgram =
        createProgram(gVertexShader, gSurfaceTextureOESFragmentShaderInverted);
    GLint repeatTexProgram =
        createProgram(gVertexShader, gRepeatTexFragmentShader);
    GLint repeatTexInvProgram =
        createProgram(gVertexShader, gRepeatTexFragmentShaderInverted);

    if (tex2DProgram == -1
        || pureColorProgram == -1
        || tex2DInvProgram == -1
        || videoProgram == -1
        || texOESProgram == -1
        || texOESInvProgram == -1
        || repeatTexProgram == -1
        || repeatTexInvProgram == -1) {
        m_needsInit = true;
        return;
    }

    GLint pureColorPosition = glGetAttribLocation(pureColorProgram, "vPosition");
    GLint pureColorProjMtx = glGetUniformLocation(pureColorProgram, "projectionMatrix");
    GLint pureColorValue = glGetUniformLocation(pureColorProgram, "inputColor");
    m_handleArray[PureColor].init(-1, -1, pureColorPosition, pureColorProgram,
                                  pureColorProjMtx, pureColorValue, -1, -1, -1, -1);
    initProgram(PureColor);

    GLint tex2DAlpha = glGetUniformLocation(tex2DProgram, "alpha");
    GLint tex2DPosition = glGetAttribLocation(tex2DProgram, "vPosition");
    GLint tex2DProjMtx = glGetUniformLocation(tex2DProgram, "projectionMatrix");
    GLint tex2DTexSampler = glGetUniformLocation(tex2DProgram, "s_texture");
    GLint tex2DFillPortion = glGetUniformLocation(tex2DProgram, "fillPortion");
    m_handleArray[Tex2D].init(tex2DAlpha, -1, tex2DPosition, tex2DProgram,
                              tex2DProjMtx, -1, tex2DTexSampler, -1, tex2DFillPortion, -1);
    initProgram(Tex2D);

    GLint tex2DInvAlpha = glGetUniformLocation(tex2DInvProgram, "alpha");
    GLint tex2DInvContrast = glGetUniformLocation(tex2DInvProgram, "contrast");
    GLint tex2DInvPosition = glGetAttribLocation(tex2DInvProgram, "vPosition");
    GLint tex2DInvProjMtx = glGetUniformLocation(tex2DInvProgram, "projectionMatrix");
    GLint tex2DInvTexSampler = glGetUniformLocation(tex2DInvProgram, "s_texture");
    GLint tex2DInvFillPortion = glGetUniformLocation(tex2DInvProgram, "fillPortion");
    m_handleArray[Tex2DInv].init(tex2DInvAlpha, tex2DInvContrast,
                                 tex2DInvPosition, tex2DInvProgram,
                                 tex2DInvProjMtx, -1,
                                 tex2DInvTexSampler, -1, tex2DInvFillPortion, -1);
    initProgram(Tex2DInv);

    GLint repeatTexAlpha = glGetUniformLocation(repeatTexProgram, "alpha");
    GLint repeatTexPosition = glGetAttribLocation(repeatTexProgram, "vPosition");
    GLint repeatTexProjMtx = glGetUniformLocation(repeatTexProgram, "projectionMatrix");
    GLint repeatTexTexSampler = glGetUniformLocation(repeatTexProgram, "s_texture");
    GLint repeatTexFillPortion = glGetUniformLocation(repeatTexProgram, "fillPortion");
    GLint repeatTexScale = glGetUniformLocation(repeatTexProgram, "repeatScale");
    m_handleArray[RepeatTex].init(repeatTexAlpha, -1, repeatTexPosition,
                                  repeatTexProgram,repeatTexProjMtx, -1,
                                  repeatTexTexSampler, -1, repeatTexFillPortion,
                                  repeatTexScale);
    initProgram(RepeatTex);

    GLint repeatTexInvAlpha = glGetUniformLocation(repeatTexInvProgram, "alpha");
    GLint repeatTexInvContrast = glGetUniformLocation(tex2DInvProgram, "contrast");
    GLint repeatTexInvPosition = glGetAttribLocation(repeatTexInvProgram, "vPosition");
    GLint repeatTexInvProjMtx = glGetUniformLocation(repeatTexInvProgram, "projectionMatrix");
    GLint repeatTexInvTexSampler = glGetUniformLocation(repeatTexInvProgram, "s_texture");
    GLint repeatTexInvFillPortion = glGetUniformLocation(repeatTexInvProgram, "fillPortion");
    GLint repeatTexInvScale = glGetUniformLocation(repeatTexInvProgram, "repeatScale");
    m_handleArray[RepeatTexInv].init(repeatTexInvAlpha, repeatTexInvContrast,
                                     repeatTexInvPosition, repeatTexInvProgram,
                                     repeatTexInvProjMtx, -1,
                                     repeatTexInvTexSampler, -1,
                                     repeatTexInvFillPortion, repeatTexInvScale);
    initProgram(RepeatTexInv);

    GLint texOESAlpha = glGetUniformLocation(texOESProgram, "alpha");
    GLint texOESPosition = glGetAttribLocation(texOESProgram, "vPosition");
    GLint texOESProjMtx = glGetUniformLocation(texOESProgram, "projectionMatrix");
    GLint texOESTexSampler = glGetUniformLocation(texOESProgram, "s_texture");
    GLint texOESFillPortion = glGetUniformLocation(texOESProgram, "fillPortion");
    m_handleArray[TexOES].init(texOESAlpha, -1, texOESPosition, texOESProgram,
                               texOESProjMtx, -1, texOESTexSampler, -1, texOESFillPortion, -1);
    initProgram(TexOES);

    GLint texOESInvAlpha = glGetUniformLocation(texOESInvProgram, "alpha");
    GLint texOESInvContrast = glGetUniformLocation(texOESInvProgram, "contrast");
    GLint texOESInvPosition = glGetAttribLocation(texOESInvProgram, "vPosition");
    GLint texOESInvProjMtx = glGetUniformLocation(texOESInvProgram, "projectionMatrix");
    GLint texOESInvTexSampler = glGetUniformLocation(texOESInvProgram, "s_texture");
    GLint texOESInvFillPortion = glGetUniformLocation(texOESInvProgram, "fillPortion");
    m_handleArray[TexOESInv].init(texOESInvAlpha, texOESInvContrast,
                                  texOESInvPosition, texOESInvProgram,
                                  texOESInvProjMtx, -1,
                                  texOESInvTexSampler, -1, texOESInvFillPortion, -1);
    initProgram(TexOESInv);

    GLint videoPosition = glGetAttribLocation(videoProgram, "vPosition");
    GLint videoProjMtx = glGetUniformLocation(videoProgram, "projectionMatrix");
    GLint videoTexSampler = glGetUniformLocation(videoProgram, "s_yuvTexture");
    GLint videoTexMtx = glGetUniformLocation(videoProgram, "textureMatrix");
    m_handleArray[Video].init(-1, -1, videoPosition, videoProgram,
                              videoProjMtx, -1, videoTexSampler,
                              videoTexMtx, -1, -1);
    initProgram(Video);

    const GLfloat coord[] = {
        0.0f, 0.0f, // C
        1.0f, 0.0f, // D
        0.0f, 1.0f, // A
        1.0f, 1.0f // B
    };

    glGenBuffers(1, m_textureBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]);
    glBufferData(GL_ARRAY_BUFFER, 2 * 4 * sizeof(GLfloat), coord, GL_STATIC_DRAW);

    TransformationMatrix matrix;
    // Map x,y from (0,1) to (-1, 1)
    matrix.scale3d(2, 2, 1);
    matrix.translate3d(-0.5, -0.5, 0);
    GLUtils::toGLMatrix(m_transferProjMtx, matrix);

    m_needsInit = GLUtils::checkGlError("initGLResources");
    return;
}

void ShaderProgram::resetBlending()
{
    glDisable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
    glBlendEquation(GL_FUNC_ADD);
    m_blendingEnabled = false;
}

void ShaderProgram::setBlendingState(bool enableBlending)
{
    if (enableBlending == m_blendingEnabled)
        return;

    if (enableBlending)
        glEnable(GL_BLEND);
    else
        glDisable(GL_BLEND);

    m_blendingEnabled = enableBlending;
}

/////////////////////////////////////////////////////////////////////////////////////////
// Drawing
/////////////////////////////////////////////////////////////////////////////////////////

// We have multiple coordinates to deal with: first is the screen coordinates,
// second is the view coordinates and the last one is content(document) coordinates.
// Both screen and view coordinates are in pixels.
// All these coordinates start from upper left, but for the purpose of OpenGL
// operations, we may need a inverted Y version of such coordinates which
// start from lower left.
//
// invScreenRect - inv screen coordinates starting from lower left.
// visibleContentRect - local content(document) coordinates starting from upper left.
// screenRect - screen coordinates starting from upper left.
// screenClip - screen coordinates starting from upper left.
//    ------------------------------------------
//    |(origin of screen)                      |
//    |screen                                  |
//    |   ---------------------------------    |
//    |   | (origin of view)              |    |
//    |   | webview                       |    |
//    |   |        --------               |    |
//    |   |        | clip |               |    |
//    |   |        |      |               |    |
//    |   |        --------               |    |
//    |   |                               |    |
//    |   |(origin of inv view)           |    |
//    |   ---------------------------------    |
//    |(origin of inv screen)                  |
//    ------------------------------------------
void ShaderProgram::setupDrawing(const IntRect& invScreenRect,
                                 const SkRect& visibleContentRect,
                                 const IntRect& screenRect, int titleBarHeight,
                                 const IntRect& screenClip, float scale)
{
    m_screenRect = screenRect;
    m_titleBarHeight = titleBarHeight;

    //// viewport ////
    GLUtils::setOrthographicMatrix(m_visibleContentRectProjectionMatrix,
                                   visibleContentRect.fLeft,
                                   visibleContentRect.fTop,
                                   visibleContentRect.fRight,
                                   visibleContentRect.fBottom,
                                   -1000, 1000);

    ALOGV("set m_clipProjectionMatrix, %d, %d, %d, %d",
          screenClip.x(), screenClip.y(), screenClip.x() + screenClip.width(),
          screenClip.y() + screenClip.height());

    // In order to incorporate the animation delta X and Y, using the clip as
    // the GL viewport can save all the trouble of re-position from screenRect
    // to final position.
    GLUtils::setOrthographicMatrix(m_clipProjectionMatrix, screenClip.x(), screenClip.y(),
                                   screenClip.x() + screenClip.width(),
                                   screenClip.y() + screenClip.height(), -1000, 1000);

    glViewport(screenClip.x(), m_targetHeight - screenClip.y() - screenClip.height() ,
               screenClip.width(), screenClip.height());

    m_visibleContentRect = visibleContentRect;
    m_currentScale = scale;


    //// viewRect ////
    m_invScreenRect = invScreenRect;

    // The following matrices transform content coordinates into view coordinates
    // and inv view coordinates.
    // Note that GLUtils::setOrthographicMatrix is inverting the Y.
    TransformationMatrix viewTranslate;
    viewTranslate.translate(1.0, 1.0);

    TransformationMatrix viewScale;
    viewScale.scale3d(m_invScreenRect.width() * 0.5f, m_invScreenRect.height() * 0.5f, 1);

    m_contentToInvViewMatrix = viewScale * viewTranslate * m_visibleContentRectProjectionMatrix;

    viewTranslate.scale3d(1, -1, 1);
    m_contentToViewMatrix = viewScale * viewTranslate * m_visibleContentRectProjectionMatrix;

    IntRect invViewRect(0, 0, m_screenRect.width(), m_screenRect.height());
    m_contentViewport = m_contentToInvViewMatrix.inverse().mapRect(invViewRect);


    //// clipping ////
    IntRect viewClip = screenClip;

    // The incoming screenClip is in screen coordinates, we first
    // translate it into view coordinates.
    // Then we convert it into inverted view coordinates.
    // Therefore, in the clip() function, we need to convert things back from
    // inverted view coordinates to inverted screen coordinates which is used by GL.
    viewClip.setX(screenClip.x() - m_screenRect.x());
    viewClip.setY(screenClip.y() - m_screenRect.y() - m_titleBarHeight);
    FloatRect invViewClip = convertViewCoordToInvViewCoord(viewClip);
    m_invViewClip.setLocation(IntPoint(invViewClip.x(), invViewClip.y()));
    // use ceilf to handle view -> doc -> view coord rounding errors
    m_invViewClip.setSize(IntSize(ceilf(invViewClip.width()), ceilf(invViewClip.height())));

    resetBlending();

    // Set up m_clipProjectionMatrix, m_currentScale and m_webViewMatrix before
    // calling this function.
    setupSurfaceProjectionMatrix();

    //// initialize frame-constant values ////
    glActiveTexture(GL_TEXTURE0);
    glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]);

    //// initialize GL cache ////
    m_cachedProgramType = UndefinedShader;
    m_cachedOpacity = -1;
    m_cachedFillPortion = FloatRect();
    m_cachedPureColor = Color();
}

// Calculate the right color value sent into the shader considering the (0,1)
// clamp and alpha blending.
Color ShaderProgram::shaderColor(Color pureColor, float opacity)
{
    float r = pureColor.red() / 255.0;
    float g = pureColor.green() / 255.0;
    float b = pureColor.blue() / 255.0;
    float a = pureColor.alpha() / 255.0;

    if (TilesManager::instance()->invertedScreen()) {
        float intensity = a - (0.2989 * r + 0.5866 * g + 0.1145 * b);
        intensity = ((intensity - a / 2.0) * m_contrast) + a / 2.0;
        intensity *= opacity;
        return Color(intensity, intensity, intensity, a * opacity);
    }
    return Color(r * opacity, g * opacity, b * opacity, a * opacity);
}

// For shaders using texture, it is easy to get the type from the textureTarget.
ShaderType ShaderProgram::getTextureShaderType(GLenum textureTarget,
                                               bool hasRepeatScale)
{
    ShaderType type = UndefinedShader;
    if (textureTarget == GL_TEXTURE_2D) {
        if (!TilesManager::instance()->invertedScreen())
            type = hasRepeatScale ?  RepeatTex : Tex2D;
        else {
            // With the new GPU texture upload path, we do not use an FBO
            // to blit the texture we receive from the TexturesGenerator thread.
            // To implement inverted rendering, we thus have to do the rendering
            // live, by using a different shader.
            type = hasRepeatScale ?  RepeatTexInv : Tex2DInv;
        }
    } else if (textureTarget == GL_TEXTURE_EXTERNAL_OES) {
        if (!TilesManager::instance()->invertedScreen())
            type = TexOES;
        else
            type = TexOESInv;
    }
    return type;
}

// This function transform a clip rect extracted from the current layer
// into a clip rect in InvView coordinates -- used by the clipping rects
FloatRect ShaderProgram::rectInInvViewCoord(const TransformationMatrix& drawMatrix, const IntSize& size)
{
    FloatRect srect(0, 0, size.width(), size.height());
    TransformationMatrix renderMatrix = m_contentToInvViewMatrix * drawMatrix;
    return renderMatrix.mapRect(srect);
}

// used by the partial screen invals
FloatRect ShaderProgram::rectInViewCoord(const TransformationMatrix& drawMatrix, const IntSize& size)
{
    FloatRect srect(0, 0, size.width(), size.height());
    TransformationMatrix renderMatrix = m_contentToViewMatrix * drawMatrix;
    return renderMatrix.mapRect(srect);
}

FloatRect ShaderProgram::rectInViewCoord(const FloatRect& rect)
{
    return m_contentToViewMatrix.mapRect(rect);
}

FloatRect ShaderProgram::rectInInvViewCoord(const FloatRect& rect)
{
    return m_contentToInvViewMatrix.mapRect(rect);
}

FloatRect ShaderProgram::convertInvViewCoordToContentCoord(const FloatRect& rect)
{
    return m_contentToInvViewMatrix.inverse().mapRect(rect);
}

FloatRect ShaderProgram::convertViewCoordToInvViewCoord(const FloatRect& rect)
{
    FloatRect visibleContentRect = m_contentToViewMatrix.inverse().mapRect(rect);
    return rectInInvViewCoord(visibleContentRect);
}

FloatRect ShaderProgram::convertInvViewCoordToViewCoord(const FloatRect& rect)
{
    FloatRect visibleContentRect = m_contentToInvViewMatrix.inverse().mapRect(rect);
    return rectInViewCoord(visibleContentRect);
}

// clip is in screen coordinates
void ShaderProgram::clip(const FloatRect& clip)
{
    if (clip == m_clipRect)
        return;

    ALOGV("--clipping rect %f %f, %f x %f",
          clip.x(), clip.y(), clip.width(), clip.height());

    // we should only call glScissor in this function, so that we can easily
    // track the current clipping rect.

    IntRect screenClip(clip.x(),
                       clip.y(),
                       clip.width(), clip.height());

    if (!m_invViewClip.isEmpty())
        screenClip.intersect(m_invViewClip);

    // The previous intersection calculation is using local screen coordinates.
    // Now we need to convert things from local screen coordinates to global
    // screen coordinates and pass to the GL functions.
    screenClip.setX(screenClip.x() + m_invScreenRect.x());
    screenClip.setY(screenClip.y() + m_invScreenRect.y());
    if (screenClip.x() < 0) {
        int w = screenClip.width();
        w += screenClip.x();
        screenClip.setX(0);
        screenClip.setWidth(w);
    }
    if (screenClip.y() < 0) {
        int h = screenClip.height();
        h += screenClip.y();
        screenClip.setY(0);
        screenClip.setHeight(h);
    }

    glScissor(screenClip.x(), screenClip.y(), screenClip.width(), screenClip.height());

    m_clipRect = clip;
}

IntRect ShaderProgram::clippedRectWithVisibleContentRect(const IntRect& rect, int margin)
{
    IntRect viewport(m_visibleContentRect.fLeft - margin, m_visibleContentRect.fTop - margin,
                     m_visibleContentRect.width() + margin,
                     m_visibleContentRect.height() + margin);
    viewport.intersect(rect);
    return viewport;
}

float ShaderProgram::zValue(const TransformationMatrix& drawMatrix, float w, float h)
{
    TransformationMatrix modifiedDrawMatrix = drawMatrix;
    modifiedDrawMatrix.scale3d(w, h, 1);
    TransformationMatrix renderMatrix =
        m_visibleContentRectProjectionMatrix * modifiedDrawMatrix;
    FloatPoint3D point(0.5, 0.5, 0.0);
    FloatPoint3D result = renderMatrix.mapPoint(point);
    return result.z();
}

void ShaderProgram::drawQuadInternal(ShaderType type, const GLfloat* matrix,
                                     int textureId, float opacity,
                                     GLenum textureTarget, GLenum filter,
                                     const Color& pureColor, const FloatRect& fillPortion,
                                     const FloatSize& repeatScale)
{
    if (m_cachedProgramType != type) {
        glUseProgram(m_handleArray[type].programHandle);
        glVertexAttribPointer(m_handleArray[type].positionHandle,
                              2, GL_FLOAT, GL_FALSE, 0, 0);
        m_cachedProgramType = type;
        m_cachedFillPortion = FloatRect();
        m_cachedOpacity = -1; // reset cache for variable shared by multiple programs
    }
    glUniformMatrix4fv(m_handleArray[type].projMtxHandle, 1, GL_FALSE, matrix);

    if (type != PureColor) {
        glBindTexture(textureTarget, textureId);
        glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, filter);
        glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, filter);

        if (m_cachedOpacity != opacity) {
            glUniform1f(m_handleArray[type].alphaHandle, opacity);
            m_cachedOpacity = opacity;
        }

        GLint contrastHandle = m_handleArray[type].contrastHandle;
        if (contrastHandle != -1)
            glUniform1f(contrastHandle, m_contrast);

        if (m_cachedFillPortion != fillPortion) {
            glUniform4f(m_handleArray[type].fillPortionHandle, fillPortion.x(), fillPortion.y(),
                        fillPortion.width(), fillPortion.height());
            m_cachedFillPortion = fillPortion;
        }

        // Only when we have repeat scale, this handle can be >= 0;
        if (m_handleArray[type].scaleHandle != -1) {
            glUniform2f(m_handleArray[type].scaleHandle,
                        repeatScale.width(), repeatScale.height());
        }
    } else {
        if (m_cachedPureColor != pureColor) {
            glUniform4f(m_handleArray[type].pureColorHandle,
                        pureColor.red() / 255.0, pureColor.green() / 255.0,
                        pureColor.blue() / 255.0, pureColor.alpha() / 255.0);
            m_cachedPureColor = pureColor;
        }
    }

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}

// Put the common matrix computation at higher level to avoid redundancy.
void ShaderProgram::setupSurfaceProjectionMatrix()
{
    TransformationMatrix scaleMatrix;
    scaleMatrix.scale3d(m_currentScale, m_currentScale, 1);
    m_surfaceProjectionMatrix = m_clipProjectionMatrix * m_webViewMatrix * scaleMatrix;
}

// Calculate the matrix given the geometry.
GLfloat* ShaderProgram::getTileProjectionMatrix(const DrawQuadData* data)
{
    DrawQuadType type = data->type();
    if (type == Blit)
        return m_transferProjMtx;

    const TransformationMatrix* matrix = data->drawMatrix();
    const SkRect* geometry = data->geometry();
    FloatRect fillPortion = data->fillPortion();
    ALOGV("fillPortion " FLOAT_RECT_FORMAT, FLOAT_RECT_ARGS(fillPortion));

    // This modifiedDrawMatrix tranform (0,0)(1x1) to the final rect in screen
    // coordinates, before applying the m_webViewMatrix.
    // It first scale and translate the vertex array from (0,0)(1x1) to real
    // tile position and size. Then apply the transform from the layer's.
    // Finally scale to the currentScale to support zooming.
    // Note the geometry contains the tile zoom scale, so visually we will see
    // the tiles scale at a ratio as (m_currentScale/tile's scale).
    TransformationMatrix modifiedDrawMatrix;
    if (type == LayerQuad)
        modifiedDrawMatrix = *matrix;
    modifiedDrawMatrix.translate(geometry->fLeft + geometry->width() * fillPortion.x(),
                                 geometry->fTop + geometry->height() * fillPortion.y());
    modifiedDrawMatrix.scale3d(geometry->width() * fillPortion.width(),
                               geometry->height() * fillPortion.height(), 1);

    // Even when we are on a alpha layer or not, we need to respect the
    // m_webViewMatrix, it may contain the layout offset. Normally it is
    // identity.
    TransformationMatrix renderMatrix;
    renderMatrix = m_surfaceProjectionMatrix * modifiedDrawMatrix;

#if DEBUG_MATRIX
    debugMatrixInfo(m_currentScale, m_clipProjectionMatrix, m_webViewMatrix,
                    modifiedDrawMatrix, matrix);
#endif

    GLUtils::toGLMatrix(m_tileProjMatrix, renderMatrix);
    return m_tileProjMatrix;
}

void ShaderProgram::drawQuad(const DrawQuadData* data)
{
    GLfloat* matrix = getTileProjectionMatrix(data);

    float opacity = data->opacity();
    bool forceBlending = data->forceBlending();
    bool enableBlending = forceBlending || opacity < 1.0;

    ShaderType shaderType = UndefinedShader;
    int textureId = 0;
    GLint textureFilter = 0;
    GLenum textureTarget = 0;

    Color quadColor = data->quadColor();
    if (data->pureColor()) {
        shaderType = PureColor;
        quadColor = shaderColor(quadColor, opacity);
        enableBlending = enableBlending || quadColor.hasAlpha();
        if (!quadColor.alpha() && enableBlending)
            return;
    } else {
        textureId = data->textureId();
        textureFilter = data->textureFilter();
        textureTarget = data->textureTarget();
        shaderType = getTextureShaderType(textureTarget, data->hasRepeatScale());
    }
    setBlendingState(enableBlending);
    drawQuadInternal(shaderType, matrix, textureId, opacity,
                     textureTarget, textureFilter, quadColor, data->fillPortion(),
                     data->repeatScale());
}

void ShaderProgram::drawVideoLayerQuad(const TransformationMatrix& drawMatrix,
                                       float* textureMatrix, SkRect& geometry,
                                       int textureId)
{
    // switch to our custom yuv video rendering program
    if (m_cachedProgramType != Video) {
        glUseProgram(m_handleArray[Video].programHandle);
        glVertexAttribPointer(m_handleArray[Video].positionHandle,
                              2, GL_FLOAT, GL_FALSE, 0, 0);
        m_cachedProgramType = Video;
    }

    // TODO: Merge drawVideoLayerQuad into drawQuad.
    TransformationMatrix modifiedDrawMatrix;
    modifiedDrawMatrix.scale3d(m_currentScale, m_currentScale, 1);
    modifiedDrawMatrix.multiply(drawMatrix);
    modifiedDrawMatrix.translate(geometry.fLeft, geometry.fTop);
    modifiedDrawMatrix.scale3d(geometry.width(), geometry.height(), 1);
    TransformationMatrix renderMatrix =
        m_clipProjectionMatrix * m_webViewMatrix * modifiedDrawMatrix;

    GLfloat projectionMatrix[16];
    GLUtils::toGLMatrix(projectionMatrix, renderMatrix);
    glUniformMatrix4fv(m_handleArray[Video].projMtxHandle, 1, GL_FALSE,
                       projectionMatrix);
    glUniformMatrix4fv(m_handleArray[Video].videoMtxHandle, 1, GL_FALSE,
                       textureMatrix);
    glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId);

    setBlendingState(false);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}

void ShaderProgram::setGLDrawInfo(const android::uirenderer::DrawGlInfo* info)
{
    GLUtils::convertToTransformationMatrix(info->transform, m_webViewMatrix);
    m_alphaLayer = info->isLayer;
    m_targetHeight = info->height;
}

// This function is called per tileGrid to minimize the computation overhead.
// The ortho projection and glViewport will map 1:1, so we don't need to
// worry about them here. Basically, if the current zoom scale / tile's scale
// plus the webview and layer transformation ends up at scale factor 1.0,
// then we can use point sampling.
bool ShaderProgram::usePointSampling(float tileScale,
                                     const TransformationMatrix* layerTransform)
{
    const float testSize = 1.0;
    FloatRect rect(0, 0, testSize, testSize);
    TransformationMatrix matrix;
    matrix.scale3d(m_currentScale, m_currentScale, 1);
    if (layerTransform)
        matrix.multiply(*layerTransform);
    matrix.scale3d(1.0 / tileScale, 1.0 / tileScale, 1);

    matrix = m_webViewMatrix * matrix;

    rect = matrix.mapRect(rect);

    float deltaWidth = abs(rect.width() - testSize);
    float deltaHeight = abs(rect.height() - testSize);

    if (deltaWidth < EPSILON && deltaHeight < EPSILON) {
        ALOGV("Point sampling : deltaWidth is %f, deltaHeight is %f", deltaWidth, deltaHeight);
        return true;
    }
    return false;
}

#if DEBUG_MATRIX
FloatRect ShaderProgram::debugMatrixTransform(const TransformationMatrix& matrix,
                                              const char* matrixName)
{
    FloatRect rect(0.0, 0.0, 1.0, 1.0);
    rect = matrix.mapRect(rect);
    ALOGV("After %s matrix:\n %f, %f rect.width() %f rect.height() %f",
          matrixName, rect.x(), rect.y(), rect.width(), rect.height());
    return rect;

}

void ShaderProgram::debugMatrixInfo(float currentScale,
                                    const TransformationMatrix& clipProjectionMatrix,
                                    const TransformationMatrix& webViewMatrix,
                                    const TransformationMatrix& modifiedDrawMatrix,
                                    const TransformationMatrix* layerMatrix)
{
    int viewport[4];
    glGetIntegerv(GL_VIEWPORT, viewport);
    ALOGV("viewport %d, %d, %d, %d , currentScale %f",
          viewport[0], viewport[1], viewport[2], viewport[3], currentScale);
    IntRect currentGLViewport(viewport[0], viewport[1], viewport[2], viewport[3]);

    TransformationMatrix scaleMatrix;
    scaleMatrix.scale3d(currentScale, currentScale, 1.0);

    if (layerMatrix)
        debugMatrixTransform(*layerMatrix, "layerMatrix");

    TransformationMatrix debugMatrix = scaleMatrix * modifiedDrawMatrix;
    debugMatrixTransform(debugMatrix, "scaleMatrix * modifiedDrawMatrix");

    debugMatrix = webViewMatrix * debugMatrix;
    debugMatrixTransform(debugMatrix, "webViewMatrix * scaleMatrix * modifiedDrawMatrix");

    debugMatrix = clipProjectionMatrix * debugMatrix;
    FloatRect finalRect =
        debugMatrixTransform(debugMatrix, "all Matrix");
    // After projection, we will be in a (-1, 1) range and now we can map it back
    // to the (x,y) -> (x+width, y+height)
    ALOGV("final convert to screen coord x, y %f, %f width %f height %f , ",
          (finalRect.x() + 1) / 2 * currentGLViewport.width() + currentGLViewport.x(),
          (finalRect.y() + 1) / 2 * currentGLViewport.height() + currentGLViewport.y(),
          finalRect.width() * currentGLViewport.width() / 2,
          finalRect.height() * currentGLViewport.height() / 2);
}
#endif // DEBUG_MATRIX

} // namespace WebCore
#endif // USE(ACCELERATED_COMPOSITING)
