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
19static const int PO_NUM_VERTICES = 6;
20
21static 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 };
28static 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
36static 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
45static 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
53PixelOutputRenderer::PixelOutputRenderer(ANativeWindow* window, bool offscreen) :
54        Renderer(window, offscreen), mWorkload(0) {
55}
56
57bool 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
82bool 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
99void 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