| /* | 
 |  * Copyright 2013 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. | 
 |  */ | 
 |  | 
 | #include "TextureRenderer.h" | 
 |  | 
 | #include "GLTest.h" | 
 |  | 
 | #include <gui/GLConsumer.h> | 
 |  | 
 | #include <GLES2/gl2.h> | 
 | #include <GLES2/gl2ext.h> | 
 |  | 
 | #include <gtest/gtest.h> | 
 |  | 
 | namespace android { | 
 |  | 
 | TextureRenderer::TextureRenderer(GLuint texName, | 
 |         const sp<GLConsumer>& st) : mTexName(texName), mST(st), mPgm(0), | 
 |         mPositionHandle(-1), mTexSamplerHandle(-1), mTexMatrixHandle(-1) { | 
 | } | 
 |  | 
 | void TextureRenderer::SetUp() { | 
 |     const char vsrc[] = | 
 |         "attribute vec4 vPosition;\n" | 
 |         "varying vec2 texCoords;\n" | 
 |         "uniform mat4 texMatrix;\n" | 
 |         "void main() {\n" | 
 |         "  vec2 vTexCoords = 0.5 * (vPosition.xy + vec2(1.0, 1.0));\n" | 
 |         "  texCoords = (texMatrix * vec4(vTexCoords, 0.0, 1.0)).xy;\n" | 
 |         "  gl_Position = vPosition;\n" | 
 |         "}\n"; | 
 |  | 
 |     const char fsrc[] = | 
 |         "#extension GL_OES_EGL_image_external : require\n" | 
 |         "precision mediump float;\n" | 
 |         "uniform samplerExternalOES texSampler;\n" | 
 |         "varying vec2 texCoords;\n" | 
 |         "void main() {\n" | 
 |         "  gl_FragColor = texture2D(texSampler, texCoords);\n" | 
 |         "}\n"; | 
 |  | 
 |     { | 
 |         SCOPED_TRACE("creating shader program"); | 
 |         ASSERT_NO_FATAL_FAILURE(GLTest::createProgram(vsrc, fsrc, &mPgm)); | 
 |     } | 
 |  | 
 |     mPositionHandle = glGetAttribLocation(mPgm, "vPosition"); | 
 |     ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); | 
 |     ASSERT_NE(-1, mPositionHandle); | 
 |     mTexSamplerHandle = glGetUniformLocation(mPgm, "texSampler"); | 
 |     ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); | 
 |     ASSERT_NE(-1, mTexSamplerHandle); | 
 |     mTexMatrixHandle = glGetUniformLocation(mPgm, "texMatrix"); | 
 |     ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); | 
 |     ASSERT_NE(-1, mTexMatrixHandle); | 
 | } | 
 |  | 
 | // drawTexture draws the GLConsumer over the entire GL viewport. | 
 | void TextureRenderer::drawTexture() { | 
 |     static const GLfloat triangleVertices[] = { | 
 |         -1.0f, 1.0f, | 
 |         -1.0f, -1.0f, | 
 |         1.0f, -1.0f, | 
 |         1.0f, 1.0f, | 
 |     }; | 
 |  | 
 |     glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, | 
 |             triangleVertices); | 
 |     ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); | 
 |     glEnableVertexAttribArray(mPositionHandle); | 
 |     ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); | 
 |  | 
 |     glUseProgram(mPgm); | 
 |     glUniform1i(mTexSamplerHandle, 0); | 
 |     ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); | 
 |     glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTexName); | 
 |     ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); | 
 |  | 
 |     // XXX: These calls are not needed for GL_TEXTURE_EXTERNAL_OES as | 
 |     // they're setting the defautls for that target, but when hacking | 
 |     // things to use GL_TEXTURE_2D they are needed to achieve the same | 
 |     // behavior. | 
 |     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, | 
 |             GL_LINEAR); | 
 |     ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); | 
 |     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, | 
 |             GL_LINEAR); | 
 |     ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); | 
 |     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, | 
 |             GL_CLAMP_TO_EDGE); | 
 |     ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); | 
 |     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, | 
 |             GL_CLAMP_TO_EDGE); | 
 |     ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); | 
 |  | 
 |     GLfloat texMatrix[16]; | 
 |     mST->getTransformMatrix(texMatrix); | 
 |     glUniformMatrix4fv(mTexMatrixHandle, 1, GL_FALSE, texMatrix); | 
 |  | 
 |     glDrawArrays(GL_TRIANGLE_FAN, 0, 4); | 
 |     ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); | 
 | } | 
 |  | 
 | } // namespace android |