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

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <com_android_graphics_libgui_flags.h>
#include <gui/SurfaceComposerClient.h>
#include <ui/DisplayMode.h>

namespace android {

GLHelper::GLHelper() :
    mDisplay(EGL_NO_DISPLAY),
    mContext(EGL_NO_CONTEXT),
    mDummySurface(EGL_NO_SURFACE),
    mConfig(0),
    mShaderPrograms(nullptr),
    mDitherTexture(0) {
}

GLHelper::~GLHelper() {
}

bool GLHelper::setUp(const sp<IBinder>& displayToken, const ShaderDesc* shaderDescs,
                     size_t numShaders) {
    bool result;

    mDisplayToken = displayToken;

    mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    if (mDisplay == EGL_NO_DISPLAY) {
        fprintf(stderr, "eglGetDisplay error: %#x\n", eglGetError());
        return false;
    }

    EGLint majorVersion;
    EGLint minorVersion;
    result = eglInitialize(mDisplay, &majorVersion, &minorVersion);
    if (result != EGL_TRUE) {
        fprintf(stderr, "eglInitialize error: %#x\n", eglGetError());
        return false;
    }

    EGLint numConfigs = 0;
    EGLint configAttribs[] = {
        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
        EGL_RED_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_BLUE_SIZE, 8,
        EGL_ALPHA_SIZE, 8,
        EGL_NONE
    };
    result = eglChooseConfig(mDisplay, configAttribs, &mConfig, 1,
            &numConfigs);
    if (result != EGL_TRUE) {
        fprintf(stderr, "eglChooseConfig error: %#x\n", eglGetError());
        return false;
    }

    EGLint contextAttribs[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2,
        EGL_NONE
    };
    mContext = eglCreateContext(mDisplay, mConfig, EGL_NO_CONTEXT,
            contextAttribs);
    if (mContext == EGL_NO_CONTEXT) {
        fprintf(stderr, "eglCreateContext error: %#x\n", eglGetError());
        return false;
    }

    bool resultb = createNamedSurfaceTexture(0, 1, 1, &mDummyGLConsumer,
            &mDummySurface);
    if (!resultb) {
        return false;
    }

    resultb = makeCurrent(mDummySurface);
    if (!resultb) {
        return false;
    }

    resultb = setUpShaders(shaderDescs, numShaders);
    if (!resultb) {
        return false;
    }

    return true;
}

void GLHelper::tearDown() {
    if (mShaderPrograms != nullptr) {
        delete[] mShaderPrograms;
        mShaderPrograms = nullptr;
    }

    if (mSurfaceComposerClient != nullptr) {
        mSurfaceComposerClient->dispose();
        mSurfaceComposerClient.clear();
    }

    if (mDisplay != EGL_NO_DISPLAY) {
        eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
                EGL_NO_CONTEXT);
    }

    if (mContext != EGL_NO_CONTEXT) {
        eglDestroyContext(mDisplay, mContext);
    }

    if (mDummySurface != EGL_NO_SURFACE) {
        eglDestroySurface(mDisplay, mDummySurface);
    }

    mDisplay = EGL_NO_DISPLAY;
    mContext = EGL_NO_CONTEXT;
    mDummySurface = EGL_NO_SURFACE;
    mDummyGLConsumer.clear();
    mConfig = 0;
}

bool GLHelper::makeCurrent(EGLSurface surface) {
    EGLint result;

    result = eglMakeCurrent(mDisplay, surface, surface, mContext);
    if (result != EGL_TRUE) {
        fprintf(stderr, "eglMakeCurrent error: %#x\n", eglGetError());
        return false;
    }

    EGLint w, h;
    eglQuerySurface(mDisplay, surface, EGL_WIDTH, &w);
    eglQuerySurface(mDisplay, surface, EGL_HEIGHT, &h);
    glViewport(0, 0, w, h);

    return true;
}

bool GLHelper::createSurfaceTexture(uint32_t w, uint32_t h,
        sp<GLConsumer>* glConsumer, EGLSurface* surface,
        GLuint* name) {
    if (!makeCurrent(mDummySurface)) {
        return false;
    }

    *name = 0;
    glGenTextures(1, name);
    if (*name == 0) {
        fprintf(stderr, "glGenTextures error: %#x\n", glGetError());
        return false;
    }

    return createNamedSurfaceTexture(*name, w, h, glConsumer, surface);
}

