|  | /* | 
|  | * 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 |