/*
* Copyright (C) 2011 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 "EmulatedEglWindowSurface.h"

#include <assert.h>
#include <ios>
#include <stdio.h>
#include <string.h>

#include <GLES/glext.h>

#include "OpenGLESDispatch/DispatchTables.h"
#include "OpenGLESDispatch/EGLDispatch.h"
#include "aemu/base/containers/Lookup.h"
#include "host-common/GfxstreamFatalError.h"
#include "host-common/logging.h"

using emugl::ABORT_REASON_OTHER;
using emugl::FatalError;

namespace gfxstream {
namespace gl {

EmulatedEglWindowSurface::EmulatedEglWindowSurface(EGLDisplay display,
                                                   EGLConfig config,
                                                   HandleType hndl) :
        mConfig(config),
        mDisplay(display),
        mHndl(hndl) {}

EmulatedEglWindowSurface::~EmulatedEglWindowSurface() {
    if (mSurface) {
        s_egl.eglDestroySurface(mDisplay, mSurface);
    }
}

std::unique_ptr<EmulatedEglWindowSurface> EmulatedEglWindowSurface::create(
        EGLDisplay display,
        EGLConfig config,
        int p_width,
        int p_height,
        HandleType hndl) {
    std::unique_ptr<EmulatedEglWindowSurface> surface(
        new EmulatedEglWindowSurface(display, config, hndl));

    // Create a pbuffer to be used as the egl surface for that window.
    if (!surface->resize(p_width, p_height)) {
        return nullptr;
    }

    return surface;
}

void EmulatedEglWindowSurface::setColorBuffer(ColorBufferPtr p_colorBuffer) {
    mAttachedColorBuffer = p_colorBuffer;
    if (!p_colorBuffer) return;

    // resize the window if the attached color buffer is of different
    // size.
    unsigned int cbWidth = mAttachedColorBuffer->getWidth();
    unsigned int cbHeight = mAttachedColorBuffer->getHeight();

    if (cbWidth != mWidth || cbHeight != mHeight) {
        resize(cbWidth, cbHeight);
    }
}

void EmulatedEglWindowSurface::bind(EmulatedEglContextPtr p_ctx, BindType p_bindType) {
    if (p_bindType == BIND_READ) {
        mReadContext = p_ctx;
    } else if (p_bindType == BIND_DRAW) {
        mDrawContext = p_ctx;
    } else if (p_bindType == BIND_READDRAW) {
        mReadContext = p_ctx;
        mDrawContext = p_ctx;
    }
}

GLuint EmulatedEglWindowSurface::getWidth() const { return mWidth; }
GLuint EmulatedEglWindowSurface::getHeight() const { return mHeight; }

bool EmulatedEglWindowSurface::flushColorBuffer() {
    if (!mAttachedColorBuffer.get()) {
        return true;
    }
    if (!mWidth || !mHeight) {
        return false;
    }

    if (mAttachedColorBuffer->getWidth() != mWidth ||
        mAttachedColorBuffer->getHeight() != mHeight) {
        // XXX: should never happen - how this needs to be handled?
        ERR("Dimensions do not match");
        return false;
    }

    if (!mDrawContext.get()) {
        ERR("%p: Draw context is NULL", this);
        return false;
    }

    GLenum resetStatus = s_gles2.glGetGraphicsResetStatusEXT();
    if (resetStatus != GL_NO_ERROR) {
        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) <<
                "Stream server aborting due to graphics reset. ResetStatus: " <<
                std::hex << resetStatus;
    }

    // Make the surface current
    EGLContext prevContext = s_egl.eglGetCurrentContext();
    EGLSurface prevReadSurf = s_egl.eglGetCurrentSurface(EGL_READ);
    EGLSurface prevDrawSurf = s_egl.eglGetCurrentSurface(EGL_DRAW);

    const bool needToSet = prevContext != mDrawContext->getEGLContext() ||
                           prevReadSurf != mSurface || prevDrawSurf != mSurface;
    if (needToSet) {
        if (!s_egl.eglMakeCurrent(mDisplay,
                                  mSurface,
                                  mSurface,
                                  mDrawContext->getEGLContext())) {
            ERR("Error making draw context current");
            return false;
        }
    }

    mAttachedColorBuffer->glOpBlitFromCurrentReadBuffer();

    if (needToSet) {
        // restore current context/surface
        s_egl.eglMakeCurrent(mDisplay, prevDrawSurf, prevReadSurf, prevContext);
    }

    return true;
}

bool EmulatedEglWindowSurface::resize(unsigned int p_width, unsigned int p_height)
{
    if (mSurface && mWidth == p_width && mHeight == p_height) {
        // no need to resize
        return true;
    }

    EGLContext prevContext = s_egl.eglGetCurrentContext();
    EGLSurface prevReadSurf = s_egl.eglGetCurrentSurface(EGL_READ);
    EGLSurface prevDrawSurf = s_egl.eglGetCurrentSurface(EGL_DRAW);
    EGLSurface prevPbuf = mSurface;
    bool needRebindContext = mSurface &&
                             (prevReadSurf == mSurface ||
                              prevDrawSurf == mSurface);

    if (needRebindContext) {
        s_egl.eglMakeCurrent(
                mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    }

    //
    // Destroy previous surface
    //
    if (mSurface) {
        s_egl.eglDestroySurface(mDisplay, mSurface);
        mSurface = NULL;
    }

    //
    // Create pbuffer surface.
    //
    const EGLint pbufAttribs[5] = {
        EGL_WIDTH, (EGLint) p_width, EGL_HEIGHT, (EGLint) p_height, EGL_NONE,
    };

    mSurface = s_egl.eglCreatePbufferSurface(mDisplay,
                                             mConfig,
                                             pbufAttribs);
    if (mSurface == EGL_NO_SURFACE) {
        ERR("Renderer error: failed to create/resize pbuffer!!");
        return false;
    }

    mWidth = p_width;
    mHeight = p_height;

    if (needRebindContext) {
        s_egl.eglMakeCurrent(
                mDisplay,
                (prevDrawSurf == prevPbuf) ? mSurface : prevDrawSurf,
                (prevReadSurf == prevPbuf) ? mSurface : prevReadSurf,
                prevContext);
    }

    return true;
}

HandleType EmulatedEglWindowSurface::getHndl() const {
    return mHndl;
}

template <class obj_t>
static void saveHndlOrNull(obj_t obj, android::base::Stream* stream) {
    if (obj) {
        stream->putBe32(obj->getHndl());
    } else {
        stream->putBe32(0);
    }
}

void EmulatedEglWindowSurface::onSave(android::base::Stream* stream) const {
    stream->putBe32(getHndl());
    saveHndlOrNull(mAttachedColorBuffer, stream);
    saveHndlOrNull(mReadContext, stream);
    saveHndlOrNull(mDrawContext, stream);
    stream->putBe32(mWidth);
    stream->putBe32(mHeight);
    if (s_egl.eglSaveConfig) {
        s_egl.eglSaveConfig(mDisplay, mConfig, stream);
    }
}

std::unique_ptr<EmulatedEglWindowSurface> EmulatedEglWindowSurface::onLoad(
        android::base::Stream* stream,
        EGLDisplay display,
        const ColorBufferMap& colorBuffers,
        const EmulatedEglContextMap& contexts) {
    HandleType hndl = stream->getBe32();
    HandleType colorBufferHndl = stream->getBe32();
    HandleType readCtx = stream->getBe32();
    HandleType drawCtx = stream->getBe32();

    GLuint width = stream->getBe32();
    GLuint height = stream->getBe32();
    EGLConfig config = 0;
    if (s_egl.eglLoadConfig) {
        config = s_egl.eglLoadConfig(display, stream);
    }

    auto surface = create(display, config, width, height, hndl);
    assert(surface);
    // fb is already locked by its caller
    if (colorBufferHndl) {
        const auto* colorBufferRef = android::base::find(colorBuffers, colorBufferHndl);
        assert(colorBufferRef);
        surface->mAttachedColorBuffer = colorBufferRef->cb;
    }
    surface->mReadContext = android::base::findOrDefault(contexts, readCtx);
    surface->mDrawContext = android::base::findOrDefault(contexts, drawCtx);
    return surface;
}

}  // namespace gl
}  // namespace gfxstream