void GLHelper::destroySurface(EGLSurface* surface) {
    if (eglGetCurrentSurface(EGL_READ) == *surface ||
            eglGetCurrentSurface(EGL_DRAW) == *surface) {
        eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
                EGL_NO_CONTEXT);
    }
    eglDestroySurface(mDisplay, *surface);
    *surface = EGL_NO_SURFACE;
}

bool GLHelper::swapBuffers(EGLSurface surface) {
    EGLint result;
    result = eglSwapBuffers(mDisplay, surface);
    if (result != EGL_TRUE) {
        fprintf(stderr, "eglSwapBuffers error: %#x\n", eglGetError());
        return false;
    }
    return true;
}

bool GLHelper::getShaderProgram(const char* name, GLuint* outPgm) {
    for (size_t i = 0; i < mNumShaders; i++) {
        if (strcmp(mShaderDescs[i].name, name) == 0) {
            *outPgm = mShaderPrograms[i];
            return true;
        }
    }

    fprintf(stderr, "unknown shader name: \"%s\"\n", name);

    return false;
}

bool GLHelper::createNamedSurfaceTexture(GLuint name, uint32_t w, uint32_t h,
        sp<GLConsumer>* glConsumer, EGLSurface* surface) {
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
    sp<GLConsumer> glc = new GLConsumer(name, GL_TEXTURE_EXTERNAL_OES, false, true);
    glc->setDefaultBufferSize(w, h);
    glc->getSurface()->setMaxDequeuedBufferCount(2);
    glc->setConsumerUsageBits(GRALLOC_USAGE_HW_COMPOSER);

    sp<ANativeWindow> anw = glc->getSurface();
#else
    sp<IGraphicBufferProducer> producer;
    sp<IGraphicBufferConsumer> consumer;
    BufferQueue::createBufferQueue(&producer, &consumer);
    sp<GLConsumer> glc = new GLConsumer(consumer, name,
            GL_TEXTURE_EXTERNAL_OES, false, true);
    glc->setDefaultBufferSize(w, h);
    producer->setMaxDequeuedBufferCount(2);
    glc->setConsumerUsageBits(GRALLOC_USAGE_HW_COMPOSER);

    sp<ANativeWindow> anw = new Surface(producer);
#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
    EGLSurface s = eglCreateWindowSurface(mDisplay, mConfig, anw.get(), nullptr);
    if (s == EGL_NO_SURFACE) {
        fprintf(stderr, "eglCreateWindowSurface error: %#x\n", eglGetError());
        return false;
    }

    *glConsumer = glc;
    *surface = s;
    return true;
}

bool GLHelper::computeWindowScale(uint32_t w, uint32_t h, float* scale) {
    ui::DisplayMode mode;
    status_t err = mSurfaceComposerClient->getActiveDisplayMode(mDisplayToken, &mode);
    if (err != NO_ERROR) {
        fprintf(stderr, "SurfaceComposer::getActiveDisplayMode failed: %#x\n", err);
        return false;
    }

    float scaleX = static_cast<float>(mode.resolution.getWidth()) / w;
    float scaleY = static_cast<float>(mode.resolution.getHeight()) / h;
    *scale = scaleX < scaleY ? scaleX : scaleY;

    return true;
}

bool GLHelper::createWindowSurface(uint32_t w, uint32_t h,
        sp<SurfaceControl>* surfaceControl, EGLSurface* surface) {
    bool result;
    status_t err;

    if (mSurfaceComposerClient == nullptr) {
        mSurfaceComposerClient = new SurfaceComposerClient;
    }
    err = mSurfaceComposerClient->initCheck();
    if (err != NO_ERROR) {
        fprintf(stderr, "SurfaceComposerClient::initCheck error: %#x\n", err);
        return false;
    }

    sp<SurfaceControl> sc = mSurfaceComposerClient->createSurface(
            String8("Benchmark"), w, h, PIXEL_FORMAT_RGBA_8888, 0);
    if (sc == nullptr || !sc->isValid()) {
        fprintf(stderr, "Failed to create SurfaceControl.\n");
        return false;
    }

    float scale;
    result = computeWindowScale(w, h, &scale);
    if (!result) {
        return false;
    }

    SurfaceComposerClient::Transaction{}.setLayer(sc, 0x7FFFFFFF)
            .setMatrix(sc, scale, 0.0f, 0.0f, scale)
            .show(sc)
            .apply();

    sp<ANativeWindow> anw = sc->getSurface();
    EGLSurface s = eglCreateWindowSurface(mDisplay, mConfig, anw.get(), nullptr);
    if (s == EGL_NO_SURFACE) {
        fprintf(stderr, "eglCreateWindowSurface error: %#x\n", eglGetError());
        return false;
    }

    *surfaceControl = sc;
    *surface = s;
    return true;
}

