1/*
2 * Copyright (C) 2011 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#include "SurfaceTextureRenderer.h"
18
19#include <GLES2/gl2ext.h>
20const GLfloat g_vVertices[] = {
21    -1.f, -1.f, 0.0f, 1.0f,  // Position 0
22    0.0f,  0.0f,         // TexCoord 0
23     1.f, -1.f, 0.0f, 1.0f, // Position 1
24    1.0f,  0.0f,         // TexCoord 1
25    -1.f,  1.f, 0.0f, 1.0f, // Position 2
26    0.0f,  1.0f,         // TexCoord 2
27    1.f,   1.f, 0.0f, 1.0f, // Position 3
28    1.0f,  1.0f          // TexCoord 3
29};
30GLushort g_iIndices2[] = { 0, 1, 2, 3 };
31
32const int GL_TEXTURE_EXTERNAL_OES_ENUM = 0x8D65;
33
34const int VERTEX_STRIDE = 6 * sizeof(GLfloat);
35
36SurfaceTextureRenderer::SurfaceTextureRenderer() : Renderer() {
37    memset(mSTMatrix, 0.0, 16*sizeof(float));
38    mSTMatrix[0] = 1.0f;
39    mSTMatrix[5] = 1.0f;
40    mSTMatrix[10] = 1.0f;
41    mSTMatrix[15] = 1.0f;
42}
43
44SurfaceTextureRenderer::~SurfaceTextureRenderer() {
45}
46
47void SurfaceTextureRenderer::SetViewportMatrix(int w, int h, int W, int H)
48{
49    for(int i=0; i<16; i++)
50    {
51        mViewportMatrix[i] = 0.0f;
52    }
53
54    mViewportMatrix[0] = float(w)/float(W);
55    mViewportMatrix[5] = float(h)/float(H);
56    mViewportMatrix[10] = 1.0f;
57    mViewportMatrix[12] = -1.0f + float(w)/float(W);
58    mViewportMatrix[13] = -1.0f + float(h)/float(H);
59    mViewportMatrix[15] = 1.0f;
60}
61
62void SurfaceTextureRenderer::SetScalingMatrix(float xscale, float yscale)
63{
64    for(int i=0; i<16; i++)
65    {
66        mScalingMatrix[i] = 0.0f;
67    }
68
69    mScalingMatrix[0] = xscale;
70    mScalingMatrix[5] = yscale;
71    mScalingMatrix[10] = 1.0f;
72    mScalingMatrix[15] = 1.0f;
73}
74
75void SurfaceTextureRenderer::SetSTMatrix(float *stmat)
76{
77    memcpy(mSTMatrix, stmat, 16*sizeof(float));
78}
79
80
81bool SurfaceTextureRenderer::InitializeGLProgram()
82{
83    bool succeeded = false;
84    do {
85        GLuint glProgram;
86        glProgram = createProgram(VertexShaderSource(),
87                FragmentShaderSource());
88        if (!glProgram) {
89            break;
90        }
91
92        glUseProgram(glProgram);
93        if (!checkGlError("glUseProgram")) break;
94
95        maPositionHandle = glGetAttribLocation(glProgram, "aPosition");
96        checkGlError("glGetAttribLocation aPosition");
97        maTextureHandle = glGetAttribLocation(glProgram, "aTextureCoord");
98        checkGlError("glGetAttribLocation aTextureCoord");
99        muSTMatrixHandle = glGetUniformLocation(glProgram, "uSTMatrix");
100        checkGlError("glGetUniformLocation uSTMatrix");
101        mScalingtransLoc = glGetUniformLocation(glProgram, "u_scalingtrans");
102
103        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
104        mGlProgram = glProgram;
105        succeeded = true;
106    } while (false);
107
108    if (!succeeded && (mGlProgram != 0))
109    {
110        glDeleteProgram(mGlProgram);
111        checkGlError("glDeleteProgram");
112        mGlProgram = 0;
113    }
114    return succeeded;
115}
116
117bool SurfaceTextureRenderer::DrawTexture(GLfloat *affine)
118{
119    bool succeeded = false;
120    do {
121        bool rt = (mFrameBuffer == NULL)?
122            SetupGraphics(mSurfaceWidth, mSurfaceHeight) :
123            SetupGraphics(mFrameBuffer);
124
125        if(!rt)
126            break;
127
128        glDisable(GL_BLEND);
129
130        glActiveTexture(GL_TEXTURE0);
131        if (!checkGlError("glActiveTexture")) break;
132
133        const GLenum texture_type = InputTextureType();
134        glBindTexture(texture_type, mInputTextureName);
135        if (!checkGlError("glBindTexture")) break;
136
137        glUniformMatrix4fv(mScalingtransLoc, 1, GL_FALSE, mScalingMatrix);
138        glUniformMatrix4fv(muSTMatrixHandle, 1, GL_FALSE, mSTMatrix);
139
140        // Load the vertex position
141        glVertexAttribPointer(maPositionHandle, 4, GL_FLOAT,
142                GL_FALSE, VERTEX_STRIDE, g_vVertices);
143        glEnableVertexAttribArray(maPositionHandle);
144        // Load the texture coordinate
145        glVertexAttribPointer(maTextureHandle, 2, GL_FLOAT,
146                GL_FALSE, VERTEX_STRIDE, &g_vVertices[4]);
147        glEnableVertexAttribArray(maTextureHandle);
148
149        // And, finally, execute the GL draw command.
150        glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, g_iIndices2);
151
152        glBindFramebuffer(GL_FRAMEBUFFER, 0);
153        succeeded = true;
154    } while (false);
155    return succeeded;
156}
157
158const char* SurfaceTextureRenderer::VertexShaderSource() const
159{
160    static const char gVertexShader[] =
161        "uniform mat4 uSTMatrix;\n"
162        "uniform mat4 u_scalingtrans;  \n"
163        "attribute vec4 aPosition;\n"
164        "attribute vec4 aTextureCoord;\n"
165        "varying vec2 vTextureNormCoord;\n"
166        "void main() {\n"
167        "  gl_Position = u_scalingtrans * aPosition;\n"
168        "  vTextureNormCoord = (uSTMatrix * aTextureCoord).xy;\n"
169        "}\n";
170
171    return gVertexShader;
172}
173
174const char* SurfaceTextureRenderer::FragmentShaderSource() const
175{
176    static const char gFragmentShader[] =
177        "#extension GL_OES_EGL_image_external : require\n"
178        "precision mediump float;\n"
179        "varying vec2 vTextureNormCoord;\n"
180        "uniform samplerExternalOES sTexture;\n"
181        "void main() {\n"
182        "  gl_FragColor = texture2D(sTexture, vTextureNormCoord);\n"
183        "}\n";
184
185    return gFragmentShader;
186}
187