/*
 * Copyright (C) 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 "ShaderPerfRenderer.h"
#include <graphics/GLUtils.h>

#include <math.h>

#include <Trace.h>

static const float GOLDEN_RATIO = (1.0f + sqrt(5.0f)) / 2.0f;

static const int SP_NUM_VERTICES = 6;

static const float SP_VERTICES[SP_NUM_VERTICES * 3] = {
        1.0f, 1.0f, -1.0f,
        -1.0f, 1.0f, -1.0f,
        -1.0f, -1.0f, -1.0f,
        -1.0f, -1.0f, -1.0f,
        1.0f, -1.0f, -1.0f,
        1.0f, 1.0f, -1.0f };

static const float SP_TEX_COORDS[SP_NUM_VERTICES * 2] = {
        1.0f, 1.0f,
        0.0f, 1.0f,
        0.0f, 0.0f,
        0.0f, 0.0f,
        1.0f, 0.0f,
        1.0f, 1.0f };

static const char* SP_VERTEX =
        "attribute vec4 a_Position;"
        "attribute vec2 a_TexCoord;"
        "varying vec2 v_TexCoord;"
        "void main() {"
        "  v_TexCoord = a_TexCoord;"
        "  gl_Position = a_Position;"
        "}";

static const char* SP_FRAGMENT_1 =
        "precision mediump float;"
        "uniform vec2 u_Seed;"
        "uniform sampler2D u_Texture;"
        "varying vec2 v_TexCoord;"
        "void main() {"
        "  int count = ";

//Add workload here

static const char* SP_FRAGMENT_2 =
        " * 4;"//workload * 4 (4 is a tweaking number, bigger = more work)
        "  vec2 z;"
        "  z.x = 3.0 * (v_TexCoord.x - 0.5);"
        "  z.y = 2.0 * (v_TexCoord.y - 0.5);"
        "  float u = 0.0;"
        "  for (int i = 0; i < count; i++) {"
        "    float x = (z.x * z.x - z.y * z.y) + u_Seed.x;"
        "    float y = (z.y * z.x + z.x * z.y) + u_Seed.y;"
        "    if (((x * x + y * y) > 4.0) && (u == 0.0)) {"
        "      u = float(i) / float(count);"
        "    }"
        "    z.x = x;"
        "    z.y = y;"
        "  }"
        "  gl_FragColor = texture2D(u_Texture, vec2(u, 0.0));"
        "}";

// Copies the source array from 0 up to and including the '\0' character to the
// destination array starting from the given start position. Unlike strcpy, this
// returns the number of characters which were copied.
static int charCopy(const char* source, char* dest, int destStart) {
    int srcAddr = 0;
    int destAddr = destStart;
    char current;
    do {
        current = source[srcAddr];
        dest[destAddr] = current;
        srcAddr++;
        destAddr++;
    } while (current != '\0');
    return destAddr - destStart;
}

ShaderPerfRenderer::ShaderPerfRenderer(ANativeWindow* window, bool offscreen) :
        Renderer(window, offscreen) {
}

bool ShaderPerfRenderer::setUp(int workload) {
    SCOPED_TRACE();
    if (!Renderer::setUp(workload)) {
        return false;
    }

    const int MAX_FRAGMENT_SHADER_SIZE = 1000;
    char* spFragment = new char[MAX_FRAGMENT_SHADER_SIZE];
    // Add the first part.
    int index = charCopy(SP_FRAGMENT_1, spFragment, 0);
    // Add the count, overwriting the '\0' added by charCopy.
    spFragment[index - 1] = (char) (((int) '0') + workload);
    // Add the second part.
    index += charCopy(SP_FRAGMENT_2, spFragment, index);
    // Create program.
    mProgramId = GLUtils::createProgram(&SP_VERTEX, const_cast<const char**>(&spFragment));
    delete[] spFragment;
    if (mProgramId == 0) {
        return false;
    }
    // Bind attributes.
    mTextureUniformHandle = glGetUniformLocation(mProgramId, "u_Texture");
    mSeedUniformHandle = glGetUniformLocation(mProgramId, "u_Seed");
    mPositionHandle = glGetAttribLocation(mProgramId, "a_Position");
    mTexCoordHandle = glGetAttribLocation(mProgramId, "a_TexCoord");

    const int SIZE = 256;
    uint32_t* m = new uint32_t[SIZE];
    if (m != NULL) {
        uint32_t* d = m;
        for (int i = 0; i < SIZE; i++) {
            *d = 0xff000000 | ((i & 0xff) << 16);
            d++;
        }
        glGenTextures(1, &mTextureId);
        glBindTexture(GL_TEXTURE_2D, mTextureId);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SIZE, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, m);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    }
    delete[] m;

    return true;
}

void ShaderPerfRenderer::drawWorkload() {
    SCOPED_TRACE();
    glUseProgram(mProgramId);
    // Set the background clear color.
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

    // No culling of back faces
    glDisable(GL_CULL_FACE);

    // Bind the texture.
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, mTextureId);
    glUniform1i(mTextureUniformHandle, 0);

    // Bind the seed.
    glUniform2f(mSeedUniformHandle, GOLDEN_RATIO - 2.0f, GOLDEN_RATIO - 1.0f);

    // Bind the vertices.
    glEnableVertexAttribArray(mPositionHandle);
    glEnableVertexAttribArray(mTexCoordHandle);
    glVertexAttribPointer(mPositionHandle, 3, GL_FLOAT, false, 0, SP_VERTICES);
    glVertexAttribPointer(mTexCoordHandle, 2, GL_FLOAT, false, 0, SP_TEX_COORDS);

    glDrawArrays(GL_TRIANGLES, 0, SP_NUM_VERTICES);
}
