// Copyright 2016 The Android Open Source Project
// This software is licensed under the terms of the GNU General Public
// License version 2, as published by the Free Software Foundation, and
// may be copied, distributed, and modified under those terms.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

#include "android/skin/qt/gl-widget.h"

#include "android/base/memory/LazyInstance.h"

#include "GLES2/gl2.h"

#include <QResizeEvent>
#include <QtGlobal>
#include <QWindow>

// Note that this header must come after ALL Qt headers.
// Including any Qt headers after it will cause compilation
// to fail spectacularly. This is because EGL indirectly
// includes X11 headers which define stuff that conflicts
// with Qt's own macros. It is a known issue.
#include "OpenGLESDispatch/EGLDispatch.h"
#include "OpenGLESDispatch/GLESv2Dispatch.h"

namespace {

// Helper class to hold a global GLESv2Dispatch that is initialized lazily
// in a thread-safe way. The instance is leaked on program exit.
struct MyGLESv2Dispatch : public GLESv2Dispatch {
    // Return pointer to global GLESv2Dispatch instance, or nullptr if there
    // was an error when trying to initialize/load the library.
    static const GLESv2Dispatch* get();

    MyGLESv2Dispatch() { mValid = gles2_dispatch_init(&mDispatch); }

private:
    GLESv2Dispatch mDispatch;
    bool mValid;
};

// Must be declared outside of MyGLESv2Dispatch scope due to the use of
// sizeof(T) within the template definition.
android::base::LazyInstance<MyGLESv2Dispatch> sGLESv2Dispatch =
        LAZY_INSTANCE_INIT;

// static
const GLESv2Dispatch* MyGLESv2Dispatch::get() {
    MyGLESv2Dispatch* instance = sGLESv2Dispatch.ptr();
    if (instance->mValid) {
        return &instance->mDispatch;
    } else {
        return nullptr;
    }
}

// Helper class used to lazily initialize the global EGL dispatch table
// in a thread safe way. Note that the dispatch table is provided by
// libOpenGLESDispatch as the 's_egl' global variable.
struct MyEGLDispatch : public EGLDispatch {
    // Return pointer to EGLDispatch table, or nullptr if there was
    // an error when trying to initialize/load the library.
    static const EGLDispatch* get();

    MyEGLDispatch() { mValid = init_egl_dispatch(); }

private:
    bool mValid;
};

android::base::LazyInstance<MyEGLDispatch> sEGLDispatch = LAZY_INSTANCE_INIT;

// static
const EGLDispatch* MyEGLDispatch::get() {
    MyEGLDispatch* instance = sEGLDispatch.ptr();
    if (instance->mValid) {
        return &s_egl;
    } else {
        return nullptr;
    }
}

}  // namespace

struct EGLState {
    EGLDisplay display;
    EGLContext context;
    EGLSurface surface;
};

// Helper function to get the nearest power-of-two.
// It's needed to create a GLCanvas with correct dimensions
// to allow generating mipmaps (GLES 2.0 doesn't support
// mipmaps for NPOT textures)
static int nearestPOT(int value) {
    return pow(2, ceil(log(value)/log(2)));
}

GLWidget::GLWidget(QWidget* parent) :
        QWidget(parent),
        mEGL(MyEGLDispatch::get()),
        mGLES2(MyGLESv2Dispatch::get()),
        mEGLState(nullptr),
        mValid(false),
        mEnableAA(false) {
    setAutoFillBackground(false);
    setAttribute(Qt::WA_OpaquePaintEvent, true);
    setAttribute(Qt::WA_PaintOnScreen, true);
    setAttribute(Qt::WA_NoSystemBackground, true);

    // QGLWidget always has a native window, and ours should behave
    // in a similar fashion as well. Not having these attributes set
    // causes issues with the window initialization.
    setAttribute(Qt::WA_DontCreateNativeAncestors, true);
    setAttribute(Qt::WA_NativeWindow, true);
}

void GLWidget::handleScreenChange(QScreen*) {
    // Destroy the context, forcing its re-creation on
    // next paint event.
    destroyContext();
    resizeGL(realPixelsWidth(), realPixelsHeight());
}

