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
27RenderDirectView::RenderDirectView(sp<IEvsEnumerator> enumerator,
28                                   const ConfigManager::CameraInfo& cam) {
29    mEnumerator = enumerator;
30    mCameraInfo = cam;
31}
32
33
34bool 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
65void 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:  If start/stop costs become a problem, we could share video textures
69    mTexture = nullptr;
70}
71
72
73bool RenderDirectView::drawFrame(const BufferDesc& tgtBuffer) {
74    // Tell GL to render to the given buffer
75    if (!attachRenderTarget(tgtBuffer)) {
76        ALOGE("Failed to attached render target");
77        return false;
78    }
79
80    // Select our screen space simple texture shader
81    glUseProgram(mShaderProgram);
82
83    // Set up the model to clip space transform (identity matrix if we're modeling in screen space)
84    GLint loc = glGetUniformLocation(mShaderProgram, "cameraMat");
85    if (loc < 0) {
86        ALOGE("Couldn't set shader parameter 'cameraMat'");
87        return false;
88    } else {
89        const android::mat4 identityMatrix;
90        glUniformMatrix4fv(loc, 1, false, identityMatrix.asArray());
91    }
92
93
94    // Bind the texture and assign it to the shader's sampler
95    mTexture->refresh();
96    glActiveTexture(GL_TEXTURE0);
97    glBindTexture(GL_TEXTURE_2D, mTexture->glId());
98
99
100    GLint sampler = glGetUniformLocation(mShaderProgram, "tex");
101    if (sampler < 0) {
102        ALOGE("Couldn't set shader parameter 'tex'");
103        return false;
104    } else {
105        // Tell the sampler we looked up from the shader to use texture slot 0 as its source
106        glUniform1i(sampler, 0);
107    }
108
109    // We want our image to show up opaque regardless of alpha values
110    glDisable(GL_BLEND);
111
112
113    // Draw a rectangle on the screen
114    GLfloat vertsCarPos[] = { -1.0,  1.0, 0.0f,   // left top in window space
115                               1.0,  1.0, 0.0f,   // right top
116                              -1.0, -1.0, 0.0f,   // left bottom
117                               1.0, -1.0, 0.0f    // right bottom
118    };
119    // TODO:  We're flipping horizontally here, but should do it only for specified cameras!
120    GLfloat vertsCarTex[] = { 1.0f, 1.0f,   // left top
121                              0.0f, 1.0f,   // right top
122                              1.0f, 0.0f,   // left bottom
123                              0.0f, 0.0f    // right bottom
124    };
125    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertsCarPos);
126    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, vertsCarTex);
127    glEnableVertexAttribArray(0);
128    glEnableVertexAttribArray(1);
129
130    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
131
132    glDisableVertexAttribArray(0);
133    glDisableVertexAttribArray(1);
134
135
136    // Wait for the rendering to finish
137    glFinish();
138
139    return true;
140}
141