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