bool GLWidget::ensureInit() {
    // If an error occured when loading the EGL/GLESv2 libraries, return false.
    if (!mEGL || !mGLES2) {
        return false;
    }

    // If already initialized, return mValid to indicate if an error occured.
    if (mEGLState) {
        return mValid;
    }

    mEGLState = new EGLState();
    mValid = false;

    mEGLState->display = mEGL->eglGetDisplay(EGL_DEFAULT_DISPLAY);
    if (mEGLState->display == EGL_NO_DISPLAY) {
        qWarning("Failed to get EGL display: EGL error %d",
                 mEGL->eglGetError());
        return false;
    }

    EGLint egl_maj, egl_min;
    EGLConfig egl_config;

    // Try to initialize EGL display.
    // Initializing an already-initialized display is OK.
    if (mEGL->eglInitialize(mEGLState->display, &egl_maj, &egl_min) ==
        EGL_FALSE) {
        qWarning("Failed to initialize EGL display: EGL error %d",
                 mEGL->eglGetError());
        return false;
    }

    // Get an EGL config.
    const EGLint config_attribs[] = {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_DEPTH_SIZE,
                                     24,
                                     EGL_SAMPLES,
                                     0,  // No multisampling
                                     EGL_NONE};
    EGLint num_config;
    EGLBoolean choose_result = mEGL->eglChooseConfig(
            mEGLState->display, config_attribs, &egl_config, 1, &num_config);
    if (choose_result == EGL_FALSE || num_config < 1) {
        qWarning("Failed to choose EGL config: EGL error %d",
                 mEGL->eglGetError());
        return false;
    }

    // Create a context.
    EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
    mEGLState->context = mEGL->eglCreateContext(
            mEGLState->display, egl_config, EGL_NO_CONTEXT, context_attribs);
    if (mEGLState->context == EGL_NO_CONTEXT) {
        qWarning("Failed to create EGL context %d", mEGL->eglGetError());
    }

    // Finally, create a window surface associated with this widget.
    mEGLState->surface = mEGL->eglCreateWindowSurface(
            mEGLState->display, egl_config, (EGLNativeWindowType)(winId()),
            nullptr);
    if (mEGLState->surface == EGL_NO_SURFACE) {
        qWarning("Failed to create an EGL surface %d", mEGL->eglGetError());
        return false;
    }


    makeContextCurrent();
    mCanvas.reset(new GLCanvas(
        nearestPOT(realPixelsWidth()),
        nearestPOT(realPixelsHeight()),
        mGLES2));
    mTextureDraw.reset(new TextureDraw(mGLES2));
    mValid = initGL();

    return mValid;
}

bool GLWidget::makeContextCurrent() {
    if (mEGLState) {
        return
            mEGL->eglMakeCurrent(mEGLState->display, mEGLState->surface,
                                 mEGLState->surface, mEGLState->context) == EGL_TRUE;

    } else {
        return false;
    }
}

void GLWidget::renderFrame() {
    if (!readyForRendering()) {
        return;
    }
    makeContextCurrent();

    // Render 3D scene to texture.
    if (mEnableAA) {
        mCanvas->bind();
        repaintGL();
        mCanvas->unbind();
    } else {
        mGLES2->glViewport(0, 0, realPixelsWidth(), realPixelsHeight());
        repaintGL();
    }

    if (mEnableAA) {
        mGLES2->glBindTexture(GL_TEXTURE_2D, mCanvas->texture());
        mGLES2->glGenerateMipmap(GL_TEXTURE_2D);
        mTextureDraw->draw(mCanvas->texture(),
                           realPixelsWidth(),
                           realPixelsHeight());
    }

    mEGL->eglSwapBuffers(mEGLState->display, mEGLState->surface);
}

void GLWidget::paintEvent(QPaintEvent*) {
    if (ensureInit()) {
      renderFrame();
    }
}

void GLWidget::showEvent(QShowEvent*) {
    // When the widget first becomes visible, we render a frame,
    // which will force the necessary initialization.
    // It is important to make sure that the widget is actually
    // visible on screen (at least for OS X) before doing any
    // initialization at all.
    // However, show events may be delivered when the widget
    // isn't visible yet, so we need an additional check.
    if (isVisible() && !visibleRegion().isNull()) {
        if (ensureInit()) {
            renderFrame();
        }
    }
    connect(window()->windowHandle(), SIGNAL(screenChanged(QScreen*)), this, SLOT(handleScreenChange(QScreen*)));
}

void GLWidget::resizeEvent(QResizeEvent* e) {
    if (mEGLState) {
        // We should only call resizeGL and repaint if all the setup
        // has been done.
        // We should NOT attempt to initialize EGL state during a resize
        // event due to some subtleties on OS X. If we attempt to initialize
        // EGL state at the time the resize event is generated, the default
        // framebuffer will not be created.
        makeContextCurrent();
        // Re-create the framebuffer with new size.
        mCanvas.reset(new GLCanvas(
            nearestPOT(e->size().width() * devicePixelRatio()),
            nearestPOT(e->size().height() * devicePixelRatio()),
            mGLES2));
        resizeGL(e->size().width() * devicePixelRatio(),
                 e->size().height() * devicePixelRatio());
        renderFrame();
    }
}

GLWidget::~GLWidget() {
    destroyContext();
}

void GLWidget::destroyContext() {
    if (mGLES2 && mEGL && mEGLState) {
        // Destroy canvas and texturedraw state
        // within this context.
        makeContextCurrent();
        mCanvas.reset(nullptr);
        mTextureDraw.reset(nullptr);

        // Make sure the context isn't active before destroying it.
        mEGL->eglMakeCurrent(mEGLState->display, 0, 0, 0);

        // Reset EGL state and set mEGLState to null, which will force
        // re-initialization when attempting to render the next frame.
        mEGL->eglDestroySurface(mEGLState->display, mEGLState->surface);
        mEGL->eglDestroyContext(mEGLState->display, mEGLState->context);
        delete mEGLState;
        mEGLState = nullptr;
    }
}
