1274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen/*
2274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * Copyright (C) 2011 The Android Open Source Project
3274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen *
4274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * Licensed under the Apache License, Version 2.0 (the "License");
5274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * you may not use this file except in compliance with the License.
6274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * You may obtain a copy of the License at
7274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen *
8274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen *      http://www.apache.org/licenses/LICENSE-2.0
9274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen *
10274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * Unless required by applicable law or agreed to in writing, software
11274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * distributed under the License is distributed on an "AS IS" BASIS,
12274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * See the License for the specific language governing permissions and
14274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * limitations under the License.
15274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen */
16274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen
1741a2e9735136f372de95652d0828600282c8e967mbansal#include "SurfaceTextureRenderer.h"
1841a2e9735136f372de95652d0828600282c8e967mbansal
1941a2e9735136f372de95652d0828600282c8e967mbansal#include <GLES2/gl2ext.h>
2041a2e9735136f372de95652d0828600282c8e967mbansalconst GLfloat g_vVertices[] = {
2141a2e9735136f372de95652d0828600282c8e967mbansal    -1.f, -1.f, 0.0f, 1.0f,  // Position 0
22c73d5e20e80cf8b28017dff3b7672b8416a3a9f4Wei-Ta Chen    0.0f,  0.0f,         // TexCoord 0
2341a2e9735136f372de95652d0828600282c8e967mbansal     1.f, -1.f, 0.0f, 1.0f, // Position 1
24c73d5e20e80cf8b28017dff3b7672b8416a3a9f4Wei-Ta Chen    1.0f,  0.0f,         // TexCoord 1
2541a2e9735136f372de95652d0828600282c8e967mbansal    -1.f,  1.f, 0.0f, 1.0f, // Position 2
26c73d5e20e80cf8b28017dff3b7672b8416a3a9f4Wei-Ta Chen    0.0f,  1.0f,         // TexCoord 2
2741a2e9735136f372de95652d0828600282c8e967mbansal    1.f,   1.f, 0.0f, 1.0f, // Position 3
28c73d5e20e80cf8b28017dff3b7672b8416a3a9f4Wei-Ta Chen    1.0f,  1.0f          // TexCoord 3
2941a2e9735136f372de95652d0828600282c8e967mbansal};
3041a2e9735136f372de95652d0828600282c8e967mbansalGLushort g_iIndices2[] = { 0, 1, 2, 3 };
3141a2e9735136f372de95652d0828600282c8e967mbansal
3241a2e9735136f372de95652d0828600282c8e967mbansalconst int GL_TEXTURE_EXTERNAL_OES_ENUM = 0x8D65;
3341a2e9735136f372de95652d0828600282c8e967mbansal
3441a2e9735136f372de95652d0828600282c8e967mbansalconst int VERTEX_STRIDE = 6 * sizeof(GLfloat);
3541a2e9735136f372de95652d0828600282c8e967mbansal
361e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalSurfaceTextureRenderer::SurfaceTextureRenderer() : Renderer() {
3741a2e9735136f372de95652d0828600282c8e967mbansal    memset(mSTMatrix, 0.0, 16*sizeof(float));
3841a2e9735136f372de95652d0828600282c8e967mbansal    mSTMatrix[0] = 1.0f;
3941a2e9735136f372de95652d0828600282c8e967mbansal    mSTMatrix[5] = 1.0f;
4041a2e9735136f372de95652d0828600282c8e967mbansal    mSTMatrix[10] = 1.0f;
4141a2e9735136f372de95652d0828600282c8e967mbansal    mSTMatrix[15] = 1.0f;
4241a2e9735136f372de95652d0828600282c8e967mbansal}
4341a2e9735136f372de95652d0828600282c8e967mbansal
4441a2e9735136f372de95652d0828600282c8e967mbansalSurfaceTextureRenderer::~SurfaceTextureRenderer() {
4541a2e9735136f372de95652d0828600282c8e967mbansal}
4641a2e9735136f372de95652d0828600282c8e967mbansal
471e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalvoid SurfaceTextureRenderer::SetViewportMatrix(int w, int h, int W, int H)
4841a2e9735136f372de95652d0828600282c8e967mbansal{
491e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal    for(int i=0; i<16; i++)
501e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal    {
511e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal        mViewportMatrix[i] = 0.0f;
5241a2e9735136f372de95652d0828600282c8e967mbansal    }
531e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal
541e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal    mViewportMatrix[0] = float(w)/float(W);
551e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal    mViewportMatrix[5] = float(h)/float(H);
561e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal    mViewportMatrix[10] = 1.0f;
571e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal    mViewportMatrix[12] = -1.0f + float(w)/float(W);
581e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal    mViewportMatrix[13] = -1.0f + float(h)/float(H);
591e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal    mViewportMatrix[15] = 1.0f;
6041a2e9735136f372de95652d0828600282c8e967mbansal}
6141a2e9735136f372de95652d0828600282c8e967mbansal
621e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalvoid SurfaceTextureRenderer::SetScalingMatrix(float xscale, float yscale)
6341a2e9735136f372de95652d0828600282c8e967mbansal{
641e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal    for(int i=0; i<16; i++)
6541a2e9735136f372de95652d0828600282c8e967mbansal    {
661e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal        mScalingMatrix[i] = 0.0f;
6741a2e9735136f372de95652d0828600282c8e967mbansal    }
6841a2e9735136f372de95652d0828600282c8e967mbansal
691e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal    mScalingMatrix[0] = xscale;
701e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal    mScalingMatrix[5] = yscale;
711e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal    mScalingMatrix[10] = 1.0f;
721e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal    mScalingMatrix[15] = 1.0f;
731e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal}
7441a2e9735136f372de95652d0828600282c8e967mbansal
751e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalvoid SurfaceTextureRenderer::SetSTMatrix(float *stmat)
761e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal{
771e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal    memcpy(mSTMatrix, stmat, 16*sizeof(float));
7841a2e9735136f372de95652d0828600282c8e967mbansal}
7941a2e9735136f372de95652d0828600282c8e967mbansal
801e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal
8141a2e9735136f372de95652d0828600282c8e967mbansalbool SurfaceTextureRenderer::InitializeGLProgram()
8241a2e9735136f372de95652d0828600282c8e967mbansal{
8341a2e9735136f372de95652d0828600282c8e967mbansal    bool succeeded = false;
8441a2e9735136f372de95652d0828600282c8e967mbansal    do {
8541a2e9735136f372de95652d0828600282c8e967mbansal        GLuint glProgram;
8641a2e9735136f372de95652d0828600282c8e967mbansal        glProgram = createProgram(VertexShaderSource(),
8741a2e9735136f372de95652d0828600282c8e967mbansal                FragmentShaderSource());
8841a2e9735136f372de95652d0828600282c8e967mbansal        if (!glProgram) {
8941a2e9735136f372de95652d0828600282c8e967mbansal            break;
9041a2e9735136f372de95652d0828600282c8e967mbansal        }
9141a2e9735136f372de95652d0828600282c8e967mbansal
9241a2e9735136f372de95652d0828600282c8e967mbansal        glUseProgram(glProgram);
9341a2e9735136f372de95652d0828600282c8e967mbansal        if (!checkGlError("glUseProgram")) break;
9441a2e9735136f372de95652d0828600282c8e967mbansal
9541a2e9735136f372de95652d0828600282c8e967mbansal        maPositionHandle = glGetAttribLocation(glProgram, "aPosition");
9641a2e9735136f372de95652d0828600282c8e967mbansal        checkGlError("glGetAttribLocation aPosition");
9741a2e9735136f372de95652d0828600282c8e967mbansal        maTextureHandle = glGetAttribLocation(glProgram, "aTextureCoord");
9841a2e9735136f372de95652d0828600282c8e967mbansal        checkGlError("glGetAttribLocation aTextureCoord");
9941a2e9735136f372de95652d0828600282c8e967mbansal        muSTMatrixHandle = glGetUniformLocation(glProgram, "uSTMatrix");
10041a2e9735136f372de95652d0828600282c8e967mbansal        checkGlError("glGetUniformLocation uSTMatrix");
10141a2e9735136f372de95652d0828600282c8e967mbansal        mScalingtransLoc = glGetUniformLocation(glProgram, "u_scalingtrans");
10241a2e9735136f372de95652d0828600282c8e967mbansal
10341a2e9735136f372de95652d0828600282c8e967mbansal        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
10441a2e9735136f372de95652d0828600282c8e967mbansal        mGlProgram = glProgram;
10541a2e9735136f372de95652d0828600282c8e967mbansal        succeeded = true;
10641a2e9735136f372de95652d0828600282c8e967mbansal    } while (false);
10741a2e9735136f372de95652d0828600282c8e967mbansal
10841a2e9735136f372de95652d0828600282c8e967mbansal    if (!succeeded && (mGlProgram != 0))
10941a2e9735136f372de95652d0828600282c8e967mbansal    {
11041a2e9735136f372de95652d0828600282c8e967mbansal        glDeleteProgram(mGlProgram);
11141a2e9735136f372de95652d0828600282c8e967mbansal        checkGlError("glDeleteProgram");
11241a2e9735136f372de95652d0828600282c8e967mbansal        mGlProgram = 0;
11341a2e9735136f372de95652d0828600282c8e967mbansal    }
11441a2e9735136f372de95652d0828600282c8e967mbansal    return succeeded;
11541a2e9735136f372de95652d0828600282c8e967mbansal}
11641a2e9735136f372de95652d0828600282c8e967mbansal
11741a2e9735136f372de95652d0828600282c8e967mbansalbool SurfaceTextureRenderer::DrawTexture(GLfloat *affine)
11841a2e9735136f372de95652d0828600282c8e967mbansal{
11941a2e9735136f372de95652d0828600282c8e967mbansal    bool succeeded = false;
12041a2e9735136f372de95652d0828600282c8e967mbansal    do {
12141a2e9735136f372de95652d0828600282c8e967mbansal        bool rt = (mFrameBuffer == NULL)?
12241a2e9735136f372de95652d0828600282c8e967mbansal            SetupGraphics(mSurfaceWidth, mSurfaceHeight) :
12341a2e9735136f372de95652d0828600282c8e967mbansal            SetupGraphics(mFrameBuffer);
12441a2e9735136f372de95652d0828600282c8e967mbansal
12541a2e9735136f372de95652d0828600282c8e967mbansal        if(!rt)
12641a2e9735136f372de95652d0828600282c8e967mbansal            break;
12741a2e9735136f372de95652d0828600282c8e967mbansal
12841a2e9735136f372de95652d0828600282c8e967mbansal        glDisable(GL_BLEND);
12941a2e9735136f372de95652d0828600282c8e967mbansal
13041a2e9735136f372de95652d0828600282c8e967mbansal        glActiveTexture(GL_TEXTURE0);
13141a2e9735136f372de95652d0828600282c8e967mbansal        if (!checkGlError("glActiveTexture")) break;
13241a2e9735136f372de95652d0828600282c8e967mbansal
13341a2e9735136f372de95652d0828600282c8e967mbansal        const GLenum texture_type = InputTextureType();
13441a2e9735136f372de95652d0828600282c8e967mbansal        glBindTexture(texture_type, mInputTextureName);
13541a2e9735136f372de95652d0828600282c8e967mbansal        if (!checkGlError("glBindTexture")) break;
13641a2e9735136f372de95652d0828600282c8e967mbansal
13741a2e9735136f372de95652d0828600282c8e967mbansal        glUniformMatrix4fv(mScalingtransLoc, 1, GL_FALSE, mScalingMatrix);
138c73d5e20e80cf8b28017dff3b7672b8416a3a9f4Wei-Ta Chen        glUniformMatrix4fv(muSTMatrixHandle, 1, GL_FALSE, mSTMatrix);
13941a2e9735136f372de95652d0828600282c8e967mbansal
14041a2e9735136f372de95652d0828600282c8e967mbansal        // Load the vertex position
14141a2e9735136f372de95652d0828600282c8e967mbansal        glVertexAttribPointer(maPositionHandle, 4, GL_FLOAT,
14241a2e9735136f372de95652d0828600282c8e967mbansal                GL_FALSE, VERTEX_STRIDE, g_vVertices);
14341a2e9735136f372de95652d0828600282c8e967mbansal        glEnableVertexAttribArray(maPositionHandle);
14441a2e9735136f372de95652d0828600282c8e967mbansal        // Load the texture coordinate
14541a2e9735136f372de95652d0828600282c8e967mbansal        glVertexAttribPointer(maTextureHandle, 2, GL_FLOAT,
14641a2e9735136f372de95652d0828600282c8e967mbansal                GL_FALSE, VERTEX_STRIDE, &g_vVertices[4]);
14741a2e9735136f372de95652d0828600282c8e967mbansal        glEnableVertexAttribArray(maTextureHandle);
14841a2e9735136f372de95652d0828600282c8e967mbansal
14941a2e9735136f372de95652d0828600282c8e967mbansal        // And, finally, execute the GL draw command.
15041a2e9735136f372de95652d0828600282c8e967mbansal        glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, g_iIndices2);
15141a2e9735136f372de95652d0828600282c8e967mbansal
15241a2e9735136f372de95652d0828600282c8e967mbansal        glBindFramebuffer(GL_FRAMEBUFFER, 0);
15341a2e9735136f372de95652d0828600282c8e967mbansal        succeeded = true;
15441a2e9735136f372de95652d0828600282c8e967mbansal    } while (false);
15541a2e9735136f372de95652d0828600282c8e967mbansal    return succeeded;
15641a2e9735136f372de95652d0828600282c8e967mbansal}
15741a2e9735136f372de95652d0828600282c8e967mbansal
15841a2e9735136f372de95652d0828600282c8e967mbansalconst char* SurfaceTextureRenderer::VertexShaderSource() const
15941a2e9735136f372de95652d0828600282c8e967mbansal{
1601e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal    static const char gVertexShader[] =
1611e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal        "uniform mat4 uSTMatrix;\n"
1621e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal        "uniform mat4 u_scalingtrans;  \n"
1631e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal        "attribute vec4 aPosition;\n"
1641e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal        "attribute vec4 aTextureCoord;\n"
1651e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal        "varying vec2 vTextureNormCoord;\n"
1661e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal        "void main() {\n"
1671e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal        "  gl_Position = u_scalingtrans * aPosition;\n"
168c73d5e20e80cf8b28017dff3b7672b8416a3a9f4Wei-Ta Chen        "  vTextureNormCoord = (uSTMatrix * aTextureCoord).xy;\n"
1691e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal        "}\n";
1701e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal
17141a2e9735136f372de95652d0828600282c8e967mbansal    return gVertexShader;
17241a2e9735136f372de95652d0828600282c8e967mbansal}
17341a2e9735136f372de95652d0828600282c8e967mbansal
17441a2e9735136f372de95652d0828600282c8e967mbansalconst char* SurfaceTextureRenderer::FragmentShaderSource() const
17541a2e9735136f372de95652d0828600282c8e967mbansal{
1761e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal    static const char gFragmentShader[] =
1771e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal        "#extension GL_OES_EGL_image_external : require\n"
1781e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal        "precision mediump float;\n"
1791e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal        "varying vec2 vTextureNormCoord;\n"
1801e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal        "uniform samplerExternalOES sTexture;\n"
1811e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal        "void main() {\n"
1821e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal        "  gl_FragColor = texture2D(sTexture, vTextureNormCoord);\n"
1831e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal        "}\n";
1841e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal
18541a2e9735136f372de95652d0828600282c8e967mbansal    return gFragmentShader;
18641a2e9735136f372de95652d0828600282c8e967mbansal}
187