/*
 * Copyright (C) 2013 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 "Renderer.h"
#include <graphics/GLUtils.h>

#define LOG_TAG "PTS_OPENGL"
#define LOG_NDEBUG 0
#include <utils/Log.h>

#include <Trace.h>

static const EGLint contextAttribs[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2,
        EGL_NONE };

static const EGLint configAttribs[] = {
        EGL_SURFACE_TYPE, EGL_PBUFFER_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_DEPTH_SIZE, 16,
        EGL_STENCIL_SIZE, 8,
        EGL_NONE };

Renderer::Renderer(ANativeWindow* window, bool offscreen, int workload) :
        mWindow(window), mEglDisplay(EGL_NO_DISPLAY), mEglSurface(EGL_NO_SURFACE),
        mEglContext(EGL_NO_CONTEXT), mOffscreen(offscreen), mWorkload(workload) {
}

bool Renderer::setUp() {
    SCOPED_TRACE();
    mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    if (EGL_NO_DISPLAY == mEglDisplay || EGL_SUCCESS != eglGetError()) {
        return false;
    }

    EGLint major;
    EGLint minor;
    if (!eglInitialize(mEglDisplay, &major, &minor) || EGL_SUCCESS != eglGetError()) {
        return false;
    }

    EGLint numConfigs = 0;
    if (!eglChooseConfig(mEglDisplay, configAttribs, &mGlConfig, 1, &numConfigs)
            || EGL_SUCCESS != eglGetError()) {
        return false;
    }

    mEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig, mWindow, NULL);
    if (EGL_NO_SURFACE == mEglSurface || EGL_SUCCESS != eglGetError()) {
        return false;
    }

    mEglContext = eglCreateContext(mEglDisplay, mGlConfig, EGL_NO_CONTEXT, contextAttribs);
    if (EGL_NO_CONTEXT == mEglContext || EGL_SUCCESS != eglGetError()) {
        return false;
    }

    if (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)
            || EGL_SUCCESS != eglGetError()) {
        return false;
    }

    if (!eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &mWidth)
            || EGL_SUCCESS != eglGetError()) {
        return false;
    }
    if (!eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &mHeight)
            || EGL_SUCCESS != eglGetError()) {
        return false;
    }

    if (mOffscreen) {
        mFboWidth = GLUtils::roundUpToSmallestPowerOf2(mWidth);
        mFboHeight = GLUtils::roundUpToSmallestPowerOf2(mHeight);
        if (!GLUtils::createFBO(mFboId, mRboId, mCboId, mFboWidth, mFboHeight)) {
            return false;
        }
        mBuffer = new GLushort[mFboWidth * mFboHeight];
        glViewport(0, 0, mFboWidth, mFboHeight);
    } else {
        mFboWidth = 0;
        mFboHeight = 0;
        mBuffer = NULL;
        mFboId = 0;
        mRboId = 0;
        mCboId = 0;
        glViewport(0, 0, mWidth, mHeight);
    }

    GLuint err = glGetError();
    if (err != GL_NO_ERROR) {
        ALOGE("GLError %d in setUp", err);
        return false;
    }
    return true;
}

bool Renderer::tearDown() {
    SCOPED_TRACE();
    if (mBuffer != NULL) {
        delete[] mBuffer;
        mBuffer = NULL;
    }
    if (mFboId != 0) {
        glDeleteFramebuffers(1, &mFboId);
        mFboId = 0;
    }
    if (mRboId != 0) {
        glDeleteRenderbuffers(1, &mRboId);
        mRboId = 0;
    }
    if (mCboId != 0) {
        glDeleteRenderbuffers(1, &mCboId);
        mCboId = 0;
    }
    if (mEglContext != EGL_NO_CONTEXT) {
        eglDestroyContext(mEglDisplay, mEglContext);
        mEglContext = EGL_NO_CONTEXT;
    }
    if (mEglSurface != EGL_NO_SURFACE) {
        eglDestroySurface(mEglDisplay, mEglSurface);
        mEglSurface = EGL_NO_SURFACE;
    }
    if (mEglDisplay != EGL_NO_DISPLAY) {
        eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
        eglTerminate(mEglDisplay);
        mEglDisplay = EGL_NO_DISPLAY;
    }

    GLuint err = glGetError();
    if (err != GL_NO_ERROR) {
        ALOGE("GLError %d in tearDown", err);
        return false;
    }

    return EGL_SUCCESS == eglGetError();
}

bool Renderer::draw() {
    SCOPED_TRACE();
    GLuint err = glGetError();
    if (err != GL_NO_ERROR) {
        ALOGE("GLError %d in draw", err);
        return false;
    }

    if (mOffscreen) {
        // Read the pixels back from the frame buffer.
        glReadPixels(0, 0, mFboWidth, mFboHeight, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, mBuffer);
        return true;
    } else {
        return eglSwapBuffers(mEglDisplay, mEglSurface);
    }
}