static bool compileShader(GLenum shaderType, const char* src,
        GLuint* outShader) {
    GLuint shader = glCreateShader(shaderType);
    if (shader == 0) {
        fprintf(stderr, "glCreateShader error: %#x\n", glGetError());
        return false;
    }

    glShaderSource(shader, 1, &src, nullptr);
    glCompileShader(shader);

    GLint compiled = 0;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
    if (!compiled) {
        GLint infoLen = 0;
        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
        if (infoLen) {
            char* buf = new char[infoLen];
            if (buf) {
                glGetShaderInfoLog(shader, infoLen, nullptr, buf);
                fprintf(stderr, "Shader compile log:\n%s\n", buf);
                delete[] buf;
            }
        }
        glDeleteShader(shader);
        return false;
    }
    *outShader = shader;
    return true;
}

static void printShaderSource(const char* const* src) {
    for (size_t i = 0; i < MAX_SHADER_LINES && src[i] != nullptr; i++) {
        fprintf(stderr, "%3zu: %s\n", i+1, src[i]);
    }
}

static const char* makeShaderString(const char* const* src) {
    size_t len = 0;
    for (size_t i = 0; i < MAX_SHADER_LINES && src[i] != nullptr; i++) {
        // The +1 is for the '\n' that will be added.
        len += strlen(src[i]) + 1;
    }

    char* result = new char[len+1];
    char* end = result;
    for (size_t i = 0; i < MAX_SHADER_LINES && src[i] != nullptr; i++) {
        strcpy(end, src[i]);
        end += strlen(src[i]);
        *end = '\n';
        end++;
    }
    *end = '\0';

    return result;
}

static bool compileShaderLines(GLenum shaderType, const char* const* lines,
        GLuint* outShader) {
    const char* src = makeShaderString(lines);
    bool result = compileShader(shaderType, src, outShader);
    if (!result) {
        fprintf(stderr, "Shader source:\n");
        printShaderSource(lines);
        delete[] src;
        return false;
    }
    delete[] src;

    return true;
}

static bool linkShaderProgram(GLuint vs, GLuint fs, GLuint* outPgm) {
    GLuint program = glCreateProgram();
    if (program == 0) {
        fprintf(stderr, "glCreateProgram error: %#x\n", glGetError());
        return false;
    }

    glAttachShader(program, vs);
    glAttachShader(program, fs);
    glLinkProgram(program);
    GLint linkStatus = GL_FALSE;
    glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
    if (linkStatus != GL_TRUE) {
        GLint bufLength = 0;
        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
        if (bufLength) {
            char* buf = new char[bufLength];
            if (buf) {
                glGetProgramInfoLog(program, bufLength, nullptr, buf);
                fprintf(stderr, "Program link log:\n%s\n", buf);
                delete[] buf;
            }
        }
        glDeleteProgram(program);
        program = 0;
    }

    *outPgm = program;
    return program != 0;
}

bool GLHelper::setUpShaders(const ShaderDesc* shaderDescs, size_t numShaders) {
    mShaderPrograms = new GLuint[numShaders];
    bool result = true;

    for (size_t i = 0; i < numShaders && result; i++) {
        GLuint vs, fs;

        result = compileShaderLines(GL_VERTEX_SHADER,
                shaderDescs[i].vertexShader, &vs);
        if (!result) {
            return false;
        }

        result = compileShaderLines(GL_FRAGMENT_SHADER,
                shaderDescs[i].fragmentShader, &fs);
        if (!result) {
            glDeleteShader(vs);
            return false;
        }

        result = linkShaderProgram(vs, fs, &mShaderPrograms[i]);
        glDeleteShader(vs);
        glDeleteShader(fs);
    }

    mNumShaders = numShaders;
    mShaderDescs = shaderDescs;

    return result;
}

bool GLHelper::getDitherTexture(GLuint* outTexName) {
    if (mDitherTexture == 0) {
        const uint8_t pattern[] = {
             0,  8,  2, 10,
            12,  4, 14,  6,
             3, 11,  1,  9,
            15,  7, 13,  5
        };

        glGenTextures(1, &mDitherTexture);
        glBindTexture(GL_TEXTURE_2D, mDitherTexture);

        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);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

        glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, DITHER_KERNEL_SIZE,
                DITHER_KERNEL_SIZE, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &pattern);
    }

    *outTexName = mDitherTexture;

    return true;
}

}
