/*
 * 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<IGraphicBufferProducer> producer;
    sp<IGraphicBufferConsumer> consumer;
    BufferQueue::createBufferQueue(&producer, &consumer, mGraphicBufferAlloc);
    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);
    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, "%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] != 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;
}

}
