/*
 * 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 <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(true, mGraphicBufferAlloc);
    sp<GLConsumer> glc = new GLConsumer(name, true,
            GL_TEXTURE_EXTERNAL_OES, false, bq);
    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;
}

}
