1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5  * in compliance with the License. You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the License
10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11  * or implied. See the License for the specific language governing permissions and limitations under
12  * the License.
13  */
14 #include "PixelOutputRenderer.h"
15 #include <graphics/GLUtils.h>
16 
17 #include <Trace.h>
18 
19 static const int PO_NUM_VERTICES = 6;
20 
21 static const float PO_VERTICES[PO_NUM_VERTICES * 3] = {
22         1.0f, 1.0f, -1.0f,
23         -1.0f, 1.0f, -1.0f,
24         -1.0f, -1.0f, -1.0f,
25         -1.0f, -1.0f, -1.0f,
26         1.0f, -1.0f, -1.0f,
27         1.0f, 1.0f, -1.0f };
28 static const float PO_TEX_COORDS[PO_NUM_VERTICES * 2] = {
29         1.0f, 1.0f,
30         0.0f, 1.0f,
31         0.0f, 0.0f,
32         0.0f, 0.0f,
33         1.0f, 0.0f,
34         1.0f, 1.0f };
35 
36 static const char* PO_VERTEX =
37         "attribute vec4 a_Position;"
38         "attribute vec2 a_TexCoord;"
39         "varying vec2 v_TexCoord;"
40         "void main() {"
41         "  v_TexCoord = a_TexCoord;"
42         "  gl_Position = a_Position;"
43         "}";
44 
45 static const char* PO_FRAGMENT =
46         "precision mediump float;"
47         "uniform sampler2D u_Texture;"
48         "varying vec2 v_TexCoord;"
49         "void main() {"
50         "  gl_FragColor = texture2D(u_Texture, v_TexCoord);"
51         "}";
52 
PixelOutputRenderer(ANativeWindow * window,bool offscreen)53 PixelOutputRenderer::PixelOutputRenderer(ANativeWindow* window, bool offscreen) :
54         Renderer(window, offscreen), mWorkload(0) {
55 }
56 
setUp(int workload)57 bool PixelOutputRenderer::setUp(int workload) {
58     SCOPED_TRACE();
59     mWorkload = workload;
60     if (!Renderer::setUp(workload)) {
61         return false;
62     }
63 
64     // Create program.
65     mProgramId = GLUtils::createProgram(&PO_VERTEX, &PO_FRAGMENT);
66     if (mProgramId == 0) {
67         return false;
68     }
69     // Bind attributes.
70     mTextureUniformHandle = glGetUniformLocation(mProgramId, "u_Texture");
71     mPositionHandle = glGetAttribLocation(mProgramId, "a_Position");
72     mTexCoordHandle = glGetAttribLocation(mProgramId, "a_TexCoord");
73 
74     // Setup texture.
75     mTextureId = GLUtils::genTexture(mWidth, mHeight, GLUtils::RANDOM_FILL);
76     if (mTextureId == 0) {
77         return false;
78     }
79     return true;
80 }
81 
tearDown()82 bool PixelOutputRenderer::tearDown() {
83     SCOPED_TRACE();
84     if (mProgramId != 0)
85     {
86         glDeleteProgram(mProgramId);
87         mProgramId = 0;
88     }
89     if (mTextureId != 0) {
90         glDeleteTextures(1, &mTextureId);
91         mTextureId = 0;
92     }
93     if (!Renderer::tearDown()) {
94         return false;
95     }
96     return true;
97 }
98 
drawWorkload()99 void PixelOutputRenderer::drawWorkload() {
100     SCOPED_TRACE();
101     glUseProgram(mProgramId);
102     // Set the background clear color to black.
103     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
104     glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
105 
106     // No culling of back faces
107     glDisable(GL_CULL_FACE);
108 
109     // No depth testing
110     glDisable(GL_DEPTH_TEST);
111 
112     // Enable blending
113     glEnable(GL_BLEND);
114     glBlendFunc(GL_ONE, GL_ONE);
115 
116     glActiveTexture(GL_TEXTURE0);
117     // Bind the texture to this unit.
118     glBindTexture(GL_TEXTURE_2D, mTextureId);
119     // Tell the texture uniform sampler to use this texture in the shader by binding to texture
120     // unit 0.
121     glUniform1i(mTextureUniformHandle, 0);
122 
123     glEnableVertexAttribArray(mPositionHandle);
124     glEnableVertexAttribArray(mTexCoordHandle);
125     glVertexAttribPointer(mPositionHandle, 3, GL_FLOAT, false, 0, PO_VERTICES);
126     glVertexAttribPointer(mTexCoordHandle, 2, GL_FLOAT, false, 0, PO_TEX_COORDS);
127 
128     for (int i = 0; i < mWorkload; i++) {
129         glDrawArrays(GL_TRIANGLES, 0, PO_NUM_VERTICES);
130     }
131 }
132