/*
* Copyright (C) 2015 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 "TextureResize.h"

#include "DispatchTables.h"
#include "FrameBuffer.h"
#include "android/utils/debug.h"

#include "GLES2/gl2ext.h"

#include <stdio.h>
#include <string.h>
#include <sstream>
#include <string>
#include <utility>

#define ERR(...)  fprintf(stderr, __VA_ARGS__)
#define V(...)  VERBOSE_PRINT(gles,__VA_ARGS__)
#define MAX_FACTOR_POWER 4

static const char kCommonShaderSource[] =
    "precision mediump float;\n"
    "varying vec2 vUV00, vUV01;\n"
    "#if FACTOR > 2\n"
    "varying vec2 vUV02, vUV03;\n"
    "#if FACTOR > 4\n"
    "varying vec2 vUV04, vUV05, vUV06, vUV07;\n"
    "#if FACTOR > 8\n"
    "varying vec2 vUV08, vUV09, vUV10, vUV11, vUV12, vUV13, vUV14, vUV15;\n"
    "#endif\n"
    "#endif\n"
    "#endif\n";

static const char kVertexShaderSource[] =
    "attribute vec2 aPosition;\n"

    "void main() {\n"
    "  gl_Position = vec4(aPosition, 0, 1);\n"
    "  vec2 uv = ((aPosition + 1.0) / 2.0) + 0.5 / kDimension;\n"
    "  vUV00 = uv;\n"
    "  #ifdef HORIZONTAL\n"
    "  vUV01 = uv + vec2( 1.0 / kDimension.x, 0);\n"
    "  #if FACTOR > 2\n"
    "  vUV02 = uv + vec2( 2.0 / kDimension.x, 0);\n"
    "  vUV03 = uv + vec2( 3.0 / kDimension.x, 0);\n"
    "  #if FACTOR > 4\n"
    "  vUV04 = uv + vec2( 4.0 / kDimension.x, 0);\n"
    "  vUV05 = uv + vec2( 5.0 / kDimension.x, 0);\n"
    "  vUV06 = uv + vec2( 6.0 / kDimension.x, 0);\n"
    "  vUV07 = uv + vec2( 7.0 / kDimension.x, 0);\n"
    "  #if FACTOR > 8\n"
    "  vUV08 = uv + vec2( 8.0 / kDimension.x, 0);\n"
    "  vUV09 = uv + vec2( 9.0 / kDimension.x, 0);\n"
    "  vUV10 = uv + vec2(10.0 / kDimension.x, 0);\n"
    "  vUV11 = uv + vec2(11.0 / kDimension.x, 0);\n"
    "  vUV12 = uv + vec2(12.0 / kDimension.x, 0);\n"
    "  vUV13 = uv + vec2(13.0 / kDimension.x, 0);\n"
    "  vUV14 = uv + vec2(14.0 / kDimension.x, 0);\n"
    "  vUV15 = uv + vec2(15.0 / kDimension.x, 0);\n"
    "  #endif\n"  // FACTOR > 8
    "  #endif\n"  // FACTOR > 4
    "  #endif\n"  // FACTOR > 2

    "  #else\n"
    "  vUV01 = uv + vec2(0,  1.0 / kDimension.y);\n"
    "  #if FACTOR > 2\n"
    "  vUV02 = uv + vec2(0,  2.0 / kDimension.y);\n"
    "  vUV03 = uv + vec2(0,  3.0 / kDimension.y);\n"
    "  #if FACTOR > 4\n"
    "  vUV04 = uv + vec2(0,  4.0 / kDimension.y);\n"
    "  vUV05 = uv + vec2(0,  5.0 / kDimension.y);\n"
    "  vUV06 = uv + vec2(0,  6.0 / kDimension.y);\n"
    "  vUV07 = uv + vec2(0,  7.0 / kDimension.y);\n"
    "  #if FACTOR > 8\n"
    "  vUV08 = uv + vec2(0,  8.0 / kDimension.y);\n"
    "  vUV09 = uv + vec2(0,  9.0 / kDimension.y);\n"
    "  vUV10 = uv + vec2(0, 10.0 / kDimension.y);\n"
    "  vUV11 = uv + vec2(0, 11.0 / kDimension.y);\n"
    "  vUV12 = uv + vec2(0, 12.0 / kDimension.y);\n"
    "  vUV13 = uv + vec2(0, 13.0 / kDimension.y);\n"
    "  vUV14 = uv + vec2(0, 14.0 / kDimension.y);\n"
    "  vUV15 = uv + vec2(0, 15.0 / kDimension.y);\n"
    "  #endif\n"  // FACTOR > 8
    "  #endif\n"  // FACTOR > 4
    "  #endif\n"  // FACTOR > 2
    "  #endif\n"  // HORIZONTAL/VERTICAL
    "}\n";

const char kFragmentShaderSource[] =
    "uniform sampler2D uTexture;\n"

    "vec3 read(vec2 uv) {\n"
    "  vec3 r = texture2D(uTexture, uv).rgb;\n"
    "  #ifdef HORIZONTAL\n"
    "  r.rgb = pow(r.rgb, vec3(2.2));\n"
    "  #endif\n"
    "  return r;\n"
    "}\n"

    "void main() {\n"
    "  vec3 sum = read(vUV00) + read(vUV01);\n"
    "  #if FACTOR > 2\n"
    "  sum += read(vUV02) + read(vUV03);\n"
    "  #if FACTOR > 4\n"
    "  sum += read(vUV04) + read(vUV05) + read(vUV06) + read(vUV07);\n"
    "  #if FACTOR > 8\n"
    "  sum += read(vUV08) + read(vUV09) + read(vUV10) + read(vUV11) +"
    "      read(vUV12) + read(vUV13) + read(vUV14) + read(vUV15);\n"
    "  #endif\n"
    "  #endif\n"
    "  #endif\n"
    "  sum /= float(FACTOR);\n"
    "  #ifdef VERTICAL\n"
    "  sum.rgb = pow(sum.rgb, vec3(1.0 / 2.2));\n"
    "  #endif\n"
    "  gl_FragColor = vec4(sum.rgb, 1.0);\n"
    "}\n";

static const float kVertexData[] = {-1, -1, 3, -1, -1, 3};

static void detachShaders(GLuint program) {
    GLuint shaders[2] = {};
    GLsizei count = 0;
    s_gles2.glGetAttachedShaders(program, 2, &count, shaders);
    if (s_gles2.glGetError() == GL_NO_ERROR) {
        for (GLsizei i = 0; i < count; i++) {
            s_gles2.glDetachShader(program, shaders[i]);
            s_gles2.glDeleteShader(shaders[i]);
        }
    }
}

static GLuint createShader(GLenum type, std::initializer_list<const char*> source) {
    GLint success, infoLength;

    GLuint shader = s_gles2.glCreateShader(type);
    if (shader) {
        s_gles2.glShaderSource(shader, source.size(), source.begin(), nullptr);
        s_gles2.glCompileShader(shader);
        s_gles2.glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
        if (success == GL_FALSE) {
            s_gles2.glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLength);
            std::string infoLog(infoLength + 1, '\0');
            s_gles2.glGetShaderInfoLog(shader, infoLength, nullptr, &infoLog[0]);
            ERR("%s shader compile failed:\n%s\n",
                    (type == GL_VERTEX_SHADER) ? "Vertex" : "Fragment",
                    infoLog.c_str());
            s_gles2.glDeleteShader(shader);
            shader = 0;
        }
    }
    return shader;
}

static void attachShaders(TextureResize::Framebuffer* fb, const char* factorDefine,
        const char* dimensionDefine, GLuint width, GLuint height) {

    std::ostringstream dimensionConst;
    dimensionConst << "const vec2 kDimension = vec2(" << width << ", " << height << ");\n";

    GLuint vShader = createShader(GL_VERTEX_SHADER, {
            factorDefine, dimensionDefine,
            kCommonShaderSource, dimensionConst.str().c_str(), kVertexShaderSource
    });
    GLuint fShader = createShader(GL_FRAGMENT_SHADER, {
        factorDefine, dimensionDefine, kCommonShaderSource, kFragmentShaderSource
    });

    if (!vShader || !fShader) {
        return;
    }

    s_gles2.glAttachShader(fb->program, vShader);
    s_gles2.glAttachShader(fb->program, fShader);
    s_gles2.glLinkProgram(fb->program);

    s_gles2.glUseProgram(fb->program);
    fb->aPosition = s_gles2.glGetAttribLocation(fb->program, "aPosition");
    fb->uTexture = s_gles2.glGetUniformLocation(fb->program, "uTexture");
}

TextureResize::TextureResize(GLuint width, GLuint height) :
        mWidth(width),
        mHeight(height),
        mFactor(1),
        mFBWidth({0,}),
        mFBHeight({0,}) {
    // SwiftShader strictly follows the GLESv2 spec and doesn't allow rendering
    // into full GL_FLOAT textures. Let's detect it and reduce the precision
    // on demand. BTW, GL_HALF_FLOAT is also only present in GLESv3, so use the
    // extension instead.
    const char* vendor, *renderer, *version;
    FrameBuffer::getFB()->getGLStrings(&vendor, &renderer, &version);
    if (renderer && strstr(renderer, "SwiftShader")) {
        mTextureDataType = GL_HALF_FLOAT_OES;
    } else {
        mTextureDataType = GL_FLOAT;
    }

    s_gles2.glGenTextures(1, &mFBWidth.texture);
    s_gles2.glBindTexture(GL_TEXTURE_2D, mFBWidth.texture);
    s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    s_gles2.glGenTextures(1, &mFBHeight.texture);
    s_gles2.glBindTexture(GL_TEXTURE_2D, mFBHeight.texture);
    s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    s_gles2.glGenFramebuffers(1, &mFBWidth.framebuffer);
    s_gles2.glGenFramebuffers(1, &mFBHeight.framebuffer);

    mFBWidth.program = s_gles2.glCreateProgram();
    mFBHeight.program = s_gles2.glCreateProgram();

    s_gles2.glGenBuffers(1, &mVertexBuffer);
    s_gles2.glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
    s_gles2.glBufferData(GL_ARRAY_BUFFER, sizeof(kVertexData), kVertexData, GL_STATIC_DRAW);
}

TextureResize::~TextureResize() {
    GLuint fb[2] = {mFBWidth.framebuffer, mFBHeight.framebuffer};
    s_gles2.glDeleteFramebuffers(2, fb);

    GLuint tex[2] = {mFBWidth.texture, mFBHeight.texture};
    s_gles2.glDeleteTextures(2, tex);

    detachShaders(mFBWidth.program);
    detachShaders(mFBHeight.program);

    s_gles2.glDeleteProgram(mFBWidth.program);
    s_gles2.glDeleteProgram(mFBHeight.program);

    s_gles2.glDeleteBuffers(1, &mVertexBuffer);
}

GLuint TextureResize::update(GLuint texture) {
    // Store the viewport. The viewport is clobbered due to the framebuffers.
    GLint vport[4] = { 0, };
    s_gles2.glGetIntegerv(GL_VIEWPORT, vport);

    // Correctly deal with rotated screens.
    GLint tWidth = vport[2], tHeight = vport[3];
    if ((mWidth < mHeight) != (tWidth < tHeight)) {
        std::swap(tWidth, tHeight);
    }

    // Compute the scaling factor needed to get an image just larger than the target viewport.
    unsigned int factor = 1;
    for (int i = 0, w = mWidth / 2, h = mHeight / 2;
        i < MAX_FACTOR_POWER && w >= tWidth && h >= tHeight;
        i++, w /= 2, h /= 2, factor *= 2) {
    }

    // No resizing needed.
    if (factor == 1) {
        return texture;
    }

    s_gles2.glGetError(); // Clear any GL errors.
    setupFramebuffers(factor);
    resize(texture);
    s_gles2.glViewport(vport[0], vport[1], vport[2], vport[3]); // Restore the viewport.

    // If there was an error while resizing, just use the unscaled texture.
    GLenum error = s_gles2.glGetError();
    if (error != GL_NO_ERROR) {
        V("GL error while resizing: 0x%x (ignored)\n", error);
        return texture;
    }

    return mFBHeight.texture;
}

void TextureResize::setupFramebuffers(unsigned int factor) {
    if (factor == mFactor) {
        // The factor hasn't changed, no need to update the framebuffers.
        return;
    }

    // Update the framebuffer sizes to match the new factor.
    s_gles2.glBindTexture(GL_TEXTURE_2D, mFBWidth.texture);
    s_gles2.glTexImage2D(
        GL_TEXTURE_2D, 0, GL_RGB, mWidth / factor, mHeight, 0, GL_RGB,
                mTextureDataType, nullptr);
    s_gles2.glBindTexture(GL_TEXTURE_2D, 0);
    s_gles2.glBindFramebuffer(GL_FRAMEBUFFER, mFBWidth.framebuffer);
    s_gles2.glFramebufferTexture2D(
        GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mFBWidth.texture, 0);

    s_gles2.glBindTexture(GL_TEXTURE_2D, mFBHeight.texture);
    s_gles2.glTexImage2D(
        GL_TEXTURE_2D, 0, GL_RGB, mWidth / factor, mHeight / factor, 0, GL_RGB,
                mTextureDataType, nullptr);
    s_gles2.glBindTexture(GL_TEXTURE_2D, 0);
    s_gles2.glBindFramebuffer(GL_FRAMEBUFFER, mFBHeight.framebuffer);
    s_gles2.glFramebufferTexture2D(
        GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mFBHeight.texture, 0);

    // Update the shaders to the new factor. First detach the old shaders...
    detachShaders(mFBWidth.program);
    detachShaders(mFBHeight.program);

    // ... then attach the new ones.
    std::ostringstream factorDefine;
    factorDefine << "#define FACTOR " << factor << '\n';
    const std::string factorDefineStr = factorDefine.str();
    attachShaders(&mFBWidth, factorDefineStr.c_str(), "#define HORIZONTAL\n", mWidth, mHeight);
    attachShaders(&mFBHeight, factorDefineStr.c_str(), "#define VERTICAL\n", mWidth, mHeight);

    mFactor = factor;
}

void TextureResize::resize(GLuint texture) {
    s_gles2.glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
    s_gles2.glActiveTexture(GL_TEXTURE0);

    // First scale the horizontal dimension by rendering the input texture to a scaled framebuffer.
    s_gles2.glBindFramebuffer(GL_FRAMEBUFFER, mFBWidth.framebuffer);
    s_gles2.glViewport(0, 0, mWidth / mFactor, mHeight);
    s_gles2.glUseProgram(mFBWidth.program);
    s_gles2.glEnableVertexAttribArray(mFBWidth.aPosition);
    s_gles2.glVertexAttribPointer(mFBWidth.aPosition, 2, GL_FLOAT, GL_FALSE, 0, 0);
    s_gles2.glBindTexture(GL_TEXTURE_2D, texture);

    // Store the current texture filters and set to nearest for scaling.
    GLint mag_filter, min_filter;
    s_gles2.glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, &mag_filter);
    s_gles2.glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, &min_filter);
    s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    s_gles2.glUniform1i(mFBWidth.uTexture, 0);
    s_gles2.glDrawArrays(GL_TRIANGLES, 0, sizeof(kVertexData) / (2 * sizeof(float)));

    // Restore the previous texture filters.
    s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter);
    s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);

    // Secondly, scale the vertical dimension using the second framebuffer.
    s_gles2.glBindFramebuffer(GL_FRAMEBUFFER, mFBHeight.framebuffer);
    s_gles2.glViewport(0, 0, mWidth / mFactor, mHeight / mFactor);
    s_gles2.glUseProgram(mFBHeight.program);
    s_gles2.glEnableVertexAttribArray(mFBHeight.aPosition);
    s_gles2.glVertexAttribPointer(mFBHeight.aPosition, 2, GL_FLOAT, GL_FALSE, 0, 0);
    s_gles2.glBindTexture(GL_TEXTURE_2D, mFBWidth.texture);
    s_gles2.glUniform1i(mFBHeight.uTexture, 0);
    s_gles2.glDrawArrays(GL_TRIANGLES, 0, sizeof(kVertexData) / (2 * sizeof(float)));

    // Clear the bindings.
    s_gles2.glBindBuffer(GL_ARRAY_BUFFER, 0);
    s_gles2.glBindFramebuffer(GL_FRAMEBUFFER, 0);
    s_gles2.glBindTexture(GL_TEXTURE_2D, 0);
}
