/*
 * 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 <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

#include <ui/DisplayInfo.h>
#include <gui/SurfaceComposerClient.h>

#include "GLHelper.h"

 namespace android {

GLHelper::GLHelper() :
    mGraphicBufferAlloc(new GraphicBufferAlloc()),
    mDisplay(EGL_NO_DISPLAY),
    mContext(EGL_NO_CONTEXT),
    mDummySurface(EGL_NO_SURFACE),
    mConfig(0),
    mShaderPrograms(NULL),
    mDitherTexture(0) {
}

GLHelper::~GLHelper() {
}

bool GLHelper::setUp(const ShaderDesc* shaderDescs, size_t numShaders) {
    bool result;

    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 != NULL) {
        delete[] mShaderPrograms;
        mShaderPrograms = NULL;
    }

    if (mSurfaceComposerClient != NULL) {
        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) {
    sp<BufferQueue> bq = new BufferQueue(mGraphicBufferAlloc);
    sp<GLConsumer> glc = new GLConsumer(bq, name,
            GL_TEXTURE_EXTERNAL_OES, false);
    glc->setDefaultBufferSize(w, h);
    glc->setDefaultMaxBufferCount(3);
    glc->setConsumerUsageBits(GRALLOC_USAGE_HW_COMPOSER);

    sp<ANativeWindow> anw = new Surface(bq);
    EGLSurface s = eglCreateWindowSurface(mDisplay, mConfig, anw.get(), NULL);
    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) {
    sp<IBinder> dpy = mSurfaceComposerClient->getBuiltInDisplay(0);
    if (dpy == NULL) {
        fprintf(stderr, "SurfaceComposer::getBuiltInDisplay failed.\n");
        return false;
    }

    DisplayInfo info;
    status_t err = mSurfaceComposerClient->getDisplayInfo(dpy, &info);
    if (err != NO_ERROR) {
        fprintf(stderr, "SurfaceComposer::getDisplayInfo failed: %#x\n", err);
        return false;
    }

    float scaleX = float(info.w) / float(w);
    float scaleY = float(info.h) / float(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 == NULL) {
        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 == NULL || !sc->isValid()) {
        fprintf(stderr, "Failed to create SurfaceControl.\n");
        return false;
    }

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

    SurfaceComposerClient::openGlobalTransaction();
    err = sc->setLayer(0x7FFFFFFF);
    if (err != NO_ERROR) {
        fprintf(stderr, "SurfaceComposer::setLayer error: %#x\n", err);
        return false;
    }
    err = sc->setMatrix(scale, 0.0f, 0.0f, scale);
    if (err != NO_ERROR) {
        fprintf(stderr, "SurfaceComposer::setMatrix error: %#x\n", err);
        return false;
    }

    err = sc->show();
    if (err != NO_ERROR) {
        fprintf(stderr, "SurfaceComposer::show error: %#x\n", err);
        return false;
    }
    SurfaceComposerClient::closeGlobalTransaction();

    sp<ANativeWindow> anw = sc->getSurface();
    EGLSurface s = eglCreateWindowSurface(mDisplay, mConfig, anw.get(), NULL);
    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, NULL);
    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, NULL, 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] != NULL; i++) {
        fprintf(stderr, "%3d: %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] != NULL; 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] != NULL; 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);
        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, NULL, 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;
}

}
