1 /*
2  * Copyright (C) 2017 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 "RenderDirectView.h"
18 #include "VideoTex.h"
19 #include "glError.h"
20 #include "shader.h"
21 #include "shader_simpleTex.h"
22 
23 #include <log/log.h>
24 #include <math/mat4.h>
25 
26 
RenderDirectView(sp<IEvsEnumerator> enumerator,const ConfigManager::CameraInfo & cam)27 RenderDirectView::RenderDirectView(sp<IEvsEnumerator> enumerator,
28                                    const ConfigManager::CameraInfo& cam) {
29     mEnumerator = enumerator;
30     mCameraInfo = cam;
31 }
32 
33 
activate()34 bool RenderDirectView::activate() {
35     // Ensure GL is ready to go...
36     if (!prepareGL()) {
37         ALOGE("Error initializing GL");
38         return false;
39     }
40 
41     // Load our shader program if we don't have it already
42     if (!mShaderProgram) {
43         mShaderProgram = buildShaderProgram(vtxShader_simpleTexture,
44                                             pixShader_simpleTexture,
45                                             "simpleTexture");
46         if (!mShaderProgram) {
47             ALOGE("Error buliding shader program");
48             return false;
49         }
50     }
51 
52     // Construct our video texture
53     mTexture.reset(createVideoTexture(mEnumerator, mCameraInfo.cameraId.c_str(), sDisplay));
54     if (!mTexture) {
55         ALOGE("Failed to set up video texture for %s (%s)",
56               mCameraInfo.cameraId.c_str(), mCameraInfo.function.c_str());
57 // TODO:  For production use, we may actually want to fail in this case, but not yet...
58 //       return false;
59     }
60 
61     return true;
62 }
63 
64 
deactivate()65 void RenderDirectView::deactivate() {
66     // Release our video texture
67     // We can't hold onto it because some other Render object might need the same camera
68     // TODO(b/131492626):  investigate whether sharing video textures can save
69     // the time.
70   mTexture = nullptr;
71 }
72 
73 
drawFrame(const BufferDesc & tgtBuffer)74 bool RenderDirectView::drawFrame(const BufferDesc& tgtBuffer) {
75     // Tell GL to render to the given buffer
76     if (!attachRenderTarget(tgtBuffer)) {
77         ALOGE("Failed to attached render target");
78         return false;
79     }
80 
81     // Select our screen space simple texture shader
82     glUseProgram(mShaderProgram);
83 
84     // Set up the model to clip space transform (identity matrix if we're modeling in screen space)
85     GLint loc = glGetUniformLocation(mShaderProgram, "cameraMat");
86     if (loc < 0) {
87         ALOGE("Couldn't set shader parameter 'cameraMat'");
88         return false;
89     } else {
90         const android::mat4 identityMatrix;
91         glUniformMatrix4fv(loc, 1, false, identityMatrix.asArray());
92     }
93 
94 
95     // Bind the texture and assign it to the shader's sampler
96     mTexture->refresh();
97     glActiveTexture(GL_TEXTURE0);
98     glBindTexture(GL_TEXTURE_2D, mTexture->glId());
99 
100 
101     GLint sampler = glGetUniformLocation(mShaderProgram, "tex");
102     if (sampler < 0) {
103         ALOGE("Couldn't set shader parameter 'tex'");
104         return false;
105     } else {
106         // Tell the sampler we looked up from the shader to use texture slot 0 as its source
107         glUniform1i(sampler, 0);
108     }
109 
110     // We want our image to show up opaque regardless of alpha values
111     glDisable(GL_BLEND);
112 
113 
114     // Draw a rectangle on the screen
115     GLfloat vertsCarPos[] = { -1.0,  1.0, 0.0f,   // left top in window space
116                                1.0,  1.0, 0.0f,   // right top
117                               -1.0, -1.0, 0.0f,   // left bottom
118                                1.0, -1.0, 0.0f    // right bottom
119     };
120     // TODO:  We're flipping horizontally here, but should do it only for specified cameras!
121     GLfloat vertsCarTex[] = { 1.0f, 1.0f,   // left top
122                               0.0f, 1.0f,   // right top
123                               1.0f, 0.0f,   // left bottom
124                               0.0f, 0.0f    // right bottom
125     };
126     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertsCarPos);
127     glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, vertsCarTex);
128     glEnableVertexAttribArray(0);
129     glEnableVertexAttribArray(1);
130 
131     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
132 
133     glDisableVertexAttribArray(0);
134     glDisableVertexAttribArray(1);
135 
136 
137     // Now that everything is submitted, release our hold on the texture resource
138     detachRenderTarget();
139 
140     // Wait for the rendering to finish
141     glFinish();
142     detachRenderTarget();
143     return true;
144 }
